feat: next

This commit is contained in:
calebboyd
2017-04-09 14:26:29 -05:00
parent 72afbe68a4
commit 7668d7b471
50 changed files with 1932 additions and 1563 deletions
+8
View File
@@ -0,0 +1,8 @@
root = true
[*]
end_of_line = lf
charset = utf-8
indent_style = space
indent_size = 2
trim_trailing_whitespace=true
insert_final_newline = true
+146
View File
@@ -0,0 +1,146 @@
{
"env": {
"node": true,
"es6": true
},
"rules": {
"comma-dangle": [2,"never"],
"no-cond-assign": [2,"except-parens"],
"no-console": 2,
"no-constant-condition": 2,
"no-control-regex": 2,
"no-debugger": 2,
"no-dupe-keys": 2,
"no-dupe-class-members": 2,
"no-duplicate-imports": 2,
"no-empty": 2,
"no-empty-character-class": 2,
"no-ex-assign": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": 2,
"no-extra-semi": 2,
"no-func-assign": 2,
"no-inner-declarations": 2,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-negated-in-lhs": 2,
"no-obj-calls": 2,
"no-regex-spaces": 2,
"no-reserved-keys": 0,
"no-sparse-arrays": 2,
"no-unreachable": 2,
"use-isnan": 2,
"valid-jsdoc": 0,
"valid-typeof": 2,
"prefer-const": 2,
"block-scoped-var": 0,
"complexity": 0,
"consistent-return": 2,
"curly": [2,"multi-line"],
"default-case": 0,
"dot-notation": 2,
"eqeqeq": 2,
"guard-for-in": 0,
"no-alert": 2,
"no-caller": 2,
"no-div-regex": 2,
"no-else-return": 2,
"no-eq-null": 2,
"no-eval": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-implied-eval": 2,
"no-iterator": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-loop-func": 2,
"no-multi-spaces": 2,
"no-multi-str": 0,
"no-native-reassign": 0,
"no-new": 0,
"no-new-func": 2,
"no-new-wrappers": 2,
"no-octal": 0,
"no-octal-escape": 0,
"no-process-env": 0,
"no-proto": 0,
"no-redeclare": 2,
"no-return-assign": 0,
"no-script-url": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-throw-literal": 2,
"no-unused-expressions": 0,
"no-void": 0,
"no-warning-comments": [2, { "terms": ["FIXME"]}],
"no-with": 2,
"radix": 2,
"vars-on-top": 0,
"wrap-iife": 2,
"yoda": 0,
"no-catch-shadow": 2,
"no-delete-var": 2,
"no-label-var": 2,
"no-shadow": 2,
"no-shadow-restricted-names": 2,
"no-undef": 2,
"no-undef-init": 2,
"no-undefined": 2,
"no-unused-vars": 2,
"no-use-before-define": 2,
"strict": [2, "never"],
"handle-callback-err": 2,
"no-new-require": 2,
"no-path-concat": 2,
"no-process-exit": 0,
"no-restricted-modules": 0,
"no-sync": 2,
"indent": [2, 2],
"brace-style": [2,"1tbs"],
"camelcase": 0,
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": 2,
"consistent-this": 0,
"eol-last": 2,
"func-names": 0,
"func-style": 0,
"key-spacing": [2, {"beforeColon": false, "afterColon": true}],
"linebreak-style": [2, "unix"],
"max-nested-callbacks": [2, 3],
"new-parens": 2,
"no-array-constructor": 2,
"no-inline-comments": 0,
"no-lonely-if": 2,
"no-mixed-spaces-and-tabs": 2,
"no-multiple-empty-lines": [2, {"max": 1}],
"no-nested-ternary": 2,
"no-new-object": 2,
"semi-spacing": [2, {"before": false, "after": true}],
"no-spaced-func": 2,
"no-ternary": 0,
"no-trailing-spaces": 2,
"no-underscore-dangle": 0,
"operator-assignment": [2, "always"],
"padded-blocks": 0,
"quote-props": 0,
"quotes": [2, "single", "avoid-escape"],
"semi": [2, "never"],
"sort-vars": 0,
"keyword-spacing": [2, { "before": true, "after": true}],
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, "always"],
"object-curly-spacing": [2, "always"],
"array-bracket-spacing": [2, "never"],
"computed-property-spacing": [2, "never"],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": false, "nonwords": false }],
"spaced-line-comment": 0,
"wrap-regex": 0,
"require-await": 2,
"no-var": 0,
"generator-star": 0
}
}
+4 -11
View File
@@ -1,15 +1,8 @@
.DS_Store
temp/
node_modules
npm-debug.log
test/**/src
test/**/out.nex
test/**/test.nex
test/**/tmp
test/**/node_modules
test/**/*.map
test/src
test/test.log
test-results.xml
src
*.log
*.exe
.idea
.nexe
-3
View File
@@ -1,3 +0,0 @@
node_modules
test
src
+1 -2
View File
@@ -12,7 +12,7 @@
* Gave win32 a 100 length progress bar.
### Commits
* [**2cacd83**] Update README.md (@crcn)
* [**0e90ac9**] Update README.md (@crcn)
* [**54967d1**] Added Gitter badge (@jaredallard)
@@ -36,7 +36,6 @@
## 2015-02-14, Version v0.3.5, @jaredallard
### Noteable Changes
* Added new flag: `--python </path/to/python>`
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2013 Craig Condon
Copyright (c) 2013-2017 Nexe Contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
-115
View File
@@ -1,115 +0,0 @@
#!/usr/bin/env node
var path = require('path'),
fs = require('fs'),
nexe = require('../lib'),
_log = require("../lib/log"),
cli = require('yargs').
usage('Usage: $0 -i [sources] -o [binary]').
options('i', {
demand: true,
alias: 'input',
desc: 'The entry javascript files',
default: process.cwd()
}).
options('o', {
demand: true,
alias: 'output',
desc: 'The output binary',
default: "out.nex"
}).
options('r', {
alias: 'runtime',
default: 'latest',
description: 'The node.js runtime to use'
}).
options('t', {
alias: 'temp',
default: './tmp/nexe',
description: 'The path to store node.js sources'
}).
options('f', {
alias: 'flags',
description: 'Don\'t parse node and v8 flags, pass through app flags',
default: false
}).
options('d', {
alias: 'debug',
default: false,
description: 'generate and use source maps, large file size'
}).
options('j', {
alias: 'jsFlags',
default: false,
description: 'v8 flags for runtime'
}).
options('v', {
alias: 'version',
description: 'Display version number'
}).
options('p', {
alias: 'python',
description: 'Set path of python to use.',
default: 'python'
}).
options('F', {
alias: 'framework',
description: 'Set the framework to use',
default: 'nodejs'
});
var argv = cli.argv;
if (argv.h || argv.help) {
cli.showHelp();
process.exit();
} else if (argv.v || argv.version) {
var pkginfo = require('../package.json');
console.log(pkginfo.version);
process.exit();
}
/**
* TODO: Support network shares?
**/
function toAbsolute(pt) {
//already resolved?
try{
fs.accessSync(pt,fs.F_OK);
return pt;
}catch(e){}
if (pt.substr(0, 1) == "/") return pt; // for *nix "/"
if (pt.substr(0, 2) == "\\\\") return pt; // for windows "\\"
if (pt.substr(1, 3) == ":/") return pt; // for windows "c:/"
// otherwise...
return path.join(process.cwd(), pt);
}
if (fs.lstatSync(argv.i).isDirectory()) {
opts = nexe.package(path.join(argv.i, "package.json"), argv);
nexe.compile(opts, function(error) {
if (error) {
return console.log(error.message);
}
});
} else {
/**
* Call the core
**/
nexe.compile({
input: require.resolve(toAbsolute(argv.i)),
output: toAbsolute(argv.o),
flags: argv.f,
nodeVersion: argv.r,
python: argv.python,
nodeTempDir: toAbsolute(argv.t),
framework: argv.F
},
function(error) {
if (error) {
return console.log(error.message);
}
}
);
}
-8
View File
@@ -1,8 +0,0 @@
machine:
node:
version: 5.7.0
test:
override:
- npm test:
timeout: 5400
+11
View File
@@ -0,0 +1,11 @@
#!/usr/bin/env node
const nexe = require('.'),
logger = require('./src/logger').logger
module.exports = nexe
if (require.main === module) {
nexe.compile(nexe.options).catch((e) => {
logger.error(e.stack, () => process.exit(1))
})
}
+99
View File
@@ -0,0 +1,99 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _path = require('path');
var _fs = require('fs');
var _util = require('./util');
var _bluebird = require('bluebird');
var _mkdirp = require('mkdirp');
var _mkdirp2 = _interopRequireDefault(_mkdirp);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const mkdirpAsync = (0, _bluebird.promisify)(_mkdirp2.default);
const statAsync = (0, _bluebird.promisify)(_fs.stat);
const unlinkAsync = (0, _bluebird.promisify)(_fs.unlink);
const readdirAsync = (0, _bluebird.promisify)(_fs.readdir);
function readDirAsync(dir) {
return readdirAsync(dir).map(file => {
const path = (0, _path.join)(dir, file);
return statAsync(path).then(s => s.isDirectory() ? readDirAsync(path) : path);
}).reduce((a, b) => a.concat(b), []);
}
function maybeReadFileContents(file) {
return (0, _util.readFileAsync)(file, 'utf-8').catch(e => {
if (e.code === 'ENOENT') {
return '';
}
throw e;
});
}
/**
* The artifacts step is where source patches are committed, or written as "artifacts"
* Steps:
* - A temporary directory is created in the downloaded source
* - On start, any files in that directory are restored into the source tree
* - After the patch functions have run, the temporary directory is emptied
* - Original versions of sources to be patched are written to the temporary directory
* - Finally, The patched files are written into source.
*
*/
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const { src } = compiler;
const temp = (0, _path.join)(src, 'nexe');
yield mkdirpAsync(temp);
const tmpFiles = yield readDirAsync(temp);
yield (0, _bluebird.map)(tmpFiles, (() => {
var _ref2 = _asyncToGenerator(function* (path) {
return compiler.writeFileAsync(path.replace(temp, ''), (yield (0, _util.readFileAsync)(path)));
});
return function (_x3) {
return _ref2.apply(this, arguments);
};
})());
yield next();
yield (0, _bluebird.map)(tmpFiles, function (x) {
return unlinkAsync(x);
});
return (0, _bluebird.map)(compiler.files, (() => {
var _ref3 = _asyncToGenerator(function* (file) {
const sourceFile = (0, _path.join)(src, file.filename);
const tempFile = (0, _path.join)(temp, file.filename);
const fileContents = yield maybeReadFileContents(sourceFile);
yield mkdirpAsync((0, _path.dirname)(tempFile));
yield (0, _util.writeFileAsync)(tempFile, fileContents);
yield compiler.writeFileAsync(file.filename, file.contents);
});
return function (_x4) {
return _ref3.apply(this, arguments);
};
})());
});
function artifacts(_x, _x2) {
return _ref.apply(this, arguments);
}
return artifacts;
})();
-137
View File
@@ -1,137 +0,0 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* 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.
*
**/
'use strict';
let browserify = require('browserify'),
path = require("path"),
spawn = require('child_process').spawn,
insertGlobals = require('insert-module-globals'),
fs = require("fs"),
async = require("async"),
_log = require("./log");
/**
* User browserify to create a "packed" file.
*
* @param {string} input - input file
* @param {string} nc - node compiler dir
* @param {array} options - nexe options
* @param {function} complete - next function to call (async)
**/
function bundle(input, nc, options, complete) {
const bundlePath = path.join(nc, "lib", "nexe.js");
const mapfile = options.output+'.map';
let ws = fs.createWriteStream(bundlePath);
const igv = '__filename,__dirname,_process';
let insertGlobalVars = { isNexe: true },
wantedGlobalVars = igv.split(',');
// parse insertGlobalVars.
Object.keys(insertGlobals.vars).forEach(function (x) {
if (wantedGlobalVars.indexOf(x) === -1) {
insertGlobalVars[x] = undefined;
}
});
let paths = [path.join(nc, 'lib')];
if(options.browserifyPaths) {
paths = paths.concat(options.browserifyPaths);
}
_log('executing browserify via API');
let bproc = browserify([input], {
debug: options.debug,
commondir: false,
paths: paths,
builtins: false,
insertGlobalVars: insertGlobalVars,
detectGlobals: true,
browserField: false
});
if (options.browserifyExcludes && Array.isArray(options.browserifyExcludes)) {
for (let i = 0; i < options.browserifyExcludes.length; i++) {
let lib = options.browserifyExcludes[i];
_log('Excluding \'%s\' from browserify bundle', lib);
bproc.exclude(lib);
}
}
// copy the excludes code for requires for now.
if (options.browserifyRequires && Array.isArray(options.browserifyRequires)) {
for (let i = 0; i < options.browserifyRequires.length; i++) {
let lib = options.browserifyRequires[i];
let name = lib.file || lib; // for object format.
// if `lib` is object then fetch all params without `file`
// otherwise returns empty object
let opts = (lib instanceof Object) && Object.keys(lib)
.filter((key) => key !== 'file')
.reduce((acc, key) => { return acc[key] = lib[key], acc }, {})
|| {};
_log('Force including \'%s\' in browserify bundle', name);
bproc.require(lib, opts);
}
}
if(options.debug) {
bproc.require(require.resolve('source-map-support'))
}
let bprocbun = bproc.bundle() // bundle
.pipe(ws) // pipe to file
// error on require errors, still can't contionue. ffs browserify
bprocbun.on('error', function(err) {
_log('error', '[browserify] '+err);
});
ws.on('error', function(err) {
console.log(err);
_log('error', 'Failed to save stdout to disk');
process.exit(1);
})
ws.on('close', function() {
var source = fs.readFileSync(bundlePath, 'utf8');
source = source.replace(/[^\x00-\x7F]/g, "");
// write the source modified to nexe.js
fs.writeFile(bundlePath, source, 'utf8', function(err) {
if (err) {
_log('error', 'failed to save source');
process.exit(1);
}
complete();
});
});
}
module.exports = bundle;
+94
View File
@@ -0,0 +1,94 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _path = require('path');
var _bluebird = require('bluebird');
var _fs = require('fs');
var _util = require('./util');
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const isWindows = process.platform === 'win32';
function getStdIn() {
return new _bluebird.Promise(resolve => {
const bundle = [];
process.stdin.setEncoding('utf-8');
process.stdin.on('data', x => bundle.push(x));
process.stdin.once('end', () => resolve((0, _util.dequote)(Buffer.concat(bundle).toString())));
process.stdin.resume();
});
}
/**
* The "cli" step detects whether the process is in a tty. If it is then the input is read into memory.
* Otherwise, it is buffered from stdin. If no input options are passed in the tty, the package.json#main file is used.
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
*
* Configuration:
* - compiler.options.input - file path to the input bundle.
* - fallbacks: stdin, package.json#main
* - compiler.options.output - file path to the output executable.
* - fallbacks: stdout, nexe_ + epoch + ext
*
* @param {*} compiler
* @param {*} next
*/
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const input = compiler.options.input;
const bundled = Boolean(compiler.input);
if (bundled) {
yield next();
} else if (!input && !process.stdin.isTTY) {
compiler.log.verbose('Buffering stdin as main module...');
compiler.input = yield getStdIn();
} else if (input) {
compiler.log.verbose('Reading input as main module: ' + input);
compiler.input = yield (0, _util.readFileAsync)((0, _path.normalize)(input));
} else if (!compiler.options.empty) {
compiler.log.verbose('Resolving cwd as main module...');
compiler.input = yield (0, _util.readFileAsync)(require.resolve(process.cwd()));
}
if (!bundled) {
yield next();
}
const deliverable = yield compiler.getDeliverableAsync();
return new _bluebird.Promise(function (resolve, reject) {
deliverable.once('error', reject);
if (!compiler.options.output && !process.stdout.isTTY) {
compiler.log.verbose('Writing result to stdout...');
deliverable.pipe(process.stdout).once('error', reject);
resolve();
} else {
compiler.log.verbose('Writing result to file...');
const output = compiler.options.output || `${compiler.options.name}${isWindows ? '.exe' : ''}`;
deliverable.pipe((0, _fs.createWriteStream)((0, _path.normalize)(output))).once('error', reject).once('close', function (e) {
if (e) {
reject(e);
} else {
resolve(compiler.log.info('Executable written: ' + output));
}
});
}
});
});
function cli(_x, _x2) {
return _ref.apply(this, arguments);
}
return cli;
})();
+111
View File
@@ -0,0 +1,111 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.NexeCompiler = undefined;
var _path = require('path');
var _bluebird = require('bluebird');
var _fs = require('fs');
var _child_process = require('child_process');
var _logger = require('./logger');
var logger = _interopRequireWildcard(_logger);
var _util = require('./util');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const isWindows = process.platform === 'win32';
const isBsd = Boolean(~process.platform.indexOf('bsd'));
const make = isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make';
const configure = isWindows ? 'configure' : './configure';
class NexeCompiler {
constructor(options) {
var _this = this;
this.options = options;
logger.setLevel(options.loglevel);
this.log = logger;
this.python = options.python;
this.configure = options.configure;
this.make = isWindows ? options.vcBuild : options.make;
this.src = (0, _path.join)(options.temp, options.version);
this.env = Object.assign({}, process.env);
this.files = [];
this.readFileAsync = (() => {
var _ref = _asyncToGenerator(function* (file) {
let cachedFile = _this.files.find(function (x) {
return (0, _path.normalize)(x.filename) === (0, _path.normalize)(file);
});
if (!cachedFile) {
cachedFile = {
filename: file,
contents: yield (0, _util.readFileAsync)((0, _path.join)(_this.src, file), 'utf-8').catch({ code: 'ENOENT' }, function () {
return '';
})
};
_this.files.push(cachedFile);
}
return cachedFile;
});
return function (_x) {
return _ref.apply(this, arguments);
};
})();
this.writeFileAsync = (file, contents) => (0, _util.writeFileAsync)((0, _path.join)(this.src, file), contents);
}
set python(pythonPath) {
if (!pythonPath) {
return;
}
if (isWindows) {
this.env.PATH = this.env.PATH + ';"' + (0, _util.dequote)((0, _path.normalize)(pythonPath)) + '"';
} else {
this.env.PYTHON = pythonPath;
}
}
get _deliverableLocation() {
return isWindows ? (0, _path.join)(this.src, 'Release', 'node.exe') : (0, _path.join)(this.src, 'out', 'Release', 'node');
}
_runBuildCommandAsync(command, args) {
return new _bluebird.Promise((resolve, reject) => {
(0, _child_process.spawn)(command, args, {
cwd: this.src,
env: this.env,
stdio: 'ignore'
}).once('error', reject).once('close', resolve);
});
}
_configureAsync() {
return this._runBuildCommandAsync(this.env.PYTHON || 'python', [configure, ...this.configure]);
}
buildAsync() {
var _this2 = this;
return _asyncToGenerator(function* () {
yield _this2._configureAsync();
return _this2._runBuildCommandAsync(make, _this2.make);
})();
}
getDeliverableAsync() {
return _bluebird.Promise.resolve((0, _fs.createReadStream)(this._deliverableLocation));
}
}
exports.NexeCompiler = NexeCompiler;
+84
View File
@@ -0,0 +1,84 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = download;
var _zlib = require('zlib');
var _tar = require('tar');
var _request = require('request');
var _request2 = _interopRequireDefault(_request);
var _bluebird = require('bluebird');
var _fs = require('fs');
var _rimraf = require('rimraf');
var _rimraf2 = _interopRequireDefault(_rimraf);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const statAsync = (0, _bluebird.promisify)(_fs.stat);
const rimrafAsync = (0, _bluebird.promisify)(_rimraf2.default);
function progress(req, log, precision = 10) {
const logged = {};
let length = 0;
let total = 1;
return req.on('response', res => {
total = res.headers['content-length'];
}).on('data', chunk => {
length += chunk.length;
const percentComplete = +(length / total * 100).toFixed();
if (percentComplete % precision === 0 && !logged[percentComplete]) {
logged[percentComplete] = true;
log(percentComplete);
}
});
}
function fetchNodeSource(path, url, log) {
log.info('Downloading Node: ' + url);
return new _bluebird.Promise((resolve, reject) => {
progress(_request2.default.get(url), pc => {
log.verbose(`Downloading Node: ${pc}%...`);
if (pc === 100) {
log.info('Extracting Node...');
}
}).on('error', reject).pipe((0, _zlib.createGunzip)().on('error', reject)).pipe((0, _tar.Extract)({ path, strip: 1 })).on('error', reject).on('end', () => resolve(log.info('Extracted to: ' + path)));
});
}
function cleanSrc(clean, src, log) {
if (clean === true) {
log.info('Removing source: ' + src);
return rimrafAsync(src).then(() => {
log.info('Source deleted.' + src);
});
}
return _bluebird.Promise.resolve();
}
/**
* Deletes (maybe) and downloads the node source to the configured temporary directory
* @param {*} compiler
* @param {*} next
*/
function download(compiler, next) {
const { src, log } = compiler;
const { version, sourceUrl, clean } = compiler.options;
const url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`;
return cleanSrc(clean, src, log).then(() => statAsync(src).then(x => !x.isDirectory() && fetchNodeSource(src, url, log), e => {
if (e.code !== 'ENOENT') {
throw e;
}
return fetchNodeSource(src, url, log);
})).then(next);
}
-73
View File
@@ -1,73 +0,0 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* 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.
*
**/
'use strict';
let path = require("path"),
fs = require("fs");
/**
* Accessort for embed
**/
const accessor = function(key) {
if (embeddedFiles.hasOwnProperty(key)) {
return new Buffer(embeddedFiles[key], 'base64');
} else {
//file was not embedded, throw err.
throw new Error('Embedded file not found');
}
}
/**
* Embed files.
*
* @param {array} resourceFiles - array of files to embed.
* @param {string} resourceRoot - root of resources.
* @param {function} compelte - callback
**/
function embed(resourceFiles, resourceRoot, options, complete) {
const encode = function(filePath) {
return fs.readFileSync(filePath).toString('base64');
}
resourceFiles = resourceFiles || [];
resourceRoot = resourceRoot || "";
if (!Array.isArray(resourceFiles)) {
throw new Error("Bad Argument: resourceFiles is not an array");
}
let buffer = "var embeddedFiles = {\n";
for (let i = 0; i < resourceFiles.length; ++i) {
buffer += JSON.stringify(path.relative(resourceRoot, resourceFiles[i])) + ': "';
buffer += encode(resourceFiles[i]) + '",\n';
}
buffer += "\n};\n\nmodule.exports.keys = function () { return Object.keys(embeddedFiles); }\n\nmodule.exports.get = ";
buffer += accessor.toString();
complete(null, buffer);
}
module.exports = embed;
-1052
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
module.exports = require("./exe");
-57
View File
@@ -1,57 +0,0 @@
/**
* Copyright (c) 2013 Craig Condon
* Copyright (c) 2015-2016 Jared Allard
*
* 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 colors = require('colors');
/**
* standard output, takes 3 different types.
* log, error, and warn
*
* @param {any} arguments - Text to output.
* @return undefined
**/
function _log () {
var args = Array.prototype.slice.call(arguments, 0),
level = args.shift();
if (!~["log", "error", "warn"].indexOf(level)) {
args.unshift(level);
level = "log";
}
if(level == "log") {
args[0] = "----> " + args[0];
} else if(level == "error") {
args[0] = "....> " + colors.red("ERROR: ") + args[0]
} else if(level == "warn") {
args[0] = "....> " + colors.yellow("WARNING: ") + args[0]
}
console[level].apply(console, args);
}
// export the log function, for require()
module.exports = _log;
+59
View File
@@ -0,0 +1,59 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.verbose = exports.error = exports.info = exports.setLevel = undefined;
var _os = require('os');
var _chalk = require('chalk');
var _chalk2 = _interopRequireDefault(_chalk);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function isFn(f) {
return typeof f === 'function';
}
function logNoop(x, cb) {
return isFn(cb) && process.nextTick(cb);
}
function safeCb(f) {
return isFn(f) ? f : logNoop;
}
const logLevels = [['verbose', 'green'], ['info', 'blue'], ['error', 'red']];
const logger = logLevels.reduce((logMethods, info) => {
const [level, color] = info;
logMethods[level] = function (output, cb) {
process.stderr.write(_chalk2.default[color](`${_os.EOL}[${level}]: ${output}`), safeCb(cb));
};
return logMethods;
}, {
setLevel(level) {
if (level === 'silent') {
logLevels.forEach(([x]) => {
logger[x] = logNoop;
});
return;
}
process.on('beforeExit', () => {
process.stderr.write(_os.EOL);
});
if (level === 'info') {
logger.verbose = logNoop;
}
return logger;
}
});
const { info, error, verbose, setLevel } = logger;
exports.setLevel = setLevel;
exports.info = info;
exports.error = error;
exports.verbose = verbose;
-63
View File
@@ -1,63 +0,0 @@
/**
* Copyright (c) 2013 Craig Condon
*
* 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 async = require("async"),
fs = require("fs"),
_log = require("./log");
/**
* Monkey patch a file.
*
* @param {string} filePath - path to file.
* @param {function} monkeyPatched - function to process contents
* @param {function} processor - TODO: detail what this is
* @param {function} complete - callback
*
* @return undefined
*/
function _monkeypatch (filePath, monkeyPatched, processor, complete) {
async.waterfall([
function read (next) {
fs.readFile(filePath, "utf8", next);
},
// TODO - need to parse gyp file - this is a bit hacker
function monkeypatch (content, next) {
if (monkeyPatched(content)) return complete();
_log("monkey patch %s", filePath);
processor(content, next);
},
function write (content, next) {
fs.writeFile(filePath, content, "utf8", next);
}
], complete);
}
// export the function for require()
module.exports = _monkeypatch;
+85
View File
@@ -0,0 +1,85 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.compile = exports.isNexe = exports.argv = undefined;
let compile = (() => {
var _ref = _asyncToGenerator(function* (compilerOptions, callback) {
const options = yield (0, _options.normalizeOptionsAsync)(compilerOptions);
const compiler = new _compiler.NexeCompiler(options);
compiler.log.verbose('Compiler options:' + _os.EOL + JSON.stringify(compiler.options, null, 4));
const nexe = (0, _appBuilder.compose)(_bundle2.default, _cli2.default, _download2.default, (() => {
var _ref2 = _asyncToGenerator(function* (_, next) {
yield next();
return compiler.buildAsync();
});
return function (_x3, _x4) {
return _ref2.apply(this, arguments);
};
})(), _artifacts2.default, _patches2.default, compiler.options.patches);
return nexe(compiler).asCallback(callback);
});
return function compile(_x, _x2) {
return _ref.apply(this, arguments);
};
})();
var _appBuilder = require('app-builder');
var _bundle = require('./bundle');
var _bundle2 = _interopRequireDefault(_bundle);
var _compiler = require('./compiler');
var _options = require('./options');
var _cli = require('./cli');
var _cli2 = _interopRequireDefault(_cli);
var _download = require('./download');
var _download2 = _interopRequireDefault(_download);
var _artifacts = require('./artifacts');
var _artifacts2 = _interopRequireDefault(_artifacts);
var _patches = require('./patches');
var _patches2 = _interopRequireDefault(_patches);
var _os = require('os');
var _bluebird = require('bluebird');
var _logger = require('./logger');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new _bluebird.Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return _bluebird.Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
_appBuilder.PromiseConfig.constructor = _bluebird.Promise;
(0, _bluebird.longStackTraces)();
function isNexe(callback) {
return _bluebird.Promise.resolve(Boolean(process.__nexe)).asCallback(callback);
}
exports.argv = _options.argv;
exports.isNexe = isNexe;
exports.compile = compile;
if (require.main === module || process.__nexe) {
compile(_options.argv).catch(e => {
(0, _logger.error)(e.stack, () => process.exit(e.exitCode || 1));
});
}
+152
View File
@@ -0,0 +1,152 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.normalizeOptionsAsync = exports.argv = undefined;
var _minimist = require('minimist');
var _minimist2 = _interopRequireDefault(_minimist);
var _path = require('path');
var _bluebird = require('bluebird');
var _os = require('os');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function padRight(str, l) {
return (str + ' '.repeat(l)).substr(0, l);
}
const defaults = {
temp: process.env.NEXE_TEMP || (0, _path.join)(process.cwd(), '.nexe'),
version: process.version.slice(1),
flags: [],
configure: [],
make: [],
vcBuild: ['nosign', 'release'],
quick: false,
bundle: true,
enableNodeCli: false,
verbose: false,
silent: false,
padding: 2,
patches: []
};
const alias = {
i: 'input',
o: 'output',
t: 'temp',
n: 'name',
v: 'version',
p: 'python',
f: 'flag',
c: 'configure',
m: 'make',
vc: 'vcBuild',
q: 'quick',
s: 'snapshot',
b: 'bundle',
cli: 'enableNodeCli',
h: 'help',
l: 'loglevel'
};
const argv = (0, _minimist2.default)(process.argv, { alias, default: defaults });
const help = `
nexe --help CLI OPTIONS
-i --input =./index.js -- application entry point
-o --output =./nexe.exe -- path to output file
-t --temp =./.nexe -- nexe temp directory (3Gb+) ~ NEXE_TEMP
-n --name =nexe.js -- file name for error reporting at run time
-v --version =${padRight(process.version.slice(1), 23)}-- node version
-p --python =/path/to/python2 -- python executable
-f --flag ="--expose-gc" -- *v8 flags to include during compilation
-c --configure ="--with-dtrace" -- *pass arguments to the configure command
-m --make ="--loglevel" -- *pass arguments to the make command
-vc --vcBuild =x64 -- *pass arguments to vcbuild.bat
-s --snapshot =/path/to/snapshot -- build with warmup snapshot
-b --bundle -- attempt bundling application
--ico -- file name for alternate icon file (windows)
--rc-* -- populate rc file options (windows)
--clean -- force download of sources
--enableNodeCli -- enable node cli enforcement (blocks app cli)
--sourceUrl -- pass an alternate source (node.tar.gz) url
--silent -- disable logging
--verbose -- set logging to verbose
-* variable key name * option can be used more than once
TODO -q --quick =win32-x64-X.X.X -- use prebuilt binary (url, key or path)
TODO --resource-* =/path/to/resource -- *embed file bytes within the binary
`.trim();
function flattenFilter(...args) {
return [].concat(...args).filter(x => x);
}
/**
* Extract keys such as { "rc-CompanyName": "Node.js" } to
* { CompanyName: "Node.js" }
* @param {*} match
* @param {*} options
*/
function extractCliMap(match, options) {
Object.keys(options).filter(x => match.test(x)).reduce((map, option) => {
const key = option.split('-')[1];
map = map || {};
map[key] = options[option];
delete options[option];
return map;
}, null);
}
function tryResolveMainFileName() {
let filename = 'nexe';
try {
const file = require.resolve(process.cwd());
filename = (0, _path.basename)(file).replace((0, _path.extname)(file), '');
} catch (_) {}
return filename === 'index' ? 'nexe_' + Date.now() : filename;
}
function extractLogLevel(options) {
if (options.loglevel) return options.loglevel;
if (options.silent) return 'silent';
if (options.verbose) return 'verbose';
if (options.info) return 'info';
}
function extractName(options) {
if (typeof options.input === 'string') {
return options.name || (0, _path.basename)(options.input).replace((0, _path.extname)(options.input), '');
}
const mainName = tryResolveMainFileName();
return options.name || mainName;
}
function normalizeOptionsAsync(input) {
if (argv.help || Boolean(argv._.find(x => x === 'version'))) {
return (0, _bluebird.fromCallback)(cb => process.stderr.write(argv.help ? help : '2.0.0-beta.1' + _os.EOL, () => cb(null, process.exit(1))));
}
const options = Object.assign({}, defaults, input);
delete options._;
options.loglevel = extractLogLevel(options);
options.name = extractName(options);
options.flags = flattenFilter(options.flag, options.flags);
options.make = flattenFilter(options.make);
options.vcBuild = flattenFilter(options.vcBuild);
options.rc = options.rc || extractCliMap(/^rc-.*/, options);
options.resources = options.resources || extractCliMap(/^resource-.*/, options);
Object.keys(alias).filter(k => k !== 'rc').forEach(x => delete options[x]);
return _bluebird.Promise.resolve(options);
}
exports.argv = argv;
exports.normalizeOptionsAsync = normalizeOptionsAsync;
+36
View File
@@ -0,0 +1,36 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _buffer = require('buffer');
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
yield next();
const filename = 'lib/' + compiler.options.name + '.js';
const file = yield compiler.readFileAsync(filename);
const header = '/' + '*'.repeat(19) + 'nexe_';
const end = '_' + '*'.repeat(19) + '/';
const padding = Array(compiler.options.padding * 1000000).fill('*').join('');
if (!padding) {
file.contents = compiler.input;
return;
}
file.contents = [compiler.input, '/', padding, '/'].join('');
file.contents = header + _buffer.Buffer.byteLength(file.contents) + end + file.contents;
});
function content(_x, _x2) {
return _ref.apply(this, arguments);
}
return content;
})();
+29
View File
@@ -0,0 +1,29 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
if (compiler.options.enableNodeCli) {
return next();
}
const nodecc = yield compiler.readFileAsync('src/node.cc');
console.log(nodecc);
const nodeccMarker = "argv[index][0] == '-'";
nodecc.contents = nodecc.contents.replace(nodeccMarker, nodeccMarker.replace('-', ']'));
return next();
});
function disableNodeCli(_x, _x2) {
return _ref.apply(this, arguments);
}
return disableNodeCli;
})();
+28
View File
@@ -0,0 +1,28 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const nodeflags = compiler.options.flags;
if (!nodeflags.length) {
return next();
}
const nodegyp = yield compiler.readFileAsync('node.gyp');
nodegyp.contents = nodegyp.contents.replace("'node_v8_options%': ''", `'node_v8_options%': '${nodeflags.join(' ')}'`);
return next();
});
function flags(_x, _x2) {
return _ref.apply(this, arguments);
}
return flags;
})();
+31
View File
@@ -0,0 +1,31 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* ({ files, readFileAsync }, next) {
yield next();
const nodegyp = yield readFileAsync('node.gyp');
const nodeGypMarker = "'lib/fs.js',";
nodegyp.contents = nodegyp.contents.replace(nodeGypMarker, `
${nodeGypMarker}
${files.filter(function (x) {
return x.filename.startsWith('lib');
}).map(function (x) {
return `'${x.filename}'`;
}).toString()},
`.trim());
});
function nodeGyp(_x, _x2) {
return _ref.apply(this, arguments);
}
return nodeGyp;
})();
+29
View File
@@ -0,0 +1,29 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _path = require('path');
var _util = require('../util');
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const iconFile = compiler.options.ico;
if (!iconFile) {
return next();
}
const file = yield compiler.readFileAsync('src/res/node.ico');
file.contents = yield (0, _util.readFileAsync)((0, _path.normalize)(iconFile));
return next();
});
function ico(_x, _x2) {
return _ref.apply(this, arguments);
}
return ico;
})();
+39
View File
@@ -0,0 +1,39 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _gyp = require('./gyp');
var _gyp2 = _interopRequireDefault(_gyp);
var _content = require('./content');
var _content2 = _interopRequireDefault(_content);
var _thirdPartyMain = require('./third-party-main');
var _thirdPartyMain2 = _interopRequireDefault(_thirdPartyMain);
var _disableNodeCli = require('./disable-node-cli');
var _disableNodeCli2 = _interopRequireDefault(_disableNodeCli);
var _flags = require('./flags');
var _flags2 = _interopRequireDefault(_flags);
var _ico = require('./ico');
var _ico2 = _interopRequireDefault(_ico);
var _nodeRc = require('./node-rc');
var _nodeRc2 = _interopRequireDefault(_nodeRc);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const patches = [_gyp2.default, _content2.default, _thirdPartyMain2.default, _disableNodeCli2.default, _flags2.default, _ico2.default, _nodeRc2.default];
exports.default = patches;
+34
View File
@@ -0,0 +1,34 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const options = compiler.options.rc;
if (!options) {
return next();
}
const file = yield compiler.readFileAsync('src/res/node.rc');
Object.keys(options).forEach(function (key) {
let value = options[key];
const isVar = /^[A-Z_]+$/.test(value);
value = isVar ? value : `"${value}"`;
file.contents.replace(new RegExp(`VALUE "${key}",*`), `VALUE "${key}", ${value}`);
});
return next();
});
function nodeRc(_x, _x2) {
return _ref.apply(this, arguments);
}
return nodeRc;
})();
+27
View File
@@ -0,0 +1,27 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const snapshotFile = compiler.options.snapshot;
if (!snapshotFile) {
return next();
}
const file = yield compiler.readFileAsync('configure');
file.contents = file.contents.replace('def configure_v8(o):', `def configure_v8(o):\n o['variables']['embed_script'] = '${snapshotFile}'\n o['variables']['warmup_script'] = '${snapshotFile}'`);
return next();
});
function snapshot(_x, _x2) {
return _ref.apply(this, arguments);
}
return snapshot;
})();
+37
View File
@@ -0,0 +1,37 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
exports.default = (() => {
var _ref = _asyncToGenerator(function* (compiler, next) {
const mainFile = yield compiler.readFileAsync('lib/_third_party_main.js');
mainFile.contents = `
Object.defineProperty(process, '__nexe', {
value: true,
enumerable: false,
writable: false,
configurable: false
});
require("${compiler.options.name}");
`.trim();
if (compiler.options.empty === true) {
compiler.options.resources.length = 0;
//eslint-disable-next-line
compiler.input = 'console.log(`nexe-${process.platform}-${process.arch}-${process.version}`)';
return next();
}
return next();
});
function main(_x, _x2) {
return _ref.apply(this, arguments);
}
return main;
})();
+28
View File
@@ -0,0 +1,28 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.dequote = exports.writeFileAsync = exports.readFileAsync = undefined;
var _fs = require('fs');
var _bluebird = require('bluebird');
function dequote(input) {
input = input.trim();
const singleQuote = input.startsWith('\'') && input.endsWith('\'');
const doubleQuote = input.startsWith('"') && input.endsWith('"');
if (singleQuote || doubleQuote) {
return input.slice(1).slice(0, -1);
}
return input;
}
const readFileAsync = (0, _bluebird.promisify)(_fs.readFile);
const writeFileAsync = (0, _bluebird.promisify)(_fs.writeFile);
exports.readFileAsync = readFileAsync;
exports.writeFileAsync = writeFileAsync;
exports.dequote = dequote;
+21 -40
View File
@@ -1,55 +1,36 @@
{
"author": "Jared Allard <jaredallard@outlook.com>",
"name": "nexe",
"description": "create single executables out of your [node/io].js applications",
"description": "Create a single executable out of your Node.js application",
"license": "MIT",
"version": "1.1.2",
"version": "2.0.0-beta.1",
"contributors": [
{
"name": "Criag Condon",
"email": "craig.j.condon@gmail.com",
"url": "http://crcn.io/"
}
"Craig Condon <craig.j.condon@gmail.com> (http://crcn.io)",
"Jared Allard <jaredallard@outlook.com>",
"Caleb Boyd <caleb.boyd@hotmail.com>"
],
"scripts": {
"test": "echo node: $(node -v) && node_modules/.bin/mocha --reporter mocha-circleci-reporter test/test.js"
"lint": "eslint index.js ./src/**/*",
"test": "npm run lint"
},
"repository": {
"type": "git",
"url": "git://github.com/jaredallard/nexe.git"
"url": "git://github.com/nexe/nexe.git"
},
"main": "./lib/index.js",
"dependencies": {
"async": "^1.5.2",
"browserify": "^13.0.0",
"colors": "^1.1.2",
"glob": "^7.0.0",
"gunzip-maybe": "^1.3.1",
"insert-module-globals": "^7.0.1",
"mkdirp": "^0.5.1",
"module-deps": "^4.0.5",
"ncp": "^2.0.0",
"progress": "^1.1.8",
"request": "^2.67.0",
"tar-stream": "^1.3.1",
"yargs": "^4.2.0"
},
"nexe": {
"input": "./bin/nexe",
"output": "nexe^$",
"temp": "src",
"runtime": {
"framework": "nodejs",
"version": "5.5.0",
"ignoreFlags": true
}
},
"preferGlobal": true,
"main": "src/nexe.js",
"bin": {
"nexe": "bin/nexe"
"nexe": "index.js"
},
"dependencies": {
"app-builder": "^5.1.0",
"bluebird": "^3.5.0",
"chalk": "^1.1.3",
"memory-fs": "^0.4.1",
"minimist": "^1.2.0",
"request": "^2.81.0",
"tar": "^2.2.1",
"webpack": "^2.3.3"
},
"devDependencies": {
"mocha": "^2.4.5",
"mocha-circleci-reporter": "0.0.1"
"eslint": "^3.19.0"
}
}
+58
View File
@@ -0,0 +1,58 @@
const
{ join, dirname } = require('path'),
{ readdir, stat, readFile, unlink, writeFile } = require('fs'),
{ promisify, map, coroutine } = require('bluebird'),
mkdirpAsync = promisify(require('mkdirp')),
statAsync = promisify(stat),
unlinkAsync = promisify(unlink),
readdirAsync = promisify(readdir),
writeAnyFileAsync = promisify(writeFile),
readFileAsync = promisify(readFile),
readDirAsync = (dir) => {
return readdirAsync(dir).map((file) => {
const path = join(dir, file)
return statAsync(path).then(s => s.isDirectory() ? readDirAsync(path) : path)
}).reduce((a, b) => a.concat(b), [])
},
maybeReadFileContents = (file) => {
return readFileAsync(file, 'utf-8')
.catch(e => {
if (e.code === 'ENOENT') {
return ''
}
throw e
})
}
/**
* The artifacts step is where source patches are committed, or written as "artifacts"
* Steps:
* - A temporary directory is created in the downloaded source
* - On start, any files in that directory are restored into the source tree
* - After the patch functions have run, the temporary directory is emptied
* - Original versions of sources to be patched are written to the temporary directory
* - Finally, The patched files are written into source.
*
*/
module.exports.artifacts = function* artifacts ({ files, writeFileAsync, src }, next) {
const temp = join(src, 'nexe')
yield mkdirpAsync(temp)
const tmpFiles = yield readDirAsync(temp)
yield map(tmpFiles, coroutine(function* (path) {
return writeFileAsync(path.replace(temp, ''), yield readFileAsync(path))
}))
yield next()
yield map(tmpFiles, x => unlinkAsync(x))
return map(files, coroutine(function* (file) {
const sourceFile = join(src, file.filename),
tempFile = join(temp, file.filename),
fileContents = yield maybeReadFileContents(sourceFile)
yield mkdirpAsync(dirname(tempFile))
yield writeAnyFileAsync(tempFile, fileContents)
yield writeFileAsync(file.filename, file.contents)
}))
}
+46
View File
@@ -0,0 +1,46 @@
const Mfs = require('memory-fs'),
webpack = require('webpack'),
{ fromCallback } = require('bluebird'),
{ resolve, join, relative } = require('path'),
isObject = (x) => typeof x === 'object',
isString = (x) => typeof x === 'string'
function* bundle (compiler, next) {
let bundleConfig = compiler.options.bundle
if (!bundleConfig) {
return next()
}
const
input = compiler.options.input || require.resolve(process.cwd()),
fs = new Mfs(),
path = resolve('nexe'),
filename = 'virtual-bundle.js'
if (isString(bundleConfig)) {
bundleConfig === require(relative(process.cwd(), bundleConfig))
} else if (!isObject(bundleConfig)) {
bundleConfig = {
entry: resolve(input),
target: 'node',
output: { path, filename }
}
}
const bundler = webpack(bundleConfig)
bundler.outputFileSystem = fs
const stats = yield fromCallback(cb => bundler.run(cb))
if (stats.hasErrors()) {
compiler.log.error(stats.toString())
return null
}
//eslint-disable-next-line no-sync
compiler.input = fs.readFileSync(
join(bundleConfig.output.path, bundleConfig.output.filename)
)
return next()
}
module.exports.bundle = bundle
+88
View File
@@ -0,0 +1,88 @@
const
{ normalize } = require('path'),
{ Promise, promisify } = require('bluebird'),
{ createWriteStream, readFile } = require('fs')
const readFileAsync = promisify(readFile),
isWindows = process.platform === 'win32'
function dequoteStdIn (input) {
input = input.trim()
if (input.startsWith('\'') && input.endsWith('\'') ||
input.startsWith('"') && input.endsWith('"')) {
return input.slice(1).slice(0, -1)
}
return input
}
function getStdIn () {
return new Promise((resolve) => {
const bundle = []
process.stdin.setEncoding('utf-8')
process.stdin.on('data', x => bundle.push(x))
process.stdin.once('end', () =>
resolve(dequoteStdIn(Buffer.concat(bundle).toString()))
)
process.stdin.resume()
})
}
/**
* The "cli" step detects whether the process is in a tty. If it is then the input is read into memory.
* Otherwise, it is buffered from stdin. If no input options are passed in the tty, the package.json#main file is used.
* After all the build steps have run, the output (the executable) is written to a file or piped to stdout.
*
* Configuration:
* - compiler.options.input - file path to the input bundle.
* - fallbacks: stdin, package.json#main
* - compiler.options.output - file path to the output executable.
* - fallbacks: stdout, nexe_ + epoch + ext
*
* @param {*} compiler
* @param {*} next
*/
module.exports.cli = function* cli (compiler, next) {
const input = compiler.options.input,
bundled = Boolean(compiler.input)
if (bundled) {
yield next()
} else if (!input && !process.stdin.isTTY) {
compiler.log.verbose('Buffering stdin as main module...')
compiler.input = yield getStdIn()
} else if (input) {
compiler.log.verbose('Reading input as main module: ' + input)
compiler.input = yield readFileAsync(normalize(input))
} else if (!compiler.options.empty) {
compiler.log.verbose('Resolving cwd as main module...')
compiler.input = yield readFileAsync(require.resolve(process.cwd()))
}
if (!bundled) {
yield next()
}
const deliverable = yield compiler.getDeliverableAsync()
return new Promise((resolve, reject) => {
deliverable.once('error', reject)
if (!compiler.options.output && !process.stdout.isTTY) {
compiler.log.verbose('Writing result to stdout...')
deliverable.pipe(process.stdout).once('error', reject)
resolve()
} else {
compiler.log.verbose('Writing result to file...')
const output = compiler.options.output || `${compiler.options.name}${isWindows ? '.exe' : ''}`
deliverable.pipe(createWriteStream(normalize(output)))
.once('error', reject)
.once('close', e => {
if (e) {
reject(e)
} else {
resolve(compiler.log.info('Executable written: ' + output))
}
})
}
})
}
+94
View File
@@ -0,0 +1,94 @@
const
{ dirname, normalize, join } = require('path'),
{ promisify, Promise, coroutine } = require('bluebird'),
{ normalizeOptions } = require('./options'),
{ readFile, writeFile, createReadStream } = require('fs'),
{ spawn } = require('child_process'),
{ logger } = require('./logger')
const
isWindows = process.platform === 'win32',
isBsd = Boolean(~process.platform.indexOf('bsd')),
make = isWindows && 'vcbuild.bat' ||
isBsd && 'gmake' ||
'make',
configure = isWindows ? 'configure' : './configure',
readFileAsync = promisify(readFile),
writeFileAsync = promisify(writeFile)
module.exports.NexeCompiler = class NexeCompiler {
constructor (options) {
options = this.options = normalizeOptions(options)
logger.setLevel(options.loglevel)
this.log = logger
this.python = options.python
this.configure = options.configure
this.make = isWindows ? options.vcBuild : options.make
this.src = join(options.temp, options.version)
this.env = Object.assign({}, process.env)
this.files = []
this.readFileAsync = coroutine(function * (file) {
const cachedFile = this.files.find(x => normalize(x.filename) === normalize(file))
if (cachedFile) {
return Promise.resolve(cachedFile)
}
this.files.push({
filename: file,
contents: yield readFileAsync(join(this.src, file), 'utf-8').catch(e => {
if (e.code !== 'ENOENT') {
throw e
}
return ''
})
})
return this.readFileAsync(file)
}.bind(this))
this.writeFileAsync = (file, contents) => writeFileAsync(join(this.src, file), contents)
}
set python (pythonPath) {
if (!pythonPath) {
return
}
if (isWindows) {
this.env.PATH = this.env.PATH + ';' + normalize(dirname(pythonPath))
} else {
this.env.PYTHON = pythonPath
}
}
get _deliverableLocation () {
return isWindows
? join(this.src, 'Release', 'node.exe')
: join(this.src, 'out', 'Release', 'node')
}
_runBuildCommandAsync (command, args) {
return new Promise((resolve, reject) => {
spawn(command, args, {
cwd: this.src,
env: this.env,
stdio: 'ignore'
})
.once('error', reject)
.once('close', resolve)
})
}
_configureAsync () {
return this._runBuildCommandAsync(
this.env.PYTHON || 'python',
[configure, ...this.configure]
)
}
buildAsync () {
return this._configureAsync()
.then(() => this._runBuildCommandAsync(make, this.make))
}
getDeliverableAsync () {
return Promise.resolve(createReadStream(this._deliverableLocation))
}
}
+75
View File
@@ -0,0 +1,75 @@
const
unZip = require('zlib').createGunzip,
unTar = require('tar').Extract,
request = require('request'),
{ Promise, promisify } = require('bluebird'),
statAsync = promisify(require('fs').stat),
rimrafAsync = promisify(require('rimraf'))
function progress (req, log, precision = 10) {
const logged = {}
let length = 0,
total = 1
return req.on('response', (res) => {
total = res.headers['content-length']
}).on('data', (chunk) => {
length += chunk.length
const percentComplete = +(length / total * 100).toFixed()
if (percentComplete % precision === 0 && !logged[percentComplete]) {
logged[percentComplete] = true
log(percentComplete)
}
})
}
function fetchNodeSource (path, url, log) {
log.info('Downloading Node: ' + url)
return new Promise((resolve, reject) => {
progress(request.get(url), (pc) => {
log.verbose(`Downloading Node: ${pc}%...`)
if (pc === 100) {
log.info('Extracting Node...')
}
}).on('error', reject)
.pipe(unZip().on('error', reject))
.pipe(unTar({ path, strip: 1 }))
.on('error', reject)
.on('end', () => resolve(log.info('Extracted to: ' + path)))
})
}
function cleanSrc (clean, src, log) {
if (clean === true) {
log.info('Removing source: ' + src)
return rimrafAsync(src).then(() => {
log.info('Source deleted.' + src)
})
}
return Promise.resolve()
}
/**
* Deletes (maybe) and downloads the node source to the configured temporary directory
* @param {*} compiler
* @param {*} next
*/
function download (compiler, next) {
const
{ src, log } = compiler,
{ version, sourceUrl, clean } = compiler.options,
url = sourceUrl ||
`https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`
return cleanSrc(clean, src, log).then(() => statAsync(src).then(
x => !x.isDirectory() && fetchNodeSource(src, url, log),
e => {
if (e.code !== 'ENOENT') {
throw e
}
return fetchNodeSource(src, url, log)
}
)).then(next)
}
module.exports.download = download
+35
View File
@@ -0,0 +1,35 @@
const
EOL = require('os').EOL,
colors = require('chalk'),
isFn = f => typeof f === 'function',
logNoop = (x, cb) => {
isFn(cb) && process.nextTick(cb)
},
safeCb = f => isFn(f) ? f : logNoop,
logLevels = [
['verbose', 'green'],
['info', 'blue'],
['error', 'red']
],
logger = logLevels.reduce((logMethods, info) => {
const [level, color] = info
logMethods[level] = function (output, cb) {
process.stderr.write(colors[color](`${EOL}[${level}]: ${output}`), safeCb(cb))
}
return logMethods
}, {
setLevel (level) {
if (level === 'silent') {
return void logLevels.forEach(([x]) => logger[x] = logNoop)
}
process.on('beforeExit', () => {
process.stderr.write(EOL)
})
if (level === 'info') {
logger.verbose = logNoop
}
return logger
}
})
module.exports.logger = logger
+51
View File
@@ -0,0 +1,51 @@
const
{ compose } = require('app-builder'),
{ bundle } = require('./bundle'),
{ NexeCompiler } = require('./compiler'),
{ options } = require('./options'),
{ cli } = require('./cli'),
{ download } = require('./download'),
{ artifacts } = require('./artifacts'),
{ patches } = require('./patches'),
{ EOL } = require('os'),
{ coroutine, Promise } = require('bluebird'),
{ logger } = require('./logger')
function wrap (fns) {
return [].concat(...fns).map(fn => {
return fn.constructor.name === 'GeneratorFunction'
? coroutine(fn) : fn
})
}
function compile (compilerOptions, callback) {
const compiler = new NexeCompiler(compilerOptions)
compiler.log.verbose('Compiler options:' +
EOL + JSON.stringify(compiler.options, null, 4)
)
const nexe = compose(wrap([
bundle,
cli,
download,
(nexeCompiler, next) => {
return next().then(() => {
return nexeCompiler.buildAsync()
})
},
artifacts,
patches,
compiler.options.patches
]))
return Promise.resolve(nexe(compiler)).asCallback(callback)
}
module.exports.options = options
module.exports.compile = compile
if (require.main === module || process.__nexe) {
compile(options).catch((e) => {
logger.error(e.stack, () => process.exit(1))
})
}
+136
View File
@@ -0,0 +1,136 @@
const
parseArgv = require('minimist'),
{ basename, extname, join } = require('path'),
EOL = require('os').EOL,
padRight = (str, l) => {
while (str.length < l) {
str += ' '
}
return str.substr(0, l)
},
defaults = {
temp: process.env.NEXE_TEMP || join(process.cwd(), '.nexe'),
version: process.version.slice(1),
flags: [],
configure: [],
make: [],
vcBuild: ['nosign', 'release'],
quick: false,
bundle: true,
enableNodeCli: false,
verbose: false,
silent: false,
padding: 2,
patches: []
},
alias = {
i: 'input',
o: 'output',
t: 'temp',
n: 'name',
v: 'version',
p: 'python',
f: 'flag',
c: 'configure',
m: 'make',
vc: 'vcBuild',
q: 'quick',
s: 'snapshot',
b: 'bundle',
cli: 'enableNodeCli',
h: 'help',
l: 'loglevel'
},
argv = parseArgv(process.argv, { alias, default: defaults }),
help = `
nexe --help CLI OPTIONS
-i --input =./index.js -- application entry point
-o --output =./nexe.exe -- path to output file
-t --temp =./.nexe -- nexe temp directory (3Gb+) ~ NEXE_TEMP
-n --name =nexe.js -- file name for error reporting at run time
-v --version =${padRight(process.version.slice(1), 23)}-- node version
-p --python =/path/to/python2 -- python executable
-f --flag ="--expose-gc" -- *v8 flags to include during compilation
-c --configure ="--with-dtrace" -- *pass arguments to the configure command
-m --make ="--loglevel" -- *pass arguments to the make command
-vc --vcBuild =x64 -- *pass arguments to vcbuild.bat
-s --snapshot =/path/to/snapshot -- build with warmup snapshot
-b --bundle -- attempt bundling application
--ico -- file name for alternate icon file (windows)
--rc-* -- populate rc file options (windows)
--clean -- force download of sources
--enableNodeCli -- enable node cli enforcement (blocks app cli)
--sourceUrl -- pass an alternate source (node.tar.gz) url
--silent -- disable logging
--verbose -- set logging to verbose
-* variable key name * option can be used more than once
TODO -q --quick =win32-x64-X.X.X -- use prebuilt binary (url, key or path)
TODO --resource-* =/path/to/resource -- *embed file bytes within the binary
`.trim()
function flattenFilter (...args) {
return [].concat(...args).filter(x => x)
}
/**
* Extract keys such as { "rc-CompanyName": "Node.js" } to
* { CompanyName: "Node.js" }
* @param {*} match
* @param {*} options
*/
function extractCliMap (match, options) {
Object.keys(options).filter(x => match.test(x))
.reduce((map, option) => {
const key = option.split('-')[1]
map = map || {}
map[key] = options[option]
delete options[option]
return map
}, null)
}
function extractName (options) {
if (typeof options.input === 'string') {
return options.name
|| basename(options.input).replace(extname(options.input), '')
}
const mainName = basename(require.resolve(process.cwd()))
return options.name || mainName.replace(extname(mainName), '')
}
function normalizeOptions (input) {
if (input.__normalized) {
return input
}
if (argv.help || Boolean(argv._.find(x => x === 'version'))) {
process.stderr.write(
argv.help ? help : 'next' + EOL,
() => process.exit(0)
)
}
const options = Object.assign({}, defaults, input)
delete options._
delete alias.rc
options.loglevel = options.loglevel
|| options.silent && 'silent'
|| options.verbose && 'verbose' || 'info'
options.name = extractName(options)
options.flags = flattenFilter(options.flag, options.flags)
options.make = flattenFilter(options.make)
options.vcBuild = flattenFilter(options.vcBuild)
options.rc = options.rc || extractCliMap(/^rc-.*/, options)
options.resources = options.resources || extractCliMap(/^resource-.*/, options)
Object.keys(alias).forEach(x => delete options[x])
options.__normalized = true
return options
}
module.exports.normalizeOptions = normalizeOptions
module.exports.options = normalizeOptions(argv)
+27
View File
@@ -0,0 +1,27 @@
const Buffer = require('buffer').Buffer
function* content (compiler, next) {
yield next()
const filename = 'lib/' + compiler.options.name + '.js',
file = yield compiler.readFileAsync(filename),
header = '/' + '*'.repeat(19) + 'nexe_',
end = '_' + '*'.repeat(19) + '/',
padding = Array(compiler.options.padding * 1000000).fill('*').join('')
if (!padding) {
file.contents = compiler.input
return
}
file.contents = [
compiler.input,
'/',
padding,
'/'
].join('')
file.contents = header + Buffer.byteLength(file.contents) + end + file.contents
}
module.exports.content = content
+17
View File
@@ -0,0 +1,17 @@
function * disableNodeCli (compiler, next) {
if (compiler.options.enableNodeCli) {
return next()
}
const nodecc = yield compiler.readFileAsync('src/node.cc'),
nodeccMarker = "argv[index][0] == '-'"
nodecc.contents = nodecc.contents.replace(
nodeccMarker,
nodeccMarker.replace('-', ']')
)
return next()
}
module.exports.disableNodeCli = disableNodeCli
+14
View File
@@ -0,0 +1,14 @@
module.exports.flags = function* flags (compiler, next) {
const nodeflags = compiler.options.flags
if (!nodeflags.length) {
return next()
}
const nodegyp = yield compiler.readFileAsync('node.gyp')
nodegyp.contents = nodegyp.contents.replace(
"'node_v8_options%': ''",
`'node_v8_options%': '${nodeflags.join(' ')}'`)
return next()
}
+15
View File
@@ -0,0 +1,15 @@
module.exports.nodeGyp = function * nodeGyp ({ files, readFileAsync, download }, next) {
yield next()
const nodegyp = yield readFileAsync('node.gyp'),
nodeGypMarker = "'lib/fs.js',"
nodegyp.contents = nodegyp.contents
.replace(nodeGypMarker, `
${nodeGypMarker}
${files
.filter(x => x.filename.startsWith('lib'))
.map(x => `'${x.filename}'`)
.toString()},
`.trim())
}
+16
View File
@@ -0,0 +1,16 @@
const
{ readFile } = require('fs'),
{ normalize } = require('path'),
{ promisify } = require('bluebird')
const readFileAsync = promisify(readFile)
module.exports.ico = function * ico (compiler, next) {
const iconFile = compiler.options.ico
if (!iconFile) {
return next()
}
const file = yield compiler.readFileAsync('src/res/node.ico')
file.contents = yield readFileAsync(normalize(iconFile))
return next()
}
+9
View File
@@ -0,0 +1,9 @@
module.exports.patches = [
require('./gyp').nodeGyp, //upstream, sets manifest
require('./content').content, //upstream, sets main module content
require('./third-party-main').main, //loads main module
require('./disable-node-cli').disableNodeCli,
require('./flags').flags,
require('./ico').ico,
require('./node-rc').nodeRc
]
+21
View File
@@ -0,0 +1,21 @@
function* nodeRc (compiler, next) {
const options = compiler.options.rc
if (!options) {
return next()
}
const file = yield compiler.readFileAsync('src/res/node.rc')
Object.keys(options).forEach((key) => {
const value = options[key],
isVar = /^[A-Z_]+$/.test(value)
value = isVar ? value : `"${value}"`
file.contents.replace(new RegExp(`VALUE "${key}",*`), `VALUE "${key}", ${value}`)
// TODO support keys that are not present?
})
return next()
}
module.exports.nodeRc = nodeRc
+15
View File
@@ -0,0 +1,15 @@
module.exports.snapshot = function* snapshot (compiler, next) {
const snapshotFile = compiler.options.snapshot
if (!snapshotFile) {
return next()
}
const file = yield compiler.readFileAsync('configure')
file.contents = file.contents
.replace(
'def configure_v8(o):',
`def configure_v8(o):\n o['variables']['embed_script'] = '${snapshotFile}'\n o['variables']['warmup_script'] = '${snapshotFile}'`
)
return next()
}
+21
View File
@@ -0,0 +1,21 @@
function * main (compiler, next) {
const mainFile = yield compiler.readFileAsync('lib/_third_party_main.js')
mainFile.contents = `
Object.defineProperty(process, '__nexe', {
value: true,
enumerable: false,
configurable: false
});
require("${compiler.options.name}");
`.trim()
if (compiler.options.empty === true) {
compiler.options.resources.length = 0
compiler.input = 'console.log(`nexe-${process.platform}-${process.arch}-${process.version}`)'
return next()
}
return next()
}
module.exports.main = main