nexe
Version:
Create a single executable out of your Node.js application
284 lines (283 loc) • 14.3 kB
JavaScript
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;
;