Compare commits

..

2 Commits

Author SHA1 Message Date
ce3b285d1a fix(deps): update dependency @types/node to v22.15.3
All checks were successful
continuous-integration/drone/pr Build is passing
2025-04-30 18:22:04 +00:00
697cd354f6 chore(deps): update yarn to v4.9.1 (#96)
All checks were successful
continuous-integration/drone/push Build is passing
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [yarn](https://github.com/yarnpkg/berry) ([source](https://github.com/yarnpkg/berry/tree/HEAD/packages/yarnpkg-cli)) | packageManager | minor | [`4.8.1` -> `4.9.1`](https://renovatebot.com/diffs/npm/yarn/4.8.1/4.9.1) |

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzOS4xODguMyIsInVwZGF0ZWRJblZlciI6IjM5LjE4OC4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Reviewed-on: #96
Co-authored-by: renovate-bot <renovate-bot@dubas.dev>
Co-committed-by: renovate-bot <renovate-bot@dubas.dev>
2025-04-30 17:54:36 +00:00
5 changed files with 1453 additions and 1152 deletions

718
.pnp.cjs generated
View File

@ -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

File diff suppressed because one or more lines are too long

948
.yarn/releases/yarn-4.9.1.cjs vendored Executable file

File diff suppressed because one or more lines are too long

View File

@ -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

View File

@ -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",