aboutsummaryrefslogtreecommitdiff
path: root/node_modules/nexe/lib/fs
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/nexe/lib/fs')
-rw-r--r--node_modules/nexe/lib/fs/README.md40
-rw-r--r--node_modules/nexe/lib/fs/bootstrap.js20
-rw-r--r--node_modules/nexe/lib/fs/bundle.d.ts36
-rw-r--r--node_modules/nexe/lib/fs/bundle.js145
-rw-r--r--node_modules/nexe/lib/fs/package.json15
-rw-r--r--node_modules/nexe/lib/fs/patch.d.ts18
-rw-r--r--node_modules/nexe/lib/fs/patch.js372
7 files changed, 646 insertions, 0 deletions
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;