aboutsummaryrefslogtreecommitdiff
path: root/node_modules/nexe/lib/compiler.js
diff options
context:
space:
mode:
authorMinteck <nekostarfan@gmail.com>2021-08-24 14:41:48 +0200
committerMinteck <nekostarfan@gmail.com>2021-08-24 14:41:48 +0200
commitd25e11bee6ca5ca523884da132d18e1400e077b9 (patch)
tree8af39fde19f7ed640a60fb397c7edd647dff1c4c /node_modules/nexe/lib/compiler.js
downloadkartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.tar.gz
kartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.tar.bz2
kartik-iridium-d25e11bee6ca5ca523884da132d18e1400e077b9.zip
Initial commit
Diffstat (limited to 'node_modules/nexe/lib/compiler.js')
-rw-r--r--node_modules/nexe/lib/compiler.js268
1 files changed, 268 insertions, 0 deletions
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('<nexe~~sentinel>'), 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;