Compare commits
2 Commits
3a122be029
...
ce3b285d1a
Author | SHA1 | Date | |
---|---|---|---|
ce3b285d1a | |||
697cd354f6 |
718
.pnp.cjs
generated
718
.pnp.cjs
generated
@ -17,6 +17,7 @@ const RAW_RUNTIME_STATE =
|
||||
],\
|
||||
"enableTopLevelFallback": true,\
|
||||
"ignorePatternData": "(^(?:\\\\.yarn\\\\/sdks(?:\\\\/(?!\\\\.{1,2}(?:\\\\/|$))(?:(?:(?!(?:^|\\\\/)\\\\.{1,2}(?:\\\\/|$)).)*?)|$))$)",\
|
||||
"pnpZipBackend": "libzip",\
|
||||
"fallbackExclusionList": [\
|
||||
["clean-architecture", ["workspace:."]]\
|
||||
],\
|
||||
@ -9114,14 +9115,16 @@ class ZipOpenFS extends MountFS {
|
||||
return new ZipFS(p, {
|
||||
baseFs,
|
||||
readOnly: readOnlyArchives,
|
||||
stats: baseFs.statSync(p)
|
||||
stats: baseFs.statSync(p),
|
||||
customZipImplementation: opts.customZipImplementation
|
||||
});
|
||||
};
|
||||
const factoryPromise = async (baseFs, p) => {
|
||||
const zipOptions = {
|
||||
baseFs,
|
||||
readOnly: readOnlyArchives,
|
||||
stats: await baseFs.statPromise(p)
|
||||
stats: await baseFs.statPromise(p),
|
||||
customZipImplementation: opts.customZipImplementation
|
||||
};
|
||||
return () => {
|
||||
return new ZipFS(p, zipOptions);
|
||||
@ -9136,6 +9139,236 @@ class ZipOpenFS extends MountFS {
|
||||
}
|
||||
}
|
||||
|
||||
class LibzipError extends Error {
|
||||
code;
|
||||
constructor(message, code) {
|
||||
super(message);
|
||||
this.name = `Libzip Error`;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
class LibZipImpl {
|
||||
libzip;
|
||||
lzSource;
|
||||
zip;
|
||||
listings;
|
||||
symlinkCount;
|
||||
filesShouldBeCached = true;
|
||||
constructor(opts) {
|
||||
const buffer = `buffer` in opts ? opts.buffer : opts.baseFs.readFileSync(opts.path);
|
||||
this.libzip = getInstance();
|
||||
const errPtr = this.libzip.malloc(4);
|
||||
try {
|
||||
let flags = 0;
|
||||
if (opts.readOnly)
|
||||
flags |= this.libzip.ZIP_RDONLY;
|
||||
const lzSource = this.allocateUnattachedSource(buffer);
|
||||
try {
|
||||
this.zip = this.libzip.openFromSource(lzSource, flags, errPtr);
|
||||
this.lzSource = lzSource;
|
||||
} catch (error) {
|
||||
this.libzip.source.free(lzSource);
|
||||
throw error;
|
||||
}
|
||||
if (this.zip === 0) {
|
||||
const error = this.libzip.struct.errorS();
|
||||
this.libzip.error.initWithCode(error, this.libzip.getValue(errPtr, `i32`));
|
||||
throw this.makeLibzipError(error);
|
||||
}
|
||||
} finally {
|
||||
this.libzip.free(errPtr);
|
||||
}
|
||||
const entryCount = this.libzip.getNumEntries(this.zip, 0);
|
||||
const listings = new Array(entryCount);
|
||||
for (let t = 0; t < entryCount; ++t)
|
||||
listings[t] = this.libzip.getName(this.zip, t, 0);
|
||||
this.listings = listings;
|
||||
this.symlinkCount = this.libzip.ext.countSymlinks(this.zip);
|
||||
if (this.symlinkCount === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
getSymlinkCount() {
|
||||
return this.symlinkCount;
|
||||
}
|
||||
getListings() {
|
||||
return this.listings;
|
||||
}
|
||||
stat(entry) {
|
||||
const stat = this.libzip.struct.statS();
|
||||
const rc = this.libzip.statIndex(this.zip, entry, 0, 0, stat);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const size = this.libzip.struct.statSize(stat) >>> 0;
|
||||
const mtime = this.libzip.struct.statMtime(stat) >>> 0;
|
||||
const crc = this.libzip.struct.statCrc(stat) >>> 0;
|
||||
return { size, mtime, crc };
|
||||
}
|
||||
makeLibzipError(error) {
|
||||
const errorCode = this.libzip.struct.errorCodeZip(error);
|
||||
const strerror = this.libzip.error.strerror(error);
|
||||
const libzipError = new LibzipError(strerror, this.libzip.errors[errorCode]);
|
||||
if (errorCode === this.libzip.errors.ZIP_ER_CHANGED)
|
||||
throw new Error(`Assertion failed: Unexpected libzip error: ${libzipError.message}`);
|
||||
return libzipError;
|
||||
}
|
||||
setFileSource(target, compression, buffer) {
|
||||
const lzSource = this.allocateSource(buffer);
|
||||
try {
|
||||
const newIndex = this.libzip.file.add(this.zip, target, lzSource, this.libzip.ZIP_FL_OVERWRITE);
|
||||
if (newIndex === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
if (compression !== null) {
|
||||
const rc = this.libzip.file.setCompression(this.zip, newIndex, 0, compression[0], compression[1]);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
return newIndex;
|
||||
} catch (error) {
|
||||
this.libzip.source.free(lzSource);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
setMtime(entry, mtime) {
|
||||
const rc = this.libzip.file.setMtime(this.zip, entry, 0, mtime, 0);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
getExternalAttributes(index) {
|
||||
const attrs = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S);
|
||||
if (attrs === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0;
|
||||
const attributes = this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 0;
|
||||
return [opsys, attributes];
|
||||
}
|
||||
setExternalAttributes(index, opsys, attributes) {
|
||||
const rc = this.libzip.file.setExternalAttributes(this.zip, index, 0, 0, opsys, attributes);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
locate(name) {
|
||||
return this.libzip.name.locate(this.zip, name, 0);
|
||||
}
|
||||
getFileSource(index) {
|
||||
const stat = this.libzip.struct.statS();
|
||||
const rc = this.libzip.statIndex(this.zip, index, 0, 0, stat);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const size = this.libzip.struct.statCompSize(stat);
|
||||
const compressionMethod = this.libzip.struct.statCompMethod(stat);
|
||||
const buffer = this.libzip.malloc(size);
|
||||
try {
|
||||
const file = this.libzip.fopenIndex(this.zip, index, 0, this.libzip.ZIP_FL_COMPRESSED);
|
||||
if (file === 0)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
try {
|
||||
const rc2 = this.libzip.fread(file, buffer, size, 0);
|
||||
if (rc2 === -1)
|
||||
throw this.makeLibzipError(this.libzip.file.getError(file));
|
||||
else if (rc2 < size)
|
||||
throw new Error(`Incomplete read`);
|
||||
else if (rc2 > size)
|
||||
throw new Error(`Overread`);
|
||||
const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size);
|
||||
const data = Buffer.from(memory);
|
||||
return { data, compressionMethod };
|
||||
} finally {
|
||||
this.libzip.fclose(file);
|
||||
}
|
||||
} finally {
|
||||
this.libzip.free(buffer);
|
||||
}
|
||||
}
|
||||
deleteEntry(index) {
|
||||
const rc = this.libzip.delete(this.zip, index);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
addDirectory(path) {
|
||||
const index = this.libzip.dir.add(this.zip, path);
|
||||
if (index === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
return index;
|
||||
}
|
||||
getBufferAndClose() {
|
||||
try {
|
||||
this.libzip.source.keep(this.lzSource);
|
||||
if (this.libzip.close(this.zip) === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
if (this.libzip.source.open(this.lzSource) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_END) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
const size = this.libzip.source.tell(this.lzSource);
|
||||
if (size === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_SET) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
const buffer = this.libzip.malloc(size);
|
||||
if (!buffer)
|
||||
throw new Error(`Couldn't allocate enough memory`);
|
||||
try {
|
||||
const rc = this.libzip.source.read(this.lzSource, buffer, size);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
else if (rc < size)
|
||||
throw new Error(`Incomplete read`);
|
||||
else if (rc > size)
|
||||
throw new Error(`Overread`);
|
||||
let result = Buffer.from(this.libzip.HEAPU8.subarray(buffer, buffer + size));
|
||||
if (process.env.YARN_IS_TEST_ENV && process.env.YARN_ZIP_DATA_EPILOGUE)
|
||||
result = Buffer.concat([result, Buffer.from(process.env.YARN_ZIP_DATA_EPILOGUE)]);
|
||||
return result;
|
||||
} finally {
|
||||
this.libzip.free(buffer);
|
||||
}
|
||||
} finally {
|
||||
this.libzip.source.close(this.lzSource);
|
||||
this.libzip.source.free(this.lzSource);
|
||||
}
|
||||
}
|
||||
allocateBuffer(content) {
|
||||
if (!Buffer.isBuffer(content))
|
||||
content = Buffer.from(content);
|
||||
const buffer = this.libzip.malloc(content.byteLength);
|
||||
if (!buffer)
|
||||
throw new Error(`Couldn't allocate enough memory`);
|
||||
const heap = new Uint8Array(this.libzip.HEAPU8.buffer, buffer, content.byteLength);
|
||||
heap.set(content);
|
||||
return { buffer, byteLength: content.byteLength };
|
||||
}
|
||||
allocateUnattachedSource(content) {
|
||||
const error = this.libzip.struct.errorS();
|
||||
const { buffer, byteLength } = this.allocateBuffer(content);
|
||||
const source = this.libzip.source.fromUnattachedBuffer(buffer, byteLength, 0, 1, error);
|
||||
if (source === 0) {
|
||||
this.libzip.free(error);
|
||||
throw this.makeLibzipError(error);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
allocateSource(content) {
|
||||
const { buffer, byteLength } = this.allocateBuffer(content);
|
||||
const source = this.libzip.source.fromBuffer(this.zip, buffer, byteLength, 0, 1);
|
||||
if (source === 0) {
|
||||
this.libzip.free(buffer);
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
return source;
|
||||
}
|
||||
discard() {
|
||||
this.libzip.discard(this.zip);
|
||||
}
|
||||
}
|
||||
|
||||
const ZIP_UNIX = 3;
|
||||
const STORE = 0;
|
||||
const DEFLATE = 8;
|
||||
const DEFAULT_COMPRESSION_LEVEL = `mixed`;
|
||||
function toUnixTimestamp(time) {
|
||||
if (typeof time === `string` && String(+time) === time)
|
||||
@ -9177,22 +9410,12 @@ function makeEmptyArchive() {
|
||||
0
|
||||
]);
|
||||
}
|
||||
class LibzipError extends Error {
|
||||
code;
|
||||
constructor(message, code) {
|
||||
super(message);
|
||||
this.name = `Libzip Error`;
|
||||
this.code = code;
|
||||
}
|
||||
}
|
||||
class ZipFS extends BasePortableFakeFS {
|
||||
libzip;
|
||||
baseFs;
|
||||
path;
|
||||
stats;
|
||||
zip;
|
||||
lzSource;
|
||||
level;
|
||||
zipImpl;
|
||||
listings = /* @__PURE__ */ new Map();
|
||||
entries = /* @__PURE__ */ new Map();
|
||||
/**
|
||||
@ -9208,9 +9431,11 @@ class ZipFS extends BasePortableFakeFS {
|
||||
readOnly = false;
|
||||
constructor(source, opts = {}) {
|
||||
super();
|
||||
if (opts.readOnly)
|
||||
this.readOnly = true;
|
||||
const pathOptions = opts;
|
||||
this.level = typeof pathOptions.level !== `undefined` ? pathOptions.level : DEFAULT_COMPRESSION_LEVEL;
|
||||
source ??= makeEmptyArchive();
|
||||
const ZipImplCls = opts.customZipImplementation ?? LibZipImpl;
|
||||
if (typeof source === `string`) {
|
||||
const { baseFs = new NodeFS() } = pathOptions;
|
||||
this.baseFs = baseFs;
|
||||
@ -9236,36 +9461,19 @@ class ZipFS extends BasePortableFakeFS {
|
||||
this.stats = makeDefaultStats();
|
||||
}
|
||||
}
|
||||
this.libzip = getInstance();
|
||||
const errPtr = this.libzip.malloc(4);
|
||||
try {
|
||||
let flags = 0;
|
||||
if (opts.readOnly) {
|
||||
flags |= this.libzip.ZIP_RDONLY;
|
||||
this.readOnly = true;
|
||||
if (typeof source === `string`) {
|
||||
if (opts.create) {
|
||||
this.zipImpl = new ZipImplCls({ buffer: makeEmptyArchive(), readOnly: this.readOnly });
|
||||
} else {
|
||||
this.zipImpl = new ZipImplCls({ path: source, baseFs: this.baseFs, readOnly: this.readOnly, size: this.stats.size });
|
||||
}
|
||||
if (typeof source === `string`)
|
||||
source = pathOptions.create ? makeEmptyArchive() : this.baseFs.readFileSync(source);
|
||||
const lzSource = this.allocateUnattachedSource(source);
|
||||
try {
|
||||
this.zip = this.libzip.openFromSource(lzSource, flags, errPtr);
|
||||
this.lzSource = lzSource;
|
||||
} catch (error) {
|
||||
this.libzip.source.free(lzSource);
|
||||
throw error;
|
||||
}
|
||||
if (this.zip === 0) {
|
||||
const error = this.libzip.struct.errorS();
|
||||
this.libzip.error.initWithCode(error, this.libzip.getValue(errPtr, `i32`));
|
||||
throw this.makeLibzipError(error);
|
||||
}
|
||||
} finally {
|
||||
this.libzip.free(errPtr);
|
||||
} else {
|
||||
this.zipImpl = new ZipImplCls({ buffer: source ?? makeEmptyArchive(), readOnly: this.readOnly });
|
||||
}
|
||||
this.listings.set(PortablePath.root, /* @__PURE__ */ new Set());
|
||||
const entryCount = this.libzip.getNumEntries(this.zip, 0);
|
||||
for (let t = 0; t < entryCount; ++t) {
|
||||
const raw = this.libzip.getName(this.zip, t, 0);
|
||||
const listings = this.zipImpl.getListings();
|
||||
for (let t = 0; t < listings.length; t++) {
|
||||
const raw = listings[t];
|
||||
if (ppath.isAbsolute(raw))
|
||||
continue;
|
||||
const p = ppath.resolve(PortablePath.root, raw);
|
||||
@ -9274,19 +9482,9 @@ class ZipFS extends BasePortableFakeFS {
|
||||
this.registerListing(p);
|
||||
}
|
||||
}
|
||||
this.symlinkCount = this.libzip.ext.countSymlinks(this.zip);
|
||||
if (this.symlinkCount === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
this.symlinkCount = this.zipImpl.getSymlinkCount();
|
||||
this.ready = true;
|
||||
}
|
||||
makeLibzipError(error) {
|
||||
const errorCode = this.libzip.struct.errorCodeZip(error);
|
||||
const strerror = this.libzip.error.strerror(error);
|
||||
const libzipError = new LibzipError(strerror, this.libzip.errors[errorCode]);
|
||||
if (errorCode === this.libzip.errors.ZIP_ER_CHANGED)
|
||||
throw new Error(`Assertion failed: Unexpected libzip error: ${libzipError.message}`);
|
||||
return libzipError;
|
||||
}
|
||||
getExtractHint(hints) {
|
||||
for (const fileName of this.entries.keys()) {
|
||||
const ext = this.pathUtils.extname(fileName);
|
||||
@ -9316,45 +9514,14 @@ class ZipFS extends BasePortableFakeFS {
|
||||
return makeEmptyArchive();
|
||||
}
|
||||
try {
|
||||
this.libzip.source.keep(this.lzSource);
|
||||
if (this.libzip.close(this.zip) === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
if (this.libzip.source.open(this.lzSource) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_END) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
const size = this.libzip.source.tell(this.lzSource);
|
||||
if (size === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
if (this.libzip.source.seek(this.lzSource, 0, 0, this.libzip.SEEK_SET) === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
const buffer = this.libzip.malloc(size);
|
||||
if (!buffer)
|
||||
throw new Error(`Couldn't allocate enough memory`);
|
||||
try {
|
||||
const rc = this.libzip.source.read(this.lzSource, buffer, size);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.source.error(this.lzSource));
|
||||
else if (rc < size)
|
||||
throw new Error(`Incomplete read`);
|
||||
else if (rc > size)
|
||||
throw new Error(`Overread`);
|
||||
let result = Buffer.from(this.libzip.HEAPU8.subarray(buffer, buffer + size));
|
||||
if (process.env.YARN_IS_TEST_ENV && process.env.YARN_ZIP_DATA_EPILOGUE)
|
||||
result = Buffer.concat([result, Buffer.from(process.env.YARN_ZIP_DATA_EPILOGUE)]);
|
||||
return result;
|
||||
} finally {
|
||||
this.libzip.free(buffer);
|
||||
}
|
||||
return this.zipImpl.getBufferAndClose();
|
||||
} finally {
|
||||
this.libzip.source.close(this.lzSource);
|
||||
this.libzip.source.free(this.lzSource);
|
||||
this.ready = false;
|
||||
}
|
||||
}
|
||||
discardAndClose() {
|
||||
this.prepareClose();
|
||||
this.libzip.discard(this.zip);
|
||||
this.zipImpl.discard();
|
||||
this.ready = false;
|
||||
}
|
||||
saveAndClose() {
|
||||
@ -9608,16 +9775,14 @@ class ZipFS extends BasePortableFakeFS {
|
||||
statImpl(reason, p, opts = {}) {
|
||||
const entry = this.entries.get(p);
|
||||
if (typeof entry !== `undefined`) {
|
||||
const stat = this.libzip.struct.statS();
|
||||
const rc = this.libzip.statIndex(this.zip, entry, 0, 0, stat);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const stat = this.zipImpl.stat(entry);
|
||||
const crc = stat.crc;
|
||||
const size = stat.size;
|
||||
const mtimeMs = stat.mtime * 1e3;
|
||||
const uid = this.stats.uid;
|
||||
const gid = this.stats.gid;
|
||||
const size = this.libzip.struct.statSize(stat) >>> 0;
|
||||
const blksize = 512;
|
||||
const blocks = Math.ceil(size / blksize);
|
||||
const mtimeMs = (this.libzip.struct.statMtime(stat) >>> 0) * 1e3;
|
||||
const blocks = Math.ceil(stat.size / blksize);
|
||||
const atimeMs = mtimeMs;
|
||||
const birthtimeMs = mtimeMs;
|
||||
const ctimeMs = mtimeMs;
|
||||
@ -9628,7 +9793,6 @@ class ZipFS extends BasePortableFakeFS {
|
||||
const type = this.listings.has(p) ? fs.constants.S_IFDIR : this.isSymbolicLink(entry) ? fs.constants.S_IFLNK : fs.constants.S_IFREG;
|
||||
const defaultMode = type === fs.constants.S_IFDIR ? 493 : 420;
|
||||
const mode = type | this.getUnixMode(entry, defaultMode) & 511;
|
||||
const crc = this.libzip.struct.statCrc(stat);
|
||||
const statInstance = Object.assign(new StatEntry(), { uid, gid, size, blksize, blocks, atime, birthtime, ctime, mtime, atimeMs, birthtimeMs, ctimeMs, mtimeMs, mode, crc });
|
||||
return opts.bigint === true ? convertToBigIntStats(statInstance) : statInstance;
|
||||
}
|
||||
@ -9654,13 +9818,10 @@ class ZipFS extends BasePortableFakeFS {
|
||||
throw new Error(`Unreachable`);
|
||||
}
|
||||
getUnixMode(index, defaultMode) {
|
||||
const rc = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0;
|
||||
if (opsys !== this.libzip.ZIP_OPSYS_UNIX)
|
||||
const [opsys, attributes] = this.zipImpl.getExternalAttributes(index);
|
||||
if (opsys !== ZIP_UNIX)
|
||||
return defaultMode;
|
||||
return this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16;
|
||||
return attributes >>> 16;
|
||||
}
|
||||
registerListing(p) {
|
||||
const existingListing = this.listings.get(p);
|
||||
@ -9695,10 +9856,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
}
|
||||
deleteEntry(p, index) {
|
||||
this.unregisterEntry(p);
|
||||
const rc = this.libzip.delete(this.zip, index);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
this.zipImpl.deleteEntry(index);
|
||||
}
|
||||
resolveFilename(reason, p, resolveLastComponent = true, throwIfNoEntry = true) {
|
||||
if (!this.ready)
|
||||
@ -9731,7 +9889,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
resolvedP = ppath.resolve(parentP, ppath.basename(resolvedP));
|
||||
if (!resolveLastComponent || this.symlinkCount === 0)
|
||||
break;
|
||||
const index = this.libzip.name.locate(this.zip, resolvedP.slice(1), 0);
|
||||
const index = this.zipImpl.locate(resolvedP.slice(1));
|
||||
if (index === -1)
|
||||
break;
|
||||
if (this.isSymbolicLink(index)) {
|
||||
@ -9743,118 +9901,57 @@ class ZipFS extends BasePortableFakeFS {
|
||||
}
|
||||
return resolvedP;
|
||||
}
|
||||
allocateBuffer(content) {
|
||||
if (!Buffer.isBuffer(content))
|
||||
content = Buffer.from(content);
|
||||
const buffer = this.libzip.malloc(content.byteLength);
|
||||
if (!buffer)
|
||||
throw new Error(`Couldn't allocate enough memory`);
|
||||
const heap = new Uint8Array(this.libzip.HEAPU8.buffer, buffer, content.byteLength);
|
||||
heap.set(content);
|
||||
return { buffer, byteLength: content.byteLength };
|
||||
}
|
||||
allocateUnattachedSource(content) {
|
||||
const error = this.libzip.struct.errorS();
|
||||
const { buffer, byteLength } = this.allocateBuffer(content);
|
||||
const source = this.libzip.source.fromUnattachedBuffer(buffer, byteLength, 0, 1, error);
|
||||
if (source === 0) {
|
||||
this.libzip.free(error);
|
||||
throw this.makeLibzipError(error);
|
||||
}
|
||||
return source;
|
||||
}
|
||||
allocateSource(content) {
|
||||
const { buffer, byteLength } = this.allocateBuffer(content);
|
||||
const source = this.libzip.source.fromBuffer(this.zip, buffer, byteLength, 0, 1);
|
||||
if (source === 0) {
|
||||
this.libzip.free(buffer);
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
return source;
|
||||
}
|
||||
setFileSource(p, content) {
|
||||
const buffer = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
||||
const target = ppath.relative(PortablePath.root, p);
|
||||
const lzSource = this.allocateSource(content);
|
||||
try {
|
||||
const newIndex = this.libzip.file.add(this.zip, target, lzSource, this.libzip.ZIP_FL_OVERWRITE);
|
||||
if (newIndex === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
if (this.level !== `mixed`) {
|
||||
const method = this.level === 0 ? this.libzip.ZIP_CM_STORE : this.libzip.ZIP_CM_DEFLATE;
|
||||
const rc = this.libzip.file.setCompression(this.zip, newIndex, 0, method, this.level);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
}
|
||||
this.fileSources.set(newIndex, buffer);
|
||||
return newIndex;
|
||||
} catch (error) {
|
||||
this.libzip.source.free(lzSource);
|
||||
throw error;
|
||||
let compression = null;
|
||||
if (this.level !== `mixed`) {
|
||||
const method = this.level === 0 ? STORE : DEFLATE;
|
||||
compression = [method, this.level];
|
||||
}
|
||||
const newIndex = this.zipImpl.setFileSource(target, compression, buffer);
|
||||
this.fileSources.set(newIndex, buffer);
|
||||
return newIndex;
|
||||
}
|
||||
isSymbolicLink(index) {
|
||||
if (this.symlinkCount === 0)
|
||||
return false;
|
||||
const attrs = this.libzip.file.getExternalAttributes(this.zip, index, 0, 0, this.libzip.uint08S, this.libzip.uint32S);
|
||||
if (attrs === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const opsys = this.libzip.getValue(this.libzip.uint08S, `i8`) >>> 0;
|
||||
if (opsys !== this.libzip.ZIP_OPSYS_UNIX)
|
||||
const [opsys, attrs] = this.zipImpl.getExternalAttributes(index);
|
||||
if (opsys !== ZIP_UNIX)
|
||||
return false;
|
||||
const attributes = this.libzip.getValue(this.libzip.uint32S, `i32`) >>> 16;
|
||||
const attributes = attrs >>> 16;
|
||||
return (attributes & fs.constants.S_IFMT) === fs.constants.S_IFLNK;
|
||||
}
|
||||
getFileSource(index, opts = { asyncDecompress: false }) {
|
||||
const cachedFileSource = this.fileSources.get(index);
|
||||
if (typeof cachedFileSource !== `undefined`)
|
||||
return cachedFileSource;
|
||||
const stat = this.libzip.struct.statS();
|
||||
const rc = this.libzip.statIndex(this.zip, index, 0, 0, stat);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const size = this.libzip.struct.statCompSize(stat);
|
||||
const compressionMethod = this.libzip.struct.statCompMethod(stat);
|
||||
const buffer = this.libzip.malloc(size);
|
||||
try {
|
||||
const file = this.libzip.fopenIndex(this.zip, index, 0, this.libzip.ZIP_FL_COMPRESSED);
|
||||
if (file === 0)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
try {
|
||||
const rc2 = this.libzip.fread(file, buffer, size, 0);
|
||||
if (rc2 === -1)
|
||||
throw this.makeLibzipError(this.libzip.file.getError(file));
|
||||
else if (rc2 < size)
|
||||
throw new Error(`Incomplete read`);
|
||||
else if (rc2 > size)
|
||||
throw new Error(`Overread`);
|
||||
const memory = this.libzip.HEAPU8.subarray(buffer, buffer + size);
|
||||
const data = Buffer.from(memory);
|
||||
if (compressionMethod === 0) {
|
||||
this.fileSources.set(index, data);
|
||||
return data;
|
||||
} else if (opts.asyncDecompress) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zlib__default.default.inflateRaw(data, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
const { data, compressionMethod } = this.zipImpl.getFileSource(index);
|
||||
if (compressionMethod === STORE) {
|
||||
if (this.zipImpl.filesShouldBeCached)
|
||||
this.fileSources.set(index, data);
|
||||
return data;
|
||||
} else if (compressionMethod === DEFLATE) {
|
||||
if (opts.asyncDecompress) {
|
||||
return new Promise((resolve, reject) => {
|
||||
zlib__default.default.inflateRaw(data, (error, result) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
if (this.zipImpl.filesShouldBeCached)
|
||||
this.fileSources.set(index, result);
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
resolve(result);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
const decompressedData = zlib__default.default.inflateRawSync(data);
|
||||
});
|
||||
} else {
|
||||
const decompressedData = zlib__default.default.inflateRawSync(data);
|
||||
if (this.zipImpl.filesShouldBeCached)
|
||||
this.fileSources.set(index, decompressedData);
|
||||
return decompressedData;
|
||||
}
|
||||
} finally {
|
||||
this.libzip.fclose(file);
|
||||
return decompressedData;
|
||||
}
|
||||
} finally {
|
||||
this.libzip.free(buffer);
|
||||
} else {
|
||||
throw new Error(`Unsupported compression method: ${compressionMethod}`);
|
||||
}
|
||||
}
|
||||
async fchmodPromise(fd, mask) {
|
||||
@ -9876,10 +9973,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
throw new Error(`Assertion failed: The entry should have been registered (${resolvedP})`);
|
||||
const oldMod = this.getUnixMode(entry, fs.constants.S_IFREG | 0);
|
||||
const newMod = oldMod & ~511 | mask;
|
||||
const rc = this.libzip.file.setExternalAttributes(this.zip, entry, 0, 0, this.libzip.ZIP_OPSYS_UNIX, newMod << 16);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
this.zipImpl.setExternalAttributes(entry, ZIP_UNIX, newMod << 16);
|
||||
}
|
||||
async fchownPromise(fd, uid, gid) {
|
||||
return this.chownPromise(this.fdToPath(fd, `fchown`), uid, gid);
|
||||
@ -10053,10 +10147,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
const entry = this.entries.get(resolvedP);
|
||||
if (entry === void 0)
|
||||
throw new Error(`Unreachable`);
|
||||
const rc = this.libzip.file.setMtime(this.zip, entry, 0, toUnixTimestamp(mtime), 0);
|
||||
if (rc === -1) {
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
}
|
||||
this.zipImpl.setMtime(entry, toUnixTimestamp(mtime));
|
||||
}
|
||||
async mkdirPromise(p, opts) {
|
||||
return this.mkdirSync(p, opts);
|
||||
@ -10116,9 +10207,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
this.deleteEntry(p, index);
|
||||
}
|
||||
hydrateDirectory(resolvedP) {
|
||||
const index = this.libzip.dir.add(this.zip, ppath.relative(PortablePath.root, resolvedP));
|
||||
if (index === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
const index = this.zipImpl.addDirectory(ppath.relative(PortablePath.root, resolvedP));
|
||||
this.registerListing(resolvedP);
|
||||
this.registerEntry(resolvedP, index);
|
||||
return index;
|
||||
@ -10142,9 +10231,7 @@ class ZipFS extends BasePortableFakeFS {
|
||||
throw EEXIST(`symlink '${target}' -> '${p}'`);
|
||||
const index = this.setFileSource(resolvedP, target);
|
||||
this.registerEntry(resolvedP, index);
|
||||
const rc = this.libzip.file.setExternalAttributes(this.zip, index, 0, 0, this.libzip.ZIP_OPSYS_UNIX, (fs.constants.S_IFLNK | 511) << 16);
|
||||
if (rc === -1)
|
||||
throw this.makeLibzipError(this.libzip.getError(this.zip));
|
||||
this.zipImpl.setExternalAttributes(index, ZIP_UNIX, (fs.constants.S_IFLNK | 511) << 16);
|
||||
this.symlinkCount += 1;
|
||||
}
|
||||
async readFilePromise(p, encoding) {
|
||||
@ -10299,10 +10386,13 @@ class ZipFS extends BasePortableFakeFS {
|
||||
} };
|
||||
const interval = setInterval(() => {
|
||||
}, 24 * 60 * 60 * 1e3);
|
||||
return { on: () => {
|
||||
}, close: () => {
|
||||
clearInterval(interval);
|
||||
} };
|
||||
return {
|
||||
on: () => {
|
||||
},
|
||||
close: () => {
|
||||
clearInterval(interval);
|
||||
}
|
||||
};
|
||||
}
|
||||
watchFile(p, a, b) {
|
||||
const resolvedP = ppath.resolve(PortablePath.root, p);
|
||||
@ -10314,6 +10404,201 @@ class ZipFS extends BasePortableFakeFS {
|
||||
}
|
||||
}
|
||||
|
||||
const SIGNATURE = {
|
||||
CENTRAL_DIRECTORY: 33639248,
|
||||
END_OF_CENTRAL_DIRECTORY: 101010256
|
||||
};
|
||||
const noCommentCDSize = 22;
|
||||
class JsZipImpl {
|
||||
fd;
|
||||
baseFs;
|
||||
entries;
|
||||
filesShouldBeCached = false;
|
||||
constructor(opts) {
|
||||
if (`buffer` in opts)
|
||||
throw new Error(`Buffer based zip archives are not supported`);
|
||||
if (!opts.readOnly)
|
||||
throw new Error(`Writable zip archives are not supported`);
|
||||
this.baseFs = opts.baseFs;
|
||||
this.fd = this.baseFs.openSync(opts.path, `r`);
|
||||
try {
|
||||
this.entries = JsZipImpl.readZipSync(this.fd, this.baseFs, opts.size);
|
||||
} catch (error) {
|
||||
this.baseFs.closeSync(this.fd);
|
||||
this.fd = `closed`;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
static readZipSync(fd, baseFs, fileSize) {
|
||||
if (fileSize < noCommentCDSize)
|
||||
throw new Error(`Invalid ZIP file: EOCD not found`);
|
||||
let eocdOffset = -1;
|
||||
let eocdBuffer = Buffer.alloc(noCommentCDSize);
|
||||
baseFs.readSync(
|
||||
fd,
|
||||
eocdBuffer,
|
||||
0,
|
||||
noCommentCDSize,
|
||||
fileSize - noCommentCDSize
|
||||
);
|
||||
if (eocdBuffer.readUInt32LE(0) === SIGNATURE.END_OF_CENTRAL_DIRECTORY) {
|
||||
eocdOffset = 0;
|
||||
} else {
|
||||
const bufferSize = Math.min(65557, fileSize);
|
||||
eocdBuffer = Buffer.alloc(bufferSize);
|
||||
baseFs.readSync(
|
||||
fd,
|
||||
eocdBuffer,
|
||||
0,
|
||||
bufferSize,
|
||||
Math.max(0, fileSize - bufferSize)
|
||||
);
|
||||
for (let i = eocdBuffer.length - 4; i >= 0; i--) {
|
||||
if (eocdBuffer.readUInt32LE(i) === SIGNATURE.END_OF_CENTRAL_DIRECTORY) {
|
||||
eocdOffset = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (eocdOffset === -1) {
|
||||
throw new Error(`Not a zip archive`);
|
||||
}
|
||||
}
|
||||
const totalEntries = eocdBuffer.readUInt16LE(eocdOffset + 10);
|
||||
const centralDirSize = eocdBuffer.readUInt32LE(eocdOffset + 12);
|
||||
const centralDirOffset = eocdBuffer.readUInt32LE(eocdOffset + 16);
|
||||
const commentLength = eocdBuffer.readUInt16LE(eocdOffset + 20);
|
||||
if (eocdOffset + commentLength + noCommentCDSize > eocdBuffer.length)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
if (totalEntries == 65535 || centralDirSize == 4294967295 || centralDirOffset == 4294967295)
|
||||
throw new Error(`Zip 64 is not supported`);
|
||||
if (centralDirSize > fileSize)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
if (totalEntries > centralDirSize / 46)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
const cdBuffer = Buffer.alloc(centralDirSize);
|
||||
if (baseFs.readSync(fd, cdBuffer, 0, cdBuffer.length, centralDirOffset) !== cdBuffer.length)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
const entries = [];
|
||||
let offset = 0;
|
||||
let index = 0;
|
||||
let sumCompressedSize = 0;
|
||||
while (index < totalEntries) {
|
||||
if (offset + 46 > cdBuffer.length)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
if (cdBuffer.readUInt32LE(offset) !== SIGNATURE.CENTRAL_DIRECTORY)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
const versionMadeBy = cdBuffer.readUInt16LE(offset + 4);
|
||||
const os = versionMadeBy >>> 8;
|
||||
const flags = cdBuffer.readUInt16LE(offset + 8);
|
||||
if ((flags & 1) !== 0)
|
||||
throw new Error(`Encrypted zip files are not supported`);
|
||||
const compressionMethod = cdBuffer.readUInt16LE(offset + 10);
|
||||
const crc = cdBuffer.readUInt32LE(offset + 16);
|
||||
const nameLength = cdBuffer.readUInt16LE(offset + 28);
|
||||
const extraLength = cdBuffer.readUInt16LE(offset + 30);
|
||||
const commentLength2 = cdBuffer.readUInt16LE(offset + 32);
|
||||
const localHeaderOffset = cdBuffer.readUInt32LE(offset + 42);
|
||||
const name = cdBuffer.toString(`utf8`, offset + 46, offset + 46 + nameLength).replaceAll(`\0`, ` `);
|
||||
if (name.includes(`\0`))
|
||||
throw new Error(`Invalid ZIP file`);
|
||||
const compressedSize = cdBuffer.readUInt32LE(offset + 20);
|
||||
const externalAttributes = cdBuffer.readUInt32LE(offset + 38);
|
||||
entries.push({
|
||||
name,
|
||||
os,
|
||||
mtime: SAFE_TIME,
|
||||
//we dont care,
|
||||
crc,
|
||||
compressionMethod,
|
||||
isSymbolicLink: os === ZIP_UNIX && (externalAttributes >>> 16 & S_IFMT) === S_IFLNK,
|
||||
size: cdBuffer.readUInt32LE(offset + 24),
|
||||
compressedSize,
|
||||
externalAttributes,
|
||||
localHeaderOffset
|
||||
});
|
||||
sumCompressedSize += compressedSize;
|
||||
index += 1;
|
||||
offset += 46 + nameLength + extraLength + commentLength2;
|
||||
}
|
||||
if (sumCompressedSize > fileSize)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
if (offset !== cdBuffer.length)
|
||||
throw new Error(`Zip archive inconsistent`);
|
||||
return entries;
|
||||
}
|
||||
getExternalAttributes(index) {
|
||||
const entry = this.entries[index];
|
||||
return [entry.os, entry.externalAttributes];
|
||||
}
|
||||
getListings() {
|
||||
return this.entries.map((e) => e.name);
|
||||
}
|
||||
getSymlinkCount() {
|
||||
let count = 0;
|
||||
for (const entry of this.entries)
|
||||
if (entry.isSymbolicLink)
|
||||
count += 1;
|
||||
return count;
|
||||
}
|
||||
stat(index) {
|
||||
const entry = this.entries[index];
|
||||
return {
|
||||
crc: entry.crc,
|
||||
mtime: entry.mtime,
|
||||
size: entry.size
|
||||
};
|
||||
}
|
||||
locate(name) {
|
||||
for (let ind = 0; ind < this.entries.length; ind++)
|
||||
if (this.entries[ind].name === name)
|
||||
return ind;
|
||||
return -1;
|
||||
}
|
||||
getFileSource(index) {
|
||||
if (this.fd === `closed`)
|
||||
throw new Error(`ZIP file is closed`);
|
||||
const entry = this.entries[index];
|
||||
const localHeaderBuf = Buffer.alloc(30);
|
||||
this.baseFs.readSync(
|
||||
this.fd,
|
||||
localHeaderBuf,
|
||||
0,
|
||||
localHeaderBuf.length,
|
||||
entry.localHeaderOffset
|
||||
);
|
||||
const nameLength = localHeaderBuf.readUInt16LE(26);
|
||||
const extraLength = localHeaderBuf.readUInt16LE(28);
|
||||
const buffer = Buffer.alloc(entry.compressedSize);
|
||||
if (this.baseFs.readSync(this.fd, buffer, 0, entry.compressedSize, entry.localHeaderOffset + 30 + nameLength + extraLength) !== entry.compressedSize)
|
||||
throw new Error(`Invalid ZIP file`);
|
||||
return { data: buffer, compressionMethod: entry.compressionMethod };
|
||||
}
|
||||
discard() {
|
||||
if (this.fd !== `closed`) {
|
||||
this.baseFs.closeSync(this.fd);
|
||||
this.fd = `closed`;
|
||||
}
|
||||
}
|
||||
addDirectory(path) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
deleteEntry(index) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
setMtime(index, mtime) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
getBufferAndClose() {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
setFileSource(target, compression, buffer) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
setExternalAttributes(index, opsys, attributes) {
|
||||
throw new Error(`Not implemented`);
|
||||
}
|
||||
}
|
||||
|
||||
setFactory(() => {
|
||||
const emZip = createModule();
|
||||
return makeInterface(emZip);
|
||||
@ -10664,6 +10949,7 @@ function hydrateRuntimeState(data, { basePath }) {
|
||||
dependencyTreeRoots,
|
||||
enableTopLevelFallback,
|
||||
fallbackExclusionList,
|
||||
pnpZipBackend: data.pnpZipBackend,
|
||||
fallbackPool,
|
||||
ignorePattern,
|
||||
packageLocatorsByLocations,
|
||||
@ -12320,8 +12606,10 @@ const localFs = { ...fs__default.default };
|
||||
const nodeFs = new NodeFS(localFs);
|
||||
const defaultRuntimeState = $$SETUP_STATE(hydrateRuntimeState);
|
||||
const defaultPnpapiResolution = __filename;
|
||||
const customZipImplementation = defaultRuntimeState.pnpZipBackend === `js` ? JsZipImpl : void 0;
|
||||
const defaultFsLayer = new VirtualFS({
|
||||
baseFs: new ZipOpenFS({
|
||||
customZipImplementation,
|
||||
baseFs: nodeFs,
|
||||
maxOpenFiles: 80,
|
||||
readOnlyArchives: true
|
||||
|
935
.yarn/releases/yarn-4.8.1.cjs
vendored
935
.yarn/releases/yarn-4.8.1.cjs
vendored
File diff suppressed because one or more lines are too long
948
.yarn/releases/yarn-4.9.1.cjs
vendored
Executable file
948
.yarn/releases/yarn-4.9.1.cjs
vendored
Executable file
File diff suppressed because one or more lines are too long
@ -3,4 +3,4 @@ plugins:
|
||||
path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
|
||||
spec: "https://go.mskelton.dev/yarn-outdated/v4"
|
||||
|
||||
yarnPath: .yarn/releases/yarn-4.8.1.cjs
|
||||
yarnPath: .yarn/releases/yarn-4.9.1.cjs
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clean-architecture",
|
||||
"packageManager": "yarn@4.8.1",
|
||||
"packageManager": "yarn@4.9.1",
|
||||
"dependencies": {
|
||||
"@types/jest": "^29.5.13",
|
||||
"@types/node": "^22.7.5",
|
||||
|
Loading…
x
Reference in New Issue
Block a user