Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@yarnpkg/fslib

Package Overview
Dependencies
Maintainers
6
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@yarnpkg/fslib - npm Package Compare versions

Comparing version 3.0.0-rc.15 to 3.0.0-rc.16

lib/MountFS.d.ts

2

lib/FakeFS.d.ts

@@ -214,2 +214,4 @@ /// <reference types="node" />

abstract fchmodSync(fd: number, mask: number): void;
abstract fchownPromise(fd: number, uid: number, gid: number): Promise<void>;
abstract fchownSync(fd: number, uid: number, gid: number): void;
abstract chownPromise(p: P, uid: number, gid: number): Promise<void>;

@@ -216,0 +218,0 @@ abstract chownSync(p: P, uid: number, gid: number): void;

@@ -106,2 +106,4 @@ /// <reference types="node" />

chmodSync(p: PortablePath, mask: number): void;
fchownPromise(fd: number, uid: number, gid: number): Promise<void>;
fchownSync(fd: number, uid: number, gid: number): void;
chownPromise(p: PortablePath, uid: number, gid: number): Promise<void>;

@@ -108,0 +110,0 @@ chownSync(p: PortablePath, uid: number, gid: number): void;

@@ -198,2 +198,10 @@ "use strict";

}
async fchownPromise(fd, uid, gid) {
return await new Promise((resolve, reject) => {
this.realFs.fchown(fd, uid, gid, this.makeCallback(resolve, reject));
});
}
fchownSync(fd, uid, gid) {
return this.realFs.fchownSync(fd, uid, gid);
}
async chownPromise(p, uid, gid) {

@@ -200,0 +208,0 @@ return await new Promise((resolve, reject) => {

@@ -39,2 +39,4 @@ import { FakeFS } from './FakeFS';

chmodSync(): never;
fchownPromise(): Promise<never>;
fchownSync(): never;
chownPromise(): Promise<never>;

@@ -41,0 +43,0 @@ chownSync(): never;

@@ -110,2 +110,8 @@ "use strict";

}
async fchownPromise() {
throw makeError();
}
fchownSync() {
throw makeError();
}
async chownPromise() {

@@ -112,0 +118,0 @@ throw makeError();

11

lib/patchFs/FileHandle.js

@@ -36,5 +36,10 @@ "use strict";

}
// FIXME: Missing FakeFS version
chown(uid, gid) {
throw new Error(`Method not implemented.`);
async chown(uid, gid) {
try {
this[kRef](this.chown);
return await this[kBaseFs].fchownPromise(this.fd, uid, gid);
}
finally {
this[kUnref]();
}
}

@@ -41,0 +46,0 @@ async chmod(mode) {

@@ -15,2 +15,3 @@ "use strict";

`chownSync`,
`fchownSync`,
`closeSync`,

@@ -49,2 +50,3 @@ `copyFileSync`,

`chmodPromise`,
`fchownPromise`,
`chownPromise`,

@@ -51,0 +53,0 @@ `closePromise`,

@@ -112,2 +112,4 @@ /// <reference types="node" />

chmodSync(p: P, mask: number): void;
fchownPromise(fd: number, uid: number, gid: number): Promise<void>;
fchownSync(fd: number, uid: number, gid: number): void;
chownPromise(p: P, uid: number, gid: number): Promise<void>;

@@ -114,0 +116,0 @@ chownSync(p: P, uid: number, gid: number): void;

@@ -109,2 +109,8 @@ "use strict";

}
async fchownPromise(fd, uid, gid) {
return this.baseFs.fchownPromise(fd, uid, gid);
}
fchownSync(fd, uid, gid) {
return this.baseFs.fchownSync(fd, uid, gid);
}
async chownPromise(p, uid, gid) {

@@ -111,0 +117,0 @@ return this.baseFs.chownPromise(this.mapToBase(p), uid, gid);

@@ -170,2 +170,4 @@ /// <reference types="node" />

chmodSync(p: PortablePath, mask: number): void;
fchownPromise(fd: number, uid: number, gid: number): Promise<void>;
fchownSync(fd: number, uid: number, gid: number): void;
chownPromise(p: PortablePath, uid: number, gid: number): Promise<void>;

@@ -172,0 +174,0 @@ chownSync(p: PortablePath, uid: number, gid: number): void;

@@ -793,2 +793,8 @@ "use strict";

}
async fchownPromise(fd, uid, gid) {
return this.chownPromise(this.fdToPath(fd, `fchown`), uid, gid);
}
fchownSync(fd, uid, gid) {
return this.chownSync(this.fdToPath(fd, `fchownSync`), uid, gid);
}
async chownPromise(p, uid, gid) {

@@ -795,0 +801,0 @@ return this.chownSync(p, uid, gid);

@@ -1,11 +0,5 @@

/// <reference types="node" />
/// <reference types="node" />
/// <reference types="node" />
import { Libzip } from '@yarnpkg/libzip';
import { BigIntStats, Stats } from 'fs';
import { WatchOptions, WatchCallback, Watcher, StatOptions, StatSyncOptions } from './FakeFS';
import { FakeFS, MkdirOptions, RmdirOptions, WriteFileOptions, OpendirOptions } from './FakeFS';
import { Dirent, SymlinkType } from './FakeFS';
import { CreateReadStreamOptions, CreateWriteStreamOptions, BasePortableFakeFS, ExtractHintOptions, WatchFileOptions, WatchFileCallback, StatWatcher } from './FakeFS';
import { Filename, FSPath, PortablePath } from './path';
import { MountFS, MountFSOptions } from './MountFS';
import { ZipFS } from './ZipFS';
import { PortablePath } from './path';
/**

@@ -16,16 +10,7 @@ * Extracts the archive part (ending in the first instance of `extension`) from a path.

*/
export declare const getArchivePart: (path: string, extension: string) => PortablePath | null;
export declare type ZipOpenFSOptions = {
baseFs?: FakeFS<PortablePath>;
filter?: RegExp | null;
export declare function getArchivePart(path: string, extension: string): PortablePath | null;
export declare type ZipOpenFSOptions = Omit<MountFSOptions<ZipFS>, `factoryPromise` | `factorySync` | `getMountPoint`> & {
libzip: Libzip | (() => Libzip);
maxOpenFiles?: number;
readOnlyArchives?: boolean;
useCache?: boolean;
/**
* Maximum age in ms.
* ZipFS instances are pruned from the cache if they aren't accessed within this amount of time.
*/
maxAge?: number;
/**
* Which file extensions will be interpreted as zip files. Useful for supporting other formats

@@ -38,183 +23,5 @@ * packaged as zips, such as .docx.

};
export declare class ZipOpenFS extends BasePortableFakeFS {
export declare class ZipOpenFS extends MountFS<ZipFS> {
static openPromise<T>(fn: (zipOpenFs: ZipOpenFS) => Promise<T>, opts: ZipOpenFSOptions): Promise<T>;
private libzipFactory;
private libzipInstance?;
private get libzip();
private readonly baseFs;
private readonly zipInstances;
private readonly fdMap;
private nextFd;
private readonly filter;
private readonly maxOpenFiles;
private readonly maxAge;
private readonly readOnlyArchives;
private readonly fileExtensions;
private isZip;
private notZip;
private realPaths;
constructor({ libzip, baseFs, filter, maxOpenFiles, readOnlyArchives, useCache, maxAge, fileExtensions }: ZipOpenFSOptions);
getExtractHint(hints: ExtractHintOptions): boolean;
getRealPath(): PortablePath;
saveAndClose(): void;
discardAndClose(): void;
resolve(p: PortablePath): PortablePath;
private remapFd;
openPromise(p: PortablePath, flags: string, mode?: number): Promise<number>;
openSync(p: PortablePath, flags: string, mode?: number): number;
opendirPromise(p: PortablePath, opts?: OpendirOptions): Promise<import("./FakeFS").Dir<PortablePath>>;
opendirSync(p: PortablePath, opts?: OpendirOptions): import("./FakeFS").Dir<PortablePath>;
readPromise(fd: number, buffer: Buffer, offset: number, length: number, position: number): Promise<number>;
readSync(fd: number, buffer: Buffer, offset: number, length: number, position: number): number;
writePromise(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number): Promise<number>;
writePromise(fd: number, buffer: string, position?: number): Promise<number>;
writeSync(fd: number, buffer: Buffer, offset?: number, length?: number, position?: number): number;
writeSync(fd: number, buffer: string, position?: number): number;
closePromise(fd: number): Promise<void>;
closeSync(fd: number): void;
createReadStream(p: PortablePath | null, opts?: CreateReadStreamOptions): import("fs").ReadStream;
createWriteStream(p: PortablePath | null, opts?: CreateWriteStreamOptions): import("fs").WriteStream;
realpathPromise(p: PortablePath): Promise<PortablePath>;
realpathSync(p: PortablePath): PortablePath;
existsPromise(p: PortablePath): Promise<boolean>;
existsSync(p: PortablePath): boolean;
accessPromise(p: PortablePath, mode?: number): Promise<void>;
accessSync(p: PortablePath, mode?: number): void;
statPromise(p: PortablePath): Promise<Stats>;
statPromise(p: PortablePath, opts: (StatOptions & {
bigint?: false | undefined;
}) | undefined): Promise<Stats>;
statPromise(p: PortablePath, opts: StatOptions & {
bigint: true;
}): Promise<BigIntStats>;
statPromise(p: PortablePath, opts?: StatOptions): Promise<Stats | BigIntStats>;
statSync(p: PortablePath): Stats;
statSync(p: PortablePath, opts?: StatSyncOptions & {
bigint?: false | undefined;
throwIfNoEntry: false;
}): Stats | undefined;
statSync(p: PortablePath, opts: StatSyncOptions & {
bigint: true;
throwIfNoEntry: false;
}): BigIntStats | undefined;
statSync(p: PortablePath, opts?: StatSyncOptions & {
bigint?: false | undefined;
}): Stats;
statSync(p: PortablePath, opts: StatSyncOptions & {
bigint: true;
}): BigIntStats;
statSync(p: PortablePath, opts: StatSyncOptions & {
bigint: boolean;
throwIfNoEntry?: false | undefined;
}): Stats | BigIntStats;
fstatPromise(fd: number): Promise<Stats>;
fstatPromise(fd: number, opts: {
bigint: true;
}): Promise<BigIntStats>;
fstatPromise(fd: number, opts?: {
bigint: boolean;
}): Promise<BigIntStats | Stats>;
fstatSync(fd: number): Stats;
fstatSync(fd: number, opts: {
bigint: true;
}): BigIntStats;
fstatSync(fd: number, opts?: {
bigint: boolean;
}): BigIntStats | Stats;
lstatPromise(p: PortablePath): Promise<Stats>;
lstatPromise(p: PortablePath, opts: (StatOptions & {
bigint?: false | undefined;
}) | undefined): Promise<Stats>;
lstatPromise(p: PortablePath, opts: StatOptions & {
bigint: true;
}): Promise<BigIntStats>;
lstatSync(p: PortablePath): Stats;
lstatSync(p: PortablePath, opts?: StatSyncOptions & {
bigint?: false | undefined;
throwIfNoEntry: false;
}): Stats | undefined;
lstatSync(p: PortablePath, opts: StatSyncOptions & {
bigint: true;
throwIfNoEntry: false;
}): BigIntStats | undefined;
lstatSync(p: PortablePath, opts?: StatSyncOptions & {
bigint?: false | undefined;
}): Stats;
lstatSync(p: PortablePath, opts: StatSyncOptions & {
bigint: true;
}): BigIntStats;
lstatSync(p: PortablePath, opts: StatSyncOptions & {
bigint: boolean;
throwIfNoEntry?: false | undefined;
}): Stats | BigIntStats;
fchmodPromise(fd: number, mask: number): Promise<void>;
fchmodSync(fd: number, mask: number): void;
chmodPromise(p: PortablePath, mask: number): Promise<void>;
chmodSync(p: PortablePath, mask: number): void;
chownPromise(p: PortablePath, uid: number, gid: number): Promise<void>;
chownSync(p: PortablePath, uid: number, gid: number): void;
renamePromise(oldP: PortablePath, newP: PortablePath): Promise<void>;
renameSync(oldP: PortablePath, newP: PortablePath): void;
copyFilePromise(sourceP: PortablePath, destP: PortablePath, flags?: number): Promise<void>;
copyFileSync(sourceP: PortablePath, destP: PortablePath, flags?: number): void;
appendFilePromise(p: FSPath<PortablePath>, content: string | Uint8Array, opts?: WriteFileOptions): Promise<void>;
appendFileSync(p: FSPath<PortablePath>, content: string | Uint8Array, opts?: WriteFileOptions): void;
writeFilePromise(p: FSPath<PortablePath>, content: string | NodeJS.ArrayBufferView, opts?: WriteFileOptions): Promise<void>;
writeFileSync(p: FSPath<PortablePath>, content: string | NodeJS.ArrayBufferView, opts?: WriteFileOptions): void;
unlinkPromise(p: PortablePath): Promise<void>;
unlinkSync(p: PortablePath): void;
utimesPromise(p: PortablePath, atime: Date | string | number, mtime: Date | string | number): Promise<void>;
utimesSync(p: PortablePath, atime: Date | string | number, mtime: Date | string | number): void;
mkdirPromise(p: PortablePath, opts?: MkdirOptions): Promise<string | undefined>;
mkdirSync(p: PortablePath, opts?: MkdirOptions): string | undefined;
rmdirPromise(p: PortablePath, opts?: RmdirOptions): Promise<void>;
rmdirSync(p: PortablePath, opts?: RmdirOptions): void;
linkPromise(existingP: PortablePath, newP: PortablePath): Promise<void>;
linkSync(existingP: PortablePath, newP: PortablePath): void;
symlinkPromise(target: PortablePath, p: PortablePath, type?: SymlinkType): Promise<void>;
symlinkSync(target: PortablePath, p: PortablePath, type?: SymlinkType): void;
readFilePromise(p: FSPath<PortablePath>, encoding?: null): Promise<Buffer>;
readFilePromise(p: FSPath<PortablePath>, encoding: BufferEncoding): Promise<string>;
readFilePromise(p: FSPath<PortablePath>, encoding?: BufferEncoding | null): Promise<Buffer | string>;
readFileSync(p: FSPath<PortablePath>, encoding?: null): Buffer;
readFileSync(p: FSPath<PortablePath>, encoding: BufferEncoding): string;
readFileSync(p: FSPath<PortablePath>, encoding?: BufferEncoding | null): Buffer | string;
readdirPromise(p: PortablePath): Promise<Array<Filename>>;
readdirPromise(p: PortablePath, opts: {
withFileTypes: false;
} | null): Promise<Array<Filename>>;
readdirPromise(p: PortablePath, opts: {
withFileTypes: true;
}): Promise<Array<Dirent>>;
readdirPromise(p: PortablePath, opts: {
withFileTypes: boolean;
}): Promise<Array<Filename> | Array<Dirent>>;
readdirSync(p: PortablePath): Array<Filename>;
readdirSync(p: PortablePath, opts: {
withFileTypes: false;
} | null): Array<Filename>;
readdirSync(p: PortablePath, opts: {
withFileTypes: true;
}): Array<Dirent>;
readdirSync(p: PortablePath, opts: {
withFileTypes: boolean;
}): Array<Filename> | Array<Dirent>;
readlinkPromise(p: PortablePath): Promise<PortablePath>;
readlinkSync(p: PortablePath): PortablePath;
truncatePromise(p: PortablePath, len?: number): Promise<void>;
truncateSync(p: PortablePath, len?: number): void;
ftruncatePromise(fd: number, len?: number): Promise<void>;
ftruncateSync(fd: number, len?: number): void;
watch(p: PortablePath, cb?: WatchCallback): Watcher;
watch(p: PortablePath, opts: WatchOptions, cb?: WatchCallback): Watcher;
watchFile(p: PortablePath, cb: WatchFileCallback): StatWatcher;
watchFile(p: PortablePath, opts: WatchFileOptions, cb: WatchFileCallback): StatWatcher;
unwatchFile(p: PortablePath, cb?: WatchFileCallback): void;
private makeCallPromise;
private makeCallSync;
private findZip;
private limitOpenFilesTimeout;
private limitOpenFiles;
private getZipPromise;
private getZipSync;
constructor(opts: ZipOpenFSOptions);
}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZipOpenFS = exports.getArchivePart = void 0;
const tslib_1 = require("tslib");
const fs_1 = require("fs");
const FakeFS_1 = require("./FakeFS");
const NodeFS_1 = require("./NodeFS");
const MountFS_1 = require("./MountFS");
const ZipFS_1 = require("./ZipFS");
const watchFile_1 = require("./algorithms/watchFile");
const errors = tslib_1.__importStar(require("./errors"));
const path_1 = require("./path");
// Only file descriptors prefixed by those values will be forwarded to the ZipFS
// instances. Note that the highest ZIP_MAGIC bit MUST NOT be set, otherwise the
// resulting fd becomes a negative integer, which isn't supposed to happen per
// the unix rules (caused problems w/ Go).
//
// Those values must be synced with packages/yarnpkg-pnp/sources/esm-loader/fspatch.ts
//
const ZIP_MASK = 0xff000000;
const ZIP_MAGIC = 0x2a000000;
/**

@@ -26,3 +12,3 @@ * Extracts the archive part (ending in the first instance of `extension`) from a path.

*/
const getArchivePart = (path, extension) => {
function getArchivePart(path, extension) {
let idx = path.indexOf(extension);

@@ -45,24 +31,5 @@ if (idx <= 0)

return path.slice(0, nextCharIdx);
};
}
exports.getArchivePart = getArchivePart;
class ZipOpenFS extends FakeFS_1.BasePortableFakeFS {
constructor({ libzip, baseFs = new NodeFS_1.NodeFS(), filter = null, maxOpenFiles = Infinity, readOnlyArchives = false, useCache = true, maxAge = 5000, fileExtensions = null }) {
super();
this.fdMap = new Map();
this.nextFd = 3;
this.isZip = new Set();
this.notZip = new Set();
this.realPaths = new Map();
this.limitOpenFilesTimeout = null;
this.libzipFactory = typeof libzip !== `function`
? () => libzip
: libzip;
this.baseFs = baseFs;
this.zipInstances = useCache ? new Map() : null;
this.filter = filter;
this.maxOpenFiles = maxOpenFiles;
this.readOnlyArchives = readOnlyArchives;
this.maxAge = maxAge;
this.fileExtensions = fileExtensions;
}
class ZipOpenFS extends MountFS_1.MountFS {
static async openPromise(fn, opts) {

@@ -77,816 +44,52 @@ const zipOpenFs = new ZipOpenFS(opts);

}
get libzip() {
if (typeof this.libzipInstance === `undefined`)
this.libzipInstance = this.libzipFactory();
return this.libzipInstance;
}
getExtractHint(hints) {
return this.baseFs.getExtractHint(hints);
}
getRealPath() {
return this.baseFs.getRealPath();
}
saveAndClose() {
(0, watchFile_1.unwatchAllFiles)(this);
if (this.zipInstances) {
for (const [path, { zipFs }] of this.zipInstances.entries()) {
zipFs.saveAndClose();
this.zipInstances.delete(path);
}
}
}
discardAndClose() {
(0, watchFile_1.unwatchAllFiles)(this);
if (this.zipInstances) {
for (const [path, { zipFs }] of this.zipInstances.entries()) {
zipFs.discardAndClose();
this.zipInstances.delete(path);
}
}
}
resolve(p) {
return this.baseFs.resolve(p);
}
remapFd(zipFs, fd) {
const remappedFd = this.nextFd++ | ZIP_MAGIC;
this.fdMap.set(remappedFd, [zipFs, fd]);
return remappedFd;
}
async openPromise(p, flags, mode) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.openPromise(p, flags, mode);
}, async (zipFs, { subPath }) => {
return this.remapFd(zipFs, await zipFs.openPromise(subPath, flags, mode));
});
}
openSync(p, flags, mode) {
return this.makeCallSync(p, () => {
return this.baseFs.openSync(p, flags, mode);
}, (zipFs, { subPath }) => {
return this.remapFd(zipFs, zipFs.openSync(subPath, flags, mode));
});
}
async opendirPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.opendirPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.opendirPromise(subPath, opts);
}, {
requireSubpath: false,
});
}
opendirSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.opendirSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.opendirSync(subPath, opts);
}, {
requireSubpath: false,
});
}
async readPromise(fd, buffer, offset, length, position) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return await this.baseFs.readPromise(fd, buffer, offset, length, position);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`read`);
const [zipFs, realFd] = entry;
return await zipFs.readPromise(realFd, buffer, offset, length, position);
}
readSync(fd, buffer, offset, length, position) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.readSync(fd, buffer, offset, length, position);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`readSync`);
const [zipFs, realFd] = entry;
return zipFs.readSync(realFd, buffer, offset, length, position);
}
async writePromise(fd, buffer, offset, length, position) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC) {
if (typeof buffer === `string`) {
return await this.baseFs.writePromise(fd, buffer, offset);
}
else {
return await this.baseFs.writePromise(fd, buffer, offset, length, position);
}
}
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`write`);
const [zipFs, realFd] = entry;
if (typeof buffer === `string`) {
return await zipFs.writePromise(realFd, buffer, offset);
}
else {
return await zipFs.writePromise(realFd, buffer, offset, length, position);
}
}
writeSync(fd, buffer, offset, length, position) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC) {
if (typeof buffer === `string`) {
return this.baseFs.writeSync(fd, buffer, offset);
}
else {
return this.baseFs.writeSync(fd, buffer, offset, length, position);
}
}
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`writeSync`);
const [zipFs, realFd] = entry;
if (typeof buffer === `string`) {
return zipFs.writeSync(realFd, buffer, offset);
}
else {
return zipFs.writeSync(realFd, buffer, offset, length, position);
}
}
async closePromise(fd) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return await this.baseFs.closePromise(fd);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`close`);
this.fdMap.delete(fd);
const [zipFs, realFd] = entry;
return await zipFs.closePromise(realFd);
}
closeSync(fd) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.closeSync(fd);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`closeSync`);
this.fdMap.delete(fd);
const [zipFs, realFd] = entry;
return zipFs.closeSync(realFd);
}
createReadStream(p, opts) {
if (p === null)
return this.baseFs.createReadStream(p, opts);
return this.makeCallSync(p, () => {
return this.baseFs.createReadStream(p, opts);
}, (zipFs, { archivePath, subPath }) => {
const stream = zipFs.createReadStream(subPath, opts);
// This is a very hacky workaround. `ZipOpenFS` shouldn't have to work with `NativePath`s.
// Ref: https://github.com/yarnpkg/berry/pull/3774
// TODO: think of a better solution
stream.path = path_1.npath.fromPortablePath(this.pathUtils.join(archivePath, subPath));
return stream;
});
}
createWriteStream(p, opts) {
if (p === null)
return this.baseFs.createWriteStream(p, opts);
return this.makeCallSync(p, () => {
return this.baseFs.createWriteStream(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.createWriteStream(subPath, opts);
});
}
async realpathPromise(p) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.realpathPromise(p);
}, async (zipFs, { archivePath, subPath }) => {
let realArchivePath = this.realPaths.get(archivePath);
if (typeof realArchivePath === `undefined`) {
realArchivePath = await this.baseFs.realpathPromise(archivePath);
this.realPaths.set(archivePath, realArchivePath);
}
return this.pathUtils.join(realArchivePath, this.pathUtils.relative(path_1.PortablePath.root, await zipFs.realpathPromise(subPath)));
});
}
realpathSync(p) {
return this.makeCallSync(p, () => {
return this.baseFs.realpathSync(p);
}, (zipFs, { archivePath, subPath }) => {
let realArchivePath = this.realPaths.get(archivePath);
if (typeof realArchivePath === `undefined`) {
realArchivePath = this.baseFs.realpathSync(archivePath);
this.realPaths.set(archivePath, realArchivePath);
}
return this.pathUtils.join(realArchivePath, this.pathUtils.relative(path_1.PortablePath.root, zipFs.realpathSync(subPath)));
});
}
async existsPromise(p) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.existsPromise(p);
}, async (zipFs, { subPath }) => {
return await zipFs.existsPromise(subPath);
});
}
existsSync(p) {
return this.makeCallSync(p, () => {
return this.baseFs.existsSync(p);
}, (zipFs, { subPath }) => {
return zipFs.existsSync(subPath);
});
}
async accessPromise(p, mode) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.accessPromise(p, mode);
}, async (zipFs, { subPath }) => {
return await zipFs.accessPromise(subPath, mode);
});
}
accessSync(p, mode) {
return this.makeCallSync(p, () => {
return this.baseFs.accessSync(p, mode);
}, (zipFs, { subPath }) => {
return zipFs.accessSync(subPath, mode);
});
}
async statPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.statPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.statPromise(subPath, opts);
});
}
statSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.statSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.statSync(subPath, opts);
});
}
async fstatPromise(fd, opts) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.fstatPromise(fd, opts);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`fstat`);
const [zipFs, realFd] = entry;
return zipFs.fstatPromise(realFd, opts);
}
fstatSync(fd, opts) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.fstatSync(fd, opts);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`fstatSync`);
const [zipFs, realFd] = entry;
return zipFs.fstatSync(realFd, opts);
}
async lstatPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.lstatPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.lstatPromise(subPath, opts);
});
}
lstatSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.lstatSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.lstatSync(subPath, opts);
});
}
async fchmodPromise(fd, mask) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.fchmodPromise(fd, mask);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`fchmod`);
const [zipFs, realFd] = entry;
return zipFs.fchmodPromise(realFd, mask);
}
fchmodSync(fd, mask) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.fchmodSync(fd, mask);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`fchmodSync`);
const [zipFs, realFd] = entry;
return zipFs.fchmodSync(realFd, mask);
}
async chmodPromise(p, mask) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.chmodPromise(p, mask);
}, async (zipFs, { subPath }) => {
return await zipFs.chmodPromise(subPath, mask);
});
}
chmodSync(p, mask) {
return this.makeCallSync(p, () => {
return this.baseFs.chmodSync(p, mask);
}, (zipFs, { subPath }) => {
return zipFs.chmodSync(subPath, mask);
});
}
async chownPromise(p, uid, gid) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.chownPromise(p, uid, gid);
}, async (zipFs, { subPath }) => {
return await zipFs.chownPromise(subPath, uid, gid);
});
}
chownSync(p, uid, gid) {
return this.makeCallSync(p, () => {
return this.baseFs.chownSync(p, uid, gid);
}, (zipFs, { subPath }) => {
return zipFs.chownSync(subPath, uid, gid);
});
}
async renamePromise(oldP, newP) {
return await this.makeCallPromise(oldP, async () => {
return await this.makeCallPromise(newP, async () => {
return await this.baseFs.renamePromise(oldP, newP);
}, async () => {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
});
}, async (zipFsO, { subPath: subPathO }) => {
return await this.makeCallPromise(newP, async () => {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
}, async (zipFsN, { subPath: subPathN }) => {
if (zipFsO !== zipFsN) {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
}
else {
return await zipFsO.renamePromise(subPathO, subPathN);
}
});
});
}
renameSync(oldP, newP) {
return this.makeCallSync(oldP, () => {
return this.makeCallSync(newP, () => {
return this.baseFs.renameSync(oldP, newP);
}, () => {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
});
}, (zipFsO, { subPath: subPathO }) => {
return this.makeCallSync(newP, () => {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
}, (zipFsN, { subPath: subPathN }) => {
if (zipFsO !== zipFsN) {
throw Object.assign(new Error(`EEXDEV: cross-device link not permitted`), { code: `EEXDEV` });
}
else {
return zipFsO.renameSync(subPathO, subPathN);
}
});
});
}
async copyFilePromise(sourceP, destP, flags = 0) {
const fallback = async (sourceFs, sourceP, destFs, destP) => {
if ((flags & fs_1.constants.COPYFILE_FICLONE_FORCE) !== 0)
throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { code: `EXDEV` });
if ((flags & fs_1.constants.COPYFILE_EXCL) && await this.existsPromise(sourceP))
throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { code: `EEXIST` });
let content;
try {
content = await sourceFs.readFilePromise(sourceP);
}
catch (error) {
throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { code: `EINVAL` });
}
await destFs.writeFilePromise(destP, content);
constructor(opts) {
let libzipInstance;
const libzipFactory = typeof opts.libzip !== `function`
? () => opts.libzip
: opts.libzip;
const getLibzip = () => {
if (typeof libzipInstance === `undefined`)
libzipInstance = libzipFactory();
return libzipInstance;
};
return await this.makeCallPromise(sourceP, async () => {
return await this.makeCallPromise(destP, async () => {
return await this.baseFs.copyFilePromise(sourceP, destP, flags);
}, async (zipFsD, { subPath: subPathD }) => {
return await fallback(this.baseFs, sourceP, zipFsD, subPathD);
});
}, async (zipFsS, { subPath: subPathS }) => {
return await this.makeCallPromise(destP, async () => {
return await fallback(zipFsS, subPathS, this.baseFs, destP);
}, async (zipFsD, { subPath: subPathD }) => {
if (zipFsS !== zipFsD) {
return await fallback(zipFsS, subPathS, zipFsD, subPathD);
}
else {
return await zipFsS.copyFilePromise(subPathS, subPathD, flags);
}
});
});
}
copyFileSync(sourceP, destP, flags = 0) {
const fallback = (sourceFs, sourceP, destFs, destP) => {
if ((flags & fs_1.constants.COPYFILE_FICLONE_FORCE) !== 0)
throw Object.assign(new Error(`EXDEV: cross-device clone not permitted, copyfile '${sourceP}' -> ${destP}'`), { code: `EXDEV` });
if ((flags & fs_1.constants.COPYFILE_EXCL) && this.existsSync(sourceP))
throw Object.assign(new Error(`EEXIST: file already exists, copyfile '${sourceP}' -> '${destP}'`), { code: `EEXIST` });
let content;
try {
content = sourceFs.readFileSync(sourceP);
}
catch (error) {
throw Object.assign(new Error(`EINVAL: invalid argument, copyfile '${sourceP}' -> '${destP}'`), { code: `EINVAL` });
}
destFs.writeFileSync(destP, content);
};
return this.makeCallSync(sourceP, () => {
return this.makeCallSync(destP, () => {
return this.baseFs.copyFileSync(sourceP, destP, flags);
}, (zipFsD, { subPath: subPathD }) => {
return fallback(this.baseFs, sourceP, zipFsD, subPathD);
});
}, (zipFsS, { subPath: subPathS }) => {
return this.makeCallSync(destP, () => {
return fallback(zipFsS, subPathS, this.baseFs, destP);
}, (zipFsD, { subPath: subPathD }) => {
if (zipFsS !== zipFsD) {
return fallback(zipFsS, subPathS, zipFsD, subPathD);
}
else {
return zipFsS.copyFileSync(subPathS, subPathD, flags);
}
});
});
}
async appendFilePromise(p, content, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.appendFilePromise(p, content, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.appendFilePromise(subPath, content, opts);
});
}
appendFileSync(p, content, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.appendFileSync(p, content, opts);
}, (zipFs, { subPath }) => {
return zipFs.appendFileSync(subPath, content, opts);
});
}
async writeFilePromise(p, content, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.writeFilePromise(p, content, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.writeFilePromise(subPath, content, opts);
});
}
writeFileSync(p, content, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.writeFileSync(p, content, opts);
}, (zipFs, { subPath }) => {
return zipFs.writeFileSync(subPath, content, opts);
});
}
async unlinkPromise(p) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.unlinkPromise(p);
}, async (zipFs, { subPath }) => {
return await zipFs.unlinkPromise(subPath);
});
}
unlinkSync(p) {
return this.makeCallSync(p, () => {
return this.baseFs.unlinkSync(p);
}, (zipFs, { subPath }) => {
return zipFs.unlinkSync(subPath);
});
}
async utimesPromise(p, atime, mtime) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.utimesPromise(p, atime, mtime);
}, async (zipFs, { subPath }) => {
return await zipFs.utimesPromise(subPath, atime, mtime);
});
}
utimesSync(p, atime, mtime) {
return this.makeCallSync(p, () => {
return this.baseFs.utimesSync(p, atime, mtime);
}, (zipFs, { subPath }) => {
return zipFs.utimesSync(subPath, atime, mtime);
});
}
async mkdirPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.mkdirPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.mkdirPromise(subPath, opts);
});
}
mkdirSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.mkdirSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.mkdirSync(subPath, opts);
});
}
async rmdirPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.rmdirPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.rmdirPromise(subPath, opts);
});
}
rmdirSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.rmdirSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.rmdirSync(subPath, opts);
});
}
async linkPromise(existingP, newP) {
return await this.makeCallPromise(newP, async () => {
return await this.baseFs.linkPromise(existingP, newP);
}, async (zipFs, { subPath }) => {
return await zipFs.linkPromise(existingP, subPath);
});
}
linkSync(existingP, newP) {
return this.makeCallSync(newP, () => {
return this.baseFs.linkSync(existingP, newP);
}, (zipFs, { subPath }) => {
return zipFs.linkSync(existingP, subPath);
});
}
async symlinkPromise(target, p, type) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.symlinkPromise(target, p, type);
}, async (zipFs, { subPath }) => {
return await zipFs.symlinkPromise(target, subPath);
});
}
symlinkSync(target, p, type) {
return this.makeCallSync(p, () => {
return this.baseFs.symlinkSync(target, p, type);
}, (zipFs, { subPath }) => {
return zipFs.symlinkSync(target, subPath);
});
}
async readFilePromise(p, encoding) {
return this.makeCallPromise(p, async () => {
return await this.baseFs.readFilePromise(p, encoding);
}, async (zipFs, { subPath }) => {
return await zipFs.readFilePromise(subPath, encoding);
});
}
readFileSync(p, encoding) {
return this.makeCallSync(p, () => {
return this.baseFs.readFileSync(p, encoding);
}, (zipFs, { subPath }) => {
return zipFs.readFileSync(subPath, encoding);
});
}
async readdirPromise(p, opts) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.readdirPromise(p, opts);
}, async (zipFs, { subPath }) => {
return await zipFs.readdirPromise(subPath, opts);
}, {
requireSubpath: false,
});
}
readdirSync(p, opts) {
return this.makeCallSync(p, () => {
return this.baseFs.readdirSync(p, opts);
}, (zipFs, { subPath }) => {
return zipFs.readdirSync(subPath, opts);
}, {
requireSubpath: false,
});
}
async readlinkPromise(p) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.readlinkPromise(p);
}, async (zipFs, { subPath }) => {
return await zipFs.readlinkPromise(subPath);
});
}
readlinkSync(p) {
return this.makeCallSync(p, () => {
return this.baseFs.readlinkSync(p);
}, (zipFs, { subPath }) => {
return zipFs.readlinkSync(subPath);
});
}
async truncatePromise(p, len) {
return await this.makeCallPromise(p, async () => {
return await this.baseFs.truncatePromise(p, len);
}, async (zipFs, { subPath }) => {
return await zipFs.truncatePromise(subPath, len);
});
}
truncateSync(p, len) {
return this.makeCallSync(p, () => {
return this.baseFs.truncateSync(p, len);
}, (zipFs, { subPath }) => {
return zipFs.truncateSync(subPath, len);
});
}
async ftruncatePromise(fd, len) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.ftruncatePromise(fd, len);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`ftruncate`);
const [zipFs, realFd] = entry;
return zipFs.ftruncatePromise(realFd, len);
}
ftruncateSync(fd, len) {
if ((fd & ZIP_MASK) !== ZIP_MAGIC)
return this.baseFs.ftruncateSync(fd, len);
const entry = this.fdMap.get(fd);
if (typeof entry === `undefined`)
throw errors.EBADF(`ftruncateSync`);
const [zipFs, realFd] = entry;
return zipFs.ftruncateSync(realFd, len);
}
watch(p, a, b) {
return this.makeCallSync(p, () => {
return this.baseFs.watch(p,
// @ts-expect-error
a, b);
}, (zipFs, { subPath }) => {
return zipFs.watch(subPath,
// @ts-expect-error
a, b);
});
}
watchFile(p, a, b) {
return this.makeCallSync(p, () => {
return this.baseFs.watchFile(p,
// @ts-expect-error
a, b);
}, () => {
return (0, watchFile_1.watchFile)(this, p, a, b);
});
}
unwatchFile(p, cb) {
return this.makeCallSync(p, () => {
return this.baseFs.unwatchFile(p, cb);
}, () => {
return (0, watchFile_1.unwatchFile)(this, p, cb);
});
}
async makeCallPromise(p, discard, accept, { requireSubpath = true } = {}) {
if (typeof p !== `string`)
return await discard();
const normalizedP = this.resolve(p);
const zipInfo = this.findZip(normalizedP);
if (!zipInfo)
return await discard();
if (requireSubpath && zipInfo.subPath === `/`)
return await discard();
return await this.getZipPromise(zipInfo.archivePath, async (zipFs) => await accept(zipFs, zipInfo));
}
makeCallSync(p, discard, accept, { requireSubpath = true } = {}) {
if (typeof p !== `string`)
return discard();
const normalizedP = this.resolve(p);
const zipInfo = this.findZip(normalizedP);
if (!zipInfo)
return discard();
if (requireSubpath && zipInfo.subPath === `/`)
return discard();
return this.getZipSync(zipInfo.archivePath, zipFs => accept(zipFs, zipInfo));
}
findZip(p) {
if (this.filter && !this.filter.test(p))
return null;
let filePath = ``;
while (true) {
const pathPartWithArchive = p.substring(filePath.length);
let archivePart;
if (!this.fileExtensions) {
archivePart = (0, exports.getArchivePart)(pathPartWithArchive, `.zip`);
}
else {
for (const ext of this.fileExtensions) {
archivePart = (0, exports.getArchivePart)(pathPartWithArchive, ext);
if (archivePart) {
break;
const fileExtensions = opts.fileExtensions;
const readOnlyArchives = opts.readOnlyArchives;
const getMountPoint = typeof fileExtensions === `undefined`
? path => getArchivePart(path, `.zip`)
: path => {
for (const extension of fileExtensions) {
const result = getArchivePart(path, extension);
if (result) {
return result;
}
}
}
if (!archivePart)
return null;
filePath = this.pathUtils.join(filePath, archivePart);
if (this.isZip.has(filePath) === false) {
if (this.notZip.has(filePath))
continue;
try {
if (!this.baseFs.lstatSync(filePath).isFile()) {
this.notZip.add(filePath);
continue;
}
}
catch {
return null;
}
this.isZip.add(filePath);
}
return {
archivePath: filePath,
subPath: this.pathUtils.join(path_1.PortablePath.root, p.substring(filePath.length)),
};
}
}
limitOpenFiles(max) {
if (this.zipInstances === null)
return;
const now = Date.now();
let nextExpiresAt = now + this.maxAge;
let closeCount = max === null ? 0 : this.zipInstances.size - max;
for (const [path, { zipFs, expiresAt, refCount }] of this.zipInstances.entries()) {
if (refCount !== 0 || zipFs.hasOpenFileHandles()) {
continue;
}
else if (now >= expiresAt) {
zipFs.saveAndClose();
this.zipInstances.delete(path);
closeCount -= 1;
continue;
}
else if (max === null || closeCount <= 0) {
nextExpiresAt = expiresAt;
break;
}
zipFs.saveAndClose();
this.zipInstances.delete(path);
closeCount -= 1;
}
if (this.limitOpenFilesTimeout === null && ((max === null && this.zipInstances.size > 0) || max !== null)) {
this.limitOpenFilesTimeout = setTimeout(() => {
this.limitOpenFilesTimeout = null;
this.limitOpenFiles(null);
}, nextExpiresAt - now).unref();
}
}
async getZipPromise(p, accept) {
const getZipOptions = async () => ({
baseFs: this.baseFs,
libzip: this.libzip,
readOnly: this.readOnlyArchives,
stats: await this.baseFs.statPromise(p),
const factorySync = (baseFs, p) => {
return new ZipFS_1.ZipFS(p, {
baseFs,
libzip: getLibzip(),
readOnly: readOnlyArchives,
stats: baseFs.statSync(p),
});
};
const factoryPromise = async (baseFs, p) => {
const zipOptions = {
baseFs,
libzip: getLibzip(),
readOnly: readOnlyArchives,
stats: await baseFs.statPromise(p),
};
return () => {
return new ZipFS_1.ZipFS(p, zipOptions);
};
};
super({
...opts,
factorySync,
factoryPromise,
getMountPoint,
});
if (this.zipInstances) {
let cachedZipFs = this.zipInstances.get(p);
if (!cachedZipFs) {
const zipOptions = await getZipOptions();
// We need to recheck because concurrent getZipPromise calls may
// have instantiated the zip archive while we were waiting
cachedZipFs = this.zipInstances.get(p);
if (!cachedZipFs) {
cachedZipFs = {
zipFs: new ZipFS_1.ZipFS(p, zipOptions),
expiresAt: 0,
refCount: 0,
};
}
}
// Removing then re-adding the field allows us to easily implement
// a basic LRU garbage collection strategy
this.zipInstances.delete(p);
this.limitOpenFiles(this.maxOpenFiles - 1);
this.zipInstances.set(p, cachedZipFs);
cachedZipFs.expiresAt = Date.now() + this.maxAge;
cachedZipFs.refCount += 1;
try {
return await accept(cachedZipFs.zipFs);
}
finally {
cachedZipFs.refCount -= 1;
}
}
else {
const zipFs = new ZipFS_1.ZipFS(p, await getZipOptions());
try {
return await accept(zipFs);
}
finally {
zipFs.saveAndClose();
}
}
}
getZipSync(p, accept) {
const getZipOptions = () => ({
baseFs: this.baseFs,
libzip: this.libzip,
readOnly: this.readOnlyArchives,
stats: this.baseFs.statSync(p),
});
if (this.zipInstances) {
let cachedZipFs = this.zipInstances.get(p);
if (!cachedZipFs) {
cachedZipFs = {
zipFs: new ZipFS_1.ZipFS(p, getZipOptions()),
expiresAt: 0,
refCount: 0,
};
}
// Removing then re-adding the field allows us to easily implement
// a basic LRU garbage collection strategy
this.zipInstances.delete(p);
this.limitOpenFiles(this.maxOpenFiles - 1);
this.zipInstances.set(p, cachedZipFs);
cachedZipFs.expiresAt = Date.now() + this.maxAge;
return accept(cachedZipFs.zipFs);
}
else {
const zipFs = new ZipFS_1.ZipFS(p, getZipOptions());
try {
return accept(zipFs);
}
finally {
zipFs.saveAndClose();
}
}
}
}
exports.ZipOpenFS = ZipOpenFS;
{
"name": "@yarnpkg/fslib",
"version": "3.0.0-rc.15",
"version": "3.0.0-rc.16",
"stableVersion": "2.7.0",

@@ -9,3 +9,3 @@ "license": "BSD-2-Clause",

"dependencies": {
"@yarnpkg/libzip": "^3.0.0-rc.15",
"@yarnpkg/libzip": "^3.0.0-rc.16",
"tslib": "^2.4.0"

@@ -12,0 +12,0 @@ },

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc