@codesandbox/sandpack-client
Version:
<img style="width:100%" src="https://user-images.githubusercontent.com/4838076/143581035-ebee5ba2-9cb1-4fe8-a05b-2f44bd69bb4b.gif" alt="Component toolkit for live running code editing experiences" />
584 lines • 21.5 kB
JavaScript
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 });
exports.SynchronousFileSystem = exports.BaseFileSystem = void 0;
var api_error_1 = require("./api_error");
var file_flag_1 = require("./file_flag");
var path = require("path");
var util_1 = require("./util");
/**
* Basic filesystem class. Most filesystems should extend this class, as it
* provides default implementations for a handful of methods.
*/
var BaseFileSystem = /** @class */ (function () {
function BaseFileSystem() {
}
BaseFileSystem.prototype.supportsLinks = function () {
return false;
};
BaseFileSystem.prototype.diskSpace = function (p, cb) {
cb(0, 0);
};
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
*/
BaseFileSystem.prototype.openFile = function (p, flag, cb) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
/**
* Create the file at path p with the given mode. Then, open it with the given
* flag.
*/
BaseFileSystem.prototype.createFile = function (p, flag, mode, cb) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.open = function (p, flag, mode, cb) {
var _this = this;
var mustBeFile = function (e, stats) {
if (e) {
// File does not exist.
switch (flag.pathNotExistsAction()) {
case file_flag_1.ActionType.CREATE_FILE:
// Ensure parent exists.
return _this.stat(path.dirname(p), false, function (e, parentStats) {
if (e) {
cb(e);
}
else if (parentStats && !parentStats.isDirectory()) {
cb(api_error_1.ApiError.ENOTDIR(path.dirname(p)));
}
else {
_this.createFile(p, flag, mode, cb);
}
});
case file_flag_1.ActionType.THROW_EXCEPTION:
return cb(api_error_1.ApiError.ENOENT(p));
default:
return cb(new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileFlag object.'));
}
}
else {
// File exists.
if (stats && stats.isDirectory()) {
return cb(api_error_1.ApiError.EISDIR(p));
}
switch (flag.pathExistsAction()) {
case file_flag_1.ActionType.THROW_EXCEPTION:
return cb(api_error_1.ApiError.EEXIST(p));
case file_flag_1.ActionType.TRUNCATE_FILE:
// NOTE: In a previous implementation, we deleted the file and
// re-created it. However, this created a race condition if another
// asynchronous request was trying to read the file, as the file
// would not exist for a small period of time.
return _this.openFile(p, flag, function (e, fd) {
if (e) {
cb(e);
}
else if (fd) {
fd.truncate(0, function () {
fd.sync(function () {
cb(null, fd);
});
});
}
else {
(0, util_1.fail)();
}
});
case file_flag_1.ActionType.NOP:
return _this.openFile(p, flag, cb);
default:
return cb(new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileFlag object.'));
}
}
};
this.stat(p, false, mustBeFile);
};
BaseFileSystem.prototype.rename = function (oldPath, newPath, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.renameSync = function (oldPath, newPath) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.stat = function (p, isLstat, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.statSync = function (p, isLstat) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
/**
* Opens the file at path p with the given flag. The file must exist.
* @param p The path to open.
* @param flag The flag to use when opening the file.
* @return A File object corresponding to the opened file.
*/
BaseFileSystem.prototype.openFileSync = function (p, flag, mode) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
/**
* Create the file at path p with the given mode. Then, open it with the given
* flag.
*/
BaseFileSystem.prototype.createFileSync = function (p, flag, mode) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.openSync = function (p, flag, mode) {
// Check if the path exists, and is a file.
var stats;
try {
stats = this.statSync(p, false);
}
catch (e) {
// File does not exist.
switch (flag.pathNotExistsAction()) {
case file_flag_1.ActionType.CREATE_FILE:
// Ensure parent exists.
var parentStats = this.statSync(path.dirname(p), false);
if (!parentStats.isDirectory()) {
throw api_error_1.ApiError.ENOTDIR(path.dirname(p));
}
return this.createFileSync(p, flag, mode);
case file_flag_1.ActionType.THROW_EXCEPTION:
throw api_error_1.ApiError.ENOENT(p);
default:
throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileFlag object.');
}
}
// File exists.
if (stats.isDirectory()) {
throw api_error_1.ApiError.EISDIR(p);
}
switch (flag.pathExistsAction()) {
case file_flag_1.ActionType.THROW_EXCEPTION:
throw api_error_1.ApiError.EEXIST(p);
case file_flag_1.ActionType.TRUNCATE_FILE:
// Delete file.
this.unlinkSync(p);
// Create file. Use the same mode as the old file.
// Node itself modifies the ctime when this occurs, so this action
// will preserve that behavior if the underlying file system
// supports those properties.
return this.createFileSync(p, flag, stats.mode);
case file_flag_1.ActionType.NOP:
return this.openFileSync(p, flag, mode);
default:
throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileFlag object.');
}
};
BaseFileSystem.prototype.unlink = function (p, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.unlinkSync = function (p) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.rmdir = function (p, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.rmdirSync = function (p) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.mkdir = function (p, mode, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.mkdirSync = function (p, mode) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.readdir = function (p, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.readdirSync = function (p) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.exists = function (p, cb) {
this.stat(p, null, function (err) {
cb(!err);
});
};
BaseFileSystem.prototype.existsSync = function (p) {
try {
this.statSync(p, true);
return true;
}
catch (e) {
return false;
}
};
BaseFileSystem.prototype.realpath = function (p, cache, cb) {
if (this.supportsLinks()) {
// The path could contain symlinks. Split up the path,
// resolve any symlinks, return the resolved string.
var splitPath = p.split(path.sep);
// TODO: Simpler to just pass through file, find sep and such.
for (var i = 0; i < splitPath.length; i++) {
var addPaths = splitPath.slice(0, i + 1);
splitPath[i] = path.join.apply(null, addPaths);
}
}
else {
// No symlinks. We just need to verify that it exists.
this.exists(p, function (doesExist) {
if (doesExist) {
cb(null, p);
}
else {
cb(api_error_1.ApiError.ENOENT(p));
}
});
}
};
BaseFileSystem.prototype.realpathSync = function (p, cache) {
if (this.supportsLinks()) {
// The path could contain symlinks. Split up the path,
// resolve any symlinks, return the resolved string.
var splitPath = p.split(path.sep);
// TODO: Simpler to just pass through file, find sep and such.
for (var i = 0; i < splitPath.length; i++) {
var addPaths = splitPath.slice(0, i + 1);
splitPath[i] = path.join.apply(path, addPaths);
}
return splitPath.join(path.sep);
}
else {
// No symlinks. We just need to verify that it exists.
if (this.existsSync(p)) {
return p;
}
else {
throw api_error_1.ApiError.ENOENT(p);
}
}
};
BaseFileSystem.prototype.truncate = function (p, len, cb) {
this.open(p, file_flag_1.FileFlag.getFileFlag('r+'), 0x1a4, (function (er, fd) {
if (er) {
return cb(er);
}
fd.truncate(len, (function (er) {
fd.close((function (er2) {
cb(er || er2);
}));
}));
}));
};
BaseFileSystem.prototype.truncateSync = function (p, len) {
var fd = this.openSync(p, file_flag_1.FileFlag.getFileFlag('r+'), 0x1a4);
// Need to safely close FD, regardless of whether or not truncate succeeds.
try {
fd.truncateSync(len);
}
catch (e) {
throw e;
}
finally {
fd.closeSync();
}
};
BaseFileSystem.prototype.readFile = function (fname, encoding, flag, cb) {
// Wrap cb in file closing code.
var oldCb = cb;
// Get file.
this.open(fname, flag, 0x1a4, function (err, fd) {
if (err) {
return cb(err);
}
cb = function (err, arg) {
fd.close(function (err2) {
if (!err) {
err = err2;
}
return oldCb(err, arg);
});
};
fd.stat(function (err, stat) {
if (err) {
return cb(err);
}
// Allocate buffer.
var buf = Buffer.alloc(stat.size);
fd.read(buf, 0, stat.size, 0, function (err) {
if (err) {
return cb(err);
}
else if (encoding === null) {
return cb(err, buf);
}
try {
cb(null, buf.toString(encoding));
}
catch (e) {
cb(e);
}
});
});
});
};
BaseFileSystem.prototype.readFileSync = function (fname, encoding, flag) {
// Get file.
var fd = this.openSync(fname, flag, 0x1a4);
try {
var stat = fd.statSync();
// Allocate buffer.
var buf = Buffer.alloc(stat.size);
fd.readSync(buf, 0, stat.size, 0);
fd.closeSync();
if (encoding === null) {
return buf;
}
return buf.toString(encoding);
}
finally {
fd.closeSync();
}
};
BaseFileSystem.prototype.writeFile = function (fname, data, encoding, flag, mode, cb) {
// Wrap cb in file closing code.
var oldCb = cb;
// Get file.
this.open(fname, flag, 0x1a4, function (err, fd) {
if (err) {
return cb(err);
}
cb = function (err) {
fd.close(function (err2) {
oldCb(err ? err : err2);
});
};
try {
if (typeof data === 'string') {
data = Buffer.from(data, encoding);
}
}
catch (e) {
return cb(e);
}
// Write into file.
fd.write(data, 0, data.length, 0, cb);
});
};
BaseFileSystem.prototype.writeFileSync = function (fname, data, encoding, flag, mode) {
// Get file.
var fd = this.openSync(fname, flag, mode);
try {
if (typeof data === 'string') {
data = Buffer.from(data, encoding);
}
// Write into file.
fd.writeSync(data, 0, data.length, 0);
}
finally {
fd.closeSync();
}
};
BaseFileSystem.prototype.appendFile = function (fname, data, encoding, flag, mode, cb) {
// Wrap cb in file closing code.
var oldCb = cb;
this.open(fname, flag, mode, function (err, fd) {
if (err) {
return cb(err);
}
cb = function (err) {
fd.close(function (err2) {
oldCb(err ? err : err2);
});
};
if (typeof data === 'string') {
data = Buffer.from(data, encoding);
}
fd.write(data, 0, data.length, null, cb);
});
};
BaseFileSystem.prototype.appendFileSync = function (fname, data, encoding, flag, mode) {
var fd = this.openSync(fname, flag, mode);
try {
if (typeof data === 'string') {
data = Buffer.from(data, encoding);
}
fd.writeSync(data, 0, data.length, null);
}
finally {
fd.closeSync();
}
};
BaseFileSystem.prototype.chmod = function (p, isLchmod, mode, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.chmodSync = function (p, isLchmod, mode) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.chown = function (p, isLchown, uid, gid, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.chownSync = function (p, isLchown, uid, gid) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.utimes = function (p, atime, mtime, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.utimesSync = function (p, atime, mtime) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.link = function (srcpath, dstpath, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.linkSync = function (srcpath, dstpath) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.symlink = function (srcpath, dstpath, type, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.symlinkSync = function (srcpath, dstpath, type) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
BaseFileSystem.prototype.readlink = function (p, cb) {
cb(new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP));
};
BaseFileSystem.prototype.readlinkSync = function (p) {
throw new api_error_1.ApiError(api_error_1.ErrorCode.ENOTSUP);
};
return BaseFileSystem;
}());
exports.BaseFileSystem = BaseFileSystem;
/**
* Implements the asynchronous API in terms of the synchronous API.
* @class SynchronousFileSystem
*/
var SynchronousFileSystem = /** @class */ (function (_super) {
__extends(SynchronousFileSystem, _super);
function SynchronousFileSystem() {
return _super !== null && _super.apply(this, arguments) || this;
}
SynchronousFileSystem.prototype.supportsSynch = function () {
return true;
};
SynchronousFileSystem.prototype.rename = function (oldPath, newPath, cb) {
try {
this.renameSync(oldPath, newPath);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.stat = function (p, isLstat, cb) {
try {
cb(null, this.statSync(p, isLstat));
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.open = function (p, flags, mode, cb) {
try {
cb(null, this.openSync(p, flags, mode));
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.unlink = function (p, cb) {
try {
this.unlinkSync(p);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.rmdir = function (p, cb) {
try {
this.rmdirSync(p);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.mkdir = function (p, mode, cb) {
try {
this.mkdirSync(p, mode);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.readdir = function (p, cb) {
try {
cb(null, this.readdirSync(p));
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.chmod = function (p, isLchmod, mode, cb) {
try {
this.chmodSync(p, isLchmod, mode);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.chown = function (p, isLchown, uid, gid, cb) {
try {
this.chownSync(p, isLchown, uid, gid);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.utimes = function (p, atime, mtime, cb) {
try {
this.utimesSync(p, atime, mtime);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.link = function (srcpath, dstpath, cb) {
try {
this.linkSync(srcpath, dstpath);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.symlink = function (srcpath, dstpath, type, cb) {
try {
this.symlinkSync(srcpath, dstpath, type);
cb();
}
catch (e) {
cb(e);
}
};
SynchronousFileSystem.prototype.readlink = function (p, cb) {
try {
cb(null, this.readlinkSync(p));
}
catch (e) {
cb(e);
}
};
return SynchronousFileSystem;
}(BaseFileSystem));
exports.SynchronousFileSystem = SynchronousFileSystem;
;