bitwarden-estensione-browser/gulpfile.js

527 lines
15 KiB
JavaScript

var gulp = require('gulp'),
rimraf = require('rimraf'),
concat = require('gulp-concat'),
rename = require('gulp-rename'),
less = require('gulp-less'),
preprocess = require('gulp-preprocess'),
runSequence = require('run-sequence'),
jshint = require('gulp-jshint'),
merge = require('merge-stream'),
browserify = require('browserify'),
source = require('vinyl-source-stream'),
googleWebFonts = require('gulp-google-webfonts'),
webpack = require('webpack-stream'),
jeditor = require("gulp-json-editor"),
gulpUtil = require('gulp-util'),
child = require('child_process'),
zip = require('gulp-zip'),
manifest = require('./src/manifest.json'),
xmlpoke = require('gulp-xmlpoke'),
embedTemplates = require('gulp-angular-embed-templates');
var paths = {};
paths.dist = './dist/';
paths.libDir = './src/lib/';
paths.npmDir = './node_modules/';
paths.popupDir = './src/popup/';
paths.lessDir = paths.popupDir + 'less/';
paths.cssDir = paths.popupDir + 'css/';
gulp.task('lint', function () {
return gulp.src([
paths.popupDir + '**/*.js',
'./src/services/**/*.js',
'./src/notification/**/*.js',
'./src/models/**/*.js',
'./src/scripts/**/*.js',
//'./src/content/**/*.js',
'./src/overlay/**/*.js',
'./src/background.js'
])
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('build', function (cb) {
return runSequence(
'clean',
['browserify', 'webpack', 'lib', 'less', 'lint', 'webfonts'],
cb);
});
gulp.task('clean:css', function (cb) {
return rimraf(paths.cssDir, cb);
});
gulp.task('clean:lib', function (cb) {
return rimraf(paths.libDir, cb);
});
gulp.task('clean', ['clean:css', 'clean:lib']);
gulp.task('lib', ['clean:lib'], function () {
var libs = [
{
src: [
paths.npmDir + 'bootstrap/dist/**/*',
'!' + paths.npmDir + 'bootstrap/dist/**/npm.js',
'!' + paths.npmDir + 'bootstrap/dist/**/css/*theme*',
'!' + paths.npmDir + 'bootstrap/**/*.min*'
],
dest: paths.libDir + 'bootstrap'
},
{
src: paths.npmDir + 'font-awesome/css/font-awesome.css',
dest: paths.libDir + 'font-awesome/css'
},
{
src: paths.npmDir + 'font-awesome/fonts/*',
dest: paths.libDir + 'font-awesome/fonts'
},
{
src: paths.npmDir + 'jquery/dist/jquery.js',
dest: paths.libDir + 'jquery'
},
{
src: paths.npmDir + 'angular/angular.js',
dest: paths.libDir + 'angular'
},
{
src: paths.npmDir + 'angular-animate/angular-animate.js',
dest: paths.libDir + 'angular-animate'
},
{
src: paths.npmDir + 'angular-ui-router/release/angular-ui-router.js',
dest: paths.libDir + 'angular-ui-router'
},
{
src: [paths.npmDir + 'angular-toastr/dist/angular-toastr.tpls.js',
paths.npmDir + 'angular-toastr/dist/angular-toastr.css'],
dest: paths.libDir + 'angular-toastr'
},
{
src: paths.npmDir + 'ngclipboard/dist/ngclipboard.js',
dest: paths.libDir + 'ngclipboard'
},
{
src: paths.npmDir + 'clipboard/dist/clipboard.js',
dest: paths.libDir + 'clipboard'
},
{
src: paths.npmDir + 'q/q.js',
dest: paths.libDir + 'q'
},
{
src: [paths.npmDir + 'sweetalert/dist/sweetalert.css', paths.npmDir + 'sweetalert/dist/sweetalert-dev.js',
paths.npmDir + 'angular-sweetalert/SweetAlert.js'],
dest: paths.libDir + 'sweetalert'
},
{
src: [paths.npmDir + 'angulartics-google-analytics/lib/angulartics*.js',
paths.npmDir + 'angulartics/src/angulartics.js'
],
dest: paths.libDir + 'angulartics'
},
{
src: paths.npmDir + 'ng-infinite-scroll/build/ng-infinite-scroll.js',
dest: paths.libDir + 'ng-infinite-scroll'
},
{
src: paths.npmDir + 'papaparse/papaparse.js',
dest: paths.libDir + 'papaparse'
}
];
var tasks = libs.map(function (lib) {
return gulp.src(lib.src).pipe(gulp.dest(lib.dest));
});
return merge(tasks);
});
gulp.task('browserify', ['browserify:tldjs']);
gulp.task('browserify:tldjs', function () {
return browserify(paths.npmDir + 'tldjs/index.js', { standalone: 'tldjs' })
.bundle()
.pipe(source('tld.js'))
.pipe(gulp.dest(paths.libDir + 'tldjs'));
});
gulp.task('webpack', ['webpack:forge']);
gulp.task('webpack:forge', function () {
var forgeDir = paths.npmDir + '/node-forge/lib/';
return gulp.src([
forgeDir + 'pbkdf2.js',
forgeDir + 'aes.js',
forgeDir + 'hmac.js',
forgeDir + 'sha256.js',
forgeDir + 'random.js',
forgeDir + 'forge.js'
]).pipe(webpack({
output: {
filename: 'forge.js',
library: 'forge',
libraryTarget: 'umd'
},
node: {
Buffer: false,
process: false,
crypto: false,
setImmediate: false
}
})).pipe(gulp.dest(paths.libDir + 'forge'));
});
gulp.task('less', function () {
return gulp.src(paths.lessDir + 'popup.less')
.pipe(less())
.pipe(gulp.dest(paths.cssDir));
});
gulp.task('watch', function () {
gulp.watch(paths.lessDir + '*.less', ['less']);
});
gulp.task('dist:clean', function (cb) {
return rimraf(paths.dist + '**/*', cb);
});
gulp.task('dist:move', function () {
var moves = [
{
src: 'src/_locales/**/*',
dest: paths.dist + '_locales'
},
{
src: [
'src/content/**/*',
'!src/content/field.js',
'!src/content/overlay.js'
],
dest: paths.dist + 'content'
},
{
src: 'src/images/**/*',
dest: paths.dist + 'images'
},
{
src: 'src/notification/**/*',
dest: paths.dist + 'notification'
},
{
src: 'src/popup/index.html',
dest: paths.dist + 'popup'
},
{
src: 'src/popup/css/webfonts/**/*',
dest: paths.dist + 'popup/css/webfonts'
},
{
src: paths.libDir + 'font-awesome/fonts/**/*',
dest: paths.dist + 'popup/fonts'
},
{
src: 'src/services/**/*',
dest: paths.dist + 'services'
},
{
src: paths.libDir + 'forge/**/*',
dest: paths.dist + 'lib/forge'
},
{
src: paths.libDir + 'jquery/**/*',
dest: paths.dist + 'lib/jquery'
},
{
src: paths.libDir + 'tldjs/**/*',
dest: paths.dist + 'lib/tldjs'
},
{
src: paths.libDir + 'q/**/*',
dest: paths.dist + 'lib/q'
},
{
src: 'src/models/**/*',
dest: paths.dist + 'models'
},
{
src: 'src/scripts/analytics.js',
dest: paths.dist + 'scripts'
},
{
src: [
'src/background.*',
'src/manifest.json'
],
dest: paths.dist
}
];
var tasks = moves.map(function (move) {
return gulp.src(move.src).pipe(gulp.dest(move.dest));
});
return merge(tasks);
});
gulp.task('dist:css', function () {
distCss({});
});
gulp.task('dist:css:edge', function () {
distCss({ edge: true });
});
gulp.task('dist:css:firefox', function () {
distCss({ firefox: true });
});
function distCss(preprocessContext) {
return gulp
.src([
// libs
paths.libDir + '**/*.css',
'!' + paths.libDir + '**/*.min.css',
// app
paths.cssDir + 'popup.css',
paths.cssDir + 'webfonts.css'
])
.pipe(preprocess({ context: preprocessContext }))
.pipe(concat(paths.dist + 'popup/css/popup.css'))
.pipe(gulp.dest('.'));
}
gulp.task('dist:js', function () {
return distJs(false);
});
gulp.task('dist:js:edge', function () {
return distJs(true);
});
function distJs(edge) {
var appTask = gulp
.src([
// models/scripts
'./src/models/**/*.js',
'./src/scripts/*.js',
// app
paths.popupDir + 'app/app.js',
paths.popupDir + 'app/**/*Module.js',
paths.popupDir + 'app/**/*.js'
])
.pipe(embedTemplates({
basePath: './src/popup/',
minimize: { empty: true }
}))
.pipe(concat(paths.dist + 'popup/app.js'))
.pipe(gulp.dest('.'));
var libTask = gulp
.src([
paths.libDir + 'jquery/jquery.js',
paths.libDir + 'bootstrap/js/bootstrap.js',
edge ? './src/edge/angular.js' : (paths.libDir + 'angular/angular.js'),
paths.libDir + '**/*.js',
'!' + paths.libDir + 'q/**/*',
'!' + paths.libDir + 'tldjs/**/*',
'!' + paths.libDir + 'forge/**/*',
'!' + paths.libDir + '**/*.min.js'
])
.pipe(concat(paths.dist + 'popup/lib.js'))
.pipe(gulp.dest('.'));
return merge(appTask, libTask);
}
gulp.task('dist:preprocess', function () {
return gulp
.src([
paths.dist + 'popup/index.html'
], { base: '.' })
.pipe(preprocess({ context: {} }))
.pipe(gulp.dest('.'));
});
gulp.task('dist', ['build'], function (cb) {
return dist({}, cb);
});
gulp.task('dist:edge', ['build'], function (cb) {
return dist({ edge: true }, cb);
});
gulp.task('dist:firefox', ['build'], function (cb) {
return dist({ firefox: true }, cb);
});
function dist(o, cb) {
var distCss = o.edge ? 'dist:css:edge' : o.firefox ? 'dist:css:firefox' : 'dist:css';
var distJs = o.edge ? 'dist:js:edge' : 'dist:js';
return runSequence(
'dist:clean',
['dist:move', distCss, distJs],
'dist:preprocess',
cb);
}
var sidebarActionManifestObj = {
"default_title": "bitwarden",
"default_panel": "popup/index.html?uilocation=sidebar",
"default_icon": "images/icon19.png"
};
gulp.task('dist-firefox', ['dist:firefox'], function (cb) {
gulp.src(paths.dist + 'manifest.json')
.pipe(jeditor(function (manifest) {
manifest.applications = {
gecko: {
id: '{446900e4-71c2-419f-a6a7-df9c091e268b}',
strict_min_version: '42.0'
}
};
manifest['sidebar_action'] = sidebarActionManifestObj;
return manifest;
}))
.pipe(gulp.dest(paths.dist));
return zipDist('dist-firefox');
});
gulp.task('dist-opera', ['dist'], function (cb) {
gulp.src(paths.dist + 'manifest.json')
.pipe(jeditor(function (manifest) {
manifest['sidebar_action'] = sidebarActionManifestObj;
return manifest;
}))
.pipe(gulp.dest(paths.dist));
return zipDist('dist-opera');
});
gulp.task('dist-edge', ['dist:edge'], function (cb) {
// move dist to temp extension folder
new Promise(function (resolve, reject) {
gulp.src(paths.dist + '**/*')
.on('error', reject)
.pipe(gulp.dest('temp/Extension/'))
.on('end', resolve);
}).then(function () {
// move windows store files to temp folder
return new Promise(function (resolve, reject) {
gulp.src('store/windows/**/*')
.on('error', reject)
.pipe(gulp.dest('temp/'))
.on('end', resolve);
});
}).then(function () {
// delete dist folder
return new Promise(function (resolve, reject) {
rimraf(paths.dist, function () {
resolve();
})
});
}).then(function () {
// move temp back to dist
return new Promise(function (resolve, reject) {
gulp.src('temp/**/*')
.on('error', reject)
.pipe(gulp.dest(paths.dist))
.on('end', resolve);
});
}).then(function () {
// delete temp folder
return new Promise(function (resolve, reject) {
rimraf('temp', function () {
resolve();
})
});
}).then(function () {
// move src edge folder to dist
return new Promise(function (resolve, reject) {
gulp.src(['src/edge/**/*', '!src/edge/angular.js'])
.on('error', reject)
.pipe(gulp.dest(paths.dist + 'Extension/edge'))
.on('end', resolve);
});
}).then(function () {
// modify manifest with edge preload stuff
return new Promise(function (resolve, reject) {
gulp.src(paths.dist + 'Extension/manifest.json')
.pipe(jeditor(function (manifest) {
manifest['-ms-preload'] = {
backgroundScript: 'edge/backgroundScriptsAPIBridge.js',
contentScript: 'edge/contentScriptsAPIBridge.js'
};
return manifest;
}))
.on('error', reject)
.pipe(gulp.dest(paths.dist + 'Extension'))
.on('end', resolve);
});
}).then(function () {
// modify appxmanifest
return new Promise(function (resolve, reject) {
gulp.src(paths.dist + '/AppxManifest.xml')
.pipe(xmlpoke({
replacements: [{
xpath: '/p:Package/p:Identity/@Version',
value: manifest.version + '.0',
namespaces: {
'p': 'http://schemas.microsoft.com/appx/manifest/foundation/windows10'
}
}]
}))
.on('error', reject)
.pipe(gulp.dest(paths.dist))
.on('end', resolve);
});
}).then(function () {
// makeappx.exe must be in your system's path already
child.spawn('makeappx.exe', ['pack', '/h', 'SHA256', '/d', paths.dist, '/p', paths.dist + 'bitwarden.appx']);
cb();
}, function () {
cb();
});
});
gulp.task('dist-other', ['dist'], function (cb) {
return zipDist('dist-other');
});
function zipDist(fileName) {
return gulp.src(paths.dist + '**/*')
.pipe(zip(fileName + '.zip'))
.pipe(gulp.dest(paths.dist));
}
gulp.task('webfonts', function () {
return gulp.src('./webfonts.list')
.pipe(googleWebFonts({
fontsDir: 'webfonts',
cssFilename: 'webfonts.css'
}))
.pipe(gulp.dest(paths.cssDir));
});
function npmCommand(commands, cb) {
var npmLogger = (buffer) => {
buffer.toString()
.split(/\n/)
.forEach((message) => gulpUtil.log(message));
};
var npmCommand = process.platform === 'win32' ? 'npm.cmd' : 'npm';
var npmChild = child.spawn(npmCommand, commands);
npmChild.stdout.on('data', npmLogger);
npmChild.stderr.on('data', npmLogger);
npmChild.stderr.on('close', cb);
return npmChild;
}
gulp.task('webext:firefox', function (cb) {
return npmCommand(['run', 'start:firefox'], cb);
});