import { locale as appLocale } from '../../intl'

function localeCompare (a, b, locale = appLocale) {
  return a.localeCompare(b, locale, { numeric: true })
}

/*
 * Sort an Immutable List of Maps (set of disks) for display on the VmDisks list.
 * Bootable drives sort first, then sorted number aware alphabetically.
 */
export function sortDisksForDisplay (disks, locale = appLocale) {
  return disks.sort((a, b) => {
    const aBoot = a.get('bootable')
    const bBoot = b.get('bootable')

    return aBoot && !bBoot ? -1
      : !aBoot && bBoot ? 1
        : localeCompare(a.get('name'), b.get('name'), locale)
  })
}

import { locale as appLocale } from '../../intl'

function localeCompare (a, b, locale = appLocale) {
  return a.localeCompare(b, locale, { numeric: true })
}

/*
 * Sort an Immutable List of Maps (set of disks) for display on the VmDisks list.
 * Bootable drives sort first, then sorted number aware alphabetically.
 */
export function sortDisksForDisplay (disks, locale = appLocale) {
  return disks.sort((a, b) => {
    const aBoot = a.get('bootable')
    const bBoot = b.get('bootable')

    return (aBoot && !bBoot) ? -1 : (
      (!aBoot && bBoot) ? 1 : localeCompare(a.get('name'), b.get('name'), locale)
    )
  })
}

Improve readability of ternary operator


/*
  Copyright 2015 Ops For Developers

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
// ==UserScript==
// @name        Jenkins Show Advanced
// @namespace   http://opsfordevelopers.com/jenkins/userscripts
// @description Automatically shows the configuration hidden beneath the "Advanced..." buttons in Jenkins jobs
// @match       https://*/jenkins/*
// @match       http://*/jenkins/*
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
// @run-at      document-end
// @version     1.0
// @grant       none
// ==/UserScript==

function showAdvancedTables () {
  // hide the "Advanced..." buttons and show the advanced tables
  jQuery("div.advancedLink").hide();
  jQuery("table.advancedBody").show();

  // give to the advanced tables the full width and remove the adjacent td tags
  jQuery("table.advancedBody").parent("td").attr("colspan", 4);
  jQuery("table.advancedBody").parentsUntil("tbody").children("td:empty").remove();
}

jQuery(document).ready(function(){
  jQuery.noConflict();
  showAdvancedTables();
});

/*
  Copyright 2015 Ops For Developers

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
// ==UserScript==
// @name        Jenkins Show Advanced
// @namespace   http://opsfordevelopers.com/jenkins/userscripts
// @description Automatically shows the configuration hidden beneath the "Advanced..." buttons in Jenkins jobs
// @match       */job/*/configure
// @require     https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
// @run-at      document-end
// @version     1.0
// @grant       none
// ==/UserScript==

function showAdvancedTables () {
  // hide the "Advanced..." buttons and show the advanced tables
  jQuery("div.advancedLink").hide();
  jQuery("table.advancedBody").show();

  // give to the advanced tables the full width and remove the adjacent td tags
  jQuery("table.advancedBody").parent("td").attr("colspan", 4);
  jQuery("table.advancedBody").parentsUntil("tbody").children("td:empty").remove();
}

jQuery(document).ready(function(){
  jQuery.noConflict();
  showAdvancedTables();
});

Change the @match metadata to the */job/*/configure pattern to be as generic as possible


/*! jsbeautifierSettingsTweaks.js v0.1.1 by ryanpcmcquen */
(function () {

  'use strict';

  window.addEventListener('load', function () {
    // set any vars you want to change here
    var jslintCheckbox = document.getElementById('jslint-happy');
    var tabSize = document.getElementById('tabsize');

    // set your values for those vars here
    tabSize.value = 2;
    jslintCheckbox.checked = true;
  });

}());

/*! jsbeautifierSettingsTweaks.js v0.2.0 by ryanpcmcquen */
window.addEventListener('load', function () {
  'use strict';
  // Set any vars you want to change here:
  var jslintCheckbox = document.getElementById('jslint-happy');
  var tabSize = document.getElementById('tabsize');
  var wrapLength = document.getElementById('wrap-line-length');

  // Set your values for those vars here:
  tabSize.value = 2;
  jslintCheckbox.checked = true;
  wrapLength.value = 80;
});

Add 80 character wrap length.


/**
 * Truncate a string to the given length.
 *
 * @param string The string to truncate.
 * @param length The length to truncate by.
 *
 * @returns {string}
 */
export const truncateString = (string, length) => {
    return string.slice(0, length) + '...';
};

export const formatRant = (rant) => {

    return {
        color: '#f99a66',
        author_name: rant.user_username,
        image_url: rant.attached_image.url,
        title: truncateString(rant.text, 100),
        title_link: `https://devrant.io/rants/${rant.id}?ref=devrant-bot`,
        author_link: `https://devrant.io/users/${rant.user_username}?ref=devrant-bot`,
        fields: [
            {
                short: true,
                title: 'Score',
                value: rant.score
            },
            {
                short: true,
                title: 'Comments',
                value: rant.num_comments
            }
        ]
    };
};

/**
 * Truncate a string to the given length.
 *
 * @param string The string to truncate.
 * @param length The length to truncate by.
 *
 * @returns {string}
 */
export const truncateString = (string, length) => {
    return string.slice(0, length) + '...';
};

export const formatRant = (rant) => {

    return {
        color: '#f99a66',
        author_name: rant.user_username,
        image_url: rant.attached_image.url,
        title: truncateString(rant.text, 100),
        title_link: `https://www.devrant.io/rants/${rant.id}?ref=devrant-bot`,
        author_link: `https://www.devrant.io/users/${rant.user_username}?ref=devrant-bot`,
        fields: [
            {
                short: true,
                title: 'Score',
                value: rant.score
            },
            {
                short: true,
                title: 'Comments',
                value: rant.num_comments
            }
        ]
    };
};

Change link URLs to avoid redirect


/* global DEBUG */
/* eslint-disable no-console */
import { argv } from "nwjs/argv";
import Logger from "utils/Logger";

const { logDebug, logError } = new Logger( "Application" );

const onError = async ( type, err, debug ) => {
	if ( DEBUG ) {
		console.error( type, err, debug );
	}
	try {
		await logError( type ? `${type}: ${err}` : err, debug );
	} catch ( e ) {}
};

process.on( "uncaughtException", e => onError( "uncaughtException", e ) );
window.addEventListener( "unhandledrejection", e => onError( e.type, e.reason, e.promise ) );
window.addEventListener( "error", e => onError( "error", e ) );

// don't log parameters when running a dev build via grunt
if ( DEBUG ) {
	console.debug( argv );
} else {
	logDebug( "Parameters", argv );
}

/* global DEBUG */
/* eslint-disable no-console */
import Ember from "ember";
import { argv } from "nwjs/argv";
import Logger from "utils/Logger";

const { logDebug, logError } = new Logger( "Application" );

const onError = async ( type, err, debug ) => {
	if ( DEBUG ) {
		console.error( type, err, debug );
	}
	try {
		await logError( type ? `${type}: ${err}` : err, debug );
	} catch ( e ) {}
};

process.on( "uncaughtException", e => onError( "uncaughtException", e ) );
window.addEventListener( "unhandledrejection", e => onError( e.type, e.reason, e.promise ) );
window.addEventListener( "error", e => onError( "error", e.error ) );
Ember.onerror = e => e && e.name !== "Adapter Error" ? onError( "Ember error", e ) : null;

// don't log parameters when running a dev build via grunt
if ( DEBUG ) {
	console.debug( argv );
} else {
	logDebug( "Parameters", argv );
}

Fix ErrorEvent logging + add Ember error listener


//autocomplete for organism search
 $("#search_organism").autocomplete({
    position: {
       my: "right top", at: "right bottom"
    },
    source: function (request, response) {
        var $search = request.term;
        $.ajax({
            url: WebRoot.concat("/ajax/listing/Organisms"),
            data: {term:  request.term, limit: 500, search: $search},
            dataType: "json",
            success: function (data) {
                response(data);
            }
        });
    },
    minLength: 3
});

$("#search_organism").data("ui-autocomplete")._renderItem = function (ul, item) {
    var li = $("
")
            .append("" + item.scientific_name + "" + item.rank + "")
            .appendTo(ul);
    return li;
};

$("#btn_search_organism").click(function(){
    $searchTerm = $("#search_organism").val();
    $.ajax({
        url: WebRoot.concat("/ajax/listing/Organisms"),
        data: {limit: 500, search: $searchTerm},
        dataType: "json",
        success: function (data) {
            console.log(data);e
        }
    });
});

Add onclick function for button. The function is called after submitting the search. It gets the value of the search field and get the data objects via ajax


'use strict'
describe('StreamPromise', function() {
  const StreamPromise = require('../')
  const FS = require('fs')
  it('works', function() {
    waitsForPromise(function() {
      return StreamPromise.create(FS.createReadStream(`${__dirname}/fixtures/something.txt`))
        .then(function(contents) {
          expect(contents).toBe(`Something\n`)
        })
    })
  })
  it('limits by bytes', function() {
    waitsForPromise(function() {
      let Threw = false
      return StreamPromise.create(FS.createReadStream(`${__dirname}/fixtures/something.txt`), 1)
        .catch(function() {
          Threw = true
        })
        .then(function() {
          expect(Threw).toBe(true)
        })
    })
  })
})

'use strict'
describe('StreamPromise', function() {
  const StreamPromise = require('../')
  const FS = require('fs')
  it('works', function() {
    waitsForPromise(function() {
      return StreamPromise.create(FS.createReadStream(`${__dirname}/fixtures/something.txt`))
        .then(function(contents) {
          expect(contents).toBe(`Something\n`)
        })
    })
  })
  it('limits by bytes', function() {
    waitsForPromise(function() {
      let Threw = false
      return StreamPromise.create(FS.createReadStream(`${__dirname}/fixtures/something.txt`), 1)
        .catch(function() {
          Threw = true
        })
        .then(function() {
          expect(Threw).toBe(true)
        })
    })
  })
  it('rejects promise on stream error', function() {
    waitsForPromise(function() {
      let Threw = false
      return StreamPromise.create(FS.createReadStream(`/etc/some-non-existing-file`))
        .catch(function(e) {
          Threw = true
        })
        .then(function() {
          expect(Threw).toBe(true)
        })
    })
  })
})

Add specs for rejecting promise on stream error


// Dependencies
import 'engine/scene/sprites/enable';

// Loader middleware
import bitmap_font_parser from './bitmap_font_parser';
import { loader_use_procs } from 'engine/registry';
loader_use_procs.push(bitmap_font_parser);

// Renderer

// Class
export { default as BitmapText } from './BitmapText';
export { default as Text } from './Text';

// Dependencies
import 'engine/scene/sprites/enable';

// Loader middleware
import bitmap_font_parser from './bitmap_font_parser';
import { loader_use_procs } from 'engine/registry';
loader_use_procs.push(bitmap_font_parser);

// Register to global node class map
import { node_class_map } from 'engine/registry';

import Text from './Text';
import BitmapText from './BitmapText';

node_class_map['Text'] = Text;
node_class_map['BitmapText'] = BitmapText;

Add Text and BitmapText to node class map


/* globals requirejs, require */

QUnit.config.urlConfig.push({ id: 'nojshint', label: 'Disable JSHint'});

// TODO: load based on params
for (var moduleName in requirejs.entries) {
  var shouldLoad;

  if (moduleName.match(/-test$/)) { shouldLoad = true; }
  if (!QUnit.urlParams.nojshint && moduleName.match(/\.jshint$/)) { shouldLoad = true; }

  if (shouldLoad) { require(moduleName); }
}

if (QUnit.notifications) {
  QUnit.notifications({
    icons: {
      passed: '/assets/passed.png',
      failed: '/assets/failed.png'
    }
  });
}

/* globals requirejs, require */

QUnit.config.urlConfig.push({ id: 'nojshint', label: 'Disable JSHint'});

// TODO: load based on params
for (var moduleName in requirejs.entries) {
  var shouldLoad;

  if (moduleName.match(/[-_]test$/)) { shouldLoad = true; }
  if (!QUnit.urlParams.nojshint && moduleName.match(/\.jshint$/)) { shouldLoad = true; }

  if (shouldLoad) { require(moduleName); }
}

if (QUnit.notifications) {
  QUnit.notifications({
    icons: {
      passed: '/assets/passed.png',
      failed: '/assets/failed.png'
    }
  });
}

Allow tests to be underscored.


function getProcessCount(total) {
	if (total < 2) {
		return 1;
	}
	if (total > 80) {
	    return parseInt(total / 30);
	}
	return 2;
}

function getThreadCount(total) {
	if (total < 2) {
		return 1;
	}
        if (total > 80) {
	    return parseInt(total / (parseInt(total / 30)));
        }
	return parseInt(total / 2 + 0.5);
}

function getProcessCount(total) {
	if (total < 2) {
		return 1;
	}

	var processCount = 2;

	if (total > 80) {
		processCount = parseInt(total / 40) + 1;
	}

	if (processCount > 20) {
		processCount = 20;
	}
	return processCount;
}

function getThreadCount(total) {
	var processCount = getProcessCount(total);
	return parseInt(total / processCount);
}

Modify process and thread calc to support vuser more than 600.


$(function () {
    'use strict';

    var $coordinator_select = $('#coordinator_id');
    var $group_select = $('#group_id');

    $coordinator_select.select2();
    $group_select.select2();

    function set_group_users() {
        var group_id = $group_select.val();

        $.get('/api/group/users/' + group_id, {}, function (data) {
            $coordinator_select.empty();

            _(data.users).forEach(function (user) {
                var $option = $('<option></option>');
                $option.val(user.val);
                $option.text(user.label);

                $coordinator_select.append($option);
            });
        });
    }

    $group_select.change(function () {
        set_group_users();
    });
});

$(function () {
    'use strict';

    var $coordinator_select = $('#coordinator_id');
    var $group_select = $('#group_id');

    function set_group_users() {
        var group_id = $group_select.val();

        $.get('/api/group/users/' + group_id, {}, function (data) {
            $coordinator_select.empty();

            _(data.users).forEach(function (user) {
                var $option = $('<option></option>');
                $option.val(user.val);
                $option.text(user.label);

                $coordinator_select.append($option);
            });
        });
    }

    $group_select.change(function () {
        set_group_users();
    });
});

Remove select2 again, because that sucked


/* eslint-disable no-unused-expressions */

import { expect } from 'chai';

export default function orm (people, _ids, errors) {
  describe('Feathers ORM Specific Tests', () => {
    it('wraps an ORM error in a feathers error', () => {
      return people.create({}).catch(error =>
        expect(error instanceof errors.FeathersError).to.be.ok
      );
    });
  });
}

/* eslint-disable no-unused-expressions */

import { expect } from 'chai';

export default function orm (people, errors, idProp = 'id') {
  describe('Feathers ORM Common Tests', () => {
    it('wraps an ORM error in a feathers error', () => {
      return people.create({}).catch(error => {
        expect(error instanceof errors.FeathersError).to.be.ok
      });
    });

    describe('Raw/Lean Queries', () => {
      const _ids = {};
      const _data = {};

      beforeEach(() =>
        people.create({
          name: 'Doug',
          age: 32
        }).then(data => {
          _data.Doug = data;
          _ids.Doug = data[idProp];
        })
      );

      afterEach(() =>
        people.remove(_ids.Doug).catch(() => {})
      );

      function noPOJO() {
        // The prototype objects are huge and cause node to hang
        // when the reporter tries to log the errors to the console.
        throw new Error('The expected result was not a POJO.');
      }

      it('returns POJOs for find()', () => {
        return people.find({}).then(results =>
          expect(Object.getPrototypeOf(results[0])).to.equal(Object.prototype)
        ).catch(noPOJO);
      });

      it('returns a POJO for get()', () => {
        return people.get(_ids.Doug).then(result =>
          expect(Object.getPrototypeOf(result)).to.equal(Object.prototype)
        ).catch(noPOJO);
      });

      it('returns a POJO for create()', () => {
        return people.create({name: 'Sarah', age: 30}).then(result =>
          expect(Object.getPrototypeOf(result)).to.equal(Object.prototype)
        ).catch(noPOJO);
      });

      it('returns POJOs for bulk create()', () => {
        return people.create([{name: 'Sarah', age: 30}]).then(result =>
          expect(Object.getPrototypeOf(result[0])).to.equal(Object.prototype)
        ).catch(noPOJO);
      });

      it('returns a POJO for patch()', () => {
        return people.patch(_ids.Doug, {name: 'Sarah'}).then(result =>
          expect(Object.getPrototypeOf(result)).to.equal(Object.prototype)
        ).catch(noPOJO);
      });

      it('returns a POJO for update()', () => {
        return people.update(_ids.Doug, Object.assign(_data.Doug, {name: 'Sarah'})).then(result =>
          expect(Object.getPrototypeOf(result)).to.equal(Object.prototype)
        ).catch(noPOJO);
      });
    });
  });
}

Update ORM tests to ensure plain objects are returned


import { expect } from 'chai';

describe('smoke test', () => {
  it('run a test', () => {
    expect(true).to.equal(true);
  });
});

import { expect } from 'chai';

describe('smoke test', () => {
  it('run a test', () => {
    expect(true).to.equal(false);
  });
});

Make the fail the test to demo CircleCI


'use strict'

const packageJson = require('../package')
const channelHeader = `Node.js-${process.version}-SDK-v${packageJson.version}`

module.exports = {
  reqWithBody: {
    reqheaders: {
      'X-App-Id': 'node-sdk-test-id',
      'X-App-Token': 'node-sdk-test-secret',
      'X-Voucherify-Channel': channelHeader,
      'accept': 'application/json',
      'content-type': 'application/json'
    }
  },
  reqWithoutBody: {
    reqheaders: {
      'X-App-Id': 'node-sdk-test-id',
      'X-App-Token': 'node-sdk-test-secret',
      'X-Voucherify-Channel': channelHeader,
      'accept': 'application/json'
    }
  }
}

'use strict'

// FIXME leaving var to satisfy tests for node v0.10 and v0.12
var packageJson = require('../package')
var channelHeader = `Node.js-${process.version}-SDK-v${packageJson.version}`

module.exports = {
  reqWithBody: {
    reqheaders: {
      'X-App-Id': 'node-sdk-test-id',
      'X-App-Token': 'node-sdk-test-secret',
      'X-Voucherify-Channel': channelHeader,
      'accept': 'application/json',
      'content-type': 'application/json'
    }
  },
  reqWithoutBody: {
    reqheaders: {
      'X-App-Id': 'node-sdk-test-id',
      'X-App-Token': 'node-sdk-test-secret',
      'X-Voucherify-Channel': channelHeader,
      'accept': 'application/json'
    }
  }
}

Use var to satisfy tests for prehistoric nodejs versions


#!/usr/bin/env node
var Janeway = require('../lib/init.js'),
    libpath = require('path'),
    main_file;

// Get the wanted file to require
main_file = libpath.resolve(process.cwd(), process.argv[2]);

// Remove janeway from the arguments array
process.argv.splice(1, 1);

// Start initializing janeway
Janeway.start(function started(err) {

	if (err) {
		console.error('Could not start Janeway: ' + err);
	}

	try {
		Janeway.print('info', ['Requiring main file', JSON.stringify(process.argv[1])]);
		require(main_file);
	} catch (err) {
		console.log('Error requiring main file: ' + err);
	}
});

#!/usr/bin/env node
var Janeway = require('../lib/init.js'),
    libpath = require('path'),
    main_file;

// Get the wanted file to require
if (process.argv[2]) {
  main_file = libpath.resolve(process.cwd(), process.argv[2]);
}

// Remove janeway from the arguments array
process.argv.splice(1, 1);

// Start initializing janeway
Janeway.start(function started(err) {

	if (err) {
		console.error('Could not start Janeway: ' + err);
	}

	try {
    if (main_file) {
			Janeway.print('info', ['Requiring main file', JSON.stringify(process.argv[1])]);
      require(main_file);
    }
	} catch (err) {
		console.log('Error requiring main file: ' + err);
	}
});

Allow lauching without specifying main_file


#!/usr/bin/env node

var LineReader = require('line-by-line'),
    minimist   = require('minimist'),
    exec       = require('exec'),
    path       = require('path'),
    fs         = require('fs');

var filenames = minimist(process.argv.slice(2))._;

filenames.forEach(function (filename) {
  if (!fs.existsSync(filename)) {
    console.log(filename + ' does not exist or cannot be read, skipping.');
    return;
  }

  var reader = new LineReader(filename),
      lines = [];

  reader.on('error', function (err) {
    throw err;
  });

  reader.on('line', function (line) {
    var outputLine = line;

    // Not EXIF data
    if (line.indexOf('#') !== 0) {
      var filename = path.basename(line);

      // @todo Properly escape spaces
      exec('cp "' + line + '" "./' + filename + '"', function (err, out, code) {
        if (err) throw err;
      });

      // Update line with new path [same directory]
      outputLine = filename;
    }

    lines.push(outputLine);
  });

  reader.on('end', function () {
    fs.writeFileSync(filename, lines.join('\r'));
    console.log('Exported ' + filename);
  });
});

#!/usr/bin/env node

var LineReader = require('line-by-line'),
    minimist   = require('minimist'),
    exec       = require('exec'),
    path       = require('path'),
    fs         = require('fs'),
    // Get all the arguments that don't have an option associated with them
    filenames  = minimist(process.argv.slice(2))._;

filenames.forEach(function (filename) {
  if (!fs.existsSync(filename)) {
    console.log(filename + ' does not exist or cannot be read, skipping.');
    return;
  }

  var reader = new LineReader(filename),
      lines = [];

  reader.on('error', function (err) {
    throw err;
  });

  reader.on('line', function (line) {
    var outputLine = line;

    // Not EXIF data
    // @todo Is this *really* going to do?
    if (line.indexOf('#') !== 0) {
      var musicFilename = path.basename(line);

      // @todo Properly escape spaces
      exec('cp "' + line + '" "./' + musicFilename + '"', function (err, out, code) {
        if (err) throw err;
      });

      // Update line with new path [same directory]
      outputLine = musicFilename;
    }

    lines.push(outputLine);
  });

  reader.on('end', function () {
    // Write a file to the local directory — this may not be the same directory as the original m3u, but it will be
    // where the music files have been copied to, so they need to be in the same place for the new m3u to work
    fs.writeFileSync(path.basename(filename), lines.join('\r'));
    console.log('Exported ' + filename);
  });
});

Write output m3u to local directory Regardless of whether source m3u is in local dir or not


'use strict';

//var P = require('bluebird');
var Resource = require('../Resource');

function Company(primus)
{
        Resource.call(this, primus, 'Company');

        this._cache = { // contains Promises
                all: null
        };
}

require('inherits')(Company, Resource);
module.exports = Company;

Company.prototype.all = function()
{
        this._cache.all = this._cache.all || this.rpc('all');
        return this._cache.all;
};

Company.prototype.updateCompany = function(id, values)
{
        // todo update cache

        return this.rpc('updateCompany', id, values);
};

'use strict';

//var P = require('bluebird');
var Resource = require('../Resource');

function Company(primus)
{
        Resource.call(this, primus, 'Company');

        this._cache = { // contains Promises
                all: null
        };
}

require('inherits')(Company, Resource);
module.exports = Company;

Company.prototype.all = function()
{
        this._cache.all = this._cache.all || this.rpc('all');
        return this._cache.all;
};

Company.prototype.updateCompany = function(id, values)
{
        // todo update cache

        var p = this.rpc('updateCompany', id, values);

        // The caller of updateCompany does not have to wait for this stuff:
        p.then(function(rpcReturn)
        {
                if (!this._cache.all ||
                    !this._cache.all.isFulfilled())
                {
                        return;
                }

                var keys = Object.keys(values);

                this._cache.all.value().forEach(function(item)
                {
                        if (item._id !== id)
                        {
                                return;
                        }

                        keys.forEach(function(key)
                        {
                                item[key] = values[key];
                        });
                });

        });

        return p;
};

Update cache after an edit


var gulp = require('gulp');

gulp.task('test', function () {
  require('./');
  var mocha = require('gulp-mocha');
  return gulp.src('test/**/*.es6', {
    read: false
  })
    .pipe(mocha({
      bail: true
    }));
});

gulp.task('watch', ['default'], function () {
  gulp.watch([
    'index.js',
    'lib/**/*.es6',
    'test/**/*.es6'
  ], ['default']);
});

gulp.task('default', ['test']);

var gulp = require('gulp');

gulp.task('test', function () {
  require('babel/register')({
    // All the subsequent files required by node with the extension of `.es6`
    // will be transformed to ES5
    extensions: ['.es6']
  });
  var mocha = require('gulp-mocha');
  return gulp.src('test/**/*.es6', {
    read: false
  })
    .pipe(mocha({
      bail: true
    }));
});

gulp.task('watch', ['default'], function () {
  gulp.watch([
    'index.js',
    'lib/**/*.es6',
    'test/**/*.es6'
  ], ['default']);
});

gulp.task('default', ['test']);

Enable Babel properly while testing


import path from 'path';
import loadPresets from './presets';
import serverRequire from './serverRequire';

function customPreset({ configDir }) {
  return serverRequire(path.resolve(configDir, 'presets')) || [];
}

function getWebpackConfig(options, presets) {
  const babelOptions = presets.extendBabel({}, options);

  const entries = {
    iframe: presets.extendPreview([], options),
    manager: presets.extendManager([], options),
  };

  return presets.extendWebpack({}, { ...options, babelOptions, entries });
}

export default options => {
  const { corePresets = [], frameworkPresets = [], ...restOptions } = options;

  const presetsConfig = [
    ...corePresets,
    require.resolve('./core-preset-babel-cache.js'),
    ...frameworkPresets,
    ...customPreset(options),
    require.resolve('./core-preset-webpack-custom.js'),
  ];

  const presets = loadPresets(presetsConfig);

  return getWebpackConfig(restOptions, presets);
};

import path from 'path';
import { logger } from '@storybook/node-logger';
import loadPresets from './presets';
import serverRequire from './serverRequire';

function customPreset({ configDir }) {
  const presets = serverRequire(path.resolve(configDir, 'presets'));

  if (presets) {
    logger.warn(
      '"Custom presets" is an experimental and undocumented feature that will be changed or deprecated soon. Use it on your own risk.'
    );

    return presets;
  }

  return [];
}

function getWebpackConfig(options, presets) {
  const babelOptions = presets.extendBabel({}, options);

  const entries = {
    iframe: presets.extendPreview([], options),
    manager: presets.extendManager([], options),
  };

  return presets.extendWebpack({}, { ...options, babelOptions, entries });
}

export default options => {
  const { corePresets = [], frameworkPresets = [], ...restOptions } = options;

  const presetsConfig = [
    ...corePresets,
    require.resolve('./core-preset-babel-cache.js'),
    ...frameworkPresets,
    ...customPreset(options),
    require.resolve('./core-preset-webpack-custom.js'),
  ];

  const presets = loadPresets(presetsConfig);

  return getWebpackConfig(restOptions, presets);
};

Add warning about custom presets


import prerender from './prerender'

// This is a wrapper to handle a single isomorphic render inside a child process

function startRender(context) {
  prerender(context).then((result) => {
    process.send(result, null, {}, () => {
      process.exit(0)
    })
  }).catch(() => {
    process.exit(1)
  })
}

process.on('message', startRender)

import prerender from './prerender'
import { updateStrings as updateTimeAgoStrings } from './../lib/time_ago_in_words'

updateTimeAgoStrings({ about: '' })

// This is a wrapper to handle a single isomorphic render inside a child process

function startRender(context) {
  prerender(context).then((result) => {
    process.send(result, null, {}, () => {
      process.exit(0)
    })
  }).catch(() => {
    process.exit(1)
  })
}

process.on('message', startRender)

Add time ago in words to the server render


/*
 Copyright (c) 2014, Ryuichi Okumura. All rights reserved.
 Code licensed under the BSD License:
 https://github.com/okuryu/package-json-flatten/blob/master/LICENSE.md
 */
"use strict";

/*
 Based on order of the NPM official package.json reference.
 https://www.npmjs.org/doc/package.json.html
 */
var priorityKeys = [
    "name",
    "version",
    "description",
    "keywords",
    "homepage",
    "bugs",
    "license",
    "author",
    "contributors",
    "files",
    "main",
    "bin",
    "man",
    "directories",
    "repository",
    "scripts",
    "config",
    "dependencies",
    "devDependencies",
    "bundledDependencies",
    "optionalDependencies",
    "engines",
    "engineStrict",
    "os",
    "cpu",
    "preferGlobal",
    "private",
    "publishConfig"
];

export default function (inputData) {
    var flattenData = {},
        formerKey;

    priorityKeys.forEach(function (key) {
        if (inputData.hasOwnProperty(key)) {
            flattenData[key] = inputData[key];
            delete inputData[key];
        }
    });

    for (formerKey in inputData) {
        if (inputData.hasOwnProperty(formerKey)) {
            flattenData[formerKey] = inputData[formerKey];
        }
    }

    return flattenData;
}

/*
 Copyright (c) 2014, Ryuichi Okumura. All rights reserved.
 Code licensed under the BSD License:
 https://github.com/okuryu/package-json-flatten/blob/master/LICENSE.md
 */
"use strict";

/*
 Based on order of the NPM official package.json reference.
 https://www.npmjs.org/doc/package.json.html
 */
var priorityKeys = [
    "name",
    "version",
    "description",
    "keywords",
    "homepage",
    "bugs",
    "license",
    "author",
    "contributors",
    "files",
    "main",
    "bin",
    "man",
    "directories",
    "repository",
    "scripts",
    "config",
    "dependencies",
    "devDependencies",
    "bundledDependencies",
    "optionalDependencies",
    "engines",
    "engineStrict",
    "os",
    "cpu",
    "preferGlobal",
    "private",
    "publishConfig"
];

export default function (inputData) {
    var flattenData = {},
        formerKey;

    priorityKeys.forEach(function (key) {
        if (inputData.hasOwnProperty(key)) {
            flattenData[key] = inputData[key];
            delete inputData[key];
        }
    });

    for (formerKey in inputData) {
        flattenData[formerKey] = inputData[formerKey];
    }

    return flattenData;
}

Move out checking by using hasOwnProperty()


export default function CartRouters($stateProvider, $urlRouterProvider) {

}

function CartRouters($stateProvider, $urlRouterProvider) {
}

CartRouters.$inject = ['$stateProvider', '$urlRouterProvider'];

export default CartRouters;

Use injector to do angular config function.


(function($) {

    "use strict";

    var apiUrl = "http://redjohn.herokuapp.com/api/tweets";

    function addScoresToSuspects(response) {
        _.each(response.results, function(mentions, suspect) {
            $("#" + suspect).find(".mentions").text(mentions);
        });
    }

    function addTotal(response) {
        $("#tweet-count").text(response.results);
    }

    $.ajax({
        url: apiUrl + "suspects/count",
        type: "GET",
        dataType: "jsonp",
        success: addScoresToSuspects
    });

    $.ajax({
        url: apiUrl + "count",
        type: "GET",
        dataType: "jsonp",
        success: addTotal
    });

})(jQuery);

(function($) {

    "use strict";

    var apiUrl = "http://redjohn.herokuapp.com/api/tweets/";

    function addScoresToSuspects(response) {
        _.each(response.results, function(mentions, suspect) {
            $("#" + suspect).find(".mentions").text(mentions);
        });
    }

    function addTotal(response) {
        $("#tweet-count").text(response.results);
    }

    $.ajax({
        url: apiUrl + "suspects/count",
        type: "GET",
        dataType: "jsonp",
        success: addScoresToSuspects
    });

    $.ajax({
        url: apiUrl + "count",
        type: "GET",
        dataType: "jsonp",
        success: addTotal
    });

})(jQuery);

Add a trailing slash to the base API URL


function JsonRenderer() {
    this._nrLogs = 0;
}

JsonRenderer.prototype.end = function (data) {
    if (this._nrLogs) {
        process.stderr.write(']\n');
    }

    if (data) {
        process.stdout.write(this._stringify(data) + '\n');
    }
};

JsonRenderer.prototype.error = function (err) {
    err.id = err.code || 'error';
    err.level = 'error';

    this.log(err);
    this.end();
};

JsonRenderer.prototype.log = function (log) {
    if (!this._nrLogs) {
        process.stderr.write('[');
    } else {
        process.stderr.write(', ');
    }

    process.stderr.write(this._stringify(log));
    this._nrLogs++;
};

JsonRenderer.prototype.updateAvailable = function () {};

// -------------------------

JsonRenderer.prototype._stringify = function (log) {
    // To json
    var str = JSON.stringify(log, null, '  ');
    // Remove colors in case some log has colors..
    str = str.replace(/\x1B\[\d+m/g, '');

    return str;
};

module.exports = JsonRenderer;

function JsonRenderer() {
    this._nrLogs = 0;
}

JsonRenderer.prototype.end = function (data) {
    if (this._nrLogs) {
        process.stderr.write(']\n');
    }

    if (data) {
        process.stdout.write(this._stringify(data) + '\n');
    }
};

JsonRenderer.prototype.error = function (err) {
    var message = err.message;

    err.id = err.code || 'error';
    err.level = 'error';
    err.data = err.data || {};

    // Need to set message again because it is
    // not enumerable in some cases
    delete err.message;
    err.message = message;

    this.log(err);
    this.end();
};

JsonRenderer.prototype.log = function (log) {
    if (!this._nrLogs) {
        process.stderr.write('[');
    } else {
        process.stderr.write(', ');
    }

    process.stderr.write(this._stringify(log));
    this._nrLogs++;
};

JsonRenderer.prototype.updateAvailable = function () {};

// -------------------------

JsonRenderer.prototype._stringify = function (log) {
    // To json
    var str = JSON.stringify(log, null, '  ');
    // Remove colors in case some log has colors..
    str = str.replace(/\x1B\[\d+m/g, '');

    return str;
};

module.exports = JsonRenderer;

Fix log of errors not rendering the error message/data in the JSON renderer.


'use strict';
require('../helpers');
const assert  = require('assert');
const Ironium = require('../..');

describe('Queue with delay', function() {

  const captureQueue = Ironium.queue('capture');

  // Capture processed jobs here.
  const processed = [];

  before(function() {
    captureQueue.eachJob(function(job) {
      processed.push(job);
      return Promise.resolve();
    });
  });

  before(function() {
    return captureQueue.delayJob('delayed', '2s');
  });
  before(Ironium.runOnce);

  it('should not process immediately', function() {
    assert.equal(processed.length, 0);
  });

  describe('after short delay', function() {
    before(function(done) {
      setTimeout(done, 1500);
    });
    before(Ironium.runOnce);

    it('should not process job', function() {
      assert.equal(processed.length, 0);
    });
  });

  describe('after sufficient delay', function() {
    before(function(done) {
      setTimeout(done, 1000);
    });
    before(Ironium.runOnce);

    it('should process job', function() {
      assert.equal(processed.length, 1);
      assert.equal(processed[0], 'delayed');
    });
  });

});

'use strict';
require('../helpers');
const assert      = require('assert');
const Ironium     = require('../..');
const ms          = require('ms');
const TimeKeeper  = require('timekeeper');

describe('Queue with delay', function() {

  const captureQueue = Ironium.queue('capture');

  // Capture processed jobs here.
  const processed = [];

  before(function() {
    captureQueue.eachJob(function(job) {
      processed.push(job);
      return Promise.resolve();
    });
  });

  before(function() {
    return captureQueue.delayJob('delayed', '2m');
  });

  before(Ironium.runOnce);

  it('should not process immediately', function() {
    assert.equal(processed.length, 0);
  });

  describe('after 1 minute', function() {
    before(function() {
      TimeKeeper.travel(Date.now() + ms('1m'));
    });

    before(Ironium.runOnce);

    it('should not process job', function() {
      assert.equal(processed.length, 0);
    });
  });

  describe('after 2 minutes', function() {
    before(function() {
      TimeKeeper.travel(Date.now() + ms('2m'));
    });

    before(Ironium.runOnce);

    it('should process job', function() {
      assert.equal(processed.length, 1);
      assert.equal(processed[0], 'delayed');
    });
  });

});

Update delayJob test to use TimeKeeper


YUI.add("model-timeline-base", function(Y) {
    "use strict";

    var models = Y.namespace("Falco.Models"),

        TimelineBase;

    TimelineBase = Y.Base.create("timeline", Y.Model, [], {
        initializer : function(config) {
            var tweets;

            config || (config = {});

            tweets = new models.Tweets({
                items : config.tweets || []
            });

            this.set("tweets", tweets);

            this._handles = [
                tweets.after([ "more", "add" ], this._tweetAdd, this)
            ];

            this.publish("tweets", { preventable : false });
        },

        destructor : function() {
            new Y.EventTarget(this._handles).detach();

            this._handles = null;

            this.get("tweets").destroy();
        },

        // Override .toJSON() to make sure tweets are included
        toJSON : function() {
            var json = TimelineBase.superclass.toJSON.apply(this);

            json.tweets = json.tweets.toJSON();

            return json;
        },

        _tweetAdd : function(e) {
            var count = 1;

            // Don't notify for tweets from cache
            if(e.cached) {
                return;
            }

            if(e.parsed || e.models) {
                count = (e.parsed || e.models).length;
            }

            this.fire("tweets", {
                count : count
            });
        }
    });

    models.TimelineBase = TimelineBase;

}, "@VERSION@", {
    requires : [
        // YUI
        "base-build",
        "model",

        // Models
        "model-list-tweets"
    ]
});

YUI.add("model-timeline-base", function(Y) {
    "use strict";

    var models = Y.namespace("Falco.Models"),

        TimelineBase;

    TimelineBase = Y.Base.create("timeline", Y.Model, [], {
        initializer : function(config) {
            var tweets;

            if(!config) {
                config = {};
            }

            tweets = new models.Tweets({
                items : config.tweets || []
            });

            this.set("tweets", tweets);

            this._handles = [
                tweets.after([ "more", "add" ], this._tweetAdd, this)
            ];

            this.publish("tweets", { preventable : false });
        },

        destructor : function() {
            new Y.EventTarget(this._handles).detach();

            this._handles = null;

            this.get("tweets").destroy();
        },

        // Override .toJSON() to make sure tweets are included
        toJSON : function() {
            var json = TimelineBase.superclass.toJSON.apply(this);

            json.tweets = json.tweets.toJSON();

            return json;
        },

        _tweetAdd : function(e) {
            // Don't notify for tweets from cache
            // TODO: is this ever hit?
            if(e.cached) {
                debugger;

                return;
            }

            this.fire("tweets", {
                count  : e.model ? 1 : (e.parsed || e.models).length
            });
        }
    });

    models.TimelineBase = TimelineBase;

}, "@VERSION@", {
    requires : [
        // YUI
        "base-build",
        "model",

        // Models
        "model-list-tweets"
    ]
});

Clean up how timelines respond to tweets


'use strict';

/*
 * Angular Seed - v0.1
 * https://github.com/rachellcarbone/angular-seed/
 * Copyright (c) 2015 Rachel L Carbone; Licensed MIT
 */

// Include modules, and run application.
angular.module('theApp', [
    'ui.bootstrap',
    'ui.bootstrap.showErrors',
    'datatables',
    'datatables.bootstrap',
    'ngCookies',
    'ngMessages',
    'angular-md5',
    'api.v1',
    'rcDirectives',
    'rcCart',
    'app.config',
    'app.router',
    'app.run',
    'app.run.dev',
    'app.filters',
    'app.services'
]);

'use strict';

/*
 * Angular Seed - v0.1
 * https://github.com/rachellcarbone/angular-seed/
 * Copyright (c) 2015 Rachel L Carbone; Licensed MIT
 */

// Include modules, and run application.
angular.module('theApp', [
    'ui.bootstrap',
    'ui.bootstrap.showErrors',
    'datatables',
    'datatables.bootstrap',
    'ngCookies',
    'ngMessages',
    'ngFileUpload',
    'ngImgCrop',
    'angular-md5',
    'api.v1',
    'rcDirectives',
    'rcCart',
    'app.config',
    'app.router',
    'app.run',
    'app.run.dev',
    'app.filters',
    'app.services'
]);

Include new libraries in the project.


const spaceCase = (a) => {
  return a
    .replace(/(_|-|\.)/g, ' ')
    .replace(/([A-Z])/g, ' $1')
    .replace(/\s+/g, ' ')
    .replace(/^\s+/, '')
    .replace(/\s$/, '');
};

export default spaceCase;

const spaceCase = (a) => {
  return a
    .replace(/(_|-|\.)/g, ' ')
    .replace(/([A-Z])/g, ' $1')
    .replace(/\s+/g, ' ')
    .replace(/(^\s|\s$)/g, '');
};

export default spaceCase;

Refactor spaceCase to combine "ltrim/rtrim" into one regex


// Include needed files
var fluffbot = require('../lib/fluffbot')
var discord = require('discord.js')
var event = require('../lib/event')

// Instantiate bots
var fluffbot = new fluffbot()
discord = new discord.Client({autoReconnect:true})

discord.login(fluffbot.settings.bot_token)

// Initiate the playing game to say the current version
discord.on('ready', function(event) {
	this.status('online', 'Alpha v2.0.4 by FluffyMatt');
})

// Event listener when bot is added to a server
discord.on('serverCreated', function(server) {
	this.sendMessage(server.generalChannel ,'@here FluffBot has joined '+server.name+' and is here to help!');
})

// Event listener for new member joining
discord.on('serverNewMember', function(server, user) {
	this.sendMessage(server.generalChannel ,'@here Welcome '+user.toString()+' to the Fam');
})

// Event listener registered
event.bus.on('response', function(message, data) {
	discord.reply(message, data)
})

// Event listener registered
event.bus.on('message', function(message, data) {
	discord.sendMessage(message, data)
})

// Message event listener
discord.on('message', function(message) {

	if (message.content.indexOf('!') > -1 && message.content[0] == '!') {
		fluffbot._runCommand(message)
	}

})

// Include needed files
var fluffbot = require('../lib/fluffbot')
var discord = require('discord.js')
var event = require('../lib/event')

// Instantiate bots
var fluffbot = new fluffbot()
discord = new discord.Client({autoReconnect:true})

discord.login(fluffbot.settings.bot_token)

// Initiate the playing game to say the current version
discord.on('ready', function(event) {
	this.setStatus('online', 'Alpha v2.0.4 by FluffyMatt');
})

// Event listener when bot is added to a server
discord.on('serverCreated', function(server) {
	this.sendMessage(server.generalChannel ,'@here FluffBot has joined '+server.name+' and is here to help!');
})

// Event listener for new member joining
discord.on('serverNewMember', function(server, user) {
	this.sendMessage(server.generalChannel ,'@here Welcome '+user.toString()+' to the Fam');
})

// Event listener registered
event.bus.on('response', function(message, data) {
	discord.reply(message, data)
})

// Event listener registered
event.bus.on('message', function(message, data) {
	discord.sendMessage(message, data)
})

// Message event listener
discord.on('message', function(message) {

	if (message.content.indexOf('!') > -1 && message.content[0] == '!') {
		fluffbot._runCommand(message)
	}

})

Use method instead of property


'use strict';

var exec = require('child_process').exec;

module.exports = function reboot(controller) {
  controller.hears('technical assessment', ['direct_message','mention','direct_mention', 'message_received'], function(bot, message) {
    bot.reply(message, 'May god have mercy on your souls...');
    // console.log(message._client.channels.C0LFUN4F2.name);
  });
}

'use strict';

var exec = require('child_process').exec;

module.exports = function reboot(controller) {
  controller.hears('technical assessment', ['direct_message','mention','direct_mention', 'message_received'], function(bot, message) {
    bot.reply(message, 'no comment');
    // console.log(message._client.channels.C0LFUN4F2.name);
  });
}

Revert "Fixed the response to any mention of the technical (summary) assessment."


var Series = require('hapi-next'),
    Validator = require('modules/authorization/validator'),
    Controller = require('modules/authorization/controller');

module.exports = {

	login : {
		method : 'POST',
		path : '/login',
		config : {
			validate : Validator.validateReqLogin(),
			handler : function(request,reply) {

				var series = new Series([
					Validator.login,
					Controller.login
				]);

				series.execute(request,reply);
			}
		}
	},

	logout : {
		method : 'POST',
		path : '/logout',
		config : {
			handler : function(request,reply) {

				var series = new Series([
					Controller.logout
				]);

				series.execute(request,reply);
			}
		}
	}

}

Update indentation to 2 spaces


import response from 'cfn-response'
import SNS from 'aws/sns'
import { Settings } from 'model/settings'

export async function handle (event, context, callback) {
  if (event.RequestType === 'Update' || event.RequestType === 'Delete') {
    response.send(event, context, response.SUCCESS)
    return
  }

  const {
    AdminPageURL: adminPageURL,
    StatusPageURL: statusPageURL,
    CognitoPoolID: cognitoPoolID,
    IncidentNotificationTopic: incidentNotificationTopic
  } = event.ResourceProperties

  const settings = new Settings()
  try {
    if (statusPageURL) {
      await settings.setStatusPageURL(statusPageURL)
    }
  } catch (error) {
    // failed due to the unknown SNS topic.
    console.warn(error.message)
  }

  try {
    await new SNS().notifyIncidentToTopic(incidentNotificationTopic)

    if (adminPageURL) {
      await settings.setAdminPageURL(adminPageURL)
    }
    if (cognitoPoolID) {
      await settings.setCognitoPoolID(cognitoPoolID)
    }
    response.send(event, context, response.SUCCESS)
  } catch (error) {
    console.log(error.message)
    console.log(error.stack)
    response.send(event, context, response.FAILED)
  }
}

import response from 'cfn-response'
import SNS from 'aws/sns'
import { Settings } from 'model/settings'

export async function handle (event, context, callback) {
  if (event.RequestType === 'Update' || event.RequestType === 'Delete') {
    response.send(event, context, response.SUCCESS)
    return
  }

  const {
    AdminPageURL: adminPageURL,
    StatusPageURL: statusPageURL,
    CognitoPoolID: cognitoPoolID,
    IncidentNotificationTopic: incidentNotificationTopic
  } = event.ResourceProperties

  const settings = new Settings()
  try {
    if (statusPageURL) {
      await settings.setStatusPageURL(statusPageURL)
    }
  } catch (error) {
    // setStatusPageURL always fails due to the unknown SNS topic. So ignore the error here.
    // TODO: improve error handling. There may be other kinds of errors.
    console.warn(error.message)
  }

  try {
    await new SNS().notifyIncidentToTopic(incidentNotificationTopic)

    if (adminPageURL) {
      await settings.setAdminPageURL(adminPageURL)
    }
    if (cognitoPoolID) {
      await settings.setCognitoPoolID(cognitoPoolID)
    }

    await settings.createApiKey()

    response.send(event, context, response.SUCCESS)
  } catch (error) {
    console.log(error.message)
    console.log(error.stack)
    response.send(event, context, response.FAILED)
  }
}

Create new API key on launching a new stack


// Test runner
var runTests  = require('./affixing-header-specs'),
    browsers  = [
        {browserName: 'chrome'},
        {browserName: 'firefox'}
    ];

// var browserConfig = require('./helpers/browser-config');

if (process.env.TRAVIS_JOB_NUMBER) {
	browsers.push(
        {browserName: 'Safari',  version: '7'},
        {browserName: 'Safari',  deviceName: 'iPhone Simulator',           platformName: 'iOS',     platformVersion: '8.2', appiumVersion: '1.3.7'},
        {browserName: 'Safari',  deviceName: 'iPad Simulator',             platformName: 'iOS',     platformVersion: '8.2', appiumVersion: '1.3.7'},
        {browserName: 'Browser', deviceName: 'Samsung Galaxy S4 Emulator', platformName: 'Android', platformVersion: '4.4', appiumVersion: '1.3.7'},
        {browserName: 'internet explorer'}
	);
}

browsers.forEach(function(browser) {
    runTests(browser);
});

// Test runner
var runTests  = require('./affixing-header-specs'),
    browsers  = [
        {browserName: 'chrome'},
        {browserName: 'firefox'}
    ];

// var browserConfig = require('./helpers/browser-config');

if (process.env.TRAVIS_JOB_NUMBER) {
	browsers.push(
        {browserName: 'Safari',  version: '7'},
        {browserName: 'Safari',  deviceName: 'iPhone Simulator', platformName: 'iOS',     platformVersion: '8.2', appiumVersion: '1.3.7', 'device-orientation': 'portrait'},
        {browserName: 'Safari',  deviceName: 'iPad Simulator',   platformName: 'iOS',     platformVersion: '8.2', appiumVersion: '1.3.7', 'device-orientation': 'portrait'},
        {browserName: 'Browser', deviceName: 'Android Emulator', platformName: 'Android', platformVersion: '4.4', appiumVersion: '1.3.7', 'device-orientation': 'portrait'},
        {browserName: 'internet explorer'}
	);
}

browsers.forEach(function(browser) {
    runTests(browser);
});

Use generic Android Emulator, add device-orientation


'use strict';

// workflows/createDeployment
var Joi = require('joi');

module.exports = {
  schema: Joi.object({
    deployerId: Joi.string().required(),
    name:       Joi.string().min(1).required(),
  }).required().unknown(true),

  version: '1.0',

  decider: function(args) {
    return {

      createDeploymentDoc: {
        activity: 'createDeploymentDoc',
        input:    (env) => ({}),
        output:   (env) => ({ theId: env.id, newValueThatIWant: env.newValueThatIWant })
      },

      startNewDeployment: {
        dependsOn: ['createDeploymentDoc'],
        input:     (env) => ({ deploymentId: env.theId }),
        workflow:  'startDeployment'
      },

      doSomethingWithDeployment: {
        dependsOn: ['startNewDeployment'],
        input:     (env) => {
          return { theValue: env.newValueThatIWant };
        },
        output:    (env) => {
          env.BLAMMO = 'mrow0';
          return { env };
        },
        workflow:  'doSomething'
      },

      setDeploymentStateCreated: {
        dependsOn: ['startNewDeployment'],
        input:     (env) => {
          return { state: 'Running', id: env.theId };
        },
        activity:  'setDeploymentDocState',
      },

    }
  },

  output: function(results) {
    return {
      env: {
        deployment: results.startNewDeployment
      }
    };
  }
};

'use strict';

// workflows/createDeployment
var Joi = require('joi');

module.exports = {
  schema: Joi.object({
    deployerId: Joi.string().required(),
    name:       Joi.string().min(1).required(),
  }).required().unknown(true),

  version: '1.0',

  decider: function(args) {
    return {

      createDeploymentDoc: {
        activity: 'createDeploymentDoc',
        input:    (env) => ({}),
        output:   (env) => {
          return { env: { theId: env.id, newValueThatIWant: env.newValueThatIWant } };
        }
      },

      startNewDeployment: {
        dependsOn: ['createDeploymentDoc'],
        input:     (env) => {
          return { deploymentId: env.theId };
        },
        workflow:  'startDeployment'
      },

      doSomethingWithDeployment: {
        dependsOn: ['startNewDeployment'],
        input:     (env) => {
          return { theValue: env.newValueThatIWant };
        },
        output:    (env) => {
          env.BLAMMO = 'mrow0';
          return { env };
        },
        workflow:  'doSomething'
      },

      setDeploymentStateCreated: {
        dependsOn: ['startNewDeployment'],
        input:     (env) => {
          return { state: 'Running', id: env.theId };
        },
        activity:  'setDeploymentDocState',
      },

    }
  },

  output: function(results) {
    return {
      env: {
        deployment: results.startNewDeployment
      }
    };
  }
};

Update examples to return env from output defined on parent workflow


import { createAction, handleActions } from 'redux-actions'

export const INITIAL_DATA = 'INITIAL_DATA'

export const initialData = createAction(INITIAL_DATA)

const spaceshipsDataReducer = handleActions({
  [INITIAL_DATA]: (state, action) => {
    const { payload } = action
    return {
      ...state,
      spaceships: payload.products
    }
  }
}, { spaceships: [] })

export default spaceshipsDataReducer

import { createAction, handleActions } from 'redux-actions'

export const selectSpaceshipsData = state => state.spaceshipsData.spaceships

export const INITIAL_DATA = 'INITIAL_DATA'

export const initialData = createAction(INITIAL_DATA)

const spaceshipsDataReducer = handleActions({
  [INITIAL_DATA]: (state, action) => {
    const { payload } = action
    return {
      ...state,
      spaceships: payload.products
    }
  }
}, { spaceships: [] })

export default spaceshipsDataReducer

Move selectSpaceshipsData to global reducer


module.exports = {
  sortChildren (data) {
    data.forEach((el) => {
      if (el.parent) {
        this.findNestedObject(data, el.parent[0].admin.uid).children.push(el);
      }
    });
    return this.arrangeChildren(data[0]);
  },

  findNestedObject (objects, id) {
    var found;
    for (var i = 0; i < objects.length; i++) {
      if (objects[i].id === id) {
        found = objects[i];
        break;
      } else if (objects[i].children) {
        found = this.findNestedObject(objects[i].children, id);
        if (found) {
          break;
        }
      }
    }
    if (found) {
      if (!found.children) found.children = [];
      return found;
    }
  },

  arrangeChildren (item) {
    if (item.children) {
      for (var i = 0; i < item.children.length; i++) {
        this.arrangeChildren(item.children[i]);
      }
      item.children = item.children.sort(sortByIdentifier);
    }
    return item;
  }
};

function sortByIdentifier (a, b) {
  var aIdentifier = a.identifier;
  var bIdentifier = b.identifier;

  if (aIdentifier < bIdentifier) {
    return -1;
  }
  if (aIdentifier > bIdentifier) {
    return 1;
  }

  return 0;
}

module.exports = {
  sortChildren (data) {
    data.forEach((el) => {
      if (el.parent) {
        if (this.findNestedObject(data, el.parent[0].admin.uid)) {
          this.findNestedObject(data, el.parent[0].admin.uid).children.push(el);
        }
      }
    });
    return this.arrangeChildren(data[0]);
  },

  findNestedObject (objects, id) {
    var found;
    for (var i = 0; i < objects.length; i++) {
      if (objects[i].id === id) {
        found = objects[i];
        break;
      } else if (objects[i].children) {
        found = this.findNestedObject(objects[i].children, id);
        if (found) {
          break;
        }
      }
    }
    if (found) {
      if (!found.children) found.children = [];
      return found;
    }
  },

  arrangeChildren (item) {
    if (item.children) {
      for (var i = 0; i < item.children.length; i++) {
        this.arrangeChildren(item.children[i]);
      }
      item.children = item.children.sort(sortByIdentifier);
    }
    return item;
  }
};

function sortByIdentifier (a, b) {
  var aIdentifier = a.identifier;
  var bIdentifier = b.identifier;

  if (aIdentifier < bIdentifier) {
    return -1;
  }
  if (aIdentifier > bIdentifier) {
    return 1;
  }

  return 0;
}

Check for element before tryign to retrive an attibiute of that element


import OC from 'orbit-common/main';
import Cache from 'orbit-common/cache';
import IdMap from 'orbit-common/id-map';
import Schema from 'orbit-common/schema';
import Serializer from 'orbit-common/serializer';
import Source from 'orbit-common/source';
import MemorySource from 'orbit-common/memory-source';
import { OperationNotAllowed, RecordNotFoundException, LinkNotFoundException, RecordAlreadyExistsException } from 'orbit-common/lib/exceptions';

OC.Cache = Cache;
OC.Schema = Schema;
OC.Serializer = Serializer;
OC.Source = Source;
OC.MemorySource = MemorySource;
// exceptions
OC.OperationNotAllowed = OperationNotAllowed;
OC.RecordNotFoundException = RecordNotFoundException;
OC.LinkNotFoundException = LinkNotFoundException;
OC.RecordAlreadyExistsException = RecordAlreadyExistsException;

export default OC;

import OC from 'orbit-common/main';
import Cache from 'orbit-common/cache';
import Schema from 'orbit-common/schema';
import Serializer from 'orbit-common/serializer';
import Source from 'orbit-common/source';
import MemorySource from 'orbit-common/memory-source';
import { OperationNotAllowed, RecordNotFoundException, LinkNotFoundException, RecordAlreadyExistsException } from 'orbit-common/lib/exceptions';

OC.Cache = Cache;
OC.Schema = Schema;
OC.Serializer = Serializer;
OC.Source = Source;
OC.MemorySource = MemorySource;
// exceptions
OC.OperationNotAllowed = OperationNotAllowed;
OC.RecordNotFoundException = RecordNotFoundException;
OC.LinkNotFoundException = LinkNotFoundException;
OC.RecordAlreadyExistsException = RecordAlreadyExistsException;

export default OC;

Remove IdMap from Orbit exports.


define(
    [
        'Magento_Payment/js/view/payment/cc-form'
    ],
    function (Component) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'Omise_Payment/payment/omise-cc-form'
            },
        });
    }
);

define(
    [
        'Magento_Payment/js/view/payment/cc-form'
    ],
    function (Component) {
        'use strict';
        return Component.extend({
            defaults: {
                template: 'Omise_Payment/payment/omise-cc-form'
            },

            getCode: function() {
                return 'omise';
            },

            isActive: function() {
                return true;
            }
        });
    }
);

Add client side script functions to display the checkout form


'use strict';

module.exports = function(sequelize, DataTypes) {
    var University = sequelize.define("University", {
        name: {
            type: DataTypes.STRING,
            allowNull: false,
        },
        country: {
            type: DataTypes.STRING,
            allowNull: false,
        },
    }, {
        indexes: [
            {unique: true, fields: ['name']}
        ],
    });

    return University;
};

'use strict';

module.exports = function(sequelize, DataTypes) {
    var University = sequelize.define("University", {
        name: {
            type: DataTypes.STRING,
            allowNull: false,
        },
        country: {
            type: DataTypes.STRING,
            allowNull: false,
        },
    }, {
        indexes: [
            {unique: true, fields: ['name']}
        ],
        classMethods: {
            associate: (models) => {
                University.hasMany(models.User);
                University.hasMany(models.School);
            }
        }
    });

    return University;
};

Add University associations with User, School


const functions = require('firebase-functions');
const { getPullRequestsForUser } = require('./github.js');

exports.user = functions.https.onRequest(async (request, response) => {
  try {
    const data = await getPullRequestsForUser(request.params[0]);
    response.send({
      ...data,
      config: process.env.FIREBASE_CONFIG
    });
  } catch(error) {
    response.send({
      error: error.toString(),
      stacktrace: error.stack,
      config: process.env.FIREBASE_CONFIG
    });
  }
});

const functions = require('firebase-functions');
const { getPullRequestsForUser } = require('./github.js');

exports.user = functions.https.onRequest(async (request, response) => {
  try {
    const data = await getPullRequestsForUser(request.params[0]);
    response.send(data);
  } catch(error) {
    response.send({
      error: error.toString(),
      stacktrace: error.stack
    });
  }
});

Remove firebase config from resp


(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');

  var ContentHeader = helper.inherits(function() {
    ContentHeader.super_.call(this);
  }, jCore.Component);

  if (typeof module !== 'undefined' && module.exports)
    module.exports = ContentHeader;
  else
    app.ContentHeader = ContentHeader;
})(this.app || (this.app = {}));

(function(app) {
  'use strict';

  var jCore = require('jcore');
  var helper = app.helper || require('../helper.js');

  var ContentHeader = helper.inherits(function(props) {
    ContentHeader.super_.call(this);

    this.element = this.prop(props.element);
  }, jCore.Component);

  if (typeof module !== 'undefined' && module.exports)
    module.exports = ContentHeader;
  else
    app.ContentHeader = ContentHeader;
})(this.app || (this.app = {}));

Add property to access element of the content header


var cobs = require('../..'),
    http = require('http'),
    fs = require('fs');

function compileFile(filename) {
    var content = fs.readFileSync(filename).toString();
    var code = cobs.compileTemplate(content);
    var parser = new cobs.Parser(code);
    var program = parser.parseProgram();
    program.text = program.command.compile(program);
    return program;
};

var program = compileFile('./factorial.cobp');

http.createServer(function(req, res) {
    var runtime = {
        display: function() {
            if (arguments && arguments.length)
                for (var k = 0; k < arguments.length; k++)
                    if (arguments[k])
                        res.write(arguments[k].toString());

            res.write('\r\n');
        },
        write: function() {
            if (arguments && arguments.length)
                for (var k = 0; k < arguments.length; k++)
                    if (arguments[k])
                        res.write(arguments[k].toString());
        }
    }

    cobs.run(program.text, runtime, program);

    res.end();
}).listen(8000);

console.log('Server started, listening at port 8000');

var cobs = require('../..'),
    http = require('http'),
    fs = require('fs');

var program = cobs.compileTemplateFile('./factorial.cobp');

http.createServer(function(req, res) {
    var runtime = {
        display: function() {
            if (arguments && arguments.length)
                for (var k = 0; k < arguments.length; k++)
                    if (arguments[k])
                        res.write(arguments[k].toString());

            res.write('\r\n');
        },
        write: function() {
            if (arguments && arguments.length)
                for (var k = 0; k < arguments.length; k++)
                    if (arguments[k])
                        res.write(arguments[k].toString());
        }
    }

    program.run(runtime);

    res.end();
}).listen(8000);

console.log('Server started, listening at port 8000');

Refactor template web sample to use compileTemplateFile


import newResidentAndResidencySchema from '/both/schemas/newResidentAndResidencySchema';

Meteor.methods({
  addNewResidentAndResidency (document) {
    // set up validation context based on new resident and residency schama
    const validationContext = newResidentAndResidencySchema.newContext();

    // Check if submitted document is valid
    const documentIsValid = validationContext.validate(document);

    if (documentIsValid) {
      // Get fields from object
      firstName = document.firstName;
      lastInitial = document.lastInitial;
      homeId = document.homeId;
      moveIn = document.moveIn;

      // Create new resident
      // TODO: migrate homeId out of resident schema
      const residentId = Residents.insert({ firstName, lastInitial, homeId });

      if (residentId) {
        // Insert residency document
        const residencyId = Residencies.insert({ residentId, homeId, moveIn });

        if (residencyId) {
          // Submission was successful
          return true;
        } else {
          // Could not create residency
          throw new Meteor.Error(
            'could-not-create-residency',
            'Could not create residency.'
          )
        }
      } else {
        // Could not create resident
        throw new Meteor.Error(
          'could-not-create-resident',
          'Could not create resident.'
        )
      }
    } else {
      // Document is not valid
      throw new Meteor.Error(
        'resident-and-residency-invalid',
        'Resident and residency document is not valid.'
      )
    }
  }
});

import newResidentAndResidencySchema from '/both/schemas/newResidentAndResidencySchema';

Meteor.methods({
  addNewResidentAndResidency (document) {
    // set up validation context based on new resident and residency schama
    const validationContext = newResidentAndResidencySchema.newContext();

    // Check if submitted document is valid
    const documentIsValid = validationContext.validate(document);

    if (documentIsValid) {
      // Get fields from object
      const { firstName, lastInitial, homeId, moveIn } = document;

      // Create new resident
      // TODO: migrate homeId out of resident schema
      const residentId = Residents.insert({ firstName, lastInitial, homeId });

      if (residentId) {
        // Insert residency document
        const residencyId = Residencies.insert({ residentId, homeId, moveIn });

        if (residencyId) {
          // Submission was successful
          return true;
        } else {
          // Could not create residency
          throw new Meteor.Error(
            'could-not-create-residency',
            'Could not create residency.'
          )
        }
      } else {
        // Could not create resident
        throw new Meteor.Error(
          'could-not-create-resident',
          'Could not create resident.'
        )
      }
    } else {
      // Document is not valid
      throw new Meteor.Error(
        'resident-and-residency-invalid',
        'Resident and residency document is not valid.'
      )
    }
  }
});

Use object destructuring for resident attributes


// TODO: This is not a real model or controller
App.Graphs = Ember.Controller.extend({
  graph: function(emberId, entityName, entityType, numSeries) {
    entityName = entityName.replace(/\./g, '-');
    var url = ((!localStorage.apiDomain) ? '' : '//' + localStorage.apiDomain) + '/api/v1/graphs?entityType=' + entityType + '&entityName=' + entityName;
    if (numSeries) url += '&numSeries=' + numSeries;
    return Ember.$.ajax({
      url: url,
      type: 'GET',
      dataType: 'json'
    }).then(function (data) {
      if (entityType == 'node') {
        App.store.getById('node', emberId).set('graphs', App.associativeToNumericArray(data));
      } else if (entityType == 'vm') {
        App.store.getById('vm', emberId).set('graphs', App.associativeToNumericArray(data));
      }
    });
  }
});
App.graphs = App.Graphs.create();

// TODO: This is not a real model or controller
App.Graphs = Ember.Controller.extend({
  graph: function(emberId, entityName, entityType, numSeries) {
    entityName = entityName.replace(/\./g, '-');
    var url = ((!localStorage.apiDomain) ? '' : '//' + localStorage.apiDomain) + '/api/v1/graphs?entityType=' + entityType + '&entityName=' + entityName '&graphVars={"colorList":"yellow,green,orange,red,blue,pink"}';
    if (numSeries) url += '&numSeries=' + numSeries;
    return Ember.$.ajax({
      url: url,
      type: 'GET',
      dataType: 'json'
    }).then(function (data) {
      if (entityType == 'node') {
        App.store.getById('node', emberId).set('graphs', App.associativeToNumericArray(data));
      } else if (entityType == 'vm') {
        App.store.getById('vm', emberId).set('graphs', App.associativeToNumericArray(data));
      }
    });
  }
});
App.graphs = App.Graphs.create();

Use brighter colors in contextual Graphite graphs


const path = require('path');
const context = path.join(__dirname, 'site');
const public = path.join(__dirname, 'public');

module.exports = {
  context,
  devServer: {
    contentBase: public,
    historyApiFallback: true,
    open: true
  },
  devtool: 'source-map',
  entry: './index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            plugins: [
              ['transform-react-jsx', { pragma: 'h' }],
              'transform-skate-flow-props'
            ],
            presets: ['env', 'flow', 'react', 'stage-0']
          }
        }
      },
      {
        test: /\.(html|png)/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]'
          }
        }
      }
    ]
  },
  output: {
    filename: '[name].js',
    path: public,
    publicPath: '/'
  }
};

const path = require('path');
const context = path.join(__dirname, 'site');
const public = path.join(__dirname, 'public');
const webpack = require('webpack');

module.exports = {
  context,
  devServer: {
    contentBase: public,
    historyApiFallback: true,
    open: true
  },
  devtool: 'source-map',
  entry: './index.js',
  module: {
    rules: [
      {
        test: /\.js$/,
        use: {
          loader: 'babel-loader',
          options: {
            plugins: [
              ['transform-react-jsx', { pragma: 'h' }],
              'transform-skate-flow-props'
            ],
            presets: ['env', 'flow', 'react', 'stage-0']
          }
        }
      },
      {
        test: /\.(html|png)/,
        use: {
          loader: 'file-loader',
          options: {
            name: '[path][name].[ext]'
          }
        }
      }
    ]
  },
  output: {
    filename: '[name].js',
    path: public,
    publicPath: '/'
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: 'main',
      minChunks: 2,
      children: true,
      deepChildren: true
    })
  ]
};

Add common chunks to dedupe common deps between lazy components.


import template from './appstore-field-select-openstack-tenant.html';

class AppstoreFieldSelectOpenstackTenantController {
  // @ngInject
  constructor(ncUtilsFlash, openstackTenantsService, currentStateService) {
    this.ncUtilsFlash = ncUtilsFlash;
    this.openstackTenantsService = openstackTenantsService;
    this.currentStateService = currentStateService;
  }

  $onInit() {
    this.loading = true;
    this.currentStateService.getProject().then(project => {
      this.openstackTenantsService.getAll({
        field: ['name', 'uuid'],
        project_uuid: project.uuid,
      }).then(tenants => {
        this.choices = tenants.map(tenant => ({
          display_name: tenant.name,
          value: `UUID: ${tenant.uuid}. Name: ${tenant.name}`
        }));
        this.loading = false;
        this.loaded = true;
      })
      .catch(response => {
        this.ncUtilsFlash.errorFromResponse(response, gettext('Unable to get list of OpenStack tenants.'));
        this.loading = false;
        this.loaded = false;
      });
    });
  }
}

const appstoreFieldSelectOpenstackTenant = {
  template,
  bindings: {
    field: '<',
    model: '<'
  },
  controller: AppstoreFieldSelectOpenstackTenantController,
};

export default appstoreFieldSelectOpenstackTenant;

import template from './appstore-field-select-openstack-tenant.html';

class AppstoreFieldSelectOpenstackTenantController {
  // @ngInject
  constructor(ncUtilsFlash, openstackTenantsService, currentStateService) {
    this.ncUtilsFlash = ncUtilsFlash;
    this.openstackTenantsService = openstackTenantsService;
    this.currentStateService = currentStateService;
  }

  $onInit() {
    this.loading = true;
    this.currentStateService.getProject().then(project => {
      this.openstackTenantsService.getAll({
        field: ['name', 'uuid'],
        project_uuid: project.uuid,
      }).then(tenants => {
        this.choices = tenants.map(tenant => ({
          display_name: tenant.name,
          value: `Tenant UUID: ${tenant.backend_id}. Name: ${tenant.name}`
        }));
        this.loading = false;
        this.loaded = true;
      })
      .catch(response => {
        this.ncUtilsFlash.errorFromResponse(response, gettext('Unable to get list of OpenStack tenants.'));
        this.loading = false;
        this.loaded = false;
      });
    });
  }
}

const appstoreFieldSelectOpenstackTenant = {
  template,
  bindings: {
    field: '<',
    model: '<'
  },
  controller: AppstoreFieldSelectOpenstackTenantController,
};

export default appstoreFieldSelectOpenstackTenant;

Use backend_id instead of Waldur UUID for OpenStack


module.exports = {
    entry: "./src/ko-calendar.js",
    output: {
        filename: "./ko-calendar.js",
        libraryTarget: "commonjs2"
    }
}

module.exports = {
    entry: "./src/ko-calendar.js",
    output: {
        filename: "./ko-calendar.js",
        libraryTarget: "commonjs"
    }
}

Change webpack library target to commonjs


var biomes = {
    "riverLand": {
        probability: 0.8,
        tiles: {
          "bambooBush": 0.8,
          "rockCluster": 0.2
        }
    },
    "forest": {
        probability: 0.5,
        tiles: {
          "loneTree": 0.25,
          "rockCluster": 0.75
        }
    },
    "desert": {
        probability: 0.5,
        tiles: {
          "loneTree": 0.25,
          "rockCluster": 0.75
        }
    }
}

var biomes = {
    "riverLand": {
        probability: 0,
        tiles: {
          "bambooBush": 0,
          "rockCluster": 0.2
        }
    },
    "forest": {
        probability: 0.5,
        tiles: {
          "loneTree": 0.25,
          "rockCluster": 0.75
        }
    },
    "desert": {
        probability: 0.5,
        tiles: {
          "loneTree": 0.25,
          "rockCluster": 0.75
        }
    }
}

Set bamboo generation percent to 0 until water is ready


/* eslint-env node */
/* eslint-disable no-console */

const webpack = require('webpack');
const debug = require('debug')('app:webpack');

const isDev = process.env.NODE_ENV !== 'production';
debug(`Running in ${(isDev ? 'development' : 'production')} mode`);

module.exports = {
  entry: {
    'main': './src/browser/main',
    'service-worker': './src/browser/service-worker.js',
  },
  output: {
    path: './public/compiled/scripts',
    filename: '[name].js',
  },
  module: {
    rules: [
      {test: /\.js$/, exclude: /node_modules/, use: ['babel-loader']},
    ],
  },
  plugins: [].concat(
    isDev ? [] : new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
    new webpack.DefinePlugin({BUILD_ID: Date.now()}),
    new webpack.BannerPlugin({banner: `Build date: ${new Date()}`})
  ),
  devtool: 'source-map',
};

/* eslint-env node */
/* eslint-disable no-console */

const webpack = require('webpack');
const debug = require('debug')('app:webpack');

const isDev = process.env.NODE_ENV !== 'production';
debug(`Running in ${(isDev ? 'development' : 'production')} mode`);

module.exports = {
  entry: {
    'main': './src/browser/main',
    'service-worker': './src/browser/service-worker.js',
  },
  output: {
    path: `${__dirname}/public/compiled/scripts`,
    filename: '[name].js',
  },
  module: {
    rules: [
      {test: /\.js$/, exclude: /node_modules/, use: ['babel-loader']},
    ],
  },
  plugins: [].concat(
    isDev ? [] : new webpack.optimize.UglifyJsPlugin({sourceMap: true}),
    new webpack.DefinePlugin({BUILD_ID: Date.now()}),
    new webpack.BannerPlugin({banner: `Build date: ${new Date()}`})
  ),
  devtool: 'source-map',
};

Fix error "The provided value ... is not an absolute path!"


const fs = require('fs');
const Encore = require('@symfony/webpack-encore');

const { paths, js: { entries, vendor } } = JSON.parse(fs.readFileSync('./package.json')).config;
const env = process.env.NODE_ENV === 'production' ? 'production' : 'dev';

Encore.configureRuntimeEnvironment(env);

Encore
  // directory where all compiled assets will be stored
  .setOutputPath(paths.dist.js)

  // what's the public path to this directory (relative to your project's document root dir)
  .setPublicPath('/')

  // empty the outputPath dir before each build
  .cleanupOutputBeforeBuild()

  .enableSourceMaps(!Encore.isProduction())

  // Split vendor assets from the entries
  .createSharedEntry('vendor', vendor)

  // create hashed filenames (e.g. app.abc123.css)
  .enableVersioning();

// Dynamically load entry points
entries.forEach((entry) => {
  Encore.addEntry(entry.replace('.js', ''), `${paths.source.js}/${entry}`);
});

const config = Encore.getWebpackConfig();

config.bail = true;

console.log(config);

// export the final configuration
module.exports = config;

const fs = require('fs');
const Encore = require('@symfony/webpack-encore');

const { paths, js: { entries, vendor } } = JSON.parse(fs.readFileSync('./package.json')).config;
const env = process.env.NODE_ENV === 'production' ? 'production' : 'dev';

Encore.configureRuntimeEnvironment(env);

Encore
  // directory where all compiled assets will be stored
  .setOutputPath(paths.dist.js)

  // what's the public path to this directory (relative to your project's document root dir)
  .setPublicPath('/')

  // empty the outputPath dir before each build
  .cleanupOutputBeforeBuild()

  .enableSourceMaps(!Encore.isProduction())

  // Split vendor assets from the entries
  .createSharedEntry('vendor', vendor)

  // create hashed filenames (e.g. app.abc123.css)
  .enableVersioning();

// Dynamically load entry points
entries.forEach((entry) => {
  Encore.addEntry(entry.replace('.js', ''), `${paths.source.js}/${entry}`);
});

// Check for errors and exit the process
if (env === 'production') {
  Encore.addPlugin(function () { // eslint-disable-line func-names, needed to expose `this`
    this.plugin('done', (stats) => {
      if (stats.compilation.errors && stats.compilation.errors.length) {
        throw new Error('webpack build failed');
      }
    });
  });
}

// export the final configuration
module.exports = Encore.getWebpackConfig();

Exit the process if there is a compile error in a production build


import {PluginNotFound} from 'Exception/PluginNotFound';

export class Slider
{
  constructor(element)
  {
    if (!$.isFunction($.fn.slider)) {
      throw new PluginNotFound('Slider');
    }

    this.element = element;
    this.initSlider();
  }

  initSlider()
  {
    this.element.slider(
      {
        min: 0,
        max: 50,
        values: [10, 40],
        range: true,
      }
    )
  }
}

import {PluginNotFound} from 'Exception/PluginNotFound';

export class Slider
{
  constructor(element, min = 0, max = 50, values = [10, 40], range = true)
  {
    if (!$.isFunction($.fn.slider)) {
      throw new PluginNotFound('Slider');
    }

    this.element = element;
    this.min = min;
    this.max = max;
    this.values = values;
    this.range = range;
    this.initSlider();
  }

  initSlider()
  {
    this.element.slider(
      {
        min: this.min,
        max: this.max,
        values: this.values,
        range: this.range,
      }
    )
  }
}

Set default values for slider


import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import { version, name } from '../package.json';

class App extends Component {
  render() {
    return (

Welcome to React

{`${name} v${version}`}

          To get started, edit src/App.js and save to reload.

    );
  }
}

export default App;

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (

Welcome to React

          To get started, edit src/App.js and save to reload.

    );
  }
}

export default App;

Remove import package.json from template


const path = require('path')

module.exports = {
  context: __dirname,
  entry: './src/index.js',
  devtool: 'source-map',

  output: {
    library: 'es2016-starter',
    libraryTarget: 'umd',
    path: path.resolve('dist'),
    filename: 'es2015-starter.js',
  },

  resolve: {
    extensions: ['.js'],
    modules: [
      path.resolve('node_modules'),
      path.resolve('src'),
    ],
  },

  module: {
    loaders: [
      {
        use: ['babel-loader'],
        test: /\.js$/,
        exclude: [path.resolve('node_modules')],
      },
      {
        use: 'file-loader',
        test: /.*/,
        exclude: [/\.js$/],
      },
    ],
  },

  watchOptions: {
    ignored: /node_modules/,
  },

  devServer: {
    port: 3030,
    contentBase: path.resolve('src'),
    stats: 'errors-only',
    overlay: {
      warnings: true,
      errors: true,
    },
  },
}

const path = require('path')
const webpack = require('webpack')

module.exports = {
  context: __dirname,
  entry: './src/index.js',
  devtool: 'source-map',

  output: {
    library: 'es2015-starter',
    libraryTarget: 'umd',
    path: path.resolve('dist'),
    filename: 'es2015-starter.js',
  },

  resolve: {
    extensions: ['.js'],
    modules: [
      path.resolve('node_modules'),
      path.resolve('src'),
    ],
  },

  plugins: [
    new webpack.optimize.ModuleConcatenationPlugin(),
  ],

  module: {
    loaders: [
      {
        use: ['babel-loader'],
        test: /\.js$/,
        exclude: [path.resolve('node_modules')],
      },
      {
        use: 'file-loader',
        test: /.*/,
        exclude: [/\.js$/],
      },
    ],
  },

  watchOptions: {
    ignored: /node_modules/,
  },

  devServer: {
    port: 3030,
    contentBase: path.resolve('src'),
    stats: 'errors-only',
    overlay: {
      warnings: true,
      errors: true,
    },
  },
}

Fix typo on output name, add module concat plugin.


const { resolve } = require('path')

module.exports = {
  mode: 'production',
  entry: './dist.browser/index.js',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      },
      {
        test: /\.js$/,
        loader: 'file-replace-loader',
        options: {
          condition: 'always',
          replacement (resourcePath) {
            const mapping = {
              [resolve('./dist.browser/lib/logging.js')]: resolve(
                './browser/logging.js'
              ),
              [resolve('./dist.browser/lib/net/peer/libp2pnode.js')]: resolve(
                './browser/libp2pnode.js'
              )
            }
            return mapping[resourcePath]
          },
          async: true
        }
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  output: {
    filename: 'bundle.js',
    path: resolve(__dirname, 'dist'),
    library: 'ethereumjs'
  }
}

const { resolve } = require('path')

module.exports = {
  mode: 'production',
  entry: './dist.browser/browser/index.js',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: 'ts-loader',
        exclude: /node_modules/
      },
      {
        test: /\.js$/,
        loader: 'file-replace-loader',
        options: {
          condition: 'always',
          replacement (resourcePath) {
            const mapping = {
              [resolve('./dist.browser/lib/logging.js')]: resolve(
                './browser/logging.js'
              ),
              [resolve('./dist.browser/lib/net/peer/libp2pnode.js')]: resolve(
                './browser/libp2pnode.js'
              )
            }
            return mapping[resourcePath]
          },
          async: true
        }
      }
    ]
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js']
  },
  output: {
    filename: 'bundle.js',
    path: resolve(__dirname, 'dist'),
    library: 'ethereumjs'
  }
}

Revert webpack entry point change


/* eslint-env node */
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon')

module.exports = function (defaults) {
  const app = new EmberAddon(defaults, {
    babel: {
      optional: ['es7.decorators']
    },
    'ember-cli-mocha': {
      useLintTree: false
    },
    sassOptions: {
      includePaths: [
        'node_modules/ember-frost-css-core/scss',
        'node_modules/ember-frost-theme/scss'
      ]
    }
  })

  return app.toTree()
}

/* eslint-env node */
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon')

module.exports = function (defaults) {
  const app = new EmberAddon(defaults, {
    babel: {
      optional: ['es7.decorators']
    },
    sassOptions: {
      includePaths: [
        'node_modules/ember-frost-css-core/scss',
        'node_modules/ember-frost-theme/scss'
      ]
    }
  })

  return app.toTree()
}

Remove ember-cli-mocha useLintTree configuration option


const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    home: path.join(__dirname, 'app/src/home'),
  },

  module: {
    loaders: [
      {
        test: /\.sass$/,
        loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: 'node_modules',
        query: { presets: ['es2015'] },
      },
      {
        test: /\.(ttf|woff|woff2)$/,
        loader: 'file',
        query: { name: 'fonts/[name].[ext]' },
      },
      {
        test: /\.png$/,
        loader: 'file',
      },
      {
        test: /\.html$/,
        loader: 'file-loader?name=[name].[ext]!extract-loader!html-loader',
      },
    ],
  },

  output: {
    path: path.join(__dirname, 'app/build'),
    publicPath: '/',
    filename: '[name].js',
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({ minimize: true, compress: { warnings: false } }),
  ],

  // --------------------------------------------------------------------------

  devServer: {
    contentBase: path.join(__dirname, 'app/build'),
    inline: true,
  },
};

const path = require('path');
const webpack = require('webpack');

module.exports = {
  entry: {
    home: path.join(__dirname, 'app/src/home'),
  },

  module: {
    loaders: [
      {
        test: /\.sass$/,
        loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: 'node_modules',
        query: { presets: ['es2015'] },
      },
      {
        test: /\.(ttf|woff|woff2)$/,
        loader: 'file',
        query: { name: 'fonts/[name].[ext]' },
      },
      {
        test: /\.png$/,
        loader: 'file',
      },
      {
        test: /\.html$/,
        loader: 'file-loader?name=[name].[ext]!extract-loader!html-loader',
      },
    ],
  },

  output: {
    path: path.join(__dirname, 'app/build'),
    publicPath: '/',
    filename: '[name].js',
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({ minimize: true, compress: { warnings: false } }),
  ],

  // --------------------------------------------------------------------------

  devServer: {
    contentBase: path.join(__dirname, 'app/build'),
  },
};

Remove inline serving from webpack dev server


var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');

module.exports = [{
  entry: {
    horizontal: './shim/horizontal.js',
    vertical: './shim/vertical.js'
  },
  output: {
    library: 'ScratchBlocks',
    libraryTarget: 'commonjs2',
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  }
}, {
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'gh-pages')
  },
  plugins: [
      new CopyWebpackPlugin([{
        from: 'node_modules/google-closure-library',
        to: 'closure-library'
      }, {
        from: 'blocks_common',
        to: 'playgrounds/blocks_common',
      }, {
        from: 'blocks_horizontal',
        to: 'playgrounds/blocks_horizontal',
      }, {
        from: 'blocks_vertical',
        to: 'playgrounds/blocks_vertical',
      }, {
        from: 'core',
        to: 'playgrounds/core'
      }, {
        from: 'media',
        to: 'playgrounds/media'
      }, {
        from: 'msg',
        to: 'playgrounds/msg'
      }, {
        from: 'tests',
        to: 'playgrounds/tests'
      }, {
        from: '*.js',
        ignore: 'webpack.config.js',
        to: 'playgrounds'
      }])
  ]
}];

var CopyWebpackPlugin = require('copy-webpack-plugin');
var path = require('path');

module.exports = [{
  entry: {
    horizontal: './shim/horizontal.js',
    vertical: './shim/vertical.js'
  },
  output: {
    library: 'ScratchBlocks',
    libraryTarget: 'commonjs2',
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].js'
  }
}, {
  entry: {
    horizontal: './shim/horizontal.js',
    vertical: './shim/vertical.js'
  },
  output: {
    library: 'Blockly',
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'dist', 'web'),
    filename: '[name].js'
  }
},
{
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'gh-pages')
  },
  plugins: [
      new CopyWebpackPlugin([{
        from: 'node_modules/google-closure-library',
        to: 'closure-library'
      }, {
        from: 'blocks_common',
        to: 'playgrounds/blocks_common',
      }, {
        from: 'blocks_horizontal',
        to: 'playgrounds/blocks_horizontal',
      }, {
        from: 'blocks_vertical',
        to: 'playgrounds/blocks_vertical',
      }, {
        from: 'core',
        to: 'playgrounds/core'
      }, {
        from: 'media',
        to: 'playgrounds/media'
      }, {
        from: 'msg',
        to: 'playgrounds/msg'
      }, {
        from: 'tests',
        to: 'playgrounds/tests'
      }, {
        from: '*.js',
        ignore: 'webpack.config.js',
        to: 'playgrounds'
      }])
  ]
}];

Add UMD target for use without "require"/"import"


const webpack = require('webpack');

module.exports = {
  entry: `${__dirname}/src/index.js`,
  output: {
    path: `${__dirname}/build`,
    publicPath: '/build/',
    filename: 'bundle.js',
  },

  module: {
    rules: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
    ],
  },

  plugins: process.argv.indexOf('-p') === -1 ? [] : [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production'),
    }),
    new webpack.optimize.UglifyJsPlugin({
      output: {
        comments: false,
      },
    }),
  ],
};

const webpack = require('webpack');

module.exports = {
  entry: `${__dirname}/src/index.js`,
  output: {
    path: `${__dirname}/build`,
    publicPath: '/build/',
    filename: 'bundle.js',
  },

  module: {
    rules: [
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },
    ],
  },

  plugins: process.argv.indexOf('-p') === -1 ? [] : [
    new webpack.optimize.UglifyJsPlugin({
      output: {
        comments: false,
      },
    }),
  ],
};

Remove webpack plugin for node env production


var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  devtool: 'source-map',
  entry: {
    'tree-chooser': './src/index.js',
    'tree-chooser.min': './src/index.js'
  },
  output: {
    path: './dist',
    filename: '[name].js'
  },
  externals: {
    angular: 'angular',
    lodash: '_'
  },
  module: {
    preLoaders: [
      {
        test: /\.js/,
        exclude: /node_modules/,
        loader: 'jshint-loader!jscs-loader',
      },
    ],
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'ng-annotate?single_quotes!babel?presets[]=es2015'
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
      },
      {
        test: /\.html$/,
        loader: 'html?minimize=true'
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('tree-chooser.css'),
    new webpack.optimize.UglifyJsPlugin({
      include: /\.min\.js$/,
      minimize: true
    })
  ],
  jshint: {
    failOnHint: true,
    esversion: 6,
    node: true,
    quotmark: 'single'
  },
  jscs: {
    failOnHint: true
  }
};

var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  devtool: 'source-map',
  entry: {
    'tree-chooser': './src/index.js',
    'tree-chooser.min': './src/index.js'
  },
  output: {
    path: './dist',
    filename: '[name].js',
    library: 'tree-chooser',
    libraryTarget: 'commonjs'
  },
  externals: {
    angular: 'angular',
    lodash : {
      'commonjs': 'lodash'
    }
  },
  module: {
    preLoaders: [
      {
        test: /\.js/,
        exclude: /node_modules/,
        loader: 'jshint-loader!jscs-loader',
      },
    ],
    loaders: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'ng-annotate?single_quotes!babel?presets[]=es2015'
      },
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style-loader', 'css-loader')
      },
      {
        test: /\.html$/,
        loader: 'html?minimize=true'
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('tree-chooser.css'),
    new webpack.optimize.UglifyJsPlugin({
      include: /\.min\.js$/,
      minimize: true
    })
  ],
  jshint: {
    failOnHint: true,
    esversion: 6,
    node: true,
    quotmark: 'single'
  },
  jscs: {
    failOnHint: true
  }
};

Make lodash an external for real


#!/usr/bin/env node

const path = require('path');
const shell = require('shelljs');
const argv = require('yargs').argv;
const clc = require('cli-color');

function packageJsonLocations(dirname) {
  return shell.find(dirname)
    .filter(fname => !(fname.indexOf('node_modules') > -1 || fname[0] === '.') && path.basename(fname) === 'package.json')
    .map(fname => path.dirname(fname));
}

function yarn(directoryName) {
  let command = 'yarn';

  if (argv.cmd)
    command += ' ' + argv.cmd;

  if (argv.opt)
    command += ' ' + argv.opt;

  console.log(clc.blueBright('Current yarn path: ' + directoryName + '/package.json...'));

  shell.cd(directoryName);
  let result = shell.exec(command);

  return {
    directoryName: directoryName,
    exitCode: result.code
  };
}

function filterRoot(directoryName) {
  console.log('Root filtering');

  return path.normalize(directoryName) === path.normalize(process.cwd());
}

if (require.main === module) {
  let exitCode = packageJsonLocations(process.cwd())
    .filter(argv.skipRoot ? filterRoot : filtered => filtered)
    .map(yarn)
    .reduce((code, result) =>result.exitCode > code ? result.exitCode : code, 0);

  console.log(clc.green('End of yarns'));
  process.exit(exitCode);
}

module.exports = {
  yarn: yarn
};

#!/usr/bin/env node

const path = require('path');
const shell = require('shelljs');
const argv = require('yargs').argv;
const clc = require('cli-color');

function packageJsonLocations(dirname) {
  return shell.find(dirname)
    .filter(fname => !(fname.indexOf('node_modules') > -1 || fname[0] === '.') && path.basename(fname) === 'package.json')
    .map(fname => path.dirname(fname));
}

function yarn(directoryName) {
  let command = 'yarn';

  if (argv.cmd)
    command += ' ' + argv.cmd;

  if (argv.opt)
    command += ' ' + argv.opt;

  console.log(clc.blueBright('Current yarn path: ' + directoryName + path.sep + 'package.json...'));

  shell.cd(directoryName);
  let result = shell.exec(command);

  return {
    directoryName: directoryName,
    exitCode: result.code
  };
}

function filterRoot(directoryName) {
  console.log('Root filtering');

  return path.normalize(directoryName) === path.normalize(process.cwd());
}

if (require.main === module) {
  let exitCode = packageJsonLocations(process.cwd())
    .filter(argv.skipRoot ? filterRoot : filtered => filtered)
    .map(yarn)
    .reduce((code, result) =>result.exitCode > code ? result.exitCode : code, 0);

  console.log(clc.green('End of yarns'));
  process.exit(exitCode);
}

module.exports = {
  yarn: yarn
};

Use platform-specific path separator in log messages.


module.exports = {
  stories: ['../components/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/storyshots'],
};

module.exports = {
  stories: ['../components/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
};

Remove redundant storyshot plugin configuration