From d25e11bee6ca5ca523884da132d18e1400e077b9 Mon Sep 17 00:00:00 2001 From: Minteck Date: Tue, 24 Aug 2021 14:41:48 +0200 Subject: Initial commit --- node_modules/nexe/lib/compiler.js | 268 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 node_modules/nexe/lib/compiler.js (limited to 'node_modules/nexe/lib/compiler.js') diff --git a/node_modules/nexe/lib/compiler.js b/node_modules/nexe/lib/compiler.js new file mode 100644 index 0000000..4ae9284 --- /dev/null +++ b/node_modules/nexe/lib/compiler.js @@ -0,0 +1,268 @@ +"use strict"; +var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const path_1 = require("path"); +const buffer_1 = require("buffer"); +const fs_1 = require("fs"); +const child_process_1 = require("child_process"); +const logger_1 = require("./logger"); +const util_1 = require("./util"); +const options_1 = require("./options"); +const MultiStream = require("multistream"); +const bundle_1 = require("./fs/bundle"); +const isBsd = Boolean(~process.platform.indexOf('bsd')); +const make = util_1.isWindows ? 'vcbuild.bat' : isBsd ? 'gmake' : 'make'; +const configure = util_1.isWindows ? 'configure' : './configure'; +class NexeError extends Error { + constructor(m) { + super(m); + Object.setPrototypeOf(this, NexeError.prototype); + } +} +exports.NexeError = NexeError; +class NexeCompiler { + constructor(options) { + this.options = options; + /** + * Epoch of when compilation started + */ + this.start = Date.now(); + this.log = new logger_1.Logger(this.options.loglevel); + /** + * Copy of process.env + */ + this.env = Object.assign({}, process.env); + /** + * In memory files that are being manipulated by the compiler + */ + this.files = []; + /** + * Standalone pieces of code run before the application entrypoint + */ + this.shims = []; + /** + * The last shim (defaults to "require('module').runMain()") + */ + this.startup = ''; + /** + * Output filename (-o myapp.exe) + */ + this.output = this.options.output; + /** + * Flag to indicate whether or notstdin was used for input + */ + this.stdinUsed = false; + const { python } = (this.options = options); + //SOMEDAY iterate over multiple targets with `--outDir` + this.targets = options.targets; + this.target = this.targets[0]; + if (!/https?\:\/\//.test(options.remote)) { + throw new NexeError(`Invalid remote URI scheme (must be http, https, or file): ${options.remote}`); + } + this.remoteAsset = options.remote + this.target.toString(); + this.src = path_1.join(this.options.temp, this.target.version); + this.configureScript = configure + (util_1.semverGt(this.target.version, '10.10.0') ? '.py' : ''); + this.nodeSrcBinPath = util_1.isWindows + ? path_1.join(this.src, 'Release', 'node.exe') + : path_1.join(this.src, 'out', 'Release', 'node'); + this.log.step('nexe ' + options_1.version, 'info'); + this.bundle = new bundle_1.Bundle(options); + if (util_1.isWindows) { + const originalPath = process.env.PATH; + delete process.env.PATH; + this.env = Object.assign({}, process.env); + this.env.PATH = python + ? (this.env.PATH = util_1.dequote(path_1.normalize(python)) + path_1.delimiter + originalPath) + : originalPath; + process.env.PATH = originalPath; + } + else { + this.env = Object.assign({}, process.env); + python && (this.env.PYTHON = python); + } + } + addResource(absoluteFileName, content) { + return this.bundle.addResource(absoluteFileName, content); + } + readFileAsync(file) { + return __awaiter(this, void 0, void 0, function* () { + this.assertBuild(); + let cachedFile = this.files.find((x) => path_1.normalize(x.filename) === path_1.normalize(file)); + if (!cachedFile) { + const absPath = path_1.join(this.src, file); + cachedFile = { + absPath, + filename: file, + contents: yield util_1.readFileAsync(absPath, 'utf-8').catch((x) => { + if (x.code === 'ENOENT') + return ''; + throw x; + }), + }; + this.files.push(cachedFile); + } + return cachedFile; + }); + } + writeFileAsync(file, contents) { + this.assertBuild(); + return util_1.writeFileAsync(path_1.join(this.src, file), contents); + } + replaceInFileAsync(file, replace, value) { + return __awaiter(this, void 0, void 0, function* () { + const entry = yield this.readFileAsync(file); + entry.contents = entry.contents.toString().replace(replace, value); + }); + } + setFileContentsAsync(file, contents) { + return __awaiter(this, void 0, void 0, function* () { + const entry = yield this.readFileAsync(file); + entry.contents = contents; + }); + } + quit(error) { + const time = Date.now() - this.start; + this.log.write(`Finished in ${time / 1000}s`, error ? 'red' : 'green'); + return this.log.flush(); + } + assertBuild() { + if (!this.options.build) { + throw new NexeError('This feature is only available with `--build`'); + } + } + getNodeExecutableLocation(target) { + if (this.options.asset) { + return path_1.resolve(this.options.cwd, this.options.asset); + } + if (target) { + return path_1.join(this.options.temp, target.toString()); + } + return this.nodeSrcBinPath; + } + _runBuildCommandAsync(command, args) { + if (this.log.verbose) { + this.compileStep.pause(); + } + return new Promise((resolve, reject) => { + child_process_1.spawn(command, args, { + cwd: this.src, + env: this.env, + stdio: this.log.verbose ? 'inherit' : 'ignore', + }) + .once('error', (e) => { + if (this.log.verbose) { + this.compileStep.resume(); + } + reject(e); + }) + .once('close', (code) => { + if (this.log.verbose) { + this.compileStep.resume(); + } + if (code != 0) { + const error = `${command} ${args.join(' ')} exited with code: ${code}`; + reject(new NexeError(error)); + } + resolve(); + }); + }); + } + _configureAsync() { + if (util_1.isWindows && util_1.semverGt(this.target.version, '10.15.99')) { + return Promise.resolve(); + } + return this._runBuildCommandAsync(this.env.PYTHON || 'python', [ + this.configureScript, + ...this.options.configure, + ]); + } + build() { + return __awaiter(this, void 0, void 0, function* () { + this.compileStep.log(`Configuring node build${this.options.configure.length ? ': ' + this.options.configure : '...'}`); + yield this._configureAsync(); + const buildOptions = this.options.make; + this.compileStep.log(`Compiling Node${buildOptions.length ? ' with arguments: ' + buildOptions : '...'}`); + yield this._runBuildCommandAsync(make, buildOptions); + return fs_1.createReadStream(this.getNodeExecutableLocation()); + }); + } + _shouldCompileBinaryAsync(binary, location) { + return __awaiter(this, void 0, void 0, function* () { + //SOMEDAY combine make/configure/vcBuild/and modified times of included files + const { snapshot, build } = this.options; + if (!binary) { + return true; + } + if (build && snapshot != null && (yield util_1.pathExistsAsync(snapshot))) { + const snapshotLastModified = (yield util_1.statAsync(snapshot)).mtimeMs; + const binaryLastModified = (yield util_1.statAsync(location)).mtimeMs; + return snapshotLastModified > binaryLastModified; + } + return false; + }); + } + compileAsync(target) { + return __awaiter(this, void 0, void 0, function* () { + const step = (this.compileStep = this.log.step('Compiling result')); + const build = this.options.build; + const location = this.getNodeExecutableLocation(build ? undefined : target); + let binary = (yield util_1.pathExistsAsync(location)) ? fs_1.createReadStream(location) : null; + if (yield this._shouldCompileBinaryAsync(binary, location)) { + binary = yield this.build(); + step.log('Node binary compiled'); + } + return this._assembleDeliverable(binary); + }); + } + code() { + return [this.shims.join(''), this.startup].join(';'); + } + _assembleDeliverable(binary) { + return __awaiter(this, void 0, void 0, function* () { + if (!this.options.mangle) { + return binary; + } + const resources = this.bundle.renderIndex(); + this.shims.unshift(util_1.wrap(`process.__nexe = ${JSON.stringify({ resources })};\n`)); + const code = this.code(), codeSize = buffer_1.Buffer.byteLength(code), lengths = buffer_1.Buffer.from(Array(16)); + lengths.writeDoubleLE(codeSize, 0); + lengths.writeDoubleLE(this.bundle.size, 8); + return new MultiStream([ + binary, + bundle_1.toStream(code), + this.bundle.toStream(), + bundle_1.toStream(buffer_1.Buffer.concat([buffer_1.Buffer.from(''), lengths])), + ]); + }); + } +} +__decorate([ + util_1.bound +], NexeCompiler.prototype, "addResource", null); +__decorate([ + util_1.bound +], NexeCompiler.prototype, "readFileAsync", null); +__decorate([ + util_1.bound +], NexeCompiler.prototype, "writeFileAsync", null); +__decorate([ + util_1.bound +], NexeCompiler.prototype, "replaceInFileAsync", null); +__decorate([ + util_1.bound +], NexeCompiler.prototype, "setFileContentsAsync", null); +exports.NexeCompiler = NexeCompiler; -- cgit