blob: b43cd360151c2aa10703f4f9b0c12372176f5a15 [file] [log] [blame]
#!/usr/bin/env node
'use strict';
var lie = require('lie');
if (typeof Promise === 'undefined') {
global.Promise = lie; // required for denodeify in node 0.10
}
var denodeify = require('denodeify');
var browserify = require('browserify');
var collapse = require('bundle-collapser/plugin');
var es3ify = require('es3ify');
var rollup = require('rollup');
var derequire = require('derequire');
var fs = require('fs');
var writeFileAsync = denodeify(fs.writeFile);
var renameAsync = denodeify(fs.rename);
var ncp = denodeify(require('ncp').ncp);
var rimraf = denodeify(require('rimraf'));
var mkdirp = denodeify(require('mkdirp'));
var streamToPromise = require('stream-to-promise');
var findit = require('findit');
var spawn = require('child_process').spawn;
var pkg = require('../package.json');
var version = pkg.version;
var external = Object.keys(pkg.dependencies).concat([
'fs', 'crypto', 'events', 'path', 'pouchdb', 'level-sublevel/legacy'
]);
var plugins = ['fruitdown', 'localstorage', 'memory'];
var extras = {
'src/deps/promise.js': 'promise.js',
'src/replicate/checkpointer.js': 'checkpointer.js',
'src/replicate/generateReplicationId.js': 'generateReplicationId.js',
'src/deps/ajax/prequest.js': 'ajax.js',
'src_browser/deps/ajax/prequest.js': 'ajax-browser.js'
};
var currentYear = new Date().getFullYear();
var comments = {
'pouchdb': '// PouchDB ' + version +
'\n// ' +
'\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
'\n// PouchDB may be freely distributed under the Apache license, ' +
'version 2.0.' +
'\n// For all details and documentation:' +
'\n// http://pouchdb.com\n',
'memory': '// PouchDB in-memory plugin ' + version +
'\n// Based on MemDOWN: https://github.com/rvagg/memdown' +
'\n// ' +
'\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
'\n// PouchDB may be freely distributed under the Apache license, ' +
'version 2.0.' +
'\n// For all details and documentation:' +
'\n// http://pouchdb.com\n',
'localstorage': '// PouchDB localStorage plugin ' + version +
'\n// Based on localstorage-down: https://github.com/No9/localstorage-down' +
'\n// ' +
'\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
'\n// PouchDB may be freely distributed under the Apache license, ' +
'version 2.0.' +
'\n// For all details and documentation:' +
'\n// http://pouchdb.com\n',
'fruitdown': '// PouchDB fruitdown plugin ' + version +
'\n// Based on FruitDOWN: https://github.com/nolanlawson/fruitdown' +
'\n// ' +
'\n// (c) 2012-' + currentYear + ' Dale Harvey and the PouchDB team' +
'\n// PouchDB may be freely distributed under the Apache license, ' +
'version 2.0.' +
'\n// For all details and documentation:' +
'\n// http://pouchdb.com\n'
};
function writeFile(filename, contents) {
var tmp = filename + '.tmp';
return writeFileAsync(tmp, contents, 'utf-8').then(function () {
return renameAsync(tmp, filename);
}).then(function () {
console.log('Wrote ' + filename);
});
}
function addVersion(code) {
return code.replace('__VERSION__', version);
}
// do uglify in a separate process for better perf
function doUglify(code, prepend, fileOut) {
var binPath = require.resolve('uglify-js/bin/uglifyjs');
var args = [binPath, '-c', '-m', 'warnings=false', '-'];
var child = spawn(process.execPath, args, {stdio: 'pipe'});
child.stdin.setEncoding('utf-8');
child.stdin.write(code);
child.stdin.end();
return streamToPromise(child.stdout).then(function (min) {
min = prepend + min;
return writeFile(fileOut, min);
});
}
function doBrowserify(path, opts, exclude) {
var b = browserify(path, opts);
b.transform(es3ify).plugin(collapse);
if (exclude) {
b.external(exclude);
}
return streamToPromise(b.bundle()).then(function (code) {
code = derequire(code);
return code;
});
}
function doRollup(entry, fileOut) {
return rollup.rollup({
entry: entry,
external: external
}).then(function (bundle) {
var code = bundle.generate({format: 'cjs'}).code;
return writeFile(fileOut, addVersion(code));
});
}
// build for Node (index.js)
function buildForNode() {
return mkdirp('lib').then(function() {
return doRollup('src/index.js', 'lib/index.js');
});
}
// build for Browserify/Webpack (index-browser.js)
function buildForBrowserify() {
return ncp('src', 'src_browser').then(function () {
return new Promise(function (resolve, reject) {
var files = [];
findit('src_browser').on('file', function (file) {
if (/-browser.js$/.test(file)) {
files.push(file);
}
}).on('end', function () {
resolve(files);
}).on('error', reject);
});
}).then(function (files) {
return Promise.all(files.map(function (file) {
return renameAsync(file, file.replace('-browser', ''));
}));
}).then(function () {
return doRollup('src_browser/index.js', 'lib/index-browser.js');
});
}
// build for the browser (dist)
function buildForBrowser() {
return mkdirp('dist').then(function() {
return doBrowserify('.', {standalone: 'PouchDB'});
}).then(function (code) {
code = comments.pouchdb + code;
return Promise.all([
writeFile('dist/pouchdb.js', code),
doUglify(code, comments.pouchdb, 'dist/pouchdb.min.js')
]);
});
}
function buildPerformanceBundle() {
return doBrowserify('tests/performance', {
debug: true,
fullPaths: true
}).then(function (code) {
return writeFile('tests/performance-bundle.js', code);
});
}
function cleanup() {
return rimraf('src_browser');
}
function buildPluginsForBrowserify() {
return mkdirp('lib/extras').then(function() {
return Promise.all(plugins.map(function (plugin) {
return doRollup('src_browser/plugins/' + plugin + '/index.js',
'lib/extras/' + plugin + '.js');
}));
});
}
function buildExtras() {
return mkdirp('lib/extras').then(function() {
return Promise.all(Object.keys(extras).map(function (entry) {
var target = extras[entry];
return doRollup(entry, 'lib/extras/' + target);
}));
});
}
function buildPluginsForBrowser() {
return mkdirp('lib/extras').then(function() {
return Promise.all(plugins.map(function (plugin) {
var source = 'lib/extras/' + plugin + '.js';
return doBrowserify(source, {}, 'pouchdb').then(function (code) {
code = comments[plugin] + code;
return Promise.all([
writeFile('dist/pouchdb.' + plugin + '.js', code),
doUglify(code, comments[plugin], 'dist/pouchdb.' + plugin + '.min.js')
]);
});
}));
});
}
if (process.argv[2] === 'node') {
buildForNode();
return;
}
Promise.resolve()
.then(function () { return rimraf('lib'); })
.then(function () { return rimraf('dist'); })
.then(buildForNode)
.then(buildForBrowserify)
.then(buildForBrowser)
.then(buildPluginsForBrowserify)
.then(buildPluginsForBrowser)
.then(buildExtras)
.then(buildPerformanceBundle)
.then(cleanup)
.catch(function (err) {
console.log(err.stack);
process.exit(1);
}
);