<commit_before>var express = require('express');
var router = express.Router();
var mustacheExpress = require('mustache-express');
var humanize = require('humanizer');
var icons = require('glyphicons');
var jwt = require('jsonwebtoken');
var querystring = require('querystring');
var http = require('http');

var secret = process.env.TOKENS_KSOTD || 'shhhhh';
var phrase = process.env.PHRASE_KSOTD || 'hakunamatata';

var apiCall = function(path, method, signed, data, success, err) {
    let host = process.env.API || 'localhost';
    let port = process.env.API_PORT || '10010';
    let headers = {'X-API-Key': signed};
    let dataString = JSON.stringify(data);
    if(method === 'GET' && data) {
        path += '?' + querystring.stringify(data);
    } else {
        headers = {
            'Content-Type': 'application/json',
            'Content-Length': dataString.length,
            'X-API-Key': signed
          };
    }
    let options = {
        host,
        port,
        path,
        method,
        headers
      };
      try {
            let req = http.request(options, function(res){

                res.setEncoding('utf-8');
                var responseString = '';

                res.on('data', function(data){
                    responseString += data;
                });

                res.on('end', function(){
                    let responseObject = JSON.parse(responseString);
                    if(responseObject.message) {
                        err(responseObject, req);
                        return;
                    }
                    success(responseObject);
                });
            });
            req.on('error', err);
            req.write(dataString);
            req.end();
        } catch (error) {
            err(error);
        }
}

var shortcut = {
    message: 'Not yet'
}

var emptyShortcut = shortcut;

var getShortcut = function(signed, res) {
    apiCall('/shortcuts/1', 'GET', signed, null, function (dataObject){
        shortcut = dataObject || emptyShortcut;
        res.render('index', { title: 'Keyboard shortcut of the day', dissa: icons.ticket, token: signed, 'shortcut' : JSON.stringify(shortcut), 'description': shortcut.description, stitle: shortcut.title, vendor: shortcut.vendor, product: shortcut.product, keys: shortcut.keycombo, documentation: shortcut.documentation });
    },
    function(error, req){
        res.render('error', { message: error.message});
    }
    );
}

router.get('/', function (req, res) {
    var signed = jwt.sign({ phrase }, secret, { expiresIn: '1h'});
    getShortcut(signed, res);
})

var app = express();
app.use(express.static('public'));
app.engine('html', mustacheExpress());
app.set('views', 'views');
app.set('view engine', 'html');
app.use('/js', [express.static(__dirname + '/node_modules/jquery/dist/'),
                express.static(__dirname + '/node_modules/bootstrap/dist/js/'),
                express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/js/'),
                express.static(__dirname + '/node_modules/popper.js/dist/')]);
app.use('/css', [express.static(__dirname + '/node_modules/bootstrap/dist/css/'),
                express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/css/')]);
app.use('/webfonts', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/webfonts/'));
app.use('/sprites', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/sprites/'));
app.use('/svg', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/svg/'));
app.use('/', router);

app.listen(process.env.PORT || 8080);<commit_msg>Point to API by default<commit_after>var express = require('express');
var router = express.Router();
var mustacheExpress = require('mustache-express');
var humanize = require('humanizer');
var icons = require('glyphicons');
var jwt = require('jsonwebtoken');
var querystring = require('querystring');
var http = require('http');

var secret = process.env.TOKENS_KSOTD || 'shhhhh';
var phrase = process.env.PHRASE_KSOTD || 'hakunamatata';

var apiCall = function(path, method, signed, data, success, err) {
    let host = process.env.API || 'api.keyboardshortcutoftheday.com';
    let port = process.env.API_PORT || '80';
    let headers = {'X-API-Key': signed};
    let dataString = JSON.stringify(data);
    if(method === 'GET' && data) {
        path += '?' + querystring.stringify(data);
    } else {
        headers = {
            'Content-Type': 'application/json',
            'Content-Length': dataString.length,
            'X-API-Key': signed
          };
    }
    let options = {
        host,
        port,
        path,
        method,
        headers
      };
      try {
            let req = http.request(options, function(res){

                res.setEncoding('utf-8');
                var responseString = '';

                res.on('data', function(data){
                    responseString += data;
                });

                res.on('end', function(){
                    let responseObject = JSON.parse(responseString);
                    if(responseObject.message) {
                        err(responseObject, req);
                        return;
                    }
                    success(responseObject);
                });
            });
            req.on('error', err);
            req.write(dataString);
            req.end();
        } catch (error) {
            err(error);
        }
}

var shortcut = {
    message: 'Not yet'
}

var emptyShortcut = shortcut;

var getShortcut = function(signed, res) {
    apiCall('/shortcuts/1', 'GET', signed, null, function (dataObject){
        shortcut = dataObject || emptyShortcut;
        res.render('index', { title: 'Keyboard shortcut of the day', dissa: icons.ticket, token: signed, 'shortcut' : JSON.stringify(shortcut), 'description': shortcut.description, stitle: shortcut.title, vendor: shortcut.vendor, product: shortcut.product, keys: shortcut.keycombo, documentation: shortcut.documentation });
    },
    function(error, req){
        res.render('error', { message: error.message, token: signed});
    }
    );
}

router.get('/', function (req, res) {
    var signed = jwt.sign({ phrase }, secret, { expiresIn: '1h'});
    getShortcut(signed, res);
})

var app = express();
app.use(express.static('public'));
app.engine('html', mustacheExpress());
app.set('views', 'views');
app.set('view engine', 'html');
app.use('/js', [express.static(__dirname + '/node_modules/jquery/dist/'),
                express.static(__dirname + '/node_modules/bootstrap/dist/js/'),
                express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/js/'),
                express.static(__dirname + '/node_modules/popper.js/dist/')]);
app.use('/css', [express.static(__dirname + '/node_modules/bootstrap/dist/css/'),
                express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/css/')]);
app.use('/webfonts', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/webfonts/'));
app.use('/sprites', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/sprites/'));
app.use('/svg', express.static(__dirname + '/node_modules/@fortawesome/fontawesome-free/svg/'));
app.use('/', router);

app.listen(process.env.PORT || 8080);<|endoftext|>


<commit_before>var mongoose = require('mongoose'),
    Quote = mongoose.model('Quote'),
    Vendor = mongoose.model('Vendor'),
    User = mongoose.model('User'),
    moment = require('moment')
    ;

// our formatting for moment.js
var dateTimeFormat = "dddd, MMMM Do YYYY, h:mm:ss a";

// ---------------------------------------
//
// NEW QUOTE
//
// ---------------------------------------

// sent to end user
exports.newQuoteEndUser = function(req, quote) {

    // check for valid email
    // @todo this check is in the email.js module, but it throws an error. Should
    // we change that and eliminate the check here?
    if(!quote.company.contactPerson.email) return false;

    var vendorName = quote.vendorId.name || '';

    var locals = {
        to: {
            email: quote.company.contactPerson.email,
            fullName: quote.company.contactPerson.name
        },
        //from: {
        //    email : quote.salesRep.email,
        //    fullName: quote.salesRep.fullname
        //},
        variables: {
            link: quote.quoterToolLink, // a virtual property of quote model
            fullName: quote.company.contactPerson.name
        },
        subject: 'Your ' + vendorName + ' Quote'
    };

    req.app.emailer.send('quotes/new-endUser', locals);

};

// sent to sales rep on new quote
exports.newQuoteSalesRep = function(req, quote) {

    if(!quote.salesRep) {
        // @todo send a default email to system admin!
        console.log('A quote was generated for a vendor with no Marlin Sales Rep');
        return;
    }

    if(!quote.salesRep.email) {
        console.log('A quote was generated for a salesRep who has no email, ' + quote.salesRep.fullname);
        return;
    }

    var locals = {
        to: {
            email: quote.salesRep.email,
            fullName: quote.salesRep.fullname
        },
        variables: {
            link: quote.dashboardLink, // a virtual property of quote model
            dateTime: moment(quote.created).format(dateTimeFormat),

            vendorName: quote.vendorId.name,
            salesRepName: quote.salesRep.fullname,

            quoteCompany: quote.company.contactPerson.name,
            quoteMethod: quote.company.contactPerson.contactMethod,
            quoteContact: quote.company.contactPerson.name,
            quotePhone: quote.company.contactPerson.phone,
            quoteEmail: quote.company.contactPerson.email,
            quoteAmount: quote.totalCost,
            quoteDesc: quote.description
        }
    };

    req.app.emailer.send('quotes/new-salesRep', locals);
};

// sent to vendor rep on new quote
exports.newQuoteVendorRep = function(req, quote) {

    if(!quote.vendorRep) {
        // @todo send a default email to system admin!
        console.log('A quote was generated for a vendor with no vendorRep, ' + quote.vendorId.name);
        return;
    }

    if(!quote.vendorRep.email) {
        console.log('A quote was generated for a vendorRep who has no email, ' + quote.vendorRep.fullname);
        return;
    }

    var locals = {
        to: {
            email: quote.vendorRep.email,
            fullName: quote.vendorRep.fullname
        },
        variables: {
            link: quote.dashboardLink, // a virtual property of quote model
            dateTime: moment(quote.created).format(dateTimeFormat),

            vendorName: quote.vendorId.name,
            salesRepName: quote.salesRep.fullname,

            quoteCompany: quote.company.contactPerson.name,
            quoteMethod: quote.company.contactPerson.contactMethod,
            quoteContact: quote.company.contactPerson.name,
            quotePhone: quote.company.contactPerson.phone,
            quoteEmail: quote.company.contactPerson.email,
            quoteAmount: quote.totalCost,
            quoteDesc: quote.description
        }
    };

    req.app.emailer.send('quotes/new-vendorRep', locals);
};

// ---------------------------------------
//
// NEW APPLICATION
//
// ---------------------------------------
<commit_msg>Change console.logs() to console.warn()<commit_after>var mongoose = require('mongoose'),
    Quote = mongoose.model('Quote'),
    Vendor = mongoose.model('Vendor'),
    User = mongoose.model('User'),
    moment = require('moment')
    ;

// our formatting for moment.js
var dateTimeFormat = "dddd, MMMM Do YYYY, h:mm:ss a";

// ---------------------------------------
//
// NEW QUOTE
//
// ---------------------------------------

// sent to end user
exports.newQuoteEndUser = function(req, quote) {

    // check for valid email
    // @todo this check is in the email.js module, but it throws an error. Should
    // we change that and eliminate the check here?
    if(!quote.company.contactPerson.email) return false;

    var vendorName = quote.vendorId.name || '';

    var locals = {
        to: {
            email: quote.company.contactPerson.email,
            fullName: quote.company.contactPerson.name
        },
        //from: {
        //    email : quote.salesRep.email,
        //    fullName: quote.salesRep.fullname
        //},
        variables: {
            link: quote.quoterToolLink, // a virtual property of quote model
            fullName: quote.company.contactPerson.name
        },
        subject: 'Your ' + vendorName + ' Quote'
    };

    req.app.emailer.send('quotes/new-endUser', locals);

};

// sent to sales rep on new quote
exports.newQuoteSalesRep = function(req, quote) {

    if(!quote.salesRep) {
        // @todo send a default email to system admin!
        console.warn('A quote was generated for a vendor with no Marlin Sales Rep');
        return;
    }

    if(!quote.salesRep.email) {
        console.warn('A quote was generated for a salesRep who has no email, ' + quote.salesRep.fullname);
        return;
    }

    var locals = {
        to: {
            email: quote.salesRep.email,
            fullName: quote.salesRep.fullname
        },
        variables: {
            link: quote.dashboardLink, // a virtual property of quote model
            dateTime: moment(quote.created).format(dateTimeFormat),

            vendorName: quote.vendorId.name,
            salesRepName: quote.salesRep.fullname,

            quoteCompany: quote.company.contactPerson.name,
            quoteMethod: quote.company.contactPerson.contactMethod,
            quoteContact: quote.company.contactPerson.name,
            quotePhone: quote.company.contactPerson.phone,
            quoteEmail: quote.company.contactPerson.email,
            quoteAmount: quote.totalCost,
            quoteDesc: quote.description
        }
    };

    req.app.emailer.send('quotes/new-salesRep', locals);
};

// sent to vendor rep on new quote
exports.newQuoteVendorRep = function(req, quote) {

    if(!quote.vendorRep) {
        // @todo send a default email to system admin!
        console.warn('A quote was generated for a vendor with no vendorRep, ' + quote.vendorId.name);
        return;
    }

    if(!quote.vendorRep.email) {
        console.warn('A quote was generated for a vendorRep who has no email, ' + quote.vendorRep.fullname);
        return;
    }

    var locals = {
        to: {
            email: quote.vendorRep.email,
            fullName: quote.vendorRep.fullname
        },
        variables: {
            link: quote.dashboardLink, // a virtual property of quote model
            dateTime: moment(quote.created).format(dateTimeFormat),

            vendorName: quote.vendorId.name,
            salesRepName: quote.salesRep.fullname,

            quoteCompany: quote.company.contactPerson.name,
            quoteMethod: quote.company.contactPerson.contactMethod,
            quoteContact: quote.company.contactPerson.name,
            quotePhone: quote.company.contactPerson.phone,
            quoteEmail: quote.company.contactPerson.email,
            quoteAmount: quote.totalCost,
            quoteDesc: quote.description
        }
    };

    req.app.emailer.send('quotes/new-vendorRep', locals);
};

// ---------------------------------------
//
// NEW APPLICATION
//
// ---------------------------------------
<|endoftext|>


<commit_before>var buildFolder = './Build/'
        , gulp = require('gulp')
        , fs = require('fs')
        , rename = require('gulp-rename')
        , coffee = require("gulp-coffee")
        , concat = require("gulp-concat")
        , header = require("gulp-header")
        , jshint = require("gulp-jshint")
        , coffeelint = require("gulp-coffeelint")
        , minifyCss = require("gulp-minify-css")
        , minifyHtml = require("gulp-minify-html")
        , sass = require("gulp-sass")
        , less = require("gulp-less")
        , uglify = require("gulp-uglify")
        , watch = require("gulp-watch");

// Get version using NodeJs file system
var getVersion = function () {
    return fs.readFileSync('Version');
};

// Get copyright using NodeJs file system
var getCopyright = function () {
    return fs.readFileSync('Copyright');
};

// Get copyright using NodeJs file system
var getCopyrightVersion = function () {
    return fs.readFileSync('CopyrightVersion');
};

// Run All tasks one by one
gulp.task('default', ['compile-coffee'
            , 'compile-less'
            , 'compile-sass'
            , 'minify-css'
            , 'minify-html'
            , 'minify-js'
            , 'concat'
            , 'concat-copyright'
            , 'concat-copyright-version'
            , 'jsLint'
            , 'coffeeLint'
            , 'bundle-one'
            , 'rename'
]);

// Compile CoffeeScript
gulp.task('compile-coffee', function () {
    gulp.src('./CoffeeScript/one.coffee')
            .pipe(coffee())
            .pipe(gulp.dest(buildFolder + 'compile-coffee'));
});

// Compile Less
gulp.task('compile-less', function () {
    gulp.src('./Less/one.less')
            .pipe(less())
            .pipe(gulp.dest(buildFolder + 'compile-less'));
});

// Compile Sass
gulp.task('compile-sass', function () {
    gulp.src('./Sass/one.sass')
            .pipe(sass())
            .pipe(gulp.dest(buildFolder + 'compile-sass'));
});

// Minify Css
gulp.task('minify-css', function () {
    gulp.src('./Css/one.css')
            .pipe(minifyCss())
            .pipe(gulp.dest(buildFolder + 'minify-css'));
});

// Minify HTML
gulp.task('minify-html', function () {
    gulp.src('./Html/*.html')
            .pipe(minifyHtml())
            .pipe(gulp.dest(buildFolder + 'minify-html'));
});

// Minify JavaScript
gulp.task('minify-js', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(uglify())
            .pipe(gulp.dest(buildFolder + 'minify-js'));
});

// Concat JavaScript
gulp.task('concat', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat.js'))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Concat JavaScript and Add Copyright
gulp.task('concat-copyright', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat-copyright.js'))
            .pipe(header(getCopyright()))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Concat JavaScript and Add Copyright + Version
gulp.task('concat-copyright-version', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat-copyright-version.js'))
            .pipe(header(getCopyrightVersion(), {version: getVersion()}))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Lint JavaScript
gulp.task('jsLint', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(jshint())
            .pipe(jshint.reporter());
});

// Lint CoffeeScript
gulp.task('coffeeLint', function () {
    gulp.src('./CoffeeScript/*.coffee')
            .pipe(coffeelint())
            .pipe(coffeelint.reporter());
});

// Compile CoffeeScript and rename it
gulp.task('rename', function () {
    gulp.src('./CoffeeScript/one.coffee')
            .pipe(coffee())
            .pipe(rename('renamed.js'))
            .pipe(gulp.dest(buildFolder + 'compile-coffee'));
});

// bundleOne.js: Lint, Compile, Concat and minify JavaScript + Add Copyright and Version
gulp.task('bundle-one', function () {
    gulp.src('./CoffeeScript/*.coffee')
            .pipe(coffeelint()) // lint files
            .pipe(coffeelint.reporter('fail')) // make sure the task fails if not compliant
            .pipe(concat('bundleOne.js')) // concat files
            .pipe(coffee()) // compile coffee
            .pipe(uglify()) // minify files
            .pipe(header(getCopyrightVersion(), {version: getVersion()})) // Add the copyright
            .pipe(gulp.dest(buildFolder + 'bundle')); // Dump the result
});

gulp.task('watch-coffeescript', function () {
    watch(['./CoffeeScript/*.coffee'], ['compile-coffee']);
});
<commit_msg>Update gulpfile.js<commit_after>var buildFolder = './Build/'
        , gulp = require('gulp')
        , fs = require('fs')
        , rename = require('gulp-rename')
        , coffee = require("gulp-coffee")
        , concat = require("gulp-concat")
        , header = require("gulp-header")
        , jshint = require("gulp-jshint")
        , coffeelint = require("gulp-coffeelint")
        , minifyCss = require("gulp-minify-css")
        , minifyHtml = require("gulp-minify-html")
        , sass = require("gulp-sass")
        , less = require("gulp-less")
        , uglify = require("gulp-uglify");

// Get version using NodeJs file system
var getVersion = function () {
    return fs.readFileSync('Version');
};

// Get copyright using NodeJs file system
var getCopyright = function () {
    return fs.readFileSync('Copyright');
};

// Get copyright using NodeJs file system
var getCopyrightVersion = function () {
    return fs.readFileSync('CopyrightVersion');
};

// Run All tasks one by one
gulp.task('default', ['compile-coffee'
            , 'compile-less'
            , 'compile-sass'
            , 'minify-css'
            , 'minify-html'
            , 'minify-js'
            , 'concat'
            , 'concat-copyright'
            , 'concat-copyright-version'
            , 'jsLint'
            , 'coffeeLint'
            , 'bundle-one'
            , 'rename'
]);

// Compile CoffeeScript
gulp.task('compile-coffee', function () {
    gulp.src('./CoffeeScript/one.coffee')
            .pipe(coffee())
            .pipe(gulp.dest(buildFolder + 'compile-coffee'));
});

// Compile Less
gulp.task('compile-less', function () {
    gulp.src('./Less/one.less')
            .pipe(less())
            .pipe(gulp.dest(buildFolder + 'compile-less'));
});

// Compile Sass
gulp.task('compile-sass', function () {
    gulp.src('./Sass/one.sass')
            .pipe(sass())
            .pipe(gulp.dest(buildFolder + 'compile-sass'));
});

// Minify Css
gulp.task('minify-css', function () {
    gulp.src('./Css/one.css')
            .pipe(minifyCss())
            .pipe(gulp.dest(buildFolder + 'minify-css'));
});

// Minify HTML
gulp.task('minify-html', function () {
    gulp.src('./Html/*.html')
            .pipe(minifyHtml())
            .pipe(gulp.dest(buildFolder + 'minify-html'));
});

// Minify JavaScript
gulp.task('minify-js', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(uglify())
            .pipe(gulp.dest(buildFolder + 'minify-js'));
});

// Concat JavaScript
gulp.task('concat', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat.js'))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Concat JavaScript and Add Copyright
gulp.task('concat-copyright', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat-copyright.js'))
            .pipe(header(getCopyright()))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Concat JavaScript and Add Copyright + Version
gulp.task('concat-copyright-version', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(concat('concat-copyright-version.js'))
            .pipe(header(getCopyrightVersion(), {version: getVersion()}))
            .pipe(gulp.dest(buildFolder + 'concat'));
});

// Lint JavaScript
gulp.task('jsLint', function () {
    gulp.src('./JavaScript/*.js')
            .pipe(jshint())
            .pipe(jshint.reporter());
});

// Lint CoffeeScript
gulp.task('coffeeLint', function () {
    gulp.src('./CoffeeScript/*.coffee')
            .pipe(coffeelint())
            .pipe(coffeelint.reporter());
});

// Compile CoffeeScript and rename it
gulp.task('rename', function () {
    gulp.src('./CoffeeScript/one.coffee')
            .pipe(coffee())
            .pipe(rename('renamed.js'))
            .pipe(gulp.dest(buildFolder + 'compile-coffee'));
});

// bundleOne.js: Lint, Compile, Concat and minify JavaScript + Add Copyright and Version
gulp.task('bundle-one', function () {
    gulp.src('./CoffeeScript/*.coffee')
            .pipe(coffeelint()) // lint files
            .pipe(coffeelint.reporter('fail')) // make sure the task fails if not compliant
            .pipe(concat('bundleOne.js')) // concat files
            .pipe(coffee()) // compile coffee
            .pipe(uglify()) // minify files
            .pipe(header(getCopyrightVersion(), {version: getVersion()})) // Add the copyright
            .pipe(gulp.dest(buildFolder + 'bundle')); // Dump the result
});

gulp.task('watch-coffeescript', function () {
    gulp.watch(['./CoffeeScript/*.coffee'], ['compile-coffee']);
});
<|endoftext|>


<commit_before>'use strict';
var defaultConfig = {
  defaultLanguage: 'en',
  // DEFAULT network (livenet or testnet)
  networkName: 'testnet',
  forceNetwork: false,
  logLevel: 'info',

  // wallet limits
  limits: {
    totalCopayers: 12,
    mPlusN: 100,
  },

  // network layer config
  network: {
    testnet: {
      host: 'test-insight.bitpay.com',
      port: 443,
      schema: 'https'
    },
    livenet: {
      host: 'insight.bitpay.com',
      port: 443,
      schema: 'https'
    },
  },

  // wallet default config
  wallet: {
    requiredCopayers: 2,
    totalCopayers: 3,
    spendUnconfirmed: true,
    reconnectDelay: 5000,
    idleDurationMin: 4,
    settings: {
      unitName: 'bits',
      unitToSatoshi: 100,
      unitDecimals: 2,
      alternativeName: 'US Dollar',
      alternativeIsoCode: 'USD',
    }
  },

  // local encryption/security config
  passphrase: {
    iterations: 100,
    storageSalt: 'mjuBtGybi/4=',
  },

  rate: {
    url: 'https://bitpay.com/api/rates',
    updateFrequencySeconds: 60 * 60
  },

};
if (typeof module !== 'undefined')
  module.exports = defaultConfig;
<commit_msg>settings: simple insight config<commit_after>'use strict';
var defaultConfig = {
  defaultLanguage: 'en',
  // DEFAULT network (livenet or testnet)
  networkName: 'testnet',
  forceNetwork: false,
  logLevel: 'info',

  // wallet limits
  limits: {
    totalCopayers: 12,
    mPlusN: 100,
  },

  // network layer config
  network: {
    testnet: {
      url: 'https://test-insight.bitpay.com:443'
    },
    livenet: {
      url: 'https:insight.bitpay.com:443'
    },
  },

  // wallet default config
  wallet: {
    requiredCopayers: 2,
    totalCopayers: 3,
    spendUnconfirmed: true,
    reconnectDelay: 5000,
    idleDurationMin: 4,
    settings: {
      unitName: 'bits',
      unitToSatoshi: 100,
      unitDecimals: 2,
      alternativeName: 'US Dollar',
      alternativeIsoCode: 'USD',
    }
  },

  // local encryption/security config
  passphrase: {
    iterations: 100,
    storageSalt: 'mjuBtGybi/4=',
  },

  rate: {
    url: 'https://bitpay.com/api/rates',
    updateFrequencySeconds: 60 * 60
  },

};
if (typeof module !== 'undefined')
  module.exports = defaultConfig;
<|endoftext|>


<commit_before>// async series collection
// lightweight serial async iterators:
// [each, reduce, map, filter, reject, detect, every, some, concat, times, series]
// adpoted from: https://github.com/aliaksandr-pasynkau/async-iterate

function asyncEachArray (arr, iterator, done) {
  if (!arr || !arr.length) {
    done()
    return
  }

  var lastIdx = arr.length
  var iterate = function (idx) {
    if (idx === lastIdx) return done()

    iterator(arr[idx], idx, function (err) {
      if (err) return done(err)

      iterate(++idx)
    })
  }
  iterate(0)
}

function asyncEach (obj, iterator, done) {
  if (Array.isArray(obj)) {
    asyncEachArray(obj, iterator, done)
    return
  }

  asyncEachArray(obj && Object.keys(obj), function (key, index, done) {
    iterator(obj[key], key, done)
  }, done)
}

function asyncReduce (obj, result, iterator, done) {
  asyncEach(obj, function (v, k, done) {
    iterator(result, v, k, function (err, value) {
      result = value
      done(err)
    })
  }, function (err) {
      done(err, result)
  })
}

function asyncMap (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      resultObject.push(result)
      done(err, resultObject)
    })
  }, done)
}

function asyncFilter (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

function asyncReject (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (!result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

function asyncDetect (obj, iterator, cb) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) {
        resultObject = obj[k]
        return cb(err, resultObject)
      }
      done(err, resultObject)
    })
  }, cb)
}

function asyncEvery (obj, iterator, done) {
  asyncReduce(obj, true, function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (!result) resultObject = false
      done(err, resultObject)
    })
  }, done)
}

function asyncSome (obj, iterator, done) {
  asyncReduce(obj, false, function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) resultObject = true
      done(err, resultObject)
    })
  }, done)
}

function asyncConcat (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      resultObject = resultObject.concat(result || [])
      done(err, resultObject)
    })
  }, done)
}

function asyncTimes (num, iterator, done) {
  var obj = Array(num)
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(num, function (err, res) {
      resultObject.push(res)
      done(null, resultObject)
    })
  }, done)
}

function asyncSeries (obj, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    v.call(null, function (err, res) {
      resultObject.push(res)
      done(null, resultObject)
    })
  }, done)
}

exports.each   = asyncEach
exports.reduce = asyncReduce
exports.map    = asyncMap
exports.filter = asyncFilter
exports.reject = asyncReject
exports.detect = asyncDetect
exports.every  = asyncEvery
exports.some   = asyncSome
exports.concat = asyncConcat
exports.times  = asyncTimes
exports.series = asyncSeries
<commit_msg>update async/iterate<commit_after>// async series collection
// lightweight serial async iterators:
// [each, reduce, map, filter, reject, detect, every, some, concat, times, series
// sequence(composite) and compose]
// adpoted from: https://github.com/aliaksandr-pasynkau/async-iterate

function asyncEachArray (arr, iterator, done) {
  if (!arr || !arr.length) return done()

  var lastIdx = arr.length
  var iterate = function (idx) {
    if (idx === lastIdx) return done()

    iterator(arr[idx], idx, function (err) {
      if (err) return done(err)

      iterate(++idx)
    })
  }
  iterate(0)
}

function asyncEach (obj, iterator, done) {
  if (Array.isArray(obj)) {
    asyncEachArray(obj, iterator, done)
    return
  }

  asyncEachArray(obj && Object.keys(obj), function (key, index, done) {
    iterator(obj[key], key, done)
  }, done)
}

function asyncReduce (obj, result, iterator, done) {
  asyncEach(obj, function (v, k, done) {
    iterator(result, v, k, function (err, value) {
      result = value
      done(err)
    })
  }, function (err) {
      done(err, result)
  })
}

function asyncMap (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      resultObject.push(result)
      done(err, resultObject)
    })
  }, done)
}

function asyncFilter (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

function asyncReject (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (!result) resultObject.push(obj[k])
      done(err, resultObject)
    })
  }, done)
}

function asyncDetect (obj, iterator, cb) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) {
        resultObject = obj[k]
        return cb(err, resultObject)
      }
      done(err, resultObject)
    })
  }, cb)
}

function asyncEvery (obj, iterator, done) {
  asyncReduce(obj, true, function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (!result) resultObject = false
      done(err, resultObject)
    })
  }, done)
}

function asyncSome (obj, iterator, done) {
  asyncReduce(obj, false, function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      if (result) resultObject = true
      done(err, resultObject)
    })
  }, done)
}

function asyncConcat (obj, iterator, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(v, k, function (err, result) {
      resultObject = resultObject.concat(result || [])
      done(err, resultObject)
    })
  }, done)
}

function asyncTimes (num, iterator, done) {
  var obj = Array(num)
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    iterator(num, function (err, res) {
      resultObject.push(res)
      done(null, resultObject)
    })
  }, done)
}

function asyncSeries (obj, done) {
  asyncReduce(obj, [], function (resultObject, v, k, done) {
    v.call(null, function (err, res) {
      resultObject.push(res)
      done(null, resultObject)
    })
  }, done)
}

function asyncSequence (/* functions ... */) {
  var fns = arguments
  return function () {
    var that = this
    var args = _baseSlice(arguments)
    var cb = args.slice(-1)[0]

    if (typeof cb === 'function') args.pop()
    else cb = function () {}

    asyncReduce(fns, args, function (resultObject, v, k, done) {
      v.apply(that, resultObject.concat([function () {
        var err = arguments[0]
        var nextargs = _baseSlice(arguments, 1)
        done(err, nextargs)
      }]))
    }, function (err, res) {
      cb.apply(that, [err].concat(res))
    })
  }
}

function asyncCompose (/* functions ... */) {
  return asyncSequence.apply(null, [].reverse.call(arguments))
}

function _baseSlice (arr, start) {
  start = start || 0
  var idx = -1
  var len = arr.length

  if (start) {
    len -= start
    len = len < 0 ? 0 : len
  }
  var result = Array(len)
  while (++idx < len) {
    result[idx] = arr[idx + start]
  }
  return result
}

exports.each      = asyncEach
exports.reduce    = asyncReduce
exports.map       = asyncMap
exports.filter    = asyncFilter
exports.reject    = asyncReject
exports.detect    = asyncDetect
exports.every     = asyncEvery
exports.some      = asyncSome
exports.concat    = asyncConcat
exports.times     = asyncTimes
exports.series    = asyncSeries
exports.composite = asyncSequence
exports.compose   = asyncCompose
<|endoftext|>


<commit_before>/**
 * Project Oracle
 * TIE-13106 (TIE-13100) Project Work on Pervasive Systems
 */

var express = require('./node_modules/express');
var routes = require('./routes');
var http = require('http');
var https = require('https');
var path = require('path');
var bodyParser = require('body-parser');

/**
 * Creates server instance
 */
module.exports = function() {
	var app = express();

	/**
	 * Runs the server
	 * @param config
	 */
	function run(config) {

		http.createServer(app).listen(config.port, function(){
			console.log('Express http server listening on port ' + config.port);
		});

		// Start https server for other environments than heroku
		if (process.env.NODE_ENV != 'heroku' && config.useSSL) {
			if (config && config.sslOptions) {
				https.createServer(config.sslOptions, app).listen(config.sslport, function(){
					console.log('Express https server listening on port ' + config.sslport);
				});
			} else {
				throw new Error("Error: SSL options are not defined.");
			}
		}

		if (config.useSSL && config.forcedSSL) {
			if (process.env.NODE_ENV == 'heroku') {
				app.use(function (req, res, next) {
					res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
					if (req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
						return res.redirect(301, 'https://' + req.host + req.url);
					} else {
						return next();
					}
				});
			} else {
				app.use(function (req, res, next) {
				res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
					if (!req.secure) {
						return res.redirect(301, 'https://' + req.hostname  + ":" + app.get('sslport') + req.url);
					} else {
						return next();
					}
				});
			};
		}

		// Envinronment settings
		app.set('views', path.join(__dirname, 'views'));
		app.set('view engine', 'ejs');
		app.use(bodyParser.urlencoded({
		  extended: true
		}))

		routes(app);
	}

	/**
	 * Closes the server
	 */
	function close() {
		app.close();
	}

	return {app: app,
			run: run,
			close: close};
}<commit_msg>Fix SSL port configuration<commit_after>/**
 * Project Oracle
 * TIE-13106 (TIE-13100) Project Work on Pervasive Systems
 */

var express = require('./node_modules/express');
var routes = require('./routes');
var http = require('http');
var https = require('https');
var path = require('path');
var bodyParser = require('body-parser');

/**
 * Creates server instance
 */
module.exports = function() {
	var app = express();

	/**
	 * Runs the server
	 * @param config
	 */
	function run(config) {

		http.createServer(app).listen(config.port, function(){
			console.log('Express http server listening on port ' + config.port);
		});

		// Start https server for other environments than heroku
		if (process.env.NODE_ENV != 'heroku' && config.useSSL) {
			if (config && config.sslOptions) {
				https.createServer(config.sslOptions, app).listen(config.sslport, function(){
					console.log('Express https server listening on port ' + config.sslport);
				});
			} else {
				throw new Error("Error: SSL options are not defined.");
			}
		}

		if (config.useSSL && config.forcedSSL) {
			if (process.env.NODE_ENV == 'heroku') {
				app.use(function (req, res, next) {
					res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
					if (req.headers['x-forwarded-proto'] && req.headers['x-forwarded-proto'] === "http") {
						return res.redirect(301, 'https://' + req.host + req.url);
					} else {
						return next();
					}
				});
			} else {
				app.use(function (req, res, next) {
				res.setHeader('Strict-Transport-Security', 'max-age=8640000; includeSubDomains');
					if (!req.secure) {
						return res.redirect(301, 'https://' + req.hostname  + ":" + config.sslport + req.url);
					} else {
						return next();
					}
				});
			};
		}

		// Envinronment settings
		app.set('views', path.join(__dirname, 'views'));
		app.set('view engine', 'ejs');
		app.use(bodyParser.urlencoded({
		  extended: true
		}))

		routes(app);
	}

	/**
	 * Closes the server
	 */
	function close() {
		app.close();
	}

	return {app: app,
			run: run,
			close: close};
}<|endoftext|>


<commit_before>BX.Collection.Boxes.permit(['update']).apply();
BX.Collection.BoxItems.permit(['remove', 'update']).apply();

// Restrict simple:rest access to only /methods/api* methods.
JsonRoutes.Middleware.use(function (req, res, next) {
  if (req.url.indexOf('/methods/api') === 0) {
    next();
  } else {
    res.end();
  }
});

// Restrict DDP access by IP.
/*
Meteor.onConnection(function (connection) {
  var ip, whitelistIps;
  ip = connection.httpHeaders['x-forwarded-for'];
  whitelistIps = Meteor.settings.private.whitelistIps;
  console.log('Incoming DDP IP: ' + ip);
  if (whitelistIps.indexOf(ip) === -1) {
    connection.close();
  }
});
*/

// Restrict access to all simple:rest routes by IP.
/*
JsonRoutes.Middleware.use(function (req, res, next) {
  var ip, whitelistIps;
  ip = req.headers['x-forwarded-for'];
  whitelistIps = Meteor.settings.private.whitelistIps;
  //console.log('Incoming REST IP: ' + ip);
  if (whitelistIps.indexOf(ip) === -1) {
    res.end();
  } else {
    next();
  }
});
*/

BX.Utility.Security = {
  verifyAccess: function (token, boxId) {
    var hasAccess = false, adminToken, customerToken;
    adminToken =
      CryptoJS.SHA1(Meteor.settings.private.adminTokenSecret).toString();
    if (token && (token === adminToken)) {
      hasAccess = true;
    }
    if (!hasAccess && boxId) {
      customerToken = CryptoJS.SHA1(
        boxId + Meteor.settings.private.customerTokenSecret
      ).toString();
      if (token && (token === customerToken)) {
        hasAccess = true;
      }
    }
    return hasAccess;
  }
};
<commit_msg>Adjustd route restrictions to not catch everything.<commit_after>BX.Collection.Boxes.permit(['update']).apply();
BX.Collection.BoxItems.permit(['remove', 'update']).apply();

// Restrict simple:rest access to only /methods/api* methods.
JsonRoutes.Middleware.use(function (req, res, next) {
  var url = req.url;
  if ((url.indexOf('/methods') === 0)
      || (url.indexOf('/publications') === 0)) {
    if (url.indexOf('/api') > -1) {
      next();
    } else {
      res.end();
    }
  } else {
    next();
  }
});

// Restrict DDP access by IP.
/*
Meteor.onConnection(function (connection) {
  var ip, whitelistIps;
  ip = connection.httpHeaders['x-forwarded-for'];
  whitelistIps = Meteor.settings.private.whitelistIps;
  console.log('Incoming DDP IP: ' + ip);
  if (whitelistIps.indexOf(ip) === -1) {
    connection.close();
  }
});
*/

// Restrict access to all simple:rest routes by IP.
/*
JsonRoutes.Middleware.use(function (req, res, next) {
  var ip, whitelistIps;
  ip = req.headers['x-forwarded-for'];
  whitelistIps = Meteor.settings.private.whitelistIps;
  //console.log('Incoming REST IP: ' + ip);
  if (whitelistIps.indexOf(ip) === -1) {
    res.end();
  } else {
    next();
  }
});
*/

BX.Utility.Security = {
  verifyAccess: function (token, boxId) {
    var hasAccess = false, adminToken, customerToken;
    adminToken =
      CryptoJS.SHA1(Meteor.settings.private.adminTokenSecret).toString();
    if (token && (token === adminToken)) {
      hasAccess = true;
    }
    if (!hasAccess && boxId) {
      customerToken = CryptoJS.SHA1(
        boxId + Meteor.settings.private.customerTokenSecret
      ).toString();
      if (token && (token === customerToken)) {
        hasAccess = true;
      }
    }
    return hasAccess;
  }
};
<|endoftext|>


<commit_before>/**
 * model
 *
 * Defines a model that represents a discrete blob of data.
 *
 * The model should expose a few methods for finding and manipulating unique
 * model instances but should also be able to create and return an instance of
 * a specific model to work with.
 */

var util = require( 'util' ),
    EventEmitter = require( 'EventEmitter3' ),
    Promise = require( 'es6-promise' ).Promise,
    _ = require( 'lodash-node' ),

    ChangeRecord = require( './model/change-record' ).ChangeRecord,
    ChangeRecordCtrl = require( './model/change-record' ).ChangeRecordCtrl;

/**
 * Model Constructor function
 *
 * @param opts {object}
 *    id {String}
 *    schema {Schema} the schema for the model
 */
var Model = module.exports = function( opts ) {

    if ( !opts ) {
        throw new Error( 'Models should be defined by a schema' );
    }

    this.opts = opts;
    this.id = opts.id;
    this._schema = opts.schema;
};

_.extend( Model.prototype, {

    /**
     * The database level instance associated with model.
     *
     * @private
     * @type {Sublevel}
     */
    _db: null,

    /**
     * The schema associated with this model type
     *
     * @private
     * @type {Schema}
     */
    _schema: null,

    /**
     * The separator used to generate index keys
     *
     * @private
     * @type {String}
     */
    _sep: '\xff',

    /**
     * Checks to see if a db has been registered with this model
     *
     * @return {Boolean}
     */
    ready: function() {
        return !!this._db && !!this._schema;
    },

    /**
     * Creates a unique instance of the model
     */
    create: function( opts ) {
        var opts = opts || {};

        if ( !this.ready() ) {
            console.log( 'Model not ready to be created - does it have an associated db and schema?' );
        }

        var model = new ModelInstance({
            schema: this._schema,
            db: this._db,
            sep: this._sep
        });

        return opts.sync ? model : Promise.resolve( model );
    }

});

/**
 * Model Instance Constructor
 *
 * @inherits https://github.com/3rd-Eden/EventEmitter3
 * @param schema {Schema} the schema from which to create the model
 */
var ModelInstance = function( opts ) {

    EventEmitter.call( this );

    this._schema = opts.schema;
    this._sep = opts.sep;
    this.setDB( opts.db );

    // Create the change record object for this instance
    this._changes = new ChangeRecordCtrl();

    // Add each prop from the schema on to the instance
    _.each( opts.schema, function( val, key ) {
        this.addProp( key, val )
    }, this );

}

util.inherits( ModelInstance, EventEmitter );

/**
 * Model Instance Prototype
 */
_.extend( ModelInstance.prototype, {

    /*-----------------------------------------------------------*\
     *
     *  Members
     *
     *-----------------------------------------------------------*/

    /**
     * Pointer to the instance of the db this model is connected to
     */
    _db: null,

    /**
     * Pointer to the instance of the schema associated with the model
     */
    _schema: null,

    /**
     * Manages the change records
     */
    _changes: null,

    /**
     * The separator used to generate index keys
     */
    _sep: '\xff',

    /*-----------------------------------------------------------*\
     *
     *  Methods
     *
    \*-----------------------------------------------------------*/

    /**
     * Accessor function to set the db
     * @param db {LevelDB}
     */
    setDB: function( db ) {
        this._db = db;

        // Set up indices
        this._index = this._db.sublevel( 'INDEX', {
            sync: true
        });
    },

    /**
     * Adds a property to the model
     *
     * @param key {string} object key to set
     * @param def {Object} property definition - should be a schema prop def
     */
    addProp: function( key, def ) {
        var value = def.default || null;

        this.emit( 'add:' + key, value );

        this._changes.push( new ChangeRecord({
            key: key,
            oldValue: null,
            newValue: value,
            index: def.index || false
        }));

        Object.defineProperty( this, key, {
            get: function() {
                return value;
            },

            set: function( val ) {
                // Set a change record
                this._changes.push( new ChangeRecord({
                    key: key,
                    oldValue: value,
                    newValue: val,
                    index: def.index || false
                }));

                value = val;

                // Fire change events
                this.emit( 'change:' + key, value );
                var ret = {};
                ret[ key ] = value;
                this.emit( 'change', ret );
            }
        });
    },

    /**
     * Saves the model to the db.
     * Searches the change records and updates index links to the actual model object,
     * then saves the model based upon its schema.
     *
     * @returns {Promise}
     */
    save: function() {

        var ops = [];    // List of promises waiting to be fulfilled

        // Remove each change record to build the batch request object
        while( this._changes.length() ) {
            var record = this._changes.pop();

            // Insert indexable records
            if ( record.index ) {
                // Remove old record first
                ops.push( this._index.del( this.generateIndexKey( record.key, record.oldValue ), 'uniqueID') );
                ops.push( this._index.put( this.generateIndexKey( record.key, record.newValue ), 'uniqueID') );
            }
        }

        // Now put the saveable props as a json block
        ops.push( this._db.put( 'uniqueID', this.generateSaveItem() ) );

        return Promise.all( ops );
    },

    /*-----------------------------------------------------------*\
     *
     *  Helpers
     *
     *-----------------------------------------------------------*/

    /**
     * Adds separators and builds index keys.
     *
     * @param key {String} property key
     * @param value {String} property value
     * @return {String} the key to use as an index
     */
    generateIndexKey: function( key, value ) {
        return key + this._sep + value;
    },

    /**
     * Creates a saveable representation of the object, based upon the schema.
     *
     * @return {Object}
     */
    generateSaveItem: function() {
        var saveItem = {};

        _.each( this._schema, function( value, key ) {
            // Dont save silent schema props
            if ( value.silent ) {
                return;
            }

            saveItem[ key ] = this[ key ];
        }, this );

        return saveItem;
    }

});
<commit_msg>#update - api comments<commit_after>/**
 * model
 *
 * Defines a model that represents a discrete blob of data.
 *
 * The model should expose a few methods for finding and manipulating unique
 * model instances but should also be able to create and return an instance of
 * a specific model to work with.
 */

var util = require( 'util' ),
    EventEmitter = require( 'EventEmitter3' ),
    Promise = require( 'es6-promise' ).Promise,
    _ = require( 'lodash-node' ),

    ChangeRecord = require( './model/change-record' ).ChangeRecord,
    ChangeRecordCtrl = require( './model/change-record' ).ChangeRecordCtrl;

/**
 * Model Constructor function
 *
 * @param opts {object}
 *    id {String}
 *    schema {Schema} the schema for the model
 */
var Model = module.exports = function( opts ) {

    if ( !opts ) {
        throw new Error( 'Models should be defined by a schema' );
    }

    this.opts = opts;
    this.id = opts.id;
    this._schema = opts.schema;
};

_.extend( Model.prototype, {

    /**
     * The database level instance associated with model.
     *
     * @private
     * @type {Sublevel}
     */
    _db: null,

    /**
     * The schema associated with this model type
     *
     * @private
     * @type {Schema}
     */
    _schema: null,

    /**
     * The separator used to generate index keys
     *
     * @private
     * @type {String}
     */
    _sep: '\xff',

    /**
     * Checks to see if a db has been registered with this model
     *
     * @return {Boolean}
     */
    ready: function() {
        return !!this._db && !!this._schema;
    },

    /**
     * Creates a unique instance of the model
     */
    create: function( opts ) {
        var opts = opts || {};

        if ( !this.ready() ) {
            console.log( 'Model not ready to be created - does it have an associated db and schema?' );
        }

        var model = new ModelInstance({
            schema: this._schema,
            db: this._db,
            sep: this._sep
        });

        return opts.sync ? model : Promise.resolve( model );
    }

});

/**
 * Model Instance Constructor
 *
 * @inherits https://github.com/3rd-Eden/EventEmitter3
 * @param schema {Schema} the schema from which to create the model
 */
var ModelInstance = function( opts ) {

    EventEmitter.call( this );

    this._schema = opts.schema;
    this._sep = opts.sep;
    this.setDB( opts.db );

    // Create the change record object for this instance
    this._changes = new ChangeRecordCtrl();

    // Add each prop from the schema on to the instance
    _.each( opts.schema, function( val, key ) {
        this.addProp( key, val )
    }, this );

}

util.inherits( ModelInstance, EventEmitter );

/**
 * Model Instance Prototype
 */
_.extend( ModelInstance.prototype, {

    /*-----------------------------------------------------------*\
     *
     *  Members
     *
     *-----------------------------------------------------------*/

    /**
     * Pointer to the instance of the db this model is connected to
     *
     * @private
     * @type {LevelDB}
     */
    _db: null,

    /**
     * Pointer to the instance of the schema associated with the model
     *
     * @private
     * @type {Schema}
     */
    _schema: null,

    /**
     * Manages the change records
     *
     * @private
     * @type {ChangeRecordCtrl}
     */
    _changes: null,

    /**
     * The separator used to generate index keys
     *
     * @private
     * @type {char}
     */
    _sep: '\xff',

    /*-----------------------------------------------------------*\
     *
     *  Methods
     *
    \*-----------------------------------------------------------*/

    /**
     * Accessor function to set the db
     * @param db {LevelDB}
     */
    setDB: function( db ) {
        this._db = db;

        // Set up indices
        this._index = this._db.sublevel( 'INDEX', {
            sync: true
        });
    },

    /**
     * Adds a property to the model
     *
     * @param key {string} object key to set
     * @param def {Object} property definition - should be a schema prop def
     */
    addProp: function( key, def ) {
        var value = def.default || null;

        this.emit( 'add:' + key, value );

        this._changes.push( new ChangeRecord({
            key: key,
            oldValue: null,
            newValue: value,
            index: def.index || false
        }));

        Object.defineProperty( this, key, {
            get: function() {
                return value;
            },

            set: function( val ) {
                // Set a change record
                this._changes.push( new ChangeRecord({
                    key: key,
                    oldValue: value,
                    newValue: val,
                    index: def.index || false
                }));

                value = val;

                // Fire change events
                this.emit( 'change:' + key, value );
                var ret = {};
                ret[ key ] = value;
                this.emit( 'change', ret );
            }
        });
    },

    /**
     * Saves the model to the db.
     * Searches the change records and updates index links to the actual model object,
     * then saves the model based upon its schema.
     *
     * @returns {Promise}
     */
    save: function() {

        var ops = [];    // List of promises waiting to be fulfilled

        // Remove each change record to build the batch request object
        while( this._changes.length() ) {
            var record = this._changes.pop();

            // Insert indexable records
            if ( record.index ) {
                // Remove old record first
                ops.push( this._index.del( this.generateIndexKey( record.key, record.oldValue ), 'uniqueID') );
                ops.push( this._index.put( this.generateIndexKey( record.key, record.newValue ), 'uniqueID') );
            }
        }

        // Now put the saveable props as a json block
        ops.push( this._db.put( 'uniqueID', this.generateSaveItem() ) );

        return Promise.all( ops );
    },

    /*-----------------------------------------------------------*\
     *
     *  Helpers
     *
     *-----------------------------------------------------------*/

    /**
     * Adds separators and builds index keys.
     *
     * @param key {String} property key
     * @param value {String} property value
     * @return {String} the key to use as an index
     */
    generateIndexKey: function( key, value ) {
        return key + this._sep + value;
    },

    /**
     * Creates a saveable representation of the object, based upon the schema.
     *
     * @return {Object}
     */
    generateSaveItem: function() {
        var saveItem = {};

        _.each( this._schema, function( value, key ) {
            // Dont save silent schema props
            if ( value.silent ) {
                return;
            }

            saveItem[ key ] = this[ key ];
        }, this );

        return saveItem;
    }

});
<|endoftext|>


<commit_before>//////////////////////////////////////////////////
// MISSKEY-WEB BUILDER
//////////////////////////////////////////////////

'use strict';

Error.stackTraceLimit = Infinity;

const fs = require('fs');
const gulp = require('gulp');
const gutil = require('gulp-util');
const glob = require('glob');
const del = require('del');
const ts = require('gulp-typescript');
const tslint = require('gulp-tslint');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const es = require('event-stream');
const replace = require('gulp-replace');
const stylus = require('gulp-stylus');
const cssnano = require('gulp-cssnano');
const uglify = require('gulp-uglify');
const ls = require('browserify-livescript');
const jadeify = require('jadeify');
const aliasify = require('aliasify');

const env = process.env.NODE_ENV;

const isProduction = env === 'production';

/*
 * Browserifyのモジュールエイリアス
 */
const aliasifyConfig = {
	"aliases": {
		"config": "./built/_/config.json",
		"jquery": "./bower_components/jquery/dist/jquery.js",
		"jquery.transit": "./bower_components/jquery.transit/jquery.transit.js",
		"cropper": "./bower_components/cropper/dist/cropper.js",
		"moment": "./bower_components/moment/moment.js",
		"Sortable": "./bower_components/Sortable/Sortable.js",
		"fastclick": "./bower_components/fastclick/lib/fastclick.js",
		"fuck-adblock": "./bower_components/fuck-adblock/fuckadblock.js",
		"Swiper": "./bower_components/Swiper/dist/js/swiper.js"
	},
	appliesTo: {
		"includeExtensions": ['.js', '.ls']
	}
};

const project = ts.createProject('tsconfig.json', {
	typescript: require('typescript')
});

const config = require('./built/config').default;

//////////////////////////////////////////////////
// Full build
gulp.task('build', [
	'lobby',
	'test',
	'build:ts',
	'copy:bower_components',
	'build:frontside-scripts',
	'build:frontside-styles',
	'build-copy'
], () => {
	gutil.log('ビルドが終了しました。');

	if (!isProduction) {
		gutil.log('■　注意！　開発モードでのビルドです。');
	}
});

//////////////////////////////////////////////////
// LOG INFO
gulp.task('lobby', () => {
	gutil.log('Misskey-Webのビルドを開始します。時間がかかる場合があります。');
	gutil.log('ENV: ' + env);
});

//////////////////////////////////////////////////
// TypeScriptのビルド
gulp.task('build:ts', () => {
	gutil.log('TypeScriptをコンパイルします...');

	return project
		.src()
		.pipe(ts(project))
		.pipe(gulp.dest('./built/'));
});

//////////////////////////////////////////////////
// configのデプロイ
gulp.task('build:public-config', ['build:ts'], done => {
	gutil.log('設定情報を配置します...');

	fs.mkdir('./built/_', e => {
		if (!e || (e && e.code === 'EEXIST')) {
			fs.writeFile('./built/_/config.json', JSON.stringify(config), done);
		} else {
			console.error(e);
		}
	});
});

//////////////////////////////////////////////////
// Bowerのパッケージのコピー
gulp.task('copy:bower_components', () => {
	gutil.log('Bower経由のパッケージを配置します...');

	return gulp.src('./bower_components/**/*')
		.pipe(gulp.dest('./built/resources/bower_components/'));
});

//////////////////////////////////////////////////
// フロントサイドのスクリプトのビルド
gulp.task('build:frontside-scripts', ['build:public-config'], done => {
	gutil.log('フロントサイドのスクリプトを構築します...');

	glob('./src/web/**/*.ls', (err, files) => {
		const tasks = files.map(entry => {
			let bundle =
				browserify({
					entries: [entry]
				})
				.transform(ls)
				.transform(aliasify, aliasifyConfig)
				.transform(jadeify, {
					"compileDebug": false,
					"pretty": false
				})
				.bundle()
				.pipe(source(entry.replace('src/web', 'resources').replace('.ls', '.js')));

			if (isProduction) {
				bundle = bundle
					.pipe(buffer())
					.pipe(uglify());
			}

			return bundle
				.pipe(gulp.dest('./built'));
		});

		es.merge(tasks).on('end', done);
	});
});

//////////////////////////////////////////////////
// フロントサイドのスタイルのビルド
gulp.task('build:frontside-styles', ['copy:bower_components'], () => {
	gutil.log('フロントサイドのスタイルを構築します...');

	return gulp.src('./src/web/**/*.styl')
		.pipe(replace(/url\("#/g, 'url\("' + config.urls.resources))
		.pipe(stylus())
		.pipe(isProduction
			? cssnano({
				safe: true // 高度な圧縮は無効にする (一部デザインが不適切になる場合があるため)
			})
			: gutil.noop())
		.pipe(gulp.dest('./built/resources/'));
});

//////////////////////////////////////////////////
// その他のリソースのコピー
gulp.task('build-copy', [
	'build:ts',
	'build:frontside-scripts',
	'build:frontside-styles'
], () => {
	gutil.log('必要なリソースをコピーします...');

	return es.merge(
		gulp.src([
			'./src/web/**/*.styl',
			'./src/web/**/*.ts',
			'./src/web/**/*.jade'
		]).pipe(gulp.dest('./built/web/')),
		gulp.src('./src/resources/**/*').pipe(gulp.dest('./built/resources/')),
		gulp.src('./src/locales/**/*').pipe(gulp.dest('./built/locales/')),
		gulp.src([
			'./src/web/**/*',
			'!./src/web/**/*.js',
			'!./src/web/**/*.ts',
			'!./src/web/**/*.ls'
		]).pipe(gulp.dest('./built/resources/'))
	);
});

//////////////////////////////////////////////////
// テスト
gulp.task('test', [
	'lint'
]);

//////////////////////////////////////////////////
// Lint
gulp.task('lint', () => {
	gutil.log('構文の正当性を確認します...');

	return gulp.src('./src/**/*.ts')
		.pipe(tslint({
			tslint: require('tslint')
		}))
		.pipe(tslint.report('verbose'));
});

//////////////////////////////////////////////////
// CLEAN
gulp.task('clean', cb => {
	del([
		'./node_modules',
		'./typings',
		'./built',
		'./tmp'
	], cb);
});
<commit_msg>Add clean-build task<commit_after>//////////////////////////////////////////////////
// MISSKEY-WEB BUILDER
//////////////////////////////////////////////////

'use strict';

Error.stackTraceLimit = Infinity;

const fs = require('fs');
const gulp = require('gulp');
const gutil = require('gulp-util');
const glob = require('glob');
const del = require('del');
const ts = require('gulp-typescript');
const tslint = require('gulp-tslint');
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const es = require('event-stream');
const replace = require('gulp-replace');
const stylus = require('gulp-stylus');
const cssnano = require('gulp-cssnano');
const uglify = require('gulp-uglify');
const ls = require('browserify-livescript');
const jadeify = require('jadeify');
const aliasify = require('aliasify');

const env = process.env.NODE_ENV;

const isProduction = env === 'production';

/*
 * Browserifyのモジュールエイリアス
 */
const aliasifyConfig = {
	"aliases": {
		"config": "./built/_/config.json",
		"jquery": "./bower_components/jquery/dist/jquery.js",
		"jquery.transit": "./bower_components/jquery.transit/jquery.transit.js",
		"cropper": "./bower_components/cropper/dist/cropper.js",
		"moment": "./bower_components/moment/moment.js",
		"Sortable": "./bower_components/Sortable/Sortable.js",
		"fastclick": "./bower_components/fastclick/lib/fastclick.js",
		"fuck-adblock": "./bower_components/fuck-adblock/fuckadblock.js",
		"Swiper": "./bower_components/Swiper/dist/js/swiper.js"
	},
	appliesTo: {
		"includeExtensions": ['.js', '.ls']
	}
};

const project = ts.createProject('tsconfig.json', {
	typescript: require('typescript')
});

const config = require('./built/config').default;

//////////////////////////////////////////////////
// Full build
gulp.task('build', [
	'build-before',
	'test',
	'build:ts',
	'copy:bower_components',
	'build:frontside-scripts',
	'build:frontside-styles',
	'build-copy',
	'build-after'
]);

gulp.task('clean-build', [
	'clean',
	'build'
]);

//////////////////////////////////////////////////
// LOG INFO
gulp.task('build-before', () => {
	gutil.log('Misskey-Webのビルドを開始します。時間がかかる場合があります。');
	gutil.log('ENV: ' + env);
});

gulp.task('build-after', () => {
	gutil.log('ビルドが終了しました。');

	if (!isProduction) {
		gutil.log('■　注意！　開発モードでのビルドです。');
	}
});

//////////////////////////////////////////////////
// TypeScriptのビルド
gulp.task('build:ts', () => {
	gutil.log('TypeScriptをコンパイルします...');

	return project
		.src()
		.pipe(ts(project))
		.pipe(gulp.dest('./built/'));
});

//////////////////////////////////////////////////
// configのデプロイ
gulp.task('build:public-config', ['build:ts'], done => {
	gutil.log('設定情報を配置します...');

	fs.mkdir('./built/_', e => {
		if (!e || (e && e.code === 'EEXIST')) {
			fs.writeFile('./built/_/config.json', JSON.stringify(config), done);
		} else {
			console.error(e);
		}
	});
});

//////////////////////////////////////////////////
// Bowerのパッケージのコピー
gulp.task('copy:bower_components', () => {
	gutil.log('Bower経由のパッケージを配置します...');

	return gulp.src('./bower_components/**/*')
		.pipe(gulp.dest('./built/resources/bower_components/'));
});

//////////////////////////////////////////////////
// フロントサイドのスクリプトのビルド
gulp.task('build:frontside-scripts', ['build:public-config'], done => {
	gutil.log('フロントサイドのスクリプトを構築します...');

	glob('./src/web/**/*.ls', (err, files) => {
		const tasks = files.map(entry => {
			let bundle =
				browserify({
					entries: [entry]
				})
				.transform(ls)
				.transform(aliasify, aliasifyConfig)
				.transform(jadeify, {
					"compileDebug": false,
					"pretty": false
				})
				.bundle()
				.pipe(source(entry.replace('src/web', 'resources').replace('.ls', '.js')));

			if (isProduction) {
				bundle = bundle
					.pipe(buffer())
					.pipe(uglify());
			}

			return bundle
				.pipe(gulp.dest('./built'));
		});

		es.merge(tasks).on('end', done);
	});
});

//////////////////////////////////////////////////
// フロントサイドのスタイルのビルド
gulp.task('build:frontside-styles', ['copy:bower_components'], () => {
	gutil.log('フロントサイドのスタイルを構築します...');

	return gulp.src('./src/web/**/*.styl')
		.pipe(replace(/url\("#/g, 'url\("' + config.urls.resources))
		.pipe(stylus())
		.pipe(isProduction
			? cssnano({
				safe: true // 高度な圧縮は無効にする (一部デザインが不適切になる場合があるため)
			})
			: gutil.noop())
		.pipe(gulp.dest('./built/resources/'));
});

//////////////////////////////////////////////////
// その他のリソースのコピー
gulp.task('build-copy', [
	'build:ts',
	'build:frontside-scripts',
	'build:frontside-styles'
], () => {
	gutil.log('必要なリソースをコピーします...');

	return es.merge(
		gulp.src([
			'./src/web/**/*.styl',
			'./src/web/**/*.ts',
			'./src/web/**/*.jade'
		]).pipe(gulp.dest('./built/web/')),
		gulp.src('./src/resources/**/*').pipe(gulp.dest('./built/resources/')),
		gulp.src('./src/locales/**/*').pipe(gulp.dest('./built/locales/')),
		gulp.src([
			'./src/web/**/*',
			'!./src/web/**/*.js',
			'!./src/web/**/*.ts',
			'!./src/web/**/*.ls'
		]).pipe(gulp.dest('./built/resources/'))
	);
});

//////////////////////////////////////////////////
// テスト
gulp.task('test', [
	'lint'
]);

//////////////////////////////////////////////////
// Lint
gulp.task('lint', () => {
	gutil.log('構文の正当性を確認します...');

	return gulp.src('./src/**/*.ts')
		.pipe(tslint({
			tslint: require('tslint')
		}))
		.pipe(tslint.report('verbose'));
});

//////////////////////////////////////////////////
// CLEAN
gulp.task('clean', cb => {
	del([
		'./node_modules',
		'./typings',
		'./built',
		'./tmp'
	], cb);
});
<|endoftext|>


<commit_before>/**
 * タスク設定ファイル
 */

var fs = require("fs");
module.exports = {
    APP_PATH: 'app',
    debug: true,
    useAngular: true,
    flatten: false,
    // AutoPrefixer
    autoprefixer: {
        browser: ['last 3 version', 'ie >= 8', 'Android 4.0']
    },
    // SpriteSmith
    sprite: {
        extension: '.png',
        imgExtension: '.png',
        cssExtension: '.scss',
        // SpriteSmithの設定
        options: {
            cssTemplate: './templates/sprite-template.mustache',
            algorithm: 'binary-tree',
            padding: 5
        }
    },
    // FrontNote
    styleguide: {
        // 読み込むCSSのパス
        css: '../assets/css/style.css',
        // 読み込むJSのパス
        script: '../js/min/main.js'
    },
    // SVGスプライト
    iconfont: {
        template: './templates/iconfont-template.ejs',
        fontName: 'iconfont',
        fontPath: '../fonts/',
        className: 'glyph',
        classPrefix: 'glyph-',
        baseName: '_glyph'
    },
    // パス設定
    path: {
        // SASS
        sass: {
            src: 'source/sass/**/*.scss',
            dest: 'assets/css'
        },
        // HTML Lint
        html: {
            src: ['**/*.html','!styleguide/**/*.html']
        },
        // EJS
        ejs: {
            src: ['source/**/*.ejs','!source/**/_*.ejs'],
            watch: ['source/**/*.ejs'],
            dest: './'
        },
        // SpriteSmith
        sprite: {
            src: 'source/sprites/*',
            watch: 'source/sprites/**/*',
            imgDest: 'assets/images',
            cssDest: 'source/sass/sprites',
            imgPath: '../images'
        },
        // JS Hint
        js: {
            src: ['source/js/*.js','!source/js/_*.js'],
            dest: 'assets/js'
        },
        // Image min
        images: {
            src: 'source/images/**/*',
            dest: 'assets/images'
        },
        iconfont: {
            src: 'source/svg/**/*.svg',
            css: 'source/sass/sprites',
            dest: 'assets/fonts'
        }
    }
};<commit_msg>使用頻度の低いタスクを削除<commit_after>/**
 * タスク設定ファイル
 */

var fs = require("fs");
module.exports = {
    appPath: 'app',
    defaultDir: 'pc',
    // AutoPrefixer
    autoprefixer: {
        browser: ['last 3 version', 'ie >= 8', 'Android 4.0']
    },
    // SpriteSmith
    sprite: {
        extension: '.png',
        imgExtension: '.png',
        cssExtension: '.scss',
        // SpriteSmithの設定
        options: {
            cssTemplate: './templates/sprite-template.mustache',
            algorithm: 'binary-tree',
            padding: 5
        }
    },
    // FrontNote
    styleguide: {
        // 読み込むCSSのパス
        css: '../assets/css/style.css',
        // 読み込むJSのパス
        script: '../js/min/main.js'
    },
    // パス設定
    path: {
        // SASS
        sass: {
            src: 'source/%type%/sass/**/*.scss',
            dest: 'publish/%type%/css'
        },
        // EJS
        ejs: {
            src: ['source/%type%/**/*.ejs','!source/%type%/**/_*.ejs'],
            watch: ['source/%type%/**/*.ejs'],
            dest: 'publish/%type%/'
        },
        // SpriteSmith
        sprite: {
            src: 'source/%type%/sprites/*',
            watch: 'source/%type%/sprites/**/*',
            imgDest: 'source/%type%/images',
            cssDest: 'source/%type%/sass/sprites',
            imgPath: './images'
        },
        // JS Hint
        js: {
            src: ['source/%type%/js/*.js','!source/%type%/js/_*.js'],
            dest: 'publish/%type%/js'
        },
        // Image min
        images: {
            src: 'source/%type%/images/**/*',
            dest: 'publish/%type%/images'
        }
    }
};<|endoftext|>


<commit_before>cucumber = {};

DEBUG = !!process.env.VELOCITY_DEBUG;

(function () {

  'use strict';

  if (process.env.NODE_ENV !== 'development' || process.env.CUCUMBER == '0' ||
    process.env.IS_MIRROR || process.env.VELOCITY == '0') {
    return;
  }

  var path = Npm.require('path'),
      fs = Npm.require('fs'),
      FRAMEWORK_NAME = 'cucumber',
      FRAMEWORK_REGEX = FRAMEWORK_NAME + '/.+\\.(feature|js|coffee|litcoffee|coffee\\.md)$',
      featuresRelativePath = path.join(FRAMEWORK_NAME, 'features'),
      featuresPath = path.join(Velocity.getTestsPath(), featuresRelativePath);

  if (Velocity && Velocity.registerTestingFramework) {
    Velocity.registerTestingFramework(FRAMEWORK_NAME, {
      regex: FRAMEWORK_REGEX,
      sampleTestGenerator: _getSampleTestFiles
    });
  }

  if (!fs.existsSync(featuresPath)) {
    return;
  }

  function _getSampleTestFiles () {
    return [{
      path: path.join(featuresRelativePath, 'sample.feature'),
      contents: Assets.getText(path.join('sample-tests', 'feature.feature'))
    }, {
      path: path.join(featuresRelativePath, 'support', 'hooks.js'),
      contents: Assets.getText(path.join('sample-tests', 'hooks.js'))
    }, {
      path: path.join(featuresRelativePath, 'step_definitions', 'sampleSteps.js'),
      contents: Assets.getText(path.join('sample-tests', 'steps.js'))
    }, {
      path: path.join(featuresRelativePath, 'support', 'world.js'),
      contents: Assets.getText(path.join('sample-tests', 'world.js'))
    }];
  }

  var Module = Npm.require('module');

  Meteor.startup(function () {
    Meteor.call('velocity/mirrors/request', {
      framework: 'cucumber'
    });
    var init = function (mirror) {
      cucumber.mirror = mirror;

      var debouncedRerunCucumber = _.debounce(Meteor.bindEnvironment(_rerunCucumber), 300);

      VelocityTestFiles.find({targetFramework: FRAMEWORK_NAME}).observe({
        added: debouncedRerunCucumber,
        removed: debouncedRerunCucumber,
        changed: debouncedRerunCucumber
      });
    };
    VelocityMirrors.find({framework: 'cucumber', state: 'ready'}).observe({
      added: init,
      changed: init
    });
  });

  function _rerunCucumber (file) {

    console.log('[xolvio:cucumber] Cucumber is running');

    delete Module._cache[file.absolutePath];

    var cuke = Npm.require('cucumber');

    var execOptions = _getExecOptions();
    var configuration = cuke.Cli.Configuration(execOptions),
        runtime = cuke.Runtime(configuration);

    var formatter = new cuke.Listener.JsonFormatter();
    formatter.log = _.once(Meteor.bindEnvironment(function (results) {

      Meteor.call('velocity/reports/reset', {framework: FRAMEWORK_NAME}, function () {
        var features = JSON.parse(results);
        _processFeatures(features);
      });
    }));

    _patchHelpers(cuke, execOptions, configuration);

    runtime.attachListener(formatter);
    runtime.attachListener(configuration.getFormatter());

    runtime.start(Meteor.bindEnvironment(function runtimeFinished () {
      Meteor.call('velocity/reports/completed', {framework: FRAMEWORK_NAME}, function () {
        DEBUG && console.log('[xolvio:cucumber] Completed');
      });
    }));
  }

  function _patchHelpers (cuke, execOptions, configuration) {
    // taken from https://github.com/xdissent/meteor-cucumber/blob/master/src/runner/local.coffee
    var argumentParser = cuke.Cli.ArgumentParser(execOptions);
    argumentParser.parse();
    configuration.getSupportCodeLibrary = function () {
      var supportCodeFilePaths, supportCodeLoader;
      supportCodeFilePaths = argumentParser.getSupportCodeFilePaths();
      supportCodeLoader = cuke.Cli.SupportCodeLoader(supportCodeFilePaths);
      supportCodeLoader._buildSupportCodeInitializerFromPaths = supportCodeLoader.buildSupportCodeInitializerFromPaths;
      supportCodeLoader.buildSupportCodeInitializerFromPaths = function (paths) {
        var wrapper = supportCodeLoader._buildSupportCodeInitializerFromPaths(paths);
        return function () {
          _patchHelper(this);
          return wrapper.call(this);
        };
      };
      return supportCodeLoader.getSupportCodeLibrary();
    };
  }

  function _patchHelper (helper) {

    if (helper._patched != null) {
      return;
    }
    helper._patched = true;

    var steps = [
      'World',
      'Around', 'Before', 'After',
      'defineStep',
      'BeforeStep', 'AfterStep',
      'BeforeScenario', 'AfterScenario',
      'BeforeFeature', 'AfterFeature',
      'BeforeFeatures', 'AfterFeatures'];
    _.each(steps, function (step) {
      DEBUG && console.log('[xolvio:cucumber] Patching', step);
      helper['_' + step] = helper[step];
      helper[step] = function () {
        var args = Array.prototype.splice.call(arguments, 0);
        var callback = args.pop();
        args.push(Meteor.bindEnvironment(callback));
        helper['_' + step].apply(helper, args);
      }
    });
    // Given, When, Then
    helper.Given = helper.When = helper.Then = helper.defineStep;

    // What about these?
    // registerListener
    // registerHandler
    // StepResult
    // Background

  }

  function _processFeatures (features) {
    _.each(features, function (feature) {
      _processFeature(feature);
    });
  }

  function _processFeature (feature) {
    _.each(feature.elements, function (element) {
      _processFeatureElements(element, feature);
    });
  }

  function _processFeatureElements (element, feature) {
    _.each(element.steps, function (step) {
      _processStep(element, step, feature);
    });
  }

  function _processStep (element, step, feature) {

    var report = {
      id: element.id + step.keyword + step.name,
      framework: FRAMEWORK_NAME,
      name: step.keyword + step.name,
      result: step.result.status,
      ancestors: [element.name, feature.name]
    };
    if (step.result.duration) {
      report.duration = Math.round(step.result.duration / 1000000);
    }
    if (step.result.error_message) {
      if (step.result.error_message.name) {
        report.failureType = step.result.error_message.name;
        // TODO extract message
        //report.failureMessage = step.result.error_message.message;
        // TODO extract problem
        // TODO extract callstack
        report.failureStackTrace = step.result.error_message.message;
      } else {
        report.failureStackTrace = step.result.error_message;
      }
    }

    // skip before/after if they have no errors
    if (!report.failureStackTrace && (step.keyword.trim() === 'Before' || step.keyword.trim() === 'After')) {
      return;
    }

    Meteor.call('velocity/reports/submit', report);
    // Unused fields:
    // browser
    // timestamp
  }

  function _getExecOptions () {

    // TODO externalize these options
    var options = {
      files: [featuresPath],
      //steps: path.join(featuresPath, 'step_definitions'),
      tags: [],
      format: 'progress' // 'summary' 'json' 'pretty' 'progress'
    };

    var execOptions = ['node', 'node_modules/.bin/cucumber-js'];

    if (!_.isEmpty(options.files)) {
      execOptions = execOptions.concat(options.files);
    }

    if (!_.isEmpty(options.steps)) {
      execOptions.push('--require');
      execOptions.push(options.steps);
    }

    if (!_.isEmpty(options.tags)) {
      execOptions.push('--tags');
      execOptions.push(options.tags);
    }

    if (!_.isEmpty(options.format)) {
      execOptions.push('--format');
      execOptions.push(options.format);
    }
    return execOptions;
  }

})();
<commit_msg>Fixes #31<commit_after>cucumber = {};

DEBUG = !!process.env.VELOCITY_DEBUG;

(function () {

  'use strict';

  if (process.env.NODE_ENV !== 'development' || process.env.CUCUMBER == '0' ||
    process.env.IS_MIRROR || process.env.VELOCITY == '0') {
    return;
  }

  var path = Npm.require('path'),
      fs = Npm.require('fs'),
      FRAMEWORK_NAME = 'cucumber',
      FRAMEWORK_REGEX = FRAMEWORK_NAME + '/.+\\.(feature|js|coffee|litcoffee|coffee\\.md)$',
      featuresRelativePath = path.join(FRAMEWORK_NAME, 'features'),
      featuresPath = path.join(Velocity.getTestsPath(), featuresRelativePath);

  if (Velocity && Velocity.registerTestingFramework) {
    Velocity.registerTestingFramework(FRAMEWORK_NAME, {
      regex: FRAMEWORK_REGEX,
      sampleTestGenerator: _getSampleTestFiles
    });
  }

  if (!fs.existsSync(featuresPath)) {
    return;
  }

  function _getSampleTestFiles () {
    return [{
      path: path.join(featuresRelativePath, 'sample.feature'),
      contents: Assets.getText(path.join('sample-tests', 'feature.feature'))
    }, {
      path: path.join(featuresRelativePath, 'support', 'hooks.js'),
      contents: Assets.getText(path.join('sample-tests', 'hooks.js'))
    }, {
      path: path.join(featuresRelativePath, 'step_definitions', 'sampleSteps.js'),
      contents: Assets.getText(path.join('sample-tests', 'steps.js'))
    }, {
      path: path.join(featuresRelativePath, 'support', 'world.js'),
      contents: Assets.getText(path.join('sample-tests', 'world.js'))
    }];
  }

  var Module = Npm.require('module');

  Meteor.startup(function () {
    Meteor.call('velocity/mirrors/request', {
      framework: 'cucumber'
    });
    var init = function (mirror) {
      cucumber.mirror = mirror;

      var debouncedRerunCucumber = _.debounce(Meteor.bindEnvironment(_rerunCucumber), 300);

      VelocityTestFiles.find({targetFramework: FRAMEWORK_NAME}).observe({
        added: debouncedRerunCucumber,
        removed: debouncedRerunCucumber,
        changed: debouncedRerunCucumber
      });

      process.on('SIGUSR2', Meteor.bindEnvironment(function () {
        DEBUG && console.log('[xolvio:cucumber] Client restart detected');
        debouncedRerunCucumber();
      }));

    };

    var initOnce = _.once(Meteor.bindEnvironment(init));
    VelocityMirrors.find({framework: 'cucumber', state: 'ready'}).observe({
      added: initOnce,
      changed: initOnce
    });
  });

  function _rerunCucumber (file) {

    console.log('[xolvio:cucumber] Cucumber is running');

    if (file) {
      delete Module._cache[file.absolutePath];
    }

    var cuke = Npm.require('cucumber');

    var execOptions = _getExecOptions();
    var configuration = cuke.Cli.Configuration(execOptions),
        runtime = cuke.Runtime(configuration);

    var formatter = new cuke.Listener.JsonFormatter();
    formatter.log = _.once(Meteor.bindEnvironment(function (results) {

      Meteor.call('velocity/reports/reset', {framework: FRAMEWORK_NAME}, function () {
        var features = JSON.parse(results);
        _processFeatures(features);
      });
    }));

    _patchHelpers(cuke, execOptions, configuration);

    runtime.attachListener(formatter);
    runtime.attachListener(configuration.getFormatter());

    runtime.start(Meteor.bindEnvironment(function runtimeFinished () {
      Meteor.call('velocity/reports/completed', {framework: FRAMEWORK_NAME}, function () {
        DEBUG && console.log('[xolvio:cucumber] Completed');
      });
    }));
  }

  function _patchHelpers (cuke, execOptions, configuration) {
    // taken from https://github.com/xdissent/meteor-cucumber/blob/master/src/runner/local.coffee
    var argumentParser = cuke.Cli.ArgumentParser(execOptions);
    argumentParser.parse();
    configuration.getSupportCodeLibrary = function () {
      var supportCodeFilePaths, supportCodeLoader;
      supportCodeFilePaths = argumentParser.getSupportCodeFilePaths();
      supportCodeLoader = cuke.Cli.SupportCodeLoader(supportCodeFilePaths);
      supportCodeLoader._buildSupportCodeInitializerFromPaths = supportCodeLoader.buildSupportCodeInitializerFromPaths;
      supportCodeLoader.buildSupportCodeInitializerFromPaths = function (paths) {
        var wrapper = supportCodeLoader._buildSupportCodeInitializerFromPaths(paths);
        return function () {
          _patchHelper(this);
          return wrapper.call(this);
        };
      };
      return supportCodeLoader.getSupportCodeLibrary();
    };
  }

  function _patchHelper (helper) {

    if (helper._patched != null) {
      return;
    }
    helper._patched = true;

    var steps = [
      'World',
      'Around', 'Before', 'After',
      'defineStep',
      'BeforeStep', 'AfterStep',
      'BeforeScenario', 'AfterScenario',
      'BeforeFeature', 'AfterFeature',
      'BeforeFeatures', 'AfterFeatures'];
    _.each(steps, function (step) {
      DEBUG && console.log('[xolvio:cucumber] Patching', step);
      helper['_' + step] = helper[step];
      helper[step] = function () {
        var args = Array.prototype.splice.call(arguments, 0);
        var callback = args.pop();
        args.push(Meteor.bindEnvironment(callback));
        helper['_' + step].apply(helper, args);
      }
    });
    // Given, When, Then
    helper.Given = helper.When = helper.Then = helper.defineStep;

    // What about these?
    // registerListener
    // registerHandler
    // StepResult
    // Background

  }

  function _processFeatures (features) {
    _.each(features, function (feature) {
      _processFeature(feature);
    });
  }

  function _processFeature (feature) {
    _.each(feature.elements, function (element) {
      _processFeatureElements(element, feature);
    });
  }

  function _processFeatureElements (element, feature) {
    _.each(element.steps, function (step) {
      _processStep(element, step, feature);
    });
  }

  function _processStep (element, step, feature) {

    var report = {
      id: element.id + step.keyword + step.name,
      framework: FRAMEWORK_NAME,
      name: step.keyword + step.name,
      result: step.result.status,
      ancestors: [element.name, feature.name]
    };
    if (step.result.duration) {
      report.duration = Math.round(step.result.duration / 1000000);
    }
    if (step.result.error_message) {
      if (step.result.error_message.name) {
        report.failureType = step.result.error_message.name;
        // TODO extract message
        //report.failureMessage = step.result.error_message.message;
        // TODO extract problem
        // TODO extract callstack
        report.failureStackTrace = step.result.error_message.message;
      } else {
        report.failureStackTrace = step.result.error_message;
      }
    }

    // skip before/after if they have no errors
    if (!report.failureStackTrace && (step.keyword.trim() === 'Before' || step.keyword.trim() === 'After')) {
      return;
    }

    Meteor.call('velocity/reports/submit', report);
    // Unused fields:
    // browser
    // timestamp
  }

  function _getExecOptions () {

    // TODO externalize these options
    var options = {
      files: [featuresPath],
      //steps: path.join(featuresPath, 'step_definitions'),
      tags: [],
      format: 'progress' // 'summary' 'json' 'pretty' 'progress'
    };

    var execOptions = ['node', 'node_modules/.bin/cucumber-js'];

    if (!_.isEmpty(options.files)) {
      execOptions = execOptions.concat(options.files);
    }

    if (!_.isEmpty(options.steps)) {
      execOptions.push('--require');
      execOptions.push(options.steps);
    }

    if (!_.isEmpty(options.tags)) {
      execOptions.push('--tags');
      execOptions.push(options.tags);
    }

    if (!_.isEmpty(options.format)) {
      execOptions.push('--format');
      execOptions.push(options.format);
    }
    return execOptions;
  }

})();
<|endoftext|>


<commit_before>/**
 * Socket.io configuration
 */

'use strict';

var config = require('./environment');

// When the user disconnects.. perform this
function onDisconnect(socket) {
}

// When the user connects.. perform this
function onConnect(socket) {
  // When the client emits 'info', this listens and executes
  socket.on('info', function (data) {
    console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
  });

  // Insert sockets below
  require('../api/query/query.socket').register(socket);
  //require('../api/thing/thing.socket').register(socket);
}

module.exports = function (socketio) {
  // socket.io (v1.x.x) is powered by debug.
  // In order to see all the debug output, set DEBUG (in server/config/local.env.js) to including the desired scope.
  //
  // ex: DEBUG: "http*,socket.io:socket"

  // We can authenticate socket.io users and access their token through socket.handshake.decoded_token
  //
  // 1. You will need to send the token in `client/components/socket/socket.service.js`
  //
  // 2. Require authentication here:
  // socketio.use(require('socketio-jwt').authorize({
  //   secret: config.secrets.session,
  //   handshake: true
  // }));

  socketio.on('connection', function (socket) {
    socket.address = socket.handshake.address !== null ?
            socket.handshake.address.address + ':' + socket.handshake.address.port :
            process.env.DOMAIN;

    socket.connectedAt = new Date();

    // Call onDisconnect.
    socket.on('disconnect', function () {
      onDisconnect(socket);
      console.info('[%s] DISCONNECTED', socket.address);
    });

    // Call onConnect.
    onConnect(socket);
    console.info('[%s] CONNECTED', socket.address);
  });
};<commit_msg>Remove socket for query collection.<commit_after>/**
 * Socket.io configuration
 */

'use strict';

var config = require('./environment');

// When the user disconnects.. perform this
function onDisconnect(socket) {
}

// When the user connects.. perform this
function onConnect(socket) {
  // When the client emits 'info', this listens and executes
  socket.on('info', function (data) {
    console.info('[%s] %s', socket.address, JSON.stringify(data, null, 2));
  });

  // Insert sockets below
  //require('../api/thing/thing.socket').register(socket);
}

module.exports = function (socketio) {
  // socket.io (v1.x.x) is powered by debug.
  // In order to see all the debug output, set DEBUG (in server/config/local.env.js) to including the desired scope.
  //
  // ex: DEBUG: "http*,socket.io:socket"

  // We can authenticate socket.io users and access their token through socket.handshake.decoded_token
  //
  // 1. You will need to send the token in `client/components/socket/socket.service.js`
  //
  // 2. Require authentication here:
  // socketio.use(require('socketio-jwt').authorize({
  //   secret: config.secrets.session,
  //   handshake: true
  // }));

  socketio.on('connection', function (socket) {
    socket.address = socket.handshake.address !== null ?
            socket.handshake.address.address + ':' + socket.handshake.address.port :
            process.env.DOMAIN;

    socket.connectedAt = new Date();

    // Call onDisconnect.
    socket.on('disconnect', function () {
      onDisconnect(socket);
      console.info('[%s] DISCONNECTED', socket.address);
    });

    // Call onConnect.
    onConnect(socket);
    console.info('[%s] CONNECTED', socket.address);
  });
};<|endoftext|>


<commit_before>'use strict';

var del = require('del');
var gulp = require('gulp');
var browserify = require('gulp-browserify');
var jshint = require('gulp-jshint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var karma = require('karma').server;

var paths = {
  coverage: 'coverage/',
  dist: 'dist/',
  karmaConf: __dirname + '/test/karma.conf.js',
  src: ['index.js'],
  test: ['test/*.spec.js']
};

var defaultTasks = ['clean', 'lint', 'test'];

gulp.task('lint', function() {
  return gulp.src(paths.src.concat(paths.test, paths.karmaConf, __filename))
    .pipe(plumber())
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('clean', function() { // synchronous
  del([paths.coverage, paths.dist]);
});

gulp.task('dist', function() {
  return gulp.src(paths.src, { read: false })
    .pipe(plumber())
    .pipe(browserify({
      debug: true, // generate sourcemap
      insertGlobals: false,
      standalone: 'malarkey'
    }))
    .pipe(rename({ basename: 'malarkey' }))
    .pipe(gulp.dest(paths.dist))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest(paths.dist));
});

gulp.task('test', ['dist'], function(done) {
  karma.start({
    configFile: paths.karmaConf,
    singleRun: true
  }, done);
});

gulp.task('watch', defaultTasks, function() {
  gulp.watch(paths.src.concat(paths.test, paths.karmaConf), defaultTasks);
});

gulp.task('default', defaultTasks);
<commit_msg>Refactor gulpfile.js<commit_after>'use strict';

var del = require('del');
var gulp = require('gulp');
var browserify = require('gulp-browserify');
var jshint = require('gulp-jshint');
var plumber = require('gulp-plumber');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var karma = require('karma').server;

var moduleName = 'malarkey';

var paths = {
  coverage: 'coverage/',
  dist: 'dist/',
  karmaConf: __dirname + '/karma.conf.js',
  src: ['index.js'],
  test: ['test/*.spec.js']
};

var defaultTasks = ['lint', 'test'];

gulp.task('lint', function() {
  return gulp.src([].concat(__filename, paths.karmaConf, paths.src, paths.test))
    .pipe(plumber())
    .pipe(jshint())
    .pipe(jshint.reporter('jshint-stylish'));
});

gulp.task('clean', function() { // synchronous
  del([paths.coverage, paths.dist]);
});

gulp.task('dist', ['clean'], function() {
  return gulp.src(paths.src, { read: false })
    .pipe(plumber())
    .pipe(browserify({
      debug: true, // generate sourcemaps
      insertGlobals: false,
      standalone: moduleName
    }))
    .pipe(rename({ basename: moduleName }))
    .pipe(gulp.dest(paths.dist))
    .pipe(rename({ suffix: '.min' }))
    .pipe(uglify())
    .pipe(gulp.dest(paths.dist));
});

gulp.task('test', ['dist'], function(cb) {
  karma.start({
    configFile: paths.karmaConf,
    singleRun: true
  }, cb);
});

gulp.task('watch', defaultTasks, function() {
  gulp.watch([].concat(paths.karmaConf, paths.src, paths.test), defaultTasks);
});

gulp.task('default', defaultTasks);
<|endoftext|>