diff options
Diffstat (limited to 'node_modules/nexe/lib')
55 files changed, 2512 insertions, 0 deletions
diff --git a/node_modules/nexe/lib/compiler.d.ts b/node_modules/nexe/lib/compiler.d.ts new file mode 100644 index 0000000..37ed527 --- /dev/null +++ b/node_modules/nexe/lib/compiler.d.ts @@ -0,0 +1,100 @@ +/// <reference types="node" /> +import { ReadStream } from 'fs'; +import { Logger } from './logger'; +import { NexeOptions } from './options'; +import { NexeTarget } from './target'; +import { Bundle } from './fs/bundle'; +import { File } from 'resolve-dependencies'; +declare type StringReplacer = (match: string) => string; +export interface NexeFile { + filename: string; + absPath: string; + contents: string | Buffer; +} +export { NexeOptions }; +export declare class NexeError extends Error { + constructor(m: string); +} +export declare class NexeCompiler { + options: NexeOptions; + /** + * Epoch of when compilation started + */ + private start; + private compileStep; + log: Logger; + /** + * Copy of process.env + */ + env: { + [x: string]: string | undefined; + }; + /** + * Virtual FileSystem + */ + bundle: Bundle; + /** + * Root directory for the source of the current build + */ + src: string; + /** + * In memory files that are being manipulated by the compiler + */ + files: NexeFile[]; + /** + * Standalone pieces of code run before the application entrypoint + */ + shims: string[]; + /** + * The last shim (defaults to "require('module').runMain()") + */ + startup: string; + /** + * The main entrypoint filename for your application - eg. node mainFile.js + */ + entrypoint: string | undefined; + /** + * Not used + */ + targets: NexeTarget[]; + /** + * Current target of the compiler + */ + target: NexeTarget; + /** + * Output filename (-o myapp.exe) + */ + output: string; + /** + * Flag to indicate whether or notstdin was used for input + */ + stdinUsed: boolean; + /** + * Path to the configure script + */ + configureScript: string; + /** + * The file path of node binary + */ + nodeSrcBinPath: string; + /** + * Remote asset path if available + */ + remoteAsset: string; + constructor(options: NexeOptions); + addResource(absoluteFileName: string, content?: Buffer | string | File): Promise<number>; + readFileAsync(file: string): Promise<NexeFile>; + writeFileAsync(file: string, contents: string | Buffer): Promise<void>; + replaceInFileAsync(file: string, replace: string | RegExp, value: string | StringReplacer): Promise<void>; + setFileContentsAsync(file: string, contents: string | Buffer): Promise<void>; + quit(error?: any): Promise<unknown>; + assertBuild(): void; + getNodeExecutableLocation(target?: NexeTarget): string; + private _runBuildCommandAsync; + private _configureAsync; + build(): Promise<ReadStream>; + private _shouldCompileBinaryAsync; + compileAsync(target: NexeTarget): Promise<any>; + code(): string; + private _assembleDeliverable; +} 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; diff --git a/node_modules/nexe/lib/fs/README.md b/node_modules/nexe/lib/fs/README.md new file mode 100644 index 0000000..181c364 --- /dev/null +++ b/node_modules/nexe/lib/fs/README.md @@ -0,0 +1,40 @@ +# nexe-fs + +### Getting Started: + +This module contains a set of patches used to create (and use) the Nexe Virtual FileSystem + +In order for NVFS to work with node's `require` method. A custom build of node must be used. If using the `nexe` cli this will be handled automatically + +The customization should be applied as early as possbile when node is starting up. + +i.e. The contents of `nexe-fs/bootstrap` should be put [here](https://github.com/nodejs/node/blob/0827c80920311fa9d1e6989c8a73aaaeca962eb7/lib/internal/bootstrap/node.js#L27-L28). + +### Creating a NVFS: + +To create a virtual file system use the `Bundle` Object, in your build process: + +```javascript +const { Bundle } = require('nexe-fs') + +const bundle = new Bundle() +await bundle.addResource(absoluteFileName) + +bundle.toStream().pipe(fs.createWriteStream('./myFsBlob')) +``` + +In the entrypoint of your application, the fs patch needs to be applied (executed as early as possible) +For example, In the build process, the application's entrypoint could be prepended with the following: + +```javascript +const codeToPrependToEntrypoint = fs.readFileSync(require.resolve('nexe-fs/patch'), 'utf-8') + ` +shimFs({ + blobPath: 'location/of/myFsBlob', + resources: ${JSON.stringify(bundle)}, + layout: { + resourceStart: 0 // the offset within the blob that is referenced by the bundle index + } +})` +``` + +Since a custom node build is being used. A great place for this code would be the node source file: `_third_party_main.js` diff --git a/node_modules/nexe/lib/fs/bootstrap.js b/node_modules/nexe/lib/fs/bootstrap.js new file mode 100644 index 0000000..a790b91 --- /dev/null +++ b/node_modules/nexe/lib/fs/bootstrap.js @@ -0,0 +1,20 @@ +if (true) { + const __nexe_patches = (process.nexe = { patches: {} }).patches + const slice = [].slice + const __nexe_noop_patch = function (original) { + const args = slice.call(arguments, 1) + return original.apply(this, args) + } + const __nexe_patch = function (obj, method, patch) { + const original = obj[method] + if (!original) return + __nexe_patches[method] = patch + obj[method] = function() { + const args = [original].concat(slice.call(arguments)) + return __nexe_patches[method].apply(this, args) + } + } + __nexe_patch((process).binding('fs'), 'internalModuleReadFile', __nexe_noop_patch) + __nexe_patch((process).binding('fs'), 'internalModuleReadJSON', __nexe_noop_patch) + __nexe_patch((process).binding('fs'), 'internalModuleStat', __nexe_noop_patch) +} diff --git a/node_modules/nexe/lib/fs/bundle.d.ts b/node_modules/nexe/lib/fs/bundle.d.ts new file mode 100644 index 0000000..db298ed --- /dev/null +++ b/node_modules/nexe/lib/fs/bundle.d.ts @@ -0,0 +1,36 @@ +/// <reference types="node" /> +import { Readable } from 'stream'; +import { File } from 'resolve-dependencies'; +export declare type MultiStreams = (Readable | (() => Readable))[]; +export declare function toStream(content: Buffer | string): Readable; +export declare class Bundle { + size: number; + cwd: string; + rendered: boolean; + private offset; + private index; + private files; + streams: MultiStreams; + constructor({ cwd }?: { + cwd: string; + }); + get list(): string[]; + addResource(absoluteFileName: string, content?: File | Buffer | string): Promise<number>; + /** + * De-dupe files by absolute path, partition by symlink/real + * Iterate over real, add entries + * Iterate over symlinks, add symlinks + */ + renderIndex(): { + [key: string]: [number, number]; + }; + /** + * Add a stream if needed and an entry with the required offset and size + * Ensure the calling order of this method is idempotent (eg, while iterating a sorted set) + * @param entryPath + * @param file + * @param useEntry + */ + addEntry(entryPath: string, file: File, useEntry?: string): void; + toStream(): any; +} diff --git a/node_modules/nexe/lib/fs/bundle.js b/node_modules/nexe/lib/fs/bundle.js new file mode 100644 index 0000000..74ed317 --- /dev/null +++ b/node_modules/nexe/lib/fs/bundle.js @@ -0,0 +1,145 @@ +"use strict"; +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 fs = require("fs"); +const util_1 = require("util"); +const path_1 = require("path"); +const stream_1 = require("stream"); +const MultiStream = require("multistream"); +const lstat = util_1.promisify(fs.lstat), realpath = util_1.promisify(fs.realpath), createReadStream = fs.createReadStream, stat = util_1.promisify(fs.stat); +function makeRelative(cwd, path) { + return './' + path_1.relative(cwd, path); +} +function sortEntry(a, b) { + return a[0] > b[0] ? 1 : -1; +} +function toStream(content) { + const readable = new stream_1.Readable({ + read() { + this.push(content); + this.push(null); + }, + }); + return readable; +} +exports.toStream = toStream; +function createFile(absoluteFileName) { + return __awaiter(this, void 0, void 0, function* () { + const stats = yield lstat(absoluteFileName), file = { + size: stats.size, + contents: '', + absPath: absoluteFileName, + deps: {}, + }; + if (stats.isSymbolicLink()) { + file.size = stats.size; + const [realPath, realStat] = yield Promise.all([ + realpath(absoluteFileName), + stat(absoluteFileName), + ]); + file.realPath = realPath; + file.realSize = realStat.size; + } + return file; + }); +} +class Bundle { + constructor({ cwd } = { cwd: process.cwd() }) { + this.size = 0; + this.rendered = false; + this.offset = 0; + this.index = {}; + this.files = {}; + this.streams = []; + this.cwd = cwd; + } + get list() { + return Object.keys(this.files); + } + addResource(absoluteFileName, content) { + return __awaiter(this, void 0, void 0, function* () { + if (this.files[absoluteFileName]) { + return this.size; + } + if (typeof content === 'string' || Buffer.isBuffer(content)) { + this.files[absoluteFileName] = { + size: Buffer.byteLength(content), + contents: content, + deps: {}, + absPath: absoluteFileName, + }; + } + else if (content) { + this.files[content.absPath] = content; + } + else { + this.files[absoluteFileName] = { + absPath: absoluteFileName, + contents: '', + deps: {}, + size: 0, + }; + this.files[absoluteFileName] = yield createFile(absoluteFileName); + } + return (this.size += this.files[absoluteFileName].size); + }); + } + /** + * De-dupe files by absolute path, partition by symlink/real + * Iterate over real, add entries + * Iterate over symlinks, add symlinks + */ + renderIndex() { + if (this.rendered) { + throw new Error('Bundle index already rendered'); + } + const files = Object.entries(this.files), realFiles = [], symLinks = []; + for (const entry of files) { + if (entry[1].realPath) { + symLinks.push(entry); + } + else { + realFiles.push(entry); + } + } + realFiles.sort(sortEntry); + symLinks.sort(sortEntry); + for (const [absPath, file] of realFiles) { + this.addEntry(absPath, file); + } + for (const [absPath, file] of symLinks) { + this.addEntry(file.realPath, file); + this.addEntry(absPath, file, file.realPath); + } + this.rendered = true; + return this.index; + } + /** + * Add a stream if needed and an entry with the required offset and size + * Ensure the calling order of this method is idempotent (eg, while iterating a sorted set) + * @param entryPath + * @param file + * @param useEntry + */ + addEntry(entryPath, file, useEntry) { + var _a; + const existingName = useEntry && makeRelative(this.cwd, useEntry), name = makeRelative(this.cwd, entryPath), size = (_a = file.realSize) !== null && _a !== void 0 ? _a : file.size, existingEntry = this.index[existingName !== null && existingName !== void 0 ? existingName : name]; + this.index[name] = existingEntry || [this.offset, size]; + if (!existingEntry) { + this.streams.push(() => file.contents ? toStream(file.contents) : createReadStream(file.absPath)); + this.offset += size; + } + } + toStream() { + return new MultiStream(this.streams); + } +} +exports.Bundle = Bundle; diff --git a/node_modules/nexe/lib/fs/package.json b/node_modules/nexe/lib/fs/package.json new file mode 100644 index 0000000..c830c02 --- /dev/null +++ b/node_modules/nexe/lib/fs/package.json @@ -0,0 +1,15 @@ +{ + "name": "nexe-fs", + "version": "1.0.1", + "description": "Virtual File System used by nexe", + "main": "bundle.js", + "files": [ + "*.d.ts", + "*.js" + ], + "author": "Caleb Boyd", + "dependencies": { + "multistream": "^2.1.1" + }, + "license": "MIT" +} diff --git a/node_modules/nexe/lib/fs/patch.d.ts b/node_modules/nexe/lib/fs/patch.d.ts new file mode 100644 index 0000000..82c1570 --- /dev/null +++ b/node_modules/nexe/lib/fs/patch.d.ts @@ -0,0 +1,18 @@ +/// <reference types="node" /> +import { Stats } from 'fs'; +export interface NexeBinary { + blobPath: string; + resources: { + [key: string]: number[]; + }; + layout: { + stat: Stats; + resourceStart: number; + contentSize?: number; + contentStart?: number; + resourceSize?: number; + }; +} +declare function shimFs(binary: NexeBinary, fs?: any): true | undefined; +declare function restoreFs(): void; +export { shimFs, restoreFs }; diff --git a/node_modules/nexe/lib/fs/patch.js b/node_modules/nexe/lib/fs/patch.js new file mode 100644 index 0000000..14a5a60 --- /dev/null +++ b/node_modules/nexe/lib/fs/patch.js @@ -0,0 +1,372 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +let originalFsMethods = null; +let lazyRestoreFs = () => { }; +// optional Win32 file namespace prefix followed by drive letter and colon +const windowsFullPathRegex = /^(\\{2}\?\\)?([a-zA-Z]):/; +const upcaseDriveLetter = (s) => s.replace(windowsFullPathRegex, (_match, ns, drive) => `${ns || ''}${drive.toUpperCase()}:`); +function shimFs(binary, fs = require('fs')) { + if (originalFsMethods !== null) { + return; + } + originalFsMethods = Object.assign({}, fs); + const { blobPath, resources: manifest } = binary, { resourceStart, stat } = binary.layout, directories = {}, notAFile = '!@#$%^&*', isWin = process.platform.startsWith('win'), isString = (x) => typeof x === 'string' || x instanceof String, noop = () => { }, path = require('path'), winPath = isWin ? upcaseDriveLetter : (s) => s, baseDir = winPath(path.dirname(process.execPath)); + let log = (_) => true; + let loggedManifest = false; + if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) { + log = (text) => { + setupManifest(); + if (!loggedManifest) { + process.stderr.write('[nexe] - MANIFEST' + JSON.stringify(manifest, null, 4) + '\n'); + process.stderr.write('[nexe] - DIRECTORIES' + JSON.stringify(directories, null, 4) + '\n'); + loggedManifest = true; + } + return process.stderr.write('[nexe] - ' + text + '\n'); + }; + } + const getKey = function getKey(filepath) { + if (Buffer.isBuffer(filepath)) { + filepath = filepath.toString(); + } + if (!isString(filepath)) { + return notAFile; + } + let key = path.resolve(baseDir, filepath); + return winPath(key); + }; + const statTime = function () { + return { + dev: 0, + ino: 0, + nlink: 0, + rdev: 0, + uid: 123, + gid: 500, + blksize: 4096, + blocks: 0, + atime: new Date(stat.atime), + atimeMs: stat.atime.getTime(), + mtime: new Date(stat.mtime), + mtimeMs: stat.mtime.getTime(), + ctime: new Date(stat.ctime), + ctimMs: stat.ctime.getTime(), + birthtime: new Date(stat.birthtime), + birthtimeMs: stat.birthtime.getTime(), + }; + }; + let BigInt; + try { + BigInt = eval('BigInt'); + } + catch (ignored) { } + const createStat = function (extensions, options) { + const stat = Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions); + if (options && options.bigint && BigInt) { + for (const k in stat) { + if (Object.prototype.hasOwnProperty.call(stat, k) && typeof stat[k] === 'number') { + stat[k] = BigInt(stat[k]); + } + } + } + return stat; + }; + const ownStat = function (filepath, options) { + setupManifest(); + const key = getKey(filepath); + if (directories[key]) { + let mode = binary.layout.stat.mode; + mode |= fs.constants.S_IFDIR; + mode &= ~fs.constants.S_IFREG; + return createStat({ mode, size: 0 }, options); + } + if (manifest[key]) { + return createStat({ size: manifest[key][1] }, options); + } + }; + const getStat = function (fn) { + return function stat(filepath, options, callback) { + let stat; + if (typeof options === 'function') { + callback = options; + stat = ownStat(filepath, null); + } + else { + stat = ownStat(filepath, options); + } + if (stat) { + process.nextTick(() => { + callback(null, stat); + }); + } + else { + return originalFsMethods[fn].apply(fs, arguments); + } + }; + }; + function makeLong(filepath) { + return path._makeLong && path._makeLong(filepath); + } + function fileOpts(options) { + return !options ? {} : isString(options) ? { encoding: options } : options; + } + let setupManifest = () => { + Object.keys(manifest).forEach((filepath) => { + const entry = manifest[filepath]; + const absolutePath = getKey(filepath); + const longPath = makeLong(absolutePath); + const normalizedPath = winPath(path.normalize(filepath)); + if (!manifest[absolutePath]) { + manifest[absolutePath] = entry; + } + if (longPath && !manifest[longPath]) { + manifest[longPath] = entry; + } + if (!manifest[normalizedPath]) { + manifest[normalizedPath] = manifest[filepath]; + } + let currentDir = path.dirname(absolutePath); + let prevDir = absolutePath; + while (currentDir !== prevDir) { + directories[currentDir] = directories[currentDir] || {}; + directories[currentDir][path.basename(prevDir)] = true; + const longDir = makeLong(currentDir); + if (longDir && !directories[longDir]) { + directories[longDir] = directories[currentDir]; + } + prevDir = currentDir; + currentDir = path.dirname(currentDir); + } + }); + manifest[notAFile] = false; + directories[notAFile] = false; + setupManifest = noop; + }; + //naive patches intended to work for most use cases + const nfs = { + existsSync: function existsSync(filepath) { + setupManifest(); + const key = getKey(filepath); + if (manifest[key] || directories[key]) { + return true; + } + return originalFsMethods.existsSync.apply(fs, arguments); + }, + realpath: function realpath(filepath, options, cb) { + setupManifest(); + const key = getKey(filepath); + if (isString(filepath) && (manifest[filepath] || manifest[key])) { + return process.nextTick(() => cb(null, filepath)); + } + return originalFsMethods.realpath.call(fs, filepath, options, cb); + }, + realpathSync: function realpathSync(filepath, options) { + setupManifest(); + const key = getKey(filepath); + if (manifest[key]) { + return filepath; + } + return originalFsMethods.realpathSync.call(fs, filepath, options); + }, + readdir: function readdir(filepath, options, callback) { + setupManifest(); + const dir = directories[getKey(filepath)]; + if (dir) { + if ('function' === typeof options) { + callback = options; + options = { encoding: 'utf8' }; + } + process.nextTick(() => callback(null, Object.keys(dir))); + } + else { + return originalFsMethods.readdir.apply(fs, arguments); + } + }, + readdirSync: function readdirSync(filepath, options) { + setupManifest(); + const dir = directories[getKey(filepath)]; + if (dir) { + return Object.keys(dir); + } + return originalFsMethods.readdirSync.apply(fs, arguments); + }, + readFile: function readFile(filepath, options, callback) { + setupManifest(); + const entry = manifest[getKey(filepath)]; + if (!entry) { + return originalFsMethods.readFile.apply(fs, arguments); + } + const [offset, length] = entry; + const resourceOffset = resourceStart + offset; + const encoding = fileOpts(options).encoding; + callback = typeof options === 'function' ? options : callback; + originalFsMethods.open(blobPath, 'r', function (err, fd) { + if (err) + return callback(err, null); + originalFsMethods.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function (error, bytesRead, result) { + if (error) { + return originalFsMethods.close(fd, function () { + callback(error, null); + }); + } + originalFsMethods.close(fd, function (err) { + if (err) { + return callback(err, result); + } + callback(err, encoding ? result.toString(encoding) : result); + }); + }); + }); + }, + createReadStream: function createReadStream(filepath, options) { + setupManifest(); + const entry = manifest[getKey(filepath)]; + if (!entry) { + return originalFsMethods.createReadStream.apply(fs, arguments); + } + const [offset, length] = entry; + const resourceOffset = resourceStart + offset; + const opts = fileOpts(options); + return originalFsMethods.createReadStream(blobPath, Object.assign({}, opts, { + start: resourceOffset, + end: resourceOffset + length - 1, + })); + }, + readFileSync: function readFileSync(filepath, options) { + setupManifest(); + const entry = manifest[getKey(filepath)]; + if (!entry) { + return originalFsMethods.readFileSync.apply(fs, arguments); + } + const [offset, length] = entry; + const resourceOffset = resourceStart + offset; + const encoding = fileOpts(options).encoding; + const fd = originalFsMethods.openSync(process.execPath, 'r'); + const result = Buffer.alloc(length); + originalFsMethods.readSync(fd, result, 0, length, resourceOffset); + originalFsMethods.closeSync(fd); + return encoding ? result.toString(encoding) : result; + }, + statSync: function statSync(filepath, options) { + const stat = ownStat(filepath, options); + if (stat) { + return stat; + } + return originalFsMethods.statSync.apply(fs, arguments); + }, + stat: getStat('stat'), + lstat: getStat('lstat'), + lstatSync: function statSync(filepath, options) { + const stat = ownStat(filepath, options); + if (stat) { + return stat; + } + return originalFsMethods.lstatSync.apply(fs, arguments); + }, + }; + if (typeof fs.exists === 'function') { + nfs.exists = function (filepath, cb) { + cb = cb || noop; + const exists = nfs.existsSync(filepath); + process.nextTick(() => cb(exists)); + }; + } + const patches = process.nexe.patches || {}; + delete process.nexe; + patches.internalModuleReadFile = function (original, ...args) { + setupManifest(); + const filepath = getKey(args[0]); + if (manifest[filepath]) { + log('read (hit) ' + filepath); + return nfs.readFileSync(filepath, 'utf-8'); + } + log('read (miss) ' + filepath); + return original.call(this, ...args); + }; + let returningArray; + patches.internalModuleReadJSON = function (original, ...args) { + if (returningArray == null) + returningArray = Array.isArray(original.call(this, '')); + const res = patches.internalModuleReadFile.call(this, original, ...args); + return returningArray && !Array.isArray(res) + ? [res, /"(main|name|type|exports|imports)"/.test(res)] + : res; + }; + patches.internalModuleStat = function (original, ...args) { + setupManifest(); + const filepath = getKey(args[0]); + if (manifest[filepath]) { + log('stat (hit) ' + filepath + ' ' + 0); + return 0; + } + if (directories[filepath]) { + log('stat dir (hit) ' + filepath + ' ' + 1); + return 1; + } + const res = original.call(this, ...args); + if (res === 0) { + log('stat (miss) ' + filepath + ' ' + res); + } + else if (res === 1) { + log('stat dir (miss) ' + filepath + ' ' + res); + } + else { + log('stat (fail) ' + filepath + ' ' + res); + } + return res; + }; + if (typeof fs.exists === 'function') { + nfs.exists = function (filepath, cb) { + cb = cb || noop; + const exists = nfs.existsSync(filepath); + if (!exists) { + return originalFsMethods.exists(filepath, cb); + } + process.nextTick(() => cb(exists)); + }; + } + if (typeof fs.copyFile === 'function') { + nfs.copyFile = function (filepath, dest, flags, callback) { + setupManifest(); + const entry = manifest[getKey(filepath)]; + if (!entry) { + return originalFsMethods.copyFile.apply(fs, arguments); + } + if (typeof flags === 'function') { + callback = flags; + flags = 0; + } + nfs.readFile(filepath, (err, buffer) => { + if (err) { + return callback(err); + } + originalFsMethods.writeFile(dest, buffer, (err) => { + if (err) { + return callback(err); + } + callback(null); + }); + }); + }; + nfs.copyFileSync = function (filepath, dest) { + setupManifest(); + const entry = manifest[getKey(filepath)]; + if (!entry) { + return originalFsMethods.copyFileSync.apply(fs, arguments); + } + return originalFsMethods.writeFileSync(dest, nfs.readFileSync(filepath)); + }; + } + Object.assign(fs, nfs); + lazyRestoreFs = () => { + Object.keys(nfs).forEach((key) => { + fs[key] = originalFsMethods[key]; + }); + lazyRestoreFs = () => { }; + }; + return true; +} +exports.shimFs = shimFs; +function restoreFs() { + lazyRestoreFs(); +} +exports.restoreFs = restoreFs; diff --git a/node_modules/nexe/lib/logger.d.ts b/node_modules/nexe/lib/logger.d.ts new file mode 100644 index 0000000..bbae283 --- /dev/null +++ b/node_modules/nexe/lib/logger.d.ts @@ -0,0 +1,18 @@ +export interface LogStep { + modify(text: string, color?: string): void; + log(text: string, color?: string): void; + pause(): void; + resume(): void; +} +export declare class Logger { + verbose: boolean; + private silent; + private ora; + private modify; + write: (text: string, color?: string) => void; + constructor(level: 'verbose' | 'silent' | 'info'); + flush(): Promise<unknown>; + _write(update: string, color?: string): void; + _modify(update: string, color?: any): void; + step(text: string, method?: string): LogStep; +} diff --git a/node_modules/nexe/lib/logger.js b/node_modules/nexe/lib/logger.js new file mode 100644 index 0000000..31f33a2 --- /dev/null +++ b/node_modules/nexe/lib/logger.js @@ -0,0 +1,56 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const chalk_1 = require("chalk"); +const ora_1 = require("ora"); +const frameLength = 120; +class Logger { + constructor(level) { + this.verbose = level === 'verbose'; + this.silent = level === 'silent'; + if (!this.silent) { + this.ora = ora_1.default({ + text: 'Starting...', + color: 'blue', + spinner: 'dots', + }); + this.ora.stop(); + } + const noop = () => { }; + this.modify = this.silent ? noop : this._modify.bind(this); + this.write = this.silent ? noop : this._write.bind(this); + } + flush() { + !this.silent && this.ora.succeed(); + return new Promise((resolve) => setTimeout(resolve, frameLength)); + } + _write(update, color = 'green') { + this.ora.succeed().text = chalk_1.default[color](update); + this.ora.start(); + } + _modify(update, color = this.ora.color) { + this.ora.text = update; + this.ora.color = color; + } + step(text, method = 'succeed') { + if (this.silent) { + return { modify() { }, log() { }, pause() { }, resume() { } }; + } + if (!this.ora.id) { + this.ora.start().text = text; + if (method !== 'succeed') { + this.ora[method](); + } + } + else { + this.ora[method]().text = text; + this.ora.start(); + } + return { + modify: this.modify, + log: this.verbose ? this.write : this.modify, + pause: () => this.ora.stopAndPersist(), + resume: () => this.ora.start(), + }; + } +} +exports.Logger = Logger; diff --git a/node_modules/nexe/lib/nexe.d.ts b/node_modules/nexe/lib/nexe.d.ts new file mode 100644 index 0000000..7c941be --- /dev/null +++ b/node_modules/nexe/lib/nexe.d.ts @@ -0,0 +1,5 @@ +import { NexeCompiler } from './compiler'; +import { NexeOptions } from './options'; +declare function compile(compilerOptions?: Partial<NexeOptions>, callback?: (err: Error | null) => void): Promise<void>; +export { compile, NexeCompiler }; +export { argv, version, NexeOptions, help } from './options'; diff --git a/node_modules/nexe/lib/nexe.js b/node_modules/nexe/lib/nexe.js new file mode 100644 index 0000000..179e038 --- /dev/null +++ b/node_modules/nexe/lib/nexe.js @@ -0,0 +1,49 @@ +"use strict"; +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 app_builder_1 = require("app-builder"); +const compiler_1 = require("./compiler"); +exports.NexeCompiler = compiler_1.NexeCompiler; +const options_1 = require("./options"); +const resource_1 = require("./steps/resource"); +const clean_1 = require("./steps/clean"); +const cli_1 = require("./steps/cli"); +const bundle_1 = require("./steps/bundle"); +const download_1 = require("./steps/download"); +const shim_1 = require("./steps/shim"); +const artifacts_1 = require("./steps/artifacts"); +const patches_1 = require("./patches"); +function compile(compilerOptions, callback) { + return __awaiter(this, void 0, void 0, function* () { + let error = null, options = null, compiler = null; + try { + options = options_1.normalizeOptions(compilerOptions); + compiler = new compiler_1.NexeCompiler(options); + yield app_builder_1.compose(clean_1.default, resource_1.default, cli_1.default, bundle_1.default, shim_1.default, download_1.default, options.build ? [artifacts_1.default, ...patches_1.default, ...options.patches] : [], options.plugins)(compiler); + } + catch (e) { + error = e; + } + if (error) { + compiler && compiler.quit(error); + if (callback) + return callback(error); + return Promise.reject(error); + } + if (callback) + callback(null); + }); +} +exports.compile = compile; +var options_2 = require("./options"); +exports.argv = options_2.argv; +exports.version = options_2.version; +exports.help = options_2.help; diff --git a/node_modules/nexe/lib/options.d.ts b/node_modules/nexe/lib/options.d.ts new file mode 100644 index 0000000..ea28d23 --- /dev/null +++ b/node_modules/nexe/lib/options.d.ts @@ -0,0 +1,56 @@ +import * as parseArgv from 'minimist'; +import { NexeCompiler } from './compiler'; +import { NexeTarget } from './target'; +export declare const version = "{{replace:0}}"; +export interface NexePatch { + (compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; +} +export interface NexeOptions { + build: boolean; + input: string; + output: string; + targets: (string | NexeTarget)[]; + name: string; + remote: string; + asset: string; + cwd: string; + fs: boolean | string[]; + flags: string[]; + configure: string[]; + vcBuild: string[]; + make: string[]; + snapshot?: string; + resources: string[]; + temp: string; + rc: { + [key: string]: string; + }; + enableNodeCli: boolean; + bundle: boolean | string; + patches: (string | NexePatch)[]; + plugins: (string | NexePatch)[]; + native: any; + mangle: boolean; + ghToken: string; + sourceUrl?: string; + enableStdIn?: boolean; + python?: string; + loglevel: 'info' | 'silent' | 'verbose'; + silent?: boolean; + fakeArgv?: boolean; + verbose?: boolean; + info?: boolean; + ico?: string; + debugBundle?: boolean; + warmup?: string; + clean?: boolean; + /** + * Api Only + */ + downloadOptions: any; +} +declare const argv: parseArgv.ParsedArgs; +declare let help: string; +export declare function resolveEntry(input: string, cwd: string, maybeEntry: string | undefined, bundle: boolean | string): string; +declare function normalizeOptions(input?: Partial<NexeOptions>): NexeOptions; +export { argv, normalizeOptions, help }; diff --git a/node_modules/nexe/lib/options.js b/node_modules/nexe/lib/options.js new file mode 100644 index 0000000..10d80f3 --- /dev/null +++ b/node_modules/nexe/lib/options.js @@ -0,0 +1,238 @@ +"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 <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 -- 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; diff --git a/node_modules/nexe/lib/patches/boot-nexe.d.ts b/node_modules/nexe/lib/patches/boot-nexe.d.ts new file mode 100644 index 0000000..fae3f7a --- /dev/null +++ b/node_modules/nexe/lib/patches/boot-nexe.d.ts @@ -0,0 +1,5 @@ +/// <reference types="node" /> +declare const fs: any, fd: any, stat: any, tailSize: number, tailWindow: Buffer; +declare const footerPosition: number; +declare const footer: Buffer, contentSize: number, resourceSize: number, contentStart: number, resourceStart: number; +declare const contentBuffer: Buffer, Module: any; diff --git a/node_modules/nexe/lib/patches/boot-nexe.js b/node_modules/nexe/lib/patches/boot-nexe.js new file mode 100644 index 0000000..d5aa8db --- /dev/null +++ b/node_modules/nexe/lib/patches/boot-nexe.js @@ -0,0 +1,38 @@ +"use strict"; +const fs = require('fs'), fd = fs.openSync(process.execPath, 'r'), stat = fs.statSync(process.execPath), tailSize = Math.min(stat.size, 16000), tailWindow = Buffer.from(Array(tailSize)); +fs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize); +const footerPosition = tailWindow.indexOf('<nexe~~sentinel>'); +if (footerPosition == -1) { + throw 'Invalid Nexe binary'; +} +const footer = tailWindow.slice(footerPosition, footerPosition + 32), contentSize = footer.readDoubleLE(16), resourceSize = footer.readDoubleLE(24), contentStart = stat.size - tailSize + footerPosition - resourceSize - contentSize, resourceStart = contentStart + contentSize; +Object.defineProperty(process, '__nexe', (function () { + let nexeHeader = null; + return { + get: function () { + return nexeHeader; + }, + set: function (value) { + if (nexeHeader) { + throw new Error('This property is readonly'); + } + nexeHeader = Object.assign({}, value, { + blobPath: process.execPath, + layout: { + stat, + contentSize, + contentStart, + resourceSize, + resourceStart, + }, + }); + Object.freeze(nexeHeader); + }, + enumerable: false, + configurable: false, + }; +})()); +const contentBuffer = Buffer.from(Array(contentSize)), Module = require('module'); +fs.readSync(fd, contentBuffer, 0, contentSize, contentStart); +fs.closeSync(fd); +new Module(process.execPath, null)._compile(contentBuffer.toString(), process.execPath); diff --git a/node_modules/nexe/lib/patches/build-fixes.d.ts b/node_modules/nexe/lib/patches/build-fixes.d.ts new file mode 100644 index 0000000..bbed32e --- /dev/null +++ b/node_modules/nexe/lib/patches/build-fixes.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function buildFixes(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/build-fixes.js b/node_modules/nexe/lib/patches/build-fixes.js new file mode 100644 index 0000000..1bfb565 --- /dev/null +++ b/node_modules/nexe/lib/patches/build-fixes.js @@ -0,0 +1,22 @@ +"use strict"; +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 }); +function buildFixes(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + if (!compiler.target.version.startsWith('8.2')) { + return next(); + } + const file = yield compiler.readFileAsync('./tools/msvs/find_python.cmd'); + yield compiler.replaceInFileAsync('./tools/msvs/find_python.cmd', '%p%python.exe -V 2>&1', '"%p%python.exe" -V 2>&1'); + return next(); + }); +} +exports.default = buildFixes; diff --git a/node_modules/nexe/lib/patches/disable-node-cli.d.ts b/node_modules/nexe/lib/patches/disable-node-cli.d.ts new file mode 100644 index 0000000..7425253 --- /dev/null +++ b/node_modules/nexe/lib/patches/disable-node-cli.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function disableNodeCli(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/disable-node-cli.js b/node_modules/nexe/lib/patches/disable-node-cli.js new file mode 100644 index 0000000..569b400 --- /dev/null +++ b/node_modules/nexe/lib/patches/disable-node-cli.js @@ -0,0 +1,45 @@ +"use strict"; +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 util_1 = require("../util"); +function disableNodeCli(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + if (compiler.options.enableNodeCli) { + return next(); + } + if (util_1.semverGt(compiler.target.version, '11.6.0')) { + yield compiler.replaceInFileAsync('src/node.cc', /(?<!int )ProcessGlobalArgs\(argv[^;]*;/gm, '0;/*$&*/'); + } + else if (util_1.semverGt(compiler.target.version, '10.9')) { + yield compiler.replaceInFileAsync('src/node.cc', /(?<!void )ProcessArgv\(argv/g, '//$&'); + } + else if (util_1.semverGt(compiler.target.version, '9.999')) { + yield compiler.replaceInFileAsync('src/node.cc', 'int i = 1; i < v8_argc; i++', 'int i = v8_argc; i < v8_argc; i++'); + let matches = 0; + yield compiler.replaceInFileAsync('src/node.cc', /v8_argc > 1/g, (match) => { + if (matches++) { + return 'false'; + } + return match; + }); + } + else { + const nodeccMarker = 'argv[index][0] =='; + yield compiler.replaceInFileAsync('src/node.cc', `${nodeccMarker} '-'`, + // allow NODE_OPTIONS, introduced in 8.0 + util_1.semverGt(compiler.target.version, '7.99') + ? `(${nodeccMarker} (is_env ? '-' : ']'))` + : `(${nodeccMarker} ']')`); + } + return next(); + }); +} +exports.default = disableNodeCli; diff --git a/node_modules/nexe/lib/patches/flags.d.ts b/node_modules/nexe/lib/patches/flags.d.ts new file mode 100644 index 0000000..85f487c --- /dev/null +++ b/node_modules/nexe/lib/patches/flags.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function flags(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/flags.js b/node_modules/nexe/lib/patches/flags.js new file mode 100644 index 0000000..1821081 --- /dev/null +++ b/node_modules/nexe/lib/patches/flags.js @@ -0,0 +1,22 @@ +"use strict"; +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 }); +function flags(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const nodeflags = compiler.options.flags; + if (!nodeflags.length) { + return next(); + } + yield compiler.replaceInFileAsync('node.gyp', "'node_v8_options%': ''", `'node_v8_options%': '${nodeflags.join(' ')}'`); + return next(); + }); +} +exports.default = flags; diff --git a/node_modules/nexe/lib/patches/gyp.d.ts b/node_modules/nexe/lib/patches/gyp.d.ts new file mode 100644 index 0000000..38d7108 --- /dev/null +++ b/node_modules/nexe/lib/patches/gyp.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function nodeGyp({ files, replaceInFileAsync }: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/gyp.js b/node_modules/nexe/lib/patches/gyp.js new file mode 100644 index 0000000..5e51a0b --- /dev/null +++ b/node_modules/nexe/lib/patches/gyp.js @@ -0,0 +1,25 @@ +"use strict"; +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 }); +function nodeGyp({ files, replaceInFileAsync }, next) { + return __awaiter(this, void 0, void 0, function* () { + yield next(); + const nodeGypMarker = "'lib/fs.js',"; + yield replaceInFileAsync('node.gyp', nodeGypMarker, ` + ${nodeGypMarker} + ${files + .filter((x) => x.filename.startsWith('lib')) + .map((x) => `'${x.filename}'`) + .toString()}, + `.trim()); + }); +} +exports.default = nodeGyp; diff --git a/node_modules/nexe/lib/patches/ico.d.ts b/node_modules/nexe/lib/patches/ico.d.ts new file mode 100644 index 0000000..316d393 --- /dev/null +++ b/node_modules/nexe/lib/patches/ico.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function ico(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/ico.js b/node_modules/nexe/lib/patches/ico.js new file mode 100644 index 0000000..01d09b2 --- /dev/null +++ b/node_modules/nexe/lib/patches/ico.js @@ -0,0 +1,24 @@ +"use strict"; +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 util_1 = require("../util"); +function ico(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const iconFile = compiler.options.ico; + if (!iconFile) { + return next(); + } + yield compiler.setFileContentsAsync('src/res/node.ico', yield util_1.readFileAsync(path_1.normalize(iconFile))); + return next(); + }); +} +exports.default = ico; diff --git a/node_modules/nexe/lib/patches/index.d.ts b/node_modules/nexe/lib/patches/index.d.ts new file mode 100644 index 0000000..b48c12d --- /dev/null +++ b/node_modules/nexe/lib/patches/index.d.ts @@ -0,0 +1,3 @@ +import gyp from './gyp'; +declare const patches: (typeof gyp)[]; +export default patches; diff --git a/node_modules/nexe/lib/patches/index.js b/node_modules/nexe/lib/patches/index.js new file mode 100644 index 0000000..6c75700 --- /dev/null +++ b/node_modules/nexe/lib/patches/index.js @@ -0,0 +1,12 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const gyp_1 = require("./gyp"); +const third_party_main_1 = require("./third-party-main"); +const build_fixes_1 = require("./build-fixes"); +const disable_node_cli_1 = require("./disable-node-cli"); +const flags_1 = require("./flags"); +const ico_1 = require("./ico"); +const node_rc_1 = require("./node-rc"); +const snapshot_1 = require("./snapshot"); +const patches = [gyp_1.default, third_party_main_1.default, build_fixes_1.default, disable_node_cli_1.default, flags_1.default, ico_1.default, node_rc_1.default, snapshot_1.default]; +exports.default = patches; diff --git a/node_modules/nexe/lib/patches/node-rc.d.ts b/node_modules/nexe/lib/patches/node-rc.d.ts new file mode 100644 index 0000000..5be1bb6 --- /dev/null +++ b/node_modules/nexe/lib/patches/node-rc.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function nodeRc(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/node-rc.js b/node_modules/nexe/lib/patches/node-rc.js new file mode 100644 index 0000000..d689f84 --- /dev/null +++ b/node_modules/nexe/lib/patches/node-rc.js @@ -0,0 +1,37 @@ +"use strict"; +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 }); +function nodeRc(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const options = compiler.options.rc; + if (!options) { + return next(); + } + const file = yield compiler.readFileAsync('src/res/node.rc'); + Object.keys(options).forEach((key) => { + let value = options[key]; + const isVar = /^[A-Z_]+$/.test(value); + value = isVar ? value : `"${value}"`; + file.contents = file.contents + .toString() + .replace(new RegExp(`VALUE "${key}",.*`), `VALUE "${key}", ${value}`); + }); + ['PRODUCTVERSION', 'FILEVERSION'].forEach((x) => { + if (options[x]) { + file.contents = file.contents + .toString() + .replace(new RegExp(x + ' .*$', 'm'), `${x} ${options[x]}`); + } + }); + return next(); + }); +} +exports.default = nodeRc; diff --git a/node_modules/nexe/lib/patches/snapshot.d.ts b/node_modules/nexe/lib/patches/snapshot.d.ts new file mode 100644 index 0000000..a94e274 --- /dev/null +++ b/node_modules/nexe/lib/patches/snapshot.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function (compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/snapshot.js b/node_modules/nexe/lib/patches/snapshot.js new file mode 100644 index 0000000..5435b9b --- /dev/null +++ b/node_modules/nexe/lib/patches/snapshot.js @@ -0,0 +1,25 @@ +"use strict"; +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 util_1 = require("../util"); +function default_1(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { snapshot, warmup, cwd } = compiler.options; + if (!snapshot) { + return next(); + } + const variablePrefix = util_1.semverGt(compiler.target.version, '11.0.0') ? 'v8_' : ''; + yield compiler.replaceInFileAsync(compiler.configureScript, 'def configure_v8(o):', `def configure_v8(o):\n o['variables']['${variablePrefix}embed_script'] = r'${path_1.resolve(cwd, snapshot)}'\n o['variables']['${variablePrefix}warmup_script'] = r'${path_1.resolve(cwd, warmup || snapshot)}'`); + return next(); + }); +} +exports.default = default_1; diff --git a/node_modules/nexe/lib/patches/third-party-main.d.ts b/node_modules/nexe/lib/patches/third-party-main.d.ts new file mode 100644 index 0000000..606a50e --- /dev/null +++ b/node_modules/nexe/lib/patches/third-party-main.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function main(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/patches/third-party-main.js b/node_modules/nexe/lib/patches/third-party-main.js new file mode 100644 index 0000000..3a098c0 --- /dev/null +++ b/node_modules/nexe/lib/patches/third-party-main.js @@ -0,0 +1,92 @@ +"use strict"; +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 cherow_1 = require("cherow"); +const util_1 = require("../util"); +function walkSome(node, visit) { + if (!node || typeof node.type !== 'string' || node._visited) { + return false; + } + visit(node); + node._visited = true; + for (let childNode in node) { + const child = node[childNode]; + if (Array.isArray(child)) { + for (let i = 0; i < child.length; i++) { + if (walkSome(child[i], visit)) { + return true; + } + } + } + else if (walkSome(child, visit)) { + return true; + } + } + return false; +} +function main(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + let bootFile = 'lib/internal/bootstrap_node.js'; + const { version } = compiler.target; + if (version.startsWith('4.')) { + bootFile = 'src/node.js'; + } + else if (util_1.semverGt(version, '11.99')) { + bootFile = 'lib/internal/bootstrap/pre_execution.js'; + } + else if (util_1.semverGt(version, '9.10.1')) { + bootFile = 'lib/internal/bootstrap/node.js'; + } + const file = yield compiler.readFileAsync(bootFile), ast = cherow_1.parse(file.contents.toString(), { + loc: true, + tolerant: true, + next: true, + globalReturn: true, + node: true, + skipShebang: true, + }), location = { start: { line: 0 } }; + walkSome(ast, (node) => { + if (!location.start.line && node.type === 'BlockStatement') { + //Find the first block statement and mark the location + Object.assign(location, node.loc); + return true; + } + }); + const fileLines = file.contents.toString().split('\n'); + fileLines.splice(location.start.line, 0, "if (true) {\n const __nexe_patches = (process.nexe = { patches: {} }).patches\n const slice = [].slice\n const __nexe_noop_patch = function (original) {\n const args = slice.call(arguments, 1)\n return original.apply(this, args)\n }\n const __nexe_patch = function (obj, method, patch) {\n const original = obj[method]\n if (!original) return\n __nexe_patches[method] = patch\n obj[method] = function() {\n const args = [original].concat(slice.call(arguments))\n return __nexe_patches[method].apply(this, args)\n }\n }\n __nexe_patch((process).binding('fs'), 'internalModuleReadFile', __nexe_noop_patch)\n __nexe_patch((process).binding('fs'), 'internalModuleReadJSON', __nexe_noop_patch)\n __nexe_patch((process).binding('fs'), 'internalModuleStat', __nexe_noop_patch)\n}\n" + + '\n' + + (util_1.semverGt(version, '11.99') ? 'expandArgv1 = false;\n' : '')); + file.contents = fileLines.join('\n'); + if (util_1.semverGt(version, '11.99')) { + if (util_1.semverGt(version, '12.17.99')) { + yield compiler.replaceInFileAsync(bootFile, 'initializeFrozenIntrinsics();', 'initializeFrozenIntrinsics();\n' + util_1.wrap("\"use strict\";\nconst fs = require('fs'), fd = fs.openSync(process.execPath, 'r'), stat = fs.statSync(process.execPath), tailSize = Math.min(stat.size, 16000), tailWindow = Buffer.from(Array(tailSize));\nfs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize);\nconst footerPosition = tailWindow.indexOf('<nexe~~sentinel>');\nif (footerPosition == -1) {\n throw 'Invalid Nexe binary';\n}\nconst footer = tailWindow.slice(footerPosition, footerPosition + 32), contentSize = footer.readDoubleLE(16), resourceSize = footer.readDoubleLE(24), contentStart = stat.size - tailSize + footerPosition - resourceSize - contentSize, resourceStart = contentStart + contentSize;\nObject.defineProperty(process, '__nexe', (function () {\n let nexeHeader = null;\n return {\n get: function () {\n return nexeHeader;\n },\n set: function (value) {\n if (nexeHeader) {\n throw new Error('This property is readonly');\n }\n nexeHeader = Object.assign({}, value, {\n blobPath: process.execPath,\n layout: {\n stat,\n contentSize,\n contentStart,\n resourceSize,\n resourceStart,\n },\n });\n Object.freeze(nexeHeader);\n },\n enumerable: false,\n configurable: false,\n };\n})());\nconst contentBuffer = Buffer.from(Array(contentSize)), Module = require('module');\nfs.readSync(fd, contentBuffer, 0, contentSize, contentStart);\nfs.closeSync(fd);\nnew Module(process.execPath, null)._compile(contentBuffer.toString(), process.execPath);\n")); + } + else { + yield compiler.replaceInFileAsync(bootFile, 'initializePolicy();', 'initializePolicy();\n' + util_1.wrap("\"use strict\";\nconst fs = require('fs'), fd = fs.openSync(process.execPath, 'r'), stat = fs.statSync(process.execPath), tailSize = Math.min(stat.size, 16000), tailWindow = Buffer.from(Array(tailSize));\nfs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize);\nconst footerPosition = tailWindow.indexOf('<nexe~~sentinel>');\nif (footerPosition == -1) {\n throw 'Invalid Nexe binary';\n}\nconst footer = tailWindow.slice(footerPosition, footerPosition + 32), contentSize = footer.readDoubleLE(16), resourceSize = footer.readDoubleLE(24), contentStart = stat.size - tailSize + footerPosition - resourceSize - contentSize, resourceStart = contentStart + contentSize;\nObject.defineProperty(process, '__nexe', (function () {\n let nexeHeader = null;\n return {\n get: function () {\n return nexeHeader;\n },\n set: function (value) {\n if (nexeHeader) {\n throw new Error('This property is readonly');\n }\n nexeHeader = Object.assign({}, value, {\n blobPath: process.execPath,\n layout: {\n stat,\n contentSize,\n contentStart,\n resourceSize,\n resourceStart,\n },\n });\n Object.freeze(nexeHeader);\n },\n enumerable: false,\n configurable: false,\n };\n})());\nconst contentBuffer = Buffer.from(Array(contentSize)), Module = require('module');\nfs.readSync(fd, contentBuffer, 0, contentSize, contentStart);\nfs.closeSync(fd);\nnew Module(process.execPath, null)._compile(contentBuffer.toString(), process.execPath);\n")); + } + yield compiler.replaceInFileAsync(bootFile, 'assert(!CJSLoader.hasLoadedAnyUserCJSModule)', '/*assert(!CJSLoader.hasLoadedAnyUserCJSModule)*/'); + const { contents: nodeccContents } = yield compiler.readFileAsync('src/node.cc'); + if (nodeccContents.includes('if (env->worker_context() != nullptr) {')) { + yield compiler.replaceInFileAsync('src/node.cc', 'if (env->worker_context() != nullptr) {', 'if (env->worker_context() == nullptr) {\n' + + ' return StartExecution(env, "internal/main/run_main_module"); } else {\n'); + } + else { + yield compiler.replaceInFileAsync('src/node.cc', 'MaybeLocal<Value> StartMainThreadExecution(Environment* env) {', 'MaybeLocal<Value> StartMainThreadExecution(Environment* env) {\n' + + ' return StartExecution(env, "internal/main/run_main_module");\n'); + } + } + else { + yield compiler.setFileContentsAsync('lib/_third_party_main.js', "\"use strict\";\nconst fs = require('fs'), fd = fs.openSync(process.execPath, 'r'), stat = fs.statSync(process.execPath), tailSize = Math.min(stat.size, 16000), tailWindow = Buffer.from(Array(tailSize));\nfs.readSync(fd, tailWindow, 0, tailSize, stat.size - tailSize);\nconst footerPosition = tailWindow.indexOf('<nexe~~sentinel>');\nif (footerPosition == -1) {\n throw 'Invalid Nexe binary';\n}\nconst footer = tailWindow.slice(footerPosition, footerPosition + 32), contentSize = footer.readDoubleLE(16), resourceSize = footer.readDoubleLE(24), contentStart = stat.size - tailSize + footerPosition - resourceSize - contentSize, resourceStart = contentStart + contentSize;\nObject.defineProperty(process, '__nexe', (function () {\n let nexeHeader = null;\n return {\n get: function () {\n return nexeHeader;\n },\n set: function (value) {\n if (nexeHeader) {\n throw new Error('This property is readonly');\n }\n nexeHeader = Object.assign({}, value, {\n blobPath: process.execPath,\n layout: {\n stat,\n contentSize,\n contentStart,\n resourceSize,\n resourceStart,\n },\n });\n Object.freeze(nexeHeader);\n },\n enumerable: false,\n configurable: false,\n };\n})());\nconst contentBuffer = Buffer.from(Array(contentSize)), Module = require('module');\nfs.readSync(fd, contentBuffer, 0, contentSize, contentStart);\nfs.closeSync(fd);\nnew Module(process.execPath, null)._compile(contentBuffer.toString(), process.execPath);\n"); + } + return next(); + }); +} +exports.default = main; diff --git a/node_modules/nexe/lib/releases.d.ts b/node_modules/nexe/lib/releases.d.ts new file mode 100644 index 0000000..094d8ca --- /dev/null +++ b/node_modules/nexe/lib/releases.d.ts @@ -0,0 +1,15 @@ +import { NexeTarget } from './target'; +export { NexeTarget }; +export interface GitAsset { + name: string; + url: string; + browser_download_url: string; +} +export interface GitRelease { + tag_name: string; + assets_url: string; + upload_url: string; + assets: GitAsset[]; +} +export declare function getLatestGitRelease(options?: any): Promise<GitRelease>; +export declare function getUnBuiltReleases(options?: any): Promise<NexeTarget[]>; diff --git a/node_modules/nexe/lib/releases.js b/node_modules/nexe/lib/releases.js new file mode 100644 index 0000000..ffd5ec5 --- /dev/null +++ b/node_modules/nexe/lib/releases.js @@ -0,0 +1,56 @@ +"use strict"; +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 got = require("got"); +const target_1 = require("./target"); +const versionsToSkip = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 17, 19, 21, 22]; +function getJson(url, options) { + return __awaiter(this, void 0, void 0, function* () { + return JSON.parse((yield got(url, options)).body); + }); +} +function isBuildableVersion(version) { + if (version === '12.11.0') { + return false; + } + return !versionsToSkip.includes(Number(version.split('.')[0])); +} +function getLatestGitRelease(options) { + return getJson('https://api.github.com/repos/nexe/nexe/releases/latest', options); +} +exports.getLatestGitRelease = getLatestGitRelease; +function getUnBuiltReleases(options) { + return __awaiter(this, void 0, void 0, function* () { + const nodeReleases = yield getJson('https://nodejs.org/download/release/index.json'); + const existingVersions = (yield getLatestGitRelease(options)).assets.map((x) => target_1.getTarget(x.name)); + const versionMap = {}; + return nodeReleases + .reduce((versions, { version }) => { + version = version.replace('v', '').trim(); + if (!isBuildableVersion(version) || versionMap[version]) { + return versions; + } + versionMap[version] = true; + target_1.platforms.forEach((platform) => { + target_1.architectures.forEach((arch) => { + if (arch === 'x86' && platform === 'mac') + return; + if (arch.includes('arm')) + return; + versions.push(target_1.getTarget({ platform, arch, version })); + }); + }); + return versions; + }, []) + .filter((x) => !existingVersions.some((t) => target_1.targetsEqual(t, x))); + }); +} +exports.getUnBuiltReleases = getUnBuiltReleases; diff --git a/node_modules/nexe/lib/steps/artifacts.d.ts b/node_modules/nexe/lib/steps/artifacts.d.ts new file mode 100644 index 0000000..8042d38 --- /dev/null +++ b/node_modules/nexe/lib/steps/artifacts.d.ts @@ -0,0 +1,11 @@ +import { NexeCompiler } from '../compiler'; +/** + * 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. + */ +export default function artifacts(compiler: NexeCompiler, next: () => Promise<void>): Promise<void[]>; diff --git a/node_modules/nexe/lib/steps/artifacts.js b/node_modules/nexe/lib/steps/artifacts.js new file mode 100644 index 0000000..d152178 --- /dev/null +++ b/node_modules/nexe/lib/steps/artifacts.js @@ -0,0 +1,66 @@ +"use strict"; +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 fs = require("fs"); +const util_1 = require("util"); +const util_2 = require("../util"); +const mkdirpAsync = require("mkdirp"); +const unlinkAsync = util_1.promisify(fs.unlink), readdirAsync = util_1.promisify(fs.readdir); +function readDirAsync(dir) { + return readdirAsync(dir).then((paths) => { + return Promise.all(paths.map((file) => { + const path = path_1.join(dir, file); + return util_2.isDirectoryAsync(path).then((x) => (x ? readDirAsync(path) : path)); + })).then((result) => { + return [].concat(...result); + }); + }); +} +function maybeReadFileContentsAsync(file) { + return util_2.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. + */ +function artifacts(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { src } = compiler; + const temp = path_1.join(src, 'nexe'); + yield mkdirpAsync(temp); + const tmpFiles = yield readDirAsync(temp); + yield Promise.all(tmpFiles.map((path) => __awaiter(this, void 0, void 0, function* () { + return compiler.writeFileAsync(path.replace(temp, ''), yield util_2.readFileAsync(path, 'utf-8')); + }))); + yield next(); + yield Promise.all(tmpFiles.map((x) => unlinkAsync(x))); + return Promise.all(compiler.files.map((file) => __awaiter(this, void 0, void 0, function* () { + const sourceFile = path_1.join(src, file.filename); + const tempFile = path_1.join(temp, file.filename); + const fileContents = yield maybeReadFileContentsAsync(sourceFile); + yield mkdirpAsync(path_1.dirname(tempFile)); + yield util_2.writeFileAsync(tempFile, fileContents); + yield compiler.writeFileAsync(file.filename, file.contents); + }))); + }); +} +exports.default = artifacts; diff --git a/node_modules/nexe/lib/steps/bundle.d.ts b/node_modules/nexe/lib/steps/bundle.d.ts new file mode 100644 index 0000000..64229c8 --- /dev/null +++ b/node_modules/nexe/lib/steps/bundle.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function bundle(compiler: NexeCompiler, next: any): Promise<any>; diff --git a/node_modules/nexe/lib/steps/bundle.js b/node_modules/nexe/lib/steps/bundle.js new file mode 100644 index 0000000..d09f470 --- /dev/null +++ b/node_modules/nexe/lib/steps/bundle.js @@ -0,0 +1,79 @@ +"use strict"; +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 compiler_1 = require("../compiler"); +const path_1 = require("path"); +const resolve_dependencies_1 = require("resolve-dependencies"); +const util_1 = require("../util"); +function getStdIn(stdin) { + let out = ''; + return new Promise((resolve) => { + stdin + .setEncoding('utf8') + .on('readable', () => { + let current; + while ((current = stdin.read())) { + out += current; + } + }) + .on('end', () => resolve(out.trim())); + setTimeout(() => { + if (!out.trim()) { + resolve(out.trim()); + } + }, 1000); + }); +} +function bundle(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { bundle: doBundle, cwd, input: inputPath } = compiler.options; + let input = inputPath; + compiler.entrypoint = './' + path_1.relative(cwd, input); + if (util_1.semverGt(compiler.target.version, '11.99')) { + compiler.startup = ''; + } + else { + compiler.startup = ';require("module").runMain();'; + } + if (!doBundle) { + yield compiler.addResource(path_1.resolve(cwd, input)); + return next(); + } + let code = ''; + if (typeof doBundle === 'string') { + code = yield require(doBundle).createBundle(compiler.options); + } + if (input === util_1.STDIN_FLAG && (code = code || util_1.dequote(yield getStdIn(process.stdin)))) { + compiler.stdinUsed = true; + compiler.entrypoint = './__nexe_stdin.js'; + yield compiler.addResource(path_1.resolve(cwd, compiler.entrypoint), code); + return next(); + } + if (input === util_1.STDIN_FLAG) { + const maybeInput = resolve_dependencies_1.resolveSync(cwd, '.'); + if (!maybeInput || !maybeInput.absPath) { + throw new compiler_1.NexeError('No valid input detected'); + } + input = maybeInput.absPath; + compiler.entrypoint = './' + path_1.relative(cwd, input); + } + const { files, warnings } = resolve_dependencies_1.default(input, ...Object.keys(compiler.bundle.list).filter((x) => x.endsWith('.js')), { cwd, expand: 'variable', loadContent: false }); + if (warnings.filter((x) => x.startsWith('Error parsing file') && !x.includes('node_modules')).length) { + throw new compiler_1.NexeError('Parsing Error:\n' + warnings.join('\n')); + } + //TODO: warnings.forEach((x) => console.log(x)) + yield Promise.all(Object.entries(files).map(([key, file]) => { + return compiler.addResource(key, file); + })); + return next(); + }); +} +exports.default = bundle; diff --git a/node_modules/nexe/lib/steps/clean.d.ts b/node_modules/nexe/lib/steps/clean.d.ts new file mode 100644 index 0000000..ced1461 --- /dev/null +++ b/node_modules/nexe/lib/steps/clean.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function clean(compiler: NexeCompiler, next: () => Promise<any>): Promise<any>; diff --git a/node_modules/nexe/lib/steps/clean.js b/node_modules/nexe/lib/steps/clean.js new file mode 100644 index 0000000..27dba57 --- /dev/null +++ b/node_modules/nexe/lib/steps/clean.js @@ -0,0 +1,30 @@ +"use strict"; +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 util_1 = require("../util"); +function clean(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { options } = compiler; + if (options.clean) { + let path = compiler.src; + if (!options.build) { + path = compiler.getNodeExecutableLocation(compiler.options.targets[0]); + } + const step = compiler.log.step('Cleaning up nexe build artifacts...'); + step.log(`Deleting contents at: ${path}`); + yield util_1.rimrafAsync(path); + step.log(`Deleted contents at: ${path}`); + return compiler.quit(); + } + return next(); + }); +} +exports.default = clean; diff --git a/node_modules/nexe/lib/steps/cli.d.ts b/node_modules/nexe/lib/steps/cli.d.ts new file mode 100644 index 0000000..02b796a --- /dev/null +++ b/node_modules/nexe/lib/steps/cli.d.ts @@ -0,0 +1,12 @@ +import { NexeCompiler } from '../compiler'; +/** + * The "cli" step detects the appropriate input. If no input options are passed, + * 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: + * + * @param {*} compiler + * @param {*} next + */ +export default function cli(compiler: NexeCompiler, next: () => Promise<void>): Promise<unknown>; diff --git a/node_modules/nexe/lib/steps/cli.js b/node_modules/nexe/lib/steps/cli.js new file mode 100644 index 0000000..6223338 --- /dev/null +++ b/node_modules/nexe/lib/steps/cli.js @@ -0,0 +1,55 @@ +"use strict"; +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 fs_1 = require("fs"); +const util_1 = require("../util"); +const mkdirp = require("mkdirp"); +/** + * The "cli" step detects the appropriate input. If no input options are passed, + * 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: + * + * @param {*} compiler + * @param {*} next + */ +function cli(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + yield next(); + const { log } = compiler, target = compiler.options.targets.shift(), deliverable = yield compiler.compileAsync(target), output = path_1.normalize(compiler.output); + mkdirp.sync(path_1.dirname(output)); + return new Promise((res, rej) => { + const step = log.step('Writing result to file'); + deliverable + .pipe(fs_1.createWriteStream(output)) + .on('error', rej) + .once('close', (e) => { + if (e) { + rej(e); + } + else if (compiler.output) { + const output = compiler.output, mode = fs_1.statSync(output).mode | 0o111, inputFileLogOutput = path_1.relative(process.cwd(), path_1.resolve(compiler.options.cwd, compiler.entrypoint || compiler.options.input)), outputFileLogOutput = path_1.relative(process.cwd(), output); + fs_1.chmodSync(output, mode.toString(8).slice(-3)); + step.log(`Entry: '${compiler.stdinUsed + ? compiler.options.mangle + ? util_1.STDIN_FLAG + : '[none]' + : inputFileLogOutput}' written to: ${outputFileLogOutput}`); + compiler.quit(); + res(output); + } + }); + }); + }); +} +exports.default = cli; diff --git a/node_modules/nexe/lib/steps/download.d.ts b/node_modules/nexe/lib/steps/download.d.ts new file mode 100644 index 0000000..50c81ed --- /dev/null +++ b/node_modules/nexe/lib/steps/download.d.ts @@ -0,0 +1,7 @@ +import { NexeCompiler } from '../compiler'; +/** + * Downloads the node source to the configured temporary directory + * @param {*} compiler + * @param {*} next + */ +export default function downloadNode(compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/steps/download.js b/node_modules/nexe/lib/steps/download.js new file mode 100644 index 0000000..598245c --- /dev/null +++ b/node_modules/nexe/lib/steps/download.js @@ -0,0 +1,76 @@ +"use strict"; +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 download = require("download"); +const util_1 = require("../util"); +const compiler_1 = require("../compiler"); +const path_1 = require("path"); +function fetchNodeSourceAsync(dest, url, step, options = {}) { + const setText = (p) => step.modify(`Downloading Node: ${p.toFixed()}%...`); + return download(url, dest, Object.assign(options, { extract: true, strip: 1 })) + .on('response', (res) => { + const total = +res.headers['content-length']; + let current = 0; + res.on('data', (data) => { + current += data.length; + setText((current / total) * 100); + if (current === total) { + step.log('Extracting Node...'); + } + }); + }) + .then(() => step.log(`Node source extracted to: ${dest}`)); +} +function fetchPrebuiltBinary(compiler, step) { + return __awaiter(this, void 0, void 0, function* () { + const { target, remoteAsset } = compiler, filename = compiler.getNodeExecutableLocation(target); + try { + yield download(remoteAsset, path_1.dirname(filename), compiler.options.downloadOptions).on('response', (res) => { + const total = +res.headers['content-length']; + let current = 0; + res.on('data', (data) => { + current += data.length; + step.modify(`Downloading...${((current / total) * 100).toFixed()}%`); + }); + }); + } + catch (e) { + if (e.statusCode === 404) { + throw new compiler_1.NexeError(`${remoteAsset} is not available, create it using the --build flag`); + } + else { + throw new compiler_1.NexeError('Error downloading prebuilt binary: ' + e); + } + } + }); +} +/** + * Downloads the node source to the configured temporary directory + * @param {*} compiler + * @param {*} next + */ +function downloadNode(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { src, log, target } = compiler, { version } = target, { sourceUrl, downloadOptions, build } = compiler.options, url = sourceUrl || `https://nodejs.org/dist/v${version}/node-v${version}.tar.gz`, step = log.step(`Downloading ${build ? '' : 'pre-built '}Node.js${build ? `source from: ${url}` : ''}`), exeLocation = compiler.getNodeExecutableLocation(build ? undefined : target), downloadExists = yield util_1.pathExistsAsync(build ? src : exeLocation); + if (downloadExists) { + step.log('Already downloaded...'); + return next(); + } + if (build) { + yield fetchNodeSourceAsync(src, url, step, downloadOptions); + } + else { + yield fetchPrebuiltBinary(compiler, step); + } + return next(); + }); +} +exports.default = downloadNode; diff --git a/node_modules/nexe/lib/steps/resource.d.ts b/node_modules/nexe/lib/steps/resource.d.ts new file mode 100644 index 0000000..dc50712 --- /dev/null +++ b/node_modules/nexe/lib/steps/resource.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function resource(compiler: NexeCompiler, next: () => Promise<any>): Promise<any>; diff --git a/node_modules/nexe/lib/steps/resource.js b/node_modules/nexe/lib/steps/resource.js new file mode 100644 index 0000000..25f0f39 --- /dev/null +++ b/node_modules/nexe/lib/steps/resource.js @@ -0,0 +1,35 @@ +"use strict"; +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 util_1 = require("../util"); +const globs = require("globby"); +const path_1 = require("path"); +function resource(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + const { cwd, resources } = compiler.options; + if (!resources.length) { + return next(); + } + const step = compiler.log.step('Bundling Resources...'); + let count = 0; + // workaround for https://github.com/sindresorhus/globby/issues/127 + // and https://github.com/mrmlnc/fast-glob#pattern-syntax + const resourcesWithForwardSlashes = resources.map((r) => r.replace(/\\/g, '/')); + yield util_1.each(globs(resourcesWithForwardSlashes, { cwd, onlyFiles: true }), (file) => __awaiter(this, void 0, void 0, function* () { + count++; + step.log(`Including file: ${file}`); + yield compiler.addResource(path_1.resolve(cwd, file)); + })); + step.log(`Included ${count} file(s)`); + return next(); + }); +} +exports.default = resource; diff --git a/node_modules/nexe/lib/steps/shim.d.ts b/node_modules/nexe/lib/steps/shim.d.ts new file mode 100644 index 0000000..a94e274 --- /dev/null +++ b/node_modules/nexe/lib/steps/shim.d.ts @@ -0,0 +1,2 @@ +import { NexeCompiler } from '../compiler'; +export default function (compiler: NexeCompiler, next: () => Promise<void>): Promise<void>; diff --git a/node_modules/nexe/lib/steps/shim.js b/node_modules/nexe/lib/steps/shim.js new file mode 100644 index 0000000..c364c81 --- /dev/null +++ b/node_modules/nexe/lib/steps/shim.js @@ -0,0 +1,38 @@ +"use strict"; +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 util_1 = require("../util"); +function default_1(compiler, next) { + return __awaiter(this, void 0, void 0, function* () { + yield next(); + compiler.shims.push(util_1.wrap('' + + "\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nlet originalFsMethods = null;\nlet lazyRestoreFs = () => { };\n// optional Win32 file namespace prefix followed by drive letter and colon\nconst windowsFullPathRegex = /^(\\\\{2}\\?\\\\)?([a-zA-Z]):/;\nconst upcaseDriveLetter = (s) => s.replace(windowsFullPathRegex, (_match, ns, drive) => `${ns || ''}${drive.toUpperCase()}:`);\nfunction shimFs(binary, fs = require('fs')) {\n if (originalFsMethods !== null) {\n return;\n }\n originalFsMethods = Object.assign({}, fs);\n const { blobPath, resources: manifest } = binary, { resourceStart, stat } = binary.layout, directories = {}, notAFile = '!@#$%^&*', isWin = process.platform.startsWith('win'), isString = (x) => typeof x === 'string' || x instanceof String, noop = () => { }, path = require('path'), winPath = isWin ? upcaseDriveLetter : (s) => s, baseDir = winPath(path.dirname(process.execPath));\n let log = (_) => true;\n let loggedManifest = false;\n if ((process.env.DEBUG || '').toLowerCase().includes('nexe:require')) {\n log = (text) => {\n setupManifest();\n if (!loggedManifest) {\n process.stderr.write('[nexe] - MANIFEST' + JSON.stringify(manifest, null, 4) + '\\n');\n process.stderr.write('[nexe] - DIRECTORIES' + JSON.stringify(directories, null, 4) + '\\n');\n loggedManifest = true;\n }\n return process.stderr.write('[nexe] - ' + text + '\\n');\n };\n }\n const getKey = function getKey(filepath) {\n if (Buffer.isBuffer(filepath)) {\n filepath = filepath.toString();\n }\n if (!isString(filepath)) {\n return notAFile;\n }\n let key = path.resolve(baseDir, filepath);\n return winPath(key);\n };\n const statTime = function () {\n return {\n dev: 0,\n ino: 0,\n nlink: 0,\n rdev: 0,\n uid: 123,\n gid: 500,\n blksize: 4096,\n blocks: 0,\n atime: new Date(stat.atime),\n atimeMs: stat.atime.getTime(),\n mtime: new Date(stat.mtime),\n mtimeMs: stat.mtime.getTime(),\n ctime: new Date(stat.ctime),\n ctimMs: stat.ctime.getTime(),\n birthtime: new Date(stat.birthtime),\n birthtimeMs: stat.birthtime.getTime(),\n };\n };\n let BigInt;\n try {\n BigInt = eval('BigInt');\n }\n catch (ignored) { }\n const createStat = function (extensions, options) {\n const stat = Object.assign(new fs.Stats(), binary.layout.stat, statTime(), extensions);\n if (options && options.bigint && BigInt) {\n for (const k in stat) {\n if (Object.prototype.hasOwnProperty.call(stat, k) && typeof stat[k] === 'number') {\n stat[k] = BigInt(stat[k]);\n }\n }\n }\n return stat;\n };\n const ownStat = function (filepath, options) {\n setupManifest();\n const key = getKey(filepath);\n if (directories[key]) {\n let mode = binary.layout.stat.mode;\n mode |= fs.constants.S_IFDIR;\n mode &= ~fs.constants.S_IFREG;\n return createStat({ mode, size: 0 }, options);\n }\n if (manifest[key]) {\n return createStat({ size: manifest[key][1] }, options);\n }\n };\n const getStat = function (fn) {\n return function stat(filepath, options, callback) {\n let stat;\n if (typeof options === 'function') {\n callback = options;\n stat = ownStat(filepath, null);\n }\n else {\n stat = ownStat(filepath, options);\n }\n if (stat) {\n process.nextTick(() => {\n callback(null, stat);\n });\n }\n else {\n return originalFsMethods[fn].apply(fs, arguments);\n }\n };\n };\n function makeLong(filepath) {\n return path._makeLong && path._makeLong(filepath);\n }\n function fileOpts(options) {\n return !options ? {} : isString(options) ? { encoding: options } : options;\n }\n let setupManifest = () => {\n Object.keys(manifest).forEach((filepath) => {\n const entry = manifest[filepath];\n const absolutePath = getKey(filepath);\n const longPath = makeLong(absolutePath);\n const normalizedPath = winPath(path.normalize(filepath));\n if (!manifest[absolutePath]) {\n manifest[absolutePath] = entry;\n }\n if (longPath && !manifest[longPath]) {\n manifest[longPath] = entry;\n }\n if (!manifest[normalizedPath]) {\n manifest[normalizedPath] = manifest[filepath];\n }\n let currentDir = path.dirname(absolutePath);\n let prevDir = absolutePath;\n while (currentDir !== prevDir) {\n directories[currentDir] = directories[currentDir] || {};\n directories[currentDir][path.basename(prevDir)] = true;\n const longDir = makeLong(currentDir);\n if (longDir && !directories[longDir]) {\n directories[longDir] = directories[currentDir];\n }\n prevDir = currentDir;\n currentDir = path.dirname(currentDir);\n }\n });\n manifest[notAFile] = false;\n directories[notAFile] = false;\n setupManifest = noop;\n };\n //naive patches intended to work for most use cases\n const nfs = {\n existsSync: function existsSync(filepath) {\n setupManifest();\n const key = getKey(filepath);\n if (manifest[key] || directories[key]) {\n return true;\n }\n return originalFsMethods.existsSync.apply(fs, arguments);\n },\n realpath: function realpath(filepath, options, cb) {\n setupManifest();\n const key = getKey(filepath);\n if (isString(filepath) && (manifest[filepath] || manifest[key])) {\n return process.nextTick(() => cb(null, filepath));\n }\n return originalFsMethods.realpath.call(fs, filepath, options, cb);\n },\n realpathSync: function realpathSync(filepath, options) {\n setupManifest();\n const key = getKey(filepath);\n if (manifest[key]) {\n return filepath;\n }\n return originalFsMethods.realpathSync.call(fs, filepath, options);\n },\n readdir: function readdir(filepath, options, callback) {\n setupManifest();\n const dir = directories[getKey(filepath)];\n if (dir) {\n if ('function' === typeof options) {\n callback = options;\n options = { encoding: 'utf8' };\n }\n process.nextTick(() => callback(null, Object.keys(dir)));\n }\n else {\n return originalFsMethods.readdir.apply(fs, arguments);\n }\n },\n readdirSync: function readdirSync(filepath, options) {\n setupManifest();\n const dir = directories[getKey(filepath)];\n if (dir) {\n return Object.keys(dir);\n }\n return originalFsMethods.readdirSync.apply(fs, arguments);\n },\n readFile: function readFile(filepath, options, callback) {\n setupManifest();\n const entry = manifest[getKey(filepath)];\n if (!entry) {\n return originalFsMethods.readFile.apply(fs, arguments);\n }\n const [offset, length] = entry;\n const resourceOffset = resourceStart + offset;\n const encoding = fileOpts(options).encoding;\n callback = typeof options === 'function' ? options : callback;\n originalFsMethods.open(blobPath, 'r', function (err, fd) {\n if (err)\n return callback(err, null);\n originalFsMethods.read(fd, Buffer.alloc(length), 0, length, resourceOffset, function (error, bytesRead, result) {\n if (error) {\n return originalFsMethods.close(fd, function () {\n callback(error, null);\n });\n }\n originalFsMethods.close(fd, function (err) {\n if (err) {\n return callback(err, result);\n }\n callback(err, encoding ? result.toString(encoding) : result);\n });\n });\n });\n },\n createReadStream: function createReadStream(filepath, options) {\n setupManifest();\n const entry = manifest[getKey(filepath)];\n if (!entry) {\n return originalFsMethods.createReadStream.apply(fs, arguments);\n }\n const [offset, length] = entry;\n const resourceOffset = resourceStart + offset;\n const opts = fileOpts(options);\n return originalFsMethods.createReadStream(blobPath, Object.assign({}, opts, {\n start: resourceOffset,\n end: resourceOffset + length - 1,\n }));\n },\n readFileSync: function readFileSync(filepath, options) {\n setupManifest();\n const entry = manifest[getKey(filepath)];\n if (!entry) {\n return originalFsMethods.readFileSync.apply(fs, arguments);\n }\n const [offset, length] = entry;\n const resourceOffset = resourceStart + offset;\n const encoding = fileOpts(options).encoding;\n const fd = originalFsMethods.openSync(process.execPath, 'r');\n const result = Buffer.alloc(length);\n originalFsMethods.readSync(fd, result, 0, length, resourceOffset);\n originalFsMethods.closeSync(fd);\n return encoding ? result.toString(encoding) : result;\n },\n statSync: function statSync(filepath, options) {\n const stat = ownStat(filepath, options);\n if (stat) {\n return stat;\n }\n return originalFsMethods.statSync.apply(fs, arguments);\n },\n stat: getStat('stat'),\n lstat: getStat('lstat'),\n lstatSync: function statSync(filepath, options) {\n const stat = ownStat(filepath, options);\n if (stat) {\n return stat;\n }\n return originalFsMethods.lstatSync.apply(fs, arguments);\n },\n };\n if (typeof fs.exists === 'function') {\n nfs.exists = function (filepath, cb) {\n cb = cb || noop;\n const exists = nfs.existsSync(filepath);\n process.nextTick(() => cb(exists));\n };\n }\n const patches = process.nexe.patches || {};\n delete process.nexe;\n patches.internalModuleReadFile = function (original, ...args) {\n setupManifest();\n const filepath = getKey(args[0]);\n if (manifest[filepath]) {\n log('read (hit) ' + filepath);\n return nfs.readFileSync(filepath, 'utf-8');\n }\n log('read (miss) ' + filepath);\n return original.call(this, ...args);\n };\n let returningArray;\n patches.internalModuleReadJSON = function (original, ...args) {\n if (returningArray == null)\n returningArray = Array.isArray(original.call(this, ''));\n const res = patches.internalModuleReadFile.call(this, original, ...args);\n return returningArray && !Array.isArray(res)\n ? [res, /\"(main|name|type|exports|imports)\"/.test(res)]\n : res;\n };\n patches.internalModuleStat = function (original, ...args) {\n setupManifest();\n const filepath = getKey(args[0]);\n if (manifest[filepath]) {\n log('stat (hit) ' + filepath + ' ' + 0);\n return 0;\n }\n if (directories[filepath]) {\n log('stat dir (hit) ' + filepath + ' ' + 1);\n return 1;\n }\n const res = original.call(this, ...args);\n if (res === 0) {\n log('stat (miss) ' + filepath + ' ' + res);\n }\n else if (res === 1) {\n log('stat dir (miss) ' + filepath + ' ' + res);\n }\n else {\n log('stat (fail) ' + filepath + ' ' + res);\n }\n return res;\n };\n if (typeof fs.exists === 'function') {\n nfs.exists = function (filepath, cb) {\n cb = cb || noop;\n const exists = nfs.existsSync(filepath);\n if (!exists) {\n return originalFsMethods.exists(filepath, cb);\n }\n process.nextTick(() => cb(exists));\n };\n }\n if (typeof fs.copyFile === 'function') {\n nfs.copyFile = function (filepath, dest, flags, callback) {\n setupManifest();\n const entry = manifest[getKey(filepath)];\n if (!entry) {\n return originalFsMethods.copyFile.apply(fs, arguments);\n }\n if (typeof flags === 'function') {\n callback = flags;\n flags = 0;\n }\n nfs.readFile(filepath, (err, buffer) => {\n if (err) {\n return callback(err);\n }\n originalFsMethods.writeFile(dest, buffer, (err) => {\n if (err) {\n return callback(err);\n }\n callback(null);\n });\n });\n };\n nfs.copyFileSync = function (filepath, dest) {\n setupManifest();\n const entry = manifest[getKey(filepath)];\n if (!entry) {\n return originalFsMethods.copyFileSync.apply(fs, arguments);\n }\n return originalFsMethods.writeFileSync(dest, nfs.readFileSync(filepath));\n };\n }\n Object.assign(fs, nfs);\n lazyRestoreFs = () => {\n Object.keys(nfs).forEach((key) => {\n fs[key] = originalFsMethods[key];\n });\n lazyRestoreFs = () => { };\n };\n return true;\n}\nexports.shimFs = shimFs;\nfunction restoreFs() {\n lazyRestoreFs();\n}\nexports.restoreFs = restoreFs;\n" + + '\nshimFs(process.__nexe)' + + `\n${compiler.options.fs ? '' : 'restoreFs()'}` + //TODO support only restoring specific methods + )); + compiler.shims.push(util_1.wrap(` + if (process.argv[1] && process.env.NODE_UNIQUE_ID) { + const cluster = require('cluster') + cluster._setupWorker() + delete process.env.NODE_UNIQUE_ID + } + `)); + compiler.shims.push(util_1.wrap(` + if (!process.send) { + const path = require('path') + const entry = path.resolve(path.dirname(process.execPath),${JSON.stringify(compiler.entrypoint)}) + process.argv.splice(1,0, entry) + } + `)); + }); +} +exports.default = default_1; diff --git a/node_modules/nexe/lib/target.d.ts b/node_modules/nexe/lib/target.d.ts new file mode 100644 index 0000000..6e94a29 --- /dev/null +++ b/node_modules/nexe/lib/target.d.ts @@ -0,0 +1,11 @@ +export declare type NodePlatform = 'windows' | 'mac' | 'alpine' | 'linux'; +export declare type NodeArch = 'x86' | 'x64' | 'arm' | 'arm64'; +declare const platforms: NodePlatform[], architectures: NodeArch[]; +export { platforms, architectures }; +export interface NexeTarget { + version: string; + platform: NodePlatform | string; + arch: NodeArch | string; +} +export declare function targetsEqual(a: NexeTarget, b: NexeTarget): boolean; +export declare function getTarget(target?: string | Partial<NexeTarget>): NexeTarget; diff --git a/node_modules/nexe/lib/target.js b/node_modules/nexe/lib/target.js new file mode 100644 index 0000000..1edd863 --- /dev/null +++ b/node_modules/nexe/lib/target.js @@ -0,0 +1,81 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const platforms = ['windows', 'mac', 'alpine', 'linux'], architectures = ['x86', 'x64', 'arm', 'arm64']; +exports.platforms = platforms; +exports.architectures = architectures; +const prettyPlatform = { + win32: 'windows', + windows: 'windows', + win: 'windows', + darwin: 'mac', + macos: 'mac', + mac: 'mac', + linux: 'linux', + static: 'alpine', + alpine: 'alpine', +}; +const prettyArch = { + x86: 'x86', + arm6: 'arm', + arm64: 'arm64', + arm6l: 'arm', + arm: 'arm', + arm7: 'arm', + arm7l: 'arm', + amd64: 'x64', + ia32: 'x86', + x32: 'x86', + x64: 'x64', +}; +function isVersion(x) { + if (!x) { + return false; + } + return /^[\d]+$/.test(x.replace(/v|\.|\s+/g, '')); +} +function isPlatform(x) { + return x in prettyPlatform; +} +function isArch(x) { + return x in prettyArch; +} +class Target { + constructor(arch, platform, version) { + this.arch = arch; + this.platform = platform; + this.version = version; + } + toJSON() { + return this.toString(); + } + toString() { + return `${this.platform}-${this.arch}-${this.version}`; + } +} +function targetsEqual(a, b) { + return a.arch === b.arch && a.platform === b.platform && a.version === b.version; +} +exports.targetsEqual = targetsEqual; +function getTarget(target = '') { + const currentArch = process.arch; + let arch = currentArch in prettyArch ? prettyArch[process.arch] : process.arch, platform = prettyPlatform[process.platform], version = process.version.slice(1); + if (typeof target !== 'string') { + target = `${target.platform}-${target.arch}-${target.version}`; + } + target + .toLowerCase() + .split('-') + .forEach((x) => { + if (isVersion(x)) { + version = x.replace(/v/g, ''); + } + if (isPlatform(x)) { + platform = prettyPlatform[x]; + } + if (isArch(x)) { + arch = prettyArch[x]; + } + }); + return new Target(arch, platform, version); +} +exports.getTarget = getTarget; diff --git a/node_modules/nexe/lib/util.d.ts b/node_modules/nexe/lib/util.d.ts new file mode 100644 index 0000000..af5d668 --- /dev/null +++ b/node_modules/nexe/lib/util.d.ts @@ -0,0 +1,27 @@ +/// <reference types="node" /> +import { readFile, writeFile, stat } from 'fs'; +import { execFile } from 'child_process'; +declare const rimrafAsync: (arg1: string) => Promise<void>; +export declare const STDIN_FLAG = "[stdin]"; +export declare function each<T>(list: T[] | Promise<T[]>, action: (item: T, index: number, list: T[]) => Promise<any>): Promise<any[]>; +export declare function wrap(code: string): string; +declare function padRight(str: string, l: number): string; +declare const bound: MethodDecorator; +declare function dequote(input: string): string; +export interface ReadFileAsync { + (path: string): Promise<Buffer>; + (path: string, encoding: string): Promise<string>; +} +declare const readFileAsync: typeof readFile.__promisify__; +declare const writeFileAsync: typeof writeFile.__promisify__; +declare const statAsync: typeof stat.__promisify__; +declare const execFileAsync: typeof execFile.__promisify__; +declare const isWindows: boolean; +declare function pathExistsAsync(path: string): Promise<boolean>; +declare function isDirectoryAsync(path: string): Promise<boolean>; +/** + * @param version See if this version is greather than the second one + * @param operand Version to compare against + */ +declare function semverGt(version: string, operand: string): boolean; +export { dequote, padRight, semverGt, bound, isWindows, rimrafAsync, statAsync, execFileAsync, readFileAsync, pathExistsAsync, isDirectoryAsync, writeFileAsync, }; diff --git a/node_modules/nexe/lib/util.js b/node_modules/nexe/lib/util.js new file mode 100644 index 0000000..112846d --- /dev/null +++ b/node_modules/nexe/lib/util.js @@ -0,0 +1,103 @@ +"use strict"; +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 fs_1 = require("fs"); +const child_process_1 = require("child_process"); +const util_1 = require("util"); +const rimraf = require("rimraf"); +const rimrafAsync = util_1.promisify(rimraf); +exports.rimrafAsync = rimrafAsync; +exports.STDIN_FLAG = '[stdin]'; +function each(list, action) { + return __awaiter(this, void 0, void 0, function* () { + const l = yield list; + return Promise.all(l.map(action)); + }); +} +exports.each = each; +function wrap(code) { + return '!(function () {' + code + '})();'; +} +exports.wrap = wrap; +function falseOnEnoent(e) { + if (e.code === 'ENOENT') { + return false; + } + throw e; +} +function padRight(str, l) { + return (str + ' '.repeat(l)).substr(0, l); +} +exports.padRight = padRight; +const bound = function bound(target, propertyKey, descriptor) { + const configurable = true; + return { + configurable, + get() { + const value = descriptor.value.bind(this); + Object.defineProperty(this, propertyKey, { + configurable, + value, + writable: true, + }); + return value; + }, + }; +}; +exports.bound = bound; +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; +} +exports.dequote = dequote; +const readFileAsync = util_1.promisify(fs_1.readFile); +exports.readFileAsync = readFileAsync; +const writeFileAsync = util_1.promisify(fs_1.writeFile); +exports.writeFileAsync = writeFileAsync; +const statAsync = util_1.promisify(fs_1.stat); +exports.statAsync = statAsync; +const execFileAsync = util_1.promisify(child_process_1.execFile); +exports.execFileAsync = execFileAsync; +const isWindows = process.platform === 'win32'; +exports.isWindows = isWindows; +function pathExistsAsync(path) { + return statAsync(path) + .then((x) => true) + .catch(falseOnEnoent); +} +exports.pathExistsAsync = pathExistsAsync; +function isDirectoryAsync(path) { + return statAsync(path) + .then((x) => x.isDirectory()) + .catch(falseOnEnoent); +} +exports.isDirectoryAsync = isDirectoryAsync; +/** + * @param version See if this version is greather than the second one + * @param operand Version to compare against + */ +function semverGt(version, operand) { + const [cMajor, cMinor, cPatch] = version.split('.').map(Number); + let [major, minor, patch] = operand.split('.').map(Number); + if (!minor) + minor = 0; + if (!patch) + patch = 0; + return (cMajor > major || + (cMajor === major && cMinor > minor) || + (cMajor === major && cMinor === minor && cPatch > patch)); +} +exports.semverGt = semverGt; |