UNPKG

nexe

Version:

Create a single executable out of your Node.js application

245 lines (237 loc) 9.7 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.help = exports.normalizeOptions = exports.argv = exports.resolveEntry = exports.version = void 0; const minimist_1 = __importDefault(require("minimist")); const compiler_1 = require("./compiler"); const util_1 = require("./util"); const path_1 = require("path"); const target_1 = require("./target"); const os_1 = require("os"); const chalk_1 = __importDefault(require("chalk")); const resolve_dependencies_1 = require("resolve-dependencies"); const caw = require('caw'); const c = process.platform === 'win32' ? chalk_1.default.constructor({ enabled: false }) : chalk_1.default; exports.version = "5.0.0-beta.4"; const defaults = { flags: [], cwd: process.cwd(), fs: true, configure: [], mangle: true, make: [], targets: [], vcBuild: util_1.isWindows ? ['nosign', 'release'] : [], enableNodeCli: false, build: false, bundle: true, patches: [], plugins: [], remote: 'https://github.com/nexe/nexe/releases/download/v3.3.3/', }; const alias = { i: 'input', o: 'output', v: 'version', a: 'asset', t: 'target', b: 'build', n: 'name', r: 'resource', p: 'python', f: 'flag', c: 'configure', m: 'make', h: 'help', l: 'loglevel', 'fake-argv': 'fakeArgv', 'gh-token': 'ghToken', }; const argv = (0, minimist_1.default)(process.argv, { alias, default: Object.assign({}, defaults) }); exports.argv = argv; let help = ` ${c.bold('nexe <entry-file> [options]')} ${c.underline.bold('Options:')} -i --input -- application entry point -o --output -- path to output file -t --target -- node version description -n --name -- main app module name -r --resource -- *embed files (glob) within the binary --remote -- alternate location (URL) to download pre-built base (nexe) binaries from --plugin -- extend nexe runtime behavior ${c.underline.bold('Building from source:')} -b --build -- build from source -p --python -- python3 (as python) executable path -f --flag -- *v8 flags to include during compilation -c --configure -- *arguments to the configure step -m --make -- *arguments to the make/build step --patch -- module with middleware default export for adding a build patch --no-mangle -- used when generating base binaries, or when patching _third_party_main manually --snapshot -- path to a warmup snapshot --ico -- file name for alternate icon file (windows) --rc-* -- populate rc file options (windows) --sourceUrl -- pass an alternate source (node.tar.gz) url --enableNodeCli -- enable node cli enforcement (blocks app cli) ${c.underline.bold('Other options:')} --bundle -- custom bundling module with 'createBundle' export --temp -- temp file storage default '~/.nexe' --cwd -- set the current working directory for the command --fake-argv -- fake argv[1] with entry file --clean -- force download of sources --silent -- disable logging --verbose -- set logging to verbose -* variable key name * option can be used more than once`.trim(); exports.help = help; exports.help = help = os_1.EOL + help + os_1.EOL; function flatten(...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) { return Object.keys(options) .filter((x) => match.test(x)) .reduce((map, option) => { const key = option.split('-')[1]; map[key] = options[option]; delete options[option]; return map; }, {}); } function extractLogLevel(options) { if (options.loglevel) return options.loglevel; if (options.silent) return 'silent'; if (options.verbose) return 'verbose'; return 'info'; } function isName(name) { return name && name !== 'index' && name !== util_1.STDIN_FLAG; } function extractName(options) { let name = options.name; //try and use the input filename as the output filename if its not index if (!isName(name) && typeof options.input === 'string') { name = (0, path_1.basename)(options.input).replace((0, path_1.extname)(options.input), ''); } //try and use the directory as the filename if (!isName(name) && (0, path_1.basename)(options.cwd)) { name = (0, path_1.basename)(options.cwd); } return name.replace(/\.exe$/, ''); } function padRelative(input) { let prefix = ''; if (!input.startsWith('.')) { prefix = './'; } return prefix + input; } function isEntryFile(filename) { return Boolean(filename && !(0, path_1.isAbsolute)(filename)); } function resolveEntry(input, cwd, maybeEntry, bundle) { let result = null; if (input === '-' || maybeEntry === '-') { return util_1.STDIN_FLAG; } if (input && (0, path_1.isAbsolute)(input)) { return input; } if (input) { const inputPath = padRelative(input); result = (0, resolve_dependencies_1.resolveSync)(cwd, inputPath); } if (isEntryFile(maybeEntry) && (!result || !result.absPath)) { const inputPath = padRelative(maybeEntry); result = (0, resolve_dependencies_1.resolveSync)(cwd, inputPath); } if (!process.stdin.isTTY && (!result || !result.absPath) && bundle === defaults.bundle) { return util_1.STDIN_FLAG; } if (!result || !result.absPath) { result = (0, resolve_dependencies_1.resolveSync)(cwd, '.'); } if (!result.absPath) { throw new compiler_1.NexeError(`Entry file "${input || ''}" not found!`); } return result.absPath; } exports.resolveEntry = resolveEntry; function isCli(options) { return argv === options; } function normalizeOptions(input) { const options = Object.assign({}, defaults, input); const opts = options; const cwd = (options.cwd = (0, path_1.resolve)(options.cwd)); options.temp = options.temp ? (0, path_1.resolve)(cwd, options.temp) : process.env.NEXE_TEMP || (0, path_1.join)((0, os_1.homedir)(), '.nexe'); const maybeEntry = isCli(input) ? argv._[argv._.length - 1] : undefined; options.input = resolveEntry(options.input, cwd, maybeEntry, options.bundle); options.enableStdIn = isCli(input) && options.input === util_1.STDIN_FLAG; options.name = extractName(options); options.loglevel = extractLogLevel(options); options.flags = flatten(opts.flag, options.flags); options.targets = flatten(opts.target, options.targets).map(target_1.getTarget); if (!options.targets.length) { options.targets.push((0, target_1.getTarget)()); } options.ghToken = options.ghToken || process.env.GITHUB_TOKEN || ''; options.make = flatten(util_1.isWindows ? options.vcBuild : options.make); options.configure = flatten(options.configure); options.resources = flatten(opts.resource, options.resources); if (!options.remote.endsWith('/')) { options.remote += '/'; } options.downloadOptions = options.downloadOptions || {}; options.downloadOptions.headers = options.downloadOptions.headers || {}; options.downloadOptions.headers['User-Agent'] = 'nexe (https://www.npmjs.com/package/nexe)'; options.downloadOptions.agent = process.env.HTTPS_PROXY ? caw(process.env.HTTPS_PROXY, { protocol: 'https' }) : options.downloadOptions.agent || require('https').globalAgent; options.downloadOptions.rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED ? false : true; options.rc = options.rc || extractCliMap(/^rc-.*/, options); options.output = options.targets[0].platform === 'windows' ? `${(options.output || options.name).replace(/\.exe$/, '')}.exe` : `${options.output || options.name}`; options.output = (0, path_1.resolve)(cwd, options.output); const requireDefault = (x) => { if (typeof x === 'string') { return require(x).default; } return x; }; options.mangle = 'mangle' in opts ? opts.mangle : true; options.plugins = flatten(opts.plugin, options.plugins).map(requireDefault); options.patches = flatten(opts.patch, options.patches).map(requireDefault); if ((!options.mangle && !options.bundle) || options.patches.length) { options.build = true; } if (options.build) { const { arch } = options.targets[0]; if (util_1.isWindows) { options.make = Array.from(new Set(options.make.concat(arch))); } else { options.configure = Array.from(new Set(options.configure.concat([`--dest-cpu=${arch}`]))); } } Object.keys(alias) .filter((k) => k !== 'rc') .forEach((x) => delete opts[x]); return options; } exports.normalizeOptions = normalizeOptions;