Deployed the page to Github Pages.

This commit is contained in:
Batuhan Berk Başoğlu 2024-11-03 21:30:09 -05:00
parent 1d79754e93
commit 2c89899458
Signed by: batuhan-basoglu
SSH key fingerprint: SHA256:kEsnuHX+qbwhxSAXPUQ4ox535wFHu/hIRaa53FzxRpo
62797 changed files with 6551425 additions and 15279 deletions

20
node_modules/enhanced-resolve/LICENSE generated vendored Normal file
View file

@ -0,0 +1,20 @@
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

183
node_modules/enhanced-resolve/README.md generated vendored Normal file
View file

@ -0,0 +1,183 @@
# enhanced-resolve
[![npm][npm]][npm-url]
[![Build Status][build-status]][build-status-url]
[![codecov][codecov-badge]][codecov-url]
[![Install Size][size]][size-url]
[![GitHub Discussions][discussion]][discussion-url]
Offers an async require.resolve function. It's highly configurable.
## Features
- plugin system
- provide a custom filesystem
- sync and async node.js filesystems included
## Getting Started
### Install
```sh
# npm
npm install enhanced-resolve
# or Yarn
yarn add enhanced-resolve
```
### Resolve
There is a Node.js API which allows to resolve requests according to the Node.js resolving rules.
Sync and async APIs are offered. A `create` method allows to create a custom resolve function.
```js
const resolve = require("enhanced-resolve");
resolve("/some/path/to/folder", "module/dir", (err, result) => {
result; // === "/some/path/node_modules/module/dir/index.js"
});
resolve.sync("/some/path/to/folder", "../../dir");
// === "/some/path/dir/index.js"
const myResolve = resolve.create({
// or resolve.create.sync
extensions: [".ts", ".js"]
// see more options below
});
myResolve("/some/path/to/folder", "ts-module", (err, result) => {
result; // === "/some/node_modules/ts-module/index.ts"
});
```
### Creating a Resolver
The easiest way to create a resolver is to use the `createResolver` function on `ResolveFactory`, along with one of the supplied File System implementations.
```js
const fs = require("fs");
const { CachedInputFileSystem, ResolverFactory } = require("enhanced-resolve");
// create a resolver
const myResolver = ResolverFactory.createResolver({
// Typical usage will consume the `fs` + `CachedInputFileSystem`, which wraps Node.js `fs` to add caching.
fileSystem: new CachedInputFileSystem(fs, 4000),
extensions: [".js", ".json"]
/* any other resolver options here. Options/defaults can be seen below */
});
// resolve a file with the new resolver
const context = {};
const lookupStartPath = "/Users/webpack/some/root/dir";
const request = "./path/to-look-up.js";
const resolveContext = {};
myResolver.resolve(context, lookupStartPath, request, resolveContext, (
err /*Error*/,
filepath /*string*/
) => {
// Do something with the path
});
```
#### Resolver Options
| Field | Default | Description |
|------------------|-----------------------------| --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| alias | [] | A list of module alias configurations or an object which maps key to value |
| aliasFields | [] | A list of alias fields in description files |
| extensionAlias | {} | An object which maps extension to extension aliases |
| cachePredicate | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with `path` and `request` properties. |
| cacheWithContext | true | If unsafe cache is enabled, includes `request.context` in the cache key |
| conditionNames | [] | A list of exports field condition names |
| descriptionFiles | ["package.json"] | A list of description files to read from |
| enforceExtension | false | Enforce that a extension from extensions must be used |
| exportsFields | ["exports"] | A list of exports fields in description files |
| extensions | [".js", ".json", ".node"] | A list of extensions which should be tried for files |
| fallback | [] | Same as `alias`, but only used if default resolving fails |
| fileSystem | | The file system which should be used |
| fullySpecified | false | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) |
| mainFields | ["main"] | A list of main fields in description files |
| mainFiles | ["index"] | A list of main files in directories |
| modules | ["node_modules"] | A list of directories to resolve modules from, can be absolute path or folder name |
| plugins | [] | A list of additional resolve plugins which should be applied |
| resolver | undefined | A prepared Resolver to which the plugins are attached |
| resolveToContext | false | Resolve to a context instead of a file |
| preferRelative | false | Prefer to resolve module requests as relative request and fallback to resolving as module |
| preferAbsolute | false | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots |
| restrictions | [] | A list of resolve restrictions |
| roots | [] | A list of root paths |
| symlinks | true | Whether to resolve symlinks to their symlinked location |
| unsafeCache | false | Use this cache object to unsafely cache the successful requests |
## Plugins
Similar to `webpack`, the core of `enhanced-resolve` functionality is implemented as individual plugins that are executed using [`tapable`](https://github.com/webpack/tapable).
These plugins can extend the functionality of the library, adding other ways for files/contexts to be resolved.
A plugin should be a `class` (or its ES5 equivalent) with an `apply` method. The `apply` method will receive a `resolver` instance, that can be used to hook in to the event system.
### Plugin Boilerplate
```js
class MyResolverPlugin {
constructor(source, target) {
this.source = source;
this.target = target;
}
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("MyResolverPlugin", (request, resolveContext, callback) => {
// Any logic you need to create a new `request` can go here
resolver.doResolve(target, request, null, resolveContext, callback);
});
}
}
```
Plugins are executed in a pipeline, and register which event they should be executed before/after. In the example above, `source` is the name of the event that starts the pipeline, and `target` is what event this plugin should fire, which is what continues the execution of the pipeline. For an example of how these different plugin events create a chain, see `lib/ResolverFactory.js`, in the `//// pipeline ////` section.
## Escaping
It's allowed to escape `#` as `\0#` to avoid parsing it as fragment.
enhanced-resolve will try to resolve requests containing `#` as path and as fragment, so it will automatically figure out if `./some#thing` means `.../some.js#thing` or `.../some#thing.js`. When a `#` is resolved as path it will be escaped in the result. Here: `.../some\0#thing.js`.
## Tests
```javascript
yarn test
```
## Passing options from webpack
If you are using `webpack`, and you want to pass custom options to `enhanced-resolve`, the options are passed from the `resolve` key of your webpack configuration e.g.:
```
resolve: {
extensions: ['.js', '.jsx'],
modules: [path.resolve(__dirname, 'src'), 'node_modules'],
plugins: [new DirectoryNamedWebpackPlugin()]
...
},
```
## License
Copyright (c) 2012-2019 JS Foundation and other contributors
MIT (http://www.opensource.org/licenses/mit-license.php)
[npm]: https://img.shields.io/npm/v/enhanced-resolve.svg
[npm-url]: https://www.npmjs.com/package/enhanced-resolve
[build-status]: https://github.com/webpack/enhanced-resolve/actions/workflows/test.yml/badge.svg?branch=master
[build-status-url]: https://github.com/webpack/enhanced-resolve/actions
[codecov-badge]: https://codecov.io/gh/webpack/enhanced-resolve/branch/main/graph/badge.svg?token=6B6NxtsZc3
[codecov-url]: https://codecov.io/gh/webpack/enhanced-resolve
[size]: https://packagephobia.com/badge?p=enhanced-resolve
[size-url]: https://packagephobia.com/result?p=enhanced-resolve
[discussion]: https://img.shields.io/github/discussions/webpack/webpack
[discussion-url]: https://github.com/webpack/webpack/discussions

108
node_modules/enhanced-resolve/lib/AliasFieldPlugin.js generated vendored Normal file
View file

@ -0,0 +1,108 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const DescriptionFileUtils = require("./DescriptionFileUtils");
const getInnerRequest = require("./getInnerRequest");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").JsonPrimitive} JsonPrimitive */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class AliasFieldPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | Array<string>} field field
* @param {string | ResolveStepHook} target target
*/
constructor(source, field, target) {
this.source = source;
this.field = field;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("AliasFieldPlugin", (request, resolveContext, callback) => {
if (!request.descriptionFileData) return callback();
const innerRequest = getInnerRequest(resolver, request);
if (!innerRequest) return callback();
const fieldData = DescriptionFileUtils.getField(
request.descriptionFileData,
this.field
);
if (fieldData === null || typeof fieldData !== "object") {
if (resolveContext.log)
resolveContext.log(
"Field '" +
this.field +
"' doesn't contain a valid alias configuration"
);
return callback();
}
/** @type {JsonPrimitive | undefined} */
const data = Object.prototype.hasOwnProperty.call(
fieldData,
innerRequest
)
? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
innerRequest
]
: innerRequest.startsWith("./")
? /** @type {{[Key in string]: JsonPrimitive}} */ (fieldData)[
innerRequest.slice(2)
]
: undefined;
if (data === innerRequest) return callback();
if (data === undefined) return callback();
if (data === false) {
/** @type {ResolveRequest} */
const ignoreObj = {
...request,
path: false
};
if (typeof resolveContext.yield === "function") {
resolveContext.yield(ignoreObj);
return callback(null, null);
}
return callback(null, ignoreObj);
}
/** @type {ResolveRequest} */
const obj = {
...request,
path: /** @type {string} */ (request.descriptionFileRoot),
request: /** @type {string} */ (data),
fullySpecified: false
};
resolver.doResolve(
target,
obj,
"aliased from description file " +
request.descriptionFilePath +
" with mapping '" +
innerRequest +
"' to '" +
/** @type {string} */ (data) +
"'",
resolveContext,
(err, result) => {
if (err) return callback(err);
// Don't allow other aliasing or raw request
if (result === undefined) return callback(null, null);
callback(null, result);
}
);
});
}
};

154
node_modules/enhanced-resolve/lib/AliasPlugin.js generated vendored Normal file
View file

@ -0,0 +1,154 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const forEachBail = require("./forEachBail");
const { PathType, getType } = require("./util/path");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {string | Array<string> | false} Alias */
/** @typedef {{alias: Alias, name: string, onlyModule?: boolean}} AliasOption */
module.exports = class AliasPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {AliasOption | Array<AliasOption>} options options
* @param {string | ResolveStepHook} target target
*/
constructor(source, options, target) {
this.source = source;
this.options = Array.isArray(options) ? options : [options];
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
/**
* @param {string} maybeAbsolutePath path
* @returns {null|string} absolute path with slash ending
*/
const getAbsolutePathWithSlashEnding = maybeAbsolutePath => {
const type = getType(maybeAbsolutePath);
if (type === PathType.AbsolutePosix || type === PathType.AbsoluteWin) {
return resolver.join(maybeAbsolutePath, "_").slice(0, -1);
}
return null;
};
/**
* @param {string} path path
* @param {string} maybeSubPath sub path
* @returns {boolean} true, if path is sub path
*/
const isSubPath = (path, maybeSubPath) => {
const absolutePath = getAbsolutePathWithSlashEnding(maybeSubPath);
if (!absolutePath) return false;
return path.startsWith(absolutePath);
};
resolver
.getHook(this.source)
.tapAsync("AliasPlugin", (request, resolveContext, callback) => {
const innerRequest = request.request || request.path;
if (!innerRequest) return callback();
forEachBail(
this.options,
(item, callback) => {
/** @type {boolean} */
let shouldStop = false;
if (
innerRequest === item.name ||
(!item.onlyModule &&
(request.request
? innerRequest.startsWith(`${item.name}/`)
: isSubPath(innerRequest, item.name)))
) {
/** @type {string} */
const remainingRequest = innerRequest.slice(item.name.length);
/**
* @param {Alias} alias alias
* @param {(err?: null|Error, result?: null|ResolveRequest) => void} callback callback
* @returns {void}
*/
const resolveWithAlias = (alias, callback) => {
if (alias === false) {
/** @type {ResolveRequest} */
const ignoreObj = {
...request,
path: false
};
if (typeof resolveContext.yield === "function") {
resolveContext.yield(ignoreObj);
return callback(null, null);
}
return callback(null, ignoreObj);
}
if (
innerRequest !== alias &&
!innerRequest.startsWith(alias + "/")
) {
shouldStop = true;
const newRequestStr = alias + remainingRequest;
/** @type {ResolveRequest} */
const obj = {
...request,
request: newRequestStr,
fullySpecified: false
};
return resolver.doResolve(
target,
obj,
"aliased with mapping '" +
item.name +
"': '" +
alias +
"' to '" +
newRequestStr +
"'",
resolveContext,
(err, result) => {
if (err) return callback(err);
if (result) return callback(null, result);
return callback();
}
);
}
return callback();
};
/**
* @param {null|Error} [err] error
* @param {null|ResolveRequest} [result] result
* @returns {void}
*/
const stoppingCallback = (err, result) => {
if (err) return callback(err);
if (result) return callback(null, result);
// Don't allow other aliasing or raw request
if (shouldStop) return callback(null, null);
return callback();
};
if (Array.isArray(item.alias)) {
return forEachBail(
item.alias,
resolveWithAlias,
stoppingCallback
);
} else {
return resolveWithAlias(item.alias, stoppingCallback);
}
}
return callback();
},
callback
);
});
}
};

49
node_modules/enhanced-resolve/lib/AppendPlugin.js generated vendored Normal file
View file

@ -0,0 +1,49 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class AppendPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string} appending appending
* @param {string | ResolveStepHook} target target
*/
constructor(source, appending, target) {
this.source = source;
this.appending = appending;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("AppendPlugin", (request, resolveContext, callback) => {
/** @type {ResolveRequest} */
const obj = {
...request,
path: request.path + this.appending,
relativePath:
request.relativePath && request.relativePath + this.appending
};
resolver.doResolve(
target,
obj,
this.appending,
resolveContext,
callback
);
});
}
};

View file

@ -0,0 +1,664 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const nextTick = require("process").nextTick;
/** @typedef {import("./Resolver").FileSystem} FileSystem */
/** @typedef {import("./Resolver").PathLike} PathLike */
/** @typedef {import("./Resolver").PathOrFileDescriptor} PathOrFileDescriptor */
/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
/** @typedef {FileSystem & SyncFileSystem} BaseFileSystem */
/**
* @template T
* @typedef {import("./Resolver").FileSystemCallback<T>} FileSystemCallback<T>
*/
/**
* @param {string} path path
* @returns {string} dirname
*/
const dirname = path => {
let idx = path.length - 1;
while (idx >= 0) {
const c = path.charCodeAt(idx);
// slash or backslash
if (c === 47 || c === 92) break;
idx--;
}
if (idx < 0) return "";
return path.slice(0, idx);
};
/**
* @template T
* @param {FileSystemCallback<T>[]} callbacks callbacks
* @param {Error | null} err error
* @param {T} result result
*/
const runCallbacks = (callbacks, err, result) => {
if (callbacks.length === 1) {
callbacks[0](err, result);
callbacks.length = 0;
return;
}
let error;
for (const callback of callbacks) {
try {
callback(err, result);
} catch (e) {
if (!error) error = e;
}
}
callbacks.length = 0;
if (error) throw error;
};
class OperationMergerBackend {
/**
* @param {Function | undefined} provider async method in filesystem
* @param {Function | undefined} syncProvider sync method in filesystem
* @param {BaseFileSystem} providerContext call context for the provider methods
*/
constructor(provider, syncProvider, providerContext) {
this._provider = provider;
this._syncProvider = syncProvider;
this._providerContext = providerContext;
this._activeAsyncOperations = new Map();
this.provide = this._provider
? /**
* @param {PathLike | PathOrFileDescriptor} path path
* @param {object | FileSystemCallback<any> | undefined} options options
* @param {FileSystemCallback<any>=} callback callback
* @returns {any} result
*/
(path, options, callback) => {
if (typeof options === "function") {
callback = /** @type {FileSystemCallback<any>} */ (options);
options = undefined;
}
if (
typeof path !== "string" &&
!Buffer.isBuffer(path) &&
!(path instanceof URL) &&
typeof path !== "number"
) {
/** @type {Function} */
(callback)(
new TypeError("path must be a string, Buffer, URL or number")
);
return;
}
if (options) {
return /** @type {Function} */ (this._provider).call(
this._providerContext,
path,
options,
callback
);
}
let callbacks = this._activeAsyncOperations.get(path);
if (callbacks) {
callbacks.push(callback);
return;
}
this._activeAsyncOperations.set(path, (callbacks = [callback]));
/** @type {Function} */
(provider)(
path,
/**
* @param {Error} err error
* @param {any} result result
*/
(err, result) => {
this._activeAsyncOperations.delete(path);
runCallbacks(callbacks, err, result);
}
);
}
: null;
this.provideSync = this._syncProvider
? /**
* @param {PathLike | PathOrFileDescriptor} path path
* @param {object=} options options
* @returns {any} result
*/
(path, options) => {
return /** @type {Function} */ (this._syncProvider).call(
this._providerContext,
path,
options
);
}
: null;
}
purge() {}
purgeParent() {}
}
/*
IDLE:
insert data: goto SYNC
SYNC:
before provide: run ticks
event loop tick: goto ASYNC_ACTIVE
ASYNC:
timeout: run tick, goto ASYNC_PASSIVE
ASYNC_PASSIVE:
before provide: run ticks
IDLE --[insert data]--> SYNC --[event loop tick]--> ASYNC_ACTIVE --[interval tick]-> ASYNC_PASSIVE
^ |
+---------[insert data]-------+
*/
const STORAGE_MODE_IDLE = 0;
const STORAGE_MODE_SYNC = 1;
const STORAGE_MODE_ASYNC = 2;
/**
* @callback Provide
* @param {PathLike | PathOrFileDescriptor} path path
* @param {any} options options
* @param {FileSystemCallback<any>} callback callback
* @returns {void}
*/
class CacheBackend {
/**
* @param {number} duration max cache duration of items
* @param {function | undefined} provider async method
* @param {function | undefined} syncProvider sync method
* @param {BaseFileSystem} providerContext call context for the provider methods
*/
constructor(duration, provider, syncProvider, providerContext) {
this._duration = duration;
this._provider = provider;
this._syncProvider = syncProvider;
this._providerContext = providerContext;
/** @type {Map<string, FileSystemCallback<any>[]>} */
this._activeAsyncOperations = new Map();
/** @type {Map<string, { err: Error | null, result?: any, level: Set<string> }>} */
this._data = new Map();
/** @type {Set<string>[]} */
this._levels = [];
for (let i = 0; i < 10; i++) this._levels.push(new Set());
for (let i = 5000; i < duration; i += 500) this._levels.push(new Set());
this._currentLevel = 0;
this._tickInterval = Math.floor(duration / this._levels.length);
/** @type {STORAGE_MODE_IDLE | STORAGE_MODE_SYNC | STORAGE_MODE_ASYNC} */
this._mode = STORAGE_MODE_IDLE;
/** @type {NodeJS.Timeout | undefined} */
this._timeout = undefined;
/** @type {number | undefined} */
this._nextDecay = undefined;
// @ts-ignore
this.provide = provider ? this.provide.bind(this) : null;
// @ts-ignore
this.provideSync = syncProvider ? this.provideSync.bind(this) : null;
}
/**
* @param {PathLike | PathOrFileDescriptor} path path
* @param {any} options options
* @param {FileSystemCallback<any>} callback callback
* @returns {void}
*/
provide(path, options, callback) {
if (typeof options === "function") {
callback = options;
options = undefined;
}
if (
typeof path !== "string" &&
!Buffer.isBuffer(path) &&
!(path instanceof URL) &&
typeof path !== "number"
) {
callback(new TypeError("path must be a string, Buffer, URL or number"));
return;
}
const strPath = typeof path !== "string" ? path.toString() : path;
if (options) {
return /** @type {Function} */ (this._provider).call(
this._providerContext,
path,
options,
callback
);
}
// When in sync mode we can move to async mode
if (this._mode === STORAGE_MODE_SYNC) {
this._enterAsyncMode();
}
// Check in cache
let cacheEntry = this._data.get(strPath);
if (cacheEntry !== undefined) {
if (cacheEntry.err) return nextTick(callback, cacheEntry.err);
return nextTick(callback, null, cacheEntry.result);
}
// Check if there is already the same operation running
let callbacks = this._activeAsyncOperations.get(strPath);
if (callbacks !== undefined) {
callbacks.push(callback);
return;
}
this._activeAsyncOperations.set(strPath, (callbacks = [callback]));
// Run the operation
/** @type {Function} */
(this._provider).call(
this._providerContext,
path,
/**
* @param {Error | null} err error
* @param {any} [result] result
*/
(err, result) => {
this._activeAsyncOperations.delete(strPath);
this._storeResult(strPath, err, result);
// Enter async mode if not yet done
this._enterAsyncMode();
runCallbacks(
/** @type {FileSystemCallback<any>[]} */ (callbacks),
err,
result
);
}
);
}
/**
* @param {PathLike | PathOrFileDescriptor} path path
* @param {any} options options
* @returns {any} result
*/
provideSync(path, options) {
if (
typeof path !== "string" &&
!Buffer.isBuffer(path) &&
!(path instanceof URL) &&
typeof path !== "number"
) {
throw new TypeError("path must be a string");
}
const strPath = typeof path !== "string" ? path.toString() : path;
if (options) {
return /** @type {Function} */ (this._syncProvider).call(
this._providerContext,
path,
options
);
}
// In sync mode we may have to decay some cache items
if (this._mode === STORAGE_MODE_SYNC) {
this._runDecays();
}
// Check in cache
let cacheEntry = this._data.get(strPath);
if (cacheEntry !== undefined) {
if (cacheEntry.err) throw cacheEntry.err;
return cacheEntry.result;
}
// Get all active async operations
// This sync operation will also complete them
const callbacks = this._activeAsyncOperations.get(strPath);
this._activeAsyncOperations.delete(strPath);
// Run the operation
// When in idle mode, we will enter sync mode
let result;
try {
result = /** @type {Function} */ (this._syncProvider).call(
this._providerContext,
path
);
} catch (err) {
this._storeResult(strPath, /** @type {Error} */ (err), undefined);
this._enterSyncModeWhenIdle();
if (callbacks) {
runCallbacks(callbacks, /** @type {Error} */ (err), undefined);
}
throw err;
}
this._storeResult(strPath, null, result);
this._enterSyncModeWhenIdle();
if (callbacks) {
runCallbacks(callbacks, null, result);
}
return result;
}
/**
* @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
*/
purge(what) {
if (!what) {
if (this._mode !== STORAGE_MODE_IDLE) {
this._data.clear();
for (const level of this._levels) {
level.clear();
}
this._enterIdleMode();
}
} else if (
typeof what === "string" ||
Buffer.isBuffer(what) ||
what instanceof URL ||
typeof what === "number"
) {
const strWhat = typeof what !== "string" ? what.toString() : what;
for (let [key, data] of this._data) {
if (key.startsWith(strWhat)) {
this._data.delete(key);
data.level.delete(key);
}
}
if (this._data.size === 0) {
this._enterIdleMode();
}
} else {
for (let [key, data] of this._data) {
for (const item of what) {
const strItem = typeof item !== "string" ? item.toString() : item;
if (key.startsWith(strItem)) {
this._data.delete(key);
data.level.delete(key);
break;
}
}
}
if (this._data.size === 0) {
this._enterIdleMode();
}
}
}
/**
* @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
*/
purgeParent(what) {
if (!what) {
this.purge();
} else if (
typeof what === "string" ||
Buffer.isBuffer(what) ||
what instanceof URL ||
typeof what === "number"
) {
const strWhat = typeof what !== "string" ? what.toString() : what;
this.purge(dirname(strWhat));
} else {
const set = new Set();
for (const item of what) {
const strItem = typeof item !== "string" ? item.toString() : item;
set.add(dirname(strItem));
}
this.purge(set);
}
}
/**
* @param {string} path path
* @param {Error | null} err error
* @param {any} result result
*/
_storeResult(path, err, result) {
if (this._data.has(path)) return;
const level = this._levels[this._currentLevel];
this._data.set(path, { err, result, level });
level.add(path);
}
_decayLevel() {
const nextLevel = (this._currentLevel + 1) % this._levels.length;
const decay = this._levels[nextLevel];
this._currentLevel = nextLevel;
for (let item of decay) {
this._data.delete(item);
}
decay.clear();
if (this._data.size === 0) {
this._enterIdleMode();
} else {
/** @type {number} */
(this._nextDecay) += this._tickInterval;
}
}
_runDecays() {
while (
/** @type {number} */ (this._nextDecay) <= Date.now() &&
this._mode !== STORAGE_MODE_IDLE
) {
this._decayLevel();
}
}
_enterAsyncMode() {
let timeout = 0;
switch (this._mode) {
case STORAGE_MODE_ASYNC:
return;
case STORAGE_MODE_IDLE:
this._nextDecay = Date.now() + this._tickInterval;
timeout = this._tickInterval;
break;
case STORAGE_MODE_SYNC:
this._runDecays();
// _runDecays may change the mode
if (
/** @type {STORAGE_MODE_IDLE | STORAGE_MODE_SYNC | STORAGE_MODE_ASYNC}*/
(this._mode) === STORAGE_MODE_IDLE
)
return;
timeout = Math.max(
0,
/** @type {number} */ (this._nextDecay) - Date.now()
);
break;
}
this._mode = STORAGE_MODE_ASYNC;
const ref = setTimeout(() => {
this._mode = STORAGE_MODE_SYNC;
this._runDecays();
}, timeout);
if (ref.unref) ref.unref();
this._timeout = ref;
}
_enterSyncModeWhenIdle() {
if (this._mode === STORAGE_MODE_IDLE) {
this._mode = STORAGE_MODE_SYNC;
this._nextDecay = Date.now() + this._tickInterval;
}
}
_enterIdleMode() {
this._mode = STORAGE_MODE_IDLE;
this._nextDecay = undefined;
if (this._timeout) clearTimeout(this._timeout);
}
}
/**
* @template {function} Provider
* @template {function} AsyncProvider
* @template FileSystem
* @param {number} duration duration in ms files are cached
* @param {Provider | undefined} provider provider
* @param {AsyncProvider | undefined} syncProvider sync provider
* @param {BaseFileSystem} providerContext provider context
* @returns {OperationMergerBackend | CacheBackend} backend
*/
const createBackend = (duration, provider, syncProvider, providerContext) => {
if (duration > 0) {
return new CacheBackend(duration, provider, syncProvider, providerContext);
}
return new OperationMergerBackend(provider, syncProvider, providerContext);
};
module.exports = class CachedInputFileSystem {
/**
* @param {BaseFileSystem} fileSystem file system
* @param {number} duration duration in ms files are cached
*/
constructor(fileSystem, duration) {
this.fileSystem = fileSystem;
this._lstatBackend = createBackend(
duration,
this.fileSystem.lstat,
this.fileSystem.lstatSync,
this.fileSystem
);
const lstat = this._lstatBackend.provide;
this.lstat = /** @type {FileSystem["lstat"]} */ (lstat);
const lstatSync = this._lstatBackend.provideSync;
this.lstatSync = /** @type {SyncFileSystem["lstatSync"]} */ (lstatSync);
this._statBackend = createBackend(
duration,
this.fileSystem.stat,
this.fileSystem.statSync,
this.fileSystem
);
const stat = this._statBackend.provide;
this.stat = /** @type {FileSystem["stat"]} */ (stat);
const statSync = this._statBackend.provideSync;
this.statSync = /** @type {SyncFileSystem["statSync"]} */ (statSync);
this._readdirBackend = createBackend(
duration,
this.fileSystem.readdir,
this.fileSystem.readdirSync,
this.fileSystem
);
const readdir = this._readdirBackend.provide;
this.readdir = /** @type {FileSystem["readdir"]} */ (readdir);
const readdirSync = this._readdirBackend.provideSync;
this.readdirSync = /** @type {SyncFileSystem["readdirSync"]} */ (
readdirSync
);
this._readFileBackend = createBackend(
duration,
this.fileSystem.readFile,
this.fileSystem.readFileSync,
this.fileSystem
);
const readFile = this._readFileBackend.provide;
this.readFile = /** @type {FileSystem["readFile"]} */ (readFile);
const readFileSync = this._readFileBackend.provideSync;
this.readFileSync = /** @type {SyncFileSystem["readFileSync"]} */ (
readFileSync
);
this._readJsonBackend = createBackend(
duration,
// prettier-ignore
this.fileSystem.readJson ||
(this.readFile &&
(
/**
* @param {string} path path
* @param {FileSystemCallback<any>} callback
*/
(path, callback) => {
this.readFile(path, (err, buffer) => {
if (err) return callback(err);
if (!buffer || buffer.length === 0)
return callback(new Error("No file content"));
let data;
try {
data = JSON.parse(buffer.toString("utf-8"));
} catch (e) {
return callback(/** @type {Error} */ (e));
}
callback(null, data);
});
})
),
// prettier-ignore
this.fileSystem.readJsonSync ||
(this.readFileSync &&
(
/**
* @param {string} path path
* @returns {any} result
*/
(path) => {
const buffer = this.readFileSync(path);
const data = JSON.parse(buffer.toString("utf-8"));
return data;
}
)),
this.fileSystem
);
const readJson = this._readJsonBackend.provide;
this.readJson = /** @type {FileSystem["readJson"]} */ (readJson);
const readJsonSync = this._readJsonBackend.provideSync;
this.readJsonSync = /** @type {SyncFileSystem["readJsonSync"]} */ (
readJsonSync
);
this._readlinkBackend = createBackend(
duration,
this.fileSystem.readlink,
this.fileSystem.readlinkSync,
this.fileSystem
);
const readlink = this._readlinkBackend.provide;
this.readlink = /** @type {FileSystem["readlink"]} */ (readlink);
const readlinkSync = this._readlinkBackend.provideSync;
this.readlinkSync = /** @type {SyncFileSystem["readlinkSync"]} */ (
readlinkSync
);
this._realpathBackend = createBackend(
duration,
this.fileSystem.realpath,
this.fileSystem.realpathSync,
this.fileSystem
);
const realpath = this._realpathBackend.provide;
this.realpath = /** @type {FileSystem["realpath"]} */ (realpath);
const realpathSync = this._realpathBackend.provideSync;
this.realpathSync = /** @type {SyncFileSystem["realpathSync"]} */ (
realpathSync
);
}
/**
* @param {string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set<string | URL | Buffer | number>} [what] what to purge
*/
purge(what) {
this._statBackend.purge(what);
this._lstatBackend.purge(what);
this._readdirBackend.purgeParent(what);
this._readFileBackend.purge(what);
this._readlinkBackend.purge(what);
this._readJsonBackend.purge(what);
this._realpathBackend.purge(what);
}
};

View file

@ -0,0 +1,53 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const basename = require("./getPaths").basename;
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class CloneBasenamePlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("CloneBasenamePlugin", (request, resolveContext, callback) => {
const requestPath = /** @type {string} */ (request.path);
const filename = /** @type {string} */ (basename(requestPath));
const filePath = resolver.join(requestPath, filename);
/** @type {ResolveRequest} */
const obj = {
...request,
path: filePath,
relativePath:
request.relativePath &&
resolver.join(request.relativePath, filename)
};
resolver.doResolve(
target,
obj,
"using path: " + filePath,
resolveContext,
callback
);
});
}
};

View file

@ -0,0 +1,98 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const DescriptionFileUtils = require("./DescriptionFileUtils");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class DescriptionFilePlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string[]} filenames filenames
* @param {boolean} pathIsFile pathIsFile
* @param {string | ResolveStepHook} target target
*/
constructor(source, filenames, pathIsFile, target) {
this.source = source;
this.filenames = filenames;
this.pathIsFile = pathIsFile;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync(
"DescriptionFilePlugin",
(request, resolveContext, callback) => {
const path = request.path;
if (!path) return callback();
const directory = this.pathIsFile
? DescriptionFileUtils.cdUp(path)
: path;
if (!directory) return callback();
DescriptionFileUtils.loadDescriptionFile(
resolver,
directory,
this.filenames,
request.descriptionFilePath
? {
path: request.descriptionFilePath,
content: request.descriptionFileData,
directory: /** @type {string} */ (request.descriptionFileRoot)
}
: undefined,
resolveContext,
(err, result) => {
if (err) return callback(err);
if (!result) {
if (resolveContext.log)
resolveContext.log(
`No description file found in ${directory} or above`
);
return callback();
}
const relativePath =
"." + path.slice(result.directory.length).replace(/\\/g, "/");
/** @type {ResolveRequest} */
const obj = {
...request,
descriptionFilePath: result.path,
descriptionFileData: result.content,
descriptionFileRoot: result.directory,
relativePath: relativePath
};
resolver.doResolve(
target,
obj,
"using description file: " +
result.path +
" (relative path: " +
relativePath +
")",
resolveContext,
(err, result) => {
if (err) return callback(err);
// Don't allow other processing
if (result === undefined) return callback(null, null);
callback(null, result);
}
);
}
);
}
);
}
};

View file

@ -0,0 +1,201 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const forEachBail = require("./forEachBail");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").JsonObject} JsonObject */
/** @typedef {import("./Resolver").JsonValue} JsonValue */
/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/**
* @typedef {Object} DescriptionFileInfo
* @property {JsonObject=} content
* @property {string} path
* @property {string} directory
*/
/**
* @callback ErrorFirstCallback
* @param {Error|null=} error
* @param {DescriptionFileInfo=} result
*/
/**
* @typedef {Object} Result
* @property {string} path path to description file
* @property {string} directory directory of description file
* @property {JsonObject} content content of description file
*/
/**
* @param {Resolver} resolver resolver
* @param {string} directory directory
* @param {string[]} filenames filenames
* @param {DescriptionFileInfo|undefined} oldInfo oldInfo
* @param {ResolveContext} resolveContext resolveContext
* @param {ErrorFirstCallback} callback callback
*/
function loadDescriptionFile(
resolver,
directory,
filenames,
oldInfo,
resolveContext,
callback
) {
(function findDescriptionFile() {
if (oldInfo && oldInfo.directory === directory) {
// We already have info for this directory and can reuse it
return callback(null, oldInfo);
}
forEachBail(
filenames,
/**
* @param {string} filename filename
* @param {(err?: null|Error, result?: null|Result) => void} callback callback
* @returns {void}
*/
(filename, callback) => {
const descriptionFilePath = resolver.join(directory, filename);
if (resolver.fileSystem.readJson) {
resolver.fileSystem.readJson(descriptionFilePath, (err, content) => {
if (err) {
if (
typeof (/** @type {NodeJS.ErrnoException} */ (err).code) !==
"undefined"
) {
if (resolveContext.missingDependencies) {
resolveContext.missingDependencies.add(descriptionFilePath);
}
return callback();
}
if (resolveContext.fileDependencies) {
resolveContext.fileDependencies.add(descriptionFilePath);
}
return onJson(err);
}
if (resolveContext.fileDependencies) {
resolveContext.fileDependencies.add(descriptionFilePath);
}
onJson(null, content);
});
} else {
resolver.fileSystem.readFile(descriptionFilePath, (err, content) => {
if (err) {
if (resolveContext.missingDependencies) {
resolveContext.missingDependencies.add(descriptionFilePath);
}
return callback();
}
if (resolveContext.fileDependencies) {
resolveContext.fileDependencies.add(descriptionFilePath);
}
/** @type {JsonObject | undefined} */
let json;
if (content) {
try {
json = JSON.parse(content.toString());
} catch (/** @type {unknown} */ e) {
return onJson(/** @type {Error} */ (e));
}
} else {
return onJson(new Error("No content in file"));
}
onJson(null, json);
});
}
/**
* @param {null|Error} [err] error
* @param {JsonObject} [content] content
* @returns {void}
*/
function onJson(err, content) {
if (err) {
if (resolveContext.log)
resolveContext.log(
descriptionFilePath + " (directory description file): " + err
);
else
err.message =
descriptionFilePath + " (directory description file): " + err;
return callback(err);
}
callback(null, {
content: /** @type {JsonObject} */ (content),
directory,
path: descriptionFilePath
});
}
},
/**
* @param {null|Error} [err] error
* @param {null|Result} [result] result
* @returns {void}
*/
(err, result) => {
if (err) return callback(err);
if (result) {
return callback(null, result);
} else {
const dir = cdUp(directory);
if (!dir) {
return callback();
} else {
directory = dir;
return findDescriptionFile();
}
}
}
);
})();
}
/**
* @param {JsonObject} content content
* @param {string|string[]} field field
* @returns {JsonValue | undefined} field data
*/
function getField(content, field) {
if (!content) return undefined;
if (Array.isArray(field)) {
/** @type {JsonValue} */
let current = content;
for (let j = 0; j < field.length; j++) {
if (current === null || typeof current !== "object") {
current = null;
break;
}
current = /** @type {JsonObject} */ (current)[field[j]];
}
return current;
} else {
return content[field];
}
}
/**
* @param {string} directory directory
* @returns {string|null} parent directory or null
*/
function cdUp(directory) {
if (directory === "/") return null;
const i = directory.lastIndexOf("/"),
j = directory.lastIndexOf("\\");
const p = i < 0 ? j : j < 0 ? i : i < j ? j : i;
if (p < 0) return null;
return directory.slice(0, p || 1);
}
exports.loadDescriptionFile = loadDescriptionFile;
exports.getField = getField;
exports.cdUp = cdUp;

View file

@ -0,0 +1,63 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class DirectoryExistsPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync(
"DirectoryExistsPlugin",
(request, resolveContext, callback) => {
const fs = resolver.fileSystem;
const directory = request.path;
if (!directory) return callback();
fs.stat(directory, (err, stat) => {
if (err || !stat) {
if (resolveContext.missingDependencies)
resolveContext.missingDependencies.add(directory);
if (resolveContext.log)
resolveContext.log(directory + " doesn't exist");
return callback();
}
if (!stat.isDirectory()) {
if (resolveContext.missingDependencies)
resolveContext.missingDependencies.add(directory);
if (resolveContext.log)
resolveContext.log(directory + " is not a directory");
return callback();
}
if (resolveContext.fileDependencies)
resolveContext.fileDependencies.add(directory);
resolver.doResolve(
target,
request,
`existing directory ${directory}`,
resolveContext,
callback
);
});
}
);
}
};

58
node_modules/enhanced-resolve/lib/FileExistsPlugin.js generated vendored Normal file
View file

@ -0,0 +1,58 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class FileExistsPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
const fs = resolver.fileSystem;
resolver
.getHook(this.source)
.tapAsync("FileExistsPlugin", (request, resolveContext, callback) => {
const file = request.path;
if (!file) return callback();
fs.stat(file, (err, stat) => {
if (err || !stat) {
if (resolveContext.missingDependencies)
resolveContext.missingDependencies.add(file);
if (resolveContext.log) resolveContext.log(file + " doesn't exist");
return callback();
}
if (!stat.isFile()) {
if (resolveContext.missingDependencies)
resolveContext.missingDependencies.add(file);
if (resolveContext.log) resolveContext.log(file + " is not a file");
return callback();
}
if (resolveContext.fileDependencies)
resolveContext.fileDependencies.add(file);
resolver.doResolve(
target,
request,
"existing file: " + file,
resolveContext,
callback
);
});
});
}
};

45
node_modules/enhanced-resolve/lib/JoinRequestPlugin.js generated vendored Normal file
View file

@ -0,0 +1,45 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class JoinRequestPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("JoinRequestPlugin", (request, resolveContext, callback) => {
const requestPath = /** @type {string} */ (request.path);
const requestRequest = /** @type {string} */ (request.request);
/** @type {ResolveRequest} */
const obj = {
...request,
path: resolver.join(requestPath, requestRequest),
relativePath:
request.relativePath &&
resolver.join(request.relativePath, requestRequest),
request: undefined
};
resolver.doResolve(target, obj, null, resolveContext, callback);
});
}
};

54
node_modules/enhanced-resolve/lib/LogInfoPlugin.js generated vendored Normal file
View file

@ -0,0 +1,54 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class LogInfoPlugin {
/**
* @param {string | ResolveStepHook} source source
*/
constructor(source) {
this.source = source;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const source = this.source;
resolver
.getHook(this.source)
.tapAsync("LogInfoPlugin", (request, resolveContext, callback) => {
if (!resolveContext.log) return callback();
const log = resolveContext.log;
const prefix = "[" + source + "] ";
if (request.path)
log(prefix + "Resolving in directory: " + request.path);
if (request.request)
log(prefix + "Resolving request: " + request.request);
if (request.module) log(prefix + "Request is an module request.");
if (request.directory) log(prefix + "Request is a directory request.");
if (request.query)
log(prefix + "Resolving request query: " + request.query);
if (request.fragment)
log(prefix + "Resolving request fragment: " + request.fragment);
if (request.descriptionFilePath)
log(
prefix + "Has description data from " + request.descriptionFilePath
);
if (request.relativePath)
log(
prefix +
"Relative path from description file is: " +
request.relativePath
);
callback();
});
}
};

90
node_modules/enhanced-resolve/lib/MainFieldPlugin.js generated vendored Normal file
View file

@ -0,0 +1,90 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const path = require("path");
const DescriptionFileUtils = require("./DescriptionFileUtils");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").JsonObject} JsonObject */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {{name: string|Array<string>, forceRelative: boolean}} MainFieldOptions */
const alreadyTriedMainField = Symbol("alreadyTriedMainField");
module.exports = class MainFieldPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {MainFieldOptions} options options
* @param {string | ResolveStepHook} target target
*/
constructor(source, options, target) {
this.source = source;
this.options = options;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("MainFieldPlugin", (request, resolveContext, callback) => {
if (
request.path !== request.descriptionFileRoot ||
/** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
(request)[alreadyTriedMainField] === request.descriptionFilePath ||
!request.descriptionFilePath
)
return callback();
const filename = path.basename(request.descriptionFilePath);
let mainModule =
/** @type {string|null|undefined} */
(
DescriptionFileUtils.getField(
/** @type {JsonObject} */ (request.descriptionFileData),
this.options.name
)
);
if (
!mainModule ||
typeof mainModule !== "string" ||
mainModule === "." ||
mainModule === "./"
) {
return callback();
}
if (this.options.forceRelative && !/^\.\.?\//.test(mainModule))
mainModule = "./" + mainModule;
/** @type {ResolveRequest & { [alreadyTriedMainField]?: string }} */
const obj = {
...request,
request: mainModule,
module: false,
directory: mainModule.endsWith("/"),
[alreadyTriedMainField]: request.descriptionFilePath
};
return resolver.doResolve(
target,
obj,
"use " +
mainModule +
" from " +
this.options.name +
" in " +
filename,
resolveContext,
callback
);
});
}
};

View file

@ -0,0 +1,9 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
// TODO remove in next major
module.exports = require("./ModulesInHierarchicalDirectoriesPlugin");

View file

@ -0,0 +1,49 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class ModulesInRootPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string} path path
* @param {string | ResolveStepHook} target target
*/
constructor(source, path, target) {
this.source = source;
this.path = path;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("ModulesInRootPlugin", (request, resolveContext, callback) => {
/** @type {ResolveRequest} */
const obj = {
...request,
path: this.path,
request: "./" + request.request,
module: false
};
resolver.doResolve(
target,
obj,
"looking for modules in " + this.path,
resolveContext,
callback
);
});
}
};

33
node_modules/enhanced-resolve/lib/NextPlugin.js generated vendored Normal file
View file

@ -0,0 +1,33 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class NextPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("NextPlugin", (request, resolveContext, callback) => {
resolver.doResolve(target, request, null, resolveContext, callback);
});
}
};

76
node_modules/enhanced-resolve/lib/ParsePlugin.js generated vendored Normal file
View file

@ -0,0 +1,76 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class ParsePlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {Partial<ResolveRequest>} requestOptions request options
* @param {string | ResolveStepHook} target target
*/
constructor(source, requestOptions, target) {
this.source = source;
this.requestOptions = requestOptions;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("ParsePlugin", (request, resolveContext, callback) => {
const parsed = resolver.parse(/** @type {string} */ (request.request));
/** @type {ResolveRequest} */
const obj = { ...request, ...parsed, ...this.requestOptions };
if (request.query && !parsed.query) {
obj.query = request.query;
}
if (request.fragment && !parsed.fragment) {
obj.fragment = request.fragment;
}
if (parsed && resolveContext.log) {
if (parsed.module) resolveContext.log("Parsed request is a module");
if (parsed.directory)
resolveContext.log("Parsed request is a directory");
}
// There is an edge-case where a request with # can be a path or a fragment -> try both
if (obj.request && !obj.query && obj.fragment) {
const directory = obj.fragment.endsWith("/");
/** @type {ResolveRequest} */
const alternative = {
...obj,
directory,
request:
obj.request +
(obj.directory ? "/" : "") +
(directory ? obj.fragment.slice(0, -1) : obj.fragment),
fragment: ""
};
resolver.doResolve(
target,
alternative,
null,
resolveContext,
(err, result) => {
if (err) return callback(err);
if (result) return callback(null, result);
resolver.doResolve(target, obj, null, resolveContext, callback);
}
);
return;
}
resolver.doResolve(target, obj, null, resolveContext, callback);
});
}
};

800
node_modules/enhanced-resolve/lib/Resolver.js generated vendored Normal file
View file

@ -0,0 +1,800 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const { AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } = require("tapable");
const createInnerContext = require("./createInnerContext");
const { parseIdentifier } = require("./util/identifier");
const {
normalize,
cachedJoin: join,
getType,
PathType
} = require("./util/path");
/** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */
/** @typedef {Error & { details?: string }} ErrorWithDetail */
/** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */
/**
* @typedef {Object} PossibleFileSystemError
* @property {string=} code
* @property {number=} errno
* @property {string=} path
* @property {string=} syscall
*/
/**
* @template T
* @callback FileSystemCallback
* @param {PossibleFileSystemError & Error | null} err
* @param {T=} result
*/
/**
* @typedef {string | Buffer | URL} PathLike
*/
/**
* @typedef {PathLike | number} PathOrFileDescriptor
*/
/**
* @typedef {Object} ObjectEncodingOptions
* @property {BufferEncoding | null | undefined} [encoding]
*/
/** @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
* @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 {{
* (path: PathLike, options?: EncodingOption): string;
* (path: PathLike, options: BufferEncodingOption): Buffer;
* (path: PathLike, options?: EncodingOption): string | Buffer;
* }} RealPathSync
*/
/**
* @typedef {Object} FileSystem
* @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 {ReadFileSync} readFileSync
* @property {ReaddirSync} readdirSync
* @property {ReadJsonSync=} readJsonSync
* @property {ReadlinkSync} readlinkSync
* @property {LStatSync=} lstatSync
* @property {StatSync} statSync
* @property {RealPathSync=} realpathSync
*/
/**
* @typedef {Object} ParsedIdentifier
* @property {string} request
* @property {string} query
* @property {string} fragment
* @property {boolean} directory
* @property {boolean} module
* @property {boolean} file
* @property {boolean} internal
*/
/** @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 {Object} BaseResolveRequest
* @property {string | false} path
* @property {object=} context
* @property {string=} descriptionFilePath
* @property {string=} descriptionFileRoot
* @property {JsonObject=} descriptionFileData
* @property {string=} relativePath
* @property {boolean=} ignoreSymlinks
* @property {boolean=} fullySpecified
* @property {string=} __innerRequest
* @property {string=} __innerRequest_request
* @property {string=} __innerRequest_relativePath
*/
/** @typedef {BaseResolveRequest & Partial<ParsedIdentifier>} ResolveRequest */
/**
* String with special formatting
* @typedef {string} StackEntry
*/
/**
* @template T
* @typedef {{ add: (item: T) => void }} WriteOnlySet
*/
/** @typedef {(function (ResolveRequest): void)} ResolveContextYield */
/**
* Resolve context
* @typedef {Object} ResolveContext
* @property {WriteOnlySet<string>=} contextDependencies
* @property {WriteOnlySet<string>=} fileDependencies files that was found on file system
* @property {WriteOnlySet<string>=} missingDependencies dependencies that was not found on file system
* @property {Set<StackEntry>=} stack set of hooks' calls. For instance, `resolve → parsedResolve → describedResolve`,
* @property {(function(string): void)=} log log function
* @property {ResolveContextYield=} yield yield result, if provided plugins can return several results
*/
/** @typedef {AsyncSeriesBailHook<[ResolveRequest, ResolveContext], ResolveRequest | null>} ResolveStepHook */
/**
* @typedef {Object} KnownHooks
* @property {SyncHook<[ResolveStepHook, ResolveRequest], void>} resolveStep
* @property {SyncHook<[ResolveRequest, Error]>} noResolve
* @property {ResolveStepHook} resolve
* @property {AsyncSeriesHook<[ResolveRequest, ResolveContext]>} result
*/
/**
* @typedef {{[key: string]: ResolveStepHook}} EnsuredHooks
*/
/**
* @param {string} str input string
* @returns {string} in camel case
*/
function toCamelCase(str) {
return str.replace(/-([a-z])/g, str => str.slice(1).toUpperCase());
}
class Resolver {
/**
* @param {ResolveStepHook} hook hook
* @param {ResolveRequest} request request
* @returns {StackEntry} stack entry
*/
static createStackEntry(hook, request) {
return (
hook.name +
": (" +
request.path +
") " +
(request.request || "") +
(request.query || "") +
(request.fragment || "") +
(request.directory ? " directory" : "") +
(request.module ? " module" : "")
);
}
/**
* @param {FileSystem} fileSystem a filesystem
* @param {ResolveOptions} options options
*/
constructor(fileSystem, options) {
this.fileSystem = fileSystem;
this.options = options;
/** @type {KnownHooks} */
this.hooks = {
resolveStep: new SyncHook(["hook", "request"], "resolveStep"),
noResolve: new SyncHook(["request", "error"], "noResolve"),
resolve: new AsyncSeriesBailHook(
["request", "resolveContext"],
"resolve"
),
result: new AsyncSeriesHook(["result", "resolveContext"], "result")
};
}
/**
* @param {string | ResolveStepHook} name hook name or hook itself
* @returns {ResolveStepHook} the hook
*/
ensureHook(name) {
if (typeof name !== "string") {
return name;
}
name = toCamelCase(name);
if (/^before/.test(name)) {
return /** @type {ResolveStepHook} */ (
this.ensureHook(name[6].toLowerCase() + name.slice(7)).withOptions({
stage: -10
})
);
}
if (/^after/.test(name)) {
return /** @type {ResolveStepHook} */ (
this.ensureHook(name[5].toLowerCase() + name.slice(6)).withOptions({
stage: 10
})
);
}
/** @type {ResolveStepHook} */
const hook = /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
if (!hook) {
/** @type {KnownHooks & EnsuredHooks} */
(this.hooks)[name] = new AsyncSeriesBailHook(
["request", "resolveContext"],
name
);
return /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
}
return hook;
}
/**
* @param {string | ResolveStepHook} name hook name or hook itself
* @returns {ResolveStepHook} the hook
*/
getHook(name) {
if (typeof name !== "string") {
return name;
}
name = toCamelCase(name);
if (/^before/.test(name)) {
return /** @type {ResolveStepHook} */ (
this.getHook(name[6].toLowerCase() + name.slice(7)).withOptions({
stage: -10
})
);
}
if (/^after/.test(name)) {
return /** @type {ResolveStepHook} */ (
this.getHook(name[5].toLowerCase() + name.slice(6)).withOptions({
stage: 10
})
);
}
/** @type {ResolveStepHook} */
const hook = /** @type {KnownHooks & EnsuredHooks} */ (this.hooks)[name];
if (!hook) {
throw new Error(`Hook ${name} doesn't exist`);
}
return hook;
}
/**
* @param {object} context context information object
* @param {string} path context path
* @param {string} request request string
* @returns {string | false} result
*/
resolveSync(context, path, request) {
/** @type {Error | null | undefined} */
let err = undefined;
/** @type {string | false | undefined} */
let result = undefined;
let sync = false;
this.resolve(context, path, request, {}, (e, r) => {
err = e;
result = r;
sync = true;
});
if (!sync) {
throw new Error(
"Cannot 'resolveSync' because the fileSystem is not sync. Use 'resolve'!"
);
}
if (err) throw err;
if (result === undefined) throw new Error("No result");
return result;
}
/**
* @param {object} context context information object
* @param {string} path context path
* @param {string} request request string
* @param {ResolveContext} resolveContext resolve context
* @param {ResolveCallback} callback callback function
* @returns {void}
*/
resolve(context, path, request, resolveContext, callback) {
if (!context || typeof context !== "object")
return callback(new Error("context argument is not an object"));
if (typeof path !== "string")
return callback(new Error("path argument is not a string"));
if (typeof request !== "string")
return callback(new Error("request argument is not a string"));
if (!resolveContext)
return callback(new Error("resolveContext argument is not set"));
/** @type {ResolveRequest} */
const obj = {
context: context,
path: path,
request: request
};
/** @type {ResolveContextYield | undefined} */
let yield_;
let yieldCalled = false;
/** @type {ResolveContextYield | undefined} */
let finishYield;
if (typeof resolveContext.yield === "function") {
const old = resolveContext.yield;
/**
* @param {ResolveRequest} obj object
*/
yield_ = obj => {
old(obj);
yieldCalled = true;
};
/**
* @param {ResolveRequest} result result
* @returns {void}
*/
finishYield = result => {
if (result) {
/** @type {ResolveContextYield} */ (yield_)(result);
}
callback(null);
};
}
const message = `resolve '${request}' in '${path}'`;
/**
* @param {ResolveRequest} result result
* @returns {void}
*/
const finishResolved = result => {
return callback(
null,
result.path === false
? false
: `${result.path.replace(/#/g, "\0#")}${
result.query ? result.query.replace(/#/g, "\0#") : ""
}${result.fragment || ""}`,
result
);
};
/**
* @param {string[]} log logs
* @returns {void}
*/
const finishWithoutResolve = log => {
/**
* @type {ErrorWithDetail}
*/
const error = new Error("Can't " + message);
error.details = log.join("\n");
this.hooks.noResolve.call(obj, error);
return callback(error);
};
if (resolveContext.log) {
// We need log anyway to capture it in case of an error
const parentLog = resolveContext.log;
/** @type {string[]} */
const log = [];
return this.doResolve(
this.hooks.resolve,
obj,
message,
{
log: msg => {
parentLog(msg);
log.push(msg);
},
yield: yield_,
fileDependencies: resolveContext.fileDependencies,
contextDependencies: resolveContext.contextDependencies,
missingDependencies: resolveContext.missingDependencies,
stack: resolveContext.stack
},
(err, result) => {
if (err) return callback(err);
if (yieldCalled || (result && yield_)) {
return /** @type {ResolveContextYield} */ (finishYield)(
/** @type {ResolveRequest} */ (result)
);
}
if (result) return finishResolved(result);
return finishWithoutResolve(log);
}
);
} else {
// Try to resolve assuming there is no error
// We don't log stuff in this case
return this.doResolve(
this.hooks.resolve,
obj,
message,
{
log: undefined,
yield: yield_,
fileDependencies: resolveContext.fileDependencies,
contextDependencies: resolveContext.contextDependencies,
missingDependencies: resolveContext.missingDependencies,
stack: resolveContext.stack
},
(err, result) => {
if (err) return callback(err);
if (yieldCalled || (result && yield_)) {
return /** @type {ResolveContextYield} */ (finishYield)(
/** @type {ResolveRequest} */ (result)
);
}
if (result) return finishResolved(result);
// log is missing for the error details
// so we redo the resolving for the log info
// this is more expensive to the success case
// is assumed by default
/** @type {string[]} */
const log = [];
return this.doResolve(
this.hooks.resolve,
obj,
message,
{
log: msg => log.push(msg),
yield: yield_,
stack: resolveContext.stack
},
(err, result) => {
if (err) return callback(err);
// In a case that there is a race condition and yield will be called
if (yieldCalled || (result && yield_)) {
return /** @type {ResolveContextYield} */ (finishYield)(
/** @type {ResolveRequest} */ (result)
);
}
return finishWithoutResolve(log);
}
);
}
);
}
}
/**
* @param {ResolveStepHook} hook hook
* @param {ResolveRequest} request request
* @param {null|string} message string
* @param {ResolveContext} resolveContext resolver context
* @param {(err?: null|Error, result?: ResolveRequest) => void} callback callback
* @returns {void}
*/
doResolve(hook, request, message, resolveContext, callback) {
const stackEntry = Resolver.createStackEntry(hook, request);
/** @type {Set<string> | undefined} */
let newStack;
if (resolveContext.stack) {
newStack = new Set(resolveContext.stack);
if (resolveContext.stack.has(stackEntry)) {
/**
* Prevent recursion
* @type {Error & {recursion?: boolean}}
*/
const recursionError = new Error(
"Recursion in resolving\nStack:\n " +
Array.from(newStack).join("\n ")
);
recursionError.recursion = true;
if (resolveContext.log)
resolveContext.log("abort resolving because of recursion");
return callback(recursionError);
}
newStack.add(stackEntry);
} else {
// creating a set with new Set([item])
// allocates a new array that has to be garbage collected
// this is an EXTREMELY hot path, so let's avoid it
newStack = new Set();
newStack.add(stackEntry);
}
this.hooks.resolveStep.call(hook, request);
if (hook.isUsed()) {
const innerContext = createInnerContext(
{
log: resolveContext.log,
yield: resolveContext.yield,
fileDependencies: resolveContext.fileDependencies,
contextDependencies: resolveContext.contextDependencies,
missingDependencies: resolveContext.missingDependencies,
stack: newStack
},
message
);
return hook.callAsync(request, innerContext, (err, result) => {
if (err) return callback(err);
if (result) return callback(null, result);
callback();
});
} else {
callback();
}
}
/**
* @param {string} identifier identifier
* @returns {ParsedIdentifier} parsed identifier
*/
parse(identifier) {
const part = {
request: "",
query: "",
fragment: "",
module: false,
directory: false,
file: false,
internal: false
};
const parsedIdentifier = parseIdentifier(identifier);
if (!parsedIdentifier) return part;
[part.request, part.query, part.fragment] = parsedIdentifier;
if (part.request.length > 0) {
part.internal = this.isPrivate(identifier);
part.module = this.isModule(part.request);
part.directory = this.isDirectory(part.request);
if (part.directory) {
part.request = part.request.slice(0, -1);
}
}
return part;
}
/**
* @param {string} path path
* @returns {boolean} true, if the path is a module
*/
isModule(path) {
return getType(path) === PathType.Normal;
}
/**
* @param {string} path path
* @returns {boolean} true, if the path is private
*/
isPrivate(path) {
return getType(path) === PathType.Internal;
}
/**
* @param {string} path a path
* @returns {boolean} true, if the path is a directory path
*/
isDirectory(path) {
return path.endsWith("/");
}
/**
* @param {string} path path
* @param {string} request request
* @returns {string} joined path
*/
join(path, request) {
return join(path, request);
}
/**
* @param {string} path path
* @returns {string} normalized path
*/
normalize(path) {
return normalize(path);
}
}
module.exports = Resolver;

728
node_modules/enhanced-resolve/lib/ResolverFactory.js generated vendored Normal file
View file

@ -0,0 +1,728 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const versions = require("process").versions;
const Resolver = require("./Resolver");
const { getType, PathType } = require("./util/path");
const SyncAsyncFileSystemDecorator = require("./SyncAsyncFileSystemDecorator");
const AliasFieldPlugin = require("./AliasFieldPlugin");
const AliasPlugin = require("./AliasPlugin");
const AppendPlugin = require("./AppendPlugin");
const ConditionalPlugin = require("./ConditionalPlugin");
const DescriptionFilePlugin = require("./DescriptionFilePlugin");
const DirectoryExistsPlugin = require("./DirectoryExistsPlugin");
const ExportsFieldPlugin = require("./ExportsFieldPlugin");
const ExtensionAliasPlugin = require("./ExtensionAliasPlugin");
const FileExistsPlugin = require("./FileExistsPlugin");
const ImportsFieldPlugin = require("./ImportsFieldPlugin");
const JoinRequestPartPlugin = require("./JoinRequestPartPlugin");
const JoinRequestPlugin = require("./JoinRequestPlugin");
const MainFieldPlugin = require("./MainFieldPlugin");
const ModulesInHierarchicalDirectoriesPlugin = require("./ModulesInHierarchicalDirectoriesPlugin");
const ModulesInRootPlugin = require("./ModulesInRootPlugin");
const NextPlugin = require("./NextPlugin");
const ParsePlugin = require("./ParsePlugin");
const PnpPlugin = require("./PnpPlugin");
const RestrictionsPlugin = require("./RestrictionsPlugin");
const ResultPlugin = require("./ResultPlugin");
const RootsPlugin = require("./RootsPlugin");
const SelfReferencePlugin = require("./SelfReferencePlugin");
const SymlinkPlugin = require("./SymlinkPlugin");
const TryNextPlugin = require("./TryNextPlugin");
const UnsafeCachePlugin = require("./UnsafeCachePlugin");
const UseFilePlugin = require("./UseFilePlugin");
/** @typedef {import("./AliasPlugin").AliasOption} AliasOptionEntry */
/** @typedef {import("./ExtensionAliasPlugin").ExtensionAliasOption} ExtensionAliasOption */
/** @typedef {import("./PnpPlugin").PnpApiImpl} PnpApi */
/** @typedef {import("./Resolver").EnsuredHooks} EnsuredHooks */
/** @typedef {import("./Resolver").FileSystem} FileSystem */
/** @typedef {import("./Resolver").KnownHooks} KnownHooks */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
/** @typedef {string|string[]|false} AliasOptionNewRequest */
/** @typedef {{[k: string]: AliasOptionNewRequest}} AliasOptions */
/** @typedef {{[k: string]: string|string[] }} ExtensionAliasOptions */
/** @typedef {false | 0 | "" | null | undefined} Falsy */
/** @typedef {{apply: function(Resolver): void} | (function(this: Resolver, Resolver): void) | Falsy} Plugin */
/**
* @typedef {Object} UserResolveOptions
* @property {(AliasOptions | AliasOptionEntry[])=} alias A list of module alias configurations or an object which maps key to value
* @property {(AliasOptions | AliasOptionEntry[])=} fallback A list of module alias configurations or an object which maps key to value, applied only after modules option
* @property {ExtensionAliasOptions=} extensionAlias An object which maps extension to extension aliases
* @property {(string | string[])[]=} aliasFields A list of alias fields in description files
* @property {(function(ResolveRequest): boolean)=} cachePredicate A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties.
* @property {boolean=} cacheWithContext Whether or not the unsafeCache should include request context as part of the cache key.
* @property {string[]=} descriptionFiles A list of description files to read from
* @property {string[]=} conditionNames A list of exports field condition names.
* @property {boolean=} enforceExtension Enforce that a extension from extensions must be used
* @property {(string | string[])[]=} exportsFields A list of exports fields in description files
* @property {(string | string[])[]=} importsFields A list of imports fields in description files
* @property {string[]=} extensions A list of extensions which should be tried for files
* @property {FileSystem} fileSystem The file system which should be used
* @property {(object | boolean)=} unsafeCache Use this cache object to unsafely cache the successful requests
* @property {boolean=} symlinks Resolve symlinks to their symlinked location
* @property {Resolver=} resolver A prepared Resolver to which the plugins are attached
* @property {string[] | string=} modules A list of directories to resolve modules from, can be absolute path or folder name
* @property {(string | string[] | {name: string | string[], forceRelative: boolean})[]=} mainFields A list of main fields in description files
* @property {string[]=} mainFiles A list of main files in directories
* @property {Plugin[]=} plugins A list of additional resolve plugins which should be applied
* @property {PnpApi | null=} pnpApi A PnP API that should be used - null is "never", undefined is "auto"
* @property {string[]=} roots A list of root paths
* @property {boolean=} fullySpecified The request is already fully specified and no extensions or directories are resolved for it
* @property {boolean=} resolveToContext Resolve to a context instead of a file
* @property {(string|RegExp)[]=} restrictions A list of resolve restrictions
* @property {boolean=} useSyncFileSystemCalls Use only the sync constraints of the file system calls
* @property {boolean=} preferRelative Prefer to resolve module requests as relative requests before falling back to modules
* @property {boolean=} preferAbsolute Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots
*/
/**
* @typedef {Object} ResolveOptions
* @property {AliasOptionEntry[]} alias
* @property {AliasOptionEntry[]} fallback
* @property {Set<string | string[]>} aliasFields
* @property {ExtensionAliasOption[]} extensionAlias
* @property {(function(ResolveRequest): boolean)} cachePredicate
* @property {boolean} cacheWithContext
* @property {Set<string>} conditionNames A list of exports field condition names.
* @property {string[]} descriptionFiles
* @property {boolean} enforceExtension
* @property {Set<string | string[]>} exportsFields
* @property {Set<string | string[]>} importsFields
* @property {Set<string>} extensions
* @property {FileSystem} fileSystem
* @property {object | false} unsafeCache
* @property {boolean} symlinks
* @property {Resolver=} resolver
* @property {Array<string | string[]>} modules
* @property {{name: string[], forceRelative: boolean}[]} mainFields
* @property {Set<string>} mainFiles
* @property {Plugin[]} plugins
* @property {PnpApi | null} pnpApi
* @property {Set<string>} roots
* @property {boolean} fullySpecified
* @property {boolean} resolveToContext
* @property {Set<string|RegExp>} restrictions
* @property {boolean} preferRelative
* @property {boolean} preferAbsolute
*/
/**
* @param {PnpApi | null=} option option
* @returns {PnpApi | null} processed option
*/
function processPnpApiOption(option) {
if (
option === undefined &&
/** @type {NodeJS.ProcessVersions & {pnp: string}} */ versions.pnp
) {
const _findPnpApi =
/** @type {function(string): PnpApi | null}} */
(
// @ts-ignore
require("module").findPnpApi
);
if (_findPnpApi) {
return {
resolveToUnqualified(request, issuer, opts) {
const pnpapi = _findPnpApi(issuer);
if (!pnpapi) {
// Issuer isn't managed by PnP
return null;
}
return pnpapi.resolveToUnqualified(request, issuer, opts);
}
};
}
}
return option || null;
}
/**
* @param {AliasOptions | AliasOptionEntry[] | undefined} alias alias
* @returns {AliasOptionEntry[]} normalized aliases
*/
function normalizeAlias(alias) {
return typeof alias === "object" && !Array.isArray(alias) && alias !== null
? Object.keys(alias).map(key => {
/** @type {AliasOptionEntry} */
const obj = { name: key, onlyModule: false, alias: alias[key] };
if (/\$$/.test(key)) {
obj.onlyModule = true;
obj.name = key.slice(0, -1);
}
return obj;
})
: /** @type {Array<AliasOptionEntry>} */ (alias) || [];
}
/**
* @param {UserResolveOptions} options input options
* @returns {ResolveOptions} output options
*/
function createOptions(options) {
const mainFieldsSet = new Set(options.mainFields || ["main"]);
/** @type {ResolveOptions["mainFields"]} */
const mainFields = [];
for (const item of mainFieldsSet) {
if (typeof item === "string") {
mainFields.push({
name: [item],
forceRelative: true
});
} else if (Array.isArray(item)) {
mainFields.push({
name: item,
forceRelative: true
});
} else {
mainFields.push({
name: Array.isArray(item.name) ? item.name : [item.name],
forceRelative: item.forceRelative
});
}
}
return {
alias: normalizeAlias(options.alias),
fallback: normalizeAlias(options.fallback),
aliasFields: new Set(options.aliasFields),
cachePredicate:
options.cachePredicate ||
function () {
return true;
},
cacheWithContext:
typeof options.cacheWithContext !== "undefined"
? options.cacheWithContext
: true,
exportsFields: new Set(options.exportsFields || ["exports"]),
importsFields: new Set(options.importsFields || ["imports"]),
conditionNames: new Set(options.conditionNames),
descriptionFiles: Array.from(
new Set(options.descriptionFiles || ["package.json"])
),
enforceExtension:
options.enforceExtension === undefined
? options.extensions && options.extensions.includes("")
? true
: false
: options.enforceExtension,
extensions: new Set(options.extensions || [".js", ".json", ".node"]),
extensionAlias: options.extensionAlias
? Object.keys(options.extensionAlias).map(k => ({
extension: k,
alias: /** @type {ExtensionAliasOptions} */ (options.extensionAlias)[
k
]
}))
: [],
fileSystem: options.useSyncFileSystemCalls
? new SyncAsyncFileSystemDecorator(
/** @type {SyncFileSystem} */ (
/** @type {unknown} */ (options.fileSystem)
)
)
: options.fileSystem,
unsafeCache:
options.unsafeCache && typeof options.unsafeCache !== "object"
? {}
: options.unsafeCache || false,
symlinks: typeof options.symlinks !== "undefined" ? options.symlinks : true,
resolver: options.resolver,
modules: mergeFilteredToArray(
Array.isArray(options.modules)
? options.modules
: options.modules
? [options.modules]
: ["node_modules"],
item => {
const type = getType(item);
return type === PathType.Normal || type === PathType.Relative;
}
),
mainFields,
mainFiles: new Set(options.mainFiles || ["index"]),
plugins: options.plugins || [],
pnpApi: processPnpApiOption(options.pnpApi),
roots: new Set(options.roots || undefined),
fullySpecified: options.fullySpecified || false,
resolveToContext: options.resolveToContext || false,
preferRelative: options.preferRelative || false,
preferAbsolute: options.preferAbsolute || false,
restrictions: new Set(options.restrictions)
};
}
/**
* @param {UserResolveOptions} options resolve options
* @returns {Resolver} created resolver
*/
exports.createResolver = function (options) {
const normalizedOptions = createOptions(options);
const {
alias,
fallback,
aliasFields,
cachePredicate,
cacheWithContext,
conditionNames,
descriptionFiles,
enforceExtension,
exportsFields,
extensionAlias,
importsFields,
extensions,
fileSystem,
fullySpecified,
mainFields,
mainFiles,
modules,
plugins: userPlugins,
pnpApi,
resolveToContext,
preferRelative,
preferAbsolute,
symlinks,
unsafeCache,
resolver: customResolver,
restrictions,
roots
} = normalizedOptions;
const plugins = userPlugins.slice();
const resolver = customResolver
? customResolver
: new Resolver(fileSystem, normalizedOptions);
//// pipeline ////
resolver.ensureHook("resolve");
resolver.ensureHook("internalResolve");
resolver.ensureHook("newInternalResolve");
resolver.ensureHook("parsedResolve");
resolver.ensureHook("describedResolve");
resolver.ensureHook("rawResolve");
resolver.ensureHook("normalResolve");
resolver.ensureHook("internal");
resolver.ensureHook("rawModule");
resolver.ensureHook("alternateRawModule");
resolver.ensureHook("module");
resolver.ensureHook("resolveAsModule");
resolver.ensureHook("undescribedResolveInPackage");
resolver.ensureHook("resolveInPackage");
resolver.ensureHook("resolveInExistingDirectory");
resolver.ensureHook("relative");
resolver.ensureHook("describedRelative");
resolver.ensureHook("directory");
resolver.ensureHook("undescribedExistingDirectory");
resolver.ensureHook("existingDirectory");
resolver.ensureHook("undescribedRawFile");
resolver.ensureHook("rawFile");
resolver.ensureHook("file");
resolver.ensureHook("finalFile");
resolver.ensureHook("existingFile");
resolver.ensureHook("resolved");
// TODO remove in next major
// cspell:word Interal
// Backward-compat
// @ts-ignore
resolver.hooks.newInteralResolve = resolver.hooks.newInternalResolve;
// resolve
for (const { source, resolveOptions } of [
{ source: "resolve", resolveOptions: { fullySpecified } },
{ source: "internal-resolve", resolveOptions: { fullySpecified: false } }
]) {
if (unsafeCache) {
plugins.push(
new UnsafeCachePlugin(
source,
cachePredicate,
/** @type {import("./UnsafeCachePlugin").Cache} */ (unsafeCache),
cacheWithContext,
`new-${source}`
)
);
plugins.push(
new ParsePlugin(`new-${source}`, resolveOptions, "parsed-resolve")
);
} else {
plugins.push(new ParsePlugin(source, resolveOptions, "parsed-resolve"));
}
}
// parsed-resolve
plugins.push(
new DescriptionFilePlugin(
"parsed-resolve",
descriptionFiles,
false,
"described-resolve"
)
);
plugins.push(new NextPlugin("after-parsed-resolve", "described-resolve"));
// described-resolve
plugins.push(new NextPlugin("described-resolve", "raw-resolve"));
if (fallback.length > 0) {
plugins.push(
new AliasPlugin("described-resolve", fallback, "internal-resolve")
);
}
// raw-resolve
if (alias.length > 0) {
plugins.push(new AliasPlugin("raw-resolve", alias, "internal-resolve"));
}
aliasFields.forEach(item => {
plugins.push(new AliasFieldPlugin("raw-resolve", item, "internal-resolve"));
});
extensionAlias.forEach(item =>
plugins.push(
new ExtensionAliasPlugin("raw-resolve", item, "normal-resolve")
)
);
plugins.push(new NextPlugin("raw-resolve", "normal-resolve"));
// normal-resolve
if (preferRelative) {
plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
}
plugins.push(
new ConditionalPlugin(
"after-normal-resolve",
{ module: true },
"resolve as module",
false,
"raw-module"
)
);
plugins.push(
new ConditionalPlugin(
"after-normal-resolve",
{ internal: true },
"resolve as internal import",
false,
"internal"
)
);
if (preferAbsolute) {
plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
}
if (roots.size > 0) {
plugins.push(new RootsPlugin("after-normal-resolve", roots, "relative"));
}
if (!preferRelative && !preferAbsolute) {
plugins.push(new JoinRequestPlugin("after-normal-resolve", "relative"));
}
// internal
importsFields.forEach(importsField => {
plugins.push(
new ImportsFieldPlugin(
"internal",
conditionNames,
importsField,
"relative",
"internal-resolve"
)
);
});
// raw-module
exportsFields.forEach(exportsField => {
plugins.push(
new SelfReferencePlugin("raw-module", exportsField, "resolve-as-module")
);
});
modules.forEach(item => {
if (Array.isArray(item)) {
if (item.includes("node_modules") && pnpApi) {
plugins.push(
new ModulesInHierarchicalDirectoriesPlugin(
"raw-module",
item.filter(i => i !== "node_modules"),
"module"
)
);
plugins.push(
new PnpPlugin(
"raw-module",
pnpApi,
"undescribed-resolve-in-package",
"alternate-raw-module"
)
);
plugins.push(
new ModulesInHierarchicalDirectoriesPlugin(
"alternate-raw-module",
["node_modules"],
"module"
)
);
} else {
plugins.push(
new ModulesInHierarchicalDirectoriesPlugin(
"raw-module",
item,
"module"
)
);
}
} else {
plugins.push(new ModulesInRootPlugin("raw-module", item, "module"));
}
});
// module
plugins.push(new JoinRequestPartPlugin("module", "resolve-as-module"));
// resolve-as-module
if (!resolveToContext) {
plugins.push(
new ConditionalPlugin(
"resolve-as-module",
{ directory: false, request: "." },
"single file module",
true,
"undescribed-raw-file"
)
);
}
plugins.push(
new DirectoryExistsPlugin(
"resolve-as-module",
"undescribed-resolve-in-package"
)
);
// undescribed-resolve-in-package
plugins.push(
new DescriptionFilePlugin(
"undescribed-resolve-in-package",
descriptionFiles,
false,
"resolve-in-package"
)
);
plugins.push(
new NextPlugin("after-undescribed-resolve-in-package", "resolve-in-package")
);
// resolve-in-package
exportsFields.forEach(exportsField => {
plugins.push(
new ExportsFieldPlugin(
"resolve-in-package",
conditionNames,
exportsField,
"relative"
)
);
});
plugins.push(
new NextPlugin("resolve-in-package", "resolve-in-existing-directory")
);
// resolve-in-existing-directory
plugins.push(
new JoinRequestPlugin("resolve-in-existing-directory", "relative")
);
// relative
plugins.push(
new DescriptionFilePlugin(
"relative",
descriptionFiles,
true,
"described-relative"
)
);
plugins.push(new NextPlugin("after-relative", "described-relative"));
// described-relative
if (resolveToContext) {
plugins.push(new NextPlugin("described-relative", "directory"));
} else {
plugins.push(
new ConditionalPlugin(
"described-relative",
{ directory: false },
null,
true,
"raw-file"
)
);
plugins.push(
new ConditionalPlugin(
"described-relative",
{ fullySpecified: false },
"as directory",
true,
"directory"
)
);
}
// directory
plugins.push(
new DirectoryExistsPlugin("directory", "undescribed-existing-directory")
);
if (resolveToContext) {
// undescribed-existing-directory
plugins.push(new NextPlugin("undescribed-existing-directory", "resolved"));
} else {
// undescribed-existing-directory
plugins.push(
new DescriptionFilePlugin(
"undescribed-existing-directory",
descriptionFiles,
false,
"existing-directory"
)
);
mainFiles.forEach(item => {
plugins.push(
new UseFilePlugin(
"undescribed-existing-directory",
item,
"undescribed-raw-file"
)
);
});
// described-existing-directory
mainFields.forEach(item => {
plugins.push(
new MainFieldPlugin(
"existing-directory",
item,
"resolve-in-existing-directory"
)
);
});
mainFiles.forEach(item => {
plugins.push(
new UseFilePlugin("existing-directory", item, "undescribed-raw-file")
);
});
// undescribed-raw-file
plugins.push(
new DescriptionFilePlugin(
"undescribed-raw-file",
descriptionFiles,
true,
"raw-file"
)
);
plugins.push(new NextPlugin("after-undescribed-raw-file", "raw-file"));
// raw-file
plugins.push(
new ConditionalPlugin(
"raw-file",
{ fullySpecified: true },
null,
false,
"file"
)
);
if (!enforceExtension) {
plugins.push(new TryNextPlugin("raw-file", "no extension", "file"));
}
extensions.forEach(item => {
plugins.push(new AppendPlugin("raw-file", item, "file"));
});
// file
if (alias.length > 0)
plugins.push(new AliasPlugin("file", alias, "internal-resolve"));
aliasFields.forEach(item => {
plugins.push(new AliasFieldPlugin("file", item, "internal-resolve"));
});
plugins.push(new NextPlugin("file", "final-file"));
// final-file
plugins.push(new FileExistsPlugin("final-file", "existing-file"));
// existing-file
if (symlinks)
plugins.push(new SymlinkPlugin("existing-file", "existing-file"));
plugins.push(new NextPlugin("existing-file", "resolved"));
}
const resolved =
/** @type {KnownHooks & EnsuredHooks} */
(resolver.hooks).resolved;
// resolved
if (restrictions.size > 0) {
plugins.push(new RestrictionsPlugin(resolved, restrictions));
}
plugins.push(new ResultPlugin(resolved));
//// RESOLVER ////
for (const plugin of plugins) {
if (typeof plugin === "function") {
/** @type {function(this: Resolver, Resolver): void} */
(plugin).call(resolver, resolver);
} else if (plugin) {
plugin.apply(resolver);
}
}
return resolver;
};
/**
* Merging filtered elements
* @param {string[]} array source array
* @param {function(string): boolean} filter predicate
* @returns {Array<string | string[]>} merge result
*/
function mergeFilteredToArray(array, filter) {
/** @type {Array<string | string[]>} */
const result = [];
const set = new Set(array);
for (const item of set) {
if (filter(item)) {
const lastElement =
result.length > 0 ? result[result.length - 1] : undefined;
if (Array.isArray(lastElement)) {
lastElement.push(item);
} else {
result.push([item]);
}
} else {
result.push(item);
}
}
return result;
}

View file

@ -0,0 +1,70 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Ivan Kopeykin @vankop
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
const slashCode = "/".charCodeAt(0);
const backslashCode = "\\".charCodeAt(0);
/**
* @param {string} path path
* @param {string} parent parent path
* @returns {boolean} true, if path is inside of parent
*/
const isInside = (path, parent) => {
if (!path.startsWith(parent)) return false;
if (path.length === parent.length) return true;
const charCode = path.charCodeAt(parent.length);
return charCode === slashCode || charCode === backslashCode;
};
module.exports = class RestrictionsPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {Set<string | RegExp>} restrictions restrictions
*/
constructor(source, restrictions) {
this.source = source;
this.restrictions = restrictions;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
resolver
.getHook(this.source)
.tapAsync("RestrictionsPlugin", (request, resolveContext, callback) => {
if (typeof request.path === "string") {
const path = request.path;
for (const rule of this.restrictions) {
if (typeof rule === "string") {
if (!isInside(path, rule)) {
if (resolveContext.log) {
resolveContext.log(
`${path} is not inside of the restriction ${rule}`
);
}
return callback(null, null);
}
} else if (!rule.test(path)) {
if (resolveContext.log) {
resolveContext.log(
`${path} doesn't match the restriction ${rule}`
);
}
return callback(null, null);
}
}
}
callback();
});
}
};

42
node_modules/enhanced-resolve/lib/ResultPlugin.js generated vendored Normal file
View file

@ -0,0 +1,42 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class ResultPlugin {
/**
* @param {ResolveStepHook} source source
*/
constructor(source) {
this.source = source;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
this.source.tapAsync(
"ResultPlugin",
(request, resolverContext, callback) => {
const obj = { ...request };
if (resolverContext.log)
resolverContext.log("reporting result " + obj.path);
resolver.hooks.result.callAsync(obj, resolverContext, err => {
if (err) return callback(err);
if (typeof resolverContext.yield === "function") {
resolverContext.yield(obj);
callback(null, null);
} else {
callback(null, obj);
}
});
}
);
}
};

100
node_modules/enhanced-resolve/lib/SymlinkPlugin.js generated vendored Normal file
View file

@ -0,0 +1,100 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const forEachBail = require("./forEachBail");
const getPaths = require("./getPaths");
const { getType, PathType } = require("./util/path");
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class SymlinkPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string | ResolveStepHook} target target
*/
constructor(source, target) {
this.source = source;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
const fs = resolver.fileSystem;
resolver
.getHook(this.source)
.tapAsync("SymlinkPlugin", (request, resolveContext, callback) => {
if (request.ignoreSymlinks) return callback();
const pathsResult = getPaths(/** @type {string} */ (request.path));
const pathSegments = pathsResult.segments;
const paths = pathsResult.paths;
let containsSymlink = false;
let idx = -1;
forEachBail(
paths,
/**
* @param {string} path path
* @param {(err?: null|Error, result?: null|number) => void} callback callback
* @returns {void}
*/
(path, callback) => {
idx++;
if (resolveContext.fileDependencies)
resolveContext.fileDependencies.add(path);
fs.readlink(path, (err, result) => {
if (!err && result) {
pathSegments[idx] = /** @type {string} */ (result);
containsSymlink = true;
// Shortcut when absolute symlink found
const resultType = getType(result.toString());
if (
resultType === PathType.AbsoluteWin ||
resultType === PathType.AbsolutePosix
) {
return callback(null, idx);
}
}
callback();
});
},
/**
* @param {null|Error} [err] error
* @param {null|number} [idx] result
* @returns {void}
*/
(err, idx) => {
if (!containsSymlink) return callback();
const resultSegments =
typeof idx === "number"
? pathSegments.slice(0, idx + 1)
: pathSegments.slice();
const result = resultSegments.reduceRight((a, b) => {
return resolver.join(a, b);
});
/** @type {ResolveRequest} */
const obj = {
...request,
path: result
};
resolver.doResolve(
target,
obj,
"resolved symlink to " + result,
resolveContext,
callback
);
}
);
});
}
};

View file

@ -0,0 +1,220 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver").FileSystem} FileSystem */
/** @typedef {import("./Resolver").ReaddirStringCallback} ReaddirStringCallback */
/** @typedef {import("./Resolver").StringCallback} StringCallback */
/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */
/**
* @param {SyncFileSystem} fs file system implementation
* @constructor
*/
function SyncAsyncFileSystemDecorator(fs) {
this.fs = fs;
this.lstat = undefined;
this.lstatSync = undefined;
const lstatSync = fs.lstatSync;
if (lstatSync) {
this.lstat =
/** @type {FileSystem["lstat"]} */
(
(arg, options, callback) => {
let result;
try {
result = /** @type {Function | undefined} */ (callback)
? lstatSync.call(fs, arg, options)
: lstatSync.call(fs, arg);
} catch (e) {
return (callback || options)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.lstatSync =
/** @type {SyncFileSystem["lstatSync"]} */
((arg, options) => lstatSync.call(fs, arg, options));
}
this.stat =
/** @type {FileSystem["stat"]} */
(
(arg, options, callback) => {
let result;
try {
result = /** @type {Function | undefined} */ (callback)
? fs.statSync(arg, options)
: fs.statSync(arg);
} catch (e) {
return (callback || options)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.statSync =
/** @type {SyncFileSystem["statSync"]} */
((arg, options) => fs.statSync(arg, options));
this.readdir =
/** @type {FileSystem["readdir"]} */
(
(arg, options, callback) => {
let result;
try {
result = /** @type {Function | undefined} */ (callback)
? fs.readdirSync(
arg,
/** @type {Exclude<Parameters<FileSystem["readdir"]>[1], ReaddirStringCallback>} */
(options)
)
: fs.readdirSync(arg);
} catch (e) {
return (callback || options)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.readdirSync =
/** @type {SyncFileSystem["readdirSync"]} */
(
(arg, options) =>
fs.readdirSync(
arg,
/** @type {Parameters<SyncFileSystem["readdirSync"]>[1]} */ (options)
)
);
this.readFile =
/** @type {FileSystem["readFile"]} */
(
(arg, options, callback) => {
let result;
try {
result = /** @type {Function | undefined} */ (callback)
? fs.readFileSync(arg, options)
: fs.readFileSync(arg);
} catch (e) {
return (callback || options)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.readFileSync =
/** @type {SyncFileSystem["readFileSync"]} */
((arg, options) => fs.readFileSync(arg, options));
this.readlink =
/** @type {FileSystem["readlink"]} */
(
(arg, options, callback) => {
let result;
try {
result = /** @type {Function | undefined} */ (callback)
? fs.readlinkSync(
arg,
/** @type {Exclude<Parameters<FileSystem["readlink"]>[1], StringCallback>} */
(options)
)
: fs.readlinkSync(arg);
} catch (e) {
return (callback || options)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.readlinkSync =
/** @type {SyncFileSystem["readlinkSync"]} */
(
(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 {FileSystem["readJson"]} */
(
(arg, callback) => {
let result;
try {
result = readJsonSync.call(fs, arg);
} catch (e) {
return callback(
/** @type {NodeJS.ErrnoException | Error | null} */ (e)
);
}
callback(null, result);
}
);
this.readJsonSync =
/** @type {SyncFileSystem["readJsonSync"]} */
(arg => readJsonSync.call(fs, arg));
}
this.realpath = undefined;
this.realpathSync = undefined;
const realpathSync = fs.realpathSync;
if (realpathSync) {
this.realpath =
/** @type {FileSystem["realpath"]} */
(
(arg, options, callback) => {
let result;
try {
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)(
/** @type {NodeJS.ErrnoException | null} */ (e)
);
}
(callback || options)(null, /** @type {any} */ (result));
}
);
this.realpathSync =
/** @type {SyncFileSystem["realpathSync"]} */
(
(arg, options) =>
realpathSync.call(
fs,
arg,
/** @type {Parameters<NonNullable<SyncFileSystem["realpathSync"]>>[1]} */
(options)
)
);
}
}
module.exports = SyncAsyncFileSystemDecorator;

41
node_modules/enhanced-resolve/lib/TryNextPlugin.js generated vendored Normal file
View file

@ -0,0 +1,41 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class TryNextPlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string} message message
* @param {string | ResolveStepHook} target target
*/
constructor(source, message, target) {
this.source = source;
this.message = message;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("TryNextPlugin", (request, resolveContext, callback) => {
resolver.doResolve(
target,
request,
this.message,
resolveContext,
callback
);
});
}
};

112
node_modules/enhanced-resolve/lib/UnsafeCachePlugin.js generated vendored Normal file
View file

@ -0,0 +1,112 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
/** @typedef {import("./Resolver").ResolveContextYield} ResolveContextYield */
/** @typedef {{[k: string]: ResolveRequest | ResolveRequest[] | undefined}} Cache */
/**
* @param {string} type type of cache
* @param {ResolveRequest} request request
* @param {boolean} withContext cache with context?
* @returns {string} cache id
*/
function getCacheId(type, request, withContext) {
return JSON.stringify({
type,
context: withContext ? request.context : "",
path: request.path,
query: request.query,
fragment: request.fragment,
request: request.request
});
}
module.exports = class UnsafeCachePlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {function(ResolveRequest): boolean} filterPredicate filterPredicate
* @param {Cache} cache cache
* @param {boolean} withContext withContext
* @param {string | ResolveStepHook} target target
*/
constructor(source, filterPredicate, cache, withContext, target) {
this.source = source;
this.filterPredicate = filterPredicate;
this.withContext = withContext;
this.cache = cache;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("UnsafeCachePlugin", (request, resolveContext, callback) => {
if (!this.filterPredicate(request)) return callback();
const isYield = typeof resolveContext.yield === "function";
const cacheId = getCacheId(
isYield ? "yield" : "default",
request,
this.withContext
);
const cacheEntry = this.cache[cacheId];
if (cacheEntry) {
if (isYield) {
const yield_ = /** @type {Function} */ (resolveContext.yield);
if (Array.isArray(cacheEntry)) {
for (const result of cacheEntry) yield_(result);
} else {
yield_(cacheEntry);
}
return callback(null, null);
}
return callback(null, /** @type {ResolveRequest} */ (cacheEntry));
}
/** @type {ResolveContextYield|undefined} */
let yieldFn;
/** @type {ResolveContextYield|undefined} */
let yield_;
/** @type {ResolveRequest[]} */
const yieldResult = [];
if (isYield) {
yieldFn = resolveContext.yield;
yield_ = result => {
yieldResult.push(result);
};
}
resolver.doResolve(
target,
request,
null,
yield_ ? { ...resolveContext, yield: yield_ } : resolveContext,
(err, result) => {
if (err) return callback(err);
if (isYield) {
if (result) yieldResult.push(result);
for (const result of yieldResult) {
/** @type {ResolveContextYield} */
(yieldFn)(result);
}
this.cache[cacheId] = yieldResult;
return callback(null, null);
}
if (result) return callback(null, (this.cache[cacheId] = result));
callback();
}
);
});
}
};

55
node_modules/enhanced-resolve/lib/UseFilePlugin.js generated vendored Normal file
View file

@ -0,0 +1,55 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
module.exports = class UseFilePlugin {
/**
* @param {string | ResolveStepHook} source source
* @param {string} filename filename
* @param {string | ResolveStepHook} target target
*/
constructor(source, filename, target) {
this.source = source;
this.filename = filename;
this.target = target;
}
/**
* @param {Resolver} resolver the resolver
* @returns {void}
*/
apply(resolver) {
const target = resolver.ensureHook(this.target);
resolver
.getHook(this.source)
.tapAsync("UseFilePlugin", (request, resolveContext, callback) => {
const filePath = resolver.join(
/** @type {string} */ (request.path),
this.filename
);
/** @type {ResolveRequest} */
const obj = {
...request,
path: filePath,
relativePath:
request.relativePath &&
resolver.join(request.relativePath, this.filename)
};
resolver.doResolve(
target,
obj,
"using path: " + filePath,
resolveContext,
callback
);
});
}
};

View file

@ -0,0 +1,46 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver").ResolveContext} ResolveContext */
/**
* @param {ResolveContext} options options for inner context
* @param {null|string} message message to log
* @returns {ResolveContext} inner context
*/
module.exports = function createInnerContext(options, message) {
let messageReported = false;
let innerLog = undefined;
if (options.log) {
if (message) {
/**
* @param {string} msg message
*/
innerLog = msg => {
if (!messageReported) {
/** @type {(function(string): void)} */
(options.log)(message);
messageReported = true;
}
/** @type {(function(string): void)} */
(options.log)(" " + msg);
};
} else {
innerLog = options.log;
}
}
return {
log: innerLog,
yield: options.yield,
fileDependencies: options.fileDependencies,
contextDependencies: options.contextDependencies,
missingDependencies: options.missingDependencies,
stack: options.stack
};
};

50
node_modules/enhanced-resolve/lib/forEachBail.js generated vendored Normal file
View file

@ -0,0 +1,50 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/**
* @template T
* @template Z
* @callback Iterator
* @param {T} item item
* @param {(err?: null|Error, result?: null|Z) => void} callback callback
* @param {number} i index
* @returns {void}
*/
/**
* @template T
* @template Z
* @param {T[]} array array
* @param {Iterator<T, Z>} iterator iterator
* @param {(err?: null|Error, result?: null|Z, i?: number) => void} callback callback after all items are iterated
* @returns {void}
*/
module.exports = function forEachBail(array, iterator, callback) {
if (array.length === 0) return callback();
let i = 0;
const next = () => {
/** @type {boolean|undefined} */
let loop = undefined;
iterator(
array[i++],
(err, result) => {
if (err || result !== undefined || i >= array.length) {
return callback(err, result, i);
}
if (loop === false) while (next());
loop = true;
},
i
);
if (!loop) loop = false;
return loop;
};
while (next());
};

36
node_modules/enhanced-resolve/lib/getInnerRequest.js generated vendored Normal file
View file

@ -0,0 +1,36 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/** @typedef {import("./Resolver")} Resolver */
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
/**
* @param {Resolver} resolver resolver
* @param {ResolveRequest} request string
* @returns {string} inner request
*/
module.exports = function getInnerRequest(resolver, request) {
if (
typeof request.__innerRequest === "string" &&
request.__innerRequest_request === request.request &&
request.__innerRequest_relativePath === request.relativePath
)
return request.__innerRequest;
/** @type {string|undefined} */
let innerRequest;
if (request.request) {
innerRequest = request.request;
if (/^\.\.?(?:\/|$)/.test(innerRequest) && request.relativePath) {
innerRequest = resolver.join(request.relativePath, innerRequest);
}
} else {
innerRequest = request.relativePath;
}
request.__innerRequest_request = request.request;
request.__innerRequest_relativePath = request.relativePath;
return (request.__innerRequest = /** @type {string} */ (innerRequest));
};

45
node_modules/enhanced-resolve/lib/getPaths.js generated vendored Normal file
View file

@ -0,0 +1,45 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
/**
* @param {string} path path
* @returns {{paths: string[], segments: string[]}}} paths and segments
*/
module.exports = function getPaths(path) {
if (path === "/") return { paths: ["/"], segments: [""] };
const parts = path.split(/(.*?[\\/]+)/);
const paths = [path];
const segments = [parts[parts.length - 1]];
let part = parts[parts.length - 1];
path = path.substring(0, path.length - part.length - 1);
for (let i = parts.length - 2; i > 2; i -= 2) {
paths.push(path);
part = parts[i];
path = path.substring(0, path.length - part.length) || "/";
segments.push(part.slice(0, -1));
}
part = parts[1];
segments.push(part);
paths.push(part);
return {
paths: paths,
segments: segments
};
};
/**
* @param {string} path path
* @returns {string|null} basename or null
*/
module.exports.basename = function basename(path) {
const i = path.lastIndexOf("/"),
j = path.lastIndexOf("\\");
const p = i < 0 ? j : j < 0 ? i : i < j ? j : i;
if (p < 0) return null;
const s = path.slice(p + 1);
return s;
};

72
node_modules/enhanced-resolve/package.json generated vendored Normal file
View file

@ -0,0 +1,72 @@
{
"name": "enhanced-resolve",
"version": "5.17.1",
"author": "Tobias Koppers @sokra",
"description": "Offers a async require.resolve function. It's highly configurable.",
"files": [
"lib",
"types.d.ts",
"LICENSE"
],
"browser": {
"process": "./lib/util/process-browser.js",
"module": "./lib/util/module-browser.js"
},
"dependencies": {
"graceful-fs": "^4.2.4",
"tapable": "^2.2.0"
},
"license": "MIT",
"devDependencies": {
"@types/graceful-fs": "^4.1.6",
"@types/jest": "^27.5.1",
"@types/node": "20.9.5",
"cspell": "4.2.8",
"eslint": "^7.9.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-jsdoc": "^30.5.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.4",
"husky": "^6.0.0",
"jest": "^27.5.1",
"lint-staged": "^10.4.0",
"memfs": "^3.2.0",
"prettier": "^2.1.2",
"tooling": "webpack/tooling#v1.23.1",
"typescript": "^5.3.3"
},
"engines": {
"node": ">=10.13.0"
},
"main": "lib/index.js",
"types": "types.d.ts",
"homepage": "http://github.com/webpack/enhanced-resolve",
"scripts": {
"lint": "yarn run code-lint && yarn run type-lint && yarn typings-test && yarn run special-lint && yarn run spelling",
"fix": "yarn run code-lint-fix && yarn run special-lint-fix",
"code-lint": "eslint --cache lib test",
"code-lint-fix": "eslint --cache lib test --fix",
"type-lint": "tsc",
"typings-test": "tsc -p tsconfig.types.test.json",
"type-report": "rimraf coverage && yarn cover:types && yarn cover:report && open-cli coverage/lcov-report/index.html",
"special-lint": "node node_modules/tooling/lockfile-lint && node node_modules/tooling/inherit-types && node node_modules/tooling/format-file-header && node node_modules/tooling/generate-types",
"special-lint-fix": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/format-file-header --write && node node_modules/tooling/generate-types --write",
"pretty": "prettier --loglevel warn --write \"lib/**/*.{js,json}\" \"test/*.js\"",
"pretest": "yarn lint",
"spelling": "cspell \"**\"",
"test:only": "node_modules/.bin/jest",
"test:watch": "yarn test:only -- --watch",
"test:coverage": "yarn test:only -- --collectCoverageFrom=\"lib/**/*.js\" --coverage",
"test": "yarn test:coverage",
"precover": "yarn lint",
"prepare": "husky install"
},
"lint-staged": {
"*": "cspell --no-must-find-files",
"*.js": "eslint --cache"
},
"repository": {
"type": "git",
"url": "git://github.com/webpack/enhanced-resolve.git"
}
}