UNPKG

@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
"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 }); 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;