[generated] sandpack files from: codesandbox-client
This commit is contained in:
@@ -0,0 +1,454 @@
|
||||
"use strict";
|
||||
var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
};
|
||||
})();
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var file_system_1 = require("../core/file_system");
|
||||
var InMemory_1 = require("./InMemory");
|
||||
var api_error_1 = require("../core/api_error");
|
||||
var node_fs_1 = require("../core/node_fs");
|
||||
var path = require("path");
|
||||
var util_1 = require("../core/util");
|
||||
/**
|
||||
* The MountableFileSystem allows you to mount multiple backend types or
|
||||
* multiple instantiations of the same backend into a single file system tree.
|
||||
* The file systems do not need to know about each other; all interactions are
|
||||
* automatically facilitated through this interface.
|
||||
*
|
||||
* For example, if a file system is mounted at /mnt/blah, and a request came in
|
||||
* for /mnt/blah/foo.txt, the file system would see a request for /foo.txt.
|
||||
*
|
||||
* You can mount file systems when you configure the file system:
|
||||
* ```javascript
|
||||
* BrowserFS.configure({
|
||||
* fs: "MountableFileSystem",
|
||||
* options: {
|
||||
* '/data': { fs: 'HTTPRequest', options: { index: "http://mysite.com/files/index.json" } },
|
||||
* '/home': { fs: 'LocalStorage' }
|
||||
* }
|
||||
* }, function(e) {
|
||||
*
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* For advanced users, you can also mount file systems *after* MFS is constructed:
|
||||
* ```javascript
|
||||
* BrowserFS.FileSystem.HTTPRequest.Create({
|
||||
* index: "http://mysite.com/files/index.json"
|
||||
* }, function(e, xhrfs) {
|
||||
* BrowserFS.FileSystem.MountableFileSystem.Create({
|
||||
* '/data': xhrfs
|
||||
* }, function(e, mfs) {
|
||||
* BrowserFS.initialize(mfs);
|
||||
*
|
||||
* // Added after-the-fact...
|
||||
* BrowserFS.FileSystem.LocalStorage.Create(function(e, lsfs) {
|
||||
* mfs.mount('/home', lsfs);
|
||||
* });
|
||||
* });
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* Since MountableFileSystem simply proxies requests to mounted file systems, it supports all of the operations that the mounted file systems support.
|
||||
*
|
||||
* With no mounted file systems, `MountableFileSystem` acts as a simple `InMemory` filesystem.
|
||||
*/
|
||||
var MountableFileSystem = /** @class */ (function (_super) {
|
||||
__extends(MountableFileSystem, _super);
|
||||
/**
|
||||
* Creates a new, empty MountableFileSystem.
|
||||
*/
|
||||
function MountableFileSystem(rootFs) {
|
||||
var _this = _super.call(this) || this;
|
||||
// Contains the list of mount points in mntMap, sorted by string length in decreasing order.
|
||||
// Ensures that we scan the most specific mount points for a match first, which lets us
|
||||
// nest mount points.
|
||||
_this.mountList = [];
|
||||
_this.mntMap = {};
|
||||
_this.rootFs = rootFs;
|
||||
return _this;
|
||||
}
|
||||
/**
|
||||
* Creates a MountableFileSystem instance with the given options.
|
||||
*/
|
||||
MountableFileSystem.Create = function (opts, cb) {
|
||||
InMemory_1.default.Create({}, function (e, imfs) {
|
||||
if (imfs) {
|
||||
var fs_1 = new MountableFileSystem(imfs);
|
||||
try {
|
||||
Object.keys(opts).forEach(function (mountPoint) {
|
||||
fs_1.mount(mountPoint, opts[mountPoint]);
|
||||
});
|
||||
}
|
||||
catch (e) {
|
||||
return cb(e);
|
||||
}
|
||||
cb(null, fs_1);
|
||||
}
|
||||
else {
|
||||
cb(e);
|
||||
}
|
||||
});
|
||||
};
|
||||
MountableFileSystem.isAvailable = function () {
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Mounts the file system at the given mount point.
|
||||
*/
|
||||
MountableFileSystem.prototype.mount = function (mountPoint, fs) {
|
||||
if (mountPoint[0] !== '/') {
|
||||
mountPoint = "/".concat(mountPoint);
|
||||
}
|
||||
mountPoint = path.resolve(mountPoint);
|
||||
if (this.mntMap[mountPoint]) {
|
||||
throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, "Mount point " + mountPoint + " is already taken.");
|
||||
}
|
||||
(0, util_1.mkdirpSync)(mountPoint, 0x1ff, this.rootFs);
|
||||
this.mntMap[mountPoint] = fs;
|
||||
this.mountList.push(mountPoint);
|
||||
this.mountList = this.mountList.sort(function (a, b) { return b.length - a.length; });
|
||||
};
|
||||
MountableFileSystem.prototype.umount = function (mountPoint) {
|
||||
if (mountPoint[0] !== '/') {
|
||||
mountPoint = "/".concat(mountPoint);
|
||||
}
|
||||
mountPoint = path.resolve(mountPoint);
|
||||
if (!this.mntMap[mountPoint]) {
|
||||
throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, "Mount point " + mountPoint + " is already unmounted.");
|
||||
}
|
||||
delete this.mntMap[mountPoint];
|
||||
this.mountList.splice(this.mountList.indexOf(mountPoint), 1);
|
||||
while (mountPoint !== '/') {
|
||||
if (this.rootFs.readdirSync(mountPoint).length === 0) {
|
||||
this.rootFs.rmdirSync(mountPoint);
|
||||
mountPoint = path.dirname(mountPoint);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns the file system that the path points to.
|
||||
*/
|
||||
MountableFileSystem.prototype._getFs = function (path) {
|
||||
var mountList = this.mountList, len = mountList.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var mountPoint = mountList[i];
|
||||
// We know path is normalized, so it is a substring of the mount point.
|
||||
if (mountPoint.length <= path.length && path.indexOf(mountPoint) === 0) {
|
||||
path = path.substr(mountPoint.length > 1 ? mountPoint.length : 0);
|
||||
if (path === '') {
|
||||
path = '/';
|
||||
}
|
||||
return { fs: this.mntMap[mountPoint], path: path, mountPoint: mountPoint };
|
||||
}
|
||||
}
|
||||
// Query our root file system.
|
||||
return { fs: this.rootFs, path: path, mountPoint: '/' };
|
||||
};
|
||||
// Global information methods
|
||||
MountableFileSystem.prototype.getName = function () {
|
||||
return MountableFileSystem.Name;
|
||||
};
|
||||
MountableFileSystem.prototype.diskSpace = function (path, cb) {
|
||||
cb(0, 0);
|
||||
};
|
||||
MountableFileSystem.prototype.isReadOnly = function () {
|
||||
return false;
|
||||
};
|
||||
MountableFileSystem.prototype.supportsLinks = function () {
|
||||
// I'm not ready for cross-FS links yet.
|
||||
return false;
|
||||
};
|
||||
MountableFileSystem.prototype.supportsProps = function () {
|
||||
return false;
|
||||
};
|
||||
MountableFileSystem.prototype.supportsSynch = function () {
|
||||
return true;
|
||||
};
|
||||
/**
|
||||
* Fixes up error messages so they mention the mounted file location relative
|
||||
* to the MFS root, not to the particular FS's root.
|
||||
* Mutates the input error, and returns it.
|
||||
*/
|
||||
MountableFileSystem.prototype.standardizeError = function (err, path, realPath) {
|
||||
var index = err.message.indexOf(path);
|
||||
if (index !== -1) {
|
||||
err.message = err.message.substr(0, index) + realPath + err.message.substr(index + path.length);
|
||||
err.path = realPath;
|
||||
}
|
||||
return err;
|
||||
};
|
||||
// The following methods involve multiple file systems, and thus have custom
|
||||
// logic.
|
||||
// Note that we go through the Node API to use its robust default argument
|
||||
// processing.
|
||||
MountableFileSystem.prototype.rename = function (oldPath, newPath, cb) {
|
||||
var _this = this;
|
||||
// Scenario 1: old and new are on same FS.
|
||||
var fs1rv = this._getFs(oldPath);
|
||||
var fs2rv = this._getFs(newPath);
|
||||
if (fs1rv.fs === fs2rv.fs) {
|
||||
return fs1rv.fs.rename(fs1rv.path, fs2rv.path, function (e) {
|
||||
if (e) {
|
||||
_this.standardizeError(_this.standardizeError(e, fs1rv.path, oldPath), fs2rv.path, newPath);
|
||||
}
|
||||
cb(e);
|
||||
});
|
||||
}
|
||||
// Scenario 2: Different file systems.
|
||||
// Read old file, write new file, delete old file.
|
||||
return node_fs_1.default.readFile(oldPath, function (err, data) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
node_fs_1.default.writeFile(newPath, data, function (err) {
|
||||
if (err) {
|
||||
return cb(err);
|
||||
}
|
||||
node_fs_1.default.unlink(oldPath, cb);
|
||||
});
|
||||
});
|
||||
};
|
||||
MountableFileSystem.prototype.renameSync = function (oldPath, newPath) {
|
||||
// Scenario 1: old and new are on same FS.
|
||||
var fs1rv = this._getFs(oldPath);
|
||||
var fs2rv = this._getFs(newPath);
|
||||
if (fs1rv.fs === fs2rv.fs) {
|
||||
try {
|
||||
return fs1rv.fs.renameSync(fs1rv.path, fs2rv.path);
|
||||
}
|
||||
catch (e) {
|
||||
this.standardizeError(this.standardizeError(e, fs1rv.path, oldPath), fs2rv.path, newPath);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
// Scenario 2: Different file systems.
|
||||
var data = node_fs_1.default.readFileSync(oldPath);
|
||||
node_fs_1.default.writeFileSync(newPath, data);
|
||||
return node_fs_1.default.unlinkSync(oldPath);
|
||||
};
|
||||
MountableFileSystem.prototype.readdirSync = function (p) {
|
||||
var fsInfo = this._getFs(p);
|
||||
// If null, rootfs did not have the directory
|
||||
// (or the target FS is the root fs).
|
||||
var rv = null;
|
||||
// Mount points are all defined in the root FS.
|
||||
// Ensure that we list those, too.
|
||||
if (fsInfo.fs !== this.rootFs) {
|
||||
try {
|
||||
rv = this.rootFs.readdirSync(p);
|
||||
}
|
||||
catch (e) {
|
||||
// Ignore.
|
||||
}
|
||||
}
|
||||
try {
|
||||
var rv2_1 = fsInfo.fs.readdirSync(fsInfo.path);
|
||||
if (rv === null) {
|
||||
return rv2_1;
|
||||
}
|
||||
else {
|
||||
// Filter out duplicates.
|
||||
return rv2_1.concat(rv.filter(function (val) { return rv2_1.indexOf(val) === -1; }));
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (rv === null) {
|
||||
throw this.standardizeError(e, fsInfo.path, p);
|
||||
}
|
||||
else {
|
||||
// The root FS had something.
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
};
|
||||
MountableFileSystem.prototype.readdir = function (p, cb) {
|
||||
var _this = this;
|
||||
var fsInfo = this._getFs(p);
|
||||
fsInfo.fs.readdir(fsInfo.path, function (err, files) {
|
||||
if (fsInfo.fs !== _this.rootFs) {
|
||||
try {
|
||||
var rv = _this.rootFs.readdirSync(p);
|
||||
if (files) {
|
||||
// Filter out duplicates.
|
||||
files = files.concat(rv.filter(function (val) { return files.indexOf(val) === -1; }));
|
||||
}
|
||||
else {
|
||||
files = rv;
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
// Root FS and target FS did not have directory.
|
||||
if (err) {
|
||||
return cb(_this.standardizeError(err, fsInfo.path, p));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (err) {
|
||||
// Root FS and target FS are the same, and did not have directory.
|
||||
return cb(_this.standardizeError(err, fsInfo.path, p));
|
||||
}
|
||||
cb(null, files);
|
||||
});
|
||||
};
|
||||
MountableFileSystem.prototype.realpathSync = function (p, cache) {
|
||||
var fsInfo = this._getFs(p);
|
||||
try {
|
||||
var mountedPath = fsInfo.fs.realpathSync(fsInfo.path, {});
|
||||
// resolve is there to remove any trailing slash that may be present
|
||||
return path.resolve(path.join(fsInfo.mountPoint, mountedPath));
|
||||
}
|
||||
catch (e) {
|
||||
throw this.standardizeError(e, fsInfo.path, p);
|
||||
}
|
||||
};
|
||||
MountableFileSystem.prototype.realpath = function (p, cache, cb) {
|
||||
var _this = this;
|
||||
var fsInfo = this._getFs(p);
|
||||
fsInfo.fs.realpath(fsInfo.path, {}, function (err, rv) {
|
||||
if (err) {
|
||||
cb(_this.standardizeError(err, fsInfo.path, p));
|
||||
}
|
||||
else {
|
||||
// resolve is there to remove any trailing slash that may be present
|
||||
cb(null, path.resolve(path.join(fsInfo.mountPoint, rv)));
|
||||
}
|
||||
});
|
||||
};
|
||||
MountableFileSystem.prototype.rmdirSync = function (p) {
|
||||
var fsInfo = this._getFs(p);
|
||||
if (this._containsMountPt(p)) {
|
||||
throw api_error_1.ApiError.ENOTEMPTY(p);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
fsInfo.fs.rmdirSync(fsInfo.path);
|
||||
}
|
||||
catch (e) {
|
||||
throw this.standardizeError(e, fsInfo.path, p);
|
||||
}
|
||||
}
|
||||
};
|
||||
MountableFileSystem.prototype.rmdir = function (p, cb) {
|
||||
var _this = this;
|
||||
var fsInfo = this._getFs(p);
|
||||
if (this._containsMountPt(p)) {
|
||||
cb(api_error_1.ApiError.ENOTEMPTY(p));
|
||||
}
|
||||
else {
|
||||
fsInfo.fs.rmdir(fsInfo.path, function (err) {
|
||||
cb(err ? _this.standardizeError(err, fsInfo.path, p) : null);
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Returns true if the given path contains a mount point.
|
||||
*/
|
||||
MountableFileSystem.prototype._containsMountPt = function (p) {
|
||||
var mountPoints = this.mountList, len = mountPoints.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var pt = mountPoints[i];
|
||||
if (pt.length >= p.length && pt.slice(0, p.length) === p) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
MountableFileSystem.Name = "MountableFileSystem";
|
||||
MountableFileSystem.Options = {};
|
||||
return MountableFileSystem;
|
||||
}(file_system_1.BaseFileSystem));
|
||||
exports.default = MountableFileSystem;
|
||||
/**
|
||||
* Tricky: Define all of the functions that merely forward arguments to the
|
||||
* relevant file system, or return/throw an error.
|
||||
* Take advantage of the fact that the *first* argument is always the path, and
|
||||
* the *last* is the callback function (if async).
|
||||
* @todo Can use numArgs to make proxying more efficient.
|
||||
* @hidden
|
||||
*/
|
||||
function defineFcn(name, isSync, numArgs) {
|
||||
if (isSync) {
|
||||
return function () {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
var path = args[0];
|
||||
var rv = this._getFs(path);
|
||||
args[0] = rv.path;
|
||||
try {
|
||||
return rv.fs[name].apply(rv.fs, args);
|
||||
}
|
||||
catch (e) {
|
||||
this.standardizeError(e, rv.path, path);
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
return function () {
|
||||
var _this = this;
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
var path = args[0];
|
||||
var rv = this._getFs(path);
|
||||
args[0] = rv.path;
|
||||
if (typeof args[args.length - 1] === 'function') {
|
||||
var cb_1 = args[args.length - 1];
|
||||
args[args.length - 1] = function () {
|
||||
var args = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
args[_i] = arguments[_i];
|
||||
}
|
||||
if (args.length > 0 && args[0] instanceof api_error_1.ApiError) {
|
||||
_this.standardizeError(args[0], rv.path, path);
|
||||
}
|
||||
cb_1.apply(null, args);
|
||||
};
|
||||
}
|
||||
return rv.fs[name].apply(rv.fs, args);
|
||||
};
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @hidden
|
||||
*/
|
||||
var fsCmdMap = [
|
||||
// 1 arg functions
|
||||
['exists', 'unlink', 'readlink'],
|
||||
// 2 arg functions
|
||||
['stat', 'mkdir', 'truncate'],
|
||||
// 3 arg functions
|
||||
['open', 'readFile', 'chmod', 'utimes'],
|
||||
// 4 arg functions
|
||||
['chown'],
|
||||
// 5 arg functions
|
||||
['writeFile', 'appendFile']
|
||||
];
|
||||
for (var i = 0; i < fsCmdMap.length; i++) {
|
||||
var cmds = fsCmdMap[i];
|
||||
for (var _i = 0, cmds_1 = cmds; _i < cmds_1.length; _i++) {
|
||||
var fnName = cmds_1[_i];
|
||||
MountableFileSystem.prototype[fnName] = defineFcn(fnName, false, i + 1);
|
||||
MountableFileSystem.prototype[fnName + 'Sync'] = defineFcn(fnName + 'Sync', true, i + 1);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=MountableFileSystem.js.map
|
||||
Reference in New Issue
Block a user