<commit_before>import debug from 'debug';
import fs from 'fs-promise';
import path from 'path';
import username from 'username';

import installDepList from '../util/install-dependencies';
import readPackageJSON from '../util/read-package-json';
import asyncOra from '../util/ora-handler';

const d = debug('electron-forge:init:npm');

// FIXME remove electron-compilers entry when >= 5.3.0 is fixed
export const deps = ['electron-compile', 'electron-compilers@5.2.5'];
export const devDeps = ['babel-preset-env', 'babel-preset-react', 'babel-plugin-transform-async-to-generator'];
export const exactDevDeps = ['electron-prebuilt-compile'];
export const standardDeps = ['standard'];
export const airbnDeps = ['eslint', 'eslint-config-airbnb', 'eslint-plugin-import',
  'eslint-plugin-jsx-a11y', 'eslint-plugin-react'];

export default async (dir, lintStyle) => {
  await asyncOra('Initializing NPM Module', async () => {
    const packageJSON = await readPackageJSON(path.resolve(__dirname, '../../tmpl'));
    packageJSON.productName = packageJSON.name = path.basename(dir).toLowerCase();
    packageJSON.config.forge.electronWinstallerConfig.name = packageJSON.name.replace(/-/g, '_');
    packageJSON.config.forge.windowsStoreConfig.name = packageJSON.productName.replace(/-/g, '');
    packageJSON.author = await username();

    switch (lintStyle) {
      case 'standard':
        packageJSON.scripts.lint = 'standard';
        break;
      case 'airbnb':
        packageJSON.scripts.lint = 'eslint src';
        break;
      default:
        packageJSON.scripts.lint = 'echo "No linting configured"';
        break;
    }
    d('writing package.json to:', dir);
    await fs.writeFile(path.resolve(dir, 'package.json'), JSON.stringify(packageJSON, null, 4));
  });

  await asyncOra('Installing NPM Dependencies', async () => {
    d('installing dependencies');
    await installDepList(dir, deps);

    d('installing devDependencies');
    await installDepList(dir, devDeps, true);

    d('installing exact dependencies');
    for (const packageName of exactDevDeps) {
      await installDepList(dir, [packageName], true, true);
    }

    switch (lintStyle) {
      case 'standard':
        d('installing standard linting dependencies');
        await installDepList(dir, standardDeps, true);
        break;
      case 'airbnb':
        d('installing airbnb linting dependencies');
        await installDepList(dir, airbnDeps, true);
        break;
      default:
        d('not installing linting deps');
        break;
    }

    // NB: For babel-preset-env to work correctly, it needs to know the
    // actual version of Electron that we installed
    const content = JSON.parse(await fs.readFile(path.join(dir, '.compilerc'), 'utf8'));
    const electronPrebuilt = require(
      path.join(dir, 'node_modules', 'electron-prebuilt-compile', 'package.json'));

    for (const profile of ['development', 'production']) {
      const envTarget = content.env[profile]['application/javascript'].presets.find(x => x[0] === 'env');
      envTarget[1].targets.electron = electronPrebuilt.version;
    }

    await fs.writeFile(path.join(dir, '.compilerc'), JSON.stringify(content, null, 2), 'utf8');
  });
};
<commit_msg>fix(initializer): unpin electron-compilers<commit_after>import debug from 'debug';
import fs from 'fs-promise';
import path from 'path';
import username from 'username';

import installDepList from '../util/install-dependencies';
import readPackageJSON from '../util/read-package-json';
import asyncOra from '../util/ora-handler';

const d = debug('electron-forge:init:npm');

export const deps = ['electron-compile'];
export const devDeps = ['babel-preset-env', 'babel-preset-react', 'babel-plugin-transform-async-to-generator'];
export const exactDevDeps = ['electron-prebuilt-compile'];
export const standardDeps = ['standard'];
export const airbnDeps = ['eslint', 'eslint-config-airbnb', 'eslint-plugin-import',
  'eslint-plugin-jsx-a11y', 'eslint-plugin-react'];

export default async (dir, lintStyle) => {
  await asyncOra('Initializing NPM Module', async () => {
    const packageJSON = await readPackageJSON(path.resolve(__dirname, '../../tmpl'));
    packageJSON.productName = packageJSON.name = path.basename(dir).toLowerCase();
    packageJSON.config.forge.electronWinstallerConfig.name = packageJSON.name.replace(/-/g, '_');
    packageJSON.config.forge.windowsStoreConfig.name = packageJSON.productName.replace(/-/g, '');
    packageJSON.author = await username();

    switch (lintStyle) {
      case 'standard':
        packageJSON.scripts.lint = 'standard';
        break;
      case 'airbnb':
        packageJSON.scripts.lint = 'eslint src';
        break;
      default:
        packageJSON.scripts.lint = 'echo "No linting configured"';
        break;
    }
    d('writing package.json to:', dir);
    await fs.writeFile(path.resolve(dir, 'package.json'), JSON.stringify(packageJSON, null, 4));
  });

  await asyncOra('Installing NPM Dependencies', async () => {
    d('installing dependencies');
    await installDepList(dir, deps);

    d('installing devDependencies');
    await installDepList(dir, devDeps, true);

    d('installing exact dependencies');
    for (const packageName of exactDevDeps) {
      await installDepList(dir, [packageName], true, true);
    }

    switch (lintStyle) {
      case 'standard':
        d('installing standard linting dependencies');
        await installDepList(dir, standardDeps, true);
        break;
      case 'airbnb':
        d('installing airbnb linting dependencies');
        await installDepList(dir, airbnDeps, true);
        break;
      default:
        d('not installing linting deps');
        break;
    }

    // NB: For babel-preset-env to work correctly, it needs to know the
    // actual version of Electron that we installed
    const content = JSON.parse(await fs.readFile(path.join(dir, '.compilerc'), 'utf8'));
    const electronPrebuilt = require(
      path.join(dir, 'node_modules', 'electron-prebuilt-compile', 'package.json'));

    for (const profile of ['development', 'production']) {
      const envTarget = content.env[profile]['application/javascript'].presets.find(x => x[0] === 'env');
      envTarget[1].targets.electron = electronPrebuilt.version;
    }

    await fs.writeFile(path.join(dir, '.compilerc'), JSON.stringify(content, null, 2), 'utf8');
  });
};
<|endoftext|>


<commit_before>/* jshint esversion: 6 */

function trigger(event_names, elem) {
    // event_names: space sep names of events
    // elem: jQuery element
    if (!event_names || event_names.length === 0) {
        throw (`Cannot trigger ${event_names}, element event_names`)
    }
    if (!elem || elem.length === 0) {
        throw (`Cannot trigger ${event_names}, element missing`)
    }
    for (let event_name of event_names.split(' ')) {
        let evt = document.createEvent("MouseEvents")
        // eek, there's gotta be a better way.
        // replace with https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent
        // https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
        evt.initMouseEvent(event_name, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        let dom_elem = elem.get(0)
        dom_elem.dispatchEvent(evt)
    }
    return elem
}

class Toolbar {
    get month_view() {
        return $('#topRightNavigation .goog-imageless-button').eq(2)
    }
    get custom_view() {
        return $('#topRightNavigation .goog-imageless-button').eq(3)
    }
    get prev_month() {
        return $('.navBack').eq(0)
    }
    get today() {
        return $('#todayButton\\:1,#todayButton\\:2').children().eq(0)
    }
    get next_month() {
        return $('#dp_0_next')
    }
    get is_custom_view_active() {
        return this.custom_view.is('.goog-imageless-button-checked')
    }

    poll_custom_button_visibility(wait_ms = 500) {
        if (this.custom_view.is(":visible")) {
            $(document).trigger("custom_view_buttons_visible")
        } else {
            setTimeout((w) => this.poll_custom_button_visibility(w), wait_ms)
        }
    }

    inject_buttons() {
        this.custom_view.after(
            function() {
                return $(this)
                    .clone()
                    .removeClass('goog-imageless-button-checked')
                    .text('-')
                    .click(() => unlimited_weeks.remove_week())
            }
        ).after(
            function() {
                return $(this)
                    .clone()
                    .removeClass('goog-imageless-button-checked')
                    .text('+')
                    .click(() => unlimited_weeks.add_week())
            }
        )

        if (this.is_custom_view_active) {
            unlimited_weeks.restore_weeks()
        }

        this.custom_view.click(() => {
            unlimited_weeks.restore_weeks()
        })
    }
}

class BigCal {
    get first_day_num() {
        if (!$('#gridcontainer span[class^="ca-cdp"]').is(':visible')) {
            // no grid, must be in agenda mode
            trigger('mousedown mouseup', toolbar.month_view)
        }
        return parseInt(
            // take a fresh look, in case it's only just appeared
            $('#gridcontainer span[class^="ca-cdp"]')
            .attr('class')
            .split('ca-cdp')
            .slice(-1)[0]
        )
    }

    get num_weeks() {
        return $('.month-row').length
    }
}

class MiniCal {
    constructor(height = 6) {
        // in week rows
        this.height = height
    }

    get cells() {
        return $('.dp-cell[class*="dp-o"]')
    }
    nth(n) {
        return this.cells.eq(n)
    }
    get first() {
        return this.nth(0)
    }
    get last() {
        return this.nth(7 * this.height - 1)
    }
    extract_day_num(el) {
        // Google Calendar seems to label each day with a monotonic number
        // that skips in an unknown way
        return parseInt(el.eq(0).attr('id').split('_').slice(-1)[0])
    }
    get first_day_num() {
        return this.extract_day_num(this.first)
    }
    get last_day_num() {
        return this.extract_day_num(this.last)
    }
    get month_start_indexes() {
        // return the positions of the 1st of the current
        // and next months
        return this.cells.map((i, el) => {
            if ($(el).text() === '1') {
                return i
            } else {
                return null
            }
        })
    }
    get current_month_start_index() {
        return this.month_start_indexes[0]
    }
    get next_month_start_index() {
            return this.month_start_indexes[1]
        }
    // current month may start in either first or second row
    get current_month_starts_high() {
        return this.current_month_start_index < 7
    }
    // next month may start in either last or penultimate row
    get next_month_starts_low() {
        return this.next_month_start_index >= 7 * (this.height - 1)
    }
    get weeks_in_month() {
        // bools get cast to 0 or 1 here. each true is an extra week
        return 3 + this.current_month_starts_high + this.next_month_starts_low
    }
    cell_from_day_num(day_num) {
        return this.cells.filter(`[id$="${day_num}"]`)
    }
    month_backward() {
        trigger('mousedown mouseup', $('.dp-sb-prev'))
    }
    month_forward() {
        trigger('mousedown mouseup', $('.dp-sb-next'))
    }
    navigate_to_day_num(day_num) {
        let i = 0
        while (day_num < this.first_day_num || this.last_day_num < day_num) {
            if (++i > 10) {
                throw "Too many loops"
            }
            if (day_num < this.first_day_num) {
                this.month_backward()
            } else if (this.last_day_num < day_num) {
                this.month_forward()
            } else {
                throw 'unknown condition'
            }
        }
        if (this.cell_from_day_num(day_num).length != 1) {
            throw "target not found on mini cal"
        }
    }
}

class UnlimitedWeeks {
    add_week() {
        this.alter_weeks(+1)
    }

    remove_week() {
        this.alter_weeks(-1)
    }

    allocate_weeks(weeks_left) {
        while (weeks_left > 0) {
            let weeks_in_month = mini_cal.weeks_in_month
            if (weeks_in_month > weeks_left) {
                break
            }
            weeks_left -= weeks_in_month
            mini_cal.month_forward()
        }
        if (weeks_left > 0) {
            return 7 * weeks_left
        }
        return 0
    }

    get_start_cell() {
        let index = mini_cal.current_month_start_index + 7
        return mini_cal.nth(index)
    }

    get_end_cell(days_remaining) {
        let index = days_remaining + mini_cal.current_month_start_index
        return mini_cal.nth(index)
    }

    move_weeks(start_day_num) {
        // move the calandar back to the date it started at

        // move active range forward, out the way
        mini_cal.month_forward()
        // we must click outside the active range, otherwise, we just select a single day
        trigger('mousedown mouseup', mini_cal.last)

        // now click the date we want, in the mini map
        mini_cal.navigate_to_day_num(start_day_num)
        trigger('mousedown mouseup', mini_cal.cell_from_day_num(start_day_num))
    }

    write_custom_button_label() {
        toolbar.custom_view
            .find('.goog-imageless-button-content')
            .text(`${big_cal.num_weeks} weeks`)
    }

    save_num_weeks() {
        chrome.storage.sync.set({
            'num_weeks': big_cal.num_weeks
        })
    }

    alter_weeks(delta) {
        if (toolbar.is_custom_view_active) {
            return this.display_weeks(big_cal.num_weeks + delta)
        }
        let that = this
        chrome.storage.sync.get('num_weeks', function(data) {
            that.display_weeks(data.num_weeks + delta)
        })
    }

    restore_weeks() {
        let that = this
        chrome.storage.sync.get('num_weeks', function(data) {
            if (data.num_weeks >= 2) {
                that.display_weeks(data.num_weeks)
            }
        })
    }

    display_weeks(weeks_left) {
        if (weeks_left < 2) {
            weeks_left = 2
        }
        let target_start_day_num = big_cal.first_day_num

        // move to custom view, click doesn't work here
        trigger('mousedown mouseup', toolbar.custom_view)

        // ensure start date in visible in mini cal
        mini_cal.navigate_to_day_num(target_start_day_num)

        // do a double manoeuvre: click next month during a click drag over the mini calendar.
        // this is how we reach more than one month
        trigger('mousedown', this.get_start_cell())
        let days_remaining = this.allocate_weeks(weeks_left)
        trigger('mousemove mouseup', this.get_end_cell(days_remaining))

        this.write_custom_button_label()

        this.move_weeks(target_start_day_num)

        // preserve number of weeks for next page (re)load
        this.save_num_weeks()
    }
}

let demo = false
let mini_cal = new MiniCal()
let big_cal = new BigCal()
let toolbar = new Toolbar()
let unlimited_weeks = new UnlimitedWeeks()

$(document)
    .on("custom_view_buttons_visible", function() {
        toolbar.inject_buttons()
        if (demo === true) {
            console.log('demo')
            // demo
            setTimeout(unlimited_weeks.add_week, 1000)
            setTimeout(unlimited_weeks.add_week, 1500)
            setTimeout(unlimited_weeks.remove_week, 3000)
        }
    })

$(document).ready(
    function() {
        // triggers custom_view_buttons_visible event
        toolbar.poll_custom_button_visibility()
    })
<commit_msg>don't persist when chrome storage missing<commit_after>/* jshint esversion: 6 */

let BUTTON_CHECKED = 'goog-imageless-button-checked'

function trigger(event_names, elem) {
    // event_names: space sep names of events
    // elem: jQuery element
    if (!event_names || event_names.length === 0) {
        throw (`Cannot trigger ${event_names}, element event_names`)
    }
    if (!elem || elem.length === 0) {
        throw (`Cannot trigger ${event_names}, element missing`)
    }
    for (let event_name of event_names.split(' ')) {
        let evt = document.createEvent("MouseEvents")
        // eek, there's gotta be a better way.
        // replace with https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent
        // https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Creating_and_triggering_events
        evt.initMouseEvent(event_name, true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
        let dom_elem = elem.get(0)
        dom_elem.dispatchEvent(evt)
    }
    return elem
}

class Toolbar {
    get buttons() {
        return $('#topRightNavigation .goog-imageless-button')
    }
    get month_view() {
        return this.buttons.eq(2)
    }
    get custom_view() {
        return this.buttons.eq(3)
    }
    get prev_month() {
        return $('.navBack').eq(0)
    }
    get today() {
        return $('#todayButton\\:1,#todayButton\\:2').children().eq(0)
    }
    get next_month() {
        return $('#dp_0_next')
    }
    get is_custom_view_active() {
        return this.custom_view.is('.goog-imageless-button-checked')
    }

    poll_custom_button_visibility(wait_ms = 500) {
        if (
            this.custom_view.is(":visible") &&
            this.buttons.filter('.goog-imageless-button-checked').is(":visible")
        ) {
            $(document).trigger("custom_view_buttons_visible")
        } else {
            setTimeout((w) => this.poll_custom_button_visibility(w), wait_ms)
        }
    }

    inject_buttons() {
        toolbar.custom_view.after(
            function() {
                return $(this)
                    .clone()
                    .removeClass(BUTTON_CHECKED)
                    .text('-')
                    .click(() => unlimited_weeks.remove_week())
            }
        ).after(
            function() {
                return $(this)
                    .clone()
                    .removeClass(BUTTON_CHECKED)
                    .text('+')
                    .click(() => unlimited_weeks.add_week())
            }
        )

        if (this.is_custom_view_active) {
            unlimited_weeks.restore_weeks()
        } else {
            unlimited_weeks.load_num_weeks().then(
                function(num_weeks) {
                    unlimited_weeks.write_custom_button_label(num_weeks)
                })
        }

        this.custom_view.click(() => {
            unlimited_weeks.restore_weeks()
        })

        this.buttons.mousedown(() => {
            this.buttons.removeClass(BUTTON_CHECKED)
        })
    }
}

class BigCal {
    get first_day_num() {
        if (!$('#gridcontainer span[class^="ca-cdp"]').is(':visible')) {
            // no grid, must be in agenda mode
            trigger('mousedown mouseup', toolbar.month_view)
        }
        return parseInt(
            // take a fresh look, in case it's only just appeared
            $('#gridcontainer span[class^="ca-cdp"]')
            .attr('class')
            .split('ca-cdp')
            .slice(-1)[0]
        )
    }

    get num_weeks() {
        return $('.month-row').length
    }
}

class MiniCal {
    constructor(height = 6) {
        // in week rows
        this.height = height
    }

    get cells() {
        return $('.dp-cell[class*="dp-o"]')
    }
    nth(n) {
        return this.cells.eq(n)
    }
    get first() {
        return this.nth(0)
    }
    get last() {
        return this.nth(7 * this.height - 1)
    }
    extract_day_num(el) {
        // Google Calendar seems to label each day with a monotonic number
        // that skips in an unknown way
        return parseInt(el.eq(0).attr('id').split('_').slice(-1)[0])
    }
    get first_day_num() {
        return this.extract_day_num(this.first)
    }
    get last_day_num() {
        return this.extract_day_num(this.last)
    }
    get month_start_indexes() {
        // return the positions of the 1st of the current
        // and next months
        return this.cells.map((i, el) => {
            if ($(el).text() === '1') {
                return i
            } else {
                return null
            }
        })
    }
    get current_month_start_index() {
        return this.month_start_indexes[0]
    }
    get next_month_start_index() {
        return this.month_start_indexes[1]
    }
    // current month may start in either first or second row
    get current_month_starts_high() {
        return this.current_month_start_index < 7
    }
    // next month may start in either last or penultimate row
    get next_month_starts_low() {
        return this.next_month_start_index >= 7 * (this.height - 1)
    }
    get weeks_in_month() {
        // bools get cast to 0 or 1 here. each true is an extra week
        return 3 + this.current_month_starts_high + this.next_month_starts_low
    }
    cell_from_day_num(day_num) {
        return this.cells.filter(`[id$="${day_num}"]`)
    }
    month_backward() {
        trigger('mousedown mouseup', $('.dp-sb-prev'))
    }
    month_forward() {
        trigger('mousedown mouseup', $('.dp-sb-next'))
    }
    navigate_to_day_num(day_num) {
        let i = 0
        while (day_num < this.first_day_num || this.last_day_num < day_num) {
            if (++i > 10) {
                throw "Too many iterations"
            }
            if (day_num < this.first_day_num) {
                this.month_backward()
            } else if (this.last_day_num < day_num) {
                this.month_forward()
            } else {
                throw 'unknown condition'
            }
        }
        if (this.cell_from_day_num(day_num).length != 1) {
            throw "target not found on mini cal"
        }
    }
}

class UnlimitedWeeks {
    add_week() {
        this.alter_weeks(+1)
    }

    remove_week() {
        this.alter_weeks(-1)
    }

    allocate_weeks(weeks_left) {
        while (weeks_left > 0) {
            let weeks_in_month = mini_cal.weeks_in_month
            if (weeks_in_month > weeks_left) {
                break
            }
            weeks_left -= weeks_in_month
            mini_cal.month_forward()
        }
        if (weeks_left > 0) {
            return 7 * weeks_left
        }
        return 0
    }

    get_start_cell() {
        let index = mini_cal.current_month_start_index + 7
        return mini_cal.nth(index)
    }

    get_end_cell(days_remaining) {
        let index = days_remaining + mini_cal.current_month_start_index
        return mini_cal.nth(index)
    }

    move_weeks(start_day_num) {
        // move the calandar back to the date it started at

        // move active range forward, out the way
        mini_cal.month_forward()
        // we must click outside the active range, otherwise, we just select a single day
        trigger('mousedown mouseup', mini_cal.last)

        // now click the date we want, in the mini map
        mini_cal.navigate_to_day_num(start_day_num)
        trigger('mousedown mouseup', mini_cal.cell_from_day_num(start_day_num))
    }

    write_custom_button_label(num_weeks=null) {
        toolbar.custom_view
            .find('.goog-imageless-button-content')
            .text(`${num_weeks || big_cal.num_weeks} weeks`)
    }

    can_persist() {
        return chrome && chrome.storage && chrome.storage.sync
    }

    save_num_weeks() {
        if (this.can_persist) {
            chrome.storage.sync.set({
                'num_weeks': big_cal.num_weeks
            })
        }
    }

    load_num_weeks() {
        // returns a promise
        if (!this.can_persist) {
            return Promise((resolve, reject) => resolve(null))
        }
        return new Promise(function(resolve, reject){
            chrome.storage.sync.get('num_weeks', function(data) {
                if (
                    $.isEmptyObject(data)
                    || typeof data.num_weeks === 'number'
                    || typeof data.num_weeks >= 2
                ) {
                    return resolve(data.num_weeks)
                } else {
                    return resolve(big_cal.num_weeks)
                }
            })
        })
    }

    alter_weeks(delta) {
        if (toolbar.is_custom_view_active) {
            return this.display_weeks(big_cal.num_weeks + delta)
        }
        let that = this
        this.load_num_weeks().then(function(num_weeks) {
            that.display_weeks(num_weeks + delta)
        })
    }

    restore_weeks() {
        let that = this
        this.load_num_weeks().then(function(num_weeks) {
            that.display_weeks(num_weeks)
        })
    }

    display_weeks(weeks_left) {
        if (weeks_left < 2) {
            weeks_left = 2
        }
        let target_start_day_num = big_cal.first_day_num

        // move to custom view, click doesn't work here
        trigger('mousedown mouseup', toolbar.custom_view)

        // ensure start date in visible in mini cal
        mini_cal.navigate_to_day_num(target_start_day_num)

        // do a double manoeuvre: click next month during a click drag over the mini calendar.
        // this is how we reach more than one month
        trigger('mousedown', this.get_start_cell())
        let days_remaining = this.allocate_weeks(weeks_left)
        trigger('mousemove mouseup', this.get_end_cell(days_remaining))

        this.write_custom_button_label()

        this.move_weeks(target_start_day_num)

        // preserve number of weeks for next page (re)load
        this.save_num_weeks()
        toolbar.custom_view.addClass(BUTTON_CHECKED)

    }
}

let demo = false
let mini_cal = new MiniCal()
let big_cal = new BigCal()
let toolbar = new Toolbar()
let unlimited_weeks = new UnlimitedWeeks()

$(document)
    .on("custom_view_buttons_visible", function() {
        toolbar.inject_buttons()
        if (demo === true) {
            console.log('demo')
            setTimeout(unlimited_weeks.add_week, 1000)
            setTimeout(unlimited_weeks.add_week, 1500)
            setTimeout(unlimited_weeks.remove_week, 3000)
        }
    })

$(document).ready(
    function() {
        // triggers custom_view_buttons_visible event
        toolbar.poll_custom_button_visibility()
    })
<|endoftext|>


<commit_before>'use strict';

var q = require('q'),
    _ = require('lodash'),

    config,

    elasticsearch = require('elasticsearch'),
    client,

    /**
     * Looks for an error property and if it doesn't exist creates one.
     *
     * @param  {object} error An elasticsearch response containing an error message.
     * @return {object}       The adapted error.
     */
    adaptError = function (error) {
        if (error && !error.error) {
            error = {
                'error': error
            };
        }

        return error;
    },

    adaptResult = function (result) {
        var _result = result.fields || result._source;
        _result.id = result.id || result._id;

        return _result;
    },

    adaptResults = function (results) {
        results = _.map(results, function (result) {
            return adaptResult(result);
        });

        return {'results': results};
    },

    /**
     * The most basic GET functionality.
     *
     * @param  {string} id The id of the record you wish to retrieve.
     * @return {object}    The chainable functionality used to build the sentence.
     */
    get = function (id) {
        var typeName;

        if (_.isArray(id)) {
            return getMany(id);
        }

        return {
            /**
             * @param  {string} _typeName
             * @return {string}
             */
            'ofType': function (_typeName) {
                typeName = _typeName;
                return this;
            },

            'from': function (indexName) {
                var defer = q.defer();

                client.get({
                    'index': indexName,
                    'type': typeName,
                    'id': id
                }, function (error, response) {
                    var result;

                    if (error) {
                        defer.reject(adaptError(error));
                        return;
                    }

                    result = adaptResult(response);
                    defer.resolve(result);
                });

                return defer.promise;
            }
        };
    },

    /**
     * Takes an array of ids to return many results.
     *
     * @param {array} ids An array of ids to look up
     * @return {promise}
     */
    getMany = function (ids) {
        var typeName;

        if (!_.isArray(ids)) {
            ids = [ids];
        }

        // Ensure that array has only unique ids.
        // The second boolean parameter is 'isSorted', and runs much faster.
        ids = _.uniq(ids, true);

        return {
            /**
             * @param  {string} _typeName
             * @return {string}
             */
            'ofType': function (_typeName) {
                typeName = _typeName;
                return this;
            },

            'from': function (indexName) {
                var defer = q.defer();

                client.mget({
                    'index': indexName,
                    'type': typeName,
                    'body': {
                        'ids': ids
                    }
                }, function (error, response) {
                    var results;

                    if (error) {
                        defer.reject(adaptError(error));
                        return;
                    }

                    results = adaptResults(response.docs);
                    results.total = results.results.length;
                    defer.resolve(results);
                });

                return defer.promise;
            }
        };
    };

exports.post = function (data) {
    var typeName;

    if (!_.isArray(data)) {
        data = [data];
    }

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        into: function (indexName) {
            var promises = [],
                errorDefer;

            if (!typeName) {
                errorDefer = q.defer();
                errorDefer.reject(new Error('You must specify a type'));
                return errorDefer.promise;
            }

            data.forEach(function (item) {
                var params,
                    defer = q.defer();

                promises.push(defer.promise);

                if (!item.createdAt) {
                    item.createdAt = (new Date()).toISOString();
                }

                params = {
                    index: indexName,
                    type: typeName,
                    timestamp: (new Date()).toISOString(),
                    body: item
                };

                if (item.id) {
                    params.id = item.id;
                }

                client.create(
                    params,
                    function (error, response) {
                        if (error) {
                            defer.reject(adaptError(error));
                            return;
                        }
                        client.get({
                            index: indexName,
                            type: typeName,
                            id: response._id
                        }, function (error, result) {
                            if (error) {
                                defer.reject(adaptError(error));
                                return;
                            }
                            result = adaptResult(result);
                            defer.resolve(result);
                        });
                    }
                );
            });

            if (data.length === 1) {
                return promises[0];
            }

            return q.all(promises);
        }
    };
};

/**
 * For use with the elasticsearch dsl query structure.
 *
 * @param  {object} dslQuery
 * @return {object}
 */
exports.dslQuery = function (dslQuery) {
    var typeName,
        offset = 0,
        sort,
        filter,
        // results to return
        size = 1000000;

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        filterBy: function (_filter) {
            filter = _filter;
            return this;
        },

        sortBy: function (_sort, direction) {
            var sortOption = {};

            sort = sort || [];

            sortOption[_sort] = {
                'order': direction
            };

            sort.push(sortOption);
            return this;
        },

        withSize: function (_size) {
            size = _size;
            return this;
        },

        from: function (indexName) {
            var defer = q.defer(),
                params = {
                    index: indexName,
                    type: typeName,
                    from: offset,
                    size: size
                },
                dslParams = {};

            if (sort) {
                dslParams.sort = sort;
            }

            if (dslQuery) {
                dslParams.query = dslQuery;
            }

            if (filter) {
                dslParams.filter = filter;
            }

            params.body = dslParams;

            client.search(params, function (error, results) {
                var response;

                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }

                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * For use with the elasticsearch url query string.
 *
 * @param  {string} queryString
 * @return {object}
 */
exports.stringQuery = function (queryString) {
    var typeName,
        offset = 0,
        sort = [],
        // results to return
        size = 1000000;

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        sortBy: function (_sort) {
            sort = _sort;
            return this;
        },

        withSize: function (_size) {
            size = _size;
            return this;
        },

        from: function (indexName) {
            var defer = q.defer(),
                params = {
                    index: indexName,
                    type: typeName,
                    from: offset,
                    size: size,
                    sort: sort,
                    q: queryString
                };

            client.search(params, function (error, results) {
                var response;

                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }

                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * Convenience function. Depending on whether the query passed as a parameter is an object or a
 * string depends on which query function is called.
 *
 * @param  {string|object} query Accepts both url string query and dsl object query.
 * @return {object}
 */
exports.query = function (query) {
    if (typeof query === 'string') {
        return exports.stringQuery(query);
    } else {
        return exports.dslQuery(query);
    }
};

/**
 * Use to retrieve all results of [type] from [index].
 *
 * @param  {string} type
 * @return {promise}
 */
exports.getAll = function (type) {
    var offset = 0,
        sort = '',
        size = 1000;

    return {
        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        size: function (_size) {
            size = _size;
            return this;
        },

        /**
         * @param String _sort A comma-separated list of <field>:<direction>
         *                      pairs
         * @TODO: validate _sort
         */
        sortBy: function (_sort) {
            sort = _sort;
            return this;
        },
        from: function (indexName) {
            var defer = q.defer();

            if (!type) {
                // @TODO: if we ever actually need 'types' as a array, check
                // back in git history.
                defer.reject(new Error('Type must be supplied'));
            }

            client.search({
                index: indexName,
                q: '_type:' + type,
                from: offset,
                sort: sort,
                size: size
            }, function (error, results) {
                var response;
                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }
                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * PUT data to the supplied index. Used to update existing data.
 *
 * @param  {object} data The data to update.
 * @return {object}
 */
exports.put = function (data) {
    var typeName;

    return {

        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withId: function (_id) {
            data.id = _id;
            return this;
        },

        into: function (indexName) {
            var defer = q.defer(),

                /**
                 * Loops through the existing data key values and adds any missing from
                 * the data we want to PUT. Then saves to the elasticsearch index.
                 *
                 * @param  {object} existingData The data that exists with the id provided.
                 * @return {promise}             Resolves to an adapted data set.
                 */
                updateExistingData = function (existingData) {
                    data.updatedAt = (new Date()).toISOString();

                    _.forEach(existingData._source, function (value, key) {
                        if (data[key] === undefined) {
                            data[key] = value;
                        }
                    });

                    return client.update({
                        'id': data.id,
                        'index': indexName,
                        'type': typeName,
                        'body': {
                            'doc': data
                        }
                    });
                };

            if (!typeName) {
                defer.reject(new Error('You must specify a type'));
                return;
            }

            // GET the data as it exists now...
            exports.get(data.id).ofType(typeName).from(indexName)
                // ...update...
                .then(updateExistingData)
                // now GET the data again just to make certain it is written and to
                // make sure that the actual data now stored is returned.
                .then(function (updateResponse) {
                    return exports.get(updateResponse._id).ofType(typeName).from(indexName);
                })
                .then(function (updatedData) {
                    defer.resolve(updatedData);
                })
                .fail(function (error) {
                    defer.reject(adaptError(error));
                });

            return defer.promise;
        }
    };
};

/**
 * Delete type from index.
 * @example
 * db.delete('myType').withId(5).from('myIndex');
 * // 'withId' param is the id to delete.
 * // 'from' param is the string name of the index to delete from.
 *
 * @param  {string} typeName The name of the type to delete.
 * @return {object}
 */
exports.delete = function (typeName) {
    var id;

    return {
        withId: function (_id) {
            id = _id;
            return this;
        },

        from: function (indexName) {
            var defer = q.defer();

            client.delete({
                index: indexName,
                type: typeName,
                id: id
            }, function (error, result) {
                var response;

                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }

                // @todo: clean this up
                defer.resolve({
                    'results': result.found ? [result._id] : [],
                    'total': result.found ? 1 : 0
                });
            });

            return defer.promise;
        }
    };
};

exports.checkIndexExists = function (indexName) {
    var defer = q.defer();

    client.indices.exists({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

exports.destroyIndex = function (indexName) {
    var defer = q.defer();

    client.indices.delete({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

exports.createIndex = function (indexName) {
    var defer = q.defer();

    client.indices.create({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

/**
 * Sets the configuration for the location of the database. Acts as a getter and a setter.
 *
 * @see config.js.example
 * @param  {object} _config The configuration object.
 * @return {object|undefined}         The configuration object.
 */
exports.config = function (_config) {
    var clientOptions;

    if (!_config) {
        return config;
    }

    config = _config;

    clientOptions = {
        host: config.db.url,
        maxKeepAliveRequests: 1
    };

    if (config.db.logging) {
        clientOptions.log = config.db.logging;
    }

    // @todo: dependency injection needed here
    client = new elasticsearch.Client(clientOptions);

    return config;
};

/**
 * Given a name and a template, it will save it to the es templates.
 * For more info on how and why to use templates refer to the docs.
 *
 * @param {string} name name of the template.
 * @param {string} template the json template as a string.
 * @return {object} promise
 */
exports.createTemplate = function (name, template) {
    var defer = q.defer();

    client.indices.putTemplate({
        name: name,
        body: template
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

// API
exports.get = get;
exports.getMany = getMany;
<commit_msg>Made delete conform to the same style as the rest of the wrapper<commit_after>'use strict';

var q = require('q'),
    _ = require('lodash'),

    config,

    elasticsearch = require('elasticsearch'),
    client,

    /**
     * Looks for an error property and if it doesn't exist creates one.
     *
     * @param  {object} error An elasticsearch response containing an error message.
     * @return {object}       The adapted error.
     */
    adaptError = function (error) {
        if (error && !error.error) {
            error = {
                'error': error
            };
        }

        return error;
    },

    adaptResult = function (result) {
        var _result = result.fields || result._source;
        _result.id = result.id || result._id;

        return _result;
    },

    adaptResults = function (results) {
        results = _.map(results, function (result) {
            return adaptResult(result);
        });

        return {'results': results};
    },

    /**
     * The most basic GET functionality.
     *
     * @param  {string} id The id of the record you wish to retrieve.
     * @return {object}    The chainable functionality used to build the sentence.
     */
    get = function (id) {
        var typeName;

        if (_.isArray(id)) {
            return getMany(id);
        }

        return {
            /**
             * @param  {string} _typeName
             * @return {string}
             */
            'ofType': function (_typeName) {
                typeName = _typeName;
                return this;
            },

            'from': function (indexName) {
                var defer = q.defer();

                client.get({
                    'index': indexName,
                    'type': typeName,
                    'id': id
                }, function (error, response) {
                    var result;

                    if (error) {
                        defer.reject(adaptError(error));
                        return;
                    }

                    result = adaptResult(response);
                    defer.resolve(result);
                });

                return defer.promise;
            }
        };
    },

    /**
     * Takes an array of ids to return many results.
     *
     * @param {array} ids An array of ids to look up
     * @return {promise}
     */
    getMany = function (ids) {
        var typeName;

        if (!_.isArray(ids)) {
            ids = [ids];
        }

        // Ensure that array has only unique ids.
        // The second boolean parameter is 'isSorted', and runs much faster.
        ids = _.uniq(ids, true);

        return {
            /**
             * @param  {string} _typeName
             * @return {string}
             */
            'ofType': function (_typeName) {
                typeName = _typeName;
                return this;
            },

            'from': function (indexName) {
                var defer = q.defer();

                client.mget({
                    'index': indexName,
                    'type': typeName,
                    'body': {
                        'ids': ids
                    }
                }, function (error, response) {
                    var results;

                    if (error) {
                        defer.reject(adaptError(error));
                        return;
                    }

                    results = adaptResults(response.docs);
                    results.total = results.results.length;
                    defer.resolve(results);
                });

                return defer.promise;
            }
        };
    };

exports.post = function (data) {
    var typeName;

    if (!_.isArray(data)) {
        data = [data];
    }

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        into: function (indexName) {
            var promises = [],
                errorDefer;

            if (!typeName) {
                errorDefer = q.defer();
                errorDefer.reject(new Error('You must specify a type'));
                return errorDefer.promise;
            }

            data.forEach(function (item) {
                var params,
                    defer = q.defer();

                promises.push(defer.promise);

                if (!item.createdAt) {
                    item.createdAt = (new Date()).toISOString();
                }

                params = {
                    index: indexName,
                    type: typeName,
                    timestamp: (new Date()).toISOString(),
                    body: item
                };

                if (item.id) {
                    params.id = item.id;
                }

                client.create(
                    params,
                    function (error, response) {
                        if (error) {
                            defer.reject(adaptError(error));
                            return;
                        }
                        client.get({
                            index: indexName,
                            type: typeName,
                            id: response._id
                        }, function (error, result) {
                            if (error) {
                                defer.reject(adaptError(error));
                                return;
                            }
                            result = adaptResult(result);
                            defer.resolve(result);
                        });
                    }
                );
            });

            if (data.length === 1) {
                return promises[0];
            }

            return q.all(promises);
        }
    };
};

/**
 * For use with the elasticsearch dsl query structure.
 *
 * @param  {object} dslQuery
 * @return {object}
 */
exports.dslQuery = function (dslQuery) {
    var typeName,
        offset = 0,
        sort,
        filter,
        // results to return
        size = 1000000;

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        filterBy: function (_filter) {
            filter = _filter;
            return this;
        },

        sortBy: function (_sort, direction) {
            var sortOption = {};

            sort = sort || [];

            sortOption[_sort] = {
                'order': direction
            };

            sort.push(sortOption);
            return this;
        },

        withSize: function (_size) {
            size = _size;
            return this;
        },

        from: function (indexName) {
            var defer = q.defer(),
                params = {
                    index: indexName,
                    type: typeName,
                    from: offset,
                    size: size
                },
                dslParams = {};

            if (sort) {
                dslParams.sort = sort;
            }

            if (dslQuery) {
                dslParams.query = dslQuery;
            }

            if (filter) {
                dslParams.filter = filter;
            }

            params.body = dslParams;

            client.search(params, function (error, results) {
                var response;

                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }

                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * For use with the elasticsearch url query string.
 *
 * @param  {string} queryString
 * @return {object}
 */
exports.stringQuery = function (queryString) {
    var typeName,
        offset = 0,
        sort = [],
        // results to return
        size = 1000000;

    return {
        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        sortBy: function (_sort) {
            sort = _sort;
            return this;
        },

        withSize: function (_size) {
            size = _size;
            return this;
        },

        from: function (indexName) {
            var defer = q.defer(),
                params = {
                    index: indexName,
                    type: typeName,
                    from: offset,
                    size: size,
                    sort: sort,
                    q: queryString
                };

            client.search(params, function (error, results) {
                var response;

                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }

                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * Convenience function. Depending on whether the query passed as a parameter is an object or a
 * string depends on which query function is called.
 *
 * @param  {string|object} query Accepts both url string query and dsl object query.
 * @return {object}
 */
exports.query = function (query) {
    if (typeof query === 'string') {
        return exports.stringQuery(query);
    } else {
        return exports.dslQuery(query);
    }
};

/**
 * Use to retrieve all results of [type] from [index].
 *
 * @param  {string} type
 * @return {promise}
 */
exports.getAll = function (type) {
    var offset = 0,
        sort = '',
        size = 1000;

    return {
        withOffset: function (_offset) {
            offset = _offset;
            return this;
        },

        size: function (_size) {
            size = _size;
            return this;
        },

        /**
         * @param String _sort A comma-separated list of <field>:<direction>
         *                      pairs
         * @TODO: validate _sort
         */
        sortBy: function (_sort) {
            sort = _sort;
            return this;
        },
        from: function (indexName) {
            var defer = q.defer();

            if (!type) {
                // @TODO: if we ever actually need 'types' as a array, check
                // back in git history.
                defer.reject(new Error('Type must be supplied'));
            }

            client.search({
                index: indexName,
                q: '_type:' + type,
                from: offset,
                sort: sort,
                size: size
            }, function (error, results) {
                var response;
                if (error) {
                    defer.reject(adaptError(error));
                    return;
                }
                response = adaptResults(results.hits.hits);
                response.total = results.hits.total;
                defer.resolve(response);
            });

            return defer.promise;
        }
    };
};

/**
 * PUT data to the supplied index. Used to update existing data.
 *
 * @param  {object} data The data to update.
 * @return {object}
 */
exports.put = function (data) {
    var typeName;

    return {

        ofType: function (_typeName) {
            typeName = _typeName;
            return this;
        },

        withId: function (_id) {
            data.id = _id;
            return this;
        },

        into: function (indexName) {
            var defer = q.defer(),

                /**
                 * Loops through the existing data key values and adds any missing from
                 * the data we want to PUT. Then saves to the elasticsearch index.
                 *
                 * @param  {object} existingData The data that exists with the id provided.
                 * @return {promise}             Resolves to an adapted data set.
                 */
                updateExistingData = function (existingData) {
                    data.updatedAt = (new Date()).toISOString();

                    _.forEach(existingData._source, function (value, key) {
                        if (data[key] === undefined) {
                            data[key] = value;
                        }
                    });

                    return client.update({
                        'id': data.id,
                        'index': indexName,
                        'type': typeName,
                        'body': {
                            'doc': data
                        }
                    });
                };

            if (!typeName) {
                defer.reject(new Error('You must specify a type'));
                return;
            }

            // GET the data as it exists now...
            exports.get(data.id).ofType(typeName).from(indexName)
                // ...update...
                .then(updateExistingData)
                // now GET the data again just to make certain it is written and to
                // make sure that the actual data now stored is returned.
                .then(function (updateResponse) {
                    return exports.get(updateResponse._id).ofType(typeName).from(indexName);
                })
                .then(function (updatedData) {
                    defer.resolve(updatedData);
                })
                .fail(function (error) {
                    defer.reject(adaptError(error));
                });

            return defer.promise;
        }
    };
};

/**
 * Delete type from index.
 * @example
 * db.delete(id).ofType(type).from('myIndex');
 * // 'ofType' param is the type to delete.
 * // 'from' param is the string name of the index to delete from.
 *
 * @param  {string} typeName The name of the type to delete.
 * @return {object}
 */
 exports.delete = function (id) {
     return {
         ofType: function (_typeName) {
             typeName = _typeName;
             return this;
         },

         from: function (indexName) {
             var defer = q.defer();

             client.delete({
                 index: indexName,
                 type: typeName,
                 id: id
             }, function (error, result) {
                 var response;

                 if (error) {
                     defer.reject(adaptError(error));
                     return;
                 }

                 // @todo: clean this up
                 defer.resolve({
                     'results': result.found ? [result._id] : [],
                     'total': result.found ? 1 : 0
                 });
             });

             return defer.promise;
         }
     };
 };

exports.checkIndexExists = function (indexName) {
    var defer = q.defer();

    client.indices.exists({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

exports.destroyIndex = function (indexName) {
    var defer = q.defer();

    client.indices.delete({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

exports.createIndex = function (indexName) {
    var defer = q.defer();

    client.indices.create({
        index: indexName
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

/**
 * Sets the configuration for the location of the database. Acts as a getter and a setter.
 *
 * @see config.js.example
 * @param  {object} _config The configuration object.
 * @return {object|undefined}         The configuration object.
 */
exports.config = function (_config) {
    var clientOptions;

    if (!_config) {
        return config;
    }

    config = _config;

    clientOptions = {
        host: config.db.url,
        maxKeepAliveRequests: 1
    };

    if (config.db.logging) {
        clientOptions.log = config.db.logging;
    }

    // @todo: dependency injection needed here
    client = new elasticsearch.Client(clientOptions);

    return config;
};

/**
 * Given a name and a template, it will save it to the es templates.
 * For more info on how and why to use templates refer to the docs.
 *
 * @param {string} name name of the template.
 * @param {string} template the json template as a string.
 * @return {object} promise
 */
exports.createTemplate = function (name, template) {
    var defer = q.defer();

    client.indices.putTemplate({
        name: name,
        body: template
    }, function (error, response) {
        if (error) {
            defer.reject(adaptError(error));
            return;
        }

        defer.resolve(response);
    });

    return defer.promise;
};

// API
exports.get = get;
exports.getMany = getMany;
<|endoftext|>


<commit_before>(function() {
    function htmlreplace(a, b, reflags, element) {
        if (!element) element = document.body;
        var nodes = element.childNodes;
        var r = new RegExp(a, reflags);
        for (var n=0; n<nodes.length; n++) {
            if (nodes[n].nodeType == Node.TEXT_NODE) {
                nodes[n].textContent = nodes[n].textContent.replace(r, b);
            } else {
                htmlreplace(a, b, reflags, nodes[n]);
            }
        }
    }

    var readyStateCheckInterval = setInterval(function() {
	    if (document.readyState === "complete") {
		    clearInterval(readyStateCheckInterval);

		    htmlreplace("GNU", "GNU EH O CARALHO!!!", 'g');
		    htmlreplace("GNU[gG]", "GNU eh o caralho!!!", 'g');
		    htmlreplace("ubuntu", "gnu eh o caralho porra!!!", 'gi');
            htmlreplace("gnu/linux","Linux");
	    }
    }, 10);
})();
<commit_msg>Updating and add gnu/linux > Linux<commit_after>(function() {
    function htmlreplace(a, b, reflags, element) {
        if (!element) element = document.body;
        var nodes = element.childNodes;
        var r = new RegExp(a, reflags);
        for (var n=0; n<nodes.length; n++) {
            if (nodes[n].nodeType == Node.TEXT_NODE) {
                nodes[n].textContent = nodes[n].textContent.replace(r, b);
            } else {
                htmlreplace(a, b, reflags, nodes[n]);
            }
        }
    }

    var readyStateCheckInterval = setInterval(function() {
	    if (document.readyState === "complete") {
		    clearInterval(readyStateCheckInterval);

		    htmlreplace("GNU", "GNU EH O CARALHO!!!", 'g');
		    htmlreplace("GNU[gG]", "GNU eh o caralho!!!", 'g');
		    htmlreplace("ubuntu", "gnu eh o caralho porra!!!", 'gi');
                    htmlreplace("gnu/linux","Linux");
	    }
    }, 10);
})();
<|endoftext|>


<commit_before>'use strict'

let fs = require('fs'),
	path = require('path'),
	co = require('co'),
	csv = new (require('../modules/csvPromise'))(),
	xlsx = require('node-xlsx'),
	toolbelt = require('../modules/toolbelt')

class Base {
	constructor({componentName, componentNameSingular, routes, additionalDefaultRoutes, addDefaultRoutes}) {
		this.componentName = componentName
		this.componentNameSingular = componentNameSingular

		this.routes = routes
		if (addDefaultRoutes instanceof Array) {
			let defaultRoutes = {
					create: {method: 'post', path: `/${this.componentName}/create`, func: 'create'},
					read: {method: 'get', path: `/${this.componentName}/read`, func: 'read'},
					readList: {method: 'post', path: `/${this.componentName}/readList`, func: 'readList'},
					update: {method: 'post', path: `/${this.componentName}/update`, func: 'update'},
					checkImportFile: {method: 'get', path: `/${this.componentName}/checkImportFile`, func: 'checkImportFile'},
					importFile: {method: 'post', path: `/${this.componentName}/importFile`, func: 'importFile'},
					delete: {method: 'get', path: `/${this.componentName}/delete`, func: 'delete'}
				},
				defaultRoutesToAdd = []
			if (typeof additionalDefaultRoutes === 'object') {
				for (let key in additionalDefaultRoutes) {
					defaultRoutes[key] = additionalDefaultRoutes[key]
				}
			}
			addDefaultRoutes.forEach((route, index) => {
				if (defaultRoutes[route]) {
					defaultRoutesToAdd.push(defaultRoutes[route])
				}
			})
			this.routes = this.routes.concat(defaultRoutesToAdd)
		}
	}

	getRoutes() {
		return this.routes
	}

	importFileCheck({locals, inputFileName, delimiter}) {
		let instance = this
		return co(function*() {
			let fileName = inputFileName,
				extNameRegex = new RegExp(/\.[^/.]+$/),
				extName = extNameRegex.exec(fileName),
				inputFileData = fs.readFileSync(path.join(locals.cfg.globalUploadPath, inputFileName)),
				parsedInputFileData = null,
				template = {
					fileData: fs.readFileSync(path.join(locals.cfg.globalStoragePath, `/importTemplates/${instance.componentName}.csv`)),
					columns: []
				},
				matchesTemplate = true,
				columns = []
			extName = extName && extName[0] || ''
			template.data = yield csv.parse({data: template.fileData, options: {delimiter: ';'}})
			template.data[0].forEach((column, index) => {
				template.columns.push(column)
			})

			if (extName === '.csv') {
				parsedInputFileData = yield csv.parse({data: inputFileData, options: {delimiter: delimiter}})
			}
			if (extName === '.xlsx') {
				parsedInputFileData = xlsx.parse(inputFileData)
				parsedInputFileData = parsedInputFileData[0] && parsedInputFileData[0].data || null
			}

			if (parsedInputFileData && parsedInputFileData[0]) {
				parsedInputFileData[0].forEach((column, index) => {
					if (matchesTemplate && (template.columns[index] !== column)) {
						matchesTemplate = false
					}
					columns.push(column)
				})
			}
			return {matchesTemplate, columns, templateColumns: template.columns, fileData: parsedInputFileData}
		})
	}

	create() {
		let instance = this
		return function* (req, res, next) {
			try {
				let response = {}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].create(req.body)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	read() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {},
					response = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].read(query)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	readList() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].readList(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	update() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].update(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	checkImportFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield instance.importFileCheck({
					locals: req.locals,
					inputFileName: decodeURIComponent(req.query.fileName),
					delimiter: ';'
				}))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	importFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				let check = yield instance.importFileCheck({
						locals: req.locals,
						inputFileName: req.body.locationDataFile,
						delimiter: req.body.delimiter || ';'
					}),
					dbComponent = req.locals.dbComponents[instance.componentName],
					dataToInsert = [],
					dataToUpdate = []

				if (!(check.fileData instanceof Array) || (check.fileData.length < 2)) {
					throw {customMessage: 'The file is empty or does not contain any data.'}
				}

				if (check.matchesTemplate) {
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.columns.forEach((column, cIndex) => {
								item[column] = row[cIndex]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				} else {
					let columnsToMatch = {}
					check.templateColumns.forEach((column, cIndex) => {
						let fileColumn = req.body[column]
						if (!fileColumn) {
							throw {customMessage: 'The file does not match the template and not all columns have been mapped.'}
						}
						columnsToMatch[column] = check.columns.indexOf(fileColumn)
					})
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.templateColumns.forEach((column, cIndex) => {
								item[column] = row[columnsToMatch[column]]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				}

				req.body.UserId = req.session.passport.user

				yield req.locals.db.sequelize.transaction((t) => {
					return co(function*() {
						req.body.transaction = t

						if (dataToInsert.length) {
							yield dbComponent.bulkCreate({
								dbObjects: dataToInsert,
								options: req.body
							})
						}

						if (dataToUpdate.length) {
							for (let i in dataToUpdate) {
								let item = dataToUpdate[i]
								yield dbComponent.update({dbObject: item, where: {id: item.id}, transaction: t})
							}
						}

						return true
					})
				})

				res.json({success: true})
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	delete() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				res.json(yield req.locals.db.components[instance.componentName].destroy(query))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}
}

module.exports = Base
<commit_msg>client class - fix for when no routes are provided<commit_after>'use strict'

let fs = require('fs'),
	path = require('path'),
	co = require('co'),
	csv = new (require('../modules/csvPromise'))(),
	xlsx = require('node-xlsx'),
	toolbelt = require('../modules/toolbelt')

class Base {
	constructor({componentName, componentNameSingular, routes, additionalDefaultRoutes, addDefaultRoutes}) {
		this.componentName = componentName
		this.componentNameSingular = componentNameSingular

		this.routes = routes || []
		if (addDefaultRoutes instanceof Array) {
			let defaultRoutes = {
					create: {method: 'post', path: `/${this.componentName}/create`, func: 'create'},
					read: {method: 'get', path: `/${this.componentName}/read`, func: 'read'},
					readList: {method: 'post', path: `/${this.componentName}/readList`, func: 'readList'},
					update: {method: 'post', path: `/${this.componentName}/update`, func: 'update'},
					checkImportFile: {method: 'get', path: `/${this.componentName}/checkImportFile`, func: 'checkImportFile'},
					importFile: {method: 'post', path: `/${this.componentName}/importFile`, func: 'importFile'},
					delete: {method: 'get', path: `/${this.componentName}/delete`, func: 'delete'}
				},
				defaultRoutesToAdd = []
			if (typeof additionalDefaultRoutes === 'object') {
				for (let key in additionalDefaultRoutes) {
					defaultRoutes[key] = additionalDefaultRoutes[key]
				}
			}
			addDefaultRoutes.forEach((route, index) => {
				if (defaultRoutes[route]) {
					defaultRoutesToAdd.push(defaultRoutes[route])
				}
			})
			this.routes = this.routes.concat(defaultRoutesToAdd)
		}
	}

	getRoutes() {
		return this.routes
	}

	importFileCheck({locals, inputFileName, delimiter}) {
		let instance = this
		return co(function*() {
			let fileName = inputFileName,
				extNameRegex = new RegExp(/\.[^/.]+$/),
				extName = extNameRegex.exec(fileName),
				inputFileData = fs.readFileSync(path.join(locals.cfg.globalUploadPath, inputFileName)),
				parsedInputFileData = null,
				template = {
					fileData: fs.readFileSync(path.join(locals.cfg.globalStoragePath, `/importTemplates/${instance.componentName}.csv`)),
					columns: []
				},
				matchesTemplate = true,
				columns = []
			extName = extName && extName[0] || ''
			template.data = yield csv.parse({data: template.fileData, options: {delimiter: ';'}})
			template.data[0].forEach((column, index) => {
				template.columns.push(column)
			})

			if (extName === '.csv') {
				parsedInputFileData = yield csv.parse({data: inputFileData, options: {delimiter: delimiter}})
			}
			if (extName === '.xlsx') {
				parsedInputFileData = xlsx.parse(inputFileData)
				parsedInputFileData = parsedInputFileData[0] && parsedInputFileData[0].data || null
			}

			if (parsedInputFileData && parsedInputFileData[0]) {
				parsedInputFileData[0].forEach((column, index) => {
					if (matchesTemplate && (template.columns[index] !== column)) {
						matchesTemplate = false
					}
					columns.push(column)
				})
			}
			return {matchesTemplate, columns, templateColumns: template.columns, fileData: parsedInputFileData}
		})
	}

	create() {
		let instance = this
		return function* (req, res, next) {
			try {
				let response = {}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].create(req.body)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	read() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {},
					response = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].read(query)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	readList() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].readList(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	update() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].update(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	checkImportFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield instance.importFileCheck({
					locals: req.locals,
					inputFileName: decodeURIComponent(req.query.fileName),
					delimiter: ';'
				}))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	importFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				let check = yield instance.importFileCheck({
						locals: req.locals,
						inputFileName: req.body.locationDataFile,
						delimiter: req.body.delimiter || ';'
					}),
					dbComponent = req.locals.dbComponents[instance.componentName],
					dataToInsert = [],
					dataToUpdate = []

				if (!(check.fileData instanceof Array) || (check.fileData.length < 2)) {
					throw {customMessage: 'The file is empty or does not contain any data.'}
				}

				if (check.matchesTemplate) {
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.columns.forEach((column, cIndex) => {
								item[column] = row[cIndex]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				} else {
					let columnsToMatch = {}
					check.templateColumns.forEach((column, cIndex) => {
						let fileColumn = req.body[column]
						if (!fileColumn) {
							throw {customMessage: 'The file does not match the template and not all columns have been mapped.'}
						}
						columnsToMatch[column] = check.columns.indexOf(fileColumn)
					})
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.templateColumns.forEach((column, cIndex) => {
								item[column] = row[columnsToMatch[column]]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				}

				req.body.UserId = req.session.passport.user

				yield req.locals.db.sequelize.transaction((t) => {
					return co(function*() {
						req.body.transaction = t

						if (dataToInsert.length) {
							yield dbComponent.bulkCreate({
								dbObjects: dataToInsert,
								options: req.body
							})
						}

						if (dataToUpdate.length) {
							for (let i in dataToUpdate) {
								let item = dataToUpdate[i]
								yield dbComponent.update({dbObject: item, where: {id: item.id}, transaction: t})
							}
						}

						return true
					})
				})

				res.json({success: true})
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	delete() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				res.json(yield req.locals.db.components[instance.componentName].destroy(query))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}
}

module.exports = Base
<|endoftext|>


<commit_before>'use strict'

let fs = require('fs'),
	path = require('path'),
	co = require('co'),
	csv = new (require('../modules/csvPromise'))(),
	xlsx = require('node-xlsx'),
	toolbelt = require('../modules/toolbelt')

class Base {
	constructor({componentName, componentNameSingular, routes, additionalDefaultRoutes, addDefaultRoutes}) {
		this.componentName = componentName
		this.componentNameSingular = componentNameSingular

		this.routes = routes
		if (addDefaultRoutes instanceof Array) {
			let defaultRoutes = {
					create: {method: 'post', path: `/${this.componentName}/create`, func: 'create'},
					read: {method: 'get', path: `/${this.componentName}/read`, func: 'read'},
					readList: {method: 'post', path: `/${this.componentName}/readList`, func: 'readList'},
					update: {method: 'post', path: `/${this.componentName}/update`, func: 'update'},
					checkImportFile: {method: 'get', path: `/locations/checkImportFile`, func: 'checkImportFile'},
					importFile: {method: 'post', path: `/locations/importFile`, func: 'importFile'},
					delete: {method: 'get', path: `/${this.componentName}/delete`, func: 'delete'}
				},
				defaultRoutesToAdd = []
			if (typeof additionalDefaultRoutes === 'object') {
				for (let key in additionalDefaultRoutes) {
					defaultRoutes[key] = additionalDefaultRoutes[key]
				}
			}
			addDefaultRoutes.forEach((route, index) => {
				if (defaultRoutes[route]) {
					defaultRoutesToAdd.push(defaultRoutes[route])
				}
			})
			this.routes = this.routes.concat(defaultRoutesToAdd)
		}
	}

	getRoutes() {
		return this.routes
	}

	importFileCheck({locals, inputFileName, delimiter}) {
		let instance = this
		return co(function*() {
			let fileName = inputFileName,
				extNameRegex = new RegExp(/\.[^/.]+$/),
				extName = extNameRegex.exec(fileName),
				inputFileData = fs.readFileSync(path.join(locals.cfg.globalUploadPath, inputFileName)),
				parsedInputFileData = null,
				template = {
					fileData: fs.readFileSync(path.join(locals.cfg.globalStoragePath, `/importTemplates/${instance.componentName}.csv`)),
					columns: []
				},
				matchesTemplate = true,
				columns = []
			extName = extName && extName[0] || ''
			template.data = yield csv.parse({data: template.fileData, options: {delimiter: ';'}})
			template.data[0].forEach((column, index) => {
				template.columns.push(column)
			})

			if (extName === '.csv') {
				parsedInputFileData = yield csv.parse({data: inputFileData, options: {delimiter: delimiter}})
			}
			if (extName === '.xlsx') {
				parsedInputFileData = xlsx.parse(inputFileData)
				parsedInputFileData = parsedInputFileData[0] && parsedInputFileData[0].data || null
			}

			if (parsedInputFileData && parsedInputFileData[0]) {
				parsedInputFileData[0].forEach((column, index) => {
					if (matchesTemplate && (template.columns[index] !== column)) {
						matchesTemplate = false
					}
					columns.push(column)
				})
			}
			return {matchesTemplate, columns, templateColumns: template.columns, fileData: parsedInputFileData}
		})
	}

	create() {
		let instance = this
		return function* (req, res, next) {
			try {
				let response = {}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].create(req.body)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	read() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {},
					response = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].read(query)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	readList() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].readList(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	update() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].update(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	checkImportFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield instance.importFileCheck({
					locals: req.locals,
					inputFileName: decodeURIComponent(req.query.fileName),
					delimiter: ';'
				}))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	importFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				let check = yield instance.importFileCheck({
						locals: req.locals,
						inputFileName: req.body.locationDataFile,
						delimiter: req.body.delimiter || ';'
					}),
					dbComponent = req.locals.dbComponents[instance.componentName],
					dataToInsert = [],
					dataToUpdate = []

				if (!(check.fileData instanceof Array) || (check.fileData.length < 2)) {
					throw {customMessage: 'The file is empty or does not contain any data.'}
				}

				if (check.matchesTemplate) {
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.columns.forEach((column, cIndex) => {
								item[column] = row[cIndex]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				} else {
					let columnsToMatch = {}
					check.templateColumns.forEach((column, cIndex) => {
						let fileColumn = req.body[column]
						if (!fileColumn) {
							throw {customMessage: 'The file does not match the template and not all columns have been mapped.'}
						}
						columnsToMatch[column] = check.columns.indexOf(fileColumn)
					})
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.templateColumns.forEach((column, cIndex) => {
								item[column] = row[columnsToMatch[column]]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				}

				req.body.UserId = req.session.passport.user

				yield req.locals.db.sequelize.transaction((t) => {
					return co(function*() {
						req.body.transaction = t

						if (dataToInsert.length) {
							yield dbComponent.bulkCreate({
								dbObjects: dataToInsert,
								options: req.body
							})
						}

						if (dataToUpdate.length) {
							for (let i in dataToUpdate) {
								let item = dataToUpdate[i]
								yield dbComponent.update({dbObject: item, where: {id: item.id}, transaction: t})
							}
						}

						return true
					})
				})

				res.json({success: true})
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	delete() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				res.json(yield req.locals.db.components[instance.componentName].destroy(query))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}
}

module.exports = Base
<commit_msg>base client class fix<commit_after>'use strict'

let fs = require('fs'),
	path = require('path'),
	co = require('co'),
	csv = new (require('../modules/csvPromise'))(),
	xlsx = require('node-xlsx'),
	toolbelt = require('../modules/toolbelt')

class Base {
	constructor({componentName, componentNameSingular, routes, additionalDefaultRoutes, addDefaultRoutes}) {
		this.componentName = componentName
		this.componentNameSingular = componentNameSingular

		this.routes = routes
		if (addDefaultRoutes instanceof Array) {
			let defaultRoutes = {
					create: {method: 'post', path: `/${this.componentName}/create`, func: 'create'},
					read: {method: 'get', path: `/${this.componentName}/read`, func: 'read'},
					readList: {method: 'post', path: `/${this.componentName}/readList`, func: 'readList'},
					update: {method: 'post', path: `/${this.componentName}/update`, func: 'update'},
					checkImportFile: {method: 'get', path: `/${this.componentName}/checkImportFile`, func: 'checkImportFile'},
					importFile: {method: 'post', path: `/${this.componentName}/importFile`, func: 'importFile'},
					delete: {method: 'get', path: `/${this.componentName}/delete`, func: 'delete'}
				},
				defaultRoutesToAdd = []
			if (typeof additionalDefaultRoutes === 'object') {
				for (let key in additionalDefaultRoutes) {
					defaultRoutes[key] = additionalDefaultRoutes[key]
				}
			}
			addDefaultRoutes.forEach((route, index) => {
				if (defaultRoutes[route]) {
					defaultRoutesToAdd.push(defaultRoutes[route])
				}
			})
			this.routes = this.routes.concat(defaultRoutesToAdd)
		}
	}

	getRoutes() {
		return this.routes
	}

	importFileCheck({locals, inputFileName, delimiter}) {
		let instance = this
		return co(function*() {
			let fileName = inputFileName,
				extNameRegex = new RegExp(/\.[^/.]+$/),
				extName = extNameRegex.exec(fileName),
				inputFileData = fs.readFileSync(path.join(locals.cfg.globalUploadPath, inputFileName)),
				parsedInputFileData = null,
				template = {
					fileData: fs.readFileSync(path.join(locals.cfg.globalStoragePath, `/importTemplates/${instance.componentName}.csv`)),
					columns: []
				},
				matchesTemplate = true,
				columns = []
			extName = extName && extName[0] || ''
			template.data = yield csv.parse({data: template.fileData, options: {delimiter: ';'}})
			template.data[0].forEach((column, index) => {
				template.columns.push(column)
			})

			if (extName === '.csv') {
				parsedInputFileData = yield csv.parse({data: inputFileData, options: {delimiter: delimiter}})
			}
			if (extName === '.xlsx') {
				parsedInputFileData = xlsx.parse(inputFileData)
				parsedInputFileData = parsedInputFileData[0] && parsedInputFileData[0].data || null
			}

			if (parsedInputFileData && parsedInputFileData[0]) {
				parsedInputFileData[0].forEach((column, index) => {
					if (matchesTemplate && (template.columns[index] !== column)) {
						matchesTemplate = false
					}
					columns.push(column)
				})
			}
			return {matchesTemplate, columns, templateColumns: template.columns, fileData: parsedInputFileData}
		})
	}

	create() {
		let instance = this
		return function* (req, res, next) {
			try {
				let response = {}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].create(req.body)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	read() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {},
					response = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				response[instance.componentNameSingular] = yield req.locals.db.components[instance.componentName].read(query)
				res.json(response)
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	readList() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].readList(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	update() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield req.locals.db.components[instance.componentName].update(req.body))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	checkImportFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				res.json(yield instance.importFileCheck({
					locals: req.locals,
					inputFileName: decodeURIComponent(req.query.fileName),
					delimiter: ';'
				}))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	importFile() {
		let instance = this
		return function* (req, res, next) {
			try {
				let check = yield instance.importFileCheck({
						locals: req.locals,
						inputFileName: req.body.locationDataFile,
						delimiter: req.body.delimiter || ';'
					}),
					dbComponent = req.locals.dbComponents[instance.componentName],
					dataToInsert = [],
					dataToUpdate = []

				if (!(check.fileData instanceof Array) || (check.fileData.length < 2)) {
					throw {customMessage: 'The file is empty or does not contain any data.'}
				}

				if (check.matchesTemplate) {
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.columns.forEach((column, cIndex) => {
								item[column] = row[cIndex]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				} else {
					let columnsToMatch = {}
					check.templateColumns.forEach((column, cIndex) => {
						let fileColumn = req.body[column]
						if (!fileColumn) {
							throw {customMessage: 'The file does not match the template and not all columns have been mapped.'}
						}
						columnsToMatch[column] = check.columns.indexOf(fileColumn)
					})
					check.fileData.forEach((row, index) => {
						if (index > 0) {
							let item = {}
							check.templateColumns.forEach((column, cIndex) => {
								item[column] = row[columnsToMatch[column]]
							})
							if (item.id) {
								dataToUpdate.push(toolbelt.emptyToNull(item, {}))
							} else {
								dataToInsert.push(toolbelt.emptyToNull(item, {}))
							}
						}
					})
				}

				req.body.UserId = req.session.passport.user

				yield req.locals.db.sequelize.transaction((t) => {
					return co(function*() {
						req.body.transaction = t

						if (dataToInsert.length) {
							yield dbComponent.bulkCreate({
								dbObjects: dataToInsert,
								options: req.body
							})
						}

						if (dataToUpdate.length) {
							for (let i in dataToUpdate) {
								let item = dataToUpdate[i]
								yield dbComponent.update({dbObject: item, where: {id: item.id}, transaction: t})
							}
						}

						return true
					})
				})

				res.json({success: true})
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}

	delete() {
		let instance = this
		return function* (req, res, next) {
			try {
				let query = {}
				for (let key in req.query) {
					if (typeof req.query[key] !== 'object') {
						query[decodeURIComponent(key)] = decodeURIComponent(req.query[key])
					}
				}
				res.json(yield req.locals.db.components[instance.componentName].destroy(query))
			} catch (e) {
				req.locals.error = e
				next()
			}
		}
	}
}

module.exports = Base
<|endoftext|>


<commit_before>describe('Factory#define', function() {
  beforeEach(function() {
    dynamic_function = function() {
      return "dynamic";
    }

    callback_function = function(callback){
      return callback(null, 'called');
    }

    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: dynamic_function,
      called: callback_function
    })
  })

  it('stores the definition on the factory name', function() {
    expect(Factory.patterns.test).toEqual({
      class: TestModel,
      attributes: {
        name: 'Test Model',
        real: false,
        dynamic: dynamic_function,
        called: callback_function
      }
    })
  })
})

describe('Factory#build', function() {
  beforeEach(function() {
    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: function() {
        return "dynamic";
      }
    })
  })

  it('uses the stored definition to seed attribute values', function() {
    var object = Factory.build('test')
    expect(object.name).toEqual('Test Model')
    expect(object.real).toEqual(false)
    expect(object.dynamic).toEqual("dynamic")
  })

  it('takes an optional parameter to override stores attributes', function() {
    var object = Factory.build('test', { real: true })
    expect(object.name).toEqual('Test Model')
    expect(object.real).toEqual(true)
  })
})

describe('Factory#build_with_callback', function() {
  beforeEach(function() {
    Factory.define('test_callback', TestModel, {
      called: function(cbk) {
        return cbk(null, 'called');
      }
    })
  })

  it('uses the stored definition to seed attribute values', function() {
    var object = null;
    Factory.build('test_callback', function(err, obj){
      object = obj;
    });
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function(){
      expect(object.called).toEqual("called");
    });
  })

  it("throws an error if no callback is given", function(){
    expect(function(){
      Factory.build('test_callback');
    }).toThrow('you need to pass a callback to the build function - setter for attribute "called" is asynchronous');
  });
})

describe('Factory#create', function() {
  beforeEach(function() {
    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: function() {
        return "dynamic";
      },
      called: function(cbk) {
        return cbk(null, 'called');
      }
    })
  })

  it('should override attributes like Factory#build', function() {
    var object;
    Factory.create('test', { name: function(){return 'Test Object';}, dynamic: "another value", called: function(cbk){return cbk(null, 'new value');} }, function(e, o) {
      object = o;
    })
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function() {
      expect(object.name).toEqual('Test Object');
      expect(object.dynamic).toEqual('another value');
      expect(object.called).toEqual('new value');
    })
  })

  it('should returned saved object', function() {
    var object;
    Factory.create('test', function(e, o) {
      object = o;
    })
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function() {
      expect(object.isNew).toBe(false);
    })
  })
})
<commit_msg>Added test case for Factory#define inheritance, fails<commit_after>describe('Factory#define', function() {
  beforeEach(function() {
    dynamic_function = function() {
      return "dynamic";
    }

    callback_function = function(callback){
      return callback(null, 'called');
    }

    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: dynamic_function,
      called: callback_function
    })
  })

  it('stores the definition on the factory name', function() {
    expect(Factory.patterns.test).toEqual({
      class: TestModel,
      attributes: {
        name: 'Test Model',
        real: false,
        dynamic: dynamic_function,
        called: callback_function
      }
    })
  })

  it('inherits from already-defined models by name', function() {
    Factory.define('testChild', 'test', {
      name: 'Test Model Child'
    })

    expect(Factory.patterns.testChild).toEqual({
      class: TestModel,
      attributes: {
        name: 'Test Model Child',
        real: false,
        dynamic: dynamic_function,
        called: callback_function
      }
    })
  })
})

describe('Factory#build', function() {
  beforeEach(function() {
    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: function() {
        return "dynamic";
      }
    })
  })

  it('uses the stored definition to seed attribute values', function() {
    var object = Factory.build('test')
    expect(object.name).toEqual('Test Model')
    expect(object.real).toEqual(false)
    expect(object.dynamic).toEqual("dynamic")
  })

  it('takes an optional parameter to override stores attributes', function() {
    var object = Factory.build('test', { real: true })
    expect(object.name).toEqual('Test Model')
    expect(object.real).toEqual(true)
  })
})

describe('Factory#build_with_callback', function() {
  beforeEach(function() {
    Factory.define('test_callback', TestModel, {
      called: function(cbk) {
        return cbk(null, 'called');
      }
    })
  })

  it('uses the stored definition to seed attribute values', function() {
    var object = null;
    Factory.build('test_callback', function(err, obj){
      object = obj;
    });
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function(){
      expect(object.called).toEqual("called");
    });
  })

  it("throws an error if no callback is given", function(){
    expect(function(){
      Factory.build('test_callback');
    }).toThrow('you need to pass a callback to the build function - setter for attribute "called" is asynchronous');
  });
})

describe('Factory#create', function() {
  beforeEach(function() {
    Factory.define('test', TestModel, {
      name: 'Test Model',
      real: false,
      dynamic: function() {
        return "dynamic";
      },
      called: function(cbk) {
        return cbk(null, 'called');
      }
    })
  })

  it('should override attributes like Factory#build', function() {
    var object;
    Factory.create('test', { name: function(){return 'Test Object';}, dynamic: "another value", called: function(cbk){return cbk(null, 'new value');} }, function(e, o) {
      object = o;
    })
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function() {
      expect(object.name).toEqual('Test Object');
      expect(object.dynamic).toEqual('another value');
      expect(object.called).toEqual('new value');
    })
  })

  it('should returned saved object', function() {
    var object;
    Factory.create('test', function(e, o) {
      object = o;
    })
    waitsFor(function() { return object != null}, 'object creation failed', 1000);
    runs(function() {
      expect(object.isNew).toBe(false);
    })
  })
})
<|endoftext|>