From 178081723565ab359dc7aecb63c409d0272e6b81 Mon Sep 17 00:00:00 2001
From: "alexander.akait" <sheo13666q@gmail.com>
Date: Wed, 6 Mar 2024 17:19:55 +0300
Subject: [PATCH 1/4] fix: types

---
 .cspell.json                        |   1 +
 lib/CachedInputFileSystem.js        |  14 +-
 lib/DescriptionFileUtils.js         |   7 +-
 lib/Resolver.js                     | 257 ++++++++++++++++++++++++----
 lib/SyncAsyncFileSystemDecorator.js | 203 ++++++++++++++--------
 package.json                        |   2 +-
 yarn.lock                           |  15 +-
 7 files changed, 378 insertions(+), 121 deletions(-)

diff --git a/.cspell.json b/.cspell.json
index a1e053c8..423d93a7 100644
--- a/.cspell.json
+++ b/.cspell.json
@@ -3,6 +3,7 @@
   "words": [
     "abcxyz",
     "addrs",
+    "abortable",
     "anotherhashishere",
     "arcanis",
     "Builtins",
diff --git a/lib/CachedInputFileSystem.js b/lib/CachedInputFileSystem.js
index cdd1130f..e8188653 100644
--- a/lib/CachedInputFileSystem.js
+++ b/lib/CachedInputFileSystem.js
@@ -35,7 +35,7 @@ const dirname = path => {
 /**
  * @template T
  * @param {FileSystemCallback<T>[]} callbacks callbacks
- * @param {Error | undefined} err error
+ * @param {Error | null} err error
  * @param {T} result result
  */
 const runCallbacks = (callbacks, err, result) => {
@@ -165,7 +165,7 @@ class CacheBackend {
 		this._providerContext = providerContext;
 		/** @type {Map<string, FileSystemCallback<any>[]>} */
 		this._activeAsyncOperations = new Map();
-		/** @type {Map<string, { err?: Error, result?: any, level: Set<string> }>} */
+		/** @type {Map<string, { err: Error | null, result?: any, level: Set<string> }>} */
 		this._data = new Map();
 		/** @type {Set<string>[]} */
 		this._levels = [];
@@ -236,7 +236,7 @@ class CacheBackend {
 			this._providerContext,
 			path,
 			/**
-			 * @param {Error} [err] error
+			 * @param {Error | null} err error
 			 * @param {any} [result] result
 			 */
 			(err, result) => {
@@ -298,16 +298,16 @@ class CacheBackend {
 			}
 			throw err;
 		}
-		this._storeResult(path, undefined, result);
+		this._storeResult(path, null, result);
 		this._enterSyncModeWhenIdle();
 		if (callbacks) {
-			runCallbacks(callbacks, undefined, result);
+			runCallbacks(callbacks, null, result);
 		}
 		return result;
 	}
 
 	/**
-	 * @param {string|string[]|Set<string>} [what] what to purge
+	 * @param {string | string[] | Set<string>} [what] what to purge
 	 */
 	purge(what) {
 		if (!what) {
@@ -363,7 +363,7 @@ class CacheBackend {
 
 	/**
 	 * @param {string} path path
-	 * @param {undefined | Error} err error
+	 * @param {Error | null} err error
 	 * @param {any} result result
 	 */
 	_storeResult(path, err, result) {
diff --git a/lib/DescriptionFileUtils.js b/lib/DescriptionFileUtils.js
index cfa970bc..ff53ad5f 100644
--- a/lib/DescriptionFileUtils.js
+++ b/lib/DescriptionFileUtils.js
@@ -66,7 +66,10 @@ function loadDescriptionFile(
 				if (resolver.fileSystem.readJson) {
 					resolver.fileSystem.readJson(descriptionFilePath, (err, content) => {
 						if (err) {
-							if (typeof err.code !== "undefined") {
+							if (
+								typeof (/** @type {NodeJS.ErrnoException} */ (err).code) !==
+								"undefined"
+							) {
 								if (resolveContext.missingDependencies) {
 									resolveContext.missingDependencies.add(descriptionFilePath);
 								}
@@ -80,7 +83,7 @@ function loadDescriptionFile(
 						if (resolveContext.fileDependencies) {
 							resolveContext.fileDependencies.add(descriptionFilePath);
 						}
-						onJson(null, /** @type {JsonObject} */ (content));
+						onJson(null, content);
 					});
 				} else {
 					resolver.fileSystem.readFile(descriptionFilePath, (err, content) => {
diff --git a/lib/Resolver.js b/lib/Resolver.js
index 97d21a85..44fefee5 100644
--- a/lib/Resolver.js
+++ b/lib/Resolver.js
@@ -21,19 +21,6 @@ const {
 
 /** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */
 
-/**
- * @typedef {Object} FileSystemStats
- * @property {function(): boolean} isDirectory
- * @property {function(): boolean} isFile
- */
-
-/**
- * @typedef {Object} FileSystemDirent
- * @property {Buffer | string} name
- * @property {function(): boolean} isDirectory
- * @property {function(): boolean} isFile
- */
-
 /**
  * @typedef {Object} PossibleFileSystemError
  * @property {string=} code
@@ -45,38 +32,244 @@ const {
 /**
  * @template T
  * @callback FileSystemCallback
- * @param {PossibleFileSystemError & Error | null | undefined} err
+ * @param {PossibleFileSystemError & Error | null} err
  * @param {T=} result
  */
 
-/** @typedef {function((NodeJS.ErrnoException | null)=, (string | Buffer)[] | import("fs").Dirent[]=): void} DirentArrayCallback */
+/**
+ * @typedef {string | Buffer | URL} PathLike
+ */
+
+/**
+ * @typedef {PathLike | number} PathOrFileDescriptor
+ */
+
+/**
+ * @typedef {Object} ObjectEncodingOptions
+ * @property {BufferEncoding | null | undefined} [encoding]
+ */
+
+/** @typedef {function(NodeJS.ErrnoException | null, string | undefined): void} StringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer | undefined): void} BufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string | Buffer | undefined): void} StringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IStats | undefined): void} StatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IBigIntStats | undefined): void} BigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IStats | IBigIntStats | undefined): void} StatsOrBigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject | undefined): void} ReadJsonCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string[] | undefined): void} ReaddirStringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer[] | undefined): void} ReaddirBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string[] | Buffer[] | undefined): void} ReaddirStringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Dirent[] | undefined): void} ReaddirDirentCallback */
+
+/**
+ * @template T
+ * @typedef {Object} IStatsBase
+ * @property {() => boolean} isFile
+ * @property {() => boolean} isDirectory
+ * @property {() => boolean} isBlockDevice
+ * @property {() => boolean} isCharacterDevice
+ * @property {() => boolean} isSymbolicLink
+ * @property {() => boolean} isFIFO
+ * @property {() => boolean} isSocket
+ * @property {T} dev
+ * @property {T} ino
+ * @property {T} mode
+ * @property {T} nlink
+ * @property {T} uid
+ * @property {T} gid
+ * @property {T} rdev
+ * @property {T} size
+ * @property {T} blksize
+ * @property {T} blocks
+ * @property {T} atimeMs
+ * @property {T} mtimeMs
+ * @property {T} ctimeMs
+ * @property {T} birthtimeMs
+ * @property {Date} atime
+ * @property {Date} mtime
+ * @property {Date} ctime
+ * @property {Date} birthtime
+ */
+
+/**
+ * @typedef {IStatsBase<number>} IStats
+ */
+
+/**
+ * @typedef {IStatsBase<bigint> & { atimeNs: bigint, mtimeNs: bigint, ctimeNs: bigint, birthtimeNs: bigint  }} IBigIntStats
+ */
+
+/**
+ * @typedef {Object} Dirent
+ * @property {() => boolean} isFile
+ * @property {() => boolean} isDirectory
+ * @property {() => boolean} isBlockDevice
+ * @property {() => boolean} isCharacterDevice
+ * @property {() => boolean} isSymbolicLink
+ * @property {() => boolean} isFIFO
+ * @property {() => boolean} isSocket
+ * @property {string} name
+ * @property {string} path
+ */
+
+/**
+ * @typedef {Object} StatOptions
+ * @property {(boolean | undefined)=} bigint
+ */
+
+/**
+ * @typedef {Object} StatSyncOptions
+ * @property {(boolean | undefined)=} bigint
+ * @property {(boolean | undefined)=} throwIfNoEntry
+ */
+
+/**
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options: ({ encoding?: null | undefined, flag?: string | undefined } & import("events").Abortable) | undefined | null, callback: BufferCallback): void;
+ * (path: PathOrFileDescriptor, options: ({ encoding: BufferEncoding, flag?: string | undefined } & import("events").Abortable) | BufferEncoding, callback: StringCallback): void;
+ * (path: PathOrFileDescriptor, options: (ObjectEncodingOptions & { flag?: string | undefined } & import("events").Abortable) | BufferEncoding | undefined | null, callback: StringOrBufferCallback): void;
+ * (path: PathOrFileDescriptor, callback: BufferCallback): void;
+ * }} ReadFile
+ */
+
+/**
+ * @typedef {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption
+ */
+
+/**
+ * @typedef {'buffer'| { encoding: 'buffer' }} BufferEncodingOption
+ */
+
+/**
+ * @typedef {{
+ * (path: PathOrFileDescriptor, options?: { encoding?: null | undefined, flag?: string | undefined } | null): Buffer;
+ * (path: PathOrFileDescriptor, options: { encoding: BufferEncoding, flag?: string | undefined } | BufferEncoding): string;
+ * (path: PathOrFileDescriptor, options?: (ObjectEncodingOptions & { flag?: string | undefined }) | BufferEncoding | null): string | Buffer;
+ * }} ReadFileSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | undefined | null, callback: ReaddirStringCallback): void;
+ * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer', callback: ReaddirBufferCallback): void;
+ * (path: PathLike, callback: ReaddirStringCallback): void;
+ * (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: ReaddirStringOrBufferCallback): void;
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: ReaddirDirentCallback): void;
+ * }} Readdir
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: { encoding: BufferEncoding | null, withFileTypes?: false | undefined, recursive?: boolean | undefined } | BufferEncoding | null): string[];
+ * (path: PathLike, options: { encoding: 'buffer', withFileTypes?: false | undefined, recursive?: boolean | undefined } | 'buffer'): Buffer[];
+ * (path: PathLike, options?: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | null): string[] | Buffer[];
+ * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }): Dirent[];
+ * }} ReaddirSync
+
+ /**
+ * @typedef {function(PathOrFileDescriptor, ReadJsonCallback): void} ReadJson
+ */
+
+/**
+ * @typedef {function(PathOrFileDescriptor): JsonObject} ReadJsonSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void;
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
+ * (path: PathLike, callback: StringCallback): void;
+ * }} Readlink
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string;
+ * (path: PathLike, options: BufferEncodingOption): Buffer;
+ * (path: PathLike, options?: EncodingOption): string | Buffer;
+ * }} ReadlinkSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void;
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
+ * }} LStat
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: undefined): IStats;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+ * (path: PathLike,  options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
+ * (path: PathLike,  options?: StatSyncOptions): IStats | IBigIntStats | undefined;
+ * }} LStatSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, callback: StatsCallback): void;
+ * (path: PathLike, options: (StatOptions & { bigint?: false | undefined }) | undefined, callback: StatsCallback): void;
+ * (path: PathLike, options: StatOptions & { bigint: true }, callback: BigIntStatsCallback): void;
+ * (path: PathLike, options: StatOptions | undefined, callback: StatsOrBigIntStatsCallback): void;
+ * }} Stat
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options?: undefined): IStats;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined, throwIfNoEntry: false }): IStats | undefined;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true, throwIfNoEntry: false }): IBigIntStats | undefined;
+ * (path: PathLike, options?: StatSyncOptions & { bigint?: false | undefined }): IStats;
+ * (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+ * (path: PathLike,  options: StatSyncOptions & { bigint: boolean, throwIfNoEntry?: false | undefined }): IStats | IBigIntStats;
+ * (path: PathLike,  options?: StatSyncOptions): IStats | IBigIntStats | undefined;
+ * }} StatSync
+ */
+
+/**
+ * @typedef {{
+ * (path: PathLike, options: EncodingOption, callback: StringCallback): void;
+ * (path: PathLike, options: BufferEncodingOption, callback: BufferCallback): void;
+ * (path: PathLike, options: EncodingOption, callback: StringOrBufferCallback): void;
+ * (path: PathLike, callback: StringCallback): void;
+ * }} RealPath
+ */
 
 /**
- * @typedef {Object} ReaddirOptions
- * @property {BufferEncoding | null | 'buffer'} [encoding]
- * @property {boolean | undefined} [withFileTypes=false]
+ * @typedef {{
+ * (path: PathLike, options?: EncodingOption): string;
+ * (path: PathLike, options: BufferEncodingOption): Buffer;
+ * (path: PathLike, options?: EncodingOption): string | Buffer;
+ * }} RealPathSync
  */
 
 /**
  * @typedef {Object} FileSystem
- * @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} readFile
- * @property {function(string, (ReaddirOptions | BufferEncoding | null | undefined | 'buffer' | DirentArrayCallback)=,  DirentArrayCallback=): void} readdir
- * @property {((function(string, FileSystemCallback<object>): void) & function(string, object, FileSystemCallback<object>): void)=} readJson
- * @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} readlink
- * @property {(function(string, FileSystemCallback<FileSystemStats>): void) & function(string, object, FileSystemCallback<Buffer | string>): void=} lstat
- * @property {(function(string, FileSystemCallback<FileSystemStats>): void) & function(string, object, FileSystemCallback<Buffer | string>): void} stat
- * @property {(function(string, FileSystemCallback<Buffer | string>): void) & function(string, object, FileSystemCallback<Buffer | string>): void=} realpath
+ * @property {ReadFile} readFile
+ * @property {Readdir} readdir
+ * @property {ReadJson=} readJson
+ * @property {Readlink} readlink
+ * @property {LStat=} lstat
+ * @property {Stat} stat
+ * @property {RealPath=} realpath
  */
 
 /**
  * @typedef {Object} SyncFileSystem
- * @property {function(string, object=): Buffer | string} readFileSync
- * @property {function(string, object=): (Buffer | string)[] | FileSystemDirent[]} readdirSync
- * @property {(function(string, object=): object)=} readJsonSync
- * @property {function(string, object=): Buffer | string} readlinkSync
- * @property {function(string, object=): FileSystemStats=} lstatSync
- * @property {function(string, object=): FileSystemStats} statSync
- * @property {function(string, object=): string | Buffer=} realpathSync
+ * @property {ReadFileSync} readFileSync
+ * @property {ReaddirSync} readdirSync
+ * @property {ReadJsonSync=} readJsonSync
+ * @property {ReadlinkSync} readlinkSync
+ * @property {LStatSync=} lstatSync
+ * @property {StatSync} statSync
+ * @property {RealPathSync=} realpathSync
  */
 
 /**
diff --git a/lib/SyncAsyncFileSystemDecorator.js b/lib/SyncAsyncFileSystemDecorator.js
index 12f8d387..bbc352be 100644
--- a/lib/SyncAsyncFileSystemDecorator.js
+++ b/lib/SyncAsyncFileSystemDecorator.js
@@ -6,6 +6,7 @@
 "use strict";
 
 /** @typedef {import("./Resolver").FileSystem} FileSystem */
+/** @typedef {import("./Resolver").Dirent} Dirent */
 /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
 
 /**
@@ -15,90 +16,142 @@
 function SyncAsyncFileSystemDecorator(fs) {
 	this.fs = fs;
 
-	/** @type {FileSystem["lstat"] | undefined} */
 	this.lstat = undefined;
-	/** @type {SyncFileSystem["lstatSync"] | undefined} */
 	this.lstatSync = undefined;
 	const lstatSync = fs.lstatSync;
 	if (lstatSync) {
-		this.lstat = (arg, options, callback) => {
-			let result;
-			try {
-				result = lstatSync.call(fs, arg);
-			} catch (e) {
-				// @ts-ignore
-				return (callback || options)(e);
-			}
-			// @ts-ignore
-			(callback || options)(null, result);
-		};
-		this.lstatSync = (arg, options) => lstatSync.call(fs, arg, options);
+		this.lstat =
+			/** @type {FileSystem["lstat"]} */
+			(
+				(arg, options, callback) => {
+					let result;
+					try {
+						result = lstatSync.call(fs, arg);
+					} catch (e) {
+						return (callback || options)(e);
+					}
+
+					(callback || options)(null, result);
+				}
+			);
+		this.lstatSync =
+			/** @type {SyncFileSystem["lstatSync"]} */
+			((arg, options) => lstatSync.call(fs, arg, options));
 	}
-	// @ts-ignore
-	this.stat = (arg, options, callback) => {
-		let result;
-		try {
-			result = callback ? fs.statSync(arg, options) : fs.statSync(arg);
-		} catch (e) {
-			return (callback || options)(e);
-		}
-		(callback || options)(null, result);
-	};
-	/** @type {SyncFileSystem["statSync"]} */
-	this.statSync = (arg, options) => fs.statSync(arg, options);
-	// @ts-ignore
-	this.readdir = (arg, options, callback) => {
-		let result;
-		try {
-			result = fs.readdirSync(arg);
-		} catch (e) {
-			return (callback || options)(e);
-		}
-		(callback || options)(null, result);
-	};
-	/** @type {SyncFileSystem["readdirSync"]} */
-	this.readdirSync = (arg, options) => fs.readdirSync(arg, options);
-	// @ts-ignore
-	this.readFile = (arg, options, callback) => {
-		let result;
-		try {
-			result = fs.readFileSync(arg);
-		} catch (e) {
-			return (callback || options)(e);
-		}
-		(callback || options)(null, result);
-	};
-	/** @type {SyncFileSystem["readFileSync"]} */
-	this.readFileSync = (arg, options) => fs.readFileSync(arg, options);
-	// @ts-ignore
-	this.readlink = (arg, options, callback) => {
-		let result;
-		try {
-			result = fs.readlinkSync(arg);
-		} catch (e) {
-			return (callback || options)(e);
-		}
-		(callback || options)(null, result);
-	};
-	/** @type {SyncFileSystem["readlinkSync"]} */
-	this.readlinkSync = (arg, options) => fs.readlinkSync(arg, options);
-	/** @type {FileSystem["readJson"] | undefined} */
+
+	this.stat =
+		/** @type {FileSystem["stat"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = callback ? fs.statSync(arg, options) : fs.statSync(arg);
+				} catch (e) {
+					return (callback || options)(e);
+				}
+				(callback || options)(null, result);
+			}
+		);
+	this.statSync =
+		/** @type {SyncFileSystem["statSync"]} */
+		((arg, options) => fs.statSync(arg, options));
+
+	this.readdir =
+		/** @type {FileSystem["readdir"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = callback
+						? fs.readdirSync(arg, options)
+						: fs.readdirSync(arg);
+				} catch (e) {
+					return (callback || options)(e);
+				}
+
+				(callback || options)(null, result);
+			}
+		);
+	this.readdirSync =
+		/** @type {SyncFileSystem["readdirSync"]} */
+		((arg, options) => fs.readdirSync(arg, options));
+
+	this.readFile =
+		/** @type {FileSystem["readFile"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = fs.readFileSync(arg);
+				} catch (e) {
+					return (callback || options)(e);
+				}
+				(callback || options)(null, result);
+			}
+		);
+	this.readFileSync =
+		/** @type {SyncFileSystem["readFileSync"]} */
+		((arg, options) => fs.readFileSync(arg, options));
+
+	this.readlink =
+		/** @type {FileSystem["readlink"]} */
+		(
+			(arg, options, callback) => {
+				let result;
+				try {
+					result = fs.readlinkSync(arg);
+				} catch (e) {
+					return (callback || options)(e);
+				}
+				(callback || options)(null, result);
+			}
+		);
+	this.readlinkSync =
+		/** @type {SyncFileSystem["readlinkSync"]} */
+		((arg, options) => fs.readlinkSync(arg, options));
+
 	this.readJson = undefined;
-	/** @type {SyncFileSystem["readJsonSync"] | undefined} */
 	this.readJsonSync = undefined;
 	const readJsonSync = fs.readJsonSync;
 	if (readJsonSync) {
-		this.readJson = (arg, options, callback) => {
-			let result;
-			try {
-				result = readJsonSync.call(fs, arg);
-			} catch (e) {
-				// @ts-ignore
-				return (callback || options)(e);
-			}
-			(callback || options)(null, result);
-		};
-		this.readJsonSync = (arg, options) => readJsonSync.call(fs, arg, options);
+		this.readJson =
+			/** @type {NonNullable<FileSystem["readJson"]>} */
+			(
+				(arg, options, callback) => {
+					let result;
+					try {
+						result = readJsonSync.call(fs, arg);
+					} catch (e) {
+						return (callback || options)(e);
+					}
+					(callback || options)(null, result);
+				}
+			);
+		this.readJsonSync =
+			/** @type {SyncFileSystem["readJsonSync"]} */
+			((arg, options) => readJsonSync.call(fs, arg, options));
+	}
+
+	this.realpath = undefined;
+	this.realpathSync = undefined;
+	const realpathSync = fs.realpathSync;
+	if (realpathSync) {
+		this.realpath =
+			/** @type {FileSystem["realpath"]} */
+			(
+				(arg, options, callback) => {
+					let result;
+					try {
+						result = realpathSync.call(fs, arg);
+					} catch (e) {
+						return (callback || options)(e);
+					}
+					(callback || options)(null, result);
+				}
+			);
+		this.realpathSync =
+			/** @type {SyncFileSystem["realpathSync"]} */
+			((arg, options) => realpathSync.call(fs, arg, options));
 	}
 }
 module.exports = SyncAsyncFileSystemDecorator;
diff --git a/package.json b/package.json
index 509bd569..fff66552 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@types/graceful-fs": "^4.1.6",
     "@types/jest": "^27.5.1",
-    "@types/node": "^14.11.1",
+    "@types/node": "^20.11.24",
     "cspell": "4.2.8",
     "eslint": "^7.9.0",
     "eslint-config-prettier": "^6.11.0",
diff --git a/yarn.lock b/yarn.lock
index 659eaa14..098c4a70 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -898,10 +898,12 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.7.tgz#ce10c802f7731909d0a44ac9888e8b3a9125eb62"
   integrity sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==
 
-"@types/node@^14.11.1":
-  version "14.18.47"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.47.tgz#89a56b05804d136cb99bf2f823bb00814a889aae"
-  integrity sha512-OuJi8bIng4wYHHA3YpKauL58dZrPxro3d0tabPHyiNF8rKfGKuVfr83oFlPLmKri1cX+Z3cJP39GXmnqkP11Gw==
+"@types/node@^20.11.24":
+  version "20.11.24"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792"
+  integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==
+  dependencies:
+    undici-types "~5.26.4"
 
 "@types/parse-json@^4.0.0":
   version "4.0.0"
@@ -3898,6 +3900,11 @@ typescript@^5.0.4:
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
   integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
 
+undici-types@~5.26.4:
+  version "5.26.5"
+  resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617"
+  integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==
+
 unique-string@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"

From bf8903172a328302572844c01dbeba6a3040ebb9 Mon Sep 17 00:00:00 2001
From: "alexander.akait" <sheo13666q@gmail.com>
Date: Wed, 6 Mar 2024 17:53:26 +0300
Subject: [PATCH 2/4] fix: types

---
 lib/Resolver.js                     |  22 ++---
 lib/SyncAsyncFileSystemDecorator.js | 119 +++++++++++++++++++++-------
 package.json                        |   4 +-
 yarn.lock                           |  48 ++++++++---
 4 files changed, 143 insertions(+), 50 deletions(-)

diff --git a/lib/Resolver.js b/lib/Resolver.js
index 44fefee5..ba1dba9f 100644
--- a/lib/Resolver.js
+++ b/lib/Resolver.js
@@ -49,17 +49,17 @@ const {
  * @property {BufferEncoding | null | undefined} [encoding]
  */
 
-/** @typedef {function(NodeJS.ErrnoException | null, string | undefined): void} StringCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, Buffer | undefined): void} BufferCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, string | Buffer | undefined): void} StringOrBufferCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, IStats | undefined): void} StatsCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, IBigIntStats | undefined): void} BigIntStatsCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, IStats | IBigIntStats | undefined): void} StatsOrBigIntStatsCallback */
-/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject | undefined): void} ReadJsonCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, string[] | undefined): void} ReaddirStringCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, Buffer[] | undefined): void} ReaddirBufferCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, string[] | Buffer[] | undefined): void} ReaddirStringOrBufferCallback */
-/** @typedef {function(NodeJS.ErrnoException | null, Dirent[] | undefined): void} ReaddirDirentCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string=): void} StringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer=): void} BufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (string | Buffer)=): void} StringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IStats=): void} StatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, IBigIntStats=): void} BigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (IStats | IBigIntStats)=): void} StatsOrBigIntStatsCallback */
+/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject=): void} ReadJsonCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, string[]=): void} ReaddirStringCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Buffer[]=): void} ReaddirBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, (string[] | Buffer[])=): void} ReaddirStringOrBufferCallback */
+/** @typedef {function(NodeJS.ErrnoException | null, Dirent[]=): void} ReaddirDirentCallback */
 
 /**
  * @template T
diff --git a/lib/SyncAsyncFileSystemDecorator.js b/lib/SyncAsyncFileSystemDecorator.js
index bbc352be..d1f1814e 100644
--- a/lib/SyncAsyncFileSystemDecorator.js
+++ b/lib/SyncAsyncFileSystemDecorator.js
@@ -6,7 +6,8 @@
 "use strict";
 
 /** @typedef {import("./Resolver").FileSystem} FileSystem */
-/** @typedef {import("./Resolver").Dirent} Dirent */
+/** @typedef {import("./Resolver").ReaddirStringCallback} ReaddirStringCallback */
+/** @typedef {import("./Resolver").StringCallback} StringCallback */
 /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
 
 /**
@@ -26,12 +27,16 @@ function SyncAsyncFileSystemDecorator(fs) {
 				(arg, options, callback) => {
 					let result;
 					try {
-						result = lstatSync.call(fs, arg);
+						result = /** @type {Function | undefined} */ (callback)
+							? lstatSync.call(fs, arg, options)
+							: lstatSync.call(fs, arg);
 					} catch (e) {
-						return (callback || options)(e);
+						return (callback || options)(
+							/** @type {NodeJS.ErrnoException | null} */ (e)
+						);
 					}
 
-					(callback || options)(null, result);
+					(callback || options)(null, /** @type {any} */ (result));
 				}
 			);
 		this.lstatSync =
@@ -45,11 +50,16 @@ function SyncAsyncFileSystemDecorator(fs) {
 			(arg, options, callback) => {
 				let result;
 				try {
-					result = callback ? fs.statSync(arg, options) : fs.statSync(arg);
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.statSync(arg, options)
+						: fs.statSync(arg);
 				} catch (e) {
-					return (callback || options)(e);
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
 				}
-				(callback || options)(null, result);
+
+				(callback || options)(null, /** @type {any} */ (result));
 			}
 		);
 	this.statSync =
@@ -62,19 +72,31 @@ function SyncAsyncFileSystemDecorator(fs) {
 			(arg, options, callback) => {
 				let result;
 				try {
-					result = callback
-						? fs.readdirSync(arg, options)
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readdirSync(
+								arg,
+								/** @type {Exclude<Parameters<FileSystem["readdir"]>[1], ReaddirStringCallback>} */
+								(options)
+						  )
 						: fs.readdirSync(arg);
 				} catch (e) {
-					return (callback || options)(e);
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
 				}
 
-				(callback || options)(null, result);
+				(callback || options)(null, /** @type {any} */ (result));
 			}
 		);
 	this.readdirSync =
 		/** @type {SyncFileSystem["readdirSync"]} */
-		((arg, options) => fs.readdirSync(arg, options));
+		(
+			(arg, options) =>
+				fs.readdirSync(
+					arg,
+					/** @type {Parameters<SyncFileSystem["readdirSync"]>[1]} */ (options)
+				)
+		);
 
 	this.readFile =
 		/** @type {FileSystem["readFile"]} */
@@ -82,11 +104,16 @@ function SyncAsyncFileSystemDecorator(fs) {
 			(arg, options, callback) => {
 				let result;
 				try {
-					result = fs.readFileSync(arg);
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readFileSync(arg, options)
+						: fs.readFileSync(arg);
 				} catch (e) {
-					return (callback || options)(e);
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
 				}
-				(callback || options)(null, result);
+
+				(callback || options)(null, /** @type {any} */ (result));
 			}
 		);
 	this.readFileSync =
@@ -99,37 +126,55 @@ function SyncAsyncFileSystemDecorator(fs) {
 			(arg, options, callback) => {
 				let result;
 				try {
-					result = fs.readlinkSync(arg);
+					result = /** @type {Function | undefined} */ (callback)
+						? fs.readlinkSync(
+								arg,
+								/** @type {Exclude<Parameters<FileSystem["readlink"]>[1], StringCallback>} */
+								(options)
+						  )
+						: fs.readlinkSync(arg);
 				} catch (e) {
-					return (callback || options)(e);
+					return (callback || options)(
+						/** @type {NodeJS.ErrnoException | null} */ (e)
+					);
 				}
-				(callback || options)(null, result);
+
+				(callback || options)(null, /** @type {any} */ (result));
 			}
 		);
 	this.readlinkSync =
 		/** @type {SyncFileSystem["readlinkSync"]} */
-		((arg, options) => fs.readlinkSync(arg, options));
+		(
+			(arg, options) =>
+				fs.readlinkSync(
+					arg,
+					/** @type {Parameters<SyncFileSystem["readlinkSync"]>[1]} */ (options)
+				)
+		);
 
 	this.readJson = undefined;
 	this.readJsonSync = undefined;
 	const readJsonSync = fs.readJsonSync;
 	if (readJsonSync) {
 		this.readJson =
-			/** @type {NonNullable<FileSystem["readJson"]>} */
+			/** @type {FileSystem["readJson"]} */
 			(
-				(arg, options, callback) => {
+				(arg, callback) => {
 					let result;
 					try {
 						result = readJsonSync.call(fs, arg);
 					} catch (e) {
-						return (callback || options)(e);
+						return callback(
+							/** @type {NodeJS.ErrnoException | Error | null} */ (e)
+						);
 					}
-					(callback || options)(null, result);
+
+					callback(null, result);
 				}
 			);
 		this.readJsonSync =
 			/** @type {SyncFileSystem["readJsonSync"]} */
-			((arg, options) => readJsonSync.call(fs, arg, options));
+			(arg => readJsonSync.call(fs, arg));
 	}
 
 	this.realpath = undefined;
@@ -142,16 +187,34 @@ function SyncAsyncFileSystemDecorator(fs) {
 				(arg, options, callback) => {
 					let result;
 					try {
-						result = realpathSync.call(fs, arg);
+						result = /** @type {Function | undefined} */ (callback)
+							? realpathSync.call(
+									fs,
+									arg,
+									/** @type {Exclude<Parameters<NonNullable<FileSystem["realpath"]>>[1], StringCallback>} */
+									(options)
+							  )
+							: realpathSync.call(fs, arg);
 					} catch (e) {
-						return (callback || options)(e);
+						return (callback || options)(
+							/** @type {NodeJS.ErrnoException | null} */ (e)
+						);
 					}
-					(callback || options)(null, result);
+
+					(callback || options)(null, /** @type {any} */ (result));
 				}
 			);
 		this.realpathSync =
 			/** @type {SyncFileSystem["realpathSync"]} */
-			((arg, options) => realpathSync.call(fs, arg, options));
+			(
+				(arg, options) =>
+					realpathSync.call(
+						fs,
+						arg,
+						/** @type {Parameters<NonNullable<SyncFileSystem["realpathSync"]>>[1]} */
+						(options)
+					)
+			);
 	}
 }
 module.exports = SyncAsyncFileSystemDecorator;
diff --git a/package.json b/package.json
index fff66552..31ed5113 100644
--- a/package.json
+++ b/package.json
@@ -32,8 +32,8 @@
     "lint-staged": "^10.4.0",
     "memfs": "^3.2.0",
     "prettier": "^2.1.2",
-    "tooling": "webpack/tooling#v1.14.0",
-    "typescript": "^5.0.4"
+    "tooling": "webpack/tooling#v1.23.1",
+    "typescript": "^5.3.3"
   },
   "engines": {
     "node": ">=10.13.0"
diff --git a/yarn.lock b/yarn.lock
index 098c4a70..63baca5b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -779,6 +779,14 @@
   resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
   integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
 
+"@jridgewell/source-map@^0.3.3":
+  version "0.3.5"
+  resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91"
+  integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==
+  dependencies:
+    "@jridgewell/gen-mapping" "^0.3.0"
+    "@jridgewell/trace-mapping" "^0.3.9"
+
 "@jridgewell/sourcemap-codec@1.4.14":
   version "1.4.14"
   resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
@@ -970,6 +978,11 @@ acorn@^8.2.4:
   resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a"
   integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==
 
+acorn@^8.8.2:
+  version "8.11.3"
+  resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a"
+  integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==
+
 agent-base@6:
   version "6.0.2"
   resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77"
@@ -995,7 +1008,7 @@ ajv@^6.10.0, ajv@^6.12.4:
     json-schema-traverse "^0.4.1"
     uri-js "^4.2.2"
 
-ajv@^8.0.1:
+ajv@^8.0.1, ajv@^8.1.0:
   version "8.12.0"
   resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1"
   integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==
@@ -1337,6 +1350,11 @@ combined-stream@^1.0.8:
   dependencies:
     delayed-stream "~1.0.0"
 
+commander@^2.20.0:
+  version "2.20.3"
+  resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
+  integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+
 commander@^6.2.0:
   version "6.2.1"
   resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
@@ -3585,7 +3603,7 @@ slice-ansi@^4.0.0:
     astral-regex "^2.0.0"
     is-fullwidth-code-point "^3.0.0"
 
-source-map-support@^0.5.6:
+source-map-support@^0.5.6, source-map-support@~0.5.20:
   version "0.5.21"
   resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
   integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
@@ -3754,6 +3772,16 @@ terminal-link@^2.0.0:
     ansi-escapes "^4.2.1"
     supports-hyperlinks "^2.0.0"
 
+terser@^5.6.1:
+  version "5.29.1"
+  resolved "https://registry.yarnpkg.com/terser/-/terser-5.29.1.tgz#44e58045b70c09792ba14bfb7b4e14ca8755b9fa"
+  integrity sha512-lZQ/fyaIGxsbGxApKmoPTODIzELy3++mXhS5hOqaAWZjQtpq/hFHAc+rm29NND1rYRxRWKcjuARNwULNXa5RtQ==
+  dependencies:
+    "@jridgewell/source-map" "^0.3.3"
+    acorn "^8.8.2"
+    commander "^2.20.0"
+    source-map-support "~0.5.20"
+
 test-exclude@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e"
@@ -3817,14 +3845,16 @@ to-regex-range@^5.0.1:
   dependencies:
     is-number "^7.0.0"
 
-tooling@webpack/tooling#v1.14.0:
-  version "1.14.0"
-  resolved "https://codeload.github.com/webpack/tooling/tar.gz/f8500c02cf2a04b3a0c0c2ca38ad9df959b9d02a"
+tooling@webpack/tooling#v1.23.1:
+  version "1.23.1"
+  resolved "https://codeload.github.com/webpack/tooling/tar.gz/017c076821912f5e9f5c0d04508ed6fb7f0319ad"
   dependencies:
     "@yarnpkg/lockfile" "^1.1.0"
+    ajv "^8.1.0"
     commondir "^1.0.1"
     glob "^7.1.6"
     json-schema-to-typescript "^9.1.1"
+    terser "^5.6.1"
     yargs "^16.1.1"
 
 tough-cookie@^4.0.0:
@@ -3895,10 +3925,10 @@ typedarray-to-buffer@^3.1.5:
   dependencies:
     is-typedarray "^1.0.0"
 
-typescript@^5.0.4:
-  version "5.0.4"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
-  integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
+typescript@^5.3.3:
+  version "5.3.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.3.tgz#b3ce6ba258e72e6305ba66f5c9b452aaee3ffe37"
+  integrity sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==
 
 undici-types@~5.26.4:
   version "5.26.5"

From 99f63fb2ca7c2fa90f23ee17202f35ddbe4d1cce Mon Sep 17 00:00:00 2001
From: "alexander.akait" <sheo13666q@gmail.com>
Date: Wed, 6 Mar 2024 18:01:41 +0300
Subject: [PATCH 3/4] fix: types

---
 .github/workflows/test.yml |   2 +-
 package.json               |   2 +-
 types.d.ts                 | 876 ++++++++++++++++++++++++++-----------
 yarn.lock                  |   8 +-
 4 files changed, 636 insertions(+), 252 deletions(-)

diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9620bba5..c56a1b45 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -39,7 +39,7 @@ jobs:
         run: |
           yarn upgrade typescript@^4 --ignore-engines
           yarn --frozen-lockfile
-        if: matrix.node-version == '10.x'
+        if: matrix.node-version == '10.x' || matrix.node-version == '12.x'
       - name: Install dependencies
         run: yarn --frozen-lockfile
         if: matrix.node-version != '10.x'
diff --git a/package.json b/package.json
index 31ed5113..5aa13930 100644
--- a/package.json
+++ b/package.json
@@ -20,7 +20,7 @@
   "devDependencies": {
     "@types/graceful-fs": "^4.1.6",
     "@types/jest": "^27.5.1",
-    "@types/node": "^20.11.24",
+    "@types/node": "20.9.5",
     "cspell": "4.2.8",
     "eslint": "^7.9.0",
     "eslint-config-prettier": "^6.11.0",
diff --git a/types.d.ts b/types.d.ts
index 1522fc6a..43a1b39b 100644
--- a/types.d.ts
+++ b/types.d.ts
@@ -4,9 +4,16 @@
  * Run `yarn special-lint-fix` to update
  */
 
-import { Dirent } from "fs";
+import { Buffer } from "buffer";
 import { AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } from "tapable";
+import { URL as URL_Import } from "url";
 
+declare interface Abortable {
+	/**
+	 * When provided the corresponding `AbortController` can be used to cancel an asynchronous action.
+	 */
+	signal?: AbortSignal;
+}
 type Alias = string | false | string[];
 declare interface AliasOption {
 	alias: Alias;
@@ -30,89 +37,43 @@ declare interface BaseResolveRequest {
 	__innerRequest_request?: string;
 	__innerRequest_relativePath?: string;
 }
+type BufferEncoding =
+	| "ascii"
+	| "utf8"
+	| "utf-8"
+	| "utf16le"
+	| "utf-16le"
+	| "ucs2"
+	| "ucs-2"
+	| "base64"
+	| "base64url"
+	| "latin1"
+	| "binary"
+	| "hex";
+type BufferEncodingOption = "buffer" | { encoding: "buffer" };
 declare class CachedInputFileSystem {
 	constructor(fileSystem: any, duration: number);
 	fileSystem: any;
-	lstat?: {
-		(arg0: string, arg1: FileSystemCallback<FileSystemStats>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	lstatSync?: (arg0: string, arg1?: object) => FileSystemStats;
-	stat: {
-		(arg0: string, arg1: FileSystemCallback<FileSystemStats>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	statSync: (arg0: string, arg1?: object) => FileSystemStats;
-	readdir: (
-		arg0: string,
-		arg1?:
-			| null
-			| ((
-					arg0?: null | NodeJS.ErrnoException,
-					arg1?: (string | Buffer)[] | Dirent[]
-			  ) => void)
-			| ReaddirOptions
-			| "ascii"
-			| "utf8"
-			| "utf-8"
-			| "utf16le"
-			| "ucs2"
-			| "ucs-2"
-			| "base64"
-			| "base64url"
-			| "latin1"
-			| "binary"
-			| "hex"
-			| "buffer",
-		arg2?: (
-			arg0?: null | NodeJS.ErrnoException,
-			arg1?: (string | Buffer)[] | Dirent[]
+	lstat?: LStat;
+	lstatSync?: LStatSync;
+	stat: Stat;
+	statSync: StatSync;
+	readdir: Readdir;
+	readdirSync: ReaddirSync;
+	readFile: ReadFile;
+	readFileSync: ReadFileSync;
+	readJson?: (
+		arg0: PathOrFileDescriptor,
+		arg1: (
+			arg0: null | Error | NodeJS.ErrnoException,
+			arg1?: JsonObject
 		) => void
 	) => void;
-	readdirSync: (
-		arg0: string,
-		arg1?: object
-	) => (string | Buffer)[] | FileSystemDirent[];
-	readFile: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	readFileSync: (arg0: string, arg1?: object) => string | Buffer;
-	readJson?: {
-		(arg0: string, arg1: FileSystemCallback<object>): void;
-		(arg0: string, arg1: object, arg2: FileSystemCallback<object>): void;
-	};
-	readJsonSync?: (arg0: string, arg1?: object) => object;
-	readlink: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	readlinkSync: (arg0: string, arg1?: object) => string | Buffer;
-	realpath?: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	realpathSync?: (arg0: string, arg1?: object) => string | Buffer;
+	readJsonSync?: (arg0: PathOrFileDescriptor) => JsonObject;
+	readlink: Readlink;
+	readlinkSync: ReadlinkSync;
+	realpath?: RealPath;
+	realpathSync?: RealPathSync;
 	purge(what?: string | Set<string> | string[]): void;
 }
 declare class CloneBasenamePlugin {
@@ -144,6 +105,33 @@ declare class CloneBasenamePlugin {
 		  >;
 	apply(resolver: Resolver): void;
 }
+declare interface Dirent {
+	isFile: () => boolean;
+	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	name: string;
+	path: string;
+}
+type EncodingOption =
+	| undefined
+	| null
+	| "ascii"
+	| "utf8"
+	| "utf-8"
+	| "utf16le"
+	| "utf-16le"
+	| "ucs2"
+	| "ucs-2"
+	| "base64"
+	| "base64url"
+	| "latin1"
+	| "binary"
+	| "hex"
+	| ObjectEncodingOptions;
 type ErrorWithDetail = Error & { details?: string };
 declare interface ExtensionAliasOption {
 	alias: string | string[];
@@ -153,88 +141,79 @@ declare interface ExtensionAliasOptions {
 	[index: string]: string | string[];
 }
 declare interface FileSystem {
-	readFile: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	readdir: (
-		arg0: string,
-		arg1?:
-			| null
-			| ((
-					arg0?: null | NodeJS.ErrnoException,
-					arg1?: (string | Buffer)[] | Dirent[]
-			  ) => void)
-			| ReaddirOptions
-			| "ascii"
-			| "utf8"
-			| "utf-8"
-			| "utf16le"
-			| "ucs2"
-			| "ucs-2"
-			| "base64"
-			| "base64url"
-			| "latin1"
-			| "binary"
-			| "hex"
-			| "buffer",
-		arg2?: (
-			arg0?: null | NodeJS.ErrnoException,
-			arg1?: (string | Buffer)[] | Dirent[]
+	readFile: ReadFile;
+	readdir: Readdir;
+	readJson?: (
+		arg0: PathOrFileDescriptor,
+		arg1: (
+			arg0: null | Error | NodeJS.ErrnoException,
+			arg1?: JsonObject
 		) => void
 	) => void;
-	readJson?: {
-		(arg0: string, arg1: FileSystemCallback<object>): void;
-		(arg0: string, arg1: object, arg2: FileSystemCallback<object>): void;
-	};
-	readlink: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	lstat?: {
-		(arg0: string, arg1: FileSystemCallback<FileSystemStats>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	stat: {
-		(arg0: string, arg1: FileSystemCallback<FileSystemStats>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-	realpath?: {
-		(arg0: string, arg1: FileSystemCallback<string | Buffer>): void;
-		(
-			arg0: string,
-			arg1: object,
-			arg2: FileSystemCallback<string | Buffer>
-		): void;
-	};
-}
-declare interface FileSystemCallback<T> {
-	(err?: null | (PossibleFileSystemError & Error), result?: T): any;
+	readlink: Readlink;
+	lstat?: LStat;
+	stat: Stat;
+	realpath?: RealPath;
 }
-declare interface FileSystemDirent {
-	name: string | Buffer;
-	isDirectory: () => boolean;
+type IBigIntStats = IStatsBase<bigint> & {
+	atimeNs: bigint;
+	mtimeNs: bigint;
+	ctimeNs: bigint;
+	birthtimeNs: bigint;
+};
+declare interface IStats {
 	isFile: () => boolean;
-}
-declare interface FileSystemStats {
 	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	dev: number;
+	ino: number;
+	mode: number;
+	nlink: number;
+	uid: number;
+	gid: number;
+	rdev: number;
+	size: number;
+	blksize: number;
+	blocks: number;
+	atimeMs: number;
+	mtimeMs: number;
+	ctimeMs: number;
+	birthtimeMs: number;
+	atime: Date;
+	mtime: Date;
+	ctime: Date;
+	birthtime: Date;
+}
+declare interface IStatsBase<T> {
 	isFile: () => boolean;
+	isDirectory: () => boolean;
+	isBlockDevice: () => boolean;
+	isCharacterDevice: () => boolean;
+	isSymbolicLink: () => boolean;
+	isFIFO: () => boolean;
+	isSocket: () => boolean;
+	dev: T;
+	ino: T;
+	mode: T;
+	nlink: T;
+	uid: T;
+	gid: T;
+	rdev: T;
+	size: T;
+	blksize: T;
+	blocks: T;
+	atimeMs: T;
+	mtimeMs: T;
+	ctimeMs: T;
+	birthtimeMs: T;
+	atime: Date;
+	mtime: Date;
+	ctime: Date;
+	birthtime: Date;
 }
 declare interface Iterator<T, Z> {
 	(
@@ -271,6 +250,51 @@ declare interface KnownHooks {
 	>;
 	result: AsyncSeriesHook<[ResolveRequest, ResolveContext]>;
 }
+declare interface LStat {
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | (StatOptions & { bigint?: false }),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: StatOptions & { bigint: true },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IBigIntStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | StatOptions,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: IStats | IBigIntStats
+		) => void
+	): void;
+}
+declare interface LStatSync {
+	(path: PathLike, options?: undefined): IStats;
+	(
+		path: PathLike,
+		options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }
+	): undefined | IStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }
+	): undefined | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats;
+	(path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }
+	): IStats | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions):
+		| undefined
+		| IStats
+		| IBigIntStats;
+}
 declare class LogInfoPlugin {
 	constructor(
 		source:
@@ -288,6 +312,22 @@ declare class LogInfoPlugin {
 		  >;
 	apply(resolver: Resolver): void;
 }
+declare interface ObjectEncodingOptions {
+	encoding?:
+		| null
+		| "ascii"
+		| "utf8"
+		| "utf-8"
+		| "utf16le"
+		| "utf-16le"
+		| "ucs2"
+		| "ucs-2"
+		| "base64"
+		| "base64url"
+		| "latin1"
+		| "binary"
+		| "hex";
+}
 declare interface ParsedIdentifier {
 	request: string;
 	query: string;
@@ -297,6 +337,8 @@ declare interface ParsedIdentifier {
 	file: boolean;
 	internal: boolean;
 }
+type PathLike = string | Buffer | URL_url;
+type PathOrFileDescriptor = string | number | Buffer | URL_url;
 type Plugin =
 	| undefined
 	| null
@@ -305,40 +347,319 @@ type Plugin =
 	| 0
 	| { apply: (arg0: Resolver) => void }
 	| ((this: Resolver, arg1: Resolver) => void);
-declare interface PnpApiImpl {
+declare interface PnpApi {
 	resolveToUnqualified: (
 		arg0: string,
 		arg1: string,
 		arg2: object
 	) => null | string;
 }
-declare interface PossibleFileSystemError {
-	code?: string;
-	errno?: number;
-	path?: string;
-	syscall?: string;
+declare interface ReadFile {
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| undefined
+			| null
+			| ({ encoding?: null; flag?: string } & Abortable),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| ({ encoding: BufferEncoding; flag?: string } & Abortable)
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex",
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { flag?: string } & Abortable),
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathOrFileDescriptor,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
 }
-declare interface ReaddirOptions {
-	encoding?:
-		| null
-		| "ascii"
-		| "utf8"
-		| "utf-8"
-		| "utf16le"
-		| "ucs2"
-		| "ucs-2"
-		| "base64"
-		| "base64url"
-		| "latin1"
-		| "binary"
-		| "hex"
-		| "buffer";
-	withFileTypes?: boolean;
+declare interface ReadFileSync {
+	(
+		path: PathOrFileDescriptor,
+		options?: null | { encoding?: null; flag?: string }
+	): Buffer;
+	(
+		path: PathOrFileDescriptor,
+		options:
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| { encoding: BufferEncoding; flag?: string }
+	): string;
+	(
+		path: PathOrFileDescriptor,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { flag?: string })
+	): string | Buffer;
+}
+declare interface Readdir {
+	(
+		path: PathLike,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| {
+					encoding:
+						| null
+						| "ascii"
+						| "utf8"
+						| "utf-8"
+						| "utf16le"
+						| "utf-16le"
+						| "ucs2"
+						| "ucs-2"
+						| "base64"
+						| "base64url"
+						| "latin1"
+						| "binary"
+						| "hex";
+					withFileTypes?: false;
+					recursive?: boolean;
+			  },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string[]) => void
+	): void;
+	(
+		path: PathLike,
+		options:
+			| { encoding: "buffer"; withFileTypes?: false; recursive?: boolean }
+			| "buffer",
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer[]) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string[]) => void
+	): void;
+	(
+		path: PathLike,
+		options:
+			| undefined
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & {
+					withFileTypes?: false;
+					recursive?: boolean;
+			  }),
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string[] | Buffer[]
+		) => void
+	): void;
+	(
+		path: PathLike,
+		options: ObjectEncodingOptions & {
+			withFileTypes: true;
+			recursive?: boolean;
+		},
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Dirent[]) => void
+	): void;
+}
+declare interface ReaddirSync {
+	(
+		path: PathLike,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| {
+					encoding:
+						| null
+						| "ascii"
+						| "utf8"
+						| "utf-8"
+						| "utf16le"
+						| "utf-16le"
+						| "ucs2"
+						| "ucs-2"
+						| "base64"
+						| "base64url"
+						| "latin1"
+						| "binary"
+						| "hex";
+					withFileTypes?: false;
+					recursive?: boolean;
+			  }
+	): string[];
+	(
+		path: PathLike,
+		options:
+			| "buffer"
+			| { encoding: "buffer"; withFileTypes?: false; recursive?: boolean }
+	): Buffer[];
+	(
+		path: PathLike,
+		options?:
+			| null
+			| "ascii"
+			| "utf8"
+			| "utf-8"
+			| "utf16le"
+			| "utf-16le"
+			| "ucs2"
+			| "ucs-2"
+			| "base64"
+			| "base64url"
+			| "latin1"
+			| "binary"
+			| "hex"
+			| (ObjectEncodingOptions & { withFileTypes?: false; recursive?: boolean })
+	): string[] | Buffer[];
+	(
+		path: PathLike,
+		options: ObjectEncodingOptions & {
+			withFileTypes: true;
+			recursive?: boolean;
+		}
+	): Dirent[];
+}
+declare interface Readlink {
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathLike,
+		options: BufferEncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+}
+declare interface ReadlinkSync {
+	(path: PathLike, options?: EncodingOption): string;
+	(path: PathLike, options: BufferEncodingOption): Buffer;
+	(path: PathLike, options?: EncodingOption): string | Buffer;
+}
+declare interface RealPath {
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+	(
+		path: PathLike,
+		options: BufferEncodingOption,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: Buffer) => void
+	): void;
+	(
+		path: PathLike,
+		options: EncodingOption,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: string | Buffer
+		) => void
+	): void;
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: string) => void
+	): void;
+}
+declare interface RealPathSync {
+	(path: PathLike, options?: EncodingOption): string;
+	(path: PathLike, options: BufferEncodingOption): Buffer;
+	(path: PathLike, options?: EncodingOption): string | Buffer;
 }
-
-/**
- * Resolve context
- */
 declare interface ResolveContext {
 	contextDependencies?: WriteOnlySet<string>;
 
@@ -413,7 +734,12 @@ declare interface ResolveFunctionAsync {
 		) => void
 	): void;
 }
-declare interface ResolveOptions {
+type ResolveOptionsOptionalFS = Omit<
+	ResolveOptionsResolverFactoryObject_2,
+	"fileSystem"
+> &
+	Partial<Pick<ResolveOptionsResolverFactoryObject_2, "fileSystem">>;
+declare interface ResolveOptionsResolverFactoryObject_1 {
 	alias: AliasOption[];
 	fallback: AliasOption[];
 	aliasFields: Set<string | string[]>;
@@ -438,7 +764,7 @@ declare interface ResolveOptions {
 	mainFields: { name: string[]; forceRelative: boolean }[];
 	mainFiles: Set<string>;
 	plugins: Plugin[];
-	pnpApi: null | PnpApiImpl;
+	pnpApi: null | PnpApi;
 	roots: Set<string>;
 	fullySpecified: boolean;
 	resolveToContext: boolean;
@@ -446,65 +772,7 @@ declare interface ResolveOptions {
 	preferRelative: boolean;
 	preferAbsolute: boolean;
 }
-type ResolveOptionsOptionalFS = Omit<UserResolveOptions, "fileSystem"> &
-	Partial<Pick<UserResolveOptions, "fileSystem">>;
-type ResolveRequest = BaseResolveRequest & Partial<ParsedIdentifier>;
-declare abstract class Resolver {
-	fileSystem: FileSystem;
-	options: ResolveOptions;
-	hooks: KnownHooks;
-	ensureHook(
-		name:
-			| string
-			| AsyncSeriesBailHook<
-					[ResolveRequest, ResolveContext],
-					null | ResolveRequest
-			  >
-	): AsyncSeriesBailHook<
-		[ResolveRequest, ResolveContext],
-		null | ResolveRequest
-	>;
-	getHook(
-		name:
-			| string
-			| AsyncSeriesBailHook<
-					[ResolveRequest, ResolveContext],
-					null | ResolveRequest
-			  >
-	): AsyncSeriesBailHook<
-		[ResolveRequest, ResolveContext],
-		null | ResolveRequest
-	>;
-	resolveSync(context: object, path: string, request: string): string | false;
-	resolve(
-		context: object,
-		path: string,
-		request: string,
-		resolveContext: ResolveContext,
-		callback: (
-			err: null | ErrorWithDetail,
-			res?: string | false,
-			req?: ResolveRequest
-		) => void
-	): void;
-	doResolve(
-		hook: AsyncSeriesBailHook<
-			[ResolveRequest, ResolveContext],
-			null | ResolveRequest
-		>,
-		request: ResolveRequest,
-		message: null | string,
-		resolveContext: ResolveContext,
-		callback: (err?: null | Error, result?: ResolveRequest) => void
-	): void;
-	parse(identifier: string): ParsedIdentifier;
-	isModule(path: string): boolean;
-	isPrivate(path: string): boolean;
-	isDirectory(path: string): boolean;
-	join(path: string, request: string): string;
-	normalize(path: string): string;
-}
-declare interface UserResolveOptions {
+declare interface ResolveOptionsResolverFactoryObject_2 {
 	/**
 	 * A list of module alias configurations or an object which maps key to value
 	 */
@@ -612,7 +880,7 @@ declare interface UserResolveOptions {
 	/**
 	 * A PnP API that should be used - null is "never", undefined is "auto"
 	 */
-	pnpApi?: null | PnpApiImpl;
+	pnpApi?: null | PnpApi;
 
 	/**
 	 * A list of root paths
@@ -649,6 +917,120 @@ declare interface UserResolveOptions {
 	 */
 	preferAbsolute?: boolean;
 }
+type ResolveRequest = BaseResolveRequest & Partial<ParsedIdentifier>;
+declare abstract class Resolver {
+	fileSystem: FileSystem;
+	options: ResolveOptionsResolverFactoryObject_1;
+	hooks: KnownHooks;
+	ensureHook(
+		name:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	): AsyncSeriesBailHook<
+		[ResolveRequest, ResolveContext],
+		null | ResolveRequest
+	>;
+	getHook(
+		name:
+			| string
+			| AsyncSeriesBailHook<
+					[ResolveRequest, ResolveContext],
+					null | ResolveRequest
+			  >
+	): AsyncSeriesBailHook<
+		[ResolveRequest, ResolveContext],
+		null | ResolveRequest
+	>;
+	resolveSync(context: object, path: string, request: string): string | false;
+	resolve(
+		context: object,
+		path: string,
+		request: string,
+		resolveContext: ResolveContext,
+		callback: (
+			err: null | ErrorWithDetail,
+			res?: string | false,
+			req?: ResolveRequest
+		) => void
+	): void;
+	doResolve(
+		hook: AsyncSeriesBailHook<
+			[ResolveRequest, ResolveContext],
+			null | ResolveRequest
+		>,
+		request: ResolveRequest,
+		message: null | string,
+		resolveContext: ResolveContext,
+		callback: (err?: null | Error, result?: ResolveRequest) => void
+	): void;
+	parse(identifier: string): ParsedIdentifier;
+	isModule(path: string): boolean;
+	isPrivate(path: string): boolean;
+	isDirectory(path: string): boolean;
+	join(path: string, request: string): string;
+	normalize(path: string): string;
+}
+declare interface Stat {
+	(
+		path: PathLike,
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | (StatOptions & { bigint?: false }),
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: StatOptions & { bigint: true },
+		callback: (arg0: null | NodeJS.ErrnoException, arg1?: IBigIntStats) => void
+	): void;
+	(
+		path: PathLike,
+		options: undefined | StatOptions,
+		callback: (
+			arg0: null | NodeJS.ErrnoException,
+			arg1?: IStats | IBigIntStats
+		) => void
+	): void;
+}
+declare interface StatOptions {
+	bigint?: boolean;
+}
+declare interface StatSync {
+	(path: PathLike, options?: undefined): IStats;
+	(
+		path: PathLike,
+		options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }
+	): undefined | IStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }
+	): undefined | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats;
+	(path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats;
+	(
+		path: PathLike,
+		options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }
+	): IStats | IBigIntStats;
+	(path: PathLike, options?: StatSyncOptions):
+		| undefined
+		| IStats
+		| IBigIntStats;
+}
+declare interface StatSyncOptions {
+	bigint?: boolean;
+	throwIfNoEntry?: boolean;
+}
+
+/**
+ * `URL` class is a global reference for `require('url').URL`
+ * https://nodejs.org/api/url.html#the-whatwg-url-api
+ */
+declare interface URL_url extends URL_Import {}
 declare interface WriteOnlySet<T> {
 	add: (item: T) => void;
 }
@@ -701,7 +1083,9 @@ declare namespace exports {
 		export const sync: (options: ResolveOptionsOptionalFS) => ResolveFunction;
 	}
 	export namespace ResolverFactory {
-		export let createResolver: (options: UserResolveOptions) => Resolver;
+		export let createResolver: (
+			options: ResolveOptionsResolverFactoryObject_2
+		) => Resolver;
 	}
 	export const forEachBail: <T, Z>(
 		array: T[],
@@ -718,13 +1102,13 @@ declare namespace exports {
 		CloneBasenamePlugin,
 		LogInfoPlugin,
 		ResolveOptionsOptionalFS,
-		PnpApiImpl as PnpApi,
+		PnpApi,
 		Resolver,
 		FileSystem,
 		ResolveContext,
 		ResolveRequest,
 		Plugin,
-		UserResolveOptions as ResolveOptions,
+		ResolveOptionsResolverFactoryObject_2 as ResolveOptions,
 		ResolveFunctionAsync,
 		ResolveFunction
 	};
diff --git a/yarn.lock b/yarn.lock
index 63baca5b..7e0355bd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -906,10 +906,10 @@
   resolved "https://registry.yarnpkg.com/@types/node/-/node-20.1.7.tgz#ce10c802f7731909d0a44ac9888e8b3a9125eb62"
   integrity sha512-WCuw/o4GSwDGMoonES8rcvwsig77dGCMbZDrZr2x4ZZiNW4P/gcoZXe/0twgtobcTkmg9TuKflxYL/DuwDyJzg==
 
-"@types/node@^20.11.24":
-  version "20.11.24"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.11.24.tgz#cc207511104694e84e9fb17f9a0c4c42d4517792"
-  integrity sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==
+"@types/node@20.9.5":
+  version "20.9.5"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-20.9.5.tgz#bb441014bcb91c63742b0e1fe25b902f5d581faa"
+  integrity sha512-Uq2xbNq0chGg+/WQEU0LJTSs/1nKxz6u1iemLcGomkSnKokbW1fbLqc3HOqCf2JP7KjlL4QkS7oZZTrOQHQYgQ==
   dependencies:
     undici-types "~5.26.4"
 

From 13a3f1e2217ab3b34413620af69b6b0e031f1759 Mon Sep 17 00:00:00 2001
From: "alexander.akait" <sheo13666q@gmail.com>
Date: Wed, 6 Mar 2024 18:06:14 +0300
Subject: [PATCH 4/4] test: fix

---
 test/SyncAsyncFileSystemDecorator.test.js | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/test/SyncAsyncFileSystemDecorator.test.js b/test/SyncAsyncFileSystemDecorator.test.js
index 0f474fd6..200b5c85 100644
--- a/test/SyncAsyncFileSystemDecorator.test.js
+++ b/test/SyncAsyncFileSystemDecorator.test.js
@@ -14,7 +14,9 @@ describe("SyncAsyncFileSystemDecorator  stat", function () {
 				expect(error).toBeNull();
 				expect(result).toHaveProperty("size");
 				expect(result).toHaveProperty("birthtime");
-				expect(typeof result.size).toEqual("bigint");
+				expect(
+					typeof (/** @type {import("fs").BigIntStats} */ (result).size)
+				).toEqual("bigint");
 				done();
 			}
 		);
@@ -28,7 +30,9 @@ describe("SyncAsyncFileSystemDecorator  stat", function () {
 				expect(error).toBeNull();
 				expect(result).toHaveProperty("size");
 				expect(result).toHaveProperty("birthtime");
-				expect(typeof result.size).toEqual("number");
+				expect(
+					typeof (/** @type {import("fs").Stats} */ (result).size)
+				).toEqual("number");
 				done();
 			}
 		);