fix: `fs` types

This commit is contained in:
Alexander Akait 2024-03-11 18:15:08 +03:00 committed by GitHub
commit 94d874162a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 1829 additions and 532 deletions

View File

@ -3,6 +3,7 @@
"language": "en",
"words": [
"absolutify",
"abortable",
"acircular",
"amdmodule",
"analyse",

View File

@ -25,6 +25,7 @@ const GetFullHashRuntimeModule = require("./runtime/GetFullHashRuntimeModule");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("./Module").BuildInfo} BuildInfo */
/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("./javascript/JavascriptParser").Range} Range */
@ -187,7 +188,7 @@ class APIPlugin {
hooks.renderModuleContent.tap(
PLUGIN_NAME,
(source, module, renderContext) => {
if (module.buildInfo.needCreateRequire) {
if (/** @type {BuildInfo} */ (module.buildInfo).needCreateRequire) {
const chunkInitFragments = [
new InitFragment(
'import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module";\n',
@ -214,7 +215,8 @@ class APIPlugin {
const dep = toConstantDependency(parser, info.expr, info.req);
if (key === "__non_webpack_require__" && this.options.module) {
parser.state.module.buildInfo.needCreateRequire = true;
/** @type {BuildInfo} */
(parser.state.module.buildInfo).needCreateRequire = true;
}
return dep(expression);
@ -267,7 +269,8 @@ class APIPlugin {
parser.hooks.expression
.for("__webpack_module__.id")
.tap(PLUGIN_NAME, expr => {
parser.state.module.buildInfo.moduleConcatenationBailout =
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleConcatenationBailout =
"__webpack_module__.id";
const dep = new ConstDependency(
parser.state.module.moduleArgument + ".id",
@ -282,7 +285,8 @@ class APIPlugin {
parser.hooks.expression
.for("__webpack_module__")
.tap(PLUGIN_NAME, expr => {
parser.state.module.buildInfo.moduleConcatenationBailout =
/** @type {BuildInfo} */
(parser.state.module.buildInfo).moduleConcatenationBailout =
"__webpack_module__";
const dep = new ConstDependency(
parser.state.module.moduleArgument,

View File

@ -12,6 +12,7 @@ const { compareModulesById } = require("./util/comparators");
const { dirname, mkdirp } = require("./util/fs");
/** @typedef {import("./Compiler")} Compiler */
/** @typedef {import("./Compiler").IntermediateFileSystem} IntermediateFileSystem */
/** @typedef {import("./Module").BuildMeta} BuildMeta */
/**
@ -113,16 +114,16 @@ class LibManifestPlugin {
? JSON.stringify(manifest, null, 2)
: JSON.stringify(manifest);
const buffer = Buffer.from(manifestContent, "utf8");
const intermediateFileSystem =
/** @type {IntermediateFileSystem} */ (
compiler.intermediateFileSystem
);
mkdirp(
compiler.intermediateFileSystem,
dirname(compiler.intermediateFileSystem, targetPath),
intermediateFileSystem,
dirname(intermediateFileSystem, targetPath),
err => {
if (err) return callback(err);
compiler.intermediateFileSystem.writeFile(
targetPath,
buffer,
callback
);
intermediateFileSystem.writeFile(targetPath, buffer, callback);
}
);
},

View File

@ -86,7 +86,9 @@ class RuntimeTemplate {
this.compilation = compilation;
this.outputOptions = outputOptions || {};
this.requestShortener = requestShortener;
this.globalObject = getGlobalObject(outputOptions.globalObject);
this.globalObject =
/** @type {string} */
(getGlobalObject(outputOptions.globalObject));
this.contentHashReplacement = "X".repeat(
/** @type {NonNullable<OutputOptions["hashDigestLength"]>} */
(outputOptions.hashDigestLength)

View File

@ -18,7 +18,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
/**
* @param {JavascriptParser} parser the parser
* @param {string} value the const value
* @param {string[]=} runtimeRequirements runtime requirements
* @param {(string[] | null)=} runtimeRequirements runtime requirements
* @returns {function(Expression): true} plugin function
*/
exports.toConstantDependency = (parser, value, runtimeRequirements) => {

View File

@ -95,19 +95,32 @@ class WebpackLogger {
this[LOG_SYMBOL](LogType.groupEnd, args);
}
/**
* @param {string=} label label
*/
profile(label) {
this[LOG_SYMBOL](LogType.profile, [label]);
}
/**
* @param {string=} label label
*/
profileEnd(label) {
this[LOG_SYMBOL](LogType.profileEnd, [label]);
}
/**
* @param {string} label label
*/
time(label) {
/** @type {Map<string | undefined, [number, number]>} */
this[TIMERS_SYMBOL] = this[TIMERS_SYMBOL] || new Map();
this[TIMERS_SYMBOL].set(label, process.hrtime());
}
/**
* @param {string=} label label
*/
timeLog(label) {
const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
if (!prev) {
@ -117,16 +130,23 @@ class WebpackLogger {
this[LOG_SYMBOL](LogType.time, [label, ...time]);
}
/**
* @param {string=} label label
*/
timeEnd(label) {
const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
if (!prev) {
throw new Error(`No such label '${label}' for WebpackLogger.timeEnd()`);
}
const time = process.hrtime(prev);
this[TIMERS_SYMBOL].delete(label);
/** @type {Map<string | undefined, [number, number]>} */
(this[TIMERS_SYMBOL]).delete(label);
this[LOG_SYMBOL](LogType.time, [label, ...time]);
}
/**
* @param {string=} label label
*/
timeAggregate(label) {
const prev = this[TIMERS_SYMBOL] && this[TIMERS_SYMBOL].get(label);
if (!prev) {
@ -135,7 +155,9 @@ class WebpackLogger {
);
}
const time = process.hrtime(prev);
this[TIMERS_SYMBOL].delete(label);
/** @type {Map<string | undefined, [number, number]>} */
(this[TIMERS_SYMBOL]).delete(label);
/** @type {Map<string | undefined, [number, number]>} */
this[TIMERS_AGGREGATES_SYMBOL] =
this[TIMERS_AGGREGATES_SYMBOL] || new Map();
const current = this[TIMERS_AGGREGATES_SYMBOL].get(label);
@ -151,6 +173,9 @@ class WebpackLogger {
this[TIMERS_AGGREGATES_SYMBOL].set(label, time);
}
/**
* @param {string=} label label
*/
timeAggregateEnd(label) {
if (this[TIMERS_AGGREGATES_SYMBOL] === undefined) return;
const time = this[TIMERS_AGGREGATES_SYMBOL].get(label);

View File

@ -41,7 +41,7 @@ const { LogType } = require("./Logger");
/**
* @param {FilterItemTypes} item an input item
* @returns {FilterFunction} filter function
* @returns {FilterFunction | undefined} filter function
*/
const filterToFunction = item => {
if (typeof item === "string") {
@ -81,11 +81,14 @@ const LogLevel = {
*/
module.exports = ({ level = "info", debug = false, console }) => {
const debugFilters =
/** @type {FilterFunction[]} */
(
typeof debug === "boolean"
? [() => debug]
: /** @type {FilterItemTypes[]} */ ([])
.concat(debug)
.map(filterToFunction);
.map(filterToFunction)
);
/** @type {number} */
const loglevel = LogLevel[`${level}`] || 0;

View File

@ -5,7 +5,7 @@
"use strict";
const CachedInputFileSystem = require("enhanced-resolve/lib/CachedInputFileSystem");
const CachedInputFileSystem = require("enhanced-resolve").CachedInputFileSystem;
const fs = require("graceful-fs");
const createConsoleLogger = require("../logging/createConsoleLogger");
const NodeWatchFileSystem = require("./NodeWatchFileSystem");
@ -13,6 +13,7 @@ const nodeConsole = require("./nodeConsole");
/** @typedef {import("../../declarations/WebpackOptions").InfrastructureLogging} InfrastructureLogging */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
class NodeEnvironmentPlugin {
/**
@ -38,18 +39,23 @@ class NodeEnvironmentPlugin {
nodeConsole({
colors: infrastructureLogging.colors,
appendOnly: infrastructureLogging.appendOnly,
stream: infrastructureLogging.stream
stream:
/** @type {NodeJS.WritableStream} */
(infrastructureLogging.stream)
})
});
compiler.inputFileSystem = new CachedInputFileSystem(fs, 60000);
const inputFileSystem = compiler.inputFileSystem;
const inputFileSystem =
/** @type {InputFileSystem} */
(compiler.inputFileSystem);
compiler.outputFileSystem = fs;
compiler.intermediateFileSystem = fs;
compiler.watchFileSystem = new NodeWatchFileSystem(
compiler.inputFileSystem
);
compiler.watchFileSystem = new NodeWatchFileSystem(inputFileSystem);
compiler.hooks.beforeRun.tap("NodeEnvironmentPlugin", compiler => {
if (compiler.inputFileSystem === inputFileSystem) {
if (
compiler.inputFileSystem === inputFileSystem &&
inputFileSystem.purge
) {
compiler.fsStartTime = Date.now();
inputFileSystem.purge();
}

View File

@ -10,11 +10,15 @@ const Watchpack = require("watchpack");
/** @typedef {import("../../declarations/WebpackOptions").WatchOptions} WatchOptions */
/** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
/** @typedef {import("../util/fs").InputFileSystem} InputFileSystem */
/** @typedef {import("../util/fs").WatchFileSystem} WatchFileSystem */
/** @typedef {import("../util/fs").WatchMethod} WatchMethod */
/** @typedef {import("../util/fs").Watcher} Watcher */
class NodeWatchFileSystem {
/**
* @param {InputFileSystem} inputFileSystem input filesystem
*/
constructor(inputFileSystem) {
this.inputFileSystem = inputFileSystem;
this.watcherOptions = {
@ -29,7 +33,7 @@ class NodeWatchFileSystem {
* @param {Iterable<string>} missing watched exitance entries
* @param {number} startTime timestamp of start time
* @param {WatchOptions} options options object
* @param {function((Error | null)=, Map<string, FileSystemInfoEntry>, Map<string, FileSystemInfoEntry>, Set<string>, Set<string>): void} callback aggregated callback
* @param {function(Error | null, Map<string, FileSystemInfoEntry>, Map<string, FileSystemInfoEntry>, Set<string>, Set<string>): void} callback aggregated callback
* @param {function(string, number): void} callbackUndelayed callback when the first change was detected
* @returns {Watcher} a watcher
*/
@ -81,12 +85,18 @@ class NodeWatchFileSystem {
}
return { fileTimeInfoEntries, contextTimeInfoEntries };
};
this.watcher.once("aggregated", (changes, removals) => {
this.watcher.once(
"aggregated",
/**
* @param {Set<string>} changes changes
* @param {Set<string>} removals removals
*/
(changes, removals) => {
// pause emitting events (avoids clearing aggregated changes and removals on timeout)
this.watcher.pause();
if (this.inputFileSystem && this.inputFileSystem.purge) {
const fs = this.inputFileSystem;
if (fs && fs.purge) {
for (const item of changes) {
fs.purge(item);
}
@ -102,7 +112,8 @@ class NodeWatchFileSystem {
changes,
removals
);
});
}
);
this.watcher.watch({ files, directories, missing, startTime });
@ -124,8 +135,8 @@ class NodeWatchFileSystem {
getAggregatedRemovals: util.deprecate(
() => {
const items = this.watcher && this.watcher.aggregatedRemovals;
if (items && this.inputFileSystem && this.inputFileSystem.purge) {
const fs = this.inputFileSystem;
if (items && fs && fs.purge) {
for (const item of items) {
fs.purge(item);
}
@ -138,8 +149,8 @@ class NodeWatchFileSystem {
getAggregatedChanges: util.deprecate(
() => {
const items = this.watcher && this.watcher.aggregatedChanges;
if (items && this.inputFileSystem && this.inputFileSystem.purge) {
const fs = this.inputFileSystem;
if (items && fs && fs.purge) {
for (const item of items) {
fs.purge(item);
}
@ -166,8 +177,8 @@ class NodeWatchFileSystem {
getInfo: () => {
const removals = this.watcher && this.watcher.aggregatedRemovals;
const changes = this.watcher && this.watcher.aggregatedChanges;
if (this.inputFileSystem && this.inputFileSystem.purge) {
const fs = this.inputFileSystem;
if (fs && fs.purge) {
if (removals) {
for (const item of removals) {
fs.purge(item);

View File

@ -8,12 +8,29 @@
const util = require("util");
const truncateArgs = require("../logging/truncateArgs");
/** @typedef {import("../logging/createConsoleLogger").LoggerConsole} LoggerConsole */
/**
* @param {Object} options options
* @param {boolean=} options.colors colors
* @param {boolean=} options.appendOnly append only
* @param {NodeJS.WritableStream} options.stream stream
* @returns {LoggerConsole} logger function
*/
module.exports = ({ colors, appendOnly, stream }) => {
/** @type {string[] | undefined} */
let currentStatusMessage = undefined;
let hasStatusMessage = false;
let currentIndent = "";
let currentCollapsed = 0;
/**
* @param {string} str string
* @param {string} prefix prefix
* @param {string} colorPrefix color prefix
* @param {string} colorSuffix color suffix
* @returns {string} indented string
*/
const indent = (str, prefix, colorPrefix, colorSuffix) => {
if (str === "") return str;
prefix = currentIndent + prefix;
@ -38,7 +55,7 @@ module.exports = ({ colors, appendOnly, stream }) => {
const writeStatusMessage = () => {
if (!currentStatusMessage) return;
const l = stream.columns || 40;
const l = /** @type {TODO} */ (stream).columns || 40;
const args = truncateArgs(currentStatusMessage, l - 1);
const str = args.join(" ");
const coloredStr = `\u001b[1m${str}\u001b[39m\u001b[22m`;
@ -46,6 +63,12 @@ module.exports = ({ colors, appendOnly, stream }) => {
hasStatusMessage = true;
};
/**
* @param {string} prefix prefix
* @param {string} colorPrefix color prefix
* @param {string} colorSuffix color suffix
* @returns {(function(...any[]): void)} function to write with colors
*/
const writeColored = (prefix, colorPrefix, colorSuffix) => {
return (...args) => {
if (currentCollapsed > 0) return;

View File

@ -9,6 +9,10 @@
/** @typedef {import("./RuleSetCompiler").RuleCondition} RuleCondition */
class ObjectMatcherRulePlugin {
/**
* @param {string} ruleProperty the rule property
* @param {string=} dataProperty the data property
*/
constructor(ruleProperty, dataProperty) {
this.ruleProperty = ruleProperty;
this.dataProperty = dataProperty || ruleProperty;

View File

@ -11,7 +11,8 @@ const path = require("path");
/** @typedef {import("../FileSystemInfo").FileSystemInfoEntry} FileSystemInfoEntry */
/**
* @typedef {Object} IStats
* @template T
* @typedef {Object} IStatsBase
* @property {() => boolean} isFile
* @property {() => boolean} isDirectory
* @property {() => boolean} isBlockDevice
@ -19,20 +20,20 @@ const path = require("path");
* @property {() => boolean} isSymbolicLink
* @property {() => boolean} isFIFO
* @property {() => boolean} isSocket
* @property {number | bigint} dev
* @property {number | bigint} ino
* @property {number | bigint} mode
* @property {number | bigint} nlink
* @property {number | bigint} uid
* @property {number | bigint} gid
* @property {number | bigint} rdev
* @property {number | bigint} size
* @property {number | bigint} blksize
* @property {number | bigint} blocks
* @property {number | bigint} atimeMs
* @property {number | bigint} mtimeMs
* @property {number | bigint} ctimeMs
* @property {number | bigint} birthtimeMs
* @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
@ -40,7 +41,15 @@ const path = require("path");
*/
/**
* @typedef {Object} IDirent
* @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
@ -48,18 +57,28 @@ const path = require("path");
* @property {() => boolean} isSymbolicLink
* @property {() => boolean} isFIFO
* @property {() => boolean} isSocket
* @property {string | Buffer} name
* @property {string} name
* @property {string} path
*/
/** @typedef {function((NodeJS.ErrnoException | null)=): void} Callback */
/** @typedef {function((NodeJS.ErrnoException | null)=, Buffer=): void} BufferCallback */
/** @typedef {function((NodeJS.ErrnoException | null)=, Buffer|string=): void} BufferOrStringCallback */
/** @typedef {function((NodeJS.ErrnoException | null)=, (string | Buffer)[] | IDirent[]=): void} DirentArrayCallback */
/** @typedef {function((NodeJS.ErrnoException | null)=, string=): void} StringCallback */
/** @typedef {function((NodeJS.ErrnoException | null)=, number=): void} NumberCallback */
/** @typedef {function((NodeJS.ErrnoException | null)=, IStats=): void} StatsCallback */
/** @typedef {function((NodeJS.ErrnoException | Error | null)=, any=): void} ReadJsonCallback */
/** @typedef {function((NodeJS.ErrnoException | Error | null)=, IStats|string=): void} LstatReadlinkAbsoluteCallback */
/** @typedef {string | number | boolean | null} JsonPrimitive */
/** @typedef {JsonValue[]} JsonArray */
/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */
/** @typedef {{[Key in string]: JsonValue} & {[Key in string]?: JsonValue | undefined}} JsonObject */
/** @typedef {function(NodeJS.ErrnoException | null): void} NoParamCallback */
/** @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, (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 */
/** @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 | null, number=): void} NumberCallback */
/** @typedef {function(NodeJS.ErrnoException | Error | null, JsonObject=): void} ReadJsonCallback */
/**
* @typedef {Object} WatcherInfo
@ -88,38 +107,244 @@ const path = require("path");
* @param {Iterable<string>} missing watched exitance entries
* @param {number} startTime timestamp of start time
* @param {WatchOptions} options options object
* @param {function(Error=, Map<string, FileSystemInfoEntry | "ignore">, Map<string, FileSystemInfoEntry | "ignore">, Set<string>, Set<string>): void} callback aggregated callback
* @param {function(Error | null, Map<string, FileSystemInfoEntry | "ignore">, Map<string, FileSystemInfoEntry | "ignore">, Set<string>, Set<string>): void} callback aggregated callback
* @param {function(string, number): void} callbackUndelayed callback when the first change was detected
* @returns {Watcher} a watcher
*/
// TODO webpack 6 make optional methods required
// TODO webpack 6 make optional methods required and avoid using non standard methods like `join`, `relative`, `dirname`, move IntermediateFileSystemExtras methods to InputFilesystem or OutputFilesystem
/**
* @typedef {Object} OutputFileSystem
* @property {function(string, Buffer|string, Callback): void} writeFile
* @property {function(string, Callback): void} mkdir
* @property {function(string, DirentArrayCallback): void=} readdir
* @property {function(string, Callback): void=} rmdir
* @property {function(string, Callback): void=} unlink
* @property {function(string, StatsCallback): void} stat
* @property {function(string, StatsCallback): void=} lstat
* @property {function(string, BufferOrStringCallback): void} readFile
* @typedef {string | Buffer | URL} PathLike
*/
/**
* @typedef {PathLike | number} PathOrFileDescriptor
*/
/**
* @typedef {Object} ObjectEncodingOptions
* @property {BufferEncoding | null | undefined} [encoding]
*/
/**
* @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 {{
* (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 {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption
*/
/**
* @typedef {'buffer'| { encoding: 'buffer' }} BufferEncodingOption
*/
/**
* @typedef {Object} StatOptions
* @property {(boolean | undefined)=} bigint
*/
/**
* @typedef {Object} StatSyncOptions
* @property {(boolean | undefined)=} bigint
* @property {(boolean | undefined)=} throwIfNoEntry
*/
/**
* @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, 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 {{
* (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, 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, 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 {{
* (path: PathLike, options?: EncodingOption): string;
* (path: PathLike, options: BufferEncodingOption): Buffer;
* (path: PathLike, options?: EncodingOption): string | Buffer;
* }} RealPathSync
*/
/**
* @typedef {function(PathOrFileDescriptor, ReadJsonCallback): void} ReadJson
*/
/**
* @typedef {function(PathOrFileDescriptor): JsonObject} ReadJsonSync
*/
/**
* @typedef {function((string | string[] | Set<string>)=): void} Purge
*/
/**
* @typedef {Object} InputFileSystem
* @property {ReadFile} readFile
* @property {ReadFileSync=} readFileSync
* @property {Readlink} readlink
* @property {ReadlinkSync=} readlinkSync
* @property {Readdir} readdir
* @property {ReaddirSync=} readdirSync
* @property {Stat} stat
* @property {StatSync=} statSync
* @property {LStat=} lstat
* @property {LStatSync=} lstatSync
* @property {RealPath=} realpath
* @property {RealPathSync=} realpathSync
* @property {ReadJson=} readJson
* @property {ReadJsonSync=} readJsonSync
* @property {Purge=} purge
* @property {(function(string, string): string)=} join
* @property {(function(string, string): string)=} relative
* @property {(function(string): string)=} dirname
*/
/**
* @typedef {Object} InputFileSystem
* @property {function(string, BufferOrStringCallback): void} readFile
* @property {(function(string, ReadJsonCallback): void)=} readJson
* @property {function(string, BufferOrStringCallback): void} readlink
* @property {function(string, DirentArrayCallback): void} readdir
* @property {function(string, StatsCallback): void} stat
* @property {function(string, StatsCallback): void=} lstat
* @property {(function(string, BufferOrStringCallback): void)=} realpath
* @property {(function(string=): void)=} purge
* @typedef {number | string} Mode
*/
/**
* @typedef {(ObjectEncodingOptions & import("events").Abortable & { mode?: Mode | undefined, flag?: string | undefined, flush?: boolean | undefined }) | BufferEncoding | null} WriteFileOptions
*/
/**
* @typedef {{
* (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, options: WriteFileOptions, callback: NoParamCallback): void;
* (file: PathOrFileDescriptor, data: string | NodeJS.ArrayBufferView, callback: NoParamCallback): void;
* }} WriteFile
*/
/**
* @typedef {{ recursive?: boolean | undefined, mode?: Mode | undefined }} MakeDirectoryOptions
*/
/**
* @typedef {{
* (file: PathLike, options: MakeDirectoryOptions & { recursive: true }, callback: StringCallback): void;
* (file: PathLike, options: Mode | (MakeDirectoryOptions & { recursive?: false | undefined; }) | null | undefined, callback: NoParamCallback): void;
* (file: PathLike, options: Mode | MakeDirectoryOptions | null | undefined, callback: StringCallback): void;
* (file: PathLike, callback: NoParamCallback): void;
* }} Mkdir
*/
/**
* @typedef {{ maxRetries?: number | undefined, recursive?: boolean | undefined, retryDelay?: number | undefined }} RmDirOptions
*/
/**
* @typedef {{
* (file: PathLike, callback: NoParamCallback): void;
* (file: PathLike, options: RmDirOptions, callback: NoParamCallback): void;
* }} Rmdir
*/
/**
* @typedef {function(PathLike, NoParamCallback): void} Unlink
*/
/**
* @typedef {Object} OutputFileSystem
* @property {WriteFile} writeFile
* @property {Mkdir} mkdir
* @property {Readdir=} readdir
* @property {Rmdir=} rmdir
* @property {Unlink=} unlink
* @property {Stat} stat
* @property {LStat=} lstat
* @property {ReadFile} readFile
* @property {(function(string, string): string)=} join
* @property {(function(string, string): string)=} relative
* @property {(function(string): string)=} dirname
@ -130,14 +355,97 @@ const path = require("path");
* @property {WatchMethod} watch
*/
/**
* @typedef {{
* (path: PathLike, options: MakeDirectoryOptions & { recursive: true }): string | undefined;
* (path: PathLike, options?: Mode | (MakeDirectoryOptions & { recursive?: false | undefined }) | null): void;
* (path: PathLike, options?: Mode | MakeDirectoryOptions | null): string | undefined;
* }} MkdirSync
*/
/**
* @typedef {Object} StreamOptions
* @property {(string | undefined)=} flags
* @property {(BufferEncoding | undefined)} encoding
* @property {(number | any | undefined)=} fd
* @property {(number | undefined)=} mode
* @property {(boolean | undefined)=} autoClose
* @property {(boolean | undefined)=} emitClose
* @property {(number | undefined)=} start
* @property {(AbortSignal | null | undefined)=} signal
*/
/**
* @typedef {Object} FSImplementation
* @property {((...args: any[]) => any)=} open
* @property {((...args: any[]) => any)=} close
*/
/**
* @typedef {FSImplementation & { write: (...args: any[]) => any; close?: (...args: any[]) => any }} CreateWriteStreamFSImplementation
*/
/**
* @typedef {StreamOptions & { fs?: CreateWriteStreamFSImplementation | null | undefined }} WriteStreamOptions
*/
/**
* @typedef {function(PathLike, (BufferEncoding | WriteStreamOptions)=): NodeJS.WritableStream} CreateWriteStream
*/
/**
* @typedef {number | string} OpenMode
*/
/**
* @typedef {{
* (file: PathLike, flags: OpenMode | undefined, mode: Mode | undefined | null, callback: NumberCallback): void;
* (file: PathLike, flags: OpenMode | undefined, callback: NumberCallback): void;
* (file: PathLike, callback: NumberCallback): void;
* }} Open
*/
/**
* @typedef {number | bigint} ReadPosition
*/
/**
* @typedef {Object} ReadSyncOptions
* @property {(number | undefined)=} offset
* @property {(number | undefined)=} length
* @property {(ReadPosition | null | undefined)=} position
*/
/**
* @template {NodeJS.ArrayBufferView} TBuffer
* @typedef {Object} ReadAsyncOptions
* @property {(number | undefined)=} offset
* @property {(number | undefined)=} length
* @property {(ReadPosition | null | undefined)=} position
* @property {TBuffer=} buffer
*/
/**
* @template {NodeJS.ArrayBufferView} [TBuffer=Buffer]
* @typedef {{
* (fd: number, buffer: TBuffer, offset: number, length: number, position: ReadPosition | null, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void;
* (fd: number, options: ReadAsyncOptions<TBuffer>, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: TBuffer) => void): void;
* (fd: number, callback: (err: NodeJS.ErrnoException | null, bytesRead: number, buffer: NodeJS.ArrayBufferView) => void): void;
* }} Read
*/
/** @typedef {function(number, NoParamCallback): void} Close */
/** @typedef {function(PathLike, PathLike, NoParamCallback): void} Rename */
/**
* @typedef {Object} IntermediateFileSystemExtras
* @property {function(string): void} mkdirSync
* @property {function(string): NodeJS.WritableStream} createWriteStream
* @property {function(string, string, NumberCallback): void} open
* @property {function(number, Buffer, number, number, number, NumberCallback): void} read
* @property {function(number, Callback): void} close
* @property {function(string, string, Callback): void} rename
* @property {MkdirSync} mkdirSync
* @property {CreateWriteStream} createWriteStream
* @property {Open} open
* @property {Read} read
* @property {Close} close
* @property {Rename} rename
*/
/** @typedef {InputFileSystem & OutputFileSystem & IntermediateFileSystemExtras} IntermediateFileSystem */
@ -260,7 +568,7 @@ const mkdirpSync = (fs, p) => {
fs.mkdirSync(p);
} catch (err) {
if (err) {
if (err.code === "ENOENT") {
if (/** @type {NodeJS.ErrnoException} */ (err).code === "ENOENT") {
const dir = dirname(fs, p);
if (dir === p) {
throw err;
@ -268,7 +576,7 @@ const mkdirpSync = (fs, p) => {
mkdirpSync(fs, dir);
fs.mkdirSync(p);
return;
} else if (err.code === "EEXIST") {
} else if (/** @type {NodeJS.ErrnoException} */ (err).code === "EEXIST") {
return;
}
throw err;
@ -304,7 +612,7 @@ exports.readJson = readJson;
/**
* @param {InputFileSystem} fs a file system
* @param {string} p an absolute path
* @param {ReadJsonCallback} callback callback
* @param {function(NodeJS.ErrnoException | Error | null, (IStats | string)=): void} callback callback
* @returns {void}
*/
const lstatReadlinkAbsolute = (fs, p, callback) => {

View File

@ -14,12 +14,12 @@
"acorn-import-assertions": "^1.9.0",
"browserslist": "^4.21.10",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.15.0",
"enhanced-resolve": "^5.16.0",
"es-module-lexer": "^1.2.1",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
"glob-to-regexp": "^0.4.1",
"graceful-fs": "^4.2.9",
"graceful-fs": "^4.2.11",
"json-parse-even-better-errors": "^2.3.1",
"loader-runner": "^4.2.0",
"mime-types": "^2.1.27",
@ -80,7 +80,7 @@
"lint-staged": "^13.2.1",
"lodash": "^4.17.19",
"lodash-es": "^4.17.15",
"memfs": "^3.5.0",
"memfs": "^3.6.0",
"mini-css-extract-plugin": "^1.6.1",
"mini-svg-data-uri": "^1.2.3",
"nyc": "^15.1.0",

View File

@ -5,8 +5,14 @@ const fs = require("fs");
module.exports = {
plugins: [
compiler => {
// eslint-disable-next-line no-warning-comments
// @ts-ignore
compiler.outputFileSystem = memfs.fs;
// eslint-disable-next-line no-warning-comments
// @ts-ignore
compiler.inputFileSystem = memfs.fs;
// eslint-disable-next-line no-warning-comments
// @ts-ignore
compiler.intermediateFileSystem = memfs.fs;
compiler.outputFileSystem = fs;

1701
types.d.ts vendored

File diff suppressed because it is too large Load Diff

View File

@ -2535,10 +2535,10 @@ emojis-list@^3.0.0:
resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78"
integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0:
version "5.15.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35"
integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
enhanced-resolve@^5.0.0, enhanced-resolve@^5.16.0:
version "5.16.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz#65ec88778083056cb32487faa9aef82ed0864787"
integrity sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
@ -3258,7 +3258,7 @@ globby@^11.1.0:
merge2 "^1.4.1"
slash "^3.0.0"
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
@ -4533,10 +4533,10 @@ map-obj@^4.3.0:
resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a"
integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==
memfs@^3.4.1, memfs@^3.5.0:
version "3.5.3"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.5.3.tgz#d9b40fe4f8d5788c5f895bda804cd0d9eeee9f3b"
integrity sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==
memfs@^3.4.1, memfs@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6"
integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ==
dependencies:
fs-monkey "^1.0.4"