UNPKG

nexe

Version:

Create a single executable out of your Node.js application

284 lines (283 loc) 14.3 kB
"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 }); exports.SnapshotZipFS = void 0; const fslib_1 = require("@yarnpkg/fslib"); const libzip_1 = require("@yarnpkg/libzip"); const path_1 = require("path"); const fs_1 = require("fs"); const uniqBy = (arr, pick) => { const seen = new Set(); return arr.filter((x) => { const key = pick(x); if (seen.has(key)) return false; seen.add(key); return true; }); }; function uniqReaddir(arr) { return uniqBy(arr, (s) => (typeof s === 'string' ? s : s.name)); } class SnapshotZipFS extends fslib_1.BasePortableFakeFS { constructor(opts) { super(); this.fdMap = new Map(); this.nextFd = 3; this.accessPromise = libzip_1.ZipOpenFS.prototype.accessPromise; this.accessSync = libzip_1.ZipOpenFS.prototype.accessSync; this.appendFilePromise = libzip_1.ZipOpenFS.prototype.appendFilePromise; this.appendFileSync = libzip_1.ZipOpenFS.prototype.appendFileSync; this.chmodPromise = libzip_1.ZipOpenFS.prototype.chmodPromise; this.chmodSync = libzip_1.ZipOpenFS.prototype.chmodSync; this.fchmodPromise = libzip_1.ZipOpenFS.prototype.fchmodPromise; this.fchmodSync = libzip_1.ZipOpenFS.prototype.fchmodSync; this.chownPromise = libzip_1.ZipOpenFS.prototype.chownPromise; this.chownSync = libzip_1.ZipOpenFS.prototype.chownSync; this.fchownPromise = libzip_1.ZipOpenFS.prototype.fchownPromise; this.fchownSync = libzip_1.ZipOpenFS.prototype.fchownSync; this.closePromise = libzip_1.ZipOpenFS.prototype.closePromise; this.closeSync = libzip_1.ZipOpenFS.prototype.closeSync; this.createReadStream = libzip_1.ZipOpenFS.prototype.createReadStream; this.createWriteStream = libzip_1.ZipOpenFS.prototype.createWriteStream; this.existsPromise = libzip_1.ZipOpenFS.prototype.existsPromise; this.existsSync = libzip_1.ZipOpenFS.prototype.existsSync; this.fstatPromise = libzip_1.ZipOpenFS.prototype.fstatPromise; this.fstatSync = libzip_1.ZipOpenFS.prototype.fstatSync; this.getExtractHint = libzip_1.ZipOpenFS.prototype.getExtractHint; this.getRealPath = libzip_1.ZipOpenFS.prototype.getRealPath; this.linkPromise = libzip_1.ZipOpenFS.prototype.linkPromise; this.linkSync = libzip_1.ZipOpenFS.prototype.linkSync; this.lstatPromise = libzip_1.ZipOpenFS.prototype.lstatPromise; this.lstatSync = libzip_1.ZipOpenFS.prototype.lstatSync; this.openPromise = libzip_1.ZipOpenFS.prototype.openPromise; this.openSync = libzip_1.ZipOpenFS.prototype.openSync; this.readFilePromise = libzip_1.ZipOpenFS.prototype.readFilePromise; this.readFileSync = libzip_1.ZipOpenFS.prototype.readFileSync; this.readlinkPromise = libzip_1.ZipOpenFS.prototype.readlinkPromise; this.readlinkSync = libzip_1.ZipOpenFS.prototype.readlinkSync; this.readPromise = libzip_1.ZipOpenFS.prototype.readPromise; this.readSync = libzip_1.ZipOpenFS.prototype.readSync; this.renamePromise = libzip_1.ZipOpenFS.prototype.renamePromise; this.renameSync = libzip_1.ZipOpenFS.prototype.renameSync; this.resolve = libzip_1.ZipOpenFS.prototype.resolve; this.statPromise = libzip_1.ZipOpenFS.prototype.statPromise; this.statSync = libzip_1.ZipOpenFS.prototype.statSync; this.symlinkPromise = libzip_1.ZipOpenFS.prototype.symlinkPromise; this.symlinkSync = libzip_1.ZipOpenFS.prototype.symlinkSync; this.truncatePromise = libzip_1.ZipOpenFS.prototype.truncatePromise; this.truncateSync = libzip_1.ZipOpenFS.prototype.truncateSync; this.ftruncatePromise = libzip_1.ZipOpenFS.prototype.ftruncatePromise; this.ftruncateSync = libzip_1.ZipOpenFS.prototype.ftruncateSync; this.unlinkPromise = libzip_1.ZipOpenFS.prototype.unlinkPromise; this.unlinkSync = libzip_1.ZipOpenFS.prototype.unlinkSync; this.unwatchFile = libzip_1.ZipOpenFS.prototype.unwatchFile; this.utimesPromise = libzip_1.ZipOpenFS.prototype.utimesPromise; this.utimesSync = libzip_1.ZipOpenFS.prototype.utimesSync; this.lutimesPromise = libzip_1.ZipOpenFS.prototype.utimesPromise; this.lutimesSync = libzip_1.ZipOpenFS.prototype.utimesSync; this.watch = libzip_1.ZipOpenFS.prototype.watch; this.watchFile = libzip_1.ZipOpenFS.prototype.watchFile; this.writeFilePromise = libzip_1.ZipOpenFS.prototype.writeFilePromise; this.writeFileSync = libzip_1.ZipOpenFS.prototype.writeFileSync; this.writePromise = libzip_1.ZipOpenFS.prototype.writePromise; this.writeSync = libzip_1.ZipOpenFS.prototype.writeSync; // @ts-ignore this.remapFd = libzip_1.ZipOpenFS.prototype.remapFd; this.zipFs = opts.zipFs; this.baseFs = opts.baseFs; this.root = opts.root; this.magic = 0x2a << 24; } makeCallPromise(p, discard, accept, { requireSubpath = true } = {}) { return __awaiter(this, void 0, void 0, function* () { if (typeof p !== 'string') return yield discard(); const normalizedP = this.resolve(p); const zipInfo = this.findZip(normalizedP); if (!zipInfo) return yield discard(); if (requireSubpath && zipInfo.subPath === '/') return yield discard(); return yield accept(this.zipFs, zipInfo); }); } makeCallSync(p, discard, accept, { requireSubpath = true } = {}) { if (typeof p !== 'string') return discard(); const normalizedP = this.resolve(p); const zipInfo = this.findZip(normalizedP); if (!zipInfo) return discard(); if (requireSubpath && zipInfo.subPath === '/') return discard(); return accept(this.zipFs, Object.assign({ archivePath: '' }, zipInfo)); } realpathPromise(p) { return __awaiter(this, void 0, void 0, function* () { return yield this.realpathSync(p); }); } realpathSync(p) { return this.makeCallSync(p, () => this.baseFs.realpathSync(p), (zipFs, { subPath }) => { if (zipFs.lstatSync(subPath).isSymbolicLink()) { return zipFs.realpathSync(subPath); } else { // return the original path in case it wasn't under /snapshot, e.g. if it was for a node module - otherwise the node module parent path is the wrong one (and other things resolve relative to that) return p; } }); } findZip(p) { p = this.resolve(p); const snapshotPP = fslib_1.npath.toPortablePath('/snapshot'); const pathsToTry = Array.from(new Set([ p, (0, path_1.resolve)('/snapshot', p), fslib_1.ppath.resolve(snapshotPP, fslib_1.npath.toPortablePath(fslib_1.npath.relative(fslib_1.npath.fromPortablePath(this.root), fslib_1.npath.fromPortablePath(p)))), fslib_1.ppath.resolve(snapshotPP, fslib_1.npath.toPortablePath(fslib_1.npath.relative((0, path_1.toNamespacedPath)(fslib_1.npath.fromPortablePath(this.root)), (0, path_1.toNamespacedPath)(fslib_1.npath.fromPortablePath(p))))), fslib_1.ppath.resolve(snapshotPP, fslib_1.npath.toPortablePath(fslib_1.npath.relative(fslib_1.npath.fromPortablePath(process.cwd()), fslib_1.npath.fromPortablePath(p)))), fslib_1.ppath.resolve(snapshotPP, fslib_1.npath.toPortablePath(fslib_1.npath.relative((0, path_1.toNamespacedPath)(fslib_1.npath.fromPortablePath(process.cwd())), (0, path_1.toNamespacedPath)(fslib_1.npath.fromPortablePath(p))))), ])); for (const path of pathsToTry) { const portablePath = fslib_1.npath.toPortablePath(path); if (this.zipFs.existsSync(portablePath)) { return { subPath: portablePath, }; } } } copyFilePromise(sourceP, destP, flags = 0) { return __awaiter(this, void 0, void 0, function* () { const fallback = (sourceFs, sourceP, destFs, destP) => __awaiter(this, void 0, void 0, function* () { if ((flags & fs_1.constants.COPYFILE_FICLONE_FORCE) !== 0) throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { code: `EXDEV` }); if (flags & fs_1.constants.COPYFILE_EXCL && (yield this.existsPromise(sourceP))) throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { code: `EEXIST` }); let content; try { content = yield sourceFs.readFilePromise(sourceP); } catch (error) { throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { code: `EINVAL` }); } yield destFs.writeFilePromise(destP, content); }); return yield this.makeCallPromise(sourceP, () => __awaiter(this, void 0, void 0, function* () { return yield this.baseFs.copyFilePromise(sourceP, destP, flags); }), (zipFsS, { subPath: subPathS }) => __awaiter(this, void 0, void 0, function* () { return yield fallback(zipFsS, subPathS, this.baseFs, destP); })); }); } copyFileSync(sourceP, destP, flags = 0) { const fallback = (sourceFs, sourceP, destFs, destP) => { if ((flags & fs_1.constants.COPYFILE_FICLONE_FORCE) !== 0) throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { code: `EXDEV` }); if (flags & fs_1.constants.COPYFILE_EXCL && this.existsSync(sourceP)) throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { code: `EEXIST` }); let content; try { content = sourceFs.readFileSync(sourceP); } catch (error) { throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { code: `EINVAL` }); } destFs.writeFileSync(destP, content); }; return this.makeCallSync(sourceP, () => { return this.baseFs.copyFileSync(sourceP, destP, flags); }, (zipFsS, { subPath: subPathS }) => { return fallback(zipFsS, subPathS, this.baseFs, destP); }); } readdirPromise(p, opts) { return __awaiter(this, void 0, void 0, function* () { const fallback = () => __awaiter(this, void 0, void 0, function* () { return yield this.baseFs.readdirPromise(p, opts); }); return yield this.makeCallPromise(p, fallback, (zipFs, { subPath }) => __awaiter(this, void 0, void 0, function* () { const fallbackPaths = yield fallback().catch(() => []); return Promise.resolve(uniqReaddir(fallbackPaths.concat(yield zipFs.readdirPromise(subPath, opts)))); }), { requireSubpath: false, }); }); } readdirSync(p, opts) { const fallback = () => { return this.baseFs.readdirSync(p, opts); }; return this.makeCallSync(p, fallback, (zipFs, { subPath }) => { let fallbackPaths = []; try { fallbackPaths = fallback(); } catch (e) { } return fallbackPaths.concat(uniqReaddir(zipFs.readdirSync(subPath, opts))); }, { requireSubpath: false, }); } mkdirPromise(p, opts) { return __awaiter(this, void 0, void 0, function* () { return yield this.baseFs.mkdirPromise(p, opts); }); } mkdirSync(p, opts) { return this.baseFs.mkdirSync(p, opts); } rmdirPromise(p, opts) { return __awaiter(this, void 0, void 0, function* () { return yield this.baseFs.rmdirPromise(p, opts); }); } rmdirSync(p, opts) { return this.baseFs.rmdirSync(p, opts); } opendirPromise(p, opts) { return __awaiter(this, void 0, void 0, function* () { return this.opendirSync(p, opts); }); } opendirSync(p, opts) { const zipInfo = this.findZip(p); let zipFsDir = null; if (zipInfo) { zipFsDir = this.zipFs.opendirSync(zipInfo.subPath); } let realFsDir = null; try { realFsDir = this.baseFs.opendirSync(p); } catch (e) { if (!zipFsDir) throw e; } const seen = new Set(); const nextDirent = () => { const entry = (realFsDir === null || realFsDir === void 0 ? void 0 : realFsDir.readSync()) || (zipFsDir === null || zipFsDir === void 0 ? void 0 : zipFsDir.readSync()); if (entry && !seen.has(entry.name)) { seen.add(entry.name); return entry; } return null; }; const onClose = () => { zipFsDir === null || zipFsDir === void 0 ? void 0 : zipFsDir.closeSync(); realFsDir === null || realFsDir === void 0 ? void 0 : realFsDir.closeSync(); }; return new fslib_1.CustomDir(p, nextDirent, { onClose }); } } exports.SnapshotZipFS = SnapshotZipFS;