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" />

1,331 lines 47.7 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 }); var api_error_1 = require("../core/api_error"); var node_fs_stats_1 = require("../core/node_fs_stats"); var file_system_1 = require("../core/file_system"); var file_flag_1 = require("../core/file_flag"); var preload_file_1 = require("../generic/preload_file"); var util_1 = require("../core/util"); var path = require("path"); /** * @hidden */ var rockRidgeIdentifier = "IEEE_P1282"; /** * @hidden */ function getASCIIString(data, startIndex, length) { return data.toString('ascii', startIndex, startIndex + length).trim(); } /** * @hidden */ function getJolietString(data, startIndex, length) { if (length === 1) { // Special: Root, parent, current directory are still a single byte. return String.fromCharCode(data[startIndex]); } // UTF16-BE, which isn't natively supported by NodeJS Buffers. // Length should be even, but pessimistically floor just in case. var pairs = Math.floor(length / 2); var chars = new Array(pairs); for (var i = 0; i < pairs; i++) { var pos = startIndex + (i << 1); chars[i] = String.fromCharCode(data[pos + 1] | (data[pos] << 8)); } return chars.join(''); } /** * @hidden */ function getDate(data, startIndex) { var year = parseInt(getASCIIString(data, startIndex, 4), 10); var mon = parseInt(getASCIIString(data, startIndex + 4, 2), 10); var day = parseInt(getASCIIString(data, startIndex + 6, 2), 10); var hour = parseInt(getASCIIString(data, startIndex + 8, 2), 10); var min = parseInt(getASCIIString(data, startIndex + 10, 2), 10); var sec = parseInt(getASCIIString(data, startIndex + 12, 2), 10); var hundrethsSec = parseInt(getASCIIString(data, startIndex + 14, 2), 10); // Last is a time-zone offset, but JavaScript dates don't support time zones well. return new Date(year, mon, day, hour, min, sec, hundrethsSec * 100); } /** * @hidden */ function getShortFormDate(data, startIndex) { var yearsSince1900 = data[startIndex]; var month = data[startIndex + 1]; var day = data[startIndex + 2]; var hour = data[startIndex + 3]; var minute = data[startIndex + 4]; var second = data[startIndex + 5]; // JavaScript's Date support isn't so great; ignore timezone. // const offsetFromGMT = this._data[24]; return new Date(yearsSince1900, month - 1, day, hour, minute, second); } /** * @hidden */ function constructSystemUseEntry(bigData, i) { var data = bigData.slice(i); var sue = new SystemUseEntry(data); switch (sue.signatureWord()) { case 17221 /* SystemUseEntrySignatures.CE */: return new CEEntry(data); case 20548 /* SystemUseEntrySignatures.PD */: return new PDEntry(data); case 21328 /* SystemUseEntrySignatures.SP */: return new SPEntry(data); case 21332 /* SystemUseEntrySignatures.ST */: return new STEntry(data); case 17746 /* SystemUseEntrySignatures.ER */: return new EREntry(data); case 17747 /* SystemUseEntrySignatures.ES */: return new ESEntry(data); case 20568 /* SystemUseEntrySignatures.PX */: return new PXEntry(data); case 20558 /* SystemUseEntrySignatures.PN */: return new PNEntry(data); case 21324 /* SystemUseEntrySignatures.SL */: return new SLEntry(data); case 20045 /* SystemUseEntrySignatures.NM */: return new NMEntry(data); case 17228 /* SystemUseEntrySignatures.CL */: return new CLEntry(data); case 20556 /* SystemUseEntrySignatures.PL */: return new PLEntry(data); case 21061 /* SystemUseEntrySignatures.RE */: return new REEntry(data); case 21574 /* SystemUseEntrySignatures.TF */: return new TFEntry(data); case 21318 /* SystemUseEntrySignatures.SF */: return new SFEntry(data); case 21074 /* SystemUseEntrySignatures.RR */: return new RREntry(data); default: return sue; } } /** * @hidden */ function constructSystemUseEntries(data, i, len, isoData) { // If the remaining allocated space following the last recorded System Use Entry in a System // Use field or Continuation Area is less than four bytes long, it cannot contain a System // Use Entry and shall be ignored len = len - 4; var entries = new Array(); while (i < len) { var entry = constructSystemUseEntry(data, i); var length_1 = entry.length(); if (length_1 === 0) { // Invalid SU section; prevent infinite loop. return entries; } i += length_1; if (entry instanceof STEntry) { // ST indicates the end of entries. break; } if (entry instanceof CEEntry) { entries = entries.concat(entry.getEntries(isoData)); } else { entries.push(entry); } } return entries; } /** * @hidden */ var VolumeDescriptor = /** @class */ (function () { function VolumeDescriptor(data) { this._data = data; } VolumeDescriptor.prototype.type = function () { return this._data[0]; }; VolumeDescriptor.prototype.standardIdentifier = function () { return getASCIIString(this._data, 1, 5); }; VolumeDescriptor.prototype.version = function () { return this._data[6]; }; VolumeDescriptor.prototype.data = function () { return this._data.slice(7, 2048); }; return VolumeDescriptor; }()); /** * @hidden */ var PrimaryOrSupplementaryVolumeDescriptor = /** @class */ (function (_super) { __extends(PrimaryOrSupplementaryVolumeDescriptor, _super); function PrimaryOrSupplementaryVolumeDescriptor(data) { var _this = _super.call(this, data) || this; _this._root = null; return _this; } PrimaryOrSupplementaryVolumeDescriptor.prototype.systemIdentifier = function () { return this._getString32(8); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeIdentifier = function () { return this._getString32(40); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSpaceSize = function () { return this._data.readUInt32LE(80); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSetSize = function () { return this._data.readUInt16LE(120); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSequenceNumber = function () { return this._data.readUInt16LE(124); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.logicalBlockSize = function () { return this._data.readUInt16LE(128); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.pathTableSize = function () { return this._data.readUInt32LE(132); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfTypeLPathTable = function () { return this._data.readUInt32LE(140); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfOptionalTypeLPathTable = function () { return this._data.readUInt32LE(144); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfTypeMPathTable = function () { return this._data.readUInt32BE(148); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.locationOfOptionalTypeMPathTable = function () { return this._data.readUInt32BE(152); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.rootDirectoryEntry = function (isoData) { if (this._root === null) { this._root = this._constructRootDirectoryRecord(this._data.slice(156)); this._root.rootCheckForRockRidge(isoData); } return this._root; }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeSetIdentifier = function () { return this._getString(190, 128); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.publisherIdentifier = function () { return this._getString(318, 128); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.dataPreparerIdentifier = function () { return this._getString(446, 128); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.applicationIdentifier = function () { return this._getString(574, 128); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.copyrightFileIdentifier = function () { return this._getString(702, 38); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.abstractFileIdentifier = function () { return this._getString(740, 36); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.bibliographicFileIdentifier = function () { return this._getString(776, 37); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeCreationDate = function () { return getDate(this._data, 813); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeModificationDate = function () { return getDate(this._data, 830); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeExpirationDate = function () { return getDate(this._data, 847); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.volumeEffectiveDate = function () { return getDate(this._data, 864); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.fileStructureVersion = function () { return this._data[881]; }; PrimaryOrSupplementaryVolumeDescriptor.prototype.applicationUsed = function () { return this._data.slice(883, 883 + 512); }; PrimaryOrSupplementaryVolumeDescriptor.prototype.reserved = function () { return this._data.slice(1395, 1395 + 653); }; PrimaryOrSupplementaryVolumeDescriptor.prototype._getString32 = function (idx) { return this._getString(idx, 32); }; return PrimaryOrSupplementaryVolumeDescriptor; }(VolumeDescriptor)); /** * @hidden */ var PrimaryVolumeDescriptor = /** @class */ (function (_super) { __extends(PrimaryVolumeDescriptor, _super); function PrimaryVolumeDescriptor(data) { var _this = _super.call(this, data) || this; if (_this.type() !== 1 /* VolumeDescriptorTypeCode.PrimaryVolumeDescriptor */) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Invalid primary volume descriptor."); } return _this; } PrimaryVolumeDescriptor.prototype.name = function () { return "ISO9660"; }; PrimaryVolumeDescriptor.prototype._constructRootDirectoryRecord = function (data) { return new ISODirectoryRecord(data, -1); }; PrimaryVolumeDescriptor.prototype._getString = function (idx, len) { return this._getString(idx, len); }; return PrimaryVolumeDescriptor; }(PrimaryOrSupplementaryVolumeDescriptor)); /** * @hidden */ var SupplementaryVolumeDescriptor = /** @class */ (function (_super) { __extends(SupplementaryVolumeDescriptor, _super); function SupplementaryVolumeDescriptor(data) { var _this = _super.call(this, data) || this; if (_this.type() !== 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Invalid supplementary volume descriptor."); } var escapeSequence = _this.escapeSequence(); var third = escapeSequence[2]; // Third character identifies what 'level' of the UCS specification to follow. // We ignore it. if (escapeSequence[0] !== 0x25 || escapeSequence[1] !== 0x2F || (third !== 0x40 && third !== 0x43 && third !== 0x45)) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Unrecognized escape sequence for SupplementaryVolumeDescriptor: ".concat(escapeSequence.toString())); } return _this; } SupplementaryVolumeDescriptor.prototype.name = function () { return "Joliet"; }; SupplementaryVolumeDescriptor.prototype.escapeSequence = function () { return this._data.slice(88, 120); }; SupplementaryVolumeDescriptor.prototype._constructRootDirectoryRecord = function (data) { return new JolietDirectoryRecord(data, -1); }; SupplementaryVolumeDescriptor.prototype._getString = function (idx, len) { return getJolietString(this._data, idx, len); }; return SupplementaryVolumeDescriptor; }(PrimaryOrSupplementaryVolumeDescriptor)); /** * @hidden */ var DirectoryRecord = /** @class */ (function () { function DirectoryRecord(data, rockRidgeOffset) { this._suEntries = null; this._fileOrDir = null; this._data = data; this._rockRidgeOffset = rockRidgeOffset; } DirectoryRecord.prototype.hasRockRidge = function () { return this._rockRidgeOffset > -1; }; DirectoryRecord.prototype.getRockRidgeOffset = function () { return this._rockRidgeOffset; }; /** * !!ONLY VALID ON ROOT NODE!! * Checks if Rock Ridge is enabled, and sets the offset. */ DirectoryRecord.prototype.rootCheckForRockRidge = function (isoData) { var dir = this.getDirectory(isoData); this._rockRidgeOffset = dir.getDotEntry(isoData)._getRockRidgeOffset(isoData); if (this._rockRidgeOffset > -1) { // Wipe out directory. Start over with RR knowledge. this._fileOrDir = null; } }; DirectoryRecord.prototype.length = function () { return this._data[0]; }; DirectoryRecord.prototype.extendedAttributeRecordLength = function () { return this._data[1]; }; DirectoryRecord.prototype.lba = function () { return this._data.readUInt32LE(2) * 2048; }; DirectoryRecord.prototype.dataLength = function () { return this._data.readUInt32LE(10); }; DirectoryRecord.prototype.recordingDate = function () { return getShortFormDate(this._data, 18); }; DirectoryRecord.prototype.fileFlags = function () { return this._data[25]; }; DirectoryRecord.prototype.fileUnitSize = function () { return this._data[26]; }; DirectoryRecord.prototype.interleaveGapSize = function () { return this._data[27]; }; DirectoryRecord.prototype.volumeSequenceNumber = function () { return this._data.readUInt16LE(28); }; DirectoryRecord.prototype.identifier = function () { return this._getString(33, this._data[32]); }; DirectoryRecord.prototype.fileName = function (isoData) { if (this.hasRockRidge()) { var fn = this._rockRidgeFilename(isoData); if (fn !== null) { return fn; } } var ident = this.identifier(); if (this.isDirectory(isoData)) { return ident; } // Files: // - MUST have 0x2E (.) separating the name from the extension // - MUST have 0x3B (;) separating the file name and extension from the version // Gets expanded to two-byte char in Unicode directory records. var versionSeparator = ident.indexOf(';'); if (versionSeparator === -1) { // Some Joliet filenames lack the version separator, despite the standard // specifying that it should be there. return ident; } else if (ident[versionSeparator - 1] === '.') { // Empty extension. Do not include '.' in the filename. return ident.slice(0, versionSeparator - 1); } else { // Include up to version separator. return ident.slice(0, versionSeparator); } }; DirectoryRecord.prototype.isDirectory = function (isoData) { var rv = Boolean(this.fileFlags() && 2 /* FileFlags.Directory */); // If it lacks the Directory flag, it may still be a directory if we've exceeded the directory // depth limit. Rock Ridge marks these as files and adds a special attribute. if (!rv && this.hasRockRidge()) { rv = this.getSUEntries(isoData).filter(function (e) { return e instanceof CLEntry; }).length > 0; } return rv; }; DirectoryRecord.prototype.isSymlink = function (isoData) { return this.hasRockRidge() && this.getSUEntries(isoData).filter(function (e) { return e instanceof SLEntry; }).length > 0; }; DirectoryRecord.prototype.getSymlinkPath = function (isoData) { var p = ""; var entries = this.getSUEntries(isoData); var getStr = this._getGetString(); for (var _i = 0, entries_1 = entries; _i < entries_1.length; _i++) { var entry = entries_1[_i]; if (entry instanceof SLEntry) { var components = entry.componentRecords(); for (var _a = 0, components_1 = components; _a < components_1.length; _a++) { var component = components_1[_a]; var flags = component.flags(); if (flags & 2 /* SLComponentFlags.CURRENT */) { p += "./"; } else if (flags & 4 /* SLComponentFlags.PARENT */) { p += "../"; } else if (flags & 8 /* SLComponentFlags.ROOT */) { p += "/"; } else { p += component.content(getStr); if (!(flags & 1 /* SLComponentFlags.CONTINUE */)) { p += '/'; } } } if (!entry.continueFlag()) { // We are done with this link. break; } } } if (p.length > 1 && p[p.length - 1] === '/') { // Trim trailing '/'. return p.slice(0, p.length - 1); } else { return p; } }; DirectoryRecord.prototype.getFile = function (isoData) { if (this.isDirectory(isoData)) { throw new Error("Tried to get a File from a directory."); } if (this._fileOrDir === null) { this._fileOrDir = isoData.slice(this.lba(), this.lba() + this.dataLength()); } return this._fileOrDir; }; DirectoryRecord.prototype.getDirectory = function (isoData) { if (!this.isDirectory(isoData)) { throw new Error("Tried to get a Directory from a file."); } if (this._fileOrDir === null) { this._fileOrDir = this._constructDirectory(isoData); } return this._fileOrDir; }; DirectoryRecord.prototype.getSUEntries = function (isoData) { if (!this._suEntries) { this._constructSUEntries(isoData); } return this._suEntries; }; DirectoryRecord.prototype._rockRidgeFilename = function (isoData) { var nmEntries = this.getSUEntries(isoData).filter(function (e) { return e instanceof NMEntry; }); if (nmEntries.length === 0 || nmEntries[0].flags() & (2 /* NMFlags.CURRENT */ | 4 /* NMFlags.PARENT */)) { return null; } var str = ''; var getString = this._getGetString(); for (var _i = 0, nmEntries_1 = nmEntries; _i < nmEntries_1.length; _i++) { var e = nmEntries_1[_i]; str += e.name(getString); if (!(e.flags() & 1 /* NMFlags.CONTINUE */)) { break; } } return str; }; DirectoryRecord.prototype._constructSUEntries = function (isoData) { var i = 33 + this._data[32]; if (i % 2 === 1) { // Skip padding field. i++; } i += this._rockRidgeOffset; this._suEntries = constructSystemUseEntries(this._data, i, this.length(), isoData); }; /** * !!ONLY VALID ON FIRST ENTRY OF ROOT DIRECTORY!! * Returns -1 if rock ridge is not enabled. Otherwise, returns the offset * at which system use fields begin. */ DirectoryRecord.prototype._getRockRidgeOffset = function (isoData) { // In the worst case, we get some garbage SU entries. // Fudge offset to 0 before proceeding. this._rockRidgeOffset = 0; var suEntries = this.getSUEntries(isoData); if (suEntries.length > 0) { var spEntry = suEntries[0]; if (spEntry instanceof SPEntry && spEntry.checkBytesPass()) { // SUSP is in use. for (var i = 1; i < suEntries.length; i++) { var entry = suEntries[i]; if (entry instanceof RREntry || (entry instanceof EREntry && entry.extensionIdentifier() === rockRidgeIdentifier)) { // Rock Ridge is in use! return spEntry.bytesSkipped(); } } } } // Failed. this._rockRidgeOffset = -1; return -1; }; return DirectoryRecord; }()); /** * @hidden */ var ISODirectoryRecord = /** @class */ (function (_super) { __extends(ISODirectoryRecord, _super); function ISODirectoryRecord(data, rockRidgeOffset) { return _super.call(this, data, rockRidgeOffset) || this; } ISODirectoryRecord.prototype._getString = function (i, len) { return getASCIIString(this._data, i, len); }; ISODirectoryRecord.prototype._constructDirectory = function (isoData) { return new ISODirectory(this, isoData); }; ISODirectoryRecord.prototype._getGetString = function () { return getASCIIString; }; return ISODirectoryRecord; }(DirectoryRecord)); /** * @hidden */ var JolietDirectoryRecord = /** @class */ (function (_super) { __extends(JolietDirectoryRecord, _super); function JolietDirectoryRecord(data, rockRidgeOffset) { return _super.call(this, data, rockRidgeOffset) || this; } JolietDirectoryRecord.prototype._getString = function (i, len) { return getJolietString(this._data, i, len); }; JolietDirectoryRecord.prototype._constructDirectory = function (isoData) { return new JolietDirectory(this, isoData); }; JolietDirectoryRecord.prototype._getGetString = function () { return getJolietString; }; return JolietDirectoryRecord; }(DirectoryRecord)); /** * @hidden */ var SystemUseEntry = /** @class */ (function () { function SystemUseEntry(data) { this._data = data; } SystemUseEntry.prototype.signatureWord = function () { return this._data.readUInt16BE(0); }; SystemUseEntry.prototype.signatureWordString = function () { return getASCIIString(this._data, 0, 2); }; SystemUseEntry.prototype.length = function () { return this._data[2]; }; SystemUseEntry.prototype.suVersion = function () { return this._data[3]; }; return SystemUseEntry; }()); /** * Continuation entry. * @hidden */ var CEEntry = /** @class */ (function (_super) { __extends(CEEntry, _super); function CEEntry(data) { var _this = _super.call(this, data) || this; _this._entries = null; return _this; } /** * Logical block address of the continuation area. */ CEEntry.prototype.continuationLba = function () { return this._data.readUInt32LE(4); }; /** * Offset into the logical block. */ CEEntry.prototype.continuationLbaOffset = function () { return this._data.readUInt32LE(12); }; /** * Length of the continuation area. */ CEEntry.prototype.continuationLength = function () { return this._data.readUInt32LE(20); }; CEEntry.prototype.getEntries = function (isoData) { if (!this._entries) { var start = this.continuationLba() * 2048 + this.continuationLbaOffset(); this._entries = constructSystemUseEntries(isoData, start, this.continuationLength(), isoData); } return this._entries; }; return CEEntry; }(SystemUseEntry)); /** * Padding entry. * @hidden */ var PDEntry = /** @class */ (function (_super) { __extends(PDEntry, _super); function PDEntry(data) { return _super.call(this, data) || this; } return PDEntry; }(SystemUseEntry)); /** * Identifies that SUSP is in-use. * @hidden */ var SPEntry = /** @class */ (function (_super) { __extends(SPEntry, _super); function SPEntry(data) { return _super.call(this, data) || this; } SPEntry.prototype.checkBytesPass = function () { return this._data[4] === 0xBE && this._data[5] === 0xEF; }; SPEntry.prototype.bytesSkipped = function () { return this._data[6]; }; return SPEntry; }(SystemUseEntry)); /** * Identifies the end of the SUSP entries. * @hidden */ var STEntry = /** @class */ (function (_super) { __extends(STEntry, _super); function STEntry(data) { return _super.call(this, data) || this; } return STEntry; }(SystemUseEntry)); /** * Specifies system-specific extensions to SUSP. * @hidden */ var EREntry = /** @class */ (function (_super) { __extends(EREntry, _super); function EREntry(data) { return _super.call(this, data) || this; } EREntry.prototype.identifierLength = function () { return this._data[4]; }; EREntry.prototype.descriptorLength = function () { return this._data[5]; }; EREntry.prototype.sourceLength = function () { return this._data[6]; }; EREntry.prototype.extensionVersion = function () { return this._data[7]; }; EREntry.prototype.extensionIdentifier = function () { return getASCIIString(this._data, 8, this.identifierLength()); }; EREntry.prototype.extensionDescriptor = function () { return getASCIIString(this._data, 8 + this.identifierLength(), this.descriptorLength()); }; EREntry.prototype.extensionSource = function () { return getASCIIString(this._data, 8 + this.identifierLength() + this.descriptorLength(), this.sourceLength()); }; return EREntry; }(SystemUseEntry)); /** * @hidden */ var ESEntry = /** @class */ (function (_super) { __extends(ESEntry, _super); function ESEntry(data) { return _super.call(this, data) || this; } ESEntry.prototype.extensionSequence = function () { return this._data[4]; }; return ESEntry; }(SystemUseEntry)); /** * RockRidge: Marks that RockRidge is in use [deprecated] * @hidden */ var RREntry = /** @class */ (function (_super) { __extends(RREntry, _super); function RREntry(data) { return _super.call(this, data) || this; } return RREntry; }(SystemUseEntry)); /** * RockRidge: Records POSIX file attributes. * @hidden */ var PXEntry = /** @class */ (function (_super) { __extends(PXEntry, _super); function PXEntry(data) { return _super.call(this, data) || this; } PXEntry.prototype.mode = function () { return this._data.readUInt32LE(4); }; PXEntry.prototype.fileLinks = function () { return this._data.readUInt32LE(12); }; PXEntry.prototype.uid = function () { return this._data.readUInt32LE(20); }; PXEntry.prototype.gid = function () { return this._data.readUInt32LE(28); }; PXEntry.prototype.inode = function () { return this._data.readUInt32LE(36); }; return PXEntry; }(SystemUseEntry)); /** * RockRidge: Records POSIX device number. * @hidden */ var PNEntry = /** @class */ (function (_super) { __extends(PNEntry, _super); function PNEntry(data) { return _super.call(this, data) || this; } PNEntry.prototype.devTHigh = function () { return this._data.readUInt32LE(4); }; PNEntry.prototype.devTLow = function () { return this._data.readUInt32LE(12); }; return PNEntry; }(SystemUseEntry)); /** * RockRidge: Records symbolic link * @hidden */ var SLEntry = /** @class */ (function (_super) { __extends(SLEntry, _super); function SLEntry(data) { return _super.call(this, data) || this; } SLEntry.prototype.flags = function () { return this._data[4]; }; SLEntry.prototype.continueFlag = function () { return this.flags() & 0x1; }; SLEntry.prototype.componentRecords = function () { var records = new Array(); var i = 5; while (i < this.length()) { var record = new SLComponentRecord(this._data.slice(i)); records.push(record); i += record.length(); } return records; }; return SLEntry; }(SystemUseEntry)); /** * @hidden */ var SLComponentRecord = /** @class */ (function () { function SLComponentRecord(data) { this._data = data; } SLComponentRecord.prototype.flags = function () { return this._data[0]; }; SLComponentRecord.prototype.length = function () { return 2 + this.componentLength(); }; SLComponentRecord.prototype.componentLength = function () { return this._data[1]; }; SLComponentRecord.prototype.content = function (getString) { return getString(this._data, 2, this.componentLength()); }; return SLComponentRecord; }()); /** * RockRidge: Records alternate file name * @hidden */ var NMEntry = /** @class */ (function (_super) { __extends(NMEntry, _super); function NMEntry(data) { return _super.call(this, data) || this; } NMEntry.prototype.flags = function () { return this._data[4]; }; NMEntry.prototype.name = function (getString) { return getString(this._data, 5, this.length() - 5); }; return NMEntry; }(SystemUseEntry)); /** * RockRidge: Records child link * @hidden */ var CLEntry = /** @class */ (function (_super) { __extends(CLEntry, _super); function CLEntry(data) { return _super.call(this, data) || this; } CLEntry.prototype.childDirectoryLba = function () { return this._data.readUInt32LE(4); }; return CLEntry; }(SystemUseEntry)); /** * RockRidge: Records parent link. * @hidden */ var PLEntry = /** @class */ (function (_super) { __extends(PLEntry, _super); function PLEntry(data) { return _super.call(this, data) || this; } PLEntry.prototype.parentDirectoryLba = function () { return this._data.readUInt32LE(4); }; return PLEntry; }(SystemUseEntry)); /** * RockRidge: Records relocated directory. * @hidden */ var REEntry = /** @class */ (function (_super) { __extends(REEntry, _super); function REEntry(data) { return _super.call(this, data) || this; } return REEntry; }(SystemUseEntry)); /** * RockRidge: Records file timestamps * @hidden */ var TFEntry = /** @class */ (function (_super) { __extends(TFEntry, _super); function TFEntry(data) { return _super.call(this, data) || this; } TFEntry.prototype.flags = function () { return this._data[4]; }; TFEntry.prototype.creation = function () { if (this.flags() & 1 /* TFFlags.CREATION */) { if (this._longFormDates()) { return getDate(this._data, 5); } else { return getShortFormDate(this._data, 5); } } else { return null; } }; TFEntry.prototype.modify = function () { if (this.flags() & 2 /* TFFlags.MODIFY */) { var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0; if (this._longFormDates()) { return getDate(this._data, 5 + (previousDates * 17)); } else { return getShortFormDate(this._data, 5 + (previousDates * 7)); } } else { return null; } }; TFEntry.prototype.access = function () { if (this.flags() & 4 /* TFFlags.ACCESS */) { var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0; previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0; if (this._longFormDates()) { return getDate(this._data, 5 + (previousDates * 17)); } else { return getShortFormDate(this._data, 5 + (previousDates * 7)); } } else { return null; } }; TFEntry.prototype.backup = function () { if (this.flags() & 16 /* TFFlags.BACKUP */) { var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0; previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0; previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0; if (this._longFormDates()) { return getDate(this._data, 5 + (previousDates * 17)); } else { return getShortFormDate(this._data, 5 + (previousDates * 7)); } } else { return null; } }; TFEntry.prototype.expiration = function () { if (this.flags() & 32 /* TFFlags.EXPIRATION */) { var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0; previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0; previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0; previousDates += (this.flags() & 16 /* TFFlags.BACKUP */) ? 1 : 0; if (this._longFormDates()) { return getDate(this._data, 5 + (previousDates * 17)); } else { return getShortFormDate(this._data, 5 + (previousDates * 7)); } } else { return null; } }; TFEntry.prototype.effective = function () { if (this.flags() & 64 /* TFFlags.EFFECTIVE */) { var previousDates = (this.flags() & 1 /* TFFlags.CREATION */) ? 1 : 0; previousDates += (this.flags() & 2 /* TFFlags.MODIFY */) ? 1 : 0; previousDates += (this.flags() & 4 /* TFFlags.ACCESS */) ? 1 : 0; previousDates += (this.flags() & 16 /* TFFlags.BACKUP */) ? 1 : 0; previousDates += (this.flags() & 32 /* TFFlags.EXPIRATION */) ? 1 : 0; if (this._longFormDates()) { return getDate(this._data, 5 + (previousDates * 17)); } else { return getShortFormDate(this._data, 5 + (previousDates * 7)); } } else { return null; } }; TFEntry.prototype._longFormDates = function () { return Boolean(this.flags() && 128 /* TFFlags.LONG_FORM */); }; return TFEntry; }(SystemUseEntry)); /** * RockRidge: File data in sparse format. * @hidden */ var SFEntry = /** @class */ (function (_super) { __extends(SFEntry, _super); function SFEntry(data) { return _super.call(this, data) || this; } SFEntry.prototype.virtualSizeHigh = function () { return this._data.readUInt32LE(4); }; SFEntry.prototype.virtualSizeLow = function () { return this._data.readUInt32LE(12); }; SFEntry.prototype.tableDepth = function () { return this._data[20]; }; return SFEntry; }(SystemUseEntry)); /** * @hidden */ var Directory = /** @class */ (function () { function Directory(record, isoData) { this._fileList = []; this._fileMap = {}; this._record = record; var i = record.lba(); var iLimit = i + record.dataLength(); if (!(record.fileFlags() & 2 /* FileFlags.Directory */)) { // Must have a CL entry. var cl = record.getSUEntries(isoData).filter(function (e) { return e instanceof CLEntry; })[0]; i = cl.childDirectoryLba() * 2048; iLimit = Infinity; } while (i < iLimit) { var len = isoData[i]; // Zero-padding between sectors. // TODO: Could optimize this to seek to nearest-sector upon // seeing a 0. if (len === 0) { i++; continue; } var r = this._constructDirectoryRecord(isoData.slice(i)); var fname = r.fileName(isoData); // Skip '.' and '..' entries. if (fname !== '\u0000' && fname !== '\u0001') { // Skip relocated entries. if (!r.hasRockRidge() || r.getSUEntries(isoData).filter(function (e) { return e instanceof REEntry; }).length === 0) { this._fileMap[fname] = r; this._fileList.push(fname); } } else if (iLimit === Infinity) { // First entry contains needed data. iLimit = i + r.dataLength(); } i += r.length(); } } /** * Get the record with the given name. * Returns undefined if not present. */ Directory.prototype.getRecord = function (name) { return this._fileMap[name]; }; Directory.prototype.getFileList = function () { return this._fileList; }; Directory.prototype.getDotEntry = function (isoData) { return this._constructDirectoryRecord(isoData.slice(this._record.lba())); }; return Directory; }()); /** * @hidden */ var ISODirectory = /** @class */ (function (_super) { __extends(ISODirectory, _super); function ISODirectory(record, isoData) { return _super.call(this, record, isoData) || this; } ISODirectory.prototype._constructDirectoryRecord = function (data) { return new ISODirectoryRecord(data, this._record.getRockRidgeOffset()); }; return ISODirectory; }(Directory)); /** * @hidden */ var JolietDirectory = /** @class */ (function (_super) { __extends(JolietDirectory, _super); function JolietDirectory(record, isoData) { return _super.call(this, record, isoData) || this; } JolietDirectory.prototype._constructDirectoryRecord = function (data) { return new JolietDirectoryRecord(data, this._record.getRockRidgeOffset()); }; return JolietDirectory; }(Directory)); /** * Mounts an ISO file as a read-only file system. * * Supports: * * Vanilla ISO9660 ISOs * * Microsoft Joliet and Rock Ridge extensions to the ISO9660 standard */ var IsoFS = /** @class */ (function (_super) { __extends(IsoFS, _super); /** * **Deprecated. Please use IsoFS.Create() method instead.** * * Constructs a read-only file system from the given ISO. * @param data The ISO file in a buffer. * @param name The name of the ISO (optional; used for debug messages / identification via getName()). */ function IsoFS(data, name) { if (name === void 0) { name = ""; } var _this = _super.call(this) || this; _this._data = data; // Skip first 16 sectors. var vdTerminatorFound = false; var i = 16 * 2048; var candidateVDs = new Array(); while (!vdTerminatorFound) { var slice = data.slice(i); var vd = new VolumeDescriptor(slice); switch (vd.type()) { case 1 /* VolumeDescriptorTypeCode.PrimaryVolumeDescriptor */: candidateVDs.push(new PrimaryVolumeDescriptor(slice)); break; case 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */: candidateVDs.push(new SupplementaryVolumeDescriptor(slice)); break; case 255 /* VolumeDescriptorTypeCode.VolumeDescriptorSetTerminator */: vdTerminatorFound = true; break; } i += 2048; } if (candidateVDs.length === 0) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EIO, "Unable to find a suitable volume descriptor."); } candidateVDs.forEach(function (v) { // Take an SVD over a PVD. if (!_this._pvd || _this._pvd.type() !== 2 /* VolumeDescriptorTypeCode.SupplementaryVolumeDescriptor */) { _this._pvd = v; } }); _this._root = _this._pvd.rootDirectoryEntry(data); _this._name = name; return _this; } /** * Creates an IsoFS instance with the given options. */ IsoFS.Create = function (opts, cb) { try { cb(null, new IsoFS(opts.data, opts.name)); } catch (e) { cb(e); } }; IsoFS.isAvailable = function () { return true; }; IsoFS.prototype.getName = function () { var name = "IsoFS".concat(this._name).concat(this._pvd ? "-".concat(this._pvd.name()) : ''); if (this._root && this._root.hasRockRidge()) { name += "-RockRidge"; } return name; }; IsoFS.prototype.diskSpace = function (path, cb) { // Read-only file system. cb(this._data.length, 0); }; IsoFS.prototype.isReadOnly = function () { return true; }; IsoFS.prototype.supportsLinks = function () { return false; }; IsoFS.prototype.supportsProps = function () { return false; }; IsoFS.prototype.supportsSynch = function () { return true; }; IsoFS.prototype.statSync = function (p, isLstat) { var record = this._getDirectoryRecord(p); if (record === null) { throw api_error_1.ApiError.ENOENT(p); } return this._getStats(p, record); }; IsoFS.prototype.openSync = function (p, flags, mode) { // INVARIANT: Cannot write to RO file systems. if (flags.isWriteable()) { throw new api_error_1.ApiError(api_error_1.ErrorCode.EPERM, p); } // Check if the path exists, and is a file. var record = this._getDirectoryRecord(p); if (!record) { throw api_error_1.ApiError.ENOENT(p); } else if (record.isSymlink(this._data)) { return this.openSync(path.resolve(p, record.getSymlinkPath(this._data)), flags, mode); } else if (!record.isDirectory(this._data)) { var data = record.getFile(this._data); var stats = this._getStats(p, record); switch (flags.pathExistsAction()) { case file_flag_1.ActionType.THROW_EXCEPTION: case file_flag_1.ActionType.TRUNCATE_FILE: throw api_error_1.ApiError.EEXIST(p); case file_flag_1.ActionType.NOP: return new preload_file_1.NoSyncFile(this, p, flags, stats, data); default: throw new api_error_1.ApiError(api_error_1.ErrorCode.EINVAL, 'Invalid FileMode object.'); } } else { throw api_error_1.ApiError.EISDIR(p); } }; IsoFS.prototype.readdirSync = function (path) { // Check if it exists. var record = this._getDirectoryRecord(path); if (!record) { throw api_error_1.ApiError.ENOENT(path); } else if (record.isDirectory(this._data)) { return record.getDirectory(this._data).getFileList().slice(0); } else { throw api_error_1.ApiError.ENOTDIR(path); } }; /** * Specially-optimized readfile. */ IsoFS.prototype.readFileSync = function (fname, encoding, flag) { // Get file. var fd = this.openSync(fname, flag, 0x1a4); try { var fdCast = fd; var fdBuff = fdCast.getBuffer(); if (encoding === null) { return (0, util_1.copyingSlice)(fdBuff); } return fdBuff.toString(encoding); } finally { fd.closeSync(); } }; IsoFS.prototype._getDirectoryRecord = function (path) { // Special case. if (path === '/') { return this._root; } var components = path.split('/').slice(1); var dir = this._root; for (var _i = 0, components_2 = components; _i < components_2.length; _i++) { var component = components_2[_i]; if (dir.isDirectory(this._data)) { dir = dir.getDirectory(this._data).getRecord(component); if (!dir) { return null; } } else { return null; } } return dir; }; IsoFS.prototype._getStats = function (p, record) { if (record.isSymlink(this._data)) { var newP = path.resolve(p, record.getSymlinkPath(this._data)); var dirRec = this._getDirectoryRecord(newP); if (!dirRec) { return null; } return this._getStats(newP, dirRec); } else { var len = record.dataLength(); var mode = 0x16D; var date = record.recordingDate().getTime(); var atime = date; var mtime = date; var ctime = date; if (record.hasRockRidge()) { var entries = record.getSUEntries(this._data); for (var _i = 0, entries_2 = entries; _i < entries_2.length; _i++) { var entry = entries_2[_i]; if (entry instanceof PXEntry) { mode = entry.mode(); } else if (entry instanceof TFEntry) { var flags = entry.flags(); if (flags & 4 /* TFFlags.ACCESS */) { atime = entry.access().getTime(); } if (flags & 2 /* TFFlags.MODIFY */) { mtime = entry.modify().getTime(); } if (flags & 1 /* TFFlags.CREATION */) { ctime = entry.creation().getTime(); } } } } // Mask out writeable flags. This is a RO file system. mode = mode & 0x16D; return new node_fs_stats_1.default(record.isDirectory(this._data) ? node_fs_stats_1.FileType.DIRECTORY : node_fs_stats_1.FileType.FILE, len, mode, atime, mtime, ctime); } }; IsoFS.Name = "IsoFS"; IsoFS.Options = { data: { type: "object", description: "The ISO file in a buffer", validator: util_1.bufferValidator } }; return IsoFS; }(file_system_1.SynchronousFileSystem)); exports.default = IsoFS;