<commit_before>// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Regression test for Chromium issue 70066.  Delete should work properly
// from inside 'with' scopes.
// http://code.google.com/p/chromium/issues/detail?id=70066

x = 0;

// Delete on a slot from a function's own context.
function test1() {
  var value = 1;
  var status;
  with ({}) { status = delete value; }
  return value + ":" + status;
}

assertEquals("1:false", test1(), "test1");
assertEquals(0, x, "test1");  // Global x is undisturbed.

// Delete on a slot from an outer context.
function test2() {
  function f() {
    with ({}) { return delete value; }
  }
  var value = 2;
  var status = f();
  return value + ":" + status;
}

assertEquals("2:false", test2(), "test2");
assertEquals(0, x, "test2");  // Global x is undisturbed.

// Delete on an argument (should be the same code paths as test1 and test2).
function test3(value) {
  var status;
  with ({}) { status = delete value; }
  return value + ":" + status;
}

assertEquals("3:false", test3(3), "test3");
assertEquals(0, x, "test3");  // Global x is undisturbed.

function test4(value) {
  function f() {
    with ({}) { return delete value; }
  }
  var status = f();
  return value + ":" + status;
}

assertEquals("4:false", test4(4), "test4");
assertEquals(0, x, "test4");  // Global x is undisturbed.

// Delete on an argument found in the arguments object.  Such properties are
// normally DONT_DELETE in JavaScript but deletion is allowed by V8.
function test5(value) {
  var status;
  with ({}) { status = delete value; }
  return arguments[0] + ":" + status;
}

assertEquals("undefined:true", test5(5), "test5");
assertEquals(0, x, "test5");  // Global x is undisturbed.

function test6(value) {
  function f() {
    with ({}) { return delete value; }
  }
  var status = f();
  return arguments[0] + ":" + status;
}

assertEquals("undefined:true", test6(6), "test6");
assertEquals(0, x, "test6");  // Global x is undisturbed.

// Delete on a property found on 'with' object.
function test7(object) {
  with (object) { return delete value; }
}

var o = {value: 7};
assertEquals(true, test7(o), "test7");
assertEquals(void 0, o.value, "test7");
assertEquals(0, x, "test7");  // Global x is undisturbed.

// Delete on a global property.
function test8() {
  with ({}) { return delete x; }
}

assertEquals(true, test8(), "test8");
assertThrows("x", "test8");  // Global x should be deleted.

// Delete on a property that is not found anywhere.
function test9() {
  with ({}) { return delete x; }
}

assertThrows("x", "test9");  // Make sure it's not there.
assertEquals(true, test9(), "test9");

// Delete on a DONT_DELETE property of the global object.
var y = 10;
function test10() {
  with ({}) { return delete y; }
}

assertEquals(false, test10(), "test10");
assertEquals(10, y, "test10");
<commit_msg>Update regression test.<commit_after>// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Regression test for Chromium issue 70066.  Delete should work properly
// from inside 'with' scopes.
// http://code.google.com/p/chromium/issues/detail?id=70066

x = 0;

// Delete on a slot from a function's own context.
function test1() {
  var value = 1;
  var status;
  with ({}) { status = delete value; }
  return value + ":" + status;
}

assertEquals("1:false", test1(), "test1");
assertEquals(0, x, "test1");  // Global x is undisturbed.

// Delete on a slot from an outer context.
function test2() {
  function f() {
    with ({}) { return delete value; }
  }
  var value = 2;
  var status = f();
  return value + ":" + status;
}

assertEquals("2:false", test2(), "test2");
assertEquals(0, x, "test2");  // Global x is undisturbed.

// Delete on an argument.  This hits the same code paths as test5 because
// 'with' forces all parameters to be indirected through the arguments
// object.
function test3(value) {
  var status;
  with ({}) { status = delete value; }
  return value + ":" + status;
}

assertEquals("undefined:true", test3(3), "test3");
assertEquals(0, x, "test3");  // Global x is undisturbed.

// Delete on an argument from an outer context.  This hits the same code
// path as test2.
function test4(value) {
  function f() {
    with ({}) { return delete value; }
  }
  var status = f();
  return value + ":" + status;
}

assertEquals("4:false", test4(4), "test4");
assertEquals(0, x, "test4");  // Global x is undisturbed.

// Delete on an argument found in the arguments object.  Such properties are
// normally DONT_DELETE in JavaScript but deletion is allowed by V8.
function test5(value) {
  var status;
  with ({}) { status = delete value; }
  return arguments[0] + ":" + status;
}

assertEquals("undefined:true", test5(5), "test5");
assertEquals(0, x, "test5");  // Global x is undisturbed.

function test6(value) {
  function f() {
    with ({}) { return delete value; }
  }
  var status = f();
  return arguments[0] + ":" + status;
}

assertEquals("undefined:true", test6(6), "test6");
assertEquals(0, x, "test6");  // Global x is undisturbed.

// Delete on a property found on 'with' object.
function test7(object) {
  with (object) { return delete value; }
}

var o = {value: 7};
assertEquals(true, test7(o), "test7");
assertEquals(void 0, o.value, "test7");
assertEquals(0, x, "test7");  // Global x is undisturbed.

// Delete on a global property.
function test8() {
  with ({}) { return delete x; }
}

assertEquals(true, test8(), "test8");
assertThrows("x", "test8");  // Global x should be deleted.

// Delete on a property that is not found anywhere.
function test9() {
  with ({}) { return delete x; }
}

assertThrows("x", "test9");  // Make sure it's not there.
assertEquals(true, test9(), "test9");

// Delete on a DONT_DELETE property of the global object.
var y = 10;
function test10() {
  with ({}) { return delete y; }
}

assertEquals(false, test10(), "test10");
assertEquals(10, y, "test10");
<|endoftext|>


<commit_before>/* eslint-disable no-var, prefer-arrow-callback, prefer-template, func-names, vars-on-top */
var env = process.env.NODE_ENV || 'development';
var stopOnErrors = ['production', 'build', 'prepublish'].indexOf(env) !== -1 ||
process.env.CI === '1';
var debug = process.env.DEBUG === 1;
module.exports = function (options) {
  var fs = require('fs');
  if (!options) {
    options = {};
  }
  var gulp = options.gulp || require('gulp');
  var babel = require('gulp-babel');
  var istanbul = require('gulp-istanbul');
  var sequence = require('gulp-sequence');
  var newer = require('gulp-newer');
  var spawnMocha = require('gulp-spawn-mocha');
  var inlineMocha = require('gulp-mocha');
  var ts = require('gulp-typescript');
  var clean = require('gulp-clean');
  var sourcemaps = require('gulp-sourcemaps');
  var gulpIf = require('gulp-if');
  var plumber = require('gulp-plumber');
  var notify = require('gulp-notify');
  // var tap = require('gulp-tap');
  var add = require('gulp-add-src');
  // var inspector = require('gulp-node-inspector');
  var filter = require('gulp-filter');

  var nodemon = require('gulp-nodemon');
  var notifier = require('node-notifier');
  var merge = require('merge2');
  var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

  var otherFiles = 'src/**/!(*.js|*.map|*.src|*.ts|*.d.ts)';
  var source = options.source || 'src/**/*.ts';
  var typings = 'typings/index.d.ts';
  var customTypings = 'custom_typings/**/*.d.ts';
  var dest = 'lib';
  var destGlob = dest + '/**/*.*';
  var destGlobJs = dest + '/**/*.js';
  var coveredDest = 'lib_covered';
  var testEndpoint = dest + (options.testEndpoint || '/test/test.js');
  var coveredTestEndpoint = coveredDest + '/test/test.js';
  var startEndpoint = dest + (options.startEndpoint || '/app.js');
  // var modulesGlob = 'node_modules/**/*.*';

  var packageInfo = JSON.parse(fs.readFileSync('package.json', 'utf8'));
  var packageVersion = packageInfo.name + '@' + packageInfo.version;
  var compileErrors = 0;
  var onError = function (errorCallback) {
    return function (err) {
      if (errorCallback) {
        errorCallback();
      }
      notify.onError({
        title: 'Gulp error in ' + err.plugin,
        message: err.toString(),
      })(err);
      this.emit('end');
    };
  };

  var swallowError = function () {
    this.emit('end');
  };

  gulp.task('cleanup', ['cleanup-dest', 'cleanup-covered', 'cleanup-coverage']);
  gulp.task('cleanup-dest', function () {
    return gulp.src(dest, { read: false }).pipe(clean());
  });
  gulp.task('cleanup-coverage', function () {
    return gulp.src('coverage', { read: false }).pipe(clean());
  });
  gulp.task('cleanup-covered', function () {
    return gulp.src(coveredDest, { read: false }).pipe(clean());
  });
  gulp.task('copy-files', function () {
    return gulp.src(otherFiles)
      .pipe(newer(dest))
      // .pipe(tap(function(file) {
      //     console.log('copy', file.path);
      //  }))
      .pipe(gulp.dest(dest))
      .pipe(gulp.dest(coveredDest));
  });
  gulp.task('ts-definitions', function () {
    var tsProject = ts.createProject('tsconfig.json', { declaration: true });
    var tsResult = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: swallowError })))
      .pipe(newer({ dest, ext: '.d.ts' }))
      .pipe(add.prepend(typings))
      .pipe(add.prepend(customTypings))
      .pipe(ts(tsProject));
    return tsResult.dts.pipe(gulp.dest(dest));
  });
  function doJsCompile(covered) {
    compileErrors = 0;
    var checkDest = covered ? coveredDest : dest;
    const noMap = filter('**/!(*.map)', { restore: false });
    // const noTests = filter('**/(!test/**/*.*)', { restore: false });
    var stream = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(() => {
        compileErrors++;
      }) })))
      .pipe(newer({ dest: checkDest, ext: '.js' }))
      .pipe(sourcemaps.init())
      .pipe(babel())
      .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
      .pipe(gulp.dest(dest));
    if (covered) {
      stream = stream
        .pipe(noMap)
        // .pipe(noTests)
        .pipe(istanbul())
        .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
        .pipe(gulp.dest('lib_covered'));
    }
    return stream;
  }
  function doTsCompile(covered) {
    compileErrors = 0;
    var checkDest = covered ? coveredDest : dest;
    var noMap = filter('**/!(*.map)', { restore: false });
    // const noTests = filter('**/(!test/**/*.*)', { restore: false });
    var tsProject = ts.createProject('tsconfig.json', { isolatedModules: true, declaration: false });
    var tsResult = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(() => {
        compileErrors++;
      }) })))
      .pipe(newer({ dest: checkDest, ext: '.js' }))
      .pipe(sourcemaps.init())
      .pipe(add.prepend(typings))
      .pipe(add.prepend(customTypings))
      .pipe(ts(tsProject));
    var babelStream = tsResult.js.pipe(babel())
      .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
      .pipe(gulp.dest(dest));
    if (covered) {
      babelStream = babelStream
        .pipe(noMap)
        // .pipe(noTests)
        .pipe(istanbul())
        .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
        .pipe(gulp.dest('lib_covered'));
    }
    return merge([
      tsResult.dts
        .pipe(gulp.dest(dest)),
      babelStream,
    ]);
  }
  gulp.task('js-compile', ['copy-files'], function () {
    return doJsCompile(false);
  });
  gulp.task('js-compile-covered', ['copy-files'], function () {
    return doJsCompile(true);
  });
  gulp.task('ts-compile', ['copy-files'], function () {
    return doTsCompile(false);
  });
  gulp.task('ts-compile-covered', ['copy-files'], function () {
    return doTsCompile(true);
  });
  gulp.task('remap-istanbul', function () {
    return gulp.src('coverage/coverage-final.json')
    .pipe(remapIstanbul({
      reports: {
        json: 'coverage/coverage.json',
        html: 'coverage/html-report',
      },
    }));
  });
  gulp.task('test', ['do-test']);
  gulp.task('test-covered', function (callback) {
    return sequence(
      // 'pre-test',
      'do-test-covered',
      'remap-istanbul'
      )(callback);
  });
  function doTest(endpoints) {
    var errorHappened = false;
    var mocha;
    if (debug) {
      mocha = spawnMocha({
        debugBrk: true,
        env: { NODE_ENV: 'test' },
      });
    } else {
      mocha = inlineMocha({
        reporter: 'mocha-jenkins-reporter',
        reporterOptions: {
          junit_report_name: packageInfo.name,
          junit_report_path: 'tests-xunit.xml',
          junit_report_stack: 1,
        },
      });
    }
    return gulp.src(endpoints, { read: false })
    .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(function () {
      errorHappened = true;
    }) })))
    .pipe(mocha)
    .pipe(istanbul.writeReports({
      reporters: ['json'],
    }))
    .on('end', function () {
      if (!errorHappened && !compileErrors) {
        notifier.notify(
          { title: 'All tests passed in ' + packageInfo.name, message: 'Write some more' }
        );
      }
    });
  }
  gulp.task('do-test', function () {
    return doTest([testEndpoint]);
  });
  gulp.task('do-test-covered', function () {
    return doTest([coveredTestEndpoint]);
  });
  gulp.task('start', function () {
    nodemon({
      script: startEndpoint,
      watch: [destGlob],
    });
  });
  gulp.task('ts-watch-compile', function () {
    gulp.watch(source, ['ts-compile']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-compile-covered', function () {
    gulp.watch(source, ['ts-compile-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-compile', function () {
    gulp.watch(source, ['js-compile']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-compile-covered', function () {
    gulp.watch(source, ['js-compile-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-test', function () {
    gulp.watch(source, ['ts-compile-and-test']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-test-covered', function () {
    gulp.watch(source, ['ts-compile-and-test-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-test', function () {
    gulp.watch(source, ['js-compile-and-test']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-test-covered', function () {
    gulp.watch(source, ['js-compile-and-test-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-compile-and-test', function (callback) {
    sequence('ts-definitions', 'ts-compile', 'test')(callback);
  });
  gulp.task('ts-compile-and-test-covered', function (callback) {
    sequence('ts-definitions', 'ts-compile-covered', 'test-covered')(callback);
  });
  gulp.task('js-compile-and-test', function (callback) {
    sequence('js-compile', 'test')(callback);
  });
  gulp.task('js-compile-and-test-covered', function (callback) {
    sequence('js-compile-covered', 'test-covered')(callback);
  });
  gulp.task('ts-fresh-compile', function (callback) {
    sequence('cleanup', 'ts-definitions', 'ts-compile')(callback);
  });
  gulp.task('ts-fresh-compile-covered', function (callback) {
    sequence('cleanup', 'ts-definitions', 'ts-compile-covered')(callback);
  });
  gulp.task('js-fresh-compile', function (callback) {
    sequence('cleanup', 'js-compile')(callback);
  });
  gulp.task('js-fresh-compile-covered', function (callback) {
    sequence('cleanup', 'js-compile-covered')(callback);
  });
  gulp.task('ts-run-build', function (callback) {
    sequence('ts-fresh-compile', 'ts-watch-compile')(callback);
  });
  gulp.task('ts-run-build-covered', function (callback) {
    sequence('ts-fresh-compile-covered', 'ts-watch-compile-covered')(callback);
  });
  gulp.task('js-run-build', function (callback) {
    sequence('js-fresh-compile', 'js-watch-compile')(callback);
  });
  gulp.task('js-run-build-covered', function (callback) {
    sequence('js-fresh-compile-covered', 'js-watch-compile-covered')(callback);
  });
  gulp.task('ts-run-test', function (callback) {
    sequence('ts-run-build', 'ts-watch-test', 'test')(callback);
  });
  gulp.task('ts-run-test-covered', function (callback) {
    sequence('ts-run-build-covered', 'ts-watch-test-covered', 'test-covered')(callback);
  });
  gulp.task('js-run-test', function (callback) {
    sequence('js-run-build', 'js-watch-test', 'test')(callback);
  });
  gulp.task('js-run-test-covered', function (callback) {
    sequence('js-run-build-covered', 'js-watch-test-covered', 'test-covered')(callback);
  });
  gulp.task('ts-run', function (callback) {
    sequence('ts-watch-compile', 'start')(callback);
  });
  gulp.task('js-run', function (callback) {
    sequence('js-watch-compile', 'start')(callback);
  });
};
<commit_msg>ensure compile before running<commit_after>/* eslint-disable no-var, prefer-arrow-callback, prefer-template, func-names, vars-on-top */
var env = process.env.NODE_ENV || 'development';
var stopOnErrors = ['production', 'build', 'prepublish'].indexOf(env) !== -1 ||
process.env.CI === '1';
var debug = process.env.DEBUG === 1;
module.exports = function (options) {
  var fs = require('fs');
  if (!options) {
    options = {};
  }
  var gulp = options.gulp || require('gulp');
  var babel = require('gulp-babel');
  var istanbul = require('gulp-istanbul');
  var sequence = require('gulp-sequence');
  var newer = require('gulp-newer');
  var spawnMocha = require('gulp-spawn-mocha');
  var inlineMocha = require('gulp-mocha');
  var ts = require('gulp-typescript');
  var clean = require('gulp-clean');
  var sourcemaps = require('gulp-sourcemaps');
  var gulpIf = require('gulp-if');
  var plumber = require('gulp-plumber');
  var notify = require('gulp-notify');
  // var tap = require('gulp-tap');
  var add = require('gulp-add-src');
  // var inspector = require('gulp-node-inspector');
  var filter = require('gulp-filter');

  var nodemon = require('gulp-nodemon');
  var notifier = require('node-notifier');
  var merge = require('merge2');
  var remapIstanbul = require('remap-istanbul/lib/gulpRemapIstanbul');

  var otherFiles = 'src/**/!(*.js|*.map|*.src|*.ts|*.d.ts)';
  var source = options.source || 'src/**/*.ts';
  var typings = 'typings/index.d.ts';
  var customTypings = 'custom_typings/**/*.d.ts';
  var dest = 'lib';
  var destGlob = dest + '/**/*.*';
  var destGlobJs = dest + '/**/*.js';
  var coveredDest = 'lib_covered';
  var testEndpoint = dest + (options.testEndpoint || '/test/test.js');
  var coveredTestEndpoint = coveredDest + '/test/test.js';
  var startEndpoint = dest + (options.startEndpoint || '/app.js');
  // var modulesGlob = 'node_modules/**/*.*';

  var packageInfo = JSON.parse(fs.readFileSync('package.json', 'utf8'));
  var packageVersion = packageInfo.name + '@' + packageInfo.version;
  var compileErrors = 0;
  var onError = function (errorCallback) {
    return function (err) {
      if (errorCallback) {
        errorCallback();
      }
      notify.onError({
        title: 'Gulp error in ' + err.plugin,
        message: err.toString(),
      })(err);
      this.emit('end');
    };
  };

  var swallowError = function () {
    this.emit('end');
  };

  gulp.task('cleanup', ['cleanup-dest', 'cleanup-covered', 'cleanup-coverage']);
  gulp.task('cleanup-dest', function () {
    return gulp.src(dest, { read: false }).pipe(clean());
  });
  gulp.task('cleanup-coverage', function () {
    return gulp.src('coverage', { read: false }).pipe(clean());
  });
  gulp.task('cleanup-covered', function () {
    return gulp.src(coveredDest, { read: false }).pipe(clean());
  });
  gulp.task('copy-files', function () {
    return gulp.src(otherFiles)
      .pipe(newer(dest))
      // .pipe(tap(function(file) {
      //     console.log('copy', file.path);
      //  }))
      .pipe(gulp.dest(dest))
      .pipe(gulp.dest(coveredDest));
  });
  gulp.task('ts-definitions', function () {
    var tsProject = ts.createProject('tsconfig.json', { declaration: true });
    var tsResult = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: swallowError })))
      .pipe(newer({ dest, ext: '.d.ts' }))
      .pipe(add.prepend(typings))
      .pipe(add.prepend(customTypings))
      .pipe(ts(tsProject));
    return tsResult.dts.pipe(gulp.dest(dest));
  });
  function doJsCompile(covered) {
    compileErrors = 0;
    var checkDest = covered ? coveredDest : dest;
    const noMap = filter('**/!(*.map)', { restore: false });
    // const noTests = filter('**/(!test/**/*.*)', { restore: false });
    var stream = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(() => {
        compileErrors++;
      }) })))
      .pipe(newer({ dest: checkDest, ext: '.js' }))
      .pipe(sourcemaps.init())
      .pipe(babel())
      .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
      .pipe(gulp.dest(dest));
    if (covered) {
      stream = stream
        .pipe(noMap)
        // .pipe(noTests)
        .pipe(istanbul())
        .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
        .pipe(gulp.dest('lib_covered'));
    }
    return stream;
  }
  function doTsCompile(covered) {
    compileErrors = 0;
    var checkDest = covered ? coveredDest : dest;
    var noMap = filter('**/!(*.map)', { restore: false });
    // const noTests = filter('**/(!test/**/*.*)', { restore: false });
    var tsProject = ts.createProject('tsconfig.json', { isolatedModules: true, declaration: false });
    var tsResult = gulp.src(source)
      .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(() => {
        compileErrors++;
      }) })))
      .pipe(newer({ dest: checkDest, ext: '.js' }))
      .pipe(sourcemaps.init())
      .pipe(add.prepend(typings))
      .pipe(add.prepend(customTypings))
      .pipe(ts(tsProject));
    var babelStream = tsResult.js.pipe(babel())
      .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
      .pipe(gulp.dest(dest));
    if (covered) {
      babelStream = babelStream
        .pipe(noMap)
        // .pipe(noTests)
        .pipe(istanbul())
        .pipe(sourcemaps.write('.', { sourceRoot: '/' + packageVersion + '/src' }))
        .pipe(gulp.dest('lib_covered'));
    }
    return merge([
      tsResult.dts
        .pipe(gulp.dest(dest)),
      babelStream,
    ]);
  }
  gulp.task('js-compile', ['copy-files'], function () {
    return doJsCompile(false);
  });
  gulp.task('js-compile-covered', ['copy-files'], function () {
    return doJsCompile(true);
  });
  gulp.task('ts-compile', ['copy-files'], function () {
    return doTsCompile(false);
  });
  gulp.task('ts-compile-covered', ['copy-files'], function () {
    return doTsCompile(true);
  });
  gulp.task('remap-istanbul', function () {
    return gulp.src('coverage/coverage-final.json')
    .pipe(remapIstanbul({
      reports: {
        json: 'coverage/coverage.json',
        html: 'coverage/html-report',
      },
    }));
  });
  gulp.task('test', ['do-test']);
  gulp.task('test-covered', function (callback) {
    return sequence(
      // 'pre-test',
      'do-test-covered',
      'remap-istanbul'
      )(callback);
  });
  function doTest(endpoints) {
    var errorHappened = false;
    var mocha;
    if (debug) {
      mocha = spawnMocha({
        debugBrk: true,
        env: { NODE_ENV: 'test' },
      });
    } else {
      mocha = inlineMocha({
        reporter: 'mocha-jenkins-reporter',
        reporterOptions: {
          junit_report_name: packageInfo.name,
          junit_report_path: 'tests-xunit.xml',
          junit_report_stack: 1,
        },
      });
    }
    return gulp.src(endpoints, { read: false })
    .pipe(gulpIf(!stopOnErrors, plumber({ errorHandler: onError(function () {
      errorHappened = true;
    }) })))
    .pipe(mocha)
    .pipe(istanbul.writeReports({
      reporters: ['json'],
    }))
    .on('end', function () {
      if (!errorHappened && !compileErrors) {
        notifier.notify(
          { title: 'All tests passed in ' + packageInfo.name, message: 'Write some more' }
        );
      }
    });
  }
  gulp.task('do-test', function () {
    return doTest([testEndpoint]);
  });
  gulp.task('do-test-covered', function () {
    return doTest([coveredTestEndpoint]);
  });
  gulp.task('start', function () {
    nodemon({
      script: startEndpoint,
      watch: [destGlob],
    });
  });
  gulp.task('ts-watch-compile', function () {
    gulp.watch(source, ['ts-compile']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-compile-covered', function () {
    gulp.watch(source, ['ts-compile-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-compile', function () {
    gulp.watch(source, ['js-compile']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-compile-covered', function () {
    gulp.watch(source, ['js-compile-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-test', function () {
    gulp.watch(source, ['ts-compile-and-test']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-watch-test-covered', function () {
    gulp.watch(source, ['ts-compile-and-test-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-test', function () {
    gulp.watch(source, ['js-compile-and-test']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('js-watch-test-covered', function () {
    gulp.watch(source, ['js-compile-and-test-covered']);
    // gulp.watch(otherFiles, ['copy-files']);
  });
  gulp.task('ts-compile-and-test', function (callback) {
    sequence('ts-definitions', 'ts-compile', 'test')(callback);
  });
  gulp.task('ts-compile-and-test-covered', function (callback) {
    sequence('ts-definitions', 'ts-compile-covered', 'test-covered')(callback);
  });
  gulp.task('js-compile-and-test', function (callback) {
    sequence('js-compile', 'test')(callback);
  });
  gulp.task('js-compile-and-test-covered', function (callback) {
    sequence('js-compile-covered', 'test-covered')(callback);
  });
  gulp.task('ts-fresh-compile', function (callback) {
    sequence('cleanup', 'ts-definitions', 'ts-compile')(callback);
  });
  gulp.task('ts-fresh-compile-covered', function (callback) {
    sequence('cleanup', 'ts-definitions', 'ts-compile-covered')(callback);
  });
  gulp.task('js-fresh-compile', function (callback) {
    sequence('cleanup', 'js-compile')(callback);
  });
  gulp.task('js-fresh-compile-covered', function (callback) {
    sequence('cleanup', 'js-compile-covered')(callback);
  });
  gulp.task('ts-run-build', function (callback) {
    sequence('ts-fresh-compile', 'ts-watch-compile')(callback);
  });
  gulp.task('ts-run-build-covered', function (callback) {
    sequence('ts-fresh-compile-covered', 'ts-watch-compile-covered')(callback);
  });
  gulp.task('js-run-build', function (callback) {
    sequence('js-fresh-compile', 'js-watch-compile')(callback);
  });
  gulp.task('js-run-build-covered', function (callback) {
    sequence('js-fresh-compile-covered', 'js-watch-compile-covered')(callback);
  });
  gulp.task('ts-run-test', function (callback) {
    sequence('ts-run-build', 'ts-watch-test', 'test')(callback);
  });
  gulp.task('ts-run-test-covered', function (callback) {
    sequence('ts-run-build-covered', 'ts-watch-test-covered', 'test-covered')(callback);
  });
  gulp.task('js-run-test', function (callback) {
    sequence('js-run-build', 'js-watch-test', 'test')(callback);
  });
  gulp.task('js-run-test-covered', function (callback) {
    sequence('js-run-build-covered', 'js-watch-test-covered', 'test-covered')(callback);
  });
  gulp.task('ts-run', function (callback) {
    sequence('ts-compile', 'ts-watch-compile', 'start')(callback);
  });
  gulp.task('js-run', function (callback) {
    sequence('js-compile', 'js-watch-compile', 'start')(callback);
  });
};
<|endoftext|>


<commit_before>// original file from https://github.com/kunklejr/node-pcap-parser
// modified to work with fritzbox eth file and return full pcapPacket
// for decoding with node_pcap
// TODO: remove unneeded functions, refactor, apply linter standards

/* LICENCE:
Copyright (c) 2012 Near Infinity Corporation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

var util = require('util')
var events = require('events')
var fs = require('fs')
const pcap = require('pcap')

var GLOBAL_HEADER_LENGTH = 24 // bytes
var PACKET_HEADER_LENGTH = 16 // bytes, maybe too short for eth file?

function onError (err) {
  this.emit('error', err)
}

function onEnd () {
  this.emit('end')
}

function onData (data) {
  if (this.errored) {
    return
  }

  updateBuffer.call(this, data)

  while (this.state.call(this)) {
    // console.log('Working!');
  }
  // console.log('Done! ', this.state);
}

function updateBuffer (data) {
  if (data === null || data === undefined) {
    return
  }

  if (this.buffer === null) {
    this.buffer = data
  } else {
    var extendedBuffer = new Buffer(this.buffer.length + data.length)
    this.buffer.copy(extendedBuffer)
    data.copy(extendedBuffer, this.buffer.length)
    this.buffer = extendedBuffer
  }
}

function parseGlobalHeader () {
  var buffer = this.buffer

  if (checkIfEnoughData(buffer, GLOBAL_HEADER_LENGTH) === false) {
    return false
  }
  // console.log('enough data')
  this.magicNumber = getMagicNumber(buffer)
  // console.log('Magic Number')
  this.endianness = this.determinePcapEndianess(buffer, this.magicNumber)
  // console.log('Endianess')
  if (this.endianness === false) {
    return false
  }

  var globalHeader = getGlobalHeaderFromBuffer(buffer, this.endianness)
  // console.log(header)
  this.linkType = determineLinkLayer(globalHeader.linkLayerType)
  if (this.linkType === false) {
    return false
  }
  if (checkIfPcapVersionIsSupported(globalHeader) === false) {
    return false
  }
  // console.log(header)
  this.emit('globalHeader', globalHeader)
  this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH)
  this.state = parsePacketHeader
  return true
}

function checkIfEnoughData (buffer, length) {
  if (buffer.length < length) {
    return false
  }
  return true
}

function getMagicNumber (buffer) {
  return buffer.toString('hex', 0, 4)
}

function determinePcapEndianess (buffer, magicNumber) {
  // console.log(magicNumber)
  var endianness
  // determine pcap endianness
  // added "a1b2cd34" for fritzbox eth file
  if ((magicNumber === 'a1b2c3d4') || (magicNumber === 'a1b2cd34')) {
    endianness = 'BE'
  } else if (magicNumber === 'd4c3b2a1') {
    endianness = 'LE'
  } else {
    this.handleError('unknown magic number: %s', magicNumber)
    return false
  }
  return endianness
}

function handleError (message) {
  // console.log(this)
  this.errored = true
  this.stream.pause()
  this.emit('error', new Error(message))
  onEnd.call(this)
}

function getGlobalHeaderFromBuffer (buffer, endianness) {
  return {
    magicNumber: buffer['readUInt32' + endianness](0, true),
    majorVersion: buffer['readUInt16' + endianness](4, true),
    minorVersion: buffer['readUInt16' + endianness](6, true),
    gmtOffset: buffer['readInt32' + endianness](8, true),
    timestampAccuracy: buffer['readUInt32' + endianness](12, true),
    snapshotLength: buffer['readUInt32' + endianness](16, true),
    linkLayerType: buffer['readUInt32' + endianness](20, true)
  }
}

function determineLinkLayer (linkLayerType) {
  // set link_type TODO: move to seperate function
  var linkType
  switch (linkLayerType) {
    case 0:
      linkType = 'LINKTYPE_NULL'
      break
    case 1:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 12:
      linkType = 'LINKTYPE_RAW'
      break
    case 113:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 127:
      linkType = 'LINKTYPE_IEEE802_11_RADIO'
      break
    default:
      console.log('pcap-parser: don\'t know how to do link_type ' + linkLayerType)
      linkType = false
  }
  return linkType
}

function checkIfPcapVersionIsSupported (globalHeader) {
  if (globalHeader.majorVersion !== 2 && globalHeader.minorVersion !== 4) {
    this.handleError('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', globalHeader.majorVersion, globalHeader.minorVersion)
    return false
  }
}
// var handleError = handleErrorFactory.bind(this)

function getRawPacketBody () {
  var buffer = this.buffer
  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    this.data = buffer.slice(0, this.currentPacketHeader.capturedLength)

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength)
    this.state = buildAndSendFullPackage
    return true
  }
  return false
}

function buildAndSendFullPackage () {
  var fullPacket = new pcap.PacketWithHeader(this.data, this.rawCurrentHeader, this.linkType)
  this.emit('packet', fullPacket)
  this.state = parsePacketHeader
  return true
}

// TODO: find out about extra 8 byte
// -->Alexey Kuznetsov's modified "libpcap"format
// https://github.com/boundary/wireshark/blob/master/wiretap/libpcap.h
// starting at line 75
// node_pcap can decode this correctly if present as dumpfile
function parsePacketHeader () {
  var buffer = this.buffer
  // console.log('header: length: ', buffer.length)
  // if (buffer.length >= PACKET_HEADER_LENGTH + 8) {
  if (buffer.length >= PACKET_HEADER_LENGTH) {
    var header = {
      timestampSeconds: buffer['readUInt32' + this.endianness](0, true),
      timestampMicroseconds: buffer['readUInt32' + this.endianness](4, true),
      capturedLength: buffer['readUInt32' + this.endianness](8, true),
      originalLength: buffer['readUInt32' + this.endianness](12, true),
      item1: buffer['readUInt32' + this.endianness](16, true),
      item2: buffer['readUInt16' + this.endianness](20, true),
      item3: buffer['readUInt16' + this.endianness](22, true)
    }

    this.currentPacketHeader = header
    this.emit('packetHeader', header)
    // console.log('Header: ', this.currentPacketHeader)

    // Set raw packet header to LE
    buffer.writeUInt32LE(header.timestampSeconds, 0, true)
    buffer.writeUInt32LE(header.timestampMicroseconds, 4, true)
    buffer.writeUInt32LE(header.capturedLength, 8, true)
    buffer.writeUInt32LE(header.originalLength, 12, true)

    // this.rawCurrentHeader = buffer.slice(0, PACKET_HEADER_LENGTH + 8)
    this.rawCurrentHeader = buffer.slice(0, PACKET_HEADER_LENGTH)

    // this.buffer = buffer.slice(PACKET_HEADER_LENGTH + 8)
    this.buffer = buffer.slice(PACKET_HEADER_LENGTH)
    this.state = getRawPacketBody
    // this.state = parsePacketBody
    return true
  }

  return false
}

// TODO: check if input is stream
function Parser (input) {
  if (typeof (input) === 'string') {
    this.stream = fs.createReadStream(input)
  } else {
    // assume a ReadableStream
    this.stream = input
  }

  this.stream.pause()
  this.stream.on('data', onData.bind(this))
  this.stream.on('error', onError.bind(this))
  this.stream.on('end', onEnd.bind(this))

  this.buffer = null
  this.state = parseGlobalHeader
  this.endianness = null
  this.magicNumber = null
  this.linkType = null

  this.determinePcapEndianess = determinePcapEndianess.bind(this)
  this.handleError = handleError.bind(this)

  process.nextTick(this.stream.resume.bind(this.stream))
}
util.inherits(Parser, events.EventEmitter)

exports.parse = function (input) {
  return new Parser(input)
}
<commit_msg>extracted method getHeaderFromBuffer<commit_after>// original file from https://github.com/kunklejr/node-pcap-parser
// modified to work with fritzbox eth file and return full pcapPacket
// for decoding with node_pcap
// TODO: remove unneeded functions, refactor, apply linter standards

/* LICENCE:
Copyright (c) 2012 Near Infinity Corporation

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

var util = require('util')
var events = require('events')
var fs = require('fs')
const pcap = require('pcap')

var GLOBAL_HEADER_LENGTH = 24 // bytes
var PACKET_HEADER_LENGTH = 16 // bytes, maybe too short for eth file?

function onError (err) {
  this.emit('error', err)
}

function onEnd () {
  this.emit('end')
}

function onData (data) {
  if (this.errored) {
    return
  }

  updateBuffer.call(this, data)

  while (this.state.call(this)) {
    // console.log('Working!');
  }
  // console.log('Done! ', this.state);
}

function updateBuffer (data) {
  if (data === null || data === undefined) {
    return
  }

  if (this.buffer === null) {
    this.buffer = data
  } else {
    var extendedBuffer = new Buffer(this.buffer.length + data.length)
    this.buffer.copy(extendedBuffer)
    data.copy(extendedBuffer, this.buffer.length)
    this.buffer = extendedBuffer
  }
}

function parseGlobalHeader () {
  var buffer = this.buffer

  if (checkIfEnoughData(buffer, GLOBAL_HEADER_LENGTH) === false) {
    return false
  }
  // console.log('enough data')
  this.magicNumber = getMagicNumber(buffer)
  // console.log('Magic Number')
  this.endianness = this.determinePcapEndianess(buffer, this.magicNumber)
  // console.log('Endianess')
  if (this.endianness === false) {
    return false
  }

  var globalHeader = getGlobalHeaderFromBuffer(buffer, this.endianness)
  // console.log(header)
  this.linkType = determineLinkLayer(globalHeader.linkLayerType)
  if (this.linkType === false) {
    return false
  }
  if (checkIfPcapVersionIsSupported(globalHeader) === false) {
    return false
  }
  // console.log(header)
  this.emit('globalHeader', globalHeader)
  this.buffer = buffer.slice(GLOBAL_HEADER_LENGTH)
  this.state = parsePacketHeader
  return true
}

function checkIfEnoughData (buffer, length) {
  if (buffer.length < length) {
    return false
  }
  return true
}

function getMagicNumber (buffer) {
  return buffer.toString('hex', 0, 4)
}

function determinePcapEndianess (buffer, magicNumber) {
  // console.log(magicNumber)
  var endianness
  // determine pcap endianness
  // added "a1b2cd34" for fritzbox eth file
  if ((magicNumber === 'a1b2c3d4') || (magicNumber === 'a1b2cd34')) {
    endianness = 'BE'
  } else if (magicNumber === 'd4c3b2a1') {
    endianness = 'LE'
  } else {
    this.handleError('unknown magic number: %s', magicNumber)
    return false
  }
  return endianness
}

function handleError (message) {
  // console.log(this)
  this.errored = true
  this.stream.pause()
  this.emit('error', new Error(message))
  onEnd.call(this)
}

function getGlobalHeaderFromBuffer (buffer, endianness) {
  return {
    magicNumber: buffer['readUInt32' + endianness](0, true),
    majorVersion: buffer['readUInt16' + endianness](4, true),
    minorVersion: buffer['readUInt16' + endianness](6, true),
    gmtOffset: buffer['readInt32' + endianness](8, true),
    timestampAccuracy: buffer['readUInt32' + endianness](12, true),
    snapshotLength: buffer['readUInt32' + endianness](16, true),
    linkLayerType: buffer['readUInt32' + endianness](20, true)
  }
}

function determineLinkLayer (linkLayerType) {
  // set link_type TODO: move to seperate function
  var linkType
  switch (linkLayerType) {
    case 0:
      linkType = 'LINKTYPE_NULL'
      break
    case 1:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 12:
      linkType = 'LINKTYPE_RAW'
      break
    case 113:
      linkType = 'LINKTYPE_ETHERNET'
      break
    case 127:
      linkType = 'LINKTYPE_IEEE802_11_RADIO'
      break
    default:
      console.log('pcap-parser: don\'t know how to do link_type ' + linkLayerType)
      linkType = false
  }
  return linkType
}

function checkIfPcapVersionIsSupported (globalHeader) {
  if (globalHeader.majorVersion !== 2 && globalHeader.minorVersion !== 4) {
    this.handleError('unsupported version %d.%d. pcap-parser only parses libpcap file format 2.4', globalHeader.majorVersion, globalHeader.minorVersion)
    return false
  }
}
// var handleError = handleErrorFactory.bind(this)

function getRawPacketBody () {
  var buffer = this.buffer
  if (buffer.length >= this.currentPacketHeader.capturedLength) {
    this.data = buffer.slice(0, this.currentPacketHeader.capturedLength)

    this.buffer = buffer.slice(this.currentPacketHeader.capturedLength)
    this.state = buildAndSendFullPackage
    return true
  }
  return false
}

function buildAndSendFullPackage () {
  var fullPacket = new pcap.PacketWithHeader(this.data, this.rawCurrentHeader, this.linkType)
  this.emit('packet', fullPacket)
  this.state = parsePacketHeader
  return true
}

// TODO: find out about extra 8 byte
// -->Alexey Kuznetsov's modified "libpcap"format
// https://github.com/boundary/wireshark/blob/master/wiretap/libpcap.h
// starting at line 75
// node_pcap can decode this correctly if present as dumpfile
function parsePacketHeader () {
  var buffer = this.buffer
  // console.log('header: length: ', buffer.length)
  // if (buffer.length >= PACKET_HEADER_LENGTH + 8) {
  if (checkIfEnoughData(buffer, PACKET_HEADER_LENGTH) === false) {
    return false
  }

  var header = getHeaderFromBuffer(buffer, this.endianness)

  this.currentPacketHeader = header
  this.emit('packetHeader', header)
  // console.log('Header: ', this.currentPacketHeader)

  // Set raw packet header to LE
  buffer.writeUInt32LE(header.timestampSeconds, 0, true)
  buffer.writeUInt32LE(header.timestampMicroseconds, 4, true)
  buffer.writeUInt32LE(header.capturedLength, 8, true)
  buffer.writeUInt32LE(header.originalLength, 12, true)

  // this.rawCurrentHeader = buffer.slice(0, PACKET_HEADER_LENGTH + 8)
  this.rawCurrentHeader = buffer.slice(0, PACKET_HEADER_LENGTH)

  // this.buffer = buffer.slice(PACKET_HEADER_LENGTH + 8)
  this.buffer = buffer.slice(PACKET_HEADER_LENGTH)
  this.state = getRawPacketBody
  // this.state = parsePacketBody
  return true
}

function getHeaderFromBuffer (buffer, endianness) {
  return {
    timestampSeconds: buffer['readUInt32' + endianness](0, true),
    timestampMicroseconds: buffer['readUInt32' + endianness](4, true),
    capturedLength: buffer['readUInt32' + endianness](8, true),
    originalLength: buffer['readUInt32' + endianness](12, true),
    item1: buffer['readUInt32' + endianness](16, true),
    item2: buffer['readUInt16' + endianness](20, true),
    item3: buffer['readUInt16' + endianness](22, true)
  }
}

// TODO: check if input is stream
function Parser (input) {
  if (typeof (input) === 'string') {
    this.stream = fs.createReadStream(input)
  } else {
    // assume a ReadableStream
    this.stream = input
  }

  this.stream.pause()
  this.stream.on('data', onData.bind(this))
  this.stream.on('error', onError.bind(this))
  this.stream.on('end', onEnd.bind(this))

  this.buffer = null
  this.state = parseGlobalHeader
  this.endianness = null
  this.magicNumber = null
  this.linkType = null

  this.determinePcapEndianess = determinePcapEndianess.bind(this)
  this.handleError = handleError.bind(this)

  process.nextTick(this.stream.resume.bind(this.stream))
}
util.inherits(Parser, events.EventEmitter)

exports.parse = function (input) {
  return new Parser(input)
}
<|endoftext|>


<commit_before>var _; //globals

/* This section uses a functional extension known as Underscore.js - http://documentcloud.github.com/underscore/
     "Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support
      that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.
      It's the tie to go along with jQuery's tux."
 */
describe("About Higher Order Functions", function () {

  it("should use filter to return array items that meet a criteria", function () {
    var numbers = [1,2,3];
    var odd = _(numbers).filter(function (x) { return x % 2 !== 0 });

    expect(odd).toEqual([1,3]);
    expect(odd.length).toBe(2);
    expect(numbers.length).toBe(3);
  });

  it("should use 'map' to transform each element", function () {
    var numbers = [1, 2, 3];
    var numbersPlus1 = _(numbers).map(function(x) { return x + 1 });

    expect(numbersPlus1).toEqual([2,3,4]);
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'reduce' to update the same result on each iteration", function () {
    var numbers = [1, 2, 3];
    var reduction = _(numbers).reduce(
            function(/* result from last call */ memo, /* current */ x) { return memo + x }, /* initial */ 0);

    expect(reduction).toBe(6);
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'forEach' for simple iteration", function () {
    var numbers = [1,2,3];
    var msg = "";
    var isEven = function (item) {
      msg += (item % 2) === 0;
    };

    _(numbers).forEach(isEven);

    expect(msg).toEqual("falsetruefalse");
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'all' to test whether all items pass condition", function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).all(isEven)).toBe(FILL_ME_IN);
    expect(_(mixedBag).all(isEven)).toBe(FILL_ME_IN);
  });

  it("should use 'any' to test if any items passes condition" , function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).any(isEven)).toBe(FILL_ME_IN);
    expect(_(mixedBag).any(isEven)).toBe(FILL_ME_IN);
  });

  it("should use range to generate an array", function() {
      expect(_.range(3)).toEqual(FILL_ME_IN);
      expect(_.range(1, 4)).toEqual(FILL_ME_IN);
      expect(_.range(0, -4, -1)).toEqual(FILL_ME_IN);
  });

  it("should use flatten to make nested arrays easy to work with", function() {
      expect(_([ [1, 2], [3, 4] ]).flatten()).toEqual(FILL_ME_IN);
  });

  it("should use chain() ... .value() to use multiple higher order functions", function() {
      var result = _([ [0, 1], 2 ]).chain()
                       .flatten()
                       .map(function(x) { return x+1 } )
                       .reduce(function (sum, x) { return sum + x })
                       .value();

      expect(result).toEqual(FILL_ME_IN);
  });

});

<commit_msg>Second update on AboutHigherOrderFunctions.js - thru end<commit_after>var _; //globals

/* This section uses a functional extension known as Underscore.js - http://documentcloud.github.com/underscore/
     "Underscore is a utility-belt library for JavaScript that provides a lot of the functional programming support
      that you would expect in Prototype.js (or Ruby), but without extending any of the built-in JavaScript objects.
      It's the tie to go along with jQuery's tux."
 */
describe("About Higher Order Functions", function () {

  it("should use filter to return array items that meet a criteria", function () {
    var numbers = [1,2,3];
    var odd = _(numbers).filter(function (x) { return x % 2 !== 0 });

    expect(odd).toEqual([1,3]);
    expect(odd.length).toBe(2);
    expect(numbers.length).toBe(3);
  });

  it("should use 'map' to transform each element", function () {
    var numbers = [1, 2, 3];
    var numbersPlus1 = _(numbers).map(function(x) { return x + 1 });

    expect(numbersPlus1).toEqual([2,3,4]);
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'reduce' to update the same result on each iteration", function () {
    var numbers = [1, 2, 3];
    var reduction = _(numbers).reduce(
            function(/* result from last call */ memo, /* current */ x) { return memo + x }, /* initial */ 0);

    expect(reduction).toBe(6);
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'forEach' for simple iteration", function () {
    var numbers = [1,2,3];
    var msg = "";
    var isEven = function (item) {
      msg += (item % 2) === 0;
    };

    _(numbers).forEach(isEven);

    expect(msg).toEqual("falsetruefalse");
    expect(numbers).toEqual([1,2,3]);
  });

  it("should use 'all' to test whether all items pass condition", function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).all(isEven)).toBe(true);
    expect(_(mixedBag).all(isEven)).toBe(false);
  });

  it("should use 'any' to test if any items passes condition" , function () {
    var onlyEven = [2,4,6];
    var mixedBag = [2,4,5,6];

    var isEven = function(x) { return x % 2 === 0 };

    expect(_(onlyEven).any(isEven)).toBe(true);
    expect(_(mixedBag).any(isEven)).toBe(true);
  });

  it("should use range to generate an array", function() {
      expect(_.range(3)).toEqual([0,1,2]);
      expect(_.range(1, 4)).toEqual([1,2,3]);
      expect(_.range(0, -4, -1)).toEqual([0,-1,-2,-3]);
  });

  it("should use flatten to make nested arrays easy to work with", function() {
      expect(_([ [1, 2], [3, 4] ]).flatten()).toEqual([1,2,3,4]);
  });

  it("should use chain() ... .value() to use multiple higher order functions", function() {
      var result = _([ [0, 1], 2 ]).chain()
                       .flatten()
                       .map(function(x) { return x+1 } )
                       .reduce(function (sum, x) { return sum + x })
                       .value();

      expect(result).toEqual(6);
  });

});

<|endoftext|>


<commit_before>import withData from '../lib/withData'
import React from 'react'
import Event from '../components/Event';
import { IntlProvider, addLocaleData } from 'react-intl';

import en from 'react-intl/locale-data/en';
import fr from 'react-intl/locale-data/fr';
import es from 'react-intl/locale-data/es';
import enUS from '../lang/en-US.json';
// import frFR from '../lang/fr-FR.json';

addLocaleData([...en, ...fr, ...es]);
addLocaleData({
    locale: 'en-US',
    parentLocale: 'en',
});

class EventPage extends React.Component {
  static getInitialProps ({ query: { collectiveSlug, eventSlug } }) {
    return { collectiveSlug, eventSlug }
  }
  render() {
    const { collectiveSlug, eventSlug } = this.props;
    return (
      <IntlProvider locale="en-US" messages={enUS}>

          <Event collectiveSlug={collectiveSlug} eventSlug={eventSlug} />

      </IntlProvider>
    );
  }
}

let EventPageWithData;
require.ensure([
  'intl',
  'intl/locale-data/jsonp/en.js'
], (require) => {
  require('intl');
  require('intl/locale-data/jsonp/en.js');
  EventPageWithData = withData(EventPage);
});

export default EventPageWithData;
<commit_msg>polyfill window.Intl for Safari 9 and Firefox 28<commit_after>import withData from '../lib/withData'
import React from 'react'
import Event from '../components/Event';
import { IntlProvider, addLocaleData } from 'react-intl';

import 'intl';
import 'intl/locale-data/jsonp/en.js'; // for old browsers without window.Intl
import en from 'react-intl/locale-data/en';
import enUS from '../lang/en-US.json';
// import fr from 'react-intl/locale-data/fr';
// import es from 'react-intl/locale-data/es';
// import frFR from '../lang/fr-FR.json';

addLocaleData([...en]);
addLocaleData({
    locale: 'en-US',
    parentLocale: 'en',
});

class EventPage extends React.Component {
  static getInitialProps ({ query: { collectiveSlug, eventSlug } }) {
    return { collectiveSlug, eventSlug }
  }
  render() {
    const { collectiveSlug, eventSlug } = this.props;
    return (
      <IntlProvider locale="en-US" messages={enUS}>

          <Event collectiveSlug={collectiveSlug} eventSlug={eventSlug} />

      </IntlProvider>
    );
  }
}

export default withData(EventPage);
<|endoftext|>


<commit_before>window.cue = window.cue || {};

(function( window, $, undefined )  {
	'use strict';

	var $window = $( window ),
		cue = window.cue;

	cue.l10n = $.extend({
		nextTrack: 'Next Track',
		previousTrack: 'Previous Track',
		togglePlaylist: 'Toggle Playlist'
	}, cue.l10n || {});

	cue.settings = cue.settings || {};

	// Add mime-type aliases to MediaElement plugin support.
	mejs.plugins.silverlight[ 0 ].types.push( 'audio/x-ms-wma' );

	// Detection for browser SVG capability.
	$( 'html' ).addClass(function() {
		return document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ) ? 'svg' : 'no-svg';
	});

	$.extend( mejs.MepDefaults, {
		cueResponsiveProgress: false, // Set the progress bar to 100% on window resize.
		cueSelectors: {
			container: '.cue-playlist-container'
		},
		cueSkin: ''
	});

	/**
	 * jQuery plugin to initialize playlists.
	 *
	 * @class cuePlaylist
	 * @memberOf jQuery.fn
	 *
	 * @param {Object} options Custom settings overrides.
	 *
	 * @return {jQuery} Chainable jQuery collection.
	 */
	$.fn.cuePlaylist = function( options ) {
		var settings = $.extend( $.fn.cuePlaylist.defaults, options );

		// Add selector settings.
		settings.cueSelectors = $.extend({}, mejs.MepDefaults.cueSelectors, {
			playlist: this.selector,
			track: '.cue-track'
		});

		// Merge custom selector options into the defaults.
		if ( 'object' === typeof options && 'cueSelectors' in options ) {
			$.extend( settings.cueSelectors, options.cueSelectors );
		}

		return this.each(function() {
			var $playlist = $( this ),
				$media = $playlist.find( '.cue-audio, audio' ).first(),
				$data = $playlist.find( '.cue-playlist-data, script' ),
				data, i, trackCount;

			if ( ! $data.length ) {
				$data = $playlist.closest( settings.cueSelectors.container ).find( '.cue-playlist-data, script' );
			}

			if ( $data.length ) {
				data = $.parseJSON( $data.first().html() );

				// Add the tracks.
				if ( ( 'undefined' === typeof options || 'undefined' === typeof options.cuePlaylistTracks ) && 'tracks' in data ) {
					settings.cuePlaylistTracks = data.tracks;
				}
			}

			if ( settings.cuePlaylistTracks.length ) {
				trackCount = settings.cuePlaylistTracks.length;
				$playlist.addClass( 'cue-tracks-count-' + trackCount );

				// Create an <audio> element if one couldn't be found.
				if ( ! $media.length ) {
					for ( i = 0; i < trackCount; i++ ) {
						if ( '' === settings.cuePlaylistTracks[ i ].src ) {
							continue;
						}

						$media = $( '<audio />', {
							src: settings.cuePlaylistTracks[ i ].src
						}).prependTo( $playlist );
						break;
					}
				}

				// Initialize MediaElement.js.
				$media.mediaelementplayer( settings );
			}
		});
	};

	$.fn.cuePlaylist.defaults = {
		autosizeProgress: false,
		cuePlaylistLoop: true,
		cuePlaylistTracks: [],
		cueSkin: 'cue-skin-default',
		defaultAudioHeight: 0,
		enableAutosize: false,
		features: [
			'cueartwork',
			'cuecurrentdetails',
			'cueprevioustrack',
			'playpause',
			'cuenexttrack',
			'progress',
			'current',
			'duration',
			'cueplaylist'
		],
		success: function( media, domObject, player ) {
			var $media = $( media ),
				$container = player.container.closest( player.options.cueSelectors.playlist );

			if ( '' !== player.options.cueSkin ) {
				player.changeSkin( player.options.cueSkin );
			}

			// Make the time rail responsive.
			if ( player.options.cueResponsiveProgress ) {
				$window.on( 'resize.cue', function() {
					player.controls.find( '.mejs-time-rail' ).width( '100%' );
					//t.setControlsSize();
				}).trigger( 'resize.cue' );
			}

			$media.on( 'play.cue', function() {
				$container.addClass( 'is-playing' );
			}).on( 'pause.cue', function() {
				$container.removeClass( 'is-playing' );
			});

			$container.trigger( 'success.cue', [ media, domObject, player ]);
		},
		timeAndDurationSeparator: ' / '
	};

})( this, jQuery );
<commit_msg>Automatically add a signature from the data script if it exists.<commit_after>window.cue = window.cue || {};

(function( window, $, undefined )  {
	'use strict';

	var $window = $( window ),
		cue = window.cue;

	cue.l10n = $.extend({
		nextTrack: 'Next Track',
		previousTrack: 'Previous Track',
		togglePlaylist: 'Toggle Playlist'
	}, cue.l10n || {});

	cue.settings = cue.settings || {};

	// Add mime-type aliases to MediaElement plugin support.
	mejs.plugins.silverlight[ 0 ].types.push( 'audio/x-ms-wma' );

	// Detection for browser SVG capability.
	$( 'html' ).addClass(function() {
		return document.implementation.hasFeature( 'http://www.w3.org/TR/SVG11/feature#Image', '1.1' ) ? 'svg' : 'no-svg';
	});

	$.extend( mejs.MepDefaults, {
		cueResponsiveProgress: false, // Set the progress bar to 100% on window resize.
		cueSelectors: {
			container: '.cue-playlist-container'
		},
		cueSkin: ''
	});

	/**
	 * jQuery plugin to initialize playlists.
	 *
	 * @class cuePlaylist
	 * @memberOf jQuery.fn
	 *
	 * @param {Object} options Custom settings overrides.
	 *
	 * @return {jQuery} Chainable jQuery collection.
	 */
	$.fn.cuePlaylist = function( options ) {
		var settings = $.extend( $.fn.cuePlaylist.defaults, options );

		// Add selector settings.
		settings.cueSelectors = $.extend({}, mejs.MepDefaults.cueSelectors, {
			playlist: this.selector,
			track: '.cue-track'
		});

		// Merge custom selector options into the defaults.
		if ( 'object' === typeof options && 'cueSelectors' in options ) {
			$.extend( settings.cueSelectors, options.cueSelectors );
		}

		return this.each(function() {
			var $playlist = $( this ),
				$media = $playlist.find( '.cue-audio, audio' ).first(),
				$data = $playlist.find( '.cue-playlist-data, script' ),
				data, i, trackCount;

			if ( ! $data.length ) {
				$data = $playlist.closest( settings.cueSelectors.container ).find( '.cue-playlist-data, script' );
			}

			if ( $data.length ) {
				data = $.parseJSON( $data.first().html() );

				// Add the signature.
				if ( 'cueSignature' in data ) {
					settings.cueSignature = data.cueSignature;
				}

				// Add the tracks.
				if ( ( 'undefined' === typeof options || 'undefined' === typeof options.cuePlaylistTracks ) && 'tracks' in data ) {
					settings.cuePlaylistTracks = data.tracks;
				}
			}

			if ( settings.cuePlaylistTracks.length ) {
				trackCount = settings.cuePlaylistTracks.length;
				$playlist.addClass( 'cue-tracks-count-' + trackCount );

				// Create an <audio> element if one couldn't be found.
				if ( ! $media.length ) {
					for ( i = 0; i < trackCount; i++ ) {
						if ( '' === settings.cuePlaylistTracks[ i ].src ) {
							continue;
						}

						$media = $( '<audio />', {
							src: settings.cuePlaylistTracks[ i ].src
						}).prependTo( $playlist );
						break;
					}
				}

				// Initialize MediaElement.js.
				$media.mediaelementplayer( settings );
			}
		});
	};

	$.fn.cuePlaylist.defaults = {
		autosizeProgress: false,
		cuePlaylistLoop: true,
		cuePlaylistTracks: [],
		cueSkin: 'cue-skin-default',
		defaultAudioHeight: 0,
		enableAutosize: false,
		features: [
			'cueartwork',
			'cuecurrentdetails',
			'cueprevioustrack',
			'playpause',
			'cuenexttrack',
			'progress',
			'current',
			'duration',
			'cueplaylist'
		],
		success: function( media, domObject, player ) {
			var $media = $( media ),
				$container = player.container.closest( player.options.cueSelectors.playlist );

			if ( '' !== player.options.cueSkin ) {
				player.changeSkin( player.options.cueSkin );
			}

			// Make the time rail responsive.
			if ( player.options.cueResponsiveProgress ) {
				$window.on( 'resize.cue', function() {
					player.controls.find( '.mejs-time-rail' ).width( '100%' );
					//t.setControlsSize();
				}).trigger( 'resize.cue' );
			}

			$media.on( 'play.cue', function() {
				$container.addClass( 'is-playing' );
			}).on( 'pause.cue', function() {
				$container.removeClass( 'is-playing' );
			});

			$container.trigger( 'success.cue', [ media, domObject, player ]);
		},
		timeAndDurationSeparator: ' / '
	};

})( this, jQuery );
<|endoftext|>


<commit_before>
import Permission from './Permission'
import {ForbiddenAPIError, UnauthorizedAPIError, BadRequestAPIError} from './APIError'
import yayson from 'yayson'
import router from './Router'
import Meta from './Meta'
let config = require('../../config')

/**
 * @class
 * Base class for FuelRats API endpoints
 */
export default class API {

  getReadPermissionForEntity () {
    return []
  }

  getWritePermissionForEntity () {
    return []
  }

  hasReadPermission (ctx, entity) {
    return Permission.granted(this.getReadPermissionForEntity(ctx, entity), ctx.state.user, ctx.state.scope)
  }

  hasWritePermission (ctx, entity) {
    return Permission.granted(this.getWritePermissionForEntity(ctx, entity), ctx.state.user, ctx.state.scope)
  }

  requireReadPermission (ctx, entity) {
    if (!this.hasReadPermission(ctx, entity)) {
      throw new ForbiddenAPIError({})
    }
  }

  requireWritePermission (ctx, entity) {
    if (!this.hasWritePermission(ctx, entity)) {
      throw new ForbiddenAPIError({})
    }
  }

  static get presenter () {
    return yayson({
      adapter: 'sequelize'
    }).Presenter
  }

  static meta (result, query = null, additionalParameters = {}) {
    return new Meta(result, query, additionalParameters)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router GET endpoint
 * @param route the http path to route
 * @returns {Function} An ESNExt decorator function
 */
export function GET (route) {
  return function (target, name, descriptor) {
    router.get(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router post endpoint
 * @param route
 * @returns {Function}
 */
export function POST (route) {
  return function (target, name, descriptor) {
    router.post(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router PUT endpoint
 * @param route
 * @returns {Function}
 */
export function PUT (route) {
  return function (target, name, descriptor) {
    router.put(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router DELETE endpoint
 * @param route
 * @returns {Function}
 */
export function DELETE (route) {
  return function (target, name, descriptor) {
    router.del(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for requiring authentication on an endpoint
 */
export function authenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (ctx.state.user) {
      return endpoint.apply(target, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator for requiring client authentication on an endpoint
 */
export function clientAuthenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (ctx.state.client) {
      return endpoint.apply(this, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator for requiring IP address authentication on an endpoint
 */
export function IPAuthenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (config.whitelist.includes(ctx.inet)) {
      return endpoint.apply(this, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator requiring a set of permissions for an API endpoint
 * @param permissions the permissions to require
 * @returns {Function} A decorator function
 */
export function permissions (...permissions) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      if (Permission.granted(permissions, ctx.state.user, ctx.state.scope)) {
        return endpoint.apply(this, arguments)
      } else {
        throw new ForbiddenAPIError({})
      }
    }
  }
}

/**
 * ESNext Decorator for requiring query parameters in an endpoint
 * @param fields The query parameters to require
 * @returns {Function} A decorator function
 */
export function parameters (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      let missingFields = fields.filter((requiredField) => {
        return ctx.params.hasOwnProperty(requiredField) === false
      })
      if (missingFields.length > 0) {
        throw missingFields.map((field) => {
          return new BadRequestAPIError({ parameter: field })
        })
      }
      return endpoint.apply(this, arguments)
    }
  }
}

/**
 * ESNext Decorator for requiring data fields in an endpoint
 * @param fields The data fields to require
 * @returns {Function} A decorator function
 *
 */
export function required (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      let missingFields = fields.filter((requiredField) => {
        return ctx.data.hasOwnProperty(requiredField) === false
      })
      if (missingFields.length > 0) {
        throw missingFields.map((field) => {
          return new BadRequestAPIError({ pointer: `/data/attributes/${field}` })
        })
      }
      return endpoint.apply(this, arguments)
    }
  }
}

/**
 * ESNext Decorator for disallowing a set of data fields in an endpoint
 * @param fields The data fields to disallow
 * @returns {Function} A decorator function
 */
export function disallow (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
        fields.map((cleanField) => {
          delete ctx.data[cleanField]
        })
      }
      return endpoint.apply(target, arguments)
    }
  }
}

<commit_msg>Add a sexy decorator function that allows us to restrict specific fields in an endpoint with different permissions<commit_after>
import Permission from './Permission'
import {ForbiddenAPIError, UnauthorizedAPIError, BadRequestAPIError} from './APIError'
import yayson from 'yayson'
import router from './Router'
import Meta from './Meta'
let config = require('../../config')

/**
 * @class
 * Base class for FuelRats API endpoints
 */
export default class API {

  getReadPermissionForEntity () {
    return []
  }

  getWritePermissionForEntity () {
    return []
  }

  hasReadPermission (ctx, entity) {
    return Permission.granted(this.getReadPermissionForEntity(ctx, entity), ctx.state.user, ctx.state.scope)
  }

  hasWritePermission (ctx, entity) {
    return Permission.granted(this.getWritePermissionForEntity(ctx, entity), ctx.state.user, ctx.state.scope)
  }

  requireReadPermission (ctx, entity) {
    if (!this.hasReadPermission(ctx, entity)) {
      throw new ForbiddenAPIError({})
    }
  }

  requireWritePermission (ctx, entity) {
    if (!this.hasWritePermission(ctx, entity)) {
      throw new ForbiddenAPIError({})
    }
  }

  static get presenter () {
    return yayson({
      adapter: 'sequelize'
    }).Presenter
  }

  static meta (result, query = null, additionalParameters = {}) {
    return new Meta(result, query, additionalParameters)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router GET endpoint
 * @param route the http path to route
 * @returns {Function} An ESNExt decorator function
 */
export function GET (route) {
  return function (target, name, descriptor) {
    router.get(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router post endpoint
 * @param route
 * @returns {Function}
 */
export function POST (route) {
  return function (target, name, descriptor) {
    router.post(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router PUT endpoint
 * @param route
 * @returns {Function}
 */
export function PUT (route) {
  return function (target, name, descriptor) {
    router.put(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for routing this method through a koa router DELETE endpoint
 * @param route
 * @returns {Function}
 */
export function DELETE (route) {
  return function (target, name, descriptor) {
    router.del(route, descriptor.value)
  }
}

/**
 * ESNext Decorator for requiring authentication on an endpoint
 */
export function authenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (ctx.state.user) {
      return endpoint.apply(target, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator for requiring client authentication on an endpoint
 */
export function clientAuthenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (ctx.state.client) {
      return endpoint.apply(this, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator for requiring IP address authentication on an endpoint
 */
export function IPAuthenticated (target, name, descriptor) {
  let endpoint = descriptor.value

  descriptor.value = function (ctx) {
    if (config.whitelist.includes(ctx.inet)) {
      return endpoint.apply(this, arguments)
    } else {
      throw new UnauthorizedAPIError({})
    }
  }
}

/**
 * ESNext Decorator requiring a set of permissions for an API endpoint
 * @param permissions the permissions to require
 * @returns {Function} A decorator function
 */
export function permissions (...permissions) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      if (Permission.granted(permissions, ctx.state.user, ctx.state.scope)) {
        return endpoint.apply(this, arguments)
      } else {
        throw new ForbiddenAPIError({})
      }
    }
  }
}

/**
 * ESNext Decorator for requiring query parameters in an endpoint
 * @param fields The query parameters to require
 * @returns {Function} A decorator function
 */
export function parameters (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      let missingFields = fields.filter((requiredField) => {
        return ctx.params.hasOwnProperty(requiredField) === false
      })
      if (missingFields.length > 0) {
        throw missingFields.map((field) => {
          return new BadRequestAPIError({ parameter: field })
        })
      }
      return endpoint.apply(this, arguments)
    }
  }
}

/**
 * ESNext Decorator for requiring data fields in an endpoint
 * @param fields The data fields to require
 * @returns {Function} A decorator function
 *
 */
export function required (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      let missingFields = fields.filter((requiredField) => {
        return ctx.data.hasOwnProperty(requiredField) === false
      })
      if (missingFields.length > 0) {
        throw missingFields.map((field) => {
          return new BadRequestAPIError({ pointer: `/data/attributes/${field}` })
        })
      }
      return endpoint.apply(this, arguments)
    }
  }
}

/**
 * ESNext Decorator for disallowing a set of data fields in an endpoint
 * @param fields The data fields to disallow
 * @returns {Function} A decorator function
 */
export function disallow (...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      if (Array.isArray(ctx.data) || typeof ctx.data === 'object') {
        fields.map((cleanField) => {
          delete ctx.data[cleanField]
        })
      }
      return endpoint.apply(target, arguments)
    }
  }
}

/**
 * Protect a set of fields in an endpoint with a specific permission
 * @param permission the permission to require
 * @param fields the fields to require this permission for
 * @returns {Function} A decorator function
 */
export function protect (permission, ...fields) {
  return function (target, name, descriptor) {
    let endpoint = descriptor.value

    descriptor.value = function (ctx) {
      if (ctx.data) {
        fields.map(field => {
          if (!ctx.data[field]) {
            return
          }

          if (!Permission.Permission.granted(permissions, ctx.state.user, ctx.state.scope)) {
            throw new ForbiddenAPIError({})
          }
        })
      }
      return endpoint.apply(target, arguments)
    }
  }
}
<|endoftext|>


<commit_before>import React from 'react'
import styled, { withComponent } from 'react-emotion'
import { space } from 'styled-system'
import { Box, Text } from '../components/Layout'
import { Title, Subtitle, Paragraph, Rule } from '../components/Typography'
import ProjectPreview from '../components/ProjectPreview'

const SectionTitle = Text.withComponent('h3')

const indexPage = ({ data }) => {
  return (

        <Title
          fontSize={[4, 5]}
          fontWeight="7"
          lineHeight="title"
          mt={0}
          mb={3}
        >
          Hi! I’m Alec Lomas.
        </Title>
        <Subtitle fontSize={[3, 4]} fontWeight="5" lineHeight="title" my={3}>
          I’m a frontend developer & designer at{' '}

            <Text color="black" hover={{ color: 'orange' }}>
              Fuel Made
            </Text>.

        </Subtitle>
        <Paragraph fontSize={[2, 3]} lineHeight="copy" mt={3} mb={4}>
          My goal is to combine the principles of classic graphic design with
          the flexible and forward-thinking tenets of the internet. I care
          deeply about legibility, performance, and the open web.
          And burritos.
        </Paragraph>
        <Rule mt={4} mb={5} />

        <SectionTitle
          fontSize={[3, 4]}
          fontWeight="7"
          lineHeight="title"
          mt={5}
          mb={4}
        >
          Latest Project
        </SectionTitle>
        <ProjectPreview
          project={data.allProjectsJson.edges[0].node}
          level="h4"
        />

  )
}

export const pageQuery = graphql`
  query IndexQuery {
    allProjectsJson(limit: 1) {
      edges {
        node {
          title
          description
          website
          repo
        }
      }
    }
  }
`

export default indexPage
<commit_msg>:wheelchair: fix heading levels<commit_after>import React from 'react'
import styled, { withComponent } from 'react-emotion'
import { space } from 'styled-system'
import { Box, Text } from '../components/Layout'
import { Title, Subtitle, Paragraph, Rule } from '../components/Typography'
import ProjectPreview from '../components/ProjectPreview'

const SectionTitle = Text.withComponent('h2')

const indexPage = ({ data }) => {
  return (

        <Title
          fontSize={[4, 5]}
          fontWeight="7"
          lineHeight="title"
          mt={0}
          mb={3}
        >
          Hi! I’m Alec Lomas.
        </Title>
        <Subtitle fontSize={[3, 4]} fontWeight="5" lineHeight="title" my={3}>
          I’m a frontend developer & designer at{' '}

            <Text color="black" hover={{ color: 'orange' }}>
              Fuel Made
            </Text>.

        </Subtitle>
        <Paragraph fontSize={[2, 3]} lineHeight="copy" mt={3} mb={4}>
          My goal is to combine the principles of classic graphic design with
          the flexible and forward-thinking tenets of the internet. I care
          deeply about legibility, performance, and the open web.
          And burritos.
        </Paragraph>
        <Rule mt={4} mb={5} />

        <SectionTitle
          fontSize={[3, 4]}
          fontWeight="7"
          lineHeight="title"
          mt={5}
          mb={4}
        >
          Latest Project
        </SectionTitle>
        <ProjectPreview
          project={data.allProjectsJson.edges[0].node}
          level="h3"
        />

  )
}

export const pageQuery = graphql`
  query IndexQuery {
    allProjectsJson(limit: 1) {
      edges {
        node {
          title
          description
          website
          repo
        }
      }
    }
  }
`

export default indexPage
<|endoftext|>