"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const parseArgv = 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 = 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 = "4.0.0-beta.18"; 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 = parseArgv(process.argv, { alias, default: Object.assign({}, defaults) }); exports.argv = argv; let help = ` ${c.bold('nexe [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 -- python2 (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 = path_1.basename(options.input).replace(path_1.extname(options.input), ''); } //try and use the directory as the filename if (!isName(name) && path_1.basename(options.cwd)) { name = 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 && !path_1.isAbsolute(filename)); } function resolveEntry(input, cwd, maybeEntry, bundle) { let result = null; if (input === '-' || maybeEntry === '-') { return util_1.STDIN_FLAG; } if (input && path_1.isAbsolute(input)) { return input; } if (input) { const inputPath = padRelative(input); result = resolve_dependencies_1.resolveSync(cwd, inputPath); } if (isEntryFile(maybeEntry) && (!result || !result.absPath)) { const inputPath = padRelative(maybeEntry); result = 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 = 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 = path_1.resolve(options.cwd)); options.temp = options.temp ? path_1.resolve(cwd, options.temp) : process.env.NEXE_TEMP || path_1.join(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(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.HTTPS_PROXY ? 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 = 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;