<commit_before>const fs = require('fs');

const BuildAutoInc = function (file, config) {
    this.file = file;
    this.config = config || {};
};

BuildAutoInc.prototype.read = function (file, callback) {
    const self = this;
    const ver = { major: 0, minor: 0, patch: 0, build: 0 };
    fs.readFile(this.file, function (err, buf) {
        if (err) {
            callback(ver);
        }
        else {
            const v = buf.toString().replace(/\n/g, '').split('.');
            ver.major = v[0];
            ver.minor = v[1];
            ver.patch = v[2];
            if (!self.config.input || !self.config.input.url) {
                ver.build = v[3];
                callback(ver);
            }
            else {
                const http = require(self.config.input.url.startsWith('https') ? 'https' : 'http') ;
                http.get(self.config.input.url, (res) => {
                    const { statusCode } = res;
                    const contentType = res.headers['content-type'];

                    let error;
                    if (statusCode !== 200) {
                        error = new Error('Request Failed.\nStatus Code: ' + statusCode);
                    }
                    else if (!/^application\/json/.test(contentType) && !/^text\/plain/.test(contentType)) {
                        error = new Error('Invalid content-type.\n' +
                            `Expected application/json or text/plain but received ${contentType}`);
                    }
                    if (error) {
                        console.error(error.message);
                        res.resume();
                        return;
                    }

                    let rawData = '';
                    res.on('data', (chunk) => { rawData += chunk; });
                    res.on('end', () => {
                        if (/^application\/json/.test(contentType)) {
                            try {
                                const parsedData = JSON.parse(rawData);
                                ver.build = parsedData.build;
                            }
                            catch (e) {
                                console.error(e.message);
                                return;
                            }
                        }
                        else {
                            ver.build = rawData;
                        }
                        callback(ver);
                    });
                }).on('error', (e) => {
                    console.error(`Got error: ${e.message}`);
                });
            }
        }
    });
};

BuildAutoInc.prototype.load = function (callback) {
    this.read(this.file, callback);
};

BuildAutoInc.prototype.save = function (version, callback) {
    return this.write(this.file, version, callback);
};

BuildAutoInc.prototype.write = function (cout, ver, callback) {
    switch (cout.type) {
        case "text":
            fs.writeFile(cout.file,
                ver.text + "\n",
                callback);
            break;
        case "json":
            fs.writeFile(cout.file,
                '{"major":' + ver.major + ',"minor":' + ver.minor + ',"patch":' + ver.patch + ',"build":' + ver.build + ',"text":' + ver.text + '}' + "\n",
                callback);
            break;
        case "ts":
            fs.writeFile(cout.file,
                "export const version = {\n    major: " + ver.major + ",\n    minor: " + ver.minor + ",\n    patch: " + ver.patch + ",\n    build: "
                + ver.build + ",\n    text: '" + ver.text + "'\n};\n",
                callback);
            break;
        case "package":
            const conf = { 'bin-links': false, verbose: true, prefix: cout.dir };
            const cli = require('npm');
            cli.load(conf, (err) => {
            if(err) {
                    return reject(err);
            }
            cli.commands.version([ver.major + "." + ver.minor + "." + ver.patch], callback);
            cli.on('log', (message) => {
                    console.log(message);
                });
            });
            break;
    }
};

BuildAutoInc.prototype.apply = function (compiler) {
    const self = this;

    compiler.plugin('run', function (compilation, callback) {
        self.read(self.file, function (ver) {
            ver.patch++;
            const tv = ver.major + '.' + ver.minor + '.' + ver.patch + '.' + ver.build;
            console.log('----------------------[', tv, "]---", ver);
            ver.text = tv;
            if (self.config && self.config.output) {
                for (let i = 0; i < self.config.output.length; i++) {
                    self.write(self.config.output[i], ver, null);
                }
            }
            self.write({ type: 'text', file: self.file }, ver, callback);
        });
    });

    compiler.plugin('watch-run', function (compilation, callback) {
        self.read(self.file, function (ver) {
            ver.build++;
            let tv = ver.major + '.' + ver.minor + '.' + ver.patch + '.' + ver.build;
            console.log('----------------------[', tv, "]---", ver);
            ver.text = tv;
            self.write({ type: 'text', file: self.file }, ver, callback);
        });
    });

};

module.exports = BuildAutoInc;
<commit_msg>minor fixes, remove patch version autoincrease on "run" hook<commit_after>const fs = require('fs');

const BuildAutoInc = function (file, config) {
    this.file = file;
    this.config = config || {};
};

BuildAutoInc.prototype.read = function (file, callback) {
    const self = this;
    const ver = { major: 0, minor: 0, patch: 0, build: 0 };
    fs.readFile(this.file, function (err, buf) {
        if (err) {
            callback(ver);
        }
        else {
            const v = buf.toString().replace(/\n/g, '').split('.');
            ver.major = +v[0];
            ver.minor = +v[1];
            ver.patch = +v[2];
            if (!self.config.input || !self.config.input.url) {
                ver.build = +v[3];
                callback(ver);
            }
            else {
                const http = require(self.config.input.url.startsWith('https') ? 'https' : 'http') ;
                http.get(self.config.input.url, (res) => {
                    const { statusCode } = res;
                    const contentType = res.headers['content-type'];

                    let error;
                    if (statusCode !== 200) {
                        error = new Error('Request Failed.\nStatus Code: ' + statusCode);
                    }
                    else if (!/^application\/json/.test(contentType) && !/^text\/plain/.test(contentType)) {
                        error = new Error('Invalid content-type.\n' +
                            `Expected application/json or text/plain but received ${contentType}`);
                    }
                    if (error) {
                        console.error(error.message);
                        res.resume();
                        return;
                    }

                    let rawData = '';
                    res.on('data', (chunk) => { rawData += chunk; });
                    res.on('end', () => {
                        if (/^application\/json/.test(contentType)) {
                            try {
                                const parsedData = JSON.parse(rawData);
                                ver.build = +parsedData.build;
                            }
                            catch (e) {
                                console.error(e.message);
                                return;
                            }
                        }
                        else {
                            ver.build = +rawData;
                        }
                        callback(ver);
                    });
                }).on('error', (e) => {
                    console.error(`Got error: ${e.message}`);
                });
            }
        }
    });
};

BuildAutoInc.prototype.load = function (callback) {
    this.read(this.file, callback);
};

BuildAutoInc.prototype.save = function (version, callback) {
    return this.write(this.file, version, callback);
};

BuildAutoInc.prototype.write = function (cout, ver, callback) {
    switch (cout.type) {
        case "text":
            fs.writeFile(cout.file,
                ver.text + "\n",
                callback);
            break;
        case "json":
            fs.writeFile(cout.file,
                '{"major":' + ver.major + ',"minor":' + ver.minor + ',"patch":' + ver.patch + ',"build":' + ver.build + ',"text":' + ver.text + '}' + "\n",
                callback);
            break;
        case "ts":
            fs.writeFile(cout.file,
                "export const version = {\n    major: " + ver.major + ",\n    minor: " + ver.minor + ",\n    patch: " + ver.patch + ",\n    build: "
                + ver.build + ",\n    text: '" + ver.text + "'\n};\n",
                callback);
            break;
        case "package":
            const conf = { 'bin-links': false, verbose: true, prefix: cout.dir };
            const cli = require('npm');
            cli.load(conf, (err) => {
            if(err) {
                    return reject(err);
            }
            cli.commands.version([ver.major + "." + ver.minor + "." + ver.patch], callback);
            cli.on('log', (message) => {
                    console.log(message);
                });
            });
            break;
    }
};

BuildAutoInc.prototype.apply = function (compiler) {
    const self = this;

    compiler.plugin('run', function (compilation, callback) {
        self.read(self.file, function (ver) {
            ver.build++;
            let tv = ver.major + '.' + ver.minor + '.' + ver.patch + '.' + ver.build;
            console.log('----------------------[', tv, "]---", ver);
            ver.text = tv;
            self.write({ type: 'text', file: self.file }, ver, callback);
        });
    });

    compiler.plugin('watch-run', function (compilation, callback) {
        self.read(self.file, function (ver) {
            ver.build++;
            let tv = ver.major + '.' + ver.minor + '.' + ver.patch + '.' + ver.build;
            console.log('----------------------[', tv, "]---", ver);
            ver.text = tv;
            self.write({ type: 'text', file: self.file }, ver, callback);
        });
    });

};

module.exports = BuildAutoInc;
<|endoftext|>


<commit_before>
var http = require('http'),
    fs = require('fs'),
    events = require('events'),
    queryString = require('querystring'),
    readline = require('readline'),
    sys = require('sys');

require('./ext');

try {
    var inspect = require('eyes').inspector();
} catch (e) {
    var inspect = function (obj) { sys.puts(sys.inspect(obj).white) }
}

var consoles = [];

this.Console = function (host, port, options) {
    this.host = host;
    this.port = port;
    this.options = options;
    this.timeout = this.options.timeout ? 5000 : 0;
    this.path = [];
    this.socket = null;
    this.cookies = {};
    consoles.push(this);
};

this.Console.prototype = new(function () {
    this.initialize = function () {
        var that = this;

        this.welcome();

        // Create Stream
        this.socket = http.createClient(this.port, this.host, this.options.useSSL);
        this.socket.on('connect', function () {
            that.socket.setTimeout(that.timeout);
            that.socket.removeAllListeners('timeout');
            that.socket.on('timeout', function () {
                sys.error('The request timed out.'.red.bold);
                that.socket.destroy();
                that.prompt();
            });
        });

        this.headers = { 'Accept':'*/*' };

        if (this.options.json) { this.headers['Content-Type'] = 'application/json' }

        this.stdin    = process.openStdin();
        this.readline = readline.createInterface(this.stdin, this.stdin.fd < 3);

        this.readline.addListener('line', function (cmd) {
            that.exec(cmd.trim());
        }).addListener('close', function () {
            process.stdout.write('\n');
            process.exit(0);
        });

        //this.stdin.setEncoding('utf8');
        this.stdin.addListener('data', function (str) {
            that.readline.write(str);
        });

        this.prompt();

        return this;
    };
    this.welcome = function () {
        sys.puts("> " + ("http-console " + exports.version).bold,
                 "> Welcome, enter \\help if you're lost.",
                 "> Connecting to " + this.host + " on port " + this.port + '.');
        sys.print('\n');
    };
    this.isConnected = function () {
        return this.socket.writeable && this.socket.readable;
    };
    this.connect = function () {
        if (! this.isConnected()) {
            // Clear the request queue.
            // Because this isn't part of the API,
            // we make sure it exists first.
            if (this.socket._outgoing) {
                this.socket._outgoing = [];
            }
            this.socket.connect(this.port, this.host);
        }
    };
    this.request = function (method, path, headers, callback) {
        var request, that = this;

        this.connect();
        this.headers['Host'] = this.host;

        for (var k in this.headers) { headers[k] = this.headers[k] }

        method = method.toUpperCase();
        path   = encodeURI(path);

        if (this.options.verbose) {
            sys.puts('> ' + (method + ' ' + path).grey);
        }

        request = this.socket.request(method, path, headers);

        request.addListener('response', function (res) {
            var body = "";

            if (that.options.rememberCookies) { that.rememberCookies(res.headers) }
            res.addListener('data', function (chunk) { body += chunk });
            res.addListener('end',  function ()      { callback(res, body) });
        }).addListener('error', function (e) {
            sys.error(e.toString().red);
        });

        return request;
    };
    this.exec = function (command) {
        var method, headers = {}, path = this.path, body,
            that = this,
            match, req;

        if (this.pending) {
            req = this.request(this.pending.method, this.pending.path, {
                'Content-Length' : command.length
            }, function (res, body) {
                that.printResponse(res, body, function () {
                    that.prompt();
                });
            });
            req.write(command);
            req.end();

            return this.pending = null;
        } else if (command[0] === '/') {
            if (command === '//') {
                this.path = [];
            } else {
                Array.prototype.push.apply(
                    this.path, command.slice(1).split('/')
                );
            }
        } else if (command === '..') {
            this.path.pop();
        } else if (command[0] === '\\') {
            switch (command.slice(1)) {
                case 'headers':
                    this.printHeaders(this.headers);
                    break;
                case 'options':
                    inspect(this.options);
                    break;
                case 'cookies':
                    inspect(this.cookies);
                    break;
                case 'help':
                    sys.puts(exports.help);
                    break;
                case 'json':
                    this.headers['Content-Type'] = 'application/json';
                    break;
                case 'exit':
                case 'q':
                    process.exit(0);
            }
        } else if (match = command.match(/^([a-zA-Z-]+):\s*(.*)/)) {
            if (match[2]) {
                this.headers[match[1]] = match[2];
            } else {
                delete(this.headers[match[1]]);
            }
        } else if (/^(GET|POST|PUT|HEAD|DELETE)/i.test(command)) {
            command = command.split(/\s+/);
            method  = command.shift().toUpperCase();
            path    = this.path.slice(0);

            if (command.length > 0) { path.push(command[0]) }

            path = ('/' + path.join('/')).replace(/\/+/g, '/');

            if (method === 'PUT' || method === 'POST') {
                this.pending = { method: method, path: path };
                this.dataPrompt();
            } else {
                this.request(method, path, {}, function (res, body) {
                    that.printResponse.call(that, res, body, function () {
                        that.prompt();
                    });
                }).end();
            }
            return;
        } else if (command) {
            sys.puts(("unknown command '" + command + "'").yellow.bold);
        }
        this.prompt();
    };
    this.printResponse = function (res, body, callback) {
        var status = ('HTTP/' + res.httpVersion +
                      ' '     + res.statusCode  +
                      ' '     + http.STATUS_CODES[res.statusCode]).bold, output;

        if      (res.statusCode >= 500) { status = status.red }
        else if (res.statusCode >= 400) { status = status.yellow }
        else if (res.statusCode >= 300) { status = status.cyan }
        else                            { status = status.green }

        sys.puts(status);

        this.printHeaders(res.headers);

        sys.print('\n');

        try       { output = JSON.parse(body) }
        catch (_) { output = body.trim() }

        if (typeof(output) === 'string') {
            output.length > 0 && sys.print(output.white + '\n');
        } else {
            inspect(output);
        }

        // Make sure the buffer is flushed before
        // we display the prompt.
        if (process.stdout.write('')) {
            callback();
        } else {
            process.stdout.addListener('drain', function () {
                callback();
            });
        }
    };
    this.prompt = function () {
        var protocol = this.options.useSSL ? 'https://' : 'http://',
            path     = '/' + this.path.join('/'),
            host     = this.host + ':' + this.port,
            arrow    = '> ';

        var length = (protocol + host + path + arrow).length;

        this.readline.setPrompt((protocol + host).grey + path + arrow.grey, length);
        this.readline.prompt();
    };
    this.dataPrompt = function () {
        var prompt = '... ';
        this.readline.setPrompt(prompt.grey, prompt.length);
        this.readline.prompt();
    };
    this.printHeaders = function (headers) {
        Object.keys(headers).forEach(function (k) {
            var key = k.replace(/\b([a-z])/g, function (_, m) {
                return m.toUpperCase();
            }).bold;
            sys.puts(key + ': ' + headers[k]);
        });
    };
    this.rememberCookies = function (headers) {
        var that = this;
        var parts, cookie, name, value;

        if ('set-cookie' in headers) {
            parts  = headers['set-cookie'].split(/; */);
            cookie = parts.shift().match(/^(.+?)=(.*)$/).slice(1);
            name   = cookie[0];
            value  = queryString.unescape(cookie[1]);

            this.cookies[name] = {
                value: value,
                options: {}
            };

            parts.forEach(function (part) {
                part = part.split('=');
                that.cookies[name].options[part[0]] = part[1];
            });
        }
        this.headers['Cookie'] = Object.keys(this.cookies).map(function (k) {
            return [k, queryString.escape(that.cookies[k].value) || ''].join('=');
        }).join(', ');
    };
});

this.version = fs.readFileSync(require('path').join(__dirname, '..', 'package.json'))
                 .toString().match(/"version"\s*:\s*"([\d.]+)"/)[1];

this.help = [
    '\\headers  ' +  'show active request headers.'.grey,
    '\\options  ' +  'show options.'.grey,
    '\\cookies  ' +  'show client cookies.'.grey,
    '\\json     ' +  'set \'Content-Type\' header to \'application/json\'.'.grey,
    '\\help     ' +  'display this message.'.grey,
    '\\exit     ' +  'exit console.'.grey,
    '\\q'
].join('\n');

process.addListener('uncaughtException', function (e) {
    sys.puts(e.stack.red);
    consoles[consoles.length - 1].prompt();
});

process.addListener('exit', function () {
    consoles.forEach(function (c) {
        c.socket.destroy();
        c.stdin.destroy();
    });
    sys.print('\n');
});

<commit_msg>use 'on' instead of 'addListener'<commit_after>
var http = require('http'),
    fs = require('fs'),
    events = require('events'),
    queryString = require('querystring'),
    readline = require('readline'),
    sys = require('sys');

require('./ext');

try {
    var inspect = require('eyes').inspector();
} catch (e) {
    var inspect = function (obj) { sys.puts(sys.inspect(obj).white) }
}

var consoles = [];

this.Console = function (host, port, options) {
    this.host = host;
    this.port = port;
    this.options = options;
    this.timeout = this.options.timeout ? 5000 : 0;
    this.path = [];
    this.socket = null;
    this.cookies = {};
    consoles.push(this);
};

this.Console.prototype = new(function () {
    this.initialize = function () {
        var that = this;

        this.welcome();

        // Create Stream
        this.socket = http.createClient(this.port, this.host, this.options.useSSL);
        this.socket.on('connect', function () {
            that.socket.setTimeout(that.timeout);
            that.socket.removeAllListeners('timeout');
            that.socket.on('timeout', function () {
                sys.error('The request timed out.'.red.bold);
                that.socket.destroy();
                that.prompt();
            });
        });

        this.headers = { 'Accept':'*/*' };

        if (this.options.json) { this.headers['Content-Type'] = 'application/json' }

        this.stdin    = process.openStdin();
        this.readline = readline.createInterface(this.stdin, this.stdin.fd < 3);

        this.readline.on('line', function (cmd) {
            that.exec(cmd.trim());
        }).on('close', function () {
            process.stdout.write('\n');
            process.exit(0);
        });

        //this.stdin.setEncoding('utf8');
        this.stdin.on('data', function (str) {
            that.readline.write(str);
        });

        this.prompt();

        return this;
    };
    this.welcome = function () {
        sys.puts("> " + ("http-console " + exports.version).bold,
                 "> Welcome, enter \\help if you're lost.",
                 "> Connecting to " + this.host + " on port " + this.port + '.');
        sys.print('\n');
    };
    this.isConnected = function () {
        return this.socket.writeable && this.socket.readable;
    };
    this.connect = function () {
        if (! this.isConnected()) {
            // Clear the request queue.
            // Because this isn't part of the API,
            // we make sure it exists first.
            if (this.socket._outgoing) {
                this.socket._outgoing = [];
            }
            this.socket.connect(this.port, this.host);
        }
    };
    this.request = function (method, path, headers, callback) {
        var request, that = this;

        this.connect();
        this.headers['Host'] = this.host;

        for (var k in this.headers) { headers[k] = this.headers[k] }

        method = method.toUpperCase();
        path   = encodeURI(path);

        if (this.options.verbose) {
            sys.puts('> ' + (method + ' ' + path).grey);
        }

        request = this.socket.request(method, path, headers);

        request.on('response', function (res) {
            var body = "";

            if (that.options.rememberCookies) { that.rememberCookies(res.headers) }
            res.on('data', function (chunk) { body += chunk });
            res.on('end',  function ()      { callback(res, body) });
        }).on('error', function (e) {
            sys.error(e.toString().red);
        });

        return request;
    };
    this.exec = function (command) {
        var method, headers = {}, path = this.path, body,
            that = this,
            match, req;

        if (this.pending) {
            req = this.request(this.pending.method, this.pending.path, {
                'Content-Length' : command.length
            }, function (res, body) {
                that.printResponse(res, body, function () {
                    that.prompt();
                });
            });
            req.write(command);
            req.end();

            return this.pending = null;
        } else if (command[0] === '/') {
            if (command === '//') {
                this.path = [];
            } else {
                Array.prototype.push.apply(
                    this.path, command.slice(1).split('/')
                );
            }
        } else if (command === '..') {
            this.path.pop();
        } else if (command[0] === '\\') {
            switch (command.slice(1)) {
                case 'headers':
                    this.printHeaders(this.headers);
                    break;
                case 'options':
                    inspect(this.options);
                    break;
                case 'cookies':
                    inspect(this.cookies);
                    break;
                case 'help':
                    sys.puts(exports.help);
                    break;
                case 'json':
                    this.headers['Content-Type'] = 'application/json';
                    break;
                case 'exit':
                case 'q':
                    process.exit(0);
            }
        } else if (match = command.match(/^([a-zA-Z-]+):\s*(.*)/)) {
            if (match[2]) {
                this.headers[match[1]] = match[2];
            } else {
                delete(this.headers[match[1]]);
            }
        } else if (/^(GET|POST|PUT|HEAD|DELETE)/i.test(command)) {
            command = command.split(/\s+/);
            method  = command.shift().toUpperCase();
            path    = this.path.slice(0);

            if (command.length > 0) { path.push(command[0]) }

            path = ('/' + path.join('/')).replace(/\/+/g, '/');

            if (method === 'PUT' || method === 'POST') {
                this.pending = { method: method, path: path };
                this.dataPrompt();
            } else {
                this.request(method, path, {}, function (res, body) {
                    that.printResponse.call(that, res, body, function () {
                        that.prompt();
                    });
                }).end();
            }
            return;
        } else if (command) {
            sys.puts(("unknown command '" + command + "'").yellow.bold);
        }
        this.prompt();
    };
    this.printResponse = function (res, body, callback) {
        var status = ('HTTP/' + res.httpVersion +
                      ' '     + res.statusCode  +
                      ' '     + http.STATUS_CODES[res.statusCode]).bold, output;

        if      (res.statusCode >= 500) { status = status.red }
        else if (res.statusCode >= 400) { status = status.yellow }
        else if (res.statusCode >= 300) { status = status.cyan }
        else                            { status = status.green }

        sys.puts(status);

        this.printHeaders(res.headers);

        sys.print('\n');

        try       { output = JSON.parse(body) }
        catch (_) { output = body.trim() }

        if (typeof(output) === 'string') {
            output.length > 0 && sys.print(output.white + '\n');
        } else {
            inspect(output);
        }

        // Make sure the buffer is flushed before
        // we display the prompt.
        if (process.stdout.write('')) {
            callback();
        } else {
            process.stdout.on('drain', function () {
                callback();
            });
        }
    };
    this.prompt = function () {
        var protocol = this.options.useSSL ? 'https://' : 'http://',
            path     = '/' + this.path.join('/'),
            host     = this.host + ':' + this.port,
            arrow    = '> ';

        var length = (protocol + host + path + arrow).length;

        this.readline.setPrompt((protocol + host).grey + path + arrow.grey, length);
        this.readline.prompt();
    };
    this.dataPrompt = function () {
        var prompt = '... ';
        this.readline.setPrompt(prompt.grey, prompt.length);
        this.readline.prompt();
    };
    this.printHeaders = function (headers) {
        Object.keys(headers).forEach(function (k) {
            var key = k.replace(/\b([a-z])/g, function (_, m) {
                return m.toUpperCase();
            }).bold;
            sys.puts(key + ': ' + headers[k]);
        });
    };
    this.rememberCookies = function (headers) {
        var that = this;
        var parts, cookie, name, value;

        if ('set-cookie' in headers) {
            parts  = headers['set-cookie'].split(/; */);
            cookie = parts.shift().match(/^(.+?)=(.*)$/).slice(1);
            name   = cookie[0];
            value  = queryString.unescape(cookie[1]);

            this.cookies[name] = {
                value: value,
                options: {}
            };

            parts.forEach(function (part) {
                part = part.split('=');
                that.cookies[name].options[part[0]] = part[1];
            });
        }
        this.headers['Cookie'] = Object.keys(this.cookies).map(function (k) {
            return [k, queryString.escape(that.cookies[k].value) || ''].join('=');
        }).join(', ');
    };
});

this.version = fs.readFileSync(require('path').join(__dirname, '..', 'package.json'))
                 .toString().match(/"version"\s*:\s*"([\d.]+)"/)[1];

this.help = [
    '\\headers  ' +  'show active request headers.'.grey,
    '\\options  ' +  'show options.'.grey,
    '\\cookies  ' +  'show client cookies.'.grey,
    '\\json     ' +  'set \'Content-Type\' header to \'application/json\'.'.grey,
    '\\help     ' +  'display this message.'.grey,
    '\\exit     ' +  'exit console.'.grey,
    '\\q'
].join('\n');

process.on('uncaughtException', function (e) {
    sys.puts(e.stack.red);
    consoles[consoles.length - 1].prompt();
});

process.on('exit', function () {
    consoles.forEach(function (c) {
        c.socket.destroy();
        c.stdin.destroy();
    });
    sys.print('\n');
});

<|endoftext|>


<commit_before>var request = require('request')
var bluebird = require('bluebird')

var templates = require('./templates.js')
var parser = require('./parsers.js')

var baseUrl = 'https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx'

var Darwin = function(apiKey, options){
	this.key = apiKey || process.env.DARWIN_TOKEN
	console.log('this.key = ' + this.key)
}

Darwin.prototype.thenablePOST = function(xml){
   var xmlWithToken = xml.replace('${TOKEN}',this.key)
   return new bluebird(function(resolve, reject){
      request.post({
         url: baseUrl,
         headers:{
            'content-type':'text/xml'
         },
         body:xmlWithToken
         }, function(err, response, body){
         if(err){
            reject(err)
         }else if(response.statusCode > 300){
            reject(response)
         }else{
            resolve(body)
         }
      })
   })
}

Darwin.prototype.getDepartureBoard = function(station, options, callback){
	if(options && options.rows){
		var requestXML = templates.departureBoard.replace('${ROWS}', numrows)
	}else{
		var requestXML = templates.departureBoard.replace('${ROWS}', 15)
	}

	requestXML = requestXML.replace('${FROM}', station)
	if(options && options.filter){
		requestXML = requestXML.replace('${FILTER}', options.filter)
	}else{
		requestXML = requestXML.replace('${FILTER}', '')
	}
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseDepartureBoardResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

Darwin.prototype.getArrivalsBoard = function(station, options, callback){
	if(options && options.rows){
		var requestXML = templates.departureBoard.replace('${ROWS}', numrows)
	}else{
		var requestXML = templates.departureBoard.replace('${ROWS}', 15)
	}
	var requestXML = templates.arrivalsBoard.replace('${ROWS}', numrows)
	requestXML = requestXML.replace('${FROM}', station)
	if(options && options.filter){
		requestXML = requestXML.replace('${FILTER}', options.filter)
	}else{
		requestXML = requestXML.replace('${FILTER}', '')
	}
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseArrivalsBoardResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

Darwin.prototype.getServiceDetails = function(serviceId, callback){
	var requestXML = templates.serviceDetails.replace('${SERVICEID}', serviceId)
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseServiceIdResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

module.exports = Darwin<commit_msg>fix numrows accessor<commit_after>var request = require('request')
var bluebird = require('bluebird')

var templates = require('./templates.js')
var parser = require('./parsers.js')

var baseUrl = 'https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb9.asmx'

var Darwin = function(apiKey, options){
	this.key = apiKey || process.env.DARWIN_TOKEN
	console.log('this.key = ' + this.key)
}

Darwin.prototype.thenablePOST = function(xml){
   var xmlWithToken = xml.replace('${TOKEN}',this.key)
   return new bluebird(function(resolve, reject){
      request.post({
         url: baseUrl,
         headers:{
            'content-type':'text/xml'
         },
         body:xmlWithToken
         }, function(err, response, body){
         if(err){
            reject(err)
         }else if(response.statusCode > 300){
            reject(response)
         }else{
            resolve(body)
         }
      })
   })
}

Darwin.prototype.getDepartureBoard = function(station, options, callback){
	if(options && options.rows){
		var requestXML = templates.departureBoard.replace('${ROWS}', options.numrows)
	}else{
		var requestXML = templates.departureBoard.replace('${ROWS}', 15)
	}

	requestXML = requestXML.replace('${FROM}', station)
	if(options && options.filter){
		requestXML = requestXML.replace('${FILTER}', options.filter)
	}else{
		requestXML = requestXML.replace('${FILTER}', '')
	}
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseDepartureBoardResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

Darwin.prototype.getArrivalsBoard = function(station, options, callback){
	if(options && options.rows){
		var requestXML = templates.departureBoard.replace('${ROWS}', options.numrows)
	}else{
		var requestXML = templates.departureBoard.replace('${ROWS}', 15)
	}
	requestXML = requestXML.replace('${FROM}', station)
	if(options && options.filter){
		requestXML = requestXML.replace('${FILTER}', options.filter)
	}else{
		requestXML = requestXML.replace('${FILTER}', '')
	}
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseArrivalsBoardResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

Darwin.prototype.getServiceDetails = function(serviceId, callback){
	var requestXML = templates.serviceDetails.replace('${SERVICEID}', serviceId)
	this.thenablePOST(requestXML).then(function(result){
		callback(null, parser.parseServiceIdResponse(result))
	}).catch(function(err){
		callback(err, null)
	})
}

module.exports = Darwin<|endoftext|>


<commit_before>/**
 * request.js
 *
 * @author: Harish Anchu <harishanchu@gmail.com>
 * @copyright 2015, QuorraJS. All rights reserved.
 * @license Licensed under MIT
 */

//@todo: needs proper testing

var accepts = require('accepts');
var typeis = require('type-is');
var http = require('http');
var fresh = require('fresh');
var parseRange = require('range-parser');
var parse = require('parseurl');
var str = require('../support/str');

/**
 * Request prototype.
 */

var req = exports = module.exports = {
  __proto__: http.IncomingMessage.prototype
};

/**
 * Return request header.
 *
 * The `Referrer` header field is special-cased,
 * both `Referrer` and `Referer` are interchangeable.
 *
 * Examples:
 *
 *     req.get('Content-Type');
 *     // => "text/plain"
 *
 *     req.get('content-type');
 *     // => "text/plain"
 *
 *     req.get('Something');
 *     // => undefined
 *
 * Aliased as `req.header()`.
 *
 * @param {String} name
 * @return {String}
 */

req.get =
req.header = function(name){
  switch (name = name.toLowerCase()) {
    case 'referer':
    case 'referrer':
      return this.headers.referrer
        || this.headers.referer;
    default:
      return this.headers[name];
  }
};

/**
 * @todo: update docs.
 *
 * Check if the given `type(s)` is acceptable, returning
 * the best match when true, otherwise `undefined`, in which
 * case you should respond with 406 "Not Acceptable".
 *
 * The `type` value may be a single mime type string
 * such as "application/json", the extension name
 * such as "json", a comma-delimted list such as "json, html, text/plain",
 * an argument list such as `"json", "html", "text/plain"`,
 * or an array `["json", "html", "text/plain"]`. When a list
 * or array is given the _best_ match, if any is returned.
 *
 * Examples:
 *
 *     // Accept: text/html
 *     req.accepts('html');
 *     // => "html"
 *
 *     // Accept: text/*, application/json
 *     req.accepts('html');
 *     // => "html"
 *     req.accepts('text/html');
 *     // => "text/html"
 *     req.accepts('json, text');
 *     // => "json"
 *     req.accepts('application/json');
 *     // => "application/json"
 *
 *     // Accept: text/*, application/json
 *     req.accepts('image/png');
 *     req.accepts('png');
 *     // => undefined
 *
 *     // Accept: text/*;q=.5, application/json
 *     req.accepts(['html', 'json']);
 *     req.accepts('html', 'json');
 *     req.accepts('html, json');
 *     // => "json"
 *
 * @param {String|Array} type(s)
 * @return {String}
 */

req.accepts = function(){
  var accept = accepts(this);
  return accept.types.apply(accept, arguments);
};

/**
 * Check if the given `encoding` is accepted.
 *
 * @param {String} encoding
 * @return {Boolean}
 */

req.acceptsEncoding = // backwards compatibility
req.acceptsEncodings = function(){
  var accept = accepts(this);
  return accept.encodings.apply(accept, arguments);
};

/**
 * To do: update docs.
 *
 * Check if the given `charset` is acceptable,
 * otherwise you should respond with 406 "Not Acceptable".
 *
 * @param {String} charset
 * @return {Boolean}
 */

req.acceptsCharset = // backwards compatibility
req.acceptsCharsets = function(){
  var accept = accepts(this);
  return accept.charsets.apply(accept, arguments);
};

/**
 * To do: update docs.
 *
 * Check if the given `lang` is acceptable,
 * otherwise you should respond with 406 "Not Acceptable".
 *
 * @param {String} lang
 * @return {Boolean}
 */

req.acceptsLanguage = // backwards compatibility
req.acceptsLanguages = function(){
  var accept = accepts(this);
  return accept.languages.apply(accept, arguments);
};

/**
 * Parse Range header field,
 * capping to the given `size`.
 *
 * Unspecified ranges such as "0-" require
 * knowledge of your resource length. In
 * the case of a byte range this is of course
 * the total number of bytes. If the Range
 * header field is not given `null` is returned,
 * `-1` when unsatisfiable, `-2` when syntactically invalid.
 *
 * NOTE: remember that ranges are inclusive, so
 * for example "Range: users=0-3" should respond
 * with 4 users when available, not 3.
 *
 * @param {Number} size
 * @return {Array}
 */

req.range = function(size){
  var range = this.get('Range');
  if (!range) return;
  return parseRange(size, range);
};

/**
 * Return the value of param `name` when present or `defaultValue`.
 *
 *  - Checks route placeholders, ex: _/user/:id_
 *  - Checks body params, ex: id=12, {"id":12}
 *  - Checks query string params, ex: ?id=12
 *
 * To utilize request bodies, `req.body`
 * should be an object. This can be done by using
 * the `bodyParser()` middleware.
 *
 * @param {String} name
 * @param {Mixed} [defaultValue]
 * @return {String}
 */

req.param = function(name, defaultValue){
  var params = this.params || {};
  var body = this.body || {};
  var query = this.query || {};
  if (null != params[name] && params.hasOwnProperty(name)) return params[name];
  if (null != body[name]) return body[name];
  if (null != query[name]) return query[name];
  return defaultValue;
};

/**
 * Return the route parameters object.
 *
 * @return Array
 *
 * @throws Error
 */
req.__defineGetter__('routeParameters', function()
{
    if (isset(this.params))
    {
        Object.keys(this.params).map(function(value){
            if(str.isString(this.params['value'])) {
                this.params['value'] = decodeURIComponent(this.params['value']);
            }
        }.bind(this));

        return this.params;
    }

    throw new Error("Route is not bound.");
});

/**
 * Return the route parameter for the specified key.
 *
 * @param  {string}  name
 * @param  {*}  defaultValue
 * @return string
 */
req.routeParameter = function(name, defaultValue) {
    var parameters = this.parameters();
    return parameters[name]?parameters[name]:defaultValue;
};

/**
 * Check if the incoming request contains the "Content-Type"
 * header field, and it contains the give mime `type`.
 *
 * Examples:
 *
 *      // With Content-Type: text/html; charset=utf-8
 *      req.is('html');
 *      req.is('text/html');
 *      req.is('text/*');
 *      // => true
 *
 *      // When Content-Type is application/json
 *      req.is('json');
 *      req.is('application/json');
 *      req.is('application/*');
 *      // => true
 *
 *      req.is('html');
 *      // => false
 *
 * @param {String} type
 * @return {Boolean}
 */

req.is = function(types){
  if (!Array.isArray(types)) types = [].slice.call(arguments);
  return typeis(this, types);
};

/**
 * Return the protocol string "http" or "https"
 * when requested with TLS. When the "trust proxy"
 * setting is enabled the "X-Forwarded-Proto" header
 * field will be trusted. If you're running behind
 * a reverse proxy that supplies https for you this
 * may be enabled.
 *
 * @return {String}
 */
//@todo: modify
req.__defineGetter__('protocol', function(){
  var trustProxy = false/*this.app.get('trust proxy')*/;
  if (this.connection.encrypted) return 'https';
  if (!trustProxy) return 'http';
  var proto = this.get('X-Forwarded-Proto') || 'http';
  return proto.split(/\s*,\s*/)[0];
});

/**
 * Short-hand for:
 *
 *    req.protocol == 'https'
 *
 * @return {Boolean}
 */

req.__defineGetter__('secure', function(){
  return 'https' == this.protocol;
});

/**
 * Return the remote address, or when
 * "trust proxy" is `true` return
 * the upstream addr.
 *
 * @return {String}
 */

req.__defineGetter__('ip', function(){
  return this.ips[0] || this.connection.remoteAddress;
});

/**
 * When "trust proxy" is `true`, parse
 * the "X-Forwarded-For" ip address list.
 *
 * For example if the value were "client, proxy1, proxy2"
 * you would receive the array `["client", "proxy1", "proxy2"]`
 * where "proxy2" is the furthest down-stream.
 *
 * @return {Array}
 */
//@todo: do it later
/*req.__defineGetter__('ips', function(){
  var trustProxy = this.app.get('trust proxy');
  var val = this.get('X-Forwarded-For');
  return trustProxy && val
    ? val.split(/ *, *//*)
    : [];
});*/

/**
 * Return subdomains as an array.
 *
 * Subdomains are the dot-separated parts of the host before the main domain of
 * the app. By default, the domain of the app is assumed to be the last two
 * parts of the host. This can be changed by setting "subdomain offset".
 *
 * For example, if the domain is "tobi.ferrets.example.com":
 * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
 * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
 *
 * @return {Array}
 */
//@todo: do it later
/*req.__defineGetter__('subdomains', function(){
  var offset = this.app.get('subdomain offset');
  return (this.host || '')
    .split('.')
    .reverse()
    .slice(offset);
});*/

/**
 * Short-hand for `url.parse(req.url).pathname`.
 *
 * @return {String}
 */
//@todo: note '/' is not stripped from path
req.__defineGetter__('path', function(){
  return parse(this).pathname;
});

/**
 * Parse the "Host" header field hostname.
 *
 * @return {String}
 */
//@todo: do it later
/*req.__defineGetter__('host', function(){
  var trustProxy = this.app.get('trust proxy');
  var host = trustProxy && this.get('X-Forwarded-Host');
  host = host || this.get('Host');
  if (!host) return;
  var offset = host[0] === '['
    ? host.indexOf(']') + 1
    : 0;
  var index = host.indexOf(':', offset);
  return ~index
    ? host.substring(0, index)
    : host;
});*/

/**
 * Check if the request is fresh, aka
 * Last-Modified and/or the ETag
 * still match.
 *
 * @return {Boolean}
 */

req.__defineGetter__('fresh', function(){
  var method = this.method;
  var s = this.res.statusCode;

  // GET or HEAD for weak freshness validation only
  if ('GET' != method && 'HEAD' != method) return false;

  // 2xx or 304 as per rfc2616 14.26
  if ((s >= 200 && s < 300) || 304 == s) {
    return fresh(this.headers, this.res._headers);
  }

  return false;
});

/**
 * Check if the request is stale, aka
 * "Last-Modified" and / or the "ETag" for the
 * resource has changed.
 *
 * @return {Boolean}
 */

req.__defineGetter__('stale', function(){
  return !this.fresh;
});

/**
 * Check if the request was an _XMLHttpRequest_.
 *
 * @return {Boolean}
 */

req.__defineGetter__('xhr', function(){
  var val = this.get('X-Requested-With') || '';
  return 'xmlhttprequest' == val.toLowerCase();
});<commit_msg>Update getter method for protocol<commit_after>/**
 * request.js
 *
 * @author: Harish Anchu <harishanchu@gmail.com>
 * @copyright 2015, QuorraJS. All rights reserved.
 * @license Licensed under MIT
 */

//@todo: needs proper testing

var accepts = require('accepts');
var typeis = require('type-is');
var http = require('http');
var fresh = require('fresh');
var parseRange = require('range-parser');
var parse = require('parseurl');
var str = require('../support/str');

/**
 * Request prototype.
 */

var req = exports = module.exports = {
  __proto__: http.IncomingMessage.prototype
};

/**
 * Return request header.
 *
 * The `Referrer` header field is special-cased,
 * both `Referrer` and `Referer` are interchangeable.
 *
 * Examples:
 *
 *     req.get('Content-Type');
 *     // => "text/plain"
 *
 *     req.get('content-type');
 *     // => "text/plain"
 *
 *     req.get('Something');
 *     // => undefined
 *
 * Aliased as `req.header()`.
 *
 * @param {String} name
 * @return {String}
 */

req.get =
req.header = function(name){
  switch (name = name.toLowerCase()) {
    case 'referer':
    case 'referrer':
      return this.headers.referrer
        || this.headers.referer;
    default:
      return this.headers[name];
  }
};

/**
 * @todo: update docs.
 *
 * Check if the given `type(s)` is acceptable, returning
 * the best match when true, otherwise `undefined`, in which
 * case you should respond with 406 "Not Acceptable".
 *
 * The `type` value may be a single mime type string
 * such as "application/json", the extension name
 * such as "json", a comma-delimted list such as "json, html, text/plain",
 * an argument list such as `"json", "html", "text/plain"`,
 * or an array `["json", "html", "text/plain"]`. When a list
 * or array is given the _best_ match, if any is returned.
 *
 * Examples:
 *
 *     // Accept: text/html
 *     req.accepts('html');
 *     // => "html"
 *
 *     // Accept: text/*, application/json
 *     req.accepts('html');
 *     // => "html"
 *     req.accepts('text/html');
 *     // => "text/html"
 *     req.accepts('json, text');
 *     // => "json"
 *     req.accepts('application/json');
 *     // => "application/json"
 *
 *     // Accept: text/*, application/json
 *     req.accepts('image/png');
 *     req.accepts('png');
 *     // => undefined
 *
 *     // Accept: text/*;q=.5, application/json
 *     req.accepts(['html', 'json']);
 *     req.accepts('html', 'json');
 *     req.accepts('html, json');
 *     // => "json"
 *
 * @param {String|Array} type(s)
 * @return {String}
 */

req.accepts = function(){
  var accept = accepts(this);
  return accept.types.apply(accept, arguments);
};

/**
 * Check if the given `encoding` is accepted.
 *
 * @param {String} encoding
 * @return {Boolean}
 */

req.acceptsEncoding = // backwards compatibility
req.acceptsEncodings = function(){
  var accept = accepts(this);
  return accept.encodings.apply(accept, arguments);
};

/**
 * To do: update docs.
 *
 * Check if the given `charset` is acceptable,
 * otherwise you should respond with 406 "Not Acceptable".
 *
 * @param {String} charset
 * @return {Boolean}
 */

req.acceptsCharset = // backwards compatibility
req.acceptsCharsets = function(){
  var accept = accepts(this);
  return accept.charsets.apply(accept, arguments);
};

/**
 * To do: update docs.
 *
 * Check if the given `lang` is acceptable,
 * otherwise you should respond with 406 "Not Acceptable".
 *
 * @param {String} lang
 * @return {Boolean}
 */

req.acceptsLanguage = // backwards compatibility
req.acceptsLanguages = function(){
  var accept = accepts(this);
  return accept.languages.apply(accept, arguments);
};

/**
 * Parse Range header field,
 * capping to the given `size`.
 *
 * Unspecified ranges such as "0-" require
 * knowledge of your resource length. In
 * the case of a byte range this is of course
 * the total number of bytes. If the Range
 * header field is not given `null` is returned,
 * `-1` when unsatisfiable, `-2` when syntactically invalid.
 *
 * NOTE: remember that ranges are inclusive, so
 * for example "Range: users=0-3" should respond
 * with 4 users when available, not 3.
 *
 * @param {Number} size
 * @return {Array}
 */

req.range = function(size){
  var range = this.get('Range');
  if (!range) return;
  return parseRange(size, range);
};

/**
 * Return the value of param `name` when present or `defaultValue`.
 *
 *  - Checks route placeholders, ex: _/user/:id_
 *  - Checks body params, ex: id=12, {"id":12}
 *  - Checks query string params, ex: ?id=12
 *
 * To utilize request bodies, `req.body`
 * should be an object. This can be done by using
 * the `bodyParser()` middleware.
 *
 * @param {String} name
 * @param {Mixed} [defaultValue]
 * @return {String}
 */

req.param = function(name, defaultValue){
  var params = this.params || {};
  var body = this.body || {};
  var query = this.query || {};
  if (null != params[name] && params.hasOwnProperty(name)) return params[name];
  if (null != body[name]) return body[name];
  if (null != query[name]) return query[name];
  return defaultValue;
};

/**
 * Return the route parameters object.
 *
 * @return Array
 *
 * @throws Error
 */
req.__defineGetter__('routeParameters', function()
{
    if (isset(this.params))
    {
        Object.keys(this.params).map(function(value){
            if(str.isString(this.params['value'])) {
                this.params['value'] = decodeURIComponent(this.params['value']);
            }
        }.bind(this));

        return this.params;
    }

    throw new Error("Route is not bound.");
});

/**
 * Return the route parameter for the specified key.
 *
 * @param  {string}  name
 * @param  {*}  defaultValue
 * @return string
 */
req.routeParameter = function(name, defaultValue) {
    var parameters = this.parameters();
    return parameters[name]?parameters[name]:defaultValue;
};

/**
 * Check if the incoming request contains the "Content-Type"
 * header field, and it contains the give mime `type`.
 *
 * Examples:
 *
 *      // With Content-Type: text/html; charset=utf-8
 *      req.is('html');
 *      req.is('text/html');
 *      req.is('text/*');
 *      // => true
 *
 *      // When Content-Type is application/json
 *      req.is('json');
 *      req.is('application/json');
 *      req.is('application/*');
 *      // => true
 *
 *      req.is('html');
 *      // => false
 *
 * @param {String} type
 * @return {Boolean}
 */

req.is = function(types){
  if (!Array.isArray(types)) types = [].slice.call(arguments);
  return typeis(this, types);
};

/**
 * Return the protocol string "http" or "https"
 * when requested with TLS. When the "trust proxy"
 * setting is enabled the "X-Forwarded-Proto" header
 * field will be trusted. If you're running behind
 * a reverse proxy that supplies https for you this
 * may be enabled.
 *
 * @return {String}
 */
//@todo: modify
req.__defineGetter__('protocol', function(){
  var trustProxy = this.app.config.get('app').trustProxy;
  if (this.connection.encrypted) return 'https';
  if (!trustProxy) return 'http';
  var proto = this.get('X-Forwarded-Proto') || 'http';
  return proto.split(/\s*,\s*/)[0];
});

/**
 * Short-hand for:
 *
 *    req.protocol == 'https'
 *
 * @return {Boolean}
 */

req.__defineGetter__('secure', function(){
  return 'https' == this.protocol;
});

/**
 * Return the remote address, or when
 * "trust proxy" is `true` return
 * the upstream addr.
 *
 * @return {String}
 */

req.__defineGetter__('ip', function(){
  return this.ips[0] || this.connection.remoteAddress;
});

/**
 * When "trust proxy" is `true`, parse
 * the "X-Forwarded-For" ip address list.
 *
 * For example if the value were "client, proxy1, proxy2"
 * you would receive the array `["client", "proxy1", "proxy2"]`
 * where "proxy2" is the furthest down-stream.
 *
 * @return {Array}
 */
//@todo: do it later
/*req.__defineGetter__('ips', function(){
  var trustProxy = this.app.get('trust proxy');
  var val = this.get('X-Forwarded-For');
  return trustProxy && val
    ? val.split(/ *, *//*)
    : [];
});*/

/**
 * Return subdomains as an array.
 *
 * Subdomains are the dot-separated parts of the host before the main domain of
 * the app. By default, the domain of the app is assumed to be the last two
 * parts of the host. This can be changed by setting "subdomain offset".
 *
 * For example, if the domain is "tobi.ferrets.example.com":
 * If "subdomain offset" is not set, req.subdomains is `["ferrets", "tobi"]`.
 * If "subdomain offset" is 3, req.subdomains is `["tobi"]`.
 *
 * @return {Array}
 */
//@todo: do it later
/*req.__defineGetter__('subdomains', function(){
  var offset = this.app.get('subdomain offset');
  return (this.host || '')
    .split('.')
    .reverse()
    .slice(offset);
});*/

/**
 * Short-hand for `url.parse(req.url).pathname`.
 *
 * @return {String}
 */
//@todo: note '/' is not stripped from path
req.__defineGetter__('path', function(){
  return parse(this).pathname;
});

/**
 * Parse the "Host" header field hostname.
 *
 * @return {String}
 */
//@todo: do it later
/*req.__defineGetter__('host', function(){
  var trustProxy = this.app.get('trust proxy');
  var host = trustProxy && this.get('X-Forwarded-Host');
  host = host || this.get('Host');
  if (!host) return;
  var offset = host[0] === '['
    ? host.indexOf(']') + 1
    : 0;
  var index = host.indexOf(':', offset);
  return ~index
    ? host.substring(0, index)
    : host;
});*/

/**
 * Check if the request is fresh, aka
 * Last-Modified and/or the ETag
 * still match.
 *
 * @return {Boolean}
 */

req.__defineGetter__('fresh', function(){
  var method = this.method;
  var s = this.res.statusCode;

  // GET or HEAD for weak freshness validation only
  if ('GET' != method && 'HEAD' != method) return false;

  // 2xx or 304 as per rfc2616 14.26
  if ((s >= 200 && s < 300) || 304 == s) {
    return fresh(this.headers, this.res._headers);
  }

  return false;
});

/**
 * Check if the request is stale, aka
 * "Last-Modified" and / or the "ETag" for the
 * resource has changed.
 *
 * @return {Boolean}
 */

req.__defineGetter__('stale', function(){
  return !this.fresh;
});

/**
 * Check if the request was an _XMLHttpRequest_.
 *
 * @return {Boolean}
 */

req.__defineGetter__('xhr', function(){
  var val = this.get('X-Requested-With') || '';
  return 'xmlhttprequest' == val.toLowerCase();
});<|endoftext|>


<commit_before>var express = require('express')
var path = require("path")
var wechat = require('wechat')

// get config
var weConfig = require('./config')
var helper = require('./modules/helper')

// create app
var app = express()

// menu
var WechatAPI = require('wechat-api')
var menuModel = require('./modules/menu')
var api = new WechatAPI(weConfig.appid, weConfig.secret)
api.createMenu(menuModel, function(){})

// auto reply
app.use('/wechat', wechat(weConfig, function(req, res, next) {
	var msg = req.weixin

    if(msg.MsgType === 'event' && msg.Event === 'subscribe'){
        res.reply('等你好久了！点击链接以完成绑定(ง •_•)ง')
        next()
    }

    if(msg.MsgType === 'text'){
        if (msg.Content === 'hehe') {
    		res.reply('...')
    	} else {
    		res.reply('测试中...')
        }
        next()
    }
}))

// test
app.get('/reserve', function(req, res) {
	res.sendFile(path.join(__dirname + '/reserve.html'))
})

// reserve
app.use(express.query())
app.get('/info', function(req, res) {
	helper.getBaseInfo(app, req.query.code, function(err, baseInfoQuery){
        if(err){
            res.send(JSON.stringify(err))
        } else{
            res.redirect('/reserve?' + baseInfoQuery)
        }
	})
})

// binding
app.get('/binding', function(req, res) {
    helper.getBaseInfo(app, req.query.code, function(err, baseInfoQuery){
        if(err){
            res.send(JSON.stringify(err))
        } else{
            res.sendFile(path.join(__dirname + '/binding.html?' + baseInfoQuery))
        }
	})
})

app.listen(weConfig.port)
<commit_msg>fix get base info<commit_after>var express = require('express')
var path = require("path")
var wechat = require('wechat')

// get config
var weConfig = require('./config')
var helper = require('./modules/helper')

// create app
var app = express()

// menu
var WechatAPI = require('wechat-api')
var menuModel = require('./modules/menu')
var api = new WechatAPI(weConfig.appid, weConfig.secret)
api.createMenu(menuModel, function(){})

// auto reply
app.use('/wechat', wechat(weConfig, function(req, res, next) {
	var msg = req.weixin

    if(msg.MsgType === 'event' && msg.Event === 'subscribe'){
        res.reply('等你好久了！点击链接以完成绑定(ง •_•)ง')
        next()
    }

    if(msg.MsgType === 'text'){
        if (msg.Content === 'hehe') {
    		res.reply('...')
    	} else {
    		res.reply('测试中...')
        }
        next()
    }
}))

// test reserve
app.get('/reserve', function(req, res) {
	res.sendFile(path.join(__dirname + '/reserve.html'))
})

// binding
app.get('/binding', function(req, res) {
    res.sendFile(path.join(__dirname + '/binding.html'))
})

// reserve
app.use(express.query())
app.get('/info', function(req, res) {
	helper.getBaseInfo(app, req.query.code, function(err, baseInfoQuery){
        if(err){
            res.send(JSON.stringify(err))
        } else{
            res.redirect(req.query.state + '?' + baseInfoQuery)
        }
	})
})

app.listen(weConfig.port)
<|endoftext|>


<commit_before>"use strict";

module.exports = require("./libs/throttle");<commit_msg>path fix<commit_after>"use strict";

module.exports = require("./lib/throttle");<|endoftext|>


<commit_before>var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var cron = require('node-cron');
var cheerio = require('cheerio');
var Nightmare = require('nightmare');

var app = express();
app.listen((process.env.PORT || 3000));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// Current version
ver = 'v.0.0.31';
// Facebook pageId
pageId = '1167308473348175';
// My user on Facebook
me = '1221242727898531';

// Server endpoint
app.get('/', function (req, res){
    res.send('JKDbot here! ' + ver);
    getUserIds();
});

// Facebook webhook
app.get('/webhook', function (req, res){
    if (req.query['hub.verify_token'] === 'jkdbot_verify_token') {
        res.send(req.query['hub.challenge']);
    } else {
        res.send('Invalid verify token');
    }
});

// Handler receiving messages
app.post('/webhook', function (req, res){
    var events = req.body.entry[0].messaging;
    for (i = 0; i < events.length; i++){
        var event = events[i];
        if (event.message && event.message.text) {
            switch(event.message.text) {
                // Housekeeping commands
                case("cmd_version"):
                    sendMessage(event.sender.id, {text: ver});
                    break;
                case("cmd_subscribers"):
                    sendMessage(event.sender.id, {text: getUserIds()});
                    break;
                case("cmd_timezone"):
                    getUserAttributes(event.sender.id).then(function(res){
                        sendMessage(event.sender.id, {text: res.timezone});
                    });
                    break;
                case("cmd_stop_cron"):
                    task.stop();
                    break;
                case("cmd_stop_restart"):
                    task.start();
                    break;
                // Ack to sender
                default:
                    sendMessage(event.sender.id, {text: "Message received: " + event.message.text + " by " + event.sender.id});
                    break;
            }
        }
    }
    res.sendStatus(200);
});

// Scheduler (Everyday at 09_00AM)
var task = cron.schedule('* * 9 * *', function(){
    console.log('Running sendout');
    doSendout();
});
task.start();

// Main task
var doSendout = function(){
    sendMessage(me, {text: "jkdbot here" + ver});
}

// Sends a message to a Facebook user
var sendMessage = function(recipientId, message){
    request({
        url: 'https://graph.facebook.com/v2.8/me/messages',
        qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: recipientId},
            message: message,
        }
    }, function(error, response, html) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
};

// Collects the userId's from the page likes html
var getUserIds = function(){
    var url = 'https://www.facebook.com/browse/?type=page_fans&page_id='+pageId+'&access_token='+process.env.PAGE_ACCESS_TOKEN;
    console.log(url);
    var nightmare = new Nightmare({ show: false });
    var page = nightmare.goto(url)
        .wait()
        .evaluate(function () {
            return document.querySelectorAll('a[data-gt]');
        })
        .end()
        .then(function (result) {
            console.log(result)
        })
        .catch(function (error) {
            console.error('Search failed:', error);
        });
    console.log('Nightmare done');
};

var getUserIds2 = function(){
    var userIds = [];

    request(url, function (error, response, html) {
    if (!error && response.statusCode == 200) {
        var $ = cheerio.load(html);
        $('a[data-gt]').each(function(i, a) {
            var gt = JSON.parse(a.dataset.gt);
            if(!gt.engagement || gt.engagement.eng_type !== "1") {
                return;
            }
            console.log(gt.engagement.eng_tid);
            userIds.push(gt.engagement.eng_tid)
        });
    } else {
        console.log('Error retrieving likes: ', error);
    }
    });
};

// Retrieves the profile attributes of a user
var getUserAttributes = function(userId){
    return new Promise(function (resolve, reject){
        request({
            url: 'https://graph.facebook.com/v2.8/' + userId,
            qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
            method: 'GET'
        }, function(error, response, html) {
            if (error) {
                console.log('Error sending message: ', error);
                reject(error);
            } else if (response.body.error) {
                console.log('Error: ', response.body.error);
                reject(response.body.error);
            }
            var res = JSON.parse(response.body);
            resolve(res);
        });
    });
};

<commit_msg>Nightmare access token<commit_after>var express = require('express');
var request = require('request');
var bodyParser = require('body-parser');
var cron = require('node-cron');
var cheerio = require('cheerio');
var Nightmare = require('nightmare');

var app = express();
app.listen((process.env.PORT || 3000));
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());

// Current version
ver = 'v.0.0.31';

// Server endpoint
app.get('/', function (req, res){
    res.send('JKDbot here! ' + ver);
    getUserIds();
});

// Facebook webhook
app.get('/webhook', function (req, res){
    if (req.query['hub.verify_token'] === 'jkdbot_verify_token') {
        res.send(req.query['hub.challenge']);
    } else {
        res.send('Invalid verify token');
    }
});

// Handler receiving messages
app.post('/webhook', function (req, res){
    var events = req.body.entry[0].messaging;
    for (i = 0; i < events.length; i++){
        var event = events[i];
        if (event.message && event.message.text) {
            switch(event.message.text) {
                // Housekeeping commands
                case("cmd_version"):
                    sendMessage(event.sender.id, {text: ver});
                    break;
                case("cmd_subscribers"):
                    sendMessage(event.sender.id, {text: getUserIds()});
                    break;
                case("cmd_timezone"):
                    getUserAttributes(event.sender.id).then(function(res){
                        sendMessage(event.sender.id, {text: res.timezone});
                    });
                    break;
                case("cmd_stop_cron"):
                    task.stop();
                    break;
                case("cmd_stop_restart"):
                    task.start();
                    break;
                // Ack to sender
                default:
                    sendMessage(event.sender.id, {text: "Message received: " + event.message.text + " by " + event.sender.id});
                    break;
            }
        }
    }
    res.sendStatus(200);
});

// Scheduler (Everyday at 09_00AM)
var task = cron.schedule('* * 9 * *', function(){
    console.log('Running sendout');
    doSendout();
});
task.start();

// Main task
var doSendout = function(){
    sendMessage(me, {text: "jkdbot here" + ver});
}

// Sends a message to a Facebook user
var sendMessage = function(recipientId, message){
    request({
        url: 'https://graph.facebook.com/v2.8/me/messages',
        qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
        method: 'POST',
        json: {
            recipient: {id: recipientId},
            message: message,
        }
    }, function(error, response, html) {
        if (error) {
            console.log('Error sending message: ', error);
        } else if (response.body.error) {
            console.log('Error: ', response.body.error);
        }
    });
};

// Scraps the userId's from the page likes html
var getUserIds = function(){
    var url = 'https://www.facebook.com/browse/?type=page_fans&page_id='+process.env.PAGE_ID;
    console.log(url);
    var nightmare = new Nightmare({ show: true });
    var page = nightmare.goto(url)
        .type('#email', 'drexa1@hotmail.com')
        .type('#pass', process.env.USER_ACCESS_TOKEN)
        .click('#loginbutton')
        .wait()
        .evaluate(function () {
            console.log('***pwd ' + process.env.USER_ACCESS_TOKEN + ' ' + process.env.PAGE_ID);
            return document.querySelectorAll('.fsl');
        })
        .end()
        .then(function (result) {
            console.log(result)
        })
        .catch(function (error) {
            console.error('Search failed:', error);
        });
    console.log('Nightmare done');
};

// Retrieves the profile attributes of a user
var getUserAttributes = function(userId){
    return new Promise(function (resolve, reject){
        request({
            url: 'https://graph.facebook.com/v2.8/' + userId,
            qs: {access_token: process.env.PAGE_ACCESS_TOKEN},
            method: 'GET'
        }, function(error, response, html) {
            if (error) {
                console.log('Error sending message: ', error);
                reject(error);
            } else if (response.body.error) {
                console.log('Error: ', response.body.error);
                reject(response.body.error);
            }
            var res = JSON.parse(response.body);
            resolve(res);
        });
    });
};

<|endoftext|>


<commit_before>const elixirs = {
	haste: require('./elixirs/haste.json'),
	'max-stamina': require('./elixirs/max-stamina.json'),
	resistances: require('./elixirs/resistances.json'),
	stamina: require('./elixirs/stamina.json')
};

const recipes = {
	haste: require('./recipes/haste.json'),
	defense: require('./recipes/defense.json'),
	'max-hearts': require('./recipes/max-hearts.json'),
	'max-stamina': require('./recipes/max-stamina.json'),
	resistances: require('./recipes/resistances.json'),
	stealth: require('./recipes/stealth.json')
};

module.exports = { elixirs: elixirs, recipes: recipes };<commit_msg>updated exports for package<commit_after>const elixirs = {
	require('./elixirs/haste.json'),
	require('./elixirs/max-stamina.json'),
	require('./elixirs/resistances.json'),
	require('./elixirs/stamina.json')
};

const recipes = [
	require('./recipes/haste.json'),
	require('./recipes/defense.json'),
	require('./recipes/max-hearts.json'),
	require('./recipes/max-stamina.json'),
	require('./recipes/resistances.json'),
	require('./recipes/stealth.json')
};

module.exports = { elixirs: elixirs, recipes: recipes };<|endoftext|>


<commit_before>"use strict";

const Config = require("./lib/Config.js");

// Configuração
module.exports = {
    "Config": Config
};
<commit_msg>Corrige padronização do arquivo principal<commit_after>'use strict';

const Config = require('./lib/Config.js');

// Configuração
module.exports = {
  Config,
};
<|endoftext|>


<commit_before>"use strict";

var _ = require("lodash"),
    Sequelize = require("sequelize"),
    when = require("when");

module.exports = function G(sequelizeModelOrInstance, options) {
    options = _.merge({
        attributes: {},
        number: 1
    }, options);

    function valueBasedOnAttribute(attribute) {
        var typeString;

        if (attribute.type) {
            typeString = attribute.type.toString();
        } else {
            typeString = attribute;
        }

        if (typeString === "ENUM") {
            return _.sample(attribute.values);
        } else if (_.contains(["INTEGER", "SMALLINT UNSIGNED"], typeString)) {
            return _.parseInt(_.uniqueId(), 10);
            // starts with VARCHAR( or CHAR(, or is TEXT
        } else if (typeString.indexOf("VARCHAR(") === 0 || typeString.indexOf("CHAR") === 0 || typeString === "TEXT") {
            if (attribute.validate && attribute.validate.isUrl) {
                return "http://example.com/" + _.uniqueId();
            } else {
                return _.uniqueId();
            }
        }

        return null;
    }

    function setDefaultAttributesValue(rawAttributes, customValues, associationIdentifiers) {
        var attributes = _.clone(customValues);

        _(rawAttributes)
        // Removes from rawAttributes any attributes from customValues. We want user-passed values to take precedence
        .omit(_.keys(customValues))
        // Loop the remaining rawAttributes to set values according to its Sequelize data type
        .forEach(function (value, key) {
            if (!_.has(value, "autoIncrement") && value.autoIncrement !== true) {
                if (_.has(value, "references") || _.contains(associationIdentifiers, key)) {
                    attributes[key] = null;
                } else {
                    var valueToPopulate = valueBasedOnAttribute(value);
                    if (!_.isNull(valueToPopulate)) {
                        attributes[key] = valueToPopulate;
                    }
                }
            }
        }).value();

        return attributes;
    }

    function instancesIfNeeded(sequelizeModelOrInstance) {
        // It is a model, create the instance
        if (sequelizeModelOrInstance.tableName) {
            var associationIdentifiers = _.pluck(sequelizeModelOrInstance.associations, "identifier"),
                bulkCreateArgument = [];

            for (var i = 0; i < options.number; i++) {
                var attributes = setDefaultAttributesValue(sequelizeModelOrInstance.rawAttributes, options.attributes, associationIdentifiers);

                _.forEach(options.attributes, function (value, key) {
                    if (_.isArray(value)) { // If value is an array, we consume the first element
                        attributes[key] = value[i];
                    } else if (_.isFunction(value)) { // If value is a function, execute it
                        attributes[key] = value();
                    }
                });

                bulkCreateArgument.push(attributes);
            }

            // Sadly .bulkCreate does not return the newly created instances. We need to .findAll, but since calling G() multiple times
            // could potentially run .findAll and return previously created records, we need to .slice with just the last options.number
            // elements
            return sequelizeModelOrInstance.bulkCreate(bulkCreateArgument).then(function () {
                return sequelizeModelOrInstance.findAll();
            }).then(function (instances) {
                return instances.slice(-options.number);
            });
        } else {
            // It is already an instance, not a model, so wrap it as a promise
            return when([sequelizeModelOrInstance]);
        }
    }

    function getSetterMethod(association, instance) {
        if (association.accessors && association.accessors.set) {
            return instance[association.accessors.set];
        } else {
            // setterName code copied straight from Sequelize
            // https://github.com/sequelize/sequelize/blob/0299ce638fc13ad79a50cd0714f274143babaf29/lib/associations/belongs-to.js#L71
            var setterName = Sequelize.Utils._.camelize("set_" + (association.options.as || Sequelize.Utils.singularize(association.target.tableName, association.options.language)));

            if (instance[setterName]) {
                return instance[setterName];
            } else if (instance[setterName + "s"]) {
                return instance[setterName + "s"];
            }
        }
    }

    return instancesIfNeeded(sequelizeModelOrInstance).then(function (instances) {
        var instance;

        if (options.number > 1) {
            var originalNumber = options.number;

            options.number = options.number - instances.length;

            return when.map(instances, function (instance) {
                var optionsCopy = _.clone(options);

                if (originalNumber > 0) {
                    // This part should be refactored with bulkCreateArgument.push's from instancesIfNeeded()
                    var attributes = {};

                    _.forEach(options.attributes, function (value, key) {
                        if (_.isArray(value)) { // If value is an array, we consume the first element
                            attributes[key] = value.shift();
                        } else if (_.isFunction(value)) { // If value is a function, execute it
                            attributes[key] = value();
                        } else {
                            attributes[key] = value;
                        }
                    });

                    optionsCopy.attributes = attributes;
                }

                return new G(instance, optionsCopy);
            });
        } else {
            instance = instances[0];
        }

        // Since G is recursive, options.rootInstance keeps track of what should be ultimately returned
        if (!options.rootInstance) {
            options.rootInstance = instance;
        }

        instance.generator = {};

        var associations = _.where(instance.daoFactory.associations, {
            associationType: "BelongsTo"
        });

        if (_.isEmpty(associations)) {
            return instance;
        } else {
            return when.map(associations, function (association) {
                var target = association.target,
                    targetAttributes = options[target.name] && options[target.name].attributes || {},
                    targetInstancePromise;

                var associationIdentifiers = _.pluck(target.associations, "identifier");

                targetAttributes = setDefaultAttributesValue(target.rawAttributes, targetAttributes, associationIdentifiers);

                if (options[target.name] && options[target.name] === "shared") {
                    targetInstancePromise = target.findAll().then(function (targetInstances) {
                        if (targetInstances.length === 0) {
                            return target.create(targetAttributes);
                        } else {
                            return _.first(targetInstances);
                        }
                    });
                } else if (options[target.name] === null) {
                    return;
                } else {
                    // If the target identifier was passed as an atribute of instance, try to get the
                    // existing record from the database. In other words, the foreign key value is set.
                    // Otherwise, create the instance.
                    targetInstancePromise = target.findOrCreate({
                        id: options.attributes[association.identifier] || null
                    }, targetAttributes);
                }

                return targetInstancePromise.then(function (targetInstance) {
                    var setterMethod = getSetterMethod(association, instance);

                    if (association.associationType === "HasMany") {
                        targetInstance = [targetInstance];
                    }

                    instance.generator[target.name] = targetInstance;

                    return setterMethod.call(instance, targetInstance).then(function () {
                        return targetInstance;
                    });
                });
            }).then(function (targetInstances) {
                return when.map(targetInstances, function (targetInstance) {
                    if (targetInstance && !_.isEmpty(targetInstance.daoFactory.associations)) {
                        return new G(targetInstance, options);
                    } else {
                        return targetInstance;
                    }
                });
            }).then(function () {
                return options.rootInstance;
            });
        }
    });
};
<commit_msg>Refactored unnecessary method<commit_after>"use strict";

var _ = require("lodash"),
    Sequelize = require("sequelize"),
    when = require("when");

module.exports = function G(sequelizeModelOrInstance, options) {
    options = _.merge({
        attributes: {},
        number: 1
    }, options);

    function valueBasedOnAttribute(attribute) {
        var typeString;

        if (attribute.type) {
            typeString = attribute.type.toString();
        } else {
            typeString = attribute;
        }

        if (typeString === "ENUM") {
            return _.sample(attribute.values);
        } else if (_.contains(["INTEGER", "SMALLINT UNSIGNED"], typeString)) {
            return _.parseInt(_.uniqueId(), 10);
            // starts with VARCHAR( or CHAR(, or is TEXT
        } else if (typeString.indexOf("VARCHAR(") === 0 || typeString.indexOf("CHAR") === 0 || typeString === "TEXT") {
            if (attribute.validate && attribute.validate.isUrl) {
                return "http://example.com/" + _.uniqueId();
            } else {
                return _.uniqueId();
            }
        }

        return null;
    }

    function setDefaultAttributesValue(rawAttributes, customValues, associationIdentifiers) {
        var attributes = _.clone(customValues);

        _(rawAttributes)
        // Removes from rawAttributes any attributes from customValues. We want user-passed values to take precedence
        .omit(_.keys(customValues))
        // Loop the remaining rawAttributes to set values according to its Sequelize data type
        .forEach(function (value, key) {
            if (!_.has(value, "autoIncrement") && value.autoIncrement !== true) {
                if (_.has(value, "references") || _.contains(associationIdentifiers, key)) {
                    attributes[key] = null;
                } else {
                    var valueToPopulate = valueBasedOnAttribute(value);
                    if (!_.isNull(valueToPopulate)) {
                        attributes[key] = valueToPopulate;
                    }
                }
            }
        }).value();

        return attributes;
    }

    function instancesIfNeeded(sequelizeModelOrInstance) {
        // It is a model, create the instance
        if (sequelizeModelOrInstance.tableName) {
            var associationIdentifiers = _.pluck(sequelizeModelOrInstance.associations, "identifier"),
                bulkCreateArgument = [];

            for (var i = 0; i < options.number; i++) {
                var attributes = setDefaultAttributesValue(sequelizeModelOrInstance.rawAttributes, options.attributes, associationIdentifiers);

                _.forEach(options.attributes, function (value, key) {
                    if (_.isArray(value)) { // If value is an array, we consume the first element
                        attributes[key] = value[i];
                    } else if (_.isFunction(value)) { // If value is a function, execute it
                        attributes[key] = value();
                    }
                });

                bulkCreateArgument.push(attributes);
            }

            // Sadly .bulkCreate does not return the newly created instances. We need to .findAll, but since calling G() multiple times
            // could potentially run .findAll and return previously created records, we need to .slice with just the last options.number
            // elements
            return sequelizeModelOrInstance.bulkCreate(bulkCreateArgument).then(function () {
                return sequelizeModelOrInstance.findAll();
            }).then(function (instances) {
                return instances.slice(-options.number);
            });
        } else {
            // It is already an instance, not a model, so wrap it as a promise
            return when([sequelizeModelOrInstance]);
        }
    }

    return instancesIfNeeded(sequelizeModelOrInstance).then(function (instances) {
        var instance;

        if (options.number > 1) {
            var originalNumber = options.number;

            options.number = options.number - instances.length;

            return when.map(instances, function (instance) {
                var optionsCopy = _.clone(options);

                if (originalNumber > 0) {
                    // This part should be refactored with bulkCreateArgument.push's from instancesIfNeeded()
                    var attributes = {};

                    _.forEach(options.attributes, function (value, key) {
                        if (_.isArray(value)) { // If value is an array, we consume the first element
                            attributes[key] = value.shift();
                        } else if (_.isFunction(value)) { // If value is a function, execute it
                            attributes[key] = value();
                        } else {
                            attributes[key] = value;
                        }
                    });

                    optionsCopy.attributes = attributes;
                }

                return new G(instance, optionsCopy);
            });
        } else {
            instance = instances[0];
        }

        // Since G is recursive, options.rootInstance keeps track of what should be ultimately returned
        if (!options.rootInstance) {
            options.rootInstance = instance;
        }

        instance.generator = {};

        var associations = _.where(instance.daoFactory.associations, {
            associationType: "BelongsTo"
        });

        if (_.isEmpty(associations)) {
            return instance;
        } else {
            return when.map(associations, function (association) {
                var target = association.target,
                    targetAttributes = options[target.name] && options[target.name].attributes || {},
                    targetInstancePromise;

                var associationIdentifiers = _.pluck(target.associations, "identifier");

                targetAttributes = setDefaultAttributesValue(target.rawAttributes, targetAttributes, associationIdentifiers);

                if (options[target.name] && options[target.name] === "shared") {
                    targetInstancePromise = target.findAll().then(function (targetInstances) {
                        if (targetInstances.length === 0) {
                            return target.create(targetAttributes);
                        } else {
                            return _.first(targetInstances);
                        }
                    });
                } else if (options[target.name] === null) {
                    return;
                } else {
                    // If the target identifier was passed as an atribute of instance, try to get the
                    // existing record from the database. In other words, the foreign key value is set.
                    // Otherwise, create the instance.
                    targetInstancePromise = target.findOrCreate({
                        id: options.attributes[association.identifier] || null
                    }, targetAttributes);
                }

                return targetInstancePromise.then(function (targetInstance) {
                    var setterName = Sequelize.Utils._.camelize("set_" + (association.options.as || Sequelize.Utils.singularize(association.target.tableName, association.options.language)));

                    if (association.associationType === "HasMany") {
                        targetInstance = [targetInstance];
                    }

                    instance.generator[target.name] = targetInstance;

                    return instance[setterName].call(instance, targetInstance).then(function () {
                        return targetInstance;
                    });
                });
            }).then(function (targetInstances) {
                return when.map(targetInstances, function (targetInstance) {
                    if (targetInstance && !_.isEmpty(targetInstance.daoFactory.associations)) {
                        return new G(targetInstance, options);
                    } else {
                        return targetInstance;
                    }
                });
            }).then(function () {
                return options.rootInstance;
            });
        }
    });
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
/*jslint node: true */
/*jshint esversion: 6 */

'use strict';

const axios = require('axios');
const cheerio = require('cheerio');
const inquirer = require('inquirer');
const Table = require('cli-table');
const colors = require('colors');

const baseUrl     = "http://www.liburnasional.com/";

axios.get(baseUrl).then(response => {
    var $ = cheerio.load(response.data);
    var sources = $('.dropdown-menu').eq(0).children().children();
    var years = [];

    sources.each(function(x, y) {
        years.push({name: y.children[0].data, link: y.attribs.href});
    });

    // value : "Liburan Nasional 2012"
    return inquirer.prompt([{
        type    : "list",
        name    : "years",
        message : "Pilih Tahun: ",
        choices : years
    }]);
}).then(answer => {
    // get year from answer

    var year = answer.years.split(" ");
    return year[year.length - 1];
}).then(year => {
    let subUrl   = "http://www.liburnasional.com/kalender-";
    let url         = subUrl+year+"/";

    // get data u need
    axios.get(url).then(res => {
        var $ = cheerio.load(res.data);
        var holidays = [];

        $('.libnas-calendar-holiday-title').each(function(x, y) {
            holidays.push({
                day     : y.children[1].children[0].data,
                date    : y.children[2].children[0].data,
                title   : y.children[0].children[0].children[0].children[0].data,
            });
        });

        return holidays;
    }).then(holidays => {
        var table = new Table({
             head: ['Tanggal', 'Hari', 'Acara']
        });

        // push value to table
        holidays.forEach(x=> {
            table.push([x.date, x.day, x.title]);
        });

        console.log(colors.cyan(table.toString()));
    });
});
<commit_msg>Unexpected trailing comma.<commit_after>#!/usr/bin/env node
/*jslint node: true */
/*jshint esversion: 6 */

'use strict';

const axios = require('axios');
const cheerio = require('cheerio');
const inquirer = require('inquirer');
const Table = require('cli-table');
const colors = require('colors');

const baseUrl     = "http://www.liburnasional.com/";

axios.get(baseUrl).then(response => {
    var $ = cheerio.load(response.data);
    var sources = $('.dropdown-menu').eq(0).children().children();
    var years = [];

    sources.each(function(x, y) {
        years.push({name: y.children[0].data, link: y.attribs.href});
    });

    // value : "Liburan Nasional 2012"
    return inquirer.prompt([{
        type    : "list",
        name    : "years",
        message : "Pilih Tahun: ",
        choices : years
    }]);
}).then(answer => {
    // get year from answer

    var year = answer.years.split(" ");
    return year[year.length - 1];
}).then(year => {
    let subUrl   = "http://www.liburnasional.com/kalender-";
    let url         = subUrl+year+"/";

    // get data u need
    axios.get(url).then(res => {
        var $ = cheerio.load(res.data);
        var holidays = [];

        $('.libnas-calendar-holiday-title').each(function(x, y) {
            holidays.push({
                day     : y.children[1].children[0].data,
                date    : y.children[2].children[0].data,
                title   : y.children[0].children[0].children[0].children[0].data
            });
        });

        return holidays;
    }).then(holidays => {
        var table = new Table({
             head: ['Tanggal', 'Hari', 'Acara']
        });

        // push value to table
        holidays.forEach(x=> {
            table.push([x.date, x.day, x.title]);
        });

        console.log(colors.cyan(table.toString()));
    });
});
<|endoftext|>


<commit_before>var Metalsmith   = require('metalsmith'),
    markdown     = require('metalsmith-markdown'),
    templates    = require('metalsmith-templates'),
    collections  = require('metalsmith-collections'),
    permalinks   = require('metalsmith-permalinks'),
    feed         = require('metalsmith-feed'),
    sitemap      = require('metalsmith-sitemap'),
    assets       = require('metalsmith-assets'),
    Handlebars   = require('handlebars'),
    fs           = require('fs'),
    logger       = require('./plugins/logger'),
    setPermalink = require('./plugins/setpermalink'),
    setPageColor = require('./plugins/setpagecolor'),
    setSlug      = require('./plugins/setslug'),
    setTemplate  = require('./plugins/settemplate'),
    fixPath      = require('./plugins/fixpath'),
    dateFormat   = require('./plugins/dateformat');

/**
 * Info JSON
 */

var info = require('./info.json');

/**
 * siteInfo helper
 */

Handlebars.registerHelper('siteInfo', function (context) {
  return info[context];
});

Metalsmith(__dirname)

  /**
   * Add metadata
   */
  .metadata({
    site: {
      title: info.title,
      author: info.author,
      description: info.description,
      url: info.url
    }
  })

  /**
   * Build collections from posts and pages
   */
  .use(collections({
    posts: {
      pattern: 'posts/*.md',
      sortBy: 'date',
      reverse: true
    },
    pages: {
      pattern: 'pages/*.md'
    }
  }))

  /**
   * Set default templates
   */
  .use(setTemplate({
    default: 'default.hbt',
    post: {
      pattern: 'post',
      template: 'post.hbt'
    },
    index: {
      pattern: 'index',
      template: 'frontpage.hbt'
    }
  }))

  /**
   * Use markdown
   */
  .use(markdown({
    gfm: true,
    langPrefix: ''
  }))

  /**
   * Format dates
   */
  .use(dateFormat())

  /**
   * set page slug to title if missing
   */
  .use(setSlug())

  /**
   * Build permalinks
   */
  .use(permalinks({
    relative: false,
    pattern: ':slug'
  }))

  /**
   * Fix path for frontpage
   */
  .use(fixPath('title', 'Home'))

  /**
   * Add 'link' prop containing permalink
   */
  .use(setPermalink())

  /**
   * Add 'link' prop containing permalink
   */
  .use(setPageColor())

  /**
   * Build RSS Feed
   */
  .use(feed({
    collection: 'posts',
    destination: 'rss/rss.xml',
    postDescription: function(file) {
      return file.contents;
    }
  }))

  /**
   * Render pages
   */
  .use(templates({
    engine: 'handlebars',
    directory: 'templates',
    partials: {
      nav: 'partials/nav',
      archive: 'partials/archive',
      header: 'partials/header',
      footer: 'partials/footer'
    }
  }))

  /**
   * Build sitemap
   */
  .use(sitemap({
    output: 'sitemap.xml',
    hostname: info.url
  }))

  /**
   * Set build destination
   */
  .destination('./build')
  .use(assets({
    source: './assets', // relative to the working directory
    destination: './assets' // relative to the build directory
  }))
  //.use(logger('metadata'))
  /**
   * Set build destination
   */
  .build(function(err) {
    if (err) throw err;
  });
<commit_msg>Fix pageColor comment<commit_after>var Metalsmith   = require('metalsmith'),
    markdown     = require('metalsmith-markdown'),
    templates    = require('metalsmith-templates'),
    collections  = require('metalsmith-collections'),
    permalinks   = require('metalsmith-permalinks'),
    feed         = require('metalsmith-feed'),
    sitemap      = require('metalsmith-sitemap'),
    assets       = require('metalsmith-assets'),
    Handlebars   = require('handlebars'),
    fs           = require('fs'),
    logger       = require('./plugins/logger'),
    setPermalink = require('./plugins/setpermalink'),
    setPageColor = require('./plugins/setpagecolor'),
    setSlug      = require('./plugins/setslug'),
    setTemplate  = require('./plugins/settemplate'),
    fixPath      = require('./plugins/fixpath'),
    dateFormat   = require('./plugins/dateformat');

/**
 * Info JSON
 */

var info = require('./info.json');

/**
 * siteInfo helper
 */

Handlebars.registerHelper('siteInfo', function (context) {
  return info[context];
});

Metalsmith(__dirname)

  /**
   * Add metadata
   */
  .metadata({
    site: {
      title: info.title,
      author: info.author,
      description: info.description,
      url: info.url
    }
  })

  /**
   * Build collections from posts and pages
   */
  .use(collections({
    posts: {
      pattern: 'posts/*.md',
      sortBy: 'date',
      reverse: true
    },
    pages: {
      pattern: 'pages/*.md'
    }
  }))

  /**
   * Set default templates
   */
  .use(setTemplate({
    default: 'default.hbt',
    post: {
      pattern: 'post',
      template: 'post.hbt'
    },
    index: {
      pattern: 'index',
      template: 'frontpage.hbt'
    }
  }))

  /**
   * Use markdown
   */
  .use(markdown({
    gfm: true,
    langPrefix: ''
  }))

  /**
   * Format dates
   */
  .use(dateFormat())

  /**
   * set page slug to title if missing
   */
  .use(setSlug())

  /**
   * Build permalinks
   */
  .use(permalinks({
    relative: false,
    pattern: ':slug'
  }))

  /**
   * Fix path for frontpage
   */
  .use(fixPath('title', 'Home'))

  /**
   * Add 'link' prop containing permalink
   */
  .use(setPermalink())

  /**
   * Add 'pageColor' prop
   */
  .use(setPageColor())

  /**
   * Build RSS Feed
   */
  .use(feed({
    collection: 'posts',
    destination: 'rss/rss.xml',
    postDescription: function(file) {
      return file.contents;
    }
  }))

  /**
   * Render pages
   */
  .use(templates({
    engine: 'handlebars',
    directory: 'templates',
    partials: {
      nav: 'partials/nav',
      archive: 'partials/archive',
      header: 'partials/header',
      footer: 'partials/footer'
    }
  }))

  /**
   * Build sitemap
   */
  .use(sitemap({
    output: 'sitemap.xml',
    hostname: info.url
  }))

  /**
   * Set build destination
   */
  .destination('./build')
  .use(assets({
    source: './assets', // relative to the working directory
    destination: './assets' // relative to the build directory
  }))
  //.use(logger('metadata'))
  /**
   * Set build destination
   */
  .build(function(err) {
    if (err) throw err;
  });
<|endoftext|>


<commit_before>'use strict';

var flagsGetter = function flags() {
	if (this != null && this !== Object(this)) {
		throw new TypeError('RegExp.prototype.flags getter called on non-object');
	}
	var result = '';
	if (this.global) {
		result += 'g';
	}
	if (this.ignoreCase) {
		result += 'i';
	}
	if (this.multiline) {
		result += 'm';
	}
	if (this.unicode) {
		result += 'u';
	}
	if (this.sticky) {
		result += 'y';
	}
	return result;
};

var supportsDescriptors = (function () {
	if (!Object.defineProperty) {
		return false;
	}
	try {
		Object.defineProperty({}, 'x', {});
		return true;
	} catch (e) { /* this is IE 8. */
		return false;
	}
}());

var flags = Function.call.bind(flagsGetter);

flags.shim = function flagsShim() {
	if (!supportsDescriptors) {
		throw new TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');
	}
	if (/a/mig.flags !== 'gim') {
		Object.defineProperty(RegExp.prototype, 'flags', {
			configurable: true,
			enumerable: false,
			get: flagsGetter
		});
	}
	return flags;
};

module.exports = flags;
<commit_msg>Clean up `supportsDescriptors` check.<commit_after>'use strict';

var flagsGetter = function flags() {
	if (this != null && this !== Object(this)) {
		throw new TypeError('RegExp.prototype.flags getter called on non-object');
	}
	var result = '';
	if (this.global) {
		result += 'g';
	}
	if (this.ignoreCase) {
		result += 'i';
	}
	if (this.multiline) {
		result += 'm';
	}
	if (this.unicode) {
		result += 'u';
	}
	if (this.sticky) {
		result += 'y';
	}
	return result;
};

var supportsDescriptors = Object.defineProperty && (function () {
	try {
		var obj = {};
		Object.defineProperty(obj, 'x', { value: obj });
		return obj.x === obj;
	} catch (e) { /* this is IE 8. */
		return false;
	}
}());

var flags = Function.call.bind(flagsGetter);

flags.shim = function flagsShim() {
	if (!supportsDescriptors) {
		throw new TypeError('RegExp.prototype.flags requires a true ES5 environment that supports property descriptors');
	}
	if (/a/mig.flags !== 'gim') {
		Object.defineProperty(RegExp.prototype, 'flags', {
			configurable: true,
			enumerable: false,
			get: flagsGetter
		});
	}
	return flags;
};

module.exports = flags;
<|endoftext|>