<commit_before>/*
  SystemJS CommonJS Format
*/
(function() {
  // CJS Module Format
  // require('...') || exports[''] = ... || exports.asd = ... || module.exports = ...
  var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.]|module\.)exports\s*(\[['"]|\.)|(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])module\.exports\s*[=,]/;
  // RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339
  var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g;
  var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;

  function getCJSDeps(source) {
    cjsRequireRegEx.lastIndex = 0;

    var deps = [];

    // track comments in the source
    var match;

    var commentLocations = [];
    if (source.length / source.split('\n').length < 200) {
      while (match = commentRegEx.exec(source))
        commentLocations.push([match.index, match.index + match[0].length]);
    }

    while (match = cjsRequireRegEx.exec(source)) {
      // ensure we're not in a comment location
      var inComment = false;
      for (var i = 0; i < commentLocations.length; i++) {
        if (commentLocations[i][0] < match.index && commentLocations[i][1] > match.index + match[0].length)
          inComment = true;
      }
      if (!inComment)
        deps.push(match[1].substr(1, match[1].length - 2));
    }

    return deps;
  }

  if (typeof window != 'undefined' && typeof document != 'undefined' && window.location)
    var windowOrigin = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);

      // include the node require since we're overriding it
      if (typeof require != 'undefined' && require.resolve && typeof process != 'undefined')
        this._nodeRequire = require;
    };
  });

  hook('normalize', function(normalize) {
    return function (name, parentName) {
      // dynamically load node-core modules when requiring `@node/fs` for example
      if (name.substr(0, 6) == '@node/') {
        if (!this._nodeRequire)
          throw new TypeError('Can only load node core modules in Node.');
        this.set(name, this.newModule(getESModule(this._nodeRequire(name.substr(6)))));
      }
      return normalize.call(this, name, parentName);
    };
  });

  hook('instantiate', function(instantiate) {
    return function(load) {
      var loader = this;
      if (!load.metadata.format) {
        cjsExportsRegEx.lastIndex = 0;
        cjsRequireRegEx.lastIndex = 0;
        if (cjsRequireRegEx.exec(load.source) || cjsExportsRegEx.exec(load.source))
          load.metadata.format = 'cjs';
      }

      if (load.metadata.format == 'cjs') {
        var metaDeps = load.metadata.deps || [];
        load.metadata.deps = metaDeps.concat(getCJSDeps(load.source));

        for (var g in load.metadata.globals)
          load.metadata.deps.push(load.metadata.globals[g]);

        load.metadata.executingRequire = true;

        load.metadata.execute = function(require, exports, module) {
          // ensure meta deps execute first
          for (var i = 0; i < metaDeps.length; i++)
            require(metaDeps[i]);
          var address = load.address || '';

          var dirname = address.split('/');
          dirname.pop();
          dirname = dirname.join('/');

          if (windowOrigin && address.substr(0, windowOrigin.length) === windowOrigin) {
            address = address.substr(windowOrigin.length);
            dirname = dirname.substr(windowOrigin.length);
          }
          else if (address.substr(0, 8) == 'file:///') {
            address = address.substr(7);
            dirname = dirname.substr(7);

            // on windows remove leading '/'
            if (isWindows) {
              address = address.substr(1);
              dirname = dirname.substr(1);
            }
          }

          // disable AMD detection
          var define = __global.define;
          __global.define = undefined;

          __global.__cjsWrapper = {
            exports: exports,
            args: [require, exports, module, address, dirname, __global, __global]
          };

          var globals = '';
          if (load.metadata.globals) {
            for (var g in load.metadata.globals)
              globals += 'var ' + g + ' = require("' + load.metadata.globals[g] + '");';
          }

          load.source = "(function(require, exports, module, __filename, __dirname, global, GLOBAL) {" + globals
              + load.source + "\n}).apply(__cjsWrapper.exports, __cjsWrapper.args);";

          __exec.call(loader, load);

          __global.__cjsWrapper = undefined;
          __global.define = define;
        };
      }

      return instantiate.call(loader, load);
    };
  });
})();
<commit_msg>ensure regex reset<commit_after>/*
  SystemJS CommonJS Format
*/
(function() {
  // CJS Module Format
  // require('...') || exports[''] = ... || exports.asd = ... || module.exports = ...
  var cjsExportsRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.]|module\.)exports\s*(\[['"]|\.)|(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF.])module\.exports\s*[=,]/;
  // RegEx adjusted from https://github.com/jbrantly/yabble/blob/master/lib/yabble.js#L339
  var cjsRequireRegEx = /(?:^\uFEFF?|[^$_a-zA-Z\xA0-\uFFFF."'])require\s*\(\s*("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')\s*\)/g;
  var commentRegEx = /(\/\*([\s\S]*?)\*\/|([^:]|^)\/\/(.*)$)/mg;

  function getCJSDeps(source) {
    cjsRequireRegEx.lastIndex = commentRegEx.lastIndex = 0;

    var deps = [];

    // track comments in the source
    var match;

    var commentLocations = [];
    if (source.length / source.split('\n').length < 200) {
      while (match = commentRegEx.exec(source))
        commentLocations.push([match.index, match.index + match[0].length]);
    }

    while (match = cjsRequireRegEx.exec(source)) {
      // ensure we're not in a comment location
      var inComment = false;
      for (var i = 0; i < commentLocations.length; i++) {
        if (commentLocations[i][0] < match.index && commentLocations[i][1] > match.index + match[0].length)
          inComment = true;
      }
      if (!inComment)
        deps.push(match[1].substr(1, match[1].length - 2));
    }

    return deps;
  }

  if (typeof window != 'undefined' && typeof document != 'undefined' && window.location)
    var windowOrigin = location.protocol + '//' + location.hostname + (location.port ? ':' + location.port : '');

  hookConstructor(function(constructor) {
    return function() {
      constructor.call(this);

      // include the node require since we're overriding it
      if (typeof require != 'undefined' && require.resolve && typeof process != 'undefined')
        this._nodeRequire = require;
    };
  });

  hook('normalize', function(normalize) {
    return function (name, parentName) {
      // dynamically load node-core modules when requiring `@node/fs` for example
      if (name.substr(0, 6) == '@node/') {
        if (!this._nodeRequire)
          throw new TypeError('Can only load node core modules in Node.');
        this.set(name, this.newModule(getESModule(this._nodeRequire(name.substr(6)))));
      }
      return normalize.call(this, name, parentName);
    };
  });

  hook('instantiate', function(instantiate) {
    return function(load) {
      var loader = this;
      if (!load.metadata.format) {
        cjsExportsRegEx.lastIndex = 0;
        cjsRequireRegEx.lastIndex = 0;
        if (cjsRequireRegEx.exec(load.source) || cjsExportsRegEx.exec(load.source))
          load.metadata.format = 'cjs';
      }

      if (load.metadata.format == 'cjs') {
        var metaDeps = load.metadata.deps || [];
        load.metadata.deps = metaDeps.concat(getCJSDeps(load.source));

        for (var g in load.metadata.globals)
          load.metadata.deps.push(load.metadata.globals[g]);

        load.metadata.executingRequire = true;

        load.metadata.execute = function(require, exports, module) {
          // ensure meta deps execute first
          for (var i = 0; i < metaDeps.length; i++)
            require(metaDeps[i]);
          var address = load.address || '';

          var dirname = address.split('/');
          dirname.pop();
          dirname = dirname.join('/');

          if (windowOrigin && address.substr(0, windowOrigin.length) === windowOrigin) {
            address = address.substr(windowOrigin.length);
            dirname = dirname.substr(windowOrigin.length);
          }
          else if (address.substr(0, 8) == 'file:///') {
            address = address.substr(7);
            dirname = dirname.substr(7);

            // on windows remove leading '/'
            if (isWindows) {
              address = address.substr(1);
              dirname = dirname.substr(1);
            }
          }

          // disable AMD detection
          var define = __global.define;
          __global.define = undefined;

          __global.__cjsWrapper = {
            exports: exports,
            args: [require, exports, module, address, dirname, __global, __global]
          };

          var globals = '';
          if (load.metadata.globals) {
            for (var g in load.metadata.globals)
              globals += 'var ' + g + ' = require("' + load.metadata.globals[g] + '");';
          }

          load.source = "(function(require, exports, module, __filename, __dirname, global, GLOBAL) {" + globals
              + load.source + "\n}).apply(__cjsWrapper.exports, __cjsWrapper.args);";

          __exec.call(loader, load);

          __global.__cjsWrapper = undefined;
          __global.define = define;
        };
      }

      return instantiate.call(loader, load);
    };
  });
})();
<|endoftext|>


<commit_before>/**
 * The MIT License (MIT)
 * Copyright (c) 2016 GochoMugo <mugo@forfuture.co.ke>
 * Copyright (c) 2016 Forfuture, LLC < we@forfuture.co.ke>
 *
 * CLI.
 */

exports = module.exports = {
    run,
};

// npm-installed modules
const program = require('commander');
const out = require('cli-output');

// own modules
const defaults = require('./defaults');
const main = require('./main');
const pkg = require('../package.json');

program
    .version(pkg.version)
    .option('-d, --source-dir <path>', `source directory [${defaults.sourceDir}]`)
    .option('-r, --remote-dir <path>', `remote directory [${defaults.remoteDir}]`)
    .option('-c, --config-path <path>', `path to config file [\${sourceDir}/${defaults.configfileName}]`)
    .option('-p, --profile <name>', `configuration profile to use [${defaults.profile}]`)
    .option('-H, --ftp-host <host>', 'FTP host')
    .option('-P, --ftp-port <port>', 'FTP port')
    .option('-U, --ftp-user <user>', 'FTP username')
    .option('-X, --ftp-pass <pass>', 'FTP password')
    .option('-s, --stop-on-error', `stop on error; [${defaults.skipDeletion}]`)
    .option('-j, --parallel <num>', `handle <num> directories at a time [${defaults.parallel}]`)
    .option('-k, --skip-deletion', `skip deleting remote files [${defaults.skipDeletion}]`)
    .option('-i, --ignore-filelist', `ignore file-list [${defaults.ignoreFilelist}]`)
    ;

function run() {
    program.parse(process.argv);

    return main({
        sourceDir: program.sourceDir,
        remoteDir: program.remoteDir,
        configPath: program.configPath,
        profile: program.profile,
        ftp: {
            host: program.ftpHost,
            port: program.ftpPort,
            user: program.ftpUser,
            pass: program.ftpPass,
        },
        stopOnError: program.stopOnError,
        parallel: program.parallel,
        skipDeletion: program.skipDeletion,
        ignoreFilelist: program.ignoreFilelist,
    })
    .on('DirDone', function(err, dirpath) {
        if (err) return out.error(`DirDone with Error: ${dirpath} :: ${err}`);
        return out.info(`DirDone: ${dirpath}`);
    })
    .on('ConfigError', function(err) {
        return out.error(`ConfigError: ${err}`);
    })
    .on('WalkerError', function(err) {
        return out.error(`WalkerError: ${err}`);
    })
    .on('FTPError', function(err) {
        return out.error(`FTPError: ${err}`);
    })
    .on('Exit', function(err) {
        return out.info(`Exit :: ${err}`);
    })
    ;
}
<commit_msg>[cli] Update help information<commit_after>/**
 * The MIT License (MIT)
 * Copyright (c) 2016 GochoMugo <mugo@forfuture.co.ke>
 * Copyright (c) 2016 Forfuture, LLC < we@forfuture.co.ke>
 *
 * CLI.
 */

exports = module.exports = {
    run,
};

// npm-installed modules
const program = require('commander');
const out = require('cli-output');

// own modules
const defaults = require('./defaults');
const main = require('./main');
const pkg = require('../package.json');

program
    .version(pkg.version)
    .option('-d, --source-dir <path>', `source directory [${defaults.sourceDir}]`)
    .option('-r, --remote-dir <path>', `remote directory [${defaults.remoteDir}]`)
    .option('-c, --config-path <path>', `path to config file [\${sourceDir}/${defaults.configfileName}]`)
    .option('-p, --profile <name>', `configuration profile to use [${defaults.profile}]`)
    .option('-H, --ftp-host <host>', 'FTP host')
    .option('-P, --ftp-port <port>', `FTP port [${defaults.ftp.port}]`)
    .option('-U, --ftp-user <user>', `FTP username [${defaults.ftp.user}]`)
    .option('-X, --ftp-pass <pass>', `FTP password [${defaults.ftp.pass}]`)
    .option('-s, --stop-on-error', `stop on error [${defaults.skipDeletion}]`)
    .option('-j, --parallel <num>', `handle <num> directories at a time [${defaults.parallel}]`)
    .option('-k, --skip-deletion', `skip deleting remote files [${defaults.skipDeletion}]`)
    .option('-i, --ignore-filelist', `ignore file-list [${defaults.ignoreFilelist}]`)
    ;

function run() {
    program.parse(process.argv);

    return main({
        sourceDir: program.sourceDir,
        remoteDir: program.remoteDir,
        configPath: program.configPath,
        profile: program.profile,
        ftp: {
            host: program.ftpHost,
            port: program.ftpPort,
            user: program.ftpUser,
            pass: program.ftpPass,
        },
        stopOnError: program.stopOnError,
        parallel: program.parallel,
        skipDeletion: program.skipDeletion,
        ignoreFilelist: program.ignoreFilelist,
    })
    .on('DirDone', function(err, dirpath) {
        if (err) return out.error(`DirDone with Error: ${dirpath} :: ${err}`);
        return out.info(`DirDone: ${dirpath}`);
    })
    .on('ConfigError', function(err) {
        return out.error(`ConfigError: ${err}`);
    })
    .on('WalkerError', function(err) {
        return out.error(`WalkerError: ${err}`);
    })
    .on('FTPError', function(err) {
        return out.error(`FTPError: ${err}`);
    })
    .on('Exit', function(err) {
        return out.info(`Exit :: ${err}`);
    })
    ;
}
<|endoftext|>


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

'use strict';

var LogFind = require( './logfind.js' );
var pkg = require( '../package.json' );
var meow = require( 'meow' );

// Configure CLI
var cli = meow( {
	help: [
		'Usage:',
		'  logfind <string|regex>'
	],
	flags: {
		'o': false,
	},
	pkg: pkg
} );

// Store CLI input
var opts = cli.flags;
var args = cli.input;

// Find the files.
var logFinder = new LogFind();
var foundFiles = logFinder.find( cli.flags, cli.input );

// Report results.
if ( foundFiles.length > 0 ) {
	console.log( '\nFound in: ' );
	console.log( '------------------------------------' );
	console.log( foundFiles.map( function ( file ) {
			return '  ' + file;
		} )
		.join( '\n' ) );
} else {
	console.log( 'No results.' );
}
<commit_msg>move cli portion into an iife<commit_after>#!/usr/bin/env node
'use strict';

(function() {

	var LogFind = require( './logfind.js' );
	var pkg = require( '../package.json' );
	var meow = require( 'meow' );

	// Configure CLI
	var cli = meow( {
		help: [
			'Usage:',
			'  logfind <string|regex>'
		],
		flags: {
			'o': false,
		},
		pkg: pkg
	} );

	// Store CLI input
	var opts = cli.flags;
	var args = cli.input;

	// Find the files.
	var logFinder = new LogFind();
	var foundFiles = logFinder.find( cli.flags, cli.input );

	// Report results.
	if ( foundFiles.length > 0 ) {
		console.log( '\nFound in: ' );
		console.log( '------------------------------------' );
		console.log( foundFiles.map( function ( file ) {
				return '  ' + file;
			} )
			.join( '\n' ) );
	} else {
		console.log( 'No results.' );
	}

}());
<|endoftext|>


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

var program = require('commander');

program
	.version('0.0.1')
	.option('-s, --selenium <serverURL>', 'Specify Selenium Server, like localhost:4444 or ondemand.saucelabs.com:80')
	.option('-v --verbose')
	.option('-u --username <username>', 'Sauce, BrowserStack or Selenium User Name')
	.option('-a --accesskey <accesskey>', 'Sauce, BrowserStack or Selenium Access Key')
	.option('-d --debug', 'Enable debug mode, keep the browser alive even after the tests', false)
	.option('-c --config-file <configFile>', 'Specify a configuration file. If other options are specified, they have precedence over options in config file')
	.option('-o --output <output>', 'Format of output [table|json], defaults to table')
	.option('--prescript-file <preScriptFile>', 'Prescript node module to run (for login, etc) before the tests. Module should be module.exports = function(browser, callback){}')
	.option('-b --browsers <list of browsers>', 'Browsers to run the test on', function(val) {
		return val.split(',');
	})
	.parse(process.argv);

var log = {
	'fatal': console.error.bind(console),
	'error': console.error.bind(console),
	'warn': console.warn.bind(console),
	'info': console.info.bind(console),
	'debug': console.log.bind(console),
	'trace': console.trace.bind(console),
}

var url = program.args[0];
if (!url) {
	log.error('Please specify a URL to run');
	return;
}
program.output = program.output || 'table';
require('./index.js')(url, function(err, data) {
	if (err) {
		log.error(err);
	} else {
		if (program.output === 'table') {
			log.info(generateTable(data));
		} else {
			log.info(data);
		}
	}
}, {
	browsers: program.browsers,
	selenium: program.selenium,
	username: program.username,
	accesskey: program.accesskey,
	debug: program.debug,
	configFile: program.configFile,
	logger: (function(log) {
		log.trace = function() {}
		if (!program.verbose) {
			log.debug = log.trace;
		}
		return log;
	}(log)),
	preScriptFile: program.prescriptFile
});

function generateTable(data) {
	var cliTable = require('cli-table'),
		res = [];
	for (var i = 0; i < data.length; i++) {
		res.push('\n\nBrowser: ', data[i]._browserName + '\n');
		var table = new cliTable({
			head: ['Metrics', 'Value', 'Unit', 'Source'],
			colAligns: ['right', 'left'],
			colWidths: [35, 20, 10, 20]
		});
		for (var key in data[i]) {
			if (key.indexOf('_') === 0)
				continue;
			var val = data[i][key];
			table.push([key, val.value + '', val.unit + '', val.source + '']);
		}
		table = table.sort(function(a, b) {
			return a[0] > b[0] ? 1 : -1;
		});
		res.push(table.toString());
	}
	debugger;
	return res.join('');
}<commit_msg>(fix): Removed debugger from CLI<commit_after>#!/usr/bin/env node

var program = require('commander');

program
	.version('0.0.1')
	.option('-s, --selenium <serverURL>', 'Specify Selenium Server, like localhost:4444 or ondemand.saucelabs.com:80')
	.option('-v --verbose')
	.option('-u --username <username>', 'Sauce, BrowserStack or Selenium User Name')
	.option('-a --accesskey <accesskey>', 'Sauce, BrowserStack or Selenium Access Key')
	.option('-d --debug', 'Enable debug mode, keep the browser alive even after the tests', false)
	.option('-c --config-file <configFile>', 'Specify a configuration file. If other options are specified, they have precedence over options in config file')
	.option('-o --output <output>', 'Format of output [table|json], defaults to table')
	.option('--prescript-file <preScriptFile>', 'Prescript node module to run (for login, etc) before the tests. Module should be module.exports = function(browser, callback){}')
	.option('-b --browsers <list of browsers>', 'Browsers to run the test on', function(val) {
		return val.split(',');
	})
	.parse(process.argv);

var log = {
	'fatal': console.error.bind(console),
	'error': console.error.bind(console),
	'warn': console.warn.bind(console),
	'info': console.info.bind(console),
	'debug': console.log.bind(console),
	'trace': console.trace.bind(console),
}

var url = program.args[0];
if (!url) {
	log.error('Please specify a URL to run');
	return;
}
program.output = program.output || 'table';
require('./index.js')(url, function(err, data) {
	if (err) {
		log.error(err);
	} else {
		if (program.output === 'table') {
			log.info(generateTable(data));
		} else {
			log.info(data);
		}
	}
}, {
	browsers: program.browsers,
	selenium: program.selenium,
	username: program.username,
	accesskey: program.accesskey,
	debug: program.debug,
	configFile: program.configFile,
	logger: (function(log) {
		log.trace = function() {}
		if (!program.verbose) {
			log.debug = log.trace;
		}
		return log;
	}(log)),
	preScriptFile: program.prescriptFile
});

function generateTable(data) {
	var cliTable = require('cli-table'),
		res = [];
	for (var i = 0; i < data.length; i++) {
		res.push('\n\nBrowser: ', data[i]._browserName + '\n');
		var table = new cliTable({
			head: ['Metrics', 'Value', 'Unit', 'Source'],
			colAligns: ['right', 'left'],
			colWidths: [35, 20, 10, 20]
		});
		for (var key in data[i]) {
			if (key.indexOf('_') === 0)
				continue;
			var val = data[i][key];
			table.push([key, val.value + '', val.unit + '', val.source + '']);
		}
		table = table.sort(function(a, b) {
			return a[0] > b[0] ? 1 : -1;
		});
		res.push(table.toString());
	}
	return res.join('');
}<|endoftext|>


<commit_before>var path = require('path');

module.exports = {debugFunction: debug}
process.stdin.setEncoding('utf8');
var prompts = require('./prompts');
var debugSupport = true;

function parseArgs(args) {
  var options = {}

  for (var i = 0; i < args.length; i++) {
    switch (args[i]) {
      case "--generatorPath":
      {
        options.generatorPath = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--generatorName":
      {
        options.generatorName = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--yeoman":
      {
        options.yeoman = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--arguments":
      {
        options.arguments = (++i < args.length) ? args[i].split(' ') : null;
        break;
      }
      case "--plain":
      {
        options.plain = true;
        break;
      }
      default: //do nothing
    }
  }

  return options;
}

var options = parseArgs(process.argv.slice(2));

var prefix = (options.yeoman ? options.yeoman + path.sep + 'node_modules' + path.sep : '');
var inquirer = require(prefix + 'inquirer');
var yeomanEnv = require(prefix + 'yeoman-environment');

var env = yeomanEnv.createEnv(options.arguments, null, new Adapter);

//will works without hacks in the next versions
var callbackDone = function () {
  debug('done run generator');
}

var cwd = process.cwd();
if (options.generatorPath) {
  process.chdir(options.generatorPath);
  //env.register(options.generatorPath, 'angular:app');
  debug('invoke run');
  //env.run('angular:app', callbackDone);
  env.lookup(function () {
    debug('invoke run');
    process.chdir(cwd);
    env.run(options.generatorName, null, callbackDone);
  });
} else if (options.generatorName) {
  env.lookup(function () {
    debug('invoke run');
    env.run(options.generatorName, null, callbackDone);
  });
} else {
  throw new Error("You should specify generatorName or generatorPath");
}
/**
 * @constructor
 */
function Adapter() {
  debug('adapter create');
  this.prompt = inquirer.createPromptModule();

  Object.keys(this.prompt.prompts).forEach(function (name) {
    this.prompt.registerPrompt(name, Prompt.bind(null, prompts.handlers[name] || prompts.defaultHandler));
  }, this);

  this.log = yeomanEnv.util.log();

}

/**
 * @constructor
 */
function Prompt(getResultFunction, question, rl, answers) {
  this.question = question;
  this.rl = rl;
  this.answers = answers;

  this.run = function (callback) {
    printMessage(question);

    var listener = function (line) {
      callback(getResultFunction(question, line));
      rl.removeListener('line', listener);
    };

    rl.on('line', listener);

  }

  return this;
}

function printMessage(questionWithAnswers) {
  if (options.plain) {
    //print plain text
    process.stdout.write(questionWithAnswers.message + '\n');
    if (questionWithAnswers.choices) {
      var index = 0;
      questionWithAnswers.choices.forEach(function (v) {
        if (v instanceof String) {
          process.stdout.write('' + (index++) + ' ' + v + '\n')
        } else {
          process.stdout.write('' + (index++) + ' ' + (v.name || v.value) + (v.checked ? ' x' : '') + '\n');
        }
      });
    }
  } else {
    var stringAnswers = JSON.stringify(questionWithAnswers);
    debug(stringAnswers);
    process.stdout.write(stringAnswers + '\n');
  }
}

function debug(v) {
  if (debugSupport) console.log('--debug ' + v);
}
<commit_msg>options list<commit_after>var path = require('path');

module.exports = {debugFunction: debug}
process.stdin.setEncoding('utf8');
var prompts = require('./prompts');
var debugSupport = true;
function parseArgs(args) {
  if (!args || args.length == 0) {
    console.log('Possible options:');
    console.log('--generatorName NAME - name with namespace of the generator (Required)');
    console.log('--generatorPath PATH - path to generator folder');
    console.log('--yeoman PATH - path to yeoman nodejs package');
    console.log('--plain - by default output uses json format. If you want to use plain string specify the parameter');
    process.exit(0);
  }

  var options = {}

  for (var i = 0; i < args.length; i++) {
    switch (args[i]) {
      case "--generatorPath":
      {
        options.generatorPath = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--generatorName":
      {
        options.generatorName = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--yeoman":
      {
        options.yeoman = (++i < args.length) ? args[i] : null;
        break;
      }
      case "--arguments":
      {
        options.arguments = (++i < args.length) ? args[i].split(' ') : null;
        break;
      }
      case "--plain":
      {
        options.plain = true;
        break;
      }
      default: //do nothing
    }
  }

  return options;
}

var options = parseArgs(process.argv.slice(2));

var prefix = (options.yeoman ? options.yeoman + path.sep + 'node_modules' + path.sep : '');
var inquirer = require(prefix + 'inquirer');
var yeomanEnv = require(prefix + 'yeoman-environment');

var env = yeomanEnv.createEnv(options.arguments, null, new Adapter);

//will works without hacks in the next versions
var callbackDone = function () {
  debug('done run generator');
}

var cwd = process.cwd();
if (options.generatorPath) {
  process.chdir(options.generatorPath);
  //env.register(options.generatorPath, 'angular:app');
  debug('invoke run');
  //env.run('angular:app', callbackDone);
  env.lookup(function () {
    debug('invoke run');
    process.chdir(cwd);
    env.run(options.generatorName, null, callbackDone);
  });
} else if (options.generatorName) {
  env.lookup(function () {
    debug('invoke run');
    env.run(options.generatorName, null, callbackDone);
  });
} else {
  throw new Error("You should specify generatorName");
}
/**
 * @constructor
 */
function Adapter() {
  debug('adapter create');
  this.prompt = inquirer.createPromptModule();

  Object.keys(this.prompt.prompts).forEach(function (name) {
    this.prompt.registerPrompt(name, Prompt.bind(null, prompts.handlers[name] || prompts.defaultHandler));
  }, this);

  this.log = yeomanEnv.util.log();

}

/**
 * @constructor
 */
function Prompt(getResultFunction, question, rl, answers) {
  this.question = question;
  this.rl = rl;
  this.answers = answers;

  this.run = function (callback) {
    printMessage(question);

    var listener = function (line) {
      callback(getResultFunction(question, line));
      rl.removeListener('line', listener);
    };

    rl.on('line', listener);

  }

  return this;
}

function printMessage(questionWithAnswers) {
  if (options.plain) {
    //print plain text
    process.stdout.write(questionWithAnswers.message + '\n');
    if (questionWithAnswers.choices) {
      var index = 0;
      questionWithAnswers.choices.forEach(function (v) {
        if (v instanceof String) {
          process.stdout.write('' + (index++) + ' ' + v + '\n')
        } else {
          process.stdout.write('' + (index++) + ' ' + (v.name || v.value) + (v.checked ? ' x' : '') + '\n');
        }
      });
    }
  } else {
    var stringAnswers = JSON.stringify(questionWithAnswers);
    debug(stringAnswers);
    process.stdout.write(stringAnswers + '\n');
  }
}

function debug(v) {
  if (debugSupport) console.log('--debug ' + v);
}
<|endoftext|>


<commit_before>/**
 * Cross-Origin requests for IE 8—9
 * Uses iframe and Cross Document Messaging
 */
define(function() {

    var processing = {};

    function guid() {
        return +new Date() + '' + Math.ceil(Math.random() * 10000);
    }

    function getCORURI(request, options) {
        // TODO: always ssl
        var uri = request.uri,
            host,
            scheme = '',
            cor = '',
            _;

        _ = uri.split('//');

        if (_.length > 1) {
            if (_[0].substr(_[0].length - 1)  === ':') {
                scheme = _[0];
            }

            _ = _[1].split('/');
            host = _[0];
        }

        if (host) {
            cor = scheme + '//' + host
        }

        cor += options.cor;

        return cor;
    }

    function getProxy(uri, callback) {
        if (!getProxy.mems) {
            getProxy.mems = {};
        }

        if (getProxy.mems[uri]) {
            callback(getProxy.mems[uri]);
            return;
        }

        var div = document.createElement('div'),
            id = 'i' + guid(),
            onload = 'f' + guid();

        div.style.width = div.style.height = '0px';
        div.style.visibility = div.style.overflow = 'hidden';
        div.innerHTML = '<iframe id="' + id + '" src="' + uri + '" style="" onload="' + onload + '()" />';

        window[onload] = function() {
            getProxy.mems[uri] = document.getElementById(id).contentWindow;
            callback(getProxy.mems[uri]);
        };

        document.body.appendChild(div);
    }

    function handle(e) {
        e = e || event;

        var message,
            xhr;

        try {
            message = JSON.parse(e.data);
        } catch (e) {
            return;
        }

        if (message.type !== 'cor'
            || !processing[message.id]) {

            return;
        }

        xhr = processing[message.id];
        processing[message.id] = undefined;
        delete processing[message.id];

        xhr.status = message.status;
        xhr.responseText = message.response;
        xhr.headers = message.headers;

        message.status
            ? xhr.onload()
            : xhr.onerror({});
    }

    function send(request, options, xhr) {
        var uri = getCORURI(request, options),
            id = guid();

        processing[id] = xhr;

        getProxy(uri, function(proxy) {
            proxy.postMessage(JSON.stringify({
                id: id,
                req: request
            }), '*');
        });
    }

    window.onmessage = handle;

    return function(options) {

        var request = { headers: {} };

        this.headers = {};
        this.onload = null;
        this.onerror = null;
        this.withCredentials = false;

        this.open = function(method, uri) {
            request.method = method;
            request.uri = uri;
        };

        this.setRequestHeader = function(name, value) {
            request.headers[name] = value;
        };

        this.getResponseHeader = function(name) {
            return this.headers[name.toLowerCase()];
        };

        this.send = function(body) {
            request.body = body;

            send(request, options, this);
        };

    }

});<commit_msg>Corrected loading of root of site in iframe when COR-iframe created (actual for IE9).<commit_after>/**
 * Cross-Origin requests for IE 8—9
 * Uses iframe and Cross Document Messaging
 */
define(function() {

    var processing = {};

    function guid() {
        return +new Date() + '' + Math.ceil(Math.random() * 10000);
    }

    function getCORURI(request, options) {
        // TODO: always ssl
        var uri = request.uri,
            host,
            scheme = '',
            cor = '',
            _;

        _ = uri.split('//');

        if (_.length > 1) {
            if (_[0].substr(_[0].length - 1)  === ':') {
                scheme = _[0];
            }

            _ = _[1].split('/');
            host = _[0];
        }

        if (host) {
            cor = scheme + '//' + host
        }

        cor += options.cor;

        return cor;
    }

    function getProxy(uri, callback) {
        if (!getProxy.mems) {
            getProxy.mems = {};
        }

        if (getProxy.mems[uri]) {
            callback(getProxy.mems[uri]);
            return;
        }

        var div = document.createElement('div'),
            id = 'i' + guid(),
            onload = 'f' + guid();

        div.style.width = div.style.height = '0px';
        div.style.visibility = div.style.overflow = 'hidden';
        div.innerHTML = '<iframe id="' + id + '" style="" onload="' + onload + '()" />';
	document.getElementById(id).src = uri;

        window[onload] = function() {
            getProxy.mems[uri] = document.getElementById(id).contentWindow;
            callback(getProxy.mems[uri]);
        };

        document.body.appendChild(div);
    }

    function handle(e) {
        e = e || event;

        var message,
            xhr;

        try {
            message = JSON.parse(e.data);
        } catch (e) {
            return;
        }

        if (message.type !== 'cor'
            || !processing[message.id]) {

            return;
        }

        xhr = processing[message.id];
        processing[message.id] = undefined;
        delete processing[message.id];

        xhr.status = message.status;
        xhr.responseText = message.response;
        xhr.headers = message.headers;

        message.status
            ? xhr.onload()
            : xhr.onerror({});
    }

    function send(request, options, xhr) {
        var uri = getCORURI(request, options),
            id = guid();

        processing[id] = xhr;

        getProxy(uri, function(proxy) {
            proxy.postMessage(JSON.stringify({
                id: id,
                req: request
            }), '*');
        });
    }

    window.onmessage = handle;

    return function(options) {

        var request = { headers: {} };

        this.headers = {};
        this.onload = null;
        this.onerror = null;
        this.withCredentials = false;

        this.open = function(method, uri) {
            request.method = method;
            request.uri = uri;
        };

        this.setRequestHeader = function(name, value) {
            request.headers[name] = value;
        };

        this.getResponseHeader = function(name) {
            return this.headers[name.toLowerCase()];
        };

        this.send = function(body) {
            request.body = body;

            send(request, options, this);
        };

    }

});<|endoftext|>


<commit_before>/* сжимаем код через clean-css */
(function(){
    'use strict';

    var check       = require('checkup'),
        exec        = require('execon'),
        Clean       = require('clean-css'),

        ErrorMsg    = Error([
            'can\'t load clean-css',
            'npm install clean-css',
            'https://github.com/GoalSmashers/clean-css'].join('\n'));

    /**
     * minify css data.
     *
     * @param data
     * @param callback
     */
    module.exports = function(data, callback){
        var error, errorParse, dataOptimized;

        check(arguments, ['data', 'callback']);

        if (!Clean)
            error   = ErrorMsg;
        else
            error   = exec.try(function() {
                var min         = new Clean().minify(data);
                dataOptimized   = min.styles;
                errorParse      = min.error[0];
            });

        callback(error || errorParse, dataOptimized);
    };
})();
<commit_msg>fix(css) error -> errors<commit_after>/* сжимаем код через clean-css */
(function(){
    'use strict';

    var check       = require('checkup'),
        exec        = require('execon'),
        Clean       = require('clean-css'),

        ErrorMsg    = Error([
            'can\'t load clean-css',
            'npm install clean-css',
            'https://github.com/GoalSmashers/clean-css'].join('\n'));

    /**
     * minify css data.
     *
     * @param data
     * @param callback
     */
    module.exports = function(data, callback){
        var error, errorParse, dataOptimized;

        check(arguments, ['data', 'callback']);

        if (!Clean)
            error   = ErrorMsg;
        else
            error   = exec.try(function() {
                var min         = new Clean().minify(data);
                dataOptimized   = min.styles;
                errorParse      = min.errors[0];
            });

        callback(error || errorParse, dataOptimized);
    };
})();
<|endoftext|>


<commit_before>import {reduce} from 'lodash';
import LineToLineMappedSource from 'webpack-core/lib/LineToLineMappedSource';

export default function(transform) {
  return function() {
    this.plugin('compilation', function(compilation) {
      compilation.plugin('optimize-chunk-assets', function(chunks, callback) {
        compilation.assets = reduce(compilation.assets, (assets, asset, name) => {
          if (/\.css$/.test(name)) {
            var source = asset.source();
            assets[name] = new LineToLineMappedSource(transform(source), name, source);
          }

          return assets;
        }, compilation.assets);

        callback();
      });
    });
  }
}
<commit_msg>use correct plugin mapper<commit_after>import {reduce} from 'lodash';
import SourceMapSource from 'webpack-core/lib/SourceMapSource';

export default function(transform) {
  return function() {
    this.plugin('compilation', function(compilation) {
      compilation.plugin('optimize-chunk-assets', function(chunks, callback) {
        compilation.assets = reduce(compilation.assets, (assets, asset, name) => {
          if (/\.css$/.test(name)) {
            var source = asset.source();
            assets[name] = new SourceMapSource(transform(source), name, asset.map(), source);
          }

          return assets;
        }, compilation.assets);

        callback();
      });
    });
  }
}
<|endoftext|>


<commit_before>var Utils        = require("./utils")
  , Mixin        = require("./associations/mixin")
  , DaoValidator = require("./dao-validator")
  , DataTypes    = require("./data-types")
  , hstore       = require('./dialects/postgres/hstore')

module.exports = (function() {
  var DAO = function(values, options, isNewRecord) {
    this.dataValues                  = {}
    this.__options                   = options
    this.hasPrimaryKeys              = options.hasPrimaryKeys
    this.selectedValues              = values
    this.__eagerlyLoadedAssociations = []

    initAttributes.call(this, values, isNewRecord)
  }

  Utils._.extend(DAO.prototype, Mixin.prototype)

  Object.defineProperty(DAO.prototype, 'sequelize', {
    get: function(){ return this.__factory.daoFactoryManager.sequelize }
  })

  Object.defineProperty(DAO.prototype, 'QueryInterface', {
    get: function(){ return this.sequelize.getQueryInterface() }
  })

  Object.defineProperty(DAO.prototype, 'isDeleted', {
    get: function() {
      var result = this.__options.timestamps && this.__options.paranoid
      result = result && this.dataValues[this.__options.underscored ? 'deleted_at' : 'deletedAt'] !== null

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'values', {
    get: function() {
      var result = {}
        , self   = this

      this.attributes.concat(this.__eagerlyLoadedAssociations).forEach(function(attr) {
        result[attr] = self.dataValues.hasOwnProperty(attr)
                     ? self.dataValues[attr]
                     : self[attr]
                     ;
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'primaryKeyValues', {
    get: function() {
      var result = {}
        , self   = this

      Utils._.each(this.__factory.primaryKeys, function(_, attr) {
        result[attr] = self.dataValues[attr]
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, "identifiers", {
    get: function() {
      var primaryKeys = Object.keys(this.__factory.primaryKeys)
        , result      = {}
        , self        = this

      if (!this.__factory.hasPrimaryKeys) {
        primaryKeys = ['id']
      }

      primaryKeys.forEach(function(identifier) {
        result[identifier] = self.dataValues[identifier]
      })

      return result
    }
  })

  DAO.prototype.getDataValue = function(name) {
    return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
  }

  DAO.prototype.setDataValue = function(name, value) {
    this.dataValues[name] = value
  }

  // if an array with field names is passed to save()
  // only those fields will be updated
  DAO.prototype.save = function(fields) {
    var self          = this
      , values        = fields ? {} : this.dataValues
      , updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt'
      , createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt'

    if (fields) {
      if (self.__options.timestamps) {
        if (fields.indexOf(updatedAtAttr) === -1) {
          fields.push(updatedAtAttr)
        }

        if (fields.indexOf(createdAtAttr) === -1) {
          fields.push(createdAtAttr)
        }
      }

      var tmpVals = self.dataValues

      fields.forEach(function(field) {
        if (tmpVals[field] !== undefined) {
          values[field] = tmpVals[field]
        }
      })
    }

    for (var attrName in this.daoFactory.rawAttributes) {
      if (this.daoFactory.rawAttributes.hasOwnProperty(attrName)) {
        var definition      = this.daoFactory.rawAttributes[attrName]
          , isEnum          = (definition.type && (definition.type.toString() === DataTypes.ENUM.toString()))
          , isHstore        = (!!definition.type && !!definition.type.type && definition.type.type === DataTypes.HSTORE.type)
          , hasValue        = (typeof values[attrName] !== 'undefined')
          , valueOutOfScope = ((definition.values || []).indexOf(values[attrName]) === -1)

        if (isEnum && hasValue && valueOutOfScope) {
          throw new Error('Value "' + values[attrName] + '" for ENUM ' + attrName + ' is out of allowed scope. Allowed values: ' + definition.values.join(', '))
        }

        if (isHstore) {
          if (typeof values[attrName] === "object") {
            values[attrName] = hstore.stringify(values[attrName])
          }
        }
      }
    }

    if (this.__options.timestamps && this.dataValues.hasOwnProperty(updatedAtAttr)) {
      this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now(this.sequelize.options.dialect)
    }

    var errors = this.validate()

    if (!!errors) {
      return new Utils.CustomEventEmitter(function(emitter) {
        emitter.emit('error', errors)
      }).run()
    }
    else if (this.isNewRecord) {
      return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values)
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id };

      if (identifier === null && this.__options.whereCollection !== null) {
        identifier = this.__options.whereCollection;
      }

      var tableName  = this.QueryInterface.QueryGenerator.addSchema(this.__factory)
        , query      = this.QueryInterface.update(this, tableName, values, identifier)

      return query
    }
  }

 /*
  * Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
  * This is different from doing a `find(DAO.id)`, because that would create and return a new object. With this method,
  * all references to the DAO are updated with the new data and no new objects are created.
  *
  * @return {Object}         A promise which fires `success`, `error`, `complete` and `sql`.
  */
  DAO.prototype.reload = function() {
    var where = [
      this.QueryInterface.quoteIdentifier(this.__factory.tableName) + '.' + this.QueryInterface.quoteIdentifier('id')+'=?',
      this.id
    ]

    return new Utils.CustomEventEmitter(function(emitter) {
      this.__factory.find({
        where:   where,
        limit:   1,
        include: this.__eagerlyLoadedOptions || []
      })
      .on('sql', function(sql) { emitter.emit('sql', sql) })
      .on('error', function(error) { emitter.emit('error', error) })
      .on('success', function(obj) {
        for (var valueName in obj.values) {
          if (obj.values.hasOwnProperty(valueName)) {
            this[valueName] = obj.values[valueName]
          }
        }
        emitter.emit('success', this)
      }.bind(this))
    }.bind(this)).run()
  }

  /*
   * Validate this dao's attribute values according to validation rules set in the dao definition.
   *
   * @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
   */
  DAO.prototype.validate = function() {
    var validator = new DaoValidator(this)
      , errors    = validator.validate()

    return (Utils._.isEmpty(errors) ? null : errors)
  }

  DAO.prototype.updateAttributes = function(updates, fields) {
    this.setAttributes(updates)
    return this.save(fields)
  }

  DAO.prototype.setAttributes = function(updates) {
    var self = this

    var readOnlyAttributes = Object.keys(this.__factory.primaryKeys)

    readOnlyAttributes.push('id')
    readOnlyAttributes.push('createdAt')
    readOnlyAttributes.push('updatedAt')
    readOnlyAttributes.push('deletedAt')

    Utils._.each(updates, function(value, attr) {
      var updateAllowed = (
        (readOnlyAttributes.indexOf(attr) == -1) &&
        (readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) &&
        (self.attributes.indexOf(attr) > -1)
      )
      updateAllowed && (self[attr] = value)
    })
  }

  DAO.prototype.destroy = function() {
    if (this.__options.timestamps && this.__options.paranoid) {
      var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt'
      this.dataValues[attr] = new Date()
      return this.save()
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id };
      return this.QueryInterface.delete(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), identifier)
    }
  }

  DAO.prototype.increment = function(fields, count) {
    var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id },
      values = {}

    if (count === undefined) {
      count = 1;
    }

    if (Utils._.isString(fields)) {
      values[fields] = count;
    } else if (Utils._.isArray(fields)) {
      Utils._.each(fields, function (field) {
        values[field] = count
      })
    } else { // Assume fields is key-value pairs
      values = fields;
    }

    return this.QueryInterface.increment(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), values, identifier)
  }

  DAO.prototype.decrement = function (fields, count) {
    if (!Utils._.isString(fields) && !Utils._.isArray(fields)) { // Assume fields is key-value pairs
      Utils._.each(fields, function (value, field) {
        fields[field] = -value;
      });
    }

    return this.increment(fields, 0 - count);
  }

  DAO.prototype.equals = function(other) {
    var result = true

    Utils._.each(this.dataValues, function(value, key) {
      if(Utils._.isDate(value) && Utils._.isDate(other[key])) {
        result = result && (value.getTime() == other[key].getTime())
      } else {
        result = result && (value == other[key])
      }
    })

    return result
  }

  DAO.prototype.equalsOneOf = function(others) {
    var result = false
      , self   = this

    others.forEach(function(other) { result = result || self.equals(other) })

    return result
  }

  DAO.prototype.addAttribute = function(attribute, value) {
    if (typeof this.dataValues[attribute] !== 'undefined') {
      return
    }

    if (this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1 && value !== undefined) { // transform integer 0,1 into boolean
      value = !!value
    }

    var has = (function(o) {
      var predef = Object.getOwnPropertyDescriptor(o, attribute);

      if (predef && predef.hasOwnProperty('value')) {
        return true // true here means 'this property exist as a simple value property, do not place setters or getters at all'
      }

      return {
        get: (predef && predef.hasOwnProperty('get') ? predef.get : null) || o.__lookupGetter__(attribute),
        set: (predef && predef.hasOwnProperty('set') ? predef.set : null) || o.__lookupSetter__(attribute)
      };
    })(this);

    // @ node-v0.8.19:
    //    calling __defineGetter__ destroys any previously defined setters for the attribute in
    //    question *if* that property setter was defined on the object's prototype (which is what
    //    we do in dao-factory) ... therefore we need to [re]define both the setter and getter
    //    here with either the function that already existed OR the default/automatic definition
    //
    //    (the same is true for __defineSetter and 'prototype' getters)
    if (has !== true) {
      this.__defineGetter__(attribute, has.get || function()  { return this.dataValues[attribute]; });
      this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v;    });
    }

    this[attribute] = value;
  }

  DAO.prototype.setValidators = function(attribute, validators) {
    this.validators[attribute] = validators
  }

  DAO.prototype.toJSON = function() {
    return this.values;
  }

  // private

  var initAttributes = function(values, isNewRecord) {
    // set id to null if not passed as value, a newly created dao has no id
    var defaults = this.hasPrimaryKeys ? {} : { id: null },
        attrs    = {},
        key;

    // add all passed values to the dao and store the attribute names in this.attributes
    for (key in values) {
      if (values.hasOwnProperty(key)) {
        this.addAttribute(key, values[key])
      }
    }

    if (isNewRecord) {
      if (this.hasDefaultValues) {
        Utils._.each(this.defaultValues, function(valueFn, key) {
          if (!defaults.hasOwnProperty(key)) {
            defaults[key] = valueFn()
          }
        })
      }

      if (this.__options.timestamps) {
        defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now(this.sequelize.options.dialect)
        defaults[this.__options.underscored ? 'updated_at' : 'updatedAt'] = Utils.now(this.sequelize.options.dialect)

        if (this.__options.paranoid) {
          defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null
        }
      }
    }

    if (Utils._.size(defaults)) {
      for (key in defaults) {
        attrs[key] = Utils.toDefaultValue(defaults[key])
      }
    }

    Utils._.each(this.attributes, function(key) {
      if (!attrs.hasOwnProperty(key)) {
        attrs[key] = undefined
      }
    })

    if (values) {
      for (key in values) {
        if (values.hasOwnProperty(key)) {
          attrs[key] = values[key]
        }
      }
    }

    for (key in attrs) {
      this.addAttribute(key, attrs[key])
    }
  }

  return DAO
})()
<commit_msg>remove bogus sanity check - when adding an attribute (i.e. defining the data property in terms of getters and setters, we should not care about whether the relevant underlying dataValue is already set or not - previously added/initialized properties may have setters that set the dataValue of the attribute currently being added/initialized (e.g. the setter of a "name" property that also sets the dataValue for the "slug" property, when the "slug" property is defined after the "name" property, in the model,and the bogus sanity check in place the "slug" property does not get its setters/getters defined ... thereby breaking the model!)<commit_after>var Utils        = require("./utils")
  , Mixin        = require("./associations/mixin")
  , DaoValidator = require("./dao-validator")
  , DataTypes    = require("./data-types")
  , hstore       = require('./dialects/postgres/hstore')

module.exports = (function() {
  var DAO = function(values, options, isNewRecord) {
    this.dataValues                  = {}
    this.__options                   = options
    this.hasPrimaryKeys              = options.hasPrimaryKeys
    this.selectedValues              = values
    this.__eagerlyLoadedAssociations = []

    initAttributes.call(this, values, isNewRecord)
  }

  Utils._.extend(DAO.prototype, Mixin.prototype)

  Object.defineProperty(DAO.prototype, 'sequelize', {
    get: function(){ return this.__factory.daoFactoryManager.sequelize }
  })

  Object.defineProperty(DAO.prototype, 'QueryInterface', {
    get: function(){ return this.sequelize.getQueryInterface() }
  })

  Object.defineProperty(DAO.prototype, 'isDeleted', {
    get: function() {
      var result = this.__options.timestamps && this.__options.paranoid
      result = result && this.dataValues[this.__options.underscored ? 'deleted_at' : 'deletedAt'] !== null

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'values', {
    get: function() {
      var result = {}
        , self   = this

      this.attributes.concat(this.__eagerlyLoadedAssociations).forEach(function(attr) {
        result[attr] = self.dataValues.hasOwnProperty(attr)
                     ? self.dataValues[attr]
                     : self[attr]
                     ;
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'primaryKeyValues', {
    get: function() {
      var result = {}
        , self   = this

      Utils._.each(this.__factory.primaryKeys, function(_, attr) {
        result[attr] = self.dataValues[attr]
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, "identifiers", {
    get: function() {
      var primaryKeys = Object.keys(this.__factory.primaryKeys)
        , result      = {}
        , self        = this

      if (!this.__factory.hasPrimaryKeys) {
        primaryKeys = ['id']
      }

      primaryKeys.forEach(function(identifier) {
        result[identifier] = self.dataValues[identifier]
      })

      return result
    }
  })

  DAO.prototype.getDataValue = function(name) {
    return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
  }

  DAO.prototype.setDataValue = function(name, value) {
    this.dataValues[name] = value
  }

  // if an array with field names is passed to save()
  // only those fields will be updated
  DAO.prototype.save = function(fields) {
    var self          = this
      , values        = fields ? {} : this.dataValues
      , updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt'
      , createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt'

    if (fields) {
      if (self.__options.timestamps) {
        if (fields.indexOf(updatedAtAttr) === -1) {
          fields.push(updatedAtAttr)
        }

        if (fields.indexOf(createdAtAttr) === -1) {
          fields.push(createdAtAttr)
        }
      }

      var tmpVals = self.dataValues

      fields.forEach(function(field) {
        if (tmpVals[field] !== undefined) {
          values[field] = tmpVals[field]
        }
      })
    }

    for (var attrName in this.daoFactory.rawAttributes) {
      if (this.daoFactory.rawAttributes.hasOwnProperty(attrName)) {
        var definition      = this.daoFactory.rawAttributes[attrName]
          , isEnum          = (definition.type && (definition.type.toString() === DataTypes.ENUM.toString()))
          , isHstore        = (!!definition.type && !!definition.type.type && definition.type.type === DataTypes.HSTORE.type)
          , hasValue        = (typeof values[attrName] !== 'undefined')
          , valueOutOfScope = ((definition.values || []).indexOf(values[attrName]) === -1)

        if (isEnum && hasValue && valueOutOfScope) {
          throw new Error('Value "' + values[attrName] + '" for ENUM ' + attrName + ' is out of allowed scope. Allowed values: ' + definition.values.join(', '))
        }

        if (isHstore) {
          if (typeof values[attrName] === "object") {
            values[attrName] = hstore.stringify(values[attrName])
          }
        }
      }
    }

    if (this.__options.timestamps && this.dataValues.hasOwnProperty(updatedAtAttr)) {
      this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now(this.sequelize.options.dialect)
    }

    var errors = this.validate()

    if (!!errors) {
      return new Utils.CustomEventEmitter(function(emitter) {
        emitter.emit('error', errors)
      }).run()
    }
    else if (this.isNewRecord) {
      return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values)
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id };

      if (identifier === null && this.__options.whereCollection !== null) {
        identifier = this.__options.whereCollection;
      }

      var tableName  = this.QueryInterface.QueryGenerator.addSchema(this.__factory)
        , query      = this.QueryInterface.update(this, tableName, values, identifier)

      return query
    }
  }

 /*
  * Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
  * This is different from doing a `find(DAO.id)`, because that would create and return a new object. With this method,
  * all references to the DAO are updated with the new data and no new objects are created.
  *
  * @return {Object}         A promise which fires `success`, `error`, `complete` and `sql`.
  */
  DAO.prototype.reload = function() {
    var where = [
      this.QueryInterface.quoteIdentifier(this.__factory.tableName) + '.' + this.QueryInterface.quoteIdentifier('id')+'=?',
      this.id
    ]

    return new Utils.CustomEventEmitter(function(emitter) {
      this.__factory.find({
        where:   where,
        limit:   1,
        include: this.__eagerlyLoadedOptions || []
      })
      .on('sql', function(sql) { emitter.emit('sql', sql) })
      .on('error', function(error) { emitter.emit('error', error) })
      .on('success', function(obj) {
        for (var valueName in obj.values) {
          if (obj.values.hasOwnProperty(valueName)) {
            this[valueName] = obj.values[valueName]
          }
        }
        emitter.emit('success', this)
      }.bind(this))
    }.bind(this)).run()
  }

  /*
   * Validate this dao's attribute values according to validation rules set in the dao definition.
   *
   * @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
   */
  DAO.prototype.validate = function() {
    var validator = new DaoValidator(this)
      , errors    = validator.validate()

    return (Utils._.isEmpty(errors) ? null : errors)
  }

  DAO.prototype.updateAttributes = function(updates, fields) {
    this.setAttributes(updates)
    return this.save(fields)
  }

  DAO.prototype.setAttributes = function(updates) {
    var self = this

    var readOnlyAttributes = Object.keys(this.__factory.primaryKeys)

    readOnlyAttributes.push('id')
    readOnlyAttributes.push('createdAt')
    readOnlyAttributes.push('updatedAt')
    readOnlyAttributes.push('deletedAt')

    Utils._.each(updates, function(value, attr) {
      var updateAllowed = (
        (readOnlyAttributes.indexOf(attr) == -1) &&
        (readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) &&
        (self.attributes.indexOf(attr) > -1)
      )
      updateAllowed && (self[attr] = value)
    })
  }

  DAO.prototype.destroy = function() {
    if (this.__options.timestamps && this.__options.paranoid) {
      var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt'
      this.dataValues[attr] = new Date()
      return this.save()
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id };
      return this.QueryInterface.delete(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), identifier)
    }
  }

  DAO.prototype.increment = function(fields, count) {
    var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : { id: this.id },
      values = {}

    if (count === undefined) {
      count = 1;
    }

    if (Utils._.isString(fields)) {
      values[fields] = count;
    } else if (Utils._.isArray(fields)) {
      Utils._.each(fields, function (field) {
        values[field] = count
      })
    } else { // Assume fields is key-value pairs
      values = fields;
    }

    return this.QueryInterface.increment(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), values, identifier)
  }

  DAO.prototype.decrement = function (fields, count) {
    if (!Utils._.isString(fields) && !Utils._.isArray(fields)) { // Assume fields is key-value pairs
      Utils._.each(fields, function (value, field) {
        fields[field] = -value;
      });
    }

    return this.increment(fields, 0 - count);
  }

  DAO.prototype.equals = function(other) {
    var result = true

    Utils._.each(this.dataValues, function(value, key) {
      if(Utils._.isDate(value) && Utils._.isDate(other[key])) {
        result = result && (value.getTime() == other[key].getTime())
      } else {
        result = result && (value == other[key])
      }
    })

    return result
  }

  DAO.prototype.equalsOneOf = function(others) {
    var result = false
      , self   = this

    others.forEach(function(other) { result = result || self.equals(other) })

    return result
  }

  DAO.prototype.addAttribute = function(attribute, value) {
    if (this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1 && value !== undefined) { // transform integer 0,1 into boolean
      value = !!value
    }

    var has = (function(o) {
      var predef = Object.getOwnPropertyDescriptor(o, attribute);

      if (predef && predef.hasOwnProperty('value')) {
        return true // true here means 'this property exist as a simple value property, do not place setters or getters at all'
      }

      return {
        get: (predef && predef.hasOwnProperty('get') ? predef.get : null) || o.__lookupGetter__(attribute),
        set: (predef && predef.hasOwnProperty('set') ? predef.set : null) || o.__lookupSetter__(attribute)
      };
    })(this);

    // @ node-v0.8.19:
    //    calling __defineGetter__ destroys any previously defined setters for the attribute in
    //    question *if* that property setter was defined on the object's prototype (which is what
    //    we do in dao-factory) ... therefore we need to [re]define both the setter and getter
    //    here with either the function that already existed OR the default/automatic definition
    //
    //    (the same is true for __defineSetter and 'prototype' getters)
    if (has !== true) {
      this.__defineGetter__(attribute, has.get || function()  { return this.dataValues[attribute]; });
      this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v;    });
    }

    this[attribute] = value;
  }

  DAO.prototype.setValidators = function(attribute, validators) {
    this.validators[attribute] = validators
  }

  DAO.prototype.toJSON = function() {
    return this.values;
  }

  // private

  var initAttributes = function(values, isNewRecord) {
    // set id to null if not passed as value, a newly created dao has no id
    var defaults = this.hasPrimaryKeys ? {} : { id: null },
        attrs    = {},
        key;

    // add all passed values to the dao and store the attribute names in this.attributes
    for (key in values) {
      if (values.hasOwnProperty(key)) {
        this.addAttribute(key, values[key])
      }
    }

    if (isNewRecord) {
      if (this.hasDefaultValues) {
        Utils._.each(this.defaultValues, function(valueFn, key) {
          if (!defaults.hasOwnProperty(key)) {
            defaults[key] = valueFn()
          }
        })
      }

      if (this.__options.timestamps) {
        defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now(this.sequelize.options.dialect)
        defaults[this.__options.underscored ? 'updated_at' : 'updatedAt'] = Utils.now(this.sequelize.options.dialect)

        if (this.__options.paranoid) {
          defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null
        }
      }
    }

    if (Utils._.size(defaults)) {
      for (key in defaults) {
        attrs[key] = Utils.toDefaultValue(defaults[key])
      }
    }

    Utils._.each(this.attributes, function(key) {
      if (!attrs.hasOwnProperty(key)) {
        attrs[key] = undefined
      }
    })

    if (values) {
      for (key in values) {
        if (values.hasOwnProperty(key)) {
          attrs[key] = values[key]
        }
      }
    }

    for (key in attrs) {
      this.addAttribute(key, attrs[key])
    }
  }

  return DAO
})()
<|endoftext|>


<commit_before>var Utils     = require("./utils")
  , Mixin     = require("./associations/mixin")
  , Validator = require("validator")
  , DataTypes = require("./data-types")

module.exports = (function() {
  var DAO = function(values, options, isNewRecord) {
    var self = this

    this.dataValues                  = {}
    this.__options                   = options
    this.hasPrimaryKeys              = options.hasPrimaryKeys
    this.selectedValues              = values
    this.__eagerlyLoadedAssociations = []

    initAttributes.call(this, values, isNewRecord)
  }

  Utils._.extend(DAO.prototype, Mixin.prototype)

  Object.defineProperty(DAO.prototype, 'sequelize', {
    get: function(){ return this.__factory.daoFactoryManager.sequelize }
  })

  Object.defineProperty(DAO.prototype, 'QueryInterface', {
    get: function(){ return this.sequelize.getQueryInterface() }
  })

  Object.defineProperty(DAO.prototype, 'isDeleted', {
    get: function() {
      var result = this.__options.timestamps && this.__options.paranoid
      result = result && this.dataValues[this.__options.underscored ? 'deleted_at' : 'deletedAt'] !== null

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'values', {
    get: function() {
      var result = {}
        , self   = this

      this.attributes.concat(this.__eagerlyLoadedAssociations).forEach(function(attr) {
        result[attr] = self.dataValues.hasOwnProperty(attr)
                     ? self.dataValues[attr]
                     : self[attr]
                     ;
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'primaryKeyValues', {
    get: function() {
      var result = {}
        , self   = this

      Utils._.each(this.__factory.primaryKeys, function(_, attr) {
        result[attr] = self.dataValues[attr]
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, "identifiers", {
    get: function() {
      var primaryKeys = Object.keys(this.__factory.primaryKeys)
        , result      = {}
        , self        = this

      if (!this.__factory.hasPrimaryKeys) {
        primaryKeys = ['id']
      }

      primaryKeys.forEach(function(identifier) {
        result[identifier] = self.dataValues[identifier]
      })

      return result
    }
  })

  DAO.prototype.getDataValue = function(name) {
    return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
  }

  DAO.prototype.setDataValue = function(name, value) {
    this.dataValues[name] = value
  }

  // if an array with field names is passed to save()
  // only those fields will be updated
  DAO.prototype.save = function(fields) {
    var self          = this
      , values        = fields ? {} : this.values
      , updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt'
      , createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt'

    if (fields) {
      if (self.__options.timestamps) {
        if (fields.indexOf(updatedAtAttr) === -1) {
          fields.push(updatedAtAttr)
        }

        if (fields.indexOf(createdAtAttr) === -1) {
          fields.push(createdAtAttr)
        }
      }

      var tmpVals = self.values

      fields.forEach(function(field) {
        if (tmpVals[field] !== undefined) {
          values[field] = tmpVals[field]
        }
      })
    }

    for (var attrName in this.daoFactory.rawAttributes) {
      if (this.daoFactory.rawAttributes.hasOwnProperty(attrName)) {
        var definition      = this.daoFactory.rawAttributes[attrName]
          , isEnum          = (definition.type && (definition.type.toString() === DataTypes.ENUM.toString()))
          , isHstore        = (!!definition.type && !!definition.type.type && definition.type.type === DataTypes.HSTORE.type)
          , hasValue        = (typeof values[attrName] !== 'undefined')
          , valueOutOfScope = ((definition.values || []).indexOf(values[attrName]) === -1)

        if (isEnum && hasValue && valueOutOfScope) {
          throw new Error('Value "' + values[attrName] + '" for ENUM ' + attrName + ' is out of allowed scope. Allowed values: ' + definition.values.join(', '))
        }

        if (isHstore) {
          if (typeof values[attrName] === "object") {
            var text = []
            Utils._.each(values[attrName], function(value, key){
              if (typeof value !== "string" && typeof value !== "number") {
                throw new Error('Value for HSTORE must be a string or number.')
              }

              text.push(this.QueryInterface.QueryGenerator.addQuotes(key) + '=>' + (typeof value === "string" ? this.QueryInterface.QueryGenerator.addQuotes(value) : value))
            }.bind(this))
            values[attrName] = text.join(',')
          }
        }
      }
    }

    if (this.__options.timestamps && this.dataValues.hasOwnProperty(updatedAtAttr)) {
      this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now()
    }

    var errors = this.validate()

    if (!!errors) {
      return new Utils.CustomEventEmitter(function(emitter) {
        emitter.emit('error', errors)
      }).run()
    }
    else if (this.isNewRecord) {
      return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values)
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id;

      if (identifier === null && this.__options.whereCollection !== null) {
        identifier = this.__options.whereCollection;
      }

      var tableName  = this.QueryInterface.QueryGenerator.addSchema(this.__factory)
        , query      = this.QueryInterface.update(this, tableName, values, identifier)

      return query
    }
  }

 /*
  * Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
  * This is different from doing a `find(DAO.id)`, because that would create and return a new object. With this method,
  * all references to the DAO are updated with the new data and no new objects are created.
  *
  * @return {Object}         A promise which fires `success`, `error`, `complete` and `sql`.
  */
  DAO.prototype.reload = function() {
    var where = [
      this.QueryInterface.QueryGenerator.addQuotes(this.__factory.tableName) + '.' + this.QueryInterface.QueryGenerator.addQuotes('id')+'=?',
      this.id
    ]

    return new Utils.CustomEventEmitter(function(emitter) {
      this.__factory.find({
        where:   where,
        limit:   1,
        include: this.__eagerlyLoadedOptions || []
      })
      .on('sql', function(sql) { emitter.emit('sql', sql) })
      .on('error', function(error) { emitter.emit('error', error) })
      .on('success', function(obj) {
        for (var valueName in obj.values) {
          if (obj.values.hasOwnProperty(valueName)) {
            this[valueName] = obj.values[valueName]
          }
        }
        emitter.emit('success', this)
      }.bind(this))
    }.bind(this)).run()
  }

  /*
   * Validate this dao's attribute values according to validation rules set in the dao definition.
   *
   * @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
   */
  DAO.prototype.validate = function() {
    var self = this
    var failures = {}

    // for each field and value
    Utils._.each(self.values, function(value, field) {

      // if field has validators
      var hasAllowedNull = (self.rawAttributes[field].allowNull && self.rawAttributes[field].allowNull === true && (value === null || value === undefined));

      if (self.validators.hasOwnProperty(field) && !hasAllowedNull) {
        // for each validator
        Utils._.each(self.validators[field], function(details, validatorType) {

          var is_custom_fn = false  // if true then it's a custom validation method
          var fn_method = null      // the validation function to call
          var fn_args = []          // extra arguments to pass to validation function
          var fn_msg = ""           // the error message to return if validation fails

          // is it a custom validator function?
          if (Utils._.isFunction(details)) {
            is_custom_fn = true
            fn_method = Utils._.bind(details, self, value)
          }
          // is it a validator module function?
          else {
            // extra args
            fn_args = details.hasOwnProperty("args") ? details.args : details
            if (!Array.isArray(fn_args))
              fn_args = [fn_args]
            // error msg
            fn_msg = details.hasOwnProperty("msg") ? details.msg : false
            // check method exists
            var v = Validator.check(value, fn_msg)
            if (!Utils._.isFunction(v[validatorType]))
              throw new Error("Invalid validator function: " + validatorType)
            // bind to validator obj
            fn_method = Utils._.bind(v[validatorType], v)
          }

          try {
            fn_method.apply(null, fn_args)
          } catch (err) {
            err = err.message
            // if we didn't provide a custom error message then augment the default one returned by the validator
            if (!fn_msg && !is_custom_fn)
              err += ": " + field
            // each field can have multiple validation failures stored against it
            if (failures.hasOwnProperty(field)) {
              failures[field].push(err)
            } else {
              failures[field] = [err]
            }
          }

        }) // for each validator for this field
      } // if field has validator set
    }) // for each field

    return (Utils._.isEmpty(failures) ? null : failures)
  }

  DAO.prototype.updateAttributes = function(updates, fields) {
    this.setAttributes(updates)
    return this.save(fields)
  }

  DAO.prototype.setAttributes = function(updates) {
    var self = this

    var readOnlyAttributes = Object.keys(this.__factory.primaryKeys)

    readOnlyAttributes.push('id')
    readOnlyAttributes.push('createdAt')
    readOnlyAttributes.push('updatedAt')
    readOnlyAttributes.push('deletedAt')

    Utils._.each(updates, function(value, attr) {
      var updateAllowed = (
        (readOnlyAttributes.indexOf(attr) == -1) &&
        (readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) &&
        (self.attributes.indexOf(attr) > -1)
      )
      updateAllowed && (self[attr] = value)
    })
  }

  DAO.prototype.destroy = function() {
    if (this.__options.timestamps && this.__options.paranoid) {
      var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt'
      this.dataValues[attr] = new Date()
      return this.save()
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id
      return this.QueryInterface.delete(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), identifier)
    }
  }

  DAO.prototype.increment = function(fields, count) {
    var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id,
      values = {}

    if (count === undefined) count = 1;

    if (Utils._.isString(fields)) {
      values[fields] = count;
    } else if (Utils._.isArray(fields)) {
      Utils._.each(fields, function (field) {
        values[field] = count
      })
    } else { // Assume fields is key-value pairs
      values = fields;
    }

    return this.QueryInterface.increment(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), values, identifier)
  }

  DAO.prototype.decrement = function (fields, count) {
    if (!Utils._.isString(fields) && !Utils._.isArray(fields)) { // Assume fields is key-value pairs
      Utils._.each(fields, function (value, field) {
        fields[field] = -value;
      });
    }

    return this.increment(fields, 0 - count);
  }

  DAO.prototype.equals = function(other) {
    var result = true

    Utils._.each(this.values, function(value, key) {
      if(Utils._.isDate(value) && Utils._.isDate(other[key])) {
        result = result && (value.getTime() == other[key].getTime())
      } else {
        result = result && (value == other[key])
      }
    })

    return result
  }

  DAO.prototype.equalsOneOf = function(others) {
    var result = false
      , self   = this

    others.forEach(function(other) { result = result || self.equals(other) })

    return result
  }

  DAO.prototype.addAttribute = function(attribute, value) {
    if (typeof this.dataValues[attribute] !== 'undefined')
      return;

    if (this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1) // transform integer 0,1 into boolean
      value = !!value;

    var has = (function(o) {
      var predef = Object.getOwnPropertyDescriptor(o, attribute);

      if (predef && predef.hasOwnProperty('value'))
        return true; // true here means 'this property exist as a simple value property, do not place setters or getters at all'

        return {
          get: (predef && predef.hasOwnProperty('get') ? predef.get : null) || o.__lookupGetter__(attribute),
          set: (predef && predef.hasOwnProperty('set') ? predef.set : null) || o.__lookupSetter__(attribute)
        };
    })(this);

    // node-v0.8.19:
    //    calling __defineGetter__ destroys any previously defined setters for the attribute in
    //    question *if* that property setter was defined on the object's prototype (which is what
    //    we do in dao-factory) ... therefore we need to [re]define both the setter and getter
    //    here with either the function that already existed OR the default/automatic definition
    //
    //    (the same is true for __defineSetter and 'prototype' getters)
    if (has !== true) {
      this.__defineGetter__(attribute, has.get || function()  { return this.dataValues[attribute]; });
      this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v;    });
    }

    this[attribute] = value;
  }

  DAO.prototype.setValidators = function(attribute, validators) {
    this.validators[attribute] = validators
  }

  DAO.prototype.toJSON = function() {
    return this.values;
  }

  // private

  var initAttributes = function(values, isNewRecord) {
    // set id to null if not passed as value, a newly created dao has no id
    var defaults = this.hasPrimaryKeys ? {} : { id: null },
        attrs    = {},
        key;

    // add all passed values to the dao and store the attribute names in this.attributes
    for (key in values) {
      if (values.hasOwnProperty(key)) {
        if (typeof values[key] === "string" && !!this.__factory && !!this.__factory.rawAttributes[key] && !!this.__factory.rawAttributes[key].type && !!this.__factory.rawAttributes[key].type.type && this.__factory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
          values[key] = this.QueryInterface.QueryGenerator.toHstore(values[key])
        }

        this.addAttribute(key, values[key])
      }
    }

    if (this.__options.timestamps && isNewRecord) {
      defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now()
      defaults[this.__options.underscored ? 'updated_at' : 'updatedAt'] = Utils.now()

      if (this.__options.paranoid) {
        defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null
      }

      if (this.hasDefaultValues) {
        Utils._.each(this.defaultValues, function(valueFn, key) {
          if (!defaults.hasOwnProperty(key))
            defaults[key] = valueFn()
        })
      }
    }

    if (Utils._.size(defaults)) {
      for (key in defaults) {
        attrs[key] = Utils.toDefaultValue(defaults[key])
      }
    }

    Utils._.each(this.attributes, function(key) {
      if (!attrs.hasOwnProperty(key)) {
        attrs[key] = undefined
      }
    })

    if (values) {
      for (key in values) {
        if (values.hasOwnProperty(key)) {
          attrs[key] = values[key]
        }
      }
    }

    for (key in attrs) {
      this.addAttribute(key, attrs[key])
    }
  }

  return DAO
})()
<commit_msg>bogus commit (no code changes) to force travis-ci to run again (lets hope there are no timeouts in the postgres test run this time :-/<commit_after>var Utils     = require("./utils")
  , Mixin     = require("./associations/mixin")
  , Validator = require("validator")
  , DataTypes = require("./data-types")

module.exports = (function() {
  var DAO = function(values, options, isNewRecord) {
    var self = this

    this.dataValues                  = {}
    this.__options                   = options
    this.hasPrimaryKeys              = options.hasPrimaryKeys
    this.selectedValues              = values
    this.__eagerlyLoadedAssociations = []

    initAttributes.call(this, values, isNewRecord)
  }

  Utils._.extend(DAO.prototype, Mixin.prototype)

  Object.defineProperty(DAO.prototype, 'sequelize', {
    get: function(){ return this.__factory.daoFactoryManager.sequelize }
  })

  Object.defineProperty(DAO.prototype, 'QueryInterface', {
    get: function(){ return this.sequelize.getQueryInterface() }
  })

  Object.defineProperty(DAO.prototype, 'isDeleted', {
    get: function() {
      var result = this.__options.timestamps && this.__options.paranoid
      result = result && this.dataValues[this.__options.underscored ? 'deleted_at' : 'deletedAt'] !== null

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'values', {
    get: function() {
      var result = {}
        , self   = this

      this.attributes.concat(this.__eagerlyLoadedAssociations).forEach(function(attr) {
        result[attr] = self.dataValues.hasOwnProperty(attr)
                     ? self.dataValues[attr]
                     : self[attr]
                     ;
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, 'primaryKeyValues', {
    get: function() {
      var result = {}
        , self   = this

      Utils._.each(this.__factory.primaryKeys, function(_, attr) {
        result[attr] = self.dataValues[attr]
      })

      return result
    }
  })

  Object.defineProperty(DAO.prototype, "identifiers", {
    get: function() {
      var primaryKeys = Object.keys(this.__factory.primaryKeys)
        , result      = {}
        , self        = this

      if (!this.__factory.hasPrimaryKeys) {
        primaryKeys = ['id']
      }

      primaryKeys.forEach(function(identifier) {
        result[identifier] = self.dataValues[identifier]
      })

      return result
    }
  })

  DAO.prototype.getDataValue = function(name) {
    return this.dataValues && this.dataValues.hasOwnProperty(name) ? this.dataValues[name] : this[name]
  }

  DAO.prototype.setDataValue = function(name, value) {
    this.dataValues[name] = value
  }

  // if an array with field names is passed to save()
  // only those fields will be updated
  DAO.prototype.save = function(fields) {
    var self          = this
      , values        = fields ? {} : this.values
      , updatedAtAttr = this.__options.underscored ? 'updated_at' : 'updatedAt'
      , createdAtAttr = this.__options.underscored ? 'created_at' : 'createdAt'

    if (fields) {
      if (self.__options.timestamps) {
        if (fields.indexOf(updatedAtAttr) === -1) {
          fields.push(updatedAtAttr)
        }

        if (fields.indexOf(createdAtAttr) === -1) {
          fields.push(createdAtAttr)
        }
      }

      var tmpVals = self.values

      fields.forEach(function(field) {
        if (tmpVals[field] !== undefined) {
          values[field] = tmpVals[field]
        }
      })
    }

    for (var attrName in this.daoFactory.rawAttributes) {
      if (this.daoFactory.rawAttributes.hasOwnProperty(attrName)) {
        var definition      = this.daoFactory.rawAttributes[attrName]
          , isEnum          = (definition.type && (definition.type.toString() === DataTypes.ENUM.toString()))
          , isHstore        = (!!definition.type && !!definition.type.type && definition.type.type === DataTypes.HSTORE.type)
          , hasValue        = (typeof values[attrName] !== 'undefined')
          , valueOutOfScope = ((definition.values || []).indexOf(values[attrName]) === -1)

        if (isEnum && hasValue && valueOutOfScope) {
          throw new Error('Value "' + values[attrName] + '" for ENUM ' + attrName + ' is out of allowed scope. Allowed values: ' + definition.values.join(', '))
        }

        if (isHstore) {
          if (typeof values[attrName] === "object") {
            var text = []
            Utils._.each(values[attrName], function(value, key){
              if (typeof value !== "string" && typeof value !== "number") {
                throw new Error('Value for HSTORE must be a string or number.')
              }

              text.push(this.QueryInterface.QueryGenerator.addQuotes(key) + '=>' + (typeof value === "string" ? this.QueryInterface.QueryGenerator.addQuotes(value) : value))
            }.bind(this))
            values[attrName] = text.join(',')
          }
        }
      }
    }

    if (this.__options.timestamps && this.dataValues.hasOwnProperty(updatedAtAttr)) {
      this.dataValues[updatedAtAttr] = values[updatedAtAttr] = Utils.now()
    }

    var errors = this.validate()

    if (!!errors) {
      return new Utils.CustomEventEmitter(function(emitter) {
        emitter.emit('error', errors)
      }).run()
    }
    else if (this.isNewRecord) {
      return this.QueryInterface.insert(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory), values)
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id;

      if (identifier === null && this.__options.whereCollection !== null) {
        identifier = this.__options.whereCollection;
      }

      var tableName  = this.QueryInterface.QueryGenerator.addSchema(this.__factory)
        , query      = this.QueryInterface.update(this, tableName, values, identifier)

      return query
    }
  }

 /*
  * Refresh the current instance in-place, i.e. update the object with current data from the DB and return the same object.
  * This is different from doing a `find(DAO.id)`, because that would create and return a new object. With this method,
  * all references to the DAO are updated with the new data and no new objects are created.
  *
  * @return {Object}         A promise which fires `success`, `error`, `complete` and `sql`.
  */
  DAO.prototype.reload = function() {
    var where = [
      this.QueryInterface.QueryGenerator.addQuotes(this.__factory.tableName) + '.' + this.QueryInterface.QueryGenerator.addQuotes('id')+'=?',
      this.id
    ]

    return new Utils.CustomEventEmitter(function(emitter) {
      this.__factory.find({
        where:   where,
        limit:   1,
        include: this.__eagerlyLoadedOptions || []
      })
      .on('sql', function(sql) { emitter.emit('sql', sql) })
      .on('error', function(error) { emitter.emit('error', error) })
      .on('success', function(obj) {
        for (var valueName in obj.values) {
          if (obj.values.hasOwnProperty(valueName)) {
            this[valueName] = obj.values[valueName]
          }
        }
        emitter.emit('success', this)
      }.bind(this))
    }.bind(this)).run()
  }

  /*
   * Validate this dao's attribute values according to validation rules set in the dao definition.
   *
   * @return null if and only if validation successful; otherwise an object containing { field name : [error msgs] } entries.
   */
  DAO.prototype.validate = function() {
    var self = this
    var failures = {}

    // for each field and value
    Utils._.each(self.values, function(value, field) {

      // if field has validators
      var hasAllowedNull = (self.rawAttributes[field].allowNull && self.rawAttributes[field].allowNull === true && (value === null || value === undefined));

      if (self.validators.hasOwnProperty(field) && !hasAllowedNull) {
        // for each validator
        Utils._.each(self.validators[field], function(details, validatorType) {

          var is_custom_fn = false  // if true then it's a custom validation method
          var fn_method = null      // the validation function to call
          var fn_args = []          // extra arguments to pass to validation function
          var fn_msg = ""           // the error message to return if validation fails

          // is it a custom validator function?
          if (Utils._.isFunction(details)) {
            is_custom_fn = true
            fn_method = Utils._.bind(details, self, value)
          }
          // is it a validator module function?
          else {
            // extra args
            fn_args = details.hasOwnProperty("args") ? details.args : details
            if (!Array.isArray(fn_args))
              fn_args = [fn_args]
            // error msg
            fn_msg = details.hasOwnProperty("msg") ? details.msg : false
            // check method exists
            var v = Validator.check(value, fn_msg)
            if (!Utils._.isFunction(v[validatorType]))
              throw new Error("Invalid validator function: " + validatorType)
            // bind to validator obj
            fn_method = Utils._.bind(v[validatorType], v)
          }

          try {
            fn_method.apply(null, fn_args)
          } catch (err) {
            err = err.message
            // if we didn't provide a custom error message then augment the default one returned by the validator
            if (!fn_msg && !is_custom_fn)
              err += ": " + field
            // each field can have multiple validation failures stored against it
            if (failures.hasOwnProperty(field)) {
              failures[field].push(err)
            } else {
              failures[field] = [err]
            }
          }

        }) // for each validator for this field
      } // if field has validator set
    }) // for each field

    return (Utils._.isEmpty(failures) ? null : failures)
  }

  DAO.prototype.updateAttributes = function(updates, fields) {
    this.setAttributes(updates)
    return this.save(fields)
  }

  DAO.prototype.setAttributes = function(updates) {
    var self = this

    var readOnlyAttributes = Object.keys(this.__factory.primaryKeys)

    readOnlyAttributes.push('id')
    readOnlyAttributes.push('createdAt')
    readOnlyAttributes.push('updatedAt')
    readOnlyAttributes.push('deletedAt')

    Utils._.each(updates, function(value, attr) {
      var updateAllowed = (
        (readOnlyAttributes.indexOf(attr) == -1) &&
        (readOnlyAttributes.indexOf(Utils._.underscored(attr)) == -1) &&
        (self.attributes.indexOf(attr) > -1)
      )
      updateAllowed && (self[attr] = value)
    })
  }

  DAO.prototype.destroy = function() {
    if (this.__options.timestamps && this.__options.paranoid) {
      var attr = this.__options.underscored ? 'deleted_at' : 'deletedAt'
      this.dataValues[attr] = new Date()
      return this.save()
    } else {
      var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id
      return this.QueryInterface.delete(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), identifier)
    }
  }

  DAO.prototype.increment = function(fields, count) {
    var identifier = this.__options.hasPrimaryKeys ? this.primaryKeyValues : this.id,
      values = {}

    if (count === undefined) count = 1;

    if (Utils._.isString(fields)) {
      values[fields] = count;
    } else if (Utils._.isArray(fields)) {
      Utils._.each(fields, function (field) {
        values[field] = count
      })
    } else { // Assume fields is key-value pairs
      values = fields;
    }

    return this.QueryInterface.increment(this, this.QueryInterface.QueryGenerator.addSchema(this.__factory.tableName, this.__factory.options.schema), values, identifier)
  }

  DAO.prototype.decrement = function (fields, count) {
    if (!Utils._.isString(fields) && !Utils._.isArray(fields)) { // Assume fields is key-value pairs
      Utils._.each(fields, function (value, field) {
        fields[field] = -value;
      });
    }

    return this.increment(fields, 0 - count);
  }

  DAO.prototype.equals = function(other) {
    var result = true

    Utils._.each(this.values, function(value, key) {
      if(Utils._.isDate(value) && Utils._.isDate(other[key])) {
        result = result && (value.getTime() == other[key].getTime())
      } else {
        result = result && (value == other[key])
      }
    })

    return result
  }

  DAO.prototype.equalsOneOf = function(others) {
    var result = false
      , self   = this

    others.forEach(function(other) { result = result || self.equals(other) })

    return result
  }

  DAO.prototype.addAttribute = function(attribute, value) {
    if (typeof this.dataValues[attribute] !== 'undefined')
      return;

    if (this.booleanValues.length && this.booleanValues.indexOf(attribute) !== -1) // transform integer 0,1 into boolean
      value = !!value;

    var has = (function(o) {
      var predef = Object.getOwnPropertyDescriptor(o, attribute);

      if (predef && predef.hasOwnProperty('value'))
        return true; // true here means 'this property exist as a simple value property, do not place setters or getters at all'

        return {
          get: (predef && predef.hasOwnProperty('get') ? predef.get : null) || o.__lookupGetter__(attribute),
          set: (predef && predef.hasOwnProperty('set') ? predef.set : null) || o.__lookupSetter__(attribute)
        };
    })(this);

    // @ node-v0.8.19:
    //    calling __defineGetter__ destroys any previously defined setters for the attribute in
    //    question *if* that property setter was defined on the object's prototype (which is what
    //    we do in dao-factory) ... therefore we need to [re]define both the setter and getter
    //    here with either the function that already existed OR the default/automatic definition
    //
    //    (the same is true for __defineSetter and 'prototype' getters)
    if (has !== true) {
      this.__defineGetter__(attribute, has.get || function()  { return this.dataValues[attribute]; });
      this.__defineSetter__(attribute, has.set || function(v) { this.dataValues[attribute] = v;    });
    }

    this[attribute] = value;
  }

  DAO.prototype.setValidators = function(attribute, validators) {
    this.validators[attribute] = validators
  }

  DAO.prototype.toJSON = function() {
    return this.values;
  }

  // private

  var initAttributes = function(values, isNewRecord) {
    // set id to null if not passed as value, a newly created dao has no id
    var defaults = this.hasPrimaryKeys ? {} : { id: null },
        attrs    = {},
        key;

    // add all passed values to the dao and store the attribute names in this.attributes
    for (key in values) {
      if (values.hasOwnProperty(key)) {
        if (typeof values[key] === "string" && !!this.__factory && !!this.__factory.rawAttributes[key] && !!this.__factory.rawAttributes[key].type && !!this.__factory.rawAttributes[key].type.type && this.__factory.rawAttributes[key].type.type === DataTypes.HSTORE.type) {
          values[key] = this.QueryInterface.QueryGenerator.toHstore(values[key])
        }

        this.addAttribute(key, values[key])
      }
    }

    if (this.__options.timestamps && isNewRecord) {
      defaults[this.__options.underscored ? 'created_at' : 'createdAt'] = Utils.now()
      defaults[this.__options.underscored ? 'updated_at' : 'updatedAt'] = Utils.now()

      if (this.__options.paranoid) {
        defaults[this.__options.underscored ? 'deleted_at' : 'deletedAt'] = null
      }

      if (this.hasDefaultValues) {
        Utils._.each(this.defaultValues, function(valueFn, key) {
          if (!defaults.hasOwnProperty(key))
            defaults[key] = valueFn()
        })
      }
    }

    if (Utils._.size(defaults)) {
      for (key in defaults) {
        attrs[key] = Utils.toDefaultValue(defaults[key])
      }
    }

    Utils._.each(this.attributes, function(key) {
      if (!attrs.hasOwnProperty(key)) {
        attrs[key] = undefined
      }
    })

    if (values) {
      for (key in values) {
        if (values.hasOwnProperty(key)) {
          attrs[key] = values[key]
        }
      }
    }

    for (key in attrs) {
      this.addAttribute(key, attrs[key])
    }
  }

  return DAO
})()
<|endoftext|>