diff --git a/.changeset/generate-types-with-typescript.md b/.changeset/generate-types-with-typescript.md new file mode 100644 index 00000000..7514934c --- /dev/null +++ b/.changeset/generate-types-with-typescript.md @@ -0,0 +1,5 @@ +--- +"enhanced-resolve": minor +--- + +Generate the published type declarations with TypeScript instead of `webpack/tooling`, which is no longer a dependency. Every name the package exported before is still exported, and `types.d.ts` is still the entry point, but the declarations themselves now live in `types/` and are emitted by `tsc` from the JSDoc in `lib/`. Two shapes follow the sources more closely than the previous generator did: the object form of `Plugin` no longer declares `this: Resolver` on `apply` (it is called as `plugin.apply(resolver)`, so `this` is the plugin), and the entries of `ResolveContext.stack` declare `name: string | undefined` rather than an optional `name`. Class fields that the old generator dropped, such as the cache backends on `CachedInputFileSystem`, are now part of the declarations. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9a531d6e..11bec040 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,6 +36,21 @@ jobs: - run: npm ci - run: npm run lint + + - name: Build types + run: npm run build:types + + # `types/` is generated from the JSDoc in `lib/`, so a checkout whose + # declarations were never regenerated ships types that do not describe + # the code. Regenerating above and diffing here is what catches that. + - name: Check types + run: | + if [ -n "$(git status types --porcelain)" ]; then + git status types --porcelain + echo "::error::Generated types are out of date - run 'npm run build:types' and commit the result" + exit 1 + fi + echo "All types are up to date" test: strategy: fail-fast: false diff --git a/.prettierignore b/.prettierignore index d69fb976..793d7065 100644 --- a/.prettierignore +++ b/.prettierignore @@ -2,6 +2,3 @@ package.json package-lock.json test/**/*.* !test/*.js - -# Generated files -types.d.ts diff --git a/eslint.config.mjs b/eslint.config.mjs index bff426fa..d4a3e6c4 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -2,7 +2,7 @@ import { defineConfig, globalIgnores } from "eslint/config"; import config from "eslint-config-webpack"; export default defineConfig([ - globalIgnores(["benchmark/**/fixture/**"]), + globalIgnores(["benchmark/**/fixture/**", "types/**"]), { extends: [config], }, diff --git a/lib/PackageMapPlugin.js b/lib/PackageMapPlugin.js index 12592510..39377b33 100644 --- a/lib/PackageMapPlugin.js +++ b/lib/PackageMapPlugin.js @@ -20,7 +20,7 @@ const { /** * @typedef {object} PackageMapOptions - * @property {string | null} configFile absolute path of the configuration file, read lazily when `packages` is not given + * @property {string} configFile absolute path of the configuration file, read lazily when `packages` is not given * @property {PackageMapPackages | null} packages an already-parsed `packages` object, used instead of reading `configFile` */ @@ -159,7 +159,7 @@ module.exports = class PackageMapPlugin { * @returns {void} */ _resolveConfigFile(resolver, callback) { - const { configFile } = /** @type {{ configFile: string }} */ (this.options); + const { configFile } = this.options; const { realpath } = resolver.fileSystem; if (!this.symlinks || !realpath) return callback(configFile); diff --git a/lib/index.js b/lib/index.js index 256d4f7f..b7f7a0c1 100644 --- a/lib/index.js +++ b/lib/index.js @@ -7,7 +7,10 @@ const memoize = require("./util/memoize"); +/** @typedef {import("./CachedInputFileSystem")} CachedInputFileSystem */ /** @typedef {import("./CachedInputFileSystem").BaseFileSystem} BaseFileSystem */ +/** @typedef {import("./CloneBasenamePlugin")} CloneBasenamePlugin */ +/** @typedef {import("./LogInfoPlugin")} LogInfoPlugin */ /** @typedef {import("./PnpPlugin").PnpApiImpl} PnpApi */ /** @typedef {import("./Resolver")} Resolver */ /** @typedef {import("./Resolver").Context} Context */ @@ -18,6 +21,7 @@ const memoize = require("./util/memoize"); /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */ /** @typedef {import("./ResolverFactory").Plugin} Plugin */ /** @typedef {import("./ResolverFactory").UserResolveOptions} ResolveOptions */ +/** @typedef {import("./TsconfigPathsPlugin")} TsconfigPathsPlugin */ /** * @typedef {{ diff --git a/lib/util/graceful-fs-browser.js b/lib/util/graceful-fs-browser.js index 1dda4f00..63210c8f 100644 --- a/lib/util/graceful-fs-browser.js +++ b/lib/util/graceful-fs-browser.js @@ -16,9 +16,13 @@ const message = "Pass a `fileSystem` to `create()` or `ResolverFactory.createResolver()`."; /** + * Takes the arguments its callers pass - `readFile(path, callback)` and the + * rest - so the declaration describes a call that actually compiles, even + * though every one of them throws. + * @param {...unknown} _args arguments, ignored * @returns {never} always throws */ -const unavailable = () => { +const unavailable = (..._args) => { throw new Error(message); }; diff --git a/package-lock.json b/package-lock.json index 2374f329..7d47afe7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "enhanced-resolve", - "version": "5.24.5", + "version": "5.25.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "enhanced-resolve", - "version": "5.24.5", + "version": "5.25.1", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -26,7 +26,6 @@ "memfs": "^4.56.11", "prettier": "^3.7.4", "tinybench": "^6.0.0", - "tooling": "https://codeload.github.com/webpack/tooling/tar.gz/refs/tags/v1.26.4", "typescript": "^6.0.2", "webpack": "^5.107.2" }, @@ -34,24 +33,6 @@ "node": ">=10.13.0" } }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.9.3", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.3.tgz", - "integrity": "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, "node_modules/@babel/code-frame": { "version": "7.29.7", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz", @@ -1619,13 +1600,6 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true, - "license": "MIT" - }, "node_modules/@jsonjoy.com/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", @@ -2224,13 +2198,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/lodash": { - "version": "4.17.24", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.24.tgz", - "integrity": "sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/mdast": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", @@ -2722,13 +2689,6 @@ "dev": true, "license": "Apache-2.0" }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true, - "license": "BSD-2-Clause" - }, "node_modules/acorn": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", @@ -3350,77 +3310,6 @@ "node": ">=0.8.0" } }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/cliui/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/cliui/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -3488,13 +3377,6 @@ "node": ">= 12.0.0" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true, - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3956,13 +3838,6 @@ "dev": true, "license": "ISC" }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, "node_modules/enhanced-resolve": { "version": "5.24.5", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", @@ -5279,13 +5154,6 @@ "node": ">=0.4.x" } }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5360,16 +5228,6 @@ "node": ">=6.9.0" } }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, "node_modules/get-intrinsic": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", @@ -5457,28 +5315,6 @@ "dev": true, "license": "ISC" }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5816,25 +5652,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, "node_modules/ini": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", @@ -6414,30 +6231,6 @@ "dev": true, "license": "MIT" }, - "node_modules/json-schema-to-typescript": { - "version": "15.0.4", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz", - "integrity": "sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.5", - "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.7", - "is-glob": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "prettier": "^3.2.5", - "tinyglobby": "^0.2.9" - }, - "bin": { - "json2ts": "dist/src/cli.js" - }, - "engines": { - "node": ">=16.0.0" - } - }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -6621,13 +6414,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/lodash": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", - "dev": true, - "license": "MIT" - }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -7938,16 +7724,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -8064,16 +7840,6 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -8276,16 +8042,6 @@ "regjsparser": "bin/parser" } }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -8880,29 +8636,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -9094,50 +8827,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/tooling": { - "version": "1.26.4", - "resolved": "https://codeload.github.com/webpack/tooling/tar.gz/refs/tags/v1.26.4", - "integrity": "sha512-SpwV8A0E7t6nfWSy4tPYfmbVLjJtZu7d39tTyZ5ZUmqJ19C0dLFZHVgnUewQR6uJVkPSDyFj9PSkBiHJw7tuzw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@yarnpkg/lockfile": "^1.1.0", - "ajv": "^8.1.0", - "commondir": "^1.0.1", - "glob": "^7.1.6", - "json-schema-to-typescript": "^15.0.4", - "terser": "^5.32.0", - "yargs": "^16.1.1" - }, - "peerDependencies": { - "prettier": "*", - "typescript": "*" - } - }, - "node_modules/tooling/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/tooling/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/tree-dump": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", @@ -9689,13 +9378,6 @@ "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, "node_modules/xdg-basedir": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-5.1.0.tgz", @@ -9709,16 +9391,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -9742,60 +9414,6 @@ "url": "https://github.com/sponsors/eemeli" } }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/yocto-queue": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz", diff --git a/package.json b/package.json index 2c72af1c..e48c91af 100644 --- a/package.json +++ b/package.json @@ -20,23 +20,23 @@ "types": "types.d.ts", "files": [ "lib", + "types", "types.d.ts", "LICENSE" ], "scripts": { "prepare": "husky", - "lint": "npm run lint:code && npm run lint:types && npm run lint:types-test && npm run lint:special && npm run fmt:check && npm run lint:spellcheck", + "lint": "npm run lint:code && npm run lint:types && npm run lint:types-test && npm run fmt:check && npm run lint:spellcheck", "lint:code": "eslint --cache .", - "lint:special": "node node_modules/tooling/inherit-types && node node_modules/tooling/generate-types", "lint:types": "tsc", "lint:types-test": "tsc -p tsconfig.types.test.json", "lint:spellcheck": "cspell --cache --no-must-find-files --quiet \"**/*.*\"", "fmt": "npm run fmt:base -- --log-level warn --write", "fmt:check": "npm run fmt:base -- --check", "fmt:base": "node_modules/prettier/bin/prettier.cjs --cache --ignore-unknown .", - "fix": "npm run fix:code && npm run fix:special", + "fix": "npm run fix:code && npm run build:types", "fix:code": "npm run lint:code -- --fix", - "fix:special": "node node_modules/tooling/inherit-types --write && node node_modules/tooling/generate-types --write", + "build:types": "node -e \"require('fs').rmSync('types', { recursive: true, force: true })\" && tsc -p tsconfig.types.json && prettier --log-level warn --write \"types/**/*.d.ts\"", "type-report": "rimraf coverage && npm run cover:types && npm run cover:report && open-cli coverage/lcov-report/index.html", "pretest": "npm run lint", "test": "npm run test:only", @@ -75,7 +75,6 @@ "memfs": "^4.56.11", "prettier": "^3.7.4", "tinybench": "^6.0.0", - "tooling": "https://codeload.github.com/webpack/tooling/tar.gz/refs/tags/v1.26.4", "typescript": "^6.0.2", "webpack": "^5.107.2" }, diff --git a/tsconfig.types.json b/tsconfig.types.json index 1c66acf6..7d0dc8c4 100644 --- a/tsconfig.types.json +++ b/tsconfig.types.json @@ -1,3 +1,10 @@ { - "extends": "./tsconfig" + "extends": "./tsconfig", + "compilerOptions": { + "noEmit": false, + "declaration": true, + "emitDeclarationOnly": true, + "rootDir": "lib", + "declarationDir": "types" + } } diff --git a/types.d.ts b/types.d.ts index 8701a271..c8ec3d3b 100644 --- a/types.d.ts +++ b/types.d.ts @@ -1,2107 +1,9 @@ /* - * This file was automatically generated. - * DO NOT MODIFY BY HAND. - * Run `yarn fix:special` to update + * The type declarations are generated from the JSDoc in `lib/` and live in + * `types/`. This file re-exports the entry point so that the `types` field and + * any direct reference to `enhanced-resolve/types.d.ts` keep resolving. */ -import { Buffer } from "buffer"; -import { AsyncSeriesBailHook, AsyncSeriesHook, SyncHook } from "tapable"; -import { URL as URL_Import } from "url"; +import resolve = require("./types/index"); -declare interface Abortable { - /** - * When provided the corresponding `AbortController` can be used to cancel an asynchronous action. - */ - signal?: AbortSignal; -} -type Alias = string | false | string[]; -declare interface AliasOption { - alias: Alias; - name: string; - onlyModule?: boolean; -} -type BaseFileSystem = FileSystem & SyncFileSystem; -declare interface BaseResolveRequest { - /** - * path - */ - path: string | false; - - /** - * content - */ - context?: Context; - - /** - * description file path - */ - descriptionFilePath?: string; - - /** - * description file root - */ - descriptionFileRoot?: string; - - /** - * description file data - */ - descriptionFileData?: JsonObject; - - /** - * tsconfig paths map - */ - tsconfigPathsMap?: null | TsconfigPathsMap; - - /** - * relative path - */ - relativePath?: string; - - /** - * true when need to ignore symlinks, otherwise false - */ - ignoreSymlinks?: boolean; - - /** - * true when full specified, otherwise false - */ - fullySpecified?: boolean; - - /** - * package id the request was resolved to in the package map, to be propagated to resolutions made from the resulting file (`@experimental`, see the `packageMap` option) - */ - packageId?: string; - - /** - * inner request for internal usage - */ - __innerRequest?: string; - - /** - * inner request for internal usage - */ - __innerRequest_request?: string; - - /** - * inner relative path for internal usage - */ - __innerRequest_relativePath?: string; - - /** - * internal: shared marker `RestrictionsPlugin` flips when it filters out an existing target, letting `ExportsFieldPlugin` fall back instead of erroring - */ - __restrictionsMarker?: { blocked: boolean }; -} -declare interface BasenameCacheEntry { - /** - * cached dirname function - */ - fn: (maybePath: string, suffix?: string) => string; - - /** - * the underlying cache map - */ - cache: Map>; -} -type BufferEncoding = - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex"; -type BufferEncodingOption = "buffer" | { encoding: "buffer" }; -declare interface Cache { - [index: string]: undefined | ResolveRequest | ResolveRequest[]; -} -declare class CachedInputFileSystem { - constructor(fileSystem: BaseFileSystem, duration: number); - fileSystem: BaseFileSystem; - lstat?: LStat; - lstatSync?: LStatSync; - stat: Stat; - statSync: StatSync; - readdir: Readdir; - readdirSync: ReaddirSync; - readFile: ReadFile; - readFileSync: ReadFileSync; - readJson?: ( - pathOrFileDescription: PathOrFileDescriptor, - callback: ( - err: null | Error | NodeJS.ErrnoException, - result?: JsonObject, - ) => void, - ) => void; - readJsonSync?: (pathOrFileDescription: PathOrFileDescriptor) => JsonObject; - readlink: Readlink; - readlinkSync: ReadlinkSync; - realpath?: RealPath; - realpathSync?: RealPathSync; - purge( - what?: - | string - | number - | URL_url - | Buffer - | (string | number | URL_url | Buffer)[] - | Set, - options?: { exact?: boolean }, - ): void; -} -declare class CloneBasenamePlugin { - constructor( - source: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - target: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - ); - source: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - target: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - apply(resolver: Resolver): void; -} -declare interface CompiledAliasOption { - /** - * original alias name - */ - name: string; - - /** - * name + "/" — precomputed to avoid per-resolve concat - */ - nameWithSlash: string; - - /** - * alias target(s) - */ - alias: Alias; - - /** - * normalized onlyModule flag - */ - onlyModule: boolean; - - /** - * absolute form of `name` (with slash ending), null when not absolute - */ - absolutePath: null | string; - - /** - * substring before the single "*" in `name`, null when no wildcard - */ - wildcardPrefix: null | string; - - /** - * substring after the single "*" in `name`, null when no wildcard - */ - wildcardSuffix: null | string; - - /** - * first character code of `name` — used as a cheap screen on the hot path. `-1` indicates "matches any first char" (empty wildcard prefix). - */ - firstCharCode: number; - - /** - * true when `alias` is an array — precomputed so the hot path skips `Array.isArray` - */ - arrayAlias: boolean; -} -declare interface CompiledAliasOptions { - /** - * declaration-ordered list - */ - all: CompiledAliasOption[]; - - /** - * bucketed by first char code - */ - byFirstChar: Map; - - /** - * true when an empty-prefix wildcard is present - */ - hasAnyFirstChar: boolean; - - /** - * true when the bucket fast-path should be used at resolve time - */ - useBuckets: boolean; -} -type Context = KnownContext & Record; -declare interface Dirent { - /** - * true when is file, otherwise false - */ - isFile: () => boolean; - - /** - * true when is directory, otherwise false - */ - isDirectory: () => boolean; - - /** - * true when is block device, otherwise false - */ - isBlockDevice: () => boolean; - - /** - * true when is character device, otherwise false - */ - isCharacterDevice: () => boolean; - - /** - * true when is symbolic link, otherwise false - */ - isSymbolicLink: () => boolean; - - /** - * true when is FIFO, otherwise false - */ - isFIFO: () => boolean; - - /** - * true when is socket, otherwise false - */ - isSocket: () => boolean; - - /** - * name - */ - name: T; - - /** - * path - */ - parentPath: string; - - /** - * path - */ - path?: string; -} -declare interface DirnameCacheEntry { - /** - * cached dirname function - */ - fn: (maybePath: string) => string; - - /** - * the underlying cache map - */ - cache: Map; -} -type EncodingOption = - | undefined - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | ObjectEncodingOptions; -type ErrorWithDetail = Error & { details?: string }; -declare interface ExtensionAliasOption { - alias: string | string[]; - extension: string; -} -declare interface ExtensionAliasOptions { - [index: string]: string | string[]; -} -declare interface FileSystem { - /** - * read file method - */ - readFile: ReadFile; - - /** - * readdir method - */ - readdir: Readdir; - - /** - * read json method - */ - readJson?: ( - pathOrFileDescription: PathOrFileDescriptor, - callback: ( - err: null | Error | NodeJS.ErrnoException, - result?: JsonObject, - ) => void, - ) => void; - - /** - * read link method - */ - readlink: Readlink; - - /** - * lstat method - */ - lstat?: LStat; - - /** - * stat method - */ - stat: Stat; - - /** - * realpath method - */ - realpath?: RealPath; -} -type IBigIntStats = IStatsBase & { - atimeNs: bigint; - mtimeNs: bigint; - ctimeNs: bigint; - birthtimeNs: bigint; -}; -declare interface IStats { - /** - * is file - */ - isFile: () => boolean; - - /** - * is directory - */ - isDirectory: () => boolean; - - /** - * is block device - */ - isBlockDevice: () => boolean; - - /** - * is character device - */ - isCharacterDevice: () => boolean; - - /** - * is symbolic link - */ - isSymbolicLink: () => boolean; - - /** - * is FIFO - */ - isFIFO: () => boolean; - - /** - * is socket - */ - isSocket: () => boolean; - - /** - * dev - */ - dev: number; - - /** - * ino - */ - ino: number; - - /** - * mode - */ - mode: number; - - /** - * nlink - */ - nlink: number; - - /** - * uid - */ - uid: number; - - /** - * gid - */ - gid: number; - - /** - * rdev - */ - rdev: number; - - /** - * size - */ - size: number; - - /** - * blksize - */ - blksize: number; - - /** - * blocks - */ - blocks: number; - - /** - * atime ms - */ - atimeMs: number; - - /** - * mtime ms - */ - mtimeMs: number; - - /** - * ctime ms - */ - ctimeMs: number; - - /** - * birthtime ms - */ - birthtimeMs: number; - - /** - * atime - */ - atime: Date; - - /** - * mtime - */ - mtime: Date; - - /** - * ctime - */ - ctime: Date; - - /** - * birthtime - */ - birthtime: Date; -} -declare interface IStatsBase { - /** - * is file - */ - isFile: () => boolean; - - /** - * is directory - */ - isDirectory: () => boolean; - - /** - * is block device - */ - isBlockDevice: () => boolean; - - /** - * is character device - */ - isCharacterDevice: () => boolean; - - /** - * is symbolic link - */ - isSymbolicLink: () => boolean; - - /** - * is FIFO - */ - isFIFO: () => boolean; - - /** - * is socket - */ - isSocket: () => boolean; - - /** - * dev - */ - dev: T; - - /** - * ino - */ - ino: T; - - /** - * mode - */ - mode: T; - - /** - * nlink - */ - nlink: T; - - /** - * uid - */ - uid: T; - - /** - * gid - */ - gid: T; - - /** - * rdev - */ - rdev: T; - - /** - * size - */ - size: T; - - /** - * blksize - */ - blksize: T; - - /** - * blocks - */ - blocks: T; - - /** - * atime ms - */ - atimeMs: T; - - /** - * mtime ms - */ - mtimeMs: T; - - /** - * ctime ms - */ - ctimeMs: T; - - /** - * birthtime ms - */ - birthtimeMs: T; - - /** - * atime - */ - atime: Date; - - /** - * mtime - */ - mtime: Date; - - /** - * ctime - */ - ctime: Date; - - /** - * birthtime - */ - birthtime: Date; -} -declare interface Iterator { - ( - item: T, - callback: (err?: null | Error, result?: null | Z) => void, - i: number, - ): void; -} -declare interface JoinCacheEntry { - /** - * cached join function - */ - fn: (rootPath: string, request: string) => string; - - /** - * the underlying cache map - */ - cache: Map>; -} -declare interface JsonObject { - [index: string]: - undefined | null | string | number | boolean | JsonObject | JsonValue[]; -} -type JsonValue = null | string | number | boolean | JsonObject | JsonValue[]; -declare interface KnownContext { - /** - * environments - */ - environments?: string[]; - - /** - * package id of the importing file in the package map, propagated from a previous result to disambiguate package entries that share a location (`@experimental`, see the `packageMap` option) - */ - packageId?: string; -} -declare interface KnownHooks { - /** - * resolve step hook - */ - resolveStep: SyncHook< - [ - AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - ResolveRequest, - ] - >; - - /** - * no resolve hook - */ - noResolve: SyncHook<[ResolveRequest, Error]>; - - /** - * resolve hook - */ - resolve: AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - - /** - * result hook - */ - result: AsyncSeriesHook<[ResolveRequest, ResolveContext]>; -} -declare interface LStat { - ( - path: PathLike, - callback: (err: null | NodeJS.ErrnoException, result?: IStats) => void, - ): void; - ( - path: PathLike, - options: undefined | (StatOptions & { bigint?: false }), - callback: (err: null | NodeJS.ErrnoException, result?: IStats) => void, - ): void; - ( - path: PathLike, - options: StatOptions & { bigint: true }, - callback: ( - err: null | NodeJS.ErrnoException, - result?: IBigIntStats, - ) => void, - ): void; - ( - path: PathLike, - options: undefined | StatOptions, - callback: ( - err: null | NodeJS.ErrnoException, - result?: IStats | IBigIntStats, - ) => void, - ): void; -} -declare interface LStatSync { - (path: PathLike, options?: undefined): IStats; - ( - path: PathLike, - options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }, - ): undefined | IStats; - ( - path: PathLike, - options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }, - ): undefined | IBigIntStats; - (path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats; - (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; - ( - path: PathLike, - options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }, - ): IStats | IBigIntStats; - ( - path: PathLike, - options?: StatSyncOptions, - ): undefined | IStats | IBigIntStats; -} -declare class LogInfoPlugin { - constructor( - source: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - ); - source: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - apply(resolver: Resolver): void; -} -declare interface ObjectEncodingOptions { - /** - * encoding - */ - encoding?: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex"; -} -declare interface PackageMapDependencies { - [index: string]: string; -} -declare interface PackageMapOptions { - /** - * absolute path of the configuration file, read lazily when `packages` is not given - */ - configFile: null | string; - - /** - * an already-parsed `packages` object, used instead of reading `configFile` - */ - packages: null | PackageMapPackages; -} -declare interface PackageMapPackage { - /** - * an absolute or relative `file:` URL, resolved against the configuration file - */ - url: string; - - /** - * bare specifier to package id - */ - dependencies?: PackageMapDependencies; -} -declare interface PackageMapPackages { - [index: string]: PackageMapPackage; -} -declare interface ParsedIdentifier { - /** - * request - */ - request: string; - - /** - * query - */ - query: string; - - /** - * fragment - */ - fragment: string; - - /** - * is directory - */ - directory: boolean; - - /** - * is module - */ - module: boolean; - - /** - * is file - */ - file: boolean; - - /** - * is internal - */ - internal: boolean; -} -declare interface PathCacheFunctions { - /** - * cached join - */ - join: JoinCacheEntry; - - /** - * cached dirname - */ - dirname: DirnameCacheEntry; - - /** - * cached basename - */ - basename: BasenameCacheEntry; -} -type PathLike = string | URL_url | Buffer; -type PathOrFileDescriptor = string | number | URL_url | Buffer; -type Plugin = - | undefined - | null - | false - | "" - | 0 - | { apply: (this: Resolver, resolver: Resolver) => void } - | ((this: Resolver, resolver: Resolver) => void); -declare interface PnpApi { - /** - * resolve to unqualified - */ - resolveToUnqualified: ( - packageName: string, - issuer: string, - options: { considerBuiltins: boolean }, - ) => null | string; -} -declare interface ReadFile { - ( - path: PathOrFileDescriptor, - options: - undefined | null | ({ encoding?: null; flag?: string } & Abortable), - callback: (err: null | NodeJS.ErrnoException, result?: Buffer) => void, - ): void; - ( - path: PathOrFileDescriptor, - options: - | ({ encoding: BufferEncoding; flag?: string } & Abortable) - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex", - callback: (err: null | NodeJS.ErrnoException, result?: string) => void, - ): void; - ( - path: PathOrFileDescriptor, - options: - | undefined - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | (ObjectEncodingOptions & { flag?: string } & Abortable), - callback: ( - err: null | NodeJS.ErrnoException, - result?: string | Buffer, - ) => void, - ): void; - ( - path: PathOrFileDescriptor, - callback: (err: null | NodeJS.ErrnoException, result?: Buffer) => void, - ): void; -} -declare interface ReadFileSync { - ( - path: PathOrFileDescriptor, - options?: null | { encoding?: null; flag?: string }, - ): Buffer; - ( - path: PathOrFileDescriptor, - options: - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | { encoding: BufferEncoding; flag?: string }, - ): string; - ( - path: PathOrFileDescriptor, - options?: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | (ObjectEncodingOptions & { flag?: string }), - ): string | Buffer; -} -declare interface Readdir { - ( - path: PathLike, - options: - | undefined - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | { - encoding: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex"; - withFileTypes?: false; - recursive?: boolean; - }, - callback: (err: null | NodeJS.ErrnoException, files?: string[]) => void, - ): void; - ( - path: PathLike, - options: - | { encoding: "buffer"; withFileTypes?: false; recursive?: boolean } - | "buffer", - callback: (err: null | NodeJS.ErrnoException, files?: Buffer[]) => void, - ): void; - ( - path: PathLike, - options: - | undefined - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | (ObjectEncodingOptions & { - withFileTypes?: false; - recursive?: boolean; - }), - callback: ( - err: null | NodeJS.ErrnoException, - files?: string[] | Buffer[], - ) => void, - ): void; - ( - path: PathLike, - callback: (err: null | NodeJS.ErrnoException, files?: string[]) => void, - ): void; - ( - path: PathLike, - options: ObjectEncodingOptions & { - withFileTypes: true; - recursive?: boolean; - }, - callback: ( - err: null | NodeJS.ErrnoException, - files?: Dirent[], - ) => void, - ): void; - ( - path: PathLike, - options: { encoding: "buffer"; withFileTypes: true; recursive?: boolean }, - callback: ( - err: null | NodeJS.ErrnoException, - files: Dirent[], - ) => void, - ): void; -} -declare interface ReaddirSync { - ( - path: PathLike, - options?: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | { - encoding: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex"; - withFileTypes?: false; - recursive?: boolean; - }, - ): string[]; - ( - path: PathLike, - options: - | "buffer" - | { encoding: "buffer"; withFileTypes?: false; recursive?: boolean }, - ): Buffer[]; - ( - path: PathLike, - options?: - | null - | "ascii" - | "utf8" - | "utf-8" - | "utf16le" - | "utf-16le" - | "ucs2" - | "ucs-2" - | "base64" - | "base64url" - | "latin1" - | "binary" - | "hex" - | (ObjectEncodingOptions & { - withFileTypes?: false; - recursive?: boolean; - }), - ): string[] | Buffer[]; - ( - path: PathLike, - options: ObjectEncodingOptions & { - withFileTypes: true; - recursive?: boolean; - }, - ): Dirent[]; - ( - path: PathLike, - options: { encoding: "buffer"; withFileTypes: true; recursive?: boolean }, - ): Dirent[]; -} -declare interface Readlink { - ( - path: PathLike, - options: EncodingOption, - callback: (err: null | NodeJS.ErrnoException, result?: string) => void, - ): void; - ( - path: PathLike, - options: BufferEncodingOption, - callback: (err: null | NodeJS.ErrnoException, result?: Buffer) => void, - ): void; - ( - path: PathLike, - options: EncodingOption, - callback: ( - err: null | NodeJS.ErrnoException, - result?: string | Buffer, - ) => void, - ): void; - ( - path: PathLike, - callback: (err: null | NodeJS.ErrnoException, result?: string) => void, - ): void; -} -declare interface ReadlinkSync { - (path: PathLike, options?: EncodingOption): string; - (path: PathLike, options: BufferEncodingOption): Buffer; - (path: PathLike, options?: EncodingOption): string | Buffer; -} -declare interface RealPath { - ( - path: PathLike, - options: EncodingOption, - callback: (err: null | NodeJS.ErrnoException, result?: string) => void, - ): void; - ( - path: PathLike, - options: BufferEncodingOption, - callback: (err: null | NodeJS.ErrnoException, result?: Buffer) => void, - ): void; - ( - path: PathLike, - options: EncodingOption, - callback: ( - err: null | NodeJS.ErrnoException, - result?: string | Buffer, - ) => void, - ): void; - ( - path: PathLike, - callback: (err: null | NodeJS.ErrnoException, result?: string) => void, - ): void; -} -declare interface RealPathSync { - (path: PathLike, options?: EncodingOption): string; - (path: PathLike, options: BufferEncodingOption): Buffer; - (path: PathLike, options?: EncodingOption): string | Buffer; -} -declare interface ResolveContext { - /** - * directories that was found on file system - */ - contextDependencies?: WriteOnlySet; - - /** - * files that was found on file system - */ - fileDependencies?: WriteOnlySet; - - /** - * dependencies that was not found on file system - */ - missingDependencies?: WriteOnlySet; - - /** - * tip of the resolver call stack (a singly-linked list with Set-like API). For instance, `resolve → parsedResolve → describedResolve`. Accepts a legacy `Set` for back-compat with older callers; it is normalized internally without a hot-path branch. - */ - stack?: StackEntry | Set; - - /** - * log function - */ - log?: (str: string) => void; - - /** - * yield result, if provided plugins can return several results - */ - yield?: (request: ResolveRequest) => void; -} -declare interface ResolveFunction { - ( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): string | false; - ( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): string | false; -} -declare interface ResolveFunctionAsync { - ( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - ( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - ( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - ( - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; -} -declare interface ResolveFunctionPromise { - ( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): Promise; - ( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): Promise; -} -type ResolveOptionsOptionalFS = Omit< - ResolveOptionsResolverFactoryObject_2, - "fileSystem" -> & - Partial>; -declare interface ResolveOptionsResolverFactoryObject_1 { - /** - * alias - */ - alias: AliasOption[]; - - /** - * fallback - */ - fallback: AliasOption[]; - - /** - * alias fields - */ - aliasFields: Set; - - /** - * extension alias - */ - extensionAlias: ExtensionAliasOption[]; - - /** - * apply extension alias to exports field targets - */ - extensionAliasForExports: boolean; - - /** - * cache predicate - */ - cachePredicate: (predicate: ResolveRequest) => boolean; - - /** - * cache with context - */ - cacheWithContext: boolean; - - /** - * A list of exports field condition names. - */ - conditionNames: Set; - - /** - * description files - */ - descriptionFiles: string[]; - - /** - * enforce extension - */ - enforceExtension: boolean; - - /** - * exports fields - */ - exportsFields: Set; - - /** - * imports fields - */ - importsFields: Set; - - /** - * extensions - */ - extensions: Set; - - /** - * fileSystem - */ - fileSystem: FileSystem; - - /** - * unsafe cache - */ - unsafeCache: false | Cache; - - /** - * symlinks - */ - symlinks: boolean; - - /** - * resolver - */ - resolver?: Resolver; - - /** - * modules - */ - modules: (string | string[])[]; - - /** - * main fields - */ - mainFields: { name: string[]; forceRelative: boolean }[]; - - /** - * main files - */ - mainFiles: Set; - - /** - * plugins - */ - plugins: Plugin[]; - - /** - * package map - */ - packageMap: null | PackageMapOptions; - - /** - * pnp API - */ - pnpApi: null | PnpApi; - - /** - * roots - */ - roots: Set; - - /** - * fully specified - */ - fullySpecified: boolean; - - /** - * resolve to context - */ - resolveToContext: boolean; - - /** - * restrictions - */ - restrictions: Set; - - /** - * prefer relative - */ - preferRelative: boolean; - - /** - * prefer absolute - */ - preferAbsolute: boolean; - - /** - * tsconfig file path or config object - */ - tsconfig: string | boolean | TsconfigOptions; -} -declare interface ResolveOptionsResolverFactoryObject_2 { - /** - * A list of module alias configurations or an object which maps key to value - */ - alias?: UserAliasOptions | UserAliasOptionEntry[]; - - /** - * A list of module alias configurations or an object which maps key to value, applied only after modules option - */ - fallback?: UserAliasOptions | UserAliasOptionEntry[]; - - /** - * An object which maps extension to extension aliases - */ - extensionAlias?: ExtensionAliasOptions; - - /** - * Also apply `extensionAlias` to paths resolved through the package.json `exports` field. Off by default (Node.js-aligned); when enabled, matches TypeScript's behavior for packages that ship TS sources alongside compiled JS. - */ - extensionAliasForExports?: boolean; - - /** - * A list of alias fields in description files - */ - aliasFields?: (string | string[])[]; - - /** - * A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties. - */ - cachePredicate?: (predicate: ResolveRequest) => boolean; - - /** - * Whether or not the unsafeCache should include request context as part of the cache key. - */ - cacheWithContext?: boolean; - - /** - * A list of description files to read from - */ - descriptionFiles?: string[]; - - /** - * A list of exports field condition names. - */ - conditionNames?: string[]; - - /** - * Enforce that a extension from extensions must be used - */ - enforceExtension?: boolean; - - /** - * A list of exports fields in description files - */ - exportsFields?: (string | string[])[]; - - /** - * A list of imports fields in description files - */ - importsFields?: (string | string[])[]; - - /** - * A list of extensions which should be tried for files - */ - extensions?: string[]; - - /** - * The file system which should be used - */ - fileSystem: FileSystem; - - /** - * Use this cache object to unsafely cache the successful requests - */ - unsafeCache?: boolean | Cache; - - /** - * Resolve symlinks to their symlinked location - */ - symlinks?: boolean; - - /** - * A prepared Resolver to which the plugins are attached - */ - resolver?: Resolver; - - /** - * A list of directories to resolve modules from, can be absolute path, folder name, or a `file:` URL - */ - modules?: string | URL_url | (string | URL_url)[]; - - /** - * A list of main fields in description files - */ - mainFields?: ( - string | string[] | { name: string | string[]; forceRelative: boolean } - )[]; - - /** - * A list of main files in directories - */ - mainFiles?: string[]; - - /** - * A list of additional resolve plugins which should be applied - */ - plugins?: Plugin[]; - - /** - * A Node.js package map file path (or `file:` `URL` instance), or an object with the already-parsed `packages`. When set, bare specifiers resolve through the map instead of `node_modules` (`@experimental`) - */ - packageMap?: string | URL_url | UserPackageMapOptions; - - /** - * A PnP API that should be used - null is "never", undefined is "auto" - */ - pnpApi?: null | PnpApi; - - /** - * A list of root paths, each an absolute path or a `file:` URL - */ - roots?: (string | URL_url)[]; - - /** - * The request is already fully specified and no extensions or directories are resolved for it - */ - fullySpecified?: boolean; - - /** - * Resolve to a context instead of a file - */ - resolveToContext?: boolean; - - /** - * A list of resolve restrictions, each an absolute path, a `file:` URL, or a RegExp - */ - restrictions?: (string | RegExp | URL_url)[]; - - /** - * Use only the sync constraints of the file system calls - */ - useSyncFileSystemCalls?: boolean; - - /** - * Prefer to resolve module requests as relative requests before falling back to modules - */ - preferRelative?: boolean; - - /** - * Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots - */ - preferAbsolute?: boolean; - - /** - * TypeScript config file path (or `file:` URL) or config object with configFile and references - */ - tsconfig?: string | boolean | URL_url | UserTsconfigOptions; -} -type ResolveRequest = BaseResolveRequest & Partial; -declare abstract class Resolver { - fileSystem: FileSystem; - options: ResolveOptionsResolverFactoryObject_1; - pathCache: PathCacheFunctions; - hooks: KnownHooks; - ensureHook( - name: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - ): AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - getHook( - name: - | string - | AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - ): AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >; - resolveSync( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): string | false; - resolveSync( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): string | false; - resolvePromise( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): Promise; - resolvePromise( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext?: ResolveContext, - ): Promise; - resolve( - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - resolve( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - resolve( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - resolve( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, - ): void; - doResolve( - hook: AsyncSeriesBailHook< - [ResolveRequest, ResolveContext], - null | ResolveRequest - >, - request: ResolveRequest, - message: null | string, - resolveContext: ResolveContext, - callback: (err?: null | Error, result?: ResolveRequest) => void, - ): void; - parse(identifier: string): ParsedIdentifier; - isModule(path: string): boolean; - isPrivate(path: string): boolean; - isDirectory(path: string): boolean; - normalize(path: string): string; - join(path: string, request: string): string; - dirname(path: string): string; - basename(path: string, suffix?: string): string; -} - -/** - * Singly-linked stack entry that also exposes a Set-like API - * (`has`, `size`, iteration). Each `doResolve` call prepends a new - * `StackEntry` that points at the previous tip via `.parent`, so pushing - * is O(1) in time and memory. Recursion detection walks the linked list - * (O(n)) but the stack is typically shallow, so this is cheaper overall - * than cloning a `Set` per call. - */ -declare abstract class StackEntry { - name?: string; - path: string | false; - request: string; - query: string; - fragment: string; - directory: boolean; - module: boolean; - parent?: StackEntry; - - /** - * Strings seeded by callers that still pass `stack: new Set([...])`. - * Propagated through the chain so deeper `doResolve` calls still see - * them during recursion checks. `undefined` in the common case so - * there is no extra work on the hot path. - */ - preSeeded?: Set; - - /** - * Walk the linked list looking for an entry with the same request shape. - * Set-compatible: callers that used `stack.has(entry)` keep working. - * NOTE: kept monomorphic on purpose. An earlier draft accepted a string - * query too (so pre-5.21 plugins keeping their own `Set` of - * seen entries could probe the live stack with the formatted form), - * but adding the second shape regressed `doResolve`'s heap profile by - * ~1 MiB / 200 resolves on stack-churn — V8 keeps a polymorphic - * call-site state for `parent.has(stackEntry)` once `has` has two - * argument shapes. Plugins that need string membership can reach for - * `[...stack].find(e => e.includes(formattedString))` via the - * `String`-method proxies on `StackEntry` instead. - */ - has(query: StackEntry): boolean; - - /** - * Number of entries on the stack (oldest-to-newest length). - */ - get size(): number; - - /** - * Human-readable form used in recursion error messages, logs, and the - * iterator above. Not memoized: caching would require an extra slot on - * every `StackEntry`, which costs heap even on resolves that never look - * at the formatted form. - */ - toString(): string; - - /** - * Iterate entries from oldest (root) to newest (tip), matching how a - * `Set` that was populated in insertion order would iterate. Pre-seeded - * legacy `Set` entries come first so error-message output stays - * ordered oldest-to-newest. - * Yields each entry as its formatted `toString()` form. Plugins written - * against the pre-5.21 `Set` shape — e.g. - * `[...resolveContext.stack].find(a => a.includes("module:"))` — keep - * working unchanged because each yielded value is a plain string with - * all of `String.prototype` available natively. Resolves that never - * iterate the stack pay nothing; iteration costs one `toString()` - * allocation per stack frame. - */ - [Symbol.iterator](): IterableIterator; -} -declare interface Stat { - ( - path: PathLike, - callback: (err: null | NodeJS.ErrnoException, result?: IStats) => void, - ): void; - ( - path: PathLike, - options: undefined | (StatOptions & { bigint?: false }), - callback: (err: null | NodeJS.ErrnoException, result?: IStats) => void, - ): void; - ( - path: PathLike, - options: StatOptions & { bigint: true }, - callback: ( - err: null | NodeJS.ErrnoException, - result?: IBigIntStats, - ) => void, - ): void; - ( - path: PathLike, - options: undefined | StatOptions, - callback: ( - err: null | NodeJS.ErrnoException, - result?: IStats | IBigIntStats, - ) => void, - ): void; -} -declare interface StatOptions { - /** - * need bigint values - */ - bigint?: boolean; -} -declare interface StatSync { - (path: PathLike, options?: undefined): IStats; - ( - path: PathLike, - options?: StatSyncOptions & { bigint?: false; throwIfNoEntry: false }, - ): undefined | IStats; - ( - path: PathLike, - options: StatSyncOptions & { bigint: true; throwIfNoEntry: false }, - ): undefined | IBigIntStats; - (path: PathLike, options?: StatSyncOptions & { bigint?: false }): IStats; - (path: PathLike, options: StatSyncOptions & { bigint: true }): IBigIntStats; - ( - path: PathLike, - options: StatSyncOptions & { bigint: boolean; throwIfNoEntry?: false }, - ): IStats | IBigIntStats; - ( - path: PathLike, - options?: StatSyncOptions, - ): undefined | IStats | IBigIntStats; -} -declare interface StatSyncOptions { - /** - * need bigint values - */ - bigint?: boolean; - - /** - * throw if no entry - */ - throwIfNoEntry?: boolean; -} -declare interface SyncFileSystem { - /** - * read file sync method - */ - readFileSync: ReadFileSync; - - /** - * read dir sync method - */ - readdirSync: ReaddirSync; - - /** - * read json sync method - */ - readJsonSync?: (pathOrFileDescription: PathOrFileDescriptor) => JsonObject; - - /** - * read link sync method - */ - readlinkSync: ReadlinkSync; - - /** - * lstat sync method - */ - lstatSync?: LStatSync; - - /** - * stat sync method - */ - statSync: StatSync; - - /** - * real path sync method - */ - realpathSync?: RealPathSync; -} -declare interface TsconfigOptions { - /** - * A relative path to the tsconfig file based on cwd, or an absolute path of tsconfig file - */ - configFile?: string; - - /** - * References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths - */ - references?: string[] | "auto"; - - /** - * Override baseUrl from tsconfig.json. If provided, this value will be used instead of the baseUrl in the tsconfig file - */ - baseUrl?: string; -} -declare interface TsconfigPathsData { - /** - * tsconfig file data - */ - alias: CompiledAliasOptions; - - /** - * tsconfig file data - */ - modules: string[]; -} -declare interface TsconfigPathsMap { - /** - * main tsconfig paths data - */ - main: TsconfigPathsData; - - /** - * main tsconfig base URL (absolute path) - */ - mainContext: string; - - /** - * referenced tsconfig paths data mapped by baseUrl - */ - refs: { [index: string]: TsconfigPathsData }; - - /** - * all contexts (main + refs) for quick lookup - */ - allContexts: { [index: string]: TsconfigPathsData }; - - /** - * precomputed `Object.keys(allContexts)` — read-only; used on the `_selectPathsDataForContext` hot path - */ - contextList: string[]; - - /** - * file dependencies - */ - fileDependencies: Set; -} -declare class TsconfigPathsPlugin { - constructor(configFileOrOptions: string | true | TsconfigOptions); - isAutoConfigFile: boolean; - configFile: string; - references: "auto" | TsconfigReference[]; - baseUrl?: string; - apply(resolver: Resolver): void; -} -declare interface TsconfigReference { - /** - * Path to the referenced project - */ - path: string; -} -declare interface URL_url extends URL_Import {} -declare interface UserAliasOptionEntry { - alias: UserAliasOptionNewRequest; - name: string; - onlyModule?: boolean; -} -type UserAliasOptionNewRequest = - string | false | URL_url | (string | URL_url)[]; -declare interface UserAliasOptions { - [index: string]: UserAliasOptionNewRequest; -} -declare interface UserPackageMapOptions { - /** - * A path, or `file:` `URL` instance, pointing at the package map file. Required together with `packages`, whose relative `url` values are resolved against it - */ - configFile?: string | URL_url; - - /** - * An already-parsed `packages` object, used instead of reading `configFile` from disk - */ - packages?: PackageMapPackages; -} -declare interface UserTsconfigOptions { - /** - * A path, or `file:` URL, pointing at the tsconfig file - */ - configFile?: string | URL_url; - - /** - * References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths or `file:` URLs - */ - references?: (string | URL_url)[] | "auto"; - - /** - * Override baseUrl from tsconfig.json with a path or `file:` URL - */ - baseUrl?: string | URL_url; -} -declare interface WriteOnlySet { - add: (item: T) => void; -} -declare function exports( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, -): void; -declare function exports( - context: Context, - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, -): void; -declare function exports( - parent: string | URL_url, - specifier: string | URL_url, - resolveContext: ResolveContext, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, -): void; -declare function exports( - parent: string | URL_url, - specifier: string | URL_url, - callback: ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void, -): void; -declare namespace exports { - export const sync: ResolveFunction; - export const promise: ResolveFunctionPromise; - export function create( - options: ResolveOptionsOptionalFS, - ): ResolveFunctionAsync; - export namespace create { - export const sync: (options: ResolveOptionsOptionalFS) => ResolveFunction; - export const promise: ( - options: ResolveOptionsOptionalFS, - ) => ResolveFunctionPromise; - } - export namespace ResolverFactory { - export let createResolver: ( - options: ResolveOptionsResolverFactoryObject_2, - ) => Resolver; - } - export const forEachBail: ( - array: T[], - iterator: Iterator, - callback: (err?: null | Error, result?: null | Z, i?: number) => void, - ) => void; - export type ResolveCallback = ( - err: null | ErrorWithDetail, - res?: string | false, - req?: ResolveRequest, - ) => void; - export { - CachedInputFileSystem, - CloneBasenamePlugin, - LogInfoPlugin, - TsconfigPathsPlugin, - ResolveOptionsOptionalFS, - BaseFileSystem, - PnpApi, - Resolver, - Context, - FileSystem, - ResolveContext, - ResolveRequest, - SyncFileSystem, - Plugin, - ResolveOptionsResolverFactoryObject_2 as ResolveOptions, - ResolveFunctionAsync, - ResolveFunction, - ResolveFunctionPromise, - }; -} - -export = exports; +export = resolve; diff --git a/types/AliasFieldPlugin.d.ts b/types/AliasFieldPlugin.d.ts new file mode 100644 index 00000000..f6ce2047 --- /dev/null +++ b/types/AliasFieldPlugin.d.ts @@ -0,0 +1,41 @@ +export = AliasFieldPlugin; +declare class AliasFieldPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | string[]} field field + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + field: string | string[], + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + field: string | string[]; + target: string | import("./Resolver").ResolveStepHook; + /** @type {WeakMap} */ + _fieldDataCache: WeakMap< + import("./Resolver").JsonObject, + | { + [k: string]: JsonPrimitive; + } + | typeof NO_FIELD_OBJECT + >; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace AliasFieldPlugin { + export { Resolver, JsonPrimitive, ResolveRequest, ResolveStepHook }; +} +/** @typedef {import("./Resolver")} Resolver */ +/** @typedef {import("./Resolver").JsonPrimitive} JsonPrimitive */ +/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */ +/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ +declare const NO_FIELD_OBJECT: unique symbol; +type Resolver = import("./Resolver"); +type JsonPrimitive = import("./Resolver").JsonPrimitive; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/AliasPlugin.d.ts b/types/AliasPlugin.d.ts new file mode 100644 index 00000000..2aa17661 --- /dev/null +++ b/types/AliasPlugin.d.ts @@ -0,0 +1,32 @@ +export = AliasPlugin; +declare class AliasPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {AliasOption | AliasOption[]} options options + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + options: AliasOption | AliasOption[], + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + options: AliasOption[]; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace AliasPlugin { + export { Resolver, ResolveStepHook, Alias, AliasOption }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type Alias = string | string[] | false; +type AliasOption = { + alias: Alias; + name: string; + onlyModule?: boolean; +}; diff --git a/types/AliasUtils.d.ts b/types/AliasUtils.d.ts new file mode 100644 index 00000000..2bf58f31 --- /dev/null +++ b/types/AliasUtils.d.ts @@ -0,0 +1,128 @@ +export type InnerCallback = ( + err?: null | Error, + result?: null | ResolveRequest, +) => void; +export type Resolver = import("./Resolver"); +export type ResolveRequest = import("./Resolver").ResolveRequest; +export type ResolveContext = import("./Resolver").ResolveContext; +export type ResolveStepHook = import("./Resolver").ResolveStepHook; +export type ResolveCallback = import("./Resolver").ResolveCallback; +export type Alias = string | string[] | false; +export type AliasOption = { + alias: Alias; + name: string; + onlyModule?: boolean; +}; +export type CompiledAliasOption = { + /** + * original alias name + */ + name: string; + /** + * name + "/" — precomputed to avoid per-resolve concat + */ + nameWithSlash: string; + /** + * alias target(s) + */ + alias: Alias; + /** + * normalized onlyModule flag + */ + onlyModule: boolean; + /** + * absolute form of `name` (with slash ending), null when not absolute + */ + absolutePath: string | null; + /** + * substring before the single "*" in `name`, null when no wildcard + */ + wildcardPrefix: string | null; + /** + * substring after the single "*" in `name`, null when no wildcard + */ + wildcardSuffix: string | null; + /** + * first character code of `name` — used as a cheap screen on the hot path. `-1` indicates "matches any first char" (empty wildcard prefix). + */ + firstCharCode: number; + /** + * true when `alias` is an array — precomputed so the hot path skips `Array.isArray` + */ + arrayAlias: boolean; +}; +/** + * Bucketed view of compiled options used by `aliasResolveHandler` to avoid + * walking the full option list on every resolve. The `all` array preserves + * the legacy linear order (declaration order) for the fallback path. The + * `byFirstChar` map buckets options by the first char code of their `name` + * — each bucket preserves declaration order among its members. The + * `hasAnyFirstChar` flag is true when at least one option matches any + * first char (`firstCharCode === -1`), in which case resolve-time scans + * fall back to `all` to keep declaration-order semantics across buckets. + * The `useBuckets` flag is true only when bucketing would actually help — + * i.e. there are at least 2 distinct first chars AND no empty-prefix + * wildcard. When false, the resolve hot path skips the `Map.get` and + * iterates `all` directly with the per-option first-char-code screen + * (matching the pre-bucketing behavior). This avoids paying for `Map.get` + * on degenerate single-bucket lists like a long chain of aliases that + * all share one first char — the bucket lookup adds overhead without + * narrowing the candidate set, which showed up as a transient-memory + * regression on `pathological-deep-stack`. + */ +export type CompiledAliasOptions = { + /** + * declaration-ordered list + */ + all: CompiledAliasOption[]; + /** + * bucketed by first char code + */ + byFirstChar: Map; + /** + * true when an empty-prefix wildcard is present + */ + hasAnyFirstChar: boolean; + /** + * true when the bucket fast-path should be used at resolve time + */ + useBuckets: boolean; +}; +/** @typedef {(err?: null | Error, result?: null | ResolveRequest) => void} InnerCallback */ +/** + * @param {Resolver} resolver resolver + * @param {CompiledAliasOptions} options compiled options + * @param {ResolveStepHook} target target + * @param {ResolveRequest} request request + * @param {ResolveContext} resolveContext resolve context + * @param {InnerCallback} callback callback + * @returns {void} + */ +export function aliasResolveHandler( + resolver: Resolver, + options: CompiledAliasOptions, + target: ResolveStepHook, + request: ResolveRequest, + resolveContext: ResolveContext, + callback: InnerCallback, +): void; +/** + * Precompute per-option strings used on every resolve so the hot path in + * `aliasResolveHandler` does no string concatenation / split work per entry. + * Called once per plugin apply — the returned structure is stable for the + * lifetime of the resolver. + * + * Beyond the per-option precompute step, this also partitions the list into + * a `byFirstChar` map so that, when no "empty-prefix" wildcards are + * present, the resolve-time scan only walks options whose `name` starts + * with the same char as the current request. For large alias lists (300+ + * entries) this turns an O(N) screen into O(K) where K is the bucket size + * for the request's first char. + * @param {Resolver} resolver resolver + * @param {AliasOption[]} options options + * @returns {CompiledAliasOptions} compiled options + */ +export function compileAliasOptions( + resolver: Resolver, + options: AliasOption[], +): CompiledAliasOptions; diff --git a/types/AppendPlugin.d.ts b/types/AppendPlugin.d.ts new file mode 100644 index 00000000..97fcf625 --- /dev/null +++ b/types/AppendPlugin.d.ts @@ -0,0 +1,27 @@ +export = AppendPlugin; +declare class AppendPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string} appending appending + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + appending: string, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + appending: string; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace AppendPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/CachedInputFileSystem.d.ts b/types/CachedInputFileSystem.d.ts new file mode 100644 index 00000000..65f50c02 --- /dev/null +++ b/types/CachedInputFileSystem.d.ts @@ -0,0 +1,224 @@ +export = CachedInputFileSystem; +declare class CachedInputFileSystem { + /** + * @param {BaseFileSystem} fileSystem file system + * @param {number} duration duration in ms files are cached + */ + constructor(fileSystem: BaseFileSystem, duration: number); + fileSystem: BaseFileSystem; + _lstatBackend: OperationMergerBackend | CacheBackend; + lstat: import("./Resolver").LStat | undefined; + lstatSync: import("./Resolver").LStatSync | undefined; + _statBackend: OperationMergerBackend | CacheBackend; + stat: import("./Resolver").Stat; + statSync: import("./Resolver").StatSync; + _readdirBackend: OperationMergerBackend | CacheBackend; + readdir: import("./Resolver").Readdir; + readdirSync: import("./Resolver").ReaddirSync; + _readFileBackend: OperationMergerBackend | CacheBackend; + readFile: import("./Resolver").ReadFile; + readFileSync: import("./Resolver").ReadFileSync; + _readJsonBackend: OperationMergerBackend | CacheBackend; + readJson: import("./Resolver").ReadJson | undefined; + readJsonSync: import("./Resolver").ReadJsonSync | undefined; + _readlinkBackend: OperationMergerBackend | CacheBackend; + readlink: import("./Resolver").Readlink; + readlinkSync: import("./Resolver").ReadlinkSync; + _realpathBackend: OperationMergerBackend | CacheBackend; + realpath: import("./Resolver").RealPath | undefined; + realpathSync: import("./Resolver").RealPathSync | undefined; + /** + * @param {(string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set)=} what what to purge + * @param {{ exact?: boolean }=} options options; `exact: true` removes only cache entries whose key matches `what` exactly instead of any entry whose key starts with `what` + */ + purge( + what?: + | ( + | string + | Buffer + | URL + | number + | (string | URL | Buffer | number)[] + | Set + ) + | undefined, + options?: + | { + exact?: boolean; + } + | undefined, + ): void; +} +declare namespace CachedInputFileSystem { + export { + FileSystem, + PathLike, + PathOrFileDescriptor, + SyncFileSystem, + BaseFileSystem, + FileSystemCallback, + EXPECTED_FUNCTION, + EXPECTED_ANY, + Provide, + }; +} +declare class OperationMergerBackend { + /** + * @param {EXPECTED_FUNCTION | undefined} provider async method in filesystem + * @param {EXPECTED_FUNCTION | undefined} syncProvider sync method in filesystem + * @param {BaseFileSystem} providerContext call context for the provider methods + */ + constructor( + provider: EXPECTED_FUNCTION | undefined, + syncProvider: EXPECTED_FUNCTION | undefined, + providerContext: BaseFileSystem, + ); + _provider: Function | undefined; + _syncProvider: Function | undefined; + _providerContext: BaseFileSystem; + _activeAsyncOperations: Map; + provide: + | (( + path: PathLike | PathOrFileDescriptor, + options: object | FileSystemCallback | undefined, + callback?: FileSystemCallback | undefined, + ) => EXPECTED_ANY) + | null; + provideSync: + | (( + path: PathLike | PathOrFileDescriptor, + options?: object | undefined, + ) => EXPECTED_ANY) + | null; + purge(): void; + purgeParent(): void; +} +/** + * @callback Provide + * @param {PathLike | PathOrFileDescriptor} path path + * @param {EXPECTED_ANY} options options + * @param {FileSystemCallback} callback callback + * @returns {void} + */ +declare class CacheBackend { + /** + * @param {number} duration max cache duration of items + * @param {EXPECTED_FUNCTION | undefined} provider async method + * @param {EXPECTED_FUNCTION | undefined} syncProvider sync method + * @param {BaseFileSystem} providerContext call context for the provider methods + */ + constructor( + duration: number, + provider: EXPECTED_FUNCTION | undefined, + syncProvider: EXPECTED_FUNCTION | undefined, + providerContext: BaseFileSystem, + ); + _duration: number; + _provider: Function | undefined; + _syncProvider: Function | undefined; + _providerContext: BaseFileSystem; + /** @type {Map[]>} */ + _activeAsyncOperations: Map[]>; + /** @type {Map }>} */ + _data: Map< + string, + { + err: Error | null; + result?: EXPECTED_ANY; + level: Set; + } + >; + /** @type {Set[]} */ + _levels: Set[]; + _currentLevel: number; + _tickInterval: number; + /** @type {STORAGE_MODE_IDLE | STORAGE_MODE_SYNC | STORAGE_MODE_ASYNC} */ + _mode: 0 | 1 | 2; + /** @type {NodeJS.Timeout | undefined} */ + _timeout: NodeJS.Timeout | undefined; + /** @type {number | undefined} */ + _nextDecay: number | undefined; + /** + * @param {PathLike | PathOrFileDescriptor} path path + * @param {EXPECTED_ANY} options options + * @param {FileSystemCallback} callback callback + * @returns {void} + */ + provide( + path: PathLike | PathOrFileDescriptor, + options: EXPECTED_ANY, + callback: FileSystemCallback, + ): void; + /** + * @param {PathLike | PathOrFileDescriptor} path path + * @param {EXPECTED_ANY} options options + * @returns {EXPECTED_ANY} result + */ + provideSync( + path: PathLike | PathOrFileDescriptor, + options: EXPECTED_ANY, + ): EXPECTED_ANY; + /** + * @param {(string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set)=} what what to purge + * @param {{ exact?: boolean }=} options options; `exact: true` removes only entries whose key matches `what` exactly instead of any entry whose key starts with `what` + */ + purge( + what?: + | ( + | string + | Buffer + | URL + | number + | (string | URL | Buffer | number)[] + | Set + ) + | undefined, + options?: + | { + exact?: boolean; + } + | undefined, + ): void; + /** + * @param {(string | Buffer | URL | number | (string | URL | Buffer | number)[] | Set)=} what what to purge + */ + purgeParent( + what?: + | ( + | string + | Buffer + | URL + | number + | (string | URL | Buffer | number)[] + | Set + ) + | undefined, + ): void; + /** + * @param {string} path path + * @param {Error | null} err error + * @param {EXPECTED_ANY} result result + */ + _storeResult(path: string, err: Error | null, result: EXPECTED_ANY): void; + _decayLevel(): void; + _runDecays(): void; + _enterAsyncMode(): void; + _enterSyncModeWhenIdle(): void; + _enterIdleMode(): void; +} +type FileSystem = import("./Resolver").FileSystem; +type PathLike = import("./Resolver").PathLike; +type PathOrFileDescriptor = import("./Resolver").PathOrFileDescriptor; +type SyncFileSystem = import("./Resolver").SyncFileSystem; +type BaseFileSystem = FileSystem & SyncFileSystem; +/** + * + */ +type FileSystemCallback = import("./Resolver").FileSystemCallback; +type EXPECTED_FUNCTION = Function; +type EXPECTED_ANY = any; +type Provide = ( + path: PathLike | PathOrFileDescriptor, + options: EXPECTED_ANY, + callback: FileSystemCallback, +) => void; diff --git a/types/CloneBasenamePlugin.d.ts b/types/CloneBasenamePlugin.d.ts new file mode 100644 index 00000000..a0b852d9 --- /dev/null +++ b/types/CloneBasenamePlugin.d.ts @@ -0,0 +1,24 @@ +export = CloneBasenamePlugin; +declare class CloneBasenamePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace CloneBasenamePlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/ConditionalPlugin.d.ts b/types/ConditionalPlugin.d.ts new file mode 100644 index 00000000..a3c70e10 --- /dev/null +++ b/types/ConditionalPlugin.d.ts @@ -0,0 +1,33 @@ +export = ConditionalPlugin; +declare class ConditionalPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Partial} test compare object + * @param {string | null} message log message + * @param {boolean} allowAlternatives when false, do not continue with the current step when "test" matches + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + test: Partial, + message: string | null, + allowAlternatives: boolean, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + test: Partial; + message: string | null; + allowAlternatives: boolean; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ConditionalPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/DescriptionFilePlugin.d.ts b/types/DescriptionFilePlugin.d.ts new file mode 100644 index 00000000..c063cd7e --- /dev/null +++ b/types/DescriptionFilePlugin.d.ts @@ -0,0 +1,30 @@ +export = DescriptionFilePlugin; +declare class DescriptionFilePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string[]} filenames filenames + * @param {boolean} pathIsFile pathIsFile + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + filenames: string[], + pathIsFile: boolean, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + filenames: string[]; + pathIsFile: boolean; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace DescriptionFilePlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/DescriptionFileUtils.d.ts b/types/DescriptionFileUtils.d.ts new file mode 100644 index 00000000..29385645 --- /dev/null +++ b/types/DescriptionFileUtils.d.ts @@ -0,0 +1,83 @@ +export type Resolver = import("./Resolver"); +export type JsonObject = import("./Resolver").JsonObject; +export type JsonValue = import("./Resolver").JsonValue; +export type ResolveContext = import("./Resolver").ResolveContext; +export type ResolveRequest = import("./Resolver").ResolveRequest; +export type DescriptionFileInfo = { + /** + * content + */ + content?: JsonObject | undefined; + /** + * path + */ + path: string; + /** + * directory + */ + directory: string; +}; +export type ErrorFirstCallback = ( + error?: (Error | null) | undefined, + result?: DescriptionFileInfo | undefined, +) => any; +export type Result = { + /** + * path to description file + */ + path: string; + /** + * directory of description file + */ + directory: string; + /** + * content of description file + */ + content: JsonObject; +}; +/** + * Walk up one directory. Called once per package-root candidate and once per + * `described-resolve` (to find the enclosing description file), so it's on + * the resolver's hot path. + * + * Previous implementation called `lastIndexOf("/")` and `lastIndexOf("\\")` + * separately and then picked the larger. For any non-trivial directory + * string on POSIX, `lastIndexOf("\\")` scans the full string just to return + * -1. A single reverse char-code scan does the same work in one pass. + * + * Any single-character directory is treated as a root — `directory.length + * <= 1` collapses the `"/"`, `"\\"` and `""` branches into one compare. + * Without the `"\\"` case, `cdUp("\\")` (reached from a UNC root or a DOS + * device path like `\\?\…`) would return itself via `slice(0, i || 1)` + * and trap `loadDescriptionFile` in an infinite loop. Once single-char + * roots are filtered up front, the reverse scan always produces a + * strictly shorter string. + * @param {string} directory directory + * @returns {string | null} parent directory or null + */ +export function cdUp(directory: string): string | null; +/** + * @param {JsonObject} content content + * @param {string | string[]} field field + * @returns {JsonValue | undefined} field data + */ +export function getField( + content: JsonObject, + field: string | string[], +): JsonValue | undefined; +/** + * @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 + */ +export function loadDescriptionFile( + resolver: Resolver, + directory: string, + filenames: string[], + oldInfo: DescriptionFileInfo | undefined, + resolveContext: ResolveContext, + callback: ErrorFirstCallback, +): void; diff --git a/types/DirectoryExistsPlugin.d.ts b/types/DirectoryExistsPlugin.d.ts new file mode 100644 index 00000000..025b53ef --- /dev/null +++ b/types/DirectoryExistsPlugin.d.ts @@ -0,0 +1,23 @@ +export = DirectoryExistsPlugin; +declare class DirectoryExistsPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace DirectoryExistsPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/ExportsFieldPlugin.d.ts b/types/ExportsFieldPlugin.d.ts new file mode 100644 index 00000000..84b5375d --- /dev/null +++ b/types/ExportsFieldPlugin.d.ts @@ -0,0 +1,45 @@ +export = ExportsFieldPlugin; +declare class ExportsFieldPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Set} conditionNames condition names + * @param {string | string[]} fieldNamePath name path + * @param {string | ResolveStepHook} target target + * @param {boolean=} restrictions whether `restrictions` are configured (enables exports-target fallback when a target is filtered out) + */ + constructor( + source: string | ResolveStepHook, + conditionNames: Set, + fieldNamePath: string | string[], + target: string | ResolveStepHook, + restrictions?: boolean | undefined, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + conditionNames: Set; + fieldName: string | string[]; + restrictions: boolean; + /** @type {WeakMap} */ + _fieldProcessorCache: WeakMap; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ExportsFieldPlugin { + export { + Resolver, + JsonObject, + ResolveRequest, + ResolveStepHook, + ExportsField, + FieldProcessor, + }; +} +type Resolver = import("./Resolver"); +type JsonObject = import("./Resolver").JsonObject; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type ExportsField = import("./util/entrypoints").ExportsField; +type FieldProcessor = import("./util/entrypoints").FieldProcessor; diff --git a/types/ExtensionAliasPlugin.d.ts b/types/ExtensionAliasPlugin.d.ts new file mode 100644 index 00000000..39b35495 --- /dev/null +++ b/types/ExtensionAliasPlugin.d.ts @@ -0,0 +1,31 @@ +export = ExtensionAliasPlugin; +declare class ExtensionAliasPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {ExtensionAliasOption} options options + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + options: ExtensionAliasOption, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + options: ExtensionAliasOption; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ExtensionAliasPlugin { + export { Resolver, ResolveRequest, ResolveStepHook, ExtensionAliasOption }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type ExtensionAliasOption = { + alias: string | string[]; + extension: string; +}; diff --git a/types/FileExistsPlugin.d.ts b/types/FileExistsPlugin.d.ts new file mode 100644 index 00000000..d4f7aeea --- /dev/null +++ b/types/FileExistsPlugin.d.ts @@ -0,0 +1,23 @@ +export = FileExistsPlugin; +declare class FileExistsPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace FileExistsPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/ImportsFieldPlugin.d.ts b/types/ImportsFieldPlugin.d.ts new file mode 100644 index 00000000..197d04b2 --- /dev/null +++ b/types/ImportsFieldPlugin.d.ts @@ -0,0 +1,45 @@ +export = ImportsFieldPlugin; +declare class ImportsFieldPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Set} conditionNames condition names + * @param {string | string[]} fieldNamePath name path + * @param {string | ResolveStepHook} targetFile target file + * @param {string | ResolveStepHook} targetPackage target package + */ + constructor( + source: string | ResolveStepHook, + conditionNames: Set, + fieldNamePath: string | string[], + targetFile: string | ResolveStepHook, + targetPackage: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + targetFile: string | import("./Resolver").ResolveStepHook; + targetPackage: string | import("./Resolver").ResolveStepHook; + conditionNames: Set; + fieldName: string | string[]; + /** @type {WeakMap} */ + _fieldProcessorCache: WeakMap; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ImportsFieldPlugin { + export { + Resolver, + JsonObject, + ResolveRequest, + ResolveStepHook, + FieldProcessor, + ImportsField, + }; +} +type Resolver = import("./Resolver"); +type JsonObject = import("./Resolver").JsonObject; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type FieldProcessor = import("./util/entrypoints").FieldProcessor; +type ImportsField = import("./util/entrypoints").ImportsField; diff --git a/types/JoinRequestPartPlugin.d.ts b/types/JoinRequestPartPlugin.d.ts new file mode 100644 index 00000000..27834033 --- /dev/null +++ b/types/JoinRequestPartPlugin.d.ts @@ -0,0 +1,24 @@ +export = JoinRequestPartPlugin; +declare class JoinRequestPartPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace JoinRequestPartPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/JoinRequestPlugin.d.ts b/types/JoinRequestPlugin.d.ts new file mode 100644 index 00000000..b9fe5269 --- /dev/null +++ b/types/JoinRequestPlugin.d.ts @@ -0,0 +1,24 @@ +export = JoinRequestPlugin; +declare class JoinRequestPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace JoinRequestPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/LogInfoPlugin.d.ts b/types/LogInfoPlugin.d.ts new file mode 100644 index 00000000..9fe3d72a --- /dev/null +++ b/types/LogInfoPlugin.d.ts @@ -0,0 +1,18 @@ +export = LogInfoPlugin; +declare class LogInfoPlugin { + /** + * @param {string | ResolveStepHook} source source + */ + constructor(source: string | ResolveStepHook); + source: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace LogInfoPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/MainFieldPlugin.d.ts b/types/MainFieldPlugin.d.ts new file mode 100644 index 00000000..1b311263 --- /dev/null +++ b/types/MainFieldPlugin.d.ts @@ -0,0 +1,41 @@ +export = MainFieldPlugin; +declare class MainFieldPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {MainFieldOptions} options options + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + options: MainFieldOptions, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + options: MainFieldOptions; + target: string | import("./Resolver").ResolveStepHook; + /** @type {WeakMap} */ + _mainModuleCache: WeakMap; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace MainFieldPlugin { + export { + Resolver, + JsonObject, + ResolveRequest, + ResolveStepHook, + MainFieldOptions, + }; +} +declare const NO_MAIN: unique symbol; +type Resolver = import("./Resolver"); +type JsonObject = import("./Resolver").JsonObject; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type MainFieldOptions = { + name: string | string[]; + forceRelative: boolean; +}; diff --git a/types/ModulesInHierachicDirectoriesPlugin.d.ts b/types/ModulesInHierachicDirectoriesPlugin.d.ts new file mode 100644 index 00000000..2c309498 --- /dev/null +++ b/types/ModulesInHierachicDirectoriesPlugin.d.ts @@ -0,0 +1,2 @@ +declare const _exports: typeof import("./ModulesInHierarchicalDirectoriesPlugin"); +export = _exports; diff --git a/types/ModulesInHierarchicalDirectoriesPlugin.d.ts b/types/ModulesInHierarchicalDirectoriesPlugin.d.ts new file mode 100644 index 00000000..af501cee --- /dev/null +++ b/types/ModulesInHierarchicalDirectoriesPlugin.d.ts @@ -0,0 +1,26 @@ +export = ModulesInHierarchicalDirectoriesPlugin; +declare class ModulesInHierarchicalDirectoriesPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | string[]} directories directories + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + directories: string | string[], + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + directories: string[]; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ModulesInHierarchicalDirectoriesPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/ModulesInRootPlugin.d.ts b/types/ModulesInRootPlugin.d.ts new file mode 100644 index 00000000..87a61fd3 --- /dev/null +++ b/types/ModulesInRootPlugin.d.ts @@ -0,0 +1,27 @@ +export = ModulesInRootPlugin; +declare class ModulesInRootPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string} path path + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + path: string, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + path: string; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ModulesInRootPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/ModulesUtils.d.ts b/types/ModulesUtils.d.ts new file mode 100644 index 00000000..9a55bf73 --- /dev/null +++ b/types/ModulesUtils.d.ts @@ -0,0 +1,25 @@ +export type Resolver = import("./Resolver"); +export type ResolveRequest = import("./Resolver").ResolveRequest; +export type ResolveStepHook = import("./Resolver").ResolveStepHook; +export type ResolveContext = import("./Resolver").ResolveContext; +export type InnerCallback = ( + err?: null | Error, + result?: null | ResolveRequest, +) => void; +/** + * @param {Resolver} resolver resolver + * @param {string[]} directories directories + * @param {ResolveStepHook} target target + * @param {ResolveRequest} request request + * @param {ResolveContext} resolveContext resolve context + * @param {InnerCallback} callback callback + * @returns {void} + */ +export function modulesResolveHandler( + resolver: Resolver, + directories: string[], + target: ResolveStepHook, + request: ResolveRequest, + resolveContext: ResolveContext, + callback: InnerCallback, +): void; diff --git a/types/NextPlugin.d.ts b/types/NextPlugin.d.ts new file mode 100644 index 00000000..6a93aacc --- /dev/null +++ b/types/NextPlugin.d.ts @@ -0,0 +1,23 @@ +export = NextPlugin; +declare class NextPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace NextPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/PackageMapPlugin.d.ts b/types/PackageMapPlugin.d.ts new file mode 100644 index 00000000..76a3777d --- /dev/null +++ b/types/PackageMapPlugin.d.ts @@ -0,0 +1,85 @@ +export = PackageMapPlugin; +declare class PackageMapPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {PackageMapOptions} options package map options + * @param {boolean} symlinks whether the resolver resolves symlinks + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + options: PackageMapOptions, + symlinks: boolean, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + options: PackageMapOptions; + symlinks: boolean; + target: string | import("./Resolver").ResolveStepHook; + /** @type {PackageMap | undefined} */ + _packageMap: PackageMap | undefined; + /** @type {PackageMapCallback[] | undefined} */ + _pending: PackageMapCallback[] | undefined; + /** + * Read and parse the configuration file once, queueing every request that + * arrives while the read is in flight so a cold start does not re-read the + * same file for each of them. + * @param {Resolver} resolver the resolver + * @param {ResolveContext} resolveContext resolve context + * @param {PackageMapCallback} callback callback + * @returns {void} + */ + _getPackageMap( + resolver: Resolver, + resolveContext: ResolveContext, + callback: PackageMapCallback, + ): void; + /** + * Hand back the configuration file path package locations resolve against: + * its real path when the resolver follows symlinks, and the path as given + * otherwise. A configuration file whose real path cannot be read (it may not + * exist, or the file system may not implement it) is used as-is, so the + * read below reports the problem. + * @param {Resolver} resolver the resolver + * @param {(configFile: string) => void} callback callback + * @returns {void} + */ + _resolveConfigFile( + resolver: Resolver, + callback: (configFile: string) => void, + ): void; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace PackageMapPlugin { + export { + Resolver, + ResolveContext, + ResolveRequest, + ResolveStepHook, + PackageMap, + PackageMapPackages, + PackageMapOptions, + PackageMapCallback, + }; +} +type Resolver = import("./Resolver"); +type ResolveContext = import("./Resolver").ResolveContext; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type PackageMap = import("./util/packageMap").PackageMap; +type PackageMapPackages = import("./util/packageMap").PackageMapPackages; +type PackageMapOptions = { + /** + * absolute path of the configuration file, read lazily when `packages` is not given + */ + configFile: string; + /** + * an already-parsed `packages` object, used instead of reading `configFile` + */ + packages: PackageMapPackages | null; +}; +type PackageMapCallback = (err: Error | null, packageMap?: PackageMap) => void; diff --git a/types/ParsePlugin.d.ts b/types/ParsePlugin.d.ts new file mode 100644 index 00000000..39975049 --- /dev/null +++ b/types/ParsePlugin.d.ts @@ -0,0 +1,27 @@ +export = ParsePlugin; +declare class ParsePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Partial} requestOptions request options + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + requestOptions: Partial, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + requestOptions: Partial; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ParsePlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/PnpPlugin.d.ts b/types/PnpPlugin.d.ts new file mode 100644 index 00000000..18e1109c --- /dev/null +++ b/types/PnpPlugin.d.ts @@ -0,0 +1,42 @@ +export = PnpPlugin; +declare class PnpPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {PnpApiImpl} pnpApi pnpApi + * @param {string | ResolveStepHook} target target + * @param {string | ResolveStepHook} alternateTarget alternateTarget + */ + constructor( + source: string | ResolveStepHook, + pnpApi: PnpApiImpl, + target: string | ResolveStepHook, + alternateTarget: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + pnpApi: PnpApiImpl; + target: string | import("./Resolver").ResolveStepHook; + alternateTarget: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace PnpPlugin { + export { Resolver, ResolveStepHook, ResolveRequest, PnpApiImpl }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type ResolveRequest = import("./Resolver").ResolveRequest; +type PnpApiImpl = { + /** + * resolve to unqualified + */ + resolveToUnqualified: ( + packageName: string, + issuer: string, + options: { + considerBuiltins: boolean; + }, + ) => string | null; +}; diff --git a/types/Resolver.d.ts b/types/Resolver.d.ts new file mode 100644 index 00000000..6b88cd8c --- /dev/null +++ b/types/Resolver.d.ts @@ -0,0 +1,1545 @@ +export = Resolver; +declare class Resolver { + /** + * @param {ResolveStepHook} hook hook + * @param {ResolveRequest} request request + * @param {StackEntry=} parent previous tip of the stack + * @param {Set=} preSeeded entries pre-seeded via the legacy `Set` API + * @returns {StackEntry} stack entry + */ + static createStackEntry( + hook: ResolveStepHook, + request: ResolveRequest, + parent?: StackEntry | undefined, + preSeeded?: Set | undefined, + ): StackEntry; + /** + * @param {FileSystem} fileSystem a filesystem + * @param {ResolveOptions} options options + */ + constructor(fileSystem: FileSystem, options: ResolveOptions); + /** @type {FileSystem} */ + fileSystem: FileSystem; + /** @type {ResolveOptions} */ + options: ResolveOptions; + /** @type {PathCacheFunctions} */ + pathCache: PathCacheFunctions; + /** @type {KnownHooks} */ + hooks: KnownHooks; + /** + * @param {string | ResolveStepHook} name hook name or hook itself + * @returns {ResolveStepHook} the hook + */ + ensureHook(name: string | ResolveStepHook): ResolveStepHook; + /** + * @param {string | ResolveStepHook} name hook name or hook itself + * @returns {ResolveStepHook} the hook + */ + getHook(name: string | ResolveStepHook): ResolveStepHook; + /** + * @overload + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext=} resolveContext resolve context + * @returns {string | false} result + */ + resolveSync( + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext | undefined, + ): string | false; + /** + * @overload + * @param {Context} context context information object + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext=} resolveContext resolve context + * @returns {string | false} result + */ + resolveSync( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext | undefined, + ): string | false; + /** + * @overload + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext=} resolveContext resolve context + * @returns {Promise} result + */ + resolvePromise( + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext | undefined, + ): Promise; + /** + * @overload + * @param {Context} context context information object + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext=} resolveContext resolve context + * @returns {Promise} result + */ + resolvePromise( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext | undefined, + ): Promise; + /** + * @overload + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveCallback} callback callback function + * @returns {void} + */ + resolve( + parent: string | URL, + specifier: string | URL, + callback: ResolveCallback, + ): void; + /** + * @overload + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext} resolveContext resolve context + * @param {ResolveCallback} callback callback function + * @returns {void} + */ + resolve( + parent: string | URL, + specifier: string | URL, + resolveContext: ResolveContext, + callback: ResolveCallback, + ): void; + /** + * @overload + * @param {Context} context context information object + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveCallback} callback callback function + * @returns {void} + */ + resolve( + context: Context, + parent: string | URL, + specifier: string | URL, + callback: ResolveCallback, + ): void; + /** + * @overload + * @param {Context} context context information object + * @param {string | URL} parent context path or a `file:` URL + * @param {string | URL} specifier request string or a `file:` URL + * @param {ResolveContext} resolveContext resolve context + * @param {ResolveCallback} callback callback function + * @returns {void} + */ + resolve( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext: ResolveContext, + callback: ResolveCallback, + ): void; + /** + * @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: ResolveStepHook, + request: ResolveRequest, + message: null | string, + resolveContext: ResolveContext, + callback: (err?: null | Error, result?: ResolveRequest) => void, + ): void; + /** + * @param {string} identifier identifier + * @returns {ParsedIdentifier} parsed identifier + */ + parse(identifier: string): ParsedIdentifier; + /** + * @param {string} path path + * @returns {boolean} true, if the path is a module + */ + isModule(path: string): boolean; + /** + * @param {string} path path + * @returns {boolean} true, if the path is private + */ + isPrivate(path: string): boolean; + /** + * @param {string} path a path + * @returns {boolean} true, if the path is a directory path + */ + isDirectory(path: string): boolean; + /** + * @param {string} path path + * @returns {string} normalized path + */ + normalize(path: string): string; + /** + * @param {string} path path + * @param {string} request request + * @returns {string} joined path + */ + join(path: string, request: string): string; + /** + * @param {string} path path + * @returns {string} parent directory + */ + dirname(path: string): string; + /** + * @param {string} path the path to evaluate + * @param {string=} suffix an extension to remove from the result + * @returns {string} the last portion of a path + */ + basename(path: string, suffix?: string | undefined): string; +} +declare namespace Resolver { + export { + ResolveContext, + ResolveStepHook, + KnownHooks, + EnsuredHooks, + AliasOption, + CachedJoin, + CachedDirname, + CachedBasename, + JoinCacheEntry, + DirnameCacheEntry, + BasenameCacheEntry, + PathCacheFunctions, + ResolveOptions, + KnownContext, + Context, + ErrorWithDetail, + ResolveCallback, + PossibleFileSystemError, + FileSystemCallback, + PathLike, + PathOrFileDescriptor, + ObjectEncodingOptions, + EncodingOption, + StringCallback, + BufferCallback, + StringOrBufferCallback, + StatsCallback, + BigIntStatsCallback, + StatsOrBigIntStatsCallback, + ReadJsonCallback, + IStatsBase, + IStats, + IBigIntStats, + Dirent, + StatOptions, + StatSyncOptions, + ReadFile, + BufferEncodingOption, + ReadFileSync, + Readdir, + ReaddirSync, + ReadJson, + ReadJsonSync, + Readlink, + ReadlinkSync, + LStat, + LStatSync, + Stat, + StatSync, + RealPath, + RealPathSync, + FileSystem, + SyncFileSystem, + ParsedIdentifier, + JsonPrimitive, + JsonArray, + JsonValue, + JsonObject, + TsconfigPathsMap, + TsconfigPathsData, + BaseResolveRequest, + ResolveRequest, + WriteOnlySet, + ResolveContextYield, + }; +} +/** @typedef {import("./ResolverFactory").ResolveOptions} ResolveOptions */ +/** + * @typedef {object} KnownContext + * @property {string[]=} environments environments + * @property {string=} packageId package id of the importing file in the package map, propagated from a previous result to disambiguate package entries that share a location (`@experimental`, see the `packageMap` option) + */ +/** @typedef {KnownContext & Record} Context */ +/** @typedef {Error & { details?: string }} ErrorWithDetail */ +/** @typedef {(err: ErrorWithDetail | null, res?: string | false, req?: ResolveRequest) => void} ResolveCallback */ +/** + * @typedef {object} PossibleFileSystemError + * @property {string=} code code + * @property {number=} errno number + * @property {string=} path path + * @property {string=} syscall 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 encoding + */ +/** + * @typedef {ObjectEncodingOptions | BufferEncoding | undefined | null} EncodingOption + */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: string) => void} StringCallback */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: Buffer) => void} BufferCallback */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: (string | Buffer)) => void} StringOrBufferCallback */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: IStats) => void} StatsCallback */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: IBigIntStats) => void} BigIntStatsCallback */ +/** @typedef {(err: NodeJS.ErrnoException | null, result?: (IStats | IBigIntStats)) => void} StatsOrBigIntStatsCallback */ +/** @typedef {(err: NodeJS.ErrnoException | Error | null, result?: JsonObject) => void} ReadJsonCallback */ +/** + * @template T + * @typedef {object} IStatsBase + * @property {() => boolean} isFile is file + * @property {() => boolean} isDirectory is directory + * @property {() => boolean} isBlockDevice is block device + * @property {() => boolean} isCharacterDevice is character device + * @property {() => boolean} isSymbolicLink is symbolic link + * @property {() => boolean} isFIFO is FIFO + * @property {() => boolean} isSocket is socket + * @property {T} dev dev + * @property {T} ino ino + * @property {T} mode mode + * @property {T} nlink nlink + * @property {T} uid uid + * @property {T} gid gid + * @property {T} rdev rdev + * @property {T} size size + * @property {T} blksize blksize + * @property {T} blocks blocks + * @property {T} atimeMs atime ms + * @property {T} mtimeMs mtime ms + * @property {T} ctimeMs ctime ms + * @property {T} birthtimeMs birthtime ms + * @property {Date} atime atime + * @property {Date} mtime mtime + * @property {Date} ctime ctime + * @property {Date} birthtime birthtime + */ +/** + * @typedef {IStatsBase} IStats + */ +/** + * @typedef {IStatsBase & { atimeNs: bigint, mtimeNs: bigint, ctimeNs: bigint, birthtimeNs: bigint }} IBigIntStats + */ +/** + * @template {string | Buffer} [T=string] + * @typedef {object} Dirent + * @property {() => boolean} isFile true when is file, otherwise false + * @property {() => boolean} isDirectory true when is directory, otherwise false + * @property {() => boolean} isBlockDevice true when is block device, otherwise false + * @property {() => boolean} isCharacterDevice true when is character device, otherwise false + * @property {() => boolean} isSymbolicLink true when is symbolic link, otherwise false + * @property {() => boolean} isFIFO true when is FIFO, otherwise false + * @property {() => boolean} isSocket true when is socket, otherwise false + * @property {T} name name + * @property {string} parentPath path + * @property {string=} path path + */ +/** + * @typedef {object} StatOptions + * @property {(boolean | undefined)=} bigint need bigint values + */ +/** + * @typedef {object} StatSyncOptions + * @property {(boolean | undefined)=} bigint need bigint values + * @property {(boolean | undefined)=} throwIfNoEntry throw if no entry + */ +/** + * @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 {"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: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void, + * (path: PathLike, options: { encoding: "buffer", withFileTypes?: false | undefined, recursive?: boolean | undefined } | "buffer", callback: (err: NodeJS.ErrnoException | null, files?: Buffer[]) => void): void, + * (path: PathLike, options: (ObjectEncodingOptions & { withFileTypes?: false | undefined, recursive?: boolean | undefined }) | BufferEncoding | undefined | null, callback: (err: NodeJS.ErrnoException | null, files?: string[] | Buffer[]) => void): void, + * (path: PathLike, callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void): void, + * (path: PathLike, options: ObjectEncodingOptions & { withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files?: Dirent[]) => void): void, + * (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }, callback: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void): 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[], + * (path: PathLike, options: { encoding: "buffer", withFileTypes: true, recursive?: boolean | undefined }): Dirent[], + * }} ReaddirSync + */ +/** + * @typedef {(pathOrFileDescription: PathOrFileDescriptor, callback: ReadJsonCallback) => void} ReadJson + */ +/** + * @typedef {(pathOrFileDescription: 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 read file method + * @property {Readdir} readdir readdir method + * @property {ReadJson=} readJson read json method + * @property {Readlink} readlink read link method + * @property {LStat=} lstat lstat method + * @property {Stat} stat stat method + * @property {RealPath=} realpath realpath method + */ +/** + * @typedef {object} SyncFileSystem + * @property {ReadFileSync} readFileSync read file sync method + * @property {ReaddirSync} readdirSync read dir sync method + * @property {ReadJsonSync=} readJsonSync read json sync method + * @property {ReadlinkSync} readlinkSync read link sync method + * @property {LStatSync=} lstatSync lstat sync method + * @property {StatSync} statSync stat sync method + * @property {RealPathSync=} realpathSync real path sync method + */ +/** + * @typedef {object} ParsedIdentifier + * @property {string} request request + * @property {string} query query + * @property {string} fragment fragment + * @property {boolean} directory is directory + * @property {boolean} module is module + * @property {boolean} file is file + * @property {boolean} internal is internal + */ +/** @typedef {string | number | boolean | null} JsonPrimitive */ +/** @typedef {JsonValue[]} JsonArray */ +/** @typedef {JsonPrimitive | JsonObject | JsonArray} JsonValue */ +/** @typedef {{ [Key in string]?: JsonValue | undefined }} JsonObject */ +/** + * @typedef {object} TsconfigPathsMap + * @property {TsconfigPathsData} main main tsconfig paths data + * @property {string} mainContext main tsconfig base URL (absolute path) + * @property {{ [baseUrl: string]: TsconfigPathsData }} refs referenced tsconfig paths data mapped by baseUrl + * @property {{ [context: string]: TsconfigPathsData }} allContexts all contexts (main + refs) for quick lookup + * @property {string[]} contextList precomputed `Object.keys(allContexts)` — read-only; used on the `_selectPathsDataForContext` hot path + * @property {Set} fileDependencies file dependencies + */ +/** + * @typedef {object} TsconfigPathsData + * @property {import("./AliasUtils").CompiledAliasOptions} alias tsconfig file data + * @property {string[]} modules tsconfig file data + */ +/** + * @typedef {object} BaseResolveRequest + * @property {string | false} path path + * @property {Context=} context content + * @property {string=} descriptionFilePath description file path + * @property {string=} descriptionFileRoot description file root + * @property {JsonObject=} descriptionFileData description file data + * @property {TsconfigPathsMap | null | undefined=} tsconfigPathsMap tsconfig paths map + * @property {string=} relativePath relative path + * @property {boolean=} ignoreSymlinks true when need to ignore symlinks, otherwise false + * @property {boolean=} fullySpecified true when full specified, otherwise false + * @property {string=} packageId package id the request was resolved to in the package map, to be propagated to resolutions made from the resulting file (`@experimental`, see the `packageMap` option) + * @property {string=} __innerRequest inner request for internal usage + * @property {string=} __innerRequest_request inner request for internal usage + * @property {string=} __innerRequest_relativePath inner relative path for internal usage + * @property {{ blocked: boolean }=} __restrictionsMarker internal: shared marker `RestrictionsPlugin` flips when it filters out an existing target, letting `ExportsFieldPlugin` fall back instead of erroring + */ +/** @typedef {BaseResolveRequest & Partial} ResolveRequest */ +/** + * @template T + * @typedef {{ add: (item: T) => void }} WriteOnlySet + */ +/** @typedef {(request: ResolveRequest) => void} ResolveContextYield */ +/** + * Singly-linked stack entry that also exposes a Set-like API + * (`has`, `size`, iteration). Each `doResolve` call prepends a new + * `StackEntry` that points at the previous tip via `.parent`, so pushing + * is O(1) in time and memory. Recursion detection walks the linked list + * (O(n)) but the stack is typically shallow, so this is cheaper overall + * than cloning a `Set` per call. + */ +declare class StackEntry { + /** + * @param {ResolveStepHook} hook hook + * @param {ResolveRequest} request request + * @param {StackEntry=} parent previous tip + * @param {Set=} preSeeded entries pre-seeded via the legacy `Set` API + */ + constructor( + hook: ResolveStepHook, + request: ResolveRequest, + parent?: StackEntry | undefined, + preSeeded?: Set | undefined, + ); + name: string | undefined; + path: string | false; + request: string; + query: string; + fragment: string; + directory: boolean; + module: boolean; + /** @type {StackEntry | undefined} */ + parent: StackEntry | undefined; + /** + * Strings seeded by callers that still pass `stack: new Set([...])`. + * Propagated through the chain so deeper `doResolve` calls still see + * them during recursion checks. `undefined` in the common case so + * there is no extra work on the hot path. + * @type {Set | undefined} + */ + preSeeded: Set | undefined; + /** + * Walk the linked list looking for an entry with the same request shape. + * Set-compatible: callers that used `stack.has(entry)` keep working. + * + * NOTE: kept monomorphic on purpose. An earlier draft accepted a string + * query too (so pre-5.21 plugins keeping their own `Set` of + * seen entries could probe the live stack with the formatted form), + * but adding the second shape regressed `doResolve`'s heap profile by + * ~1 MiB / 200 resolves on stack-churn — V8 keeps a polymorphic + * call-site state for `parent.has(stackEntry)` once `has` has two + * argument shapes. Plugins that need string membership can reach for + * `[...stack].find(e => e.includes(formattedString))` via the + * `String`-method proxies on `StackEntry` instead. + * @param {StackEntry} query entry to look for + * @returns {boolean} whether the stack already contains an equivalent entry + */ + has(query: StackEntry): boolean; + /** + * Number of entries on the stack (oldest-to-newest length). + * @returns {number} size + */ + get size(): number; + /** + * Human-readable form used in recursion error messages, logs, and the + * iterator above. Not memoized: caching would require an extra slot on + * every `StackEntry`, which costs heap even on resolves that never look + * at the formatted form. + * @returns {string} formatted entry + */ + toString(): string; + /** + * Iterate entries from oldest (root) to newest (tip), matching how a + * `Set` that was populated in insertion order would iterate. Pre-seeded + * legacy `Set` entries come first so error-message output stays + * ordered oldest-to-newest. + * + * Yields each entry as its formatted `toString()` form. Plugins written + * against the pre-5.21 `Set` shape — e.g. + * `[...resolveContext.stack].find(a => a.includes("module:"))` — keep + * working unchanged because each yielded value is a plain string with + * all of `String.prototype` available natively. Resolves that never + * iterate the stack pay nothing; iteration costs one `toString()` + * allocation per stack frame. + * @returns {IterableIterator} iterator + */ + [Symbol.iterator](): IterableIterator; +} +/** + * Resolve context + */ +type ResolveContext = { + /** + * directories that was found on file system + */ + contextDependencies?: WriteOnlySet | undefined; + /** + * files that was found on file system + */ + fileDependencies?: WriteOnlySet | undefined; + /** + * dependencies that was not found on file system + */ + missingDependencies?: WriteOnlySet | undefined; + /** + * tip of the resolver call stack (a singly-linked list with Set-like API). For instance, `resolve → parsedResolve → describedResolve`. Accepts a legacy `Set` for back-compat with older callers; it is normalized internally without a hot-path branch. + */ + stack?: (StackEntry | Set) | undefined; + /** + * log function + */ + log?: ((str: string) => void) | undefined; + /** + * yield result, if provided plugins can return several results + */ + yield?: ResolveContextYield | undefined; +}; +type ResolveStepHook = AsyncSeriesBailHook< + [ResolveRequest, ResolveContext], + ResolveRequest | null +>; +type KnownHooks = { + /** + * resolve step hook + */ + resolveStep: SyncHook<[ResolveStepHook, ResolveRequest], void>; + /** + * no resolve hook + */ + noResolve: SyncHook<[ResolveRequest, Error]>; + /** + * resolve hook + */ + resolve: ResolveStepHook; + /** + * result hook + */ + result: AsyncSeriesHook<[ResolveRequest, ResolveContext]>; +}; +type EnsuredHooks = { + [key: string]: ResolveStepHook; +}; +type AliasOption = import("./AliasUtils").AliasOption; +type CachedJoin = import("./util/path").CachedJoin; +type CachedDirname = import("./util/path").CachedDirname; +type CachedBasename = import("./util/path").CachedBasename; +type JoinCacheEntry = { + /** + * cached join function + */ + fn: CachedJoin["fn"]; + /** + * the underlying cache map + */ + cache: CachedJoin["cache"]; +}; +type DirnameCacheEntry = { + /** + * cached dirname function + */ + fn: CachedDirname["fn"]; + /** + * the underlying cache map + */ + cache: CachedDirname["cache"]; +}; +type BasenameCacheEntry = { + /** + * cached dirname function + */ + fn: CachedBasename["fn"]; + /** + * the underlying cache map + */ + cache: CachedBasename["cache"]; +}; +type PathCacheFunctions = { + /** + * cached join + */ + join: JoinCacheEntry; + /** + * cached dirname + */ + dirname: DirnameCacheEntry; + /** + * cached basename + */ + basename: BasenameCacheEntry; +}; +type ResolveOptions = import("./ResolverFactory").ResolveOptions; +type KnownContext = { + /** + * environments + */ + environments?: string[] | undefined; + /** + * package id of the importing file in the package map, propagated from a previous result to disambiguate package entries that share a location (`@experimental`, see the `packageMap` option) + */ + packageId?: string | undefined; +}; +type Context = KnownContext & Record; +type ErrorWithDetail = Error & { + details?: string; +}; +type ResolveCallback = ( + err: ErrorWithDetail | null, + res?: string | false, + req?: ResolveRequest, +) => void; +type PossibleFileSystemError = { + /** + * code + */ + code?: string | undefined; + /** + * number + */ + errno?: number | undefined; + /** + * path + */ + path?: string | undefined; + /** + * syscall + */ + syscall?: string | undefined; +}; +type FileSystemCallback = ( + err: (PossibleFileSystemError & Error) | null, + result?: T | undefined, +) => any; +type PathLike = string | Buffer | URL; +type PathOrFileDescriptor = PathLike | number; +type ObjectEncodingOptions = { + /** + * encoding + */ + encoding?: (BufferEncoding | null | undefined) | undefined; +}; +type EncodingOption = ObjectEncodingOptions | BufferEncoding | undefined | null; +type StringCallback = ( + err: NodeJS.ErrnoException | null, + result?: string, +) => void; +type BufferCallback = ( + err: NodeJS.ErrnoException | null, + result?: Buffer, +) => void; +type StringOrBufferCallback = ( + err: NodeJS.ErrnoException | null, + result?: string | Buffer, +) => void; +type StatsCallback = ( + err: NodeJS.ErrnoException | null, + result?: IStats, +) => void; +type BigIntStatsCallback = ( + err: NodeJS.ErrnoException | null, + result?: IBigIntStats, +) => void; +type StatsOrBigIntStatsCallback = ( + err: NodeJS.ErrnoException | null, + result?: IStats | IBigIntStats, +) => void; +type ReadJsonCallback = ( + err: NodeJS.ErrnoException | Error | null, + result?: JsonObject, +) => void; +type IStatsBase = { + /** + * is file + */ + isFile: () => boolean; + /** + * is directory + */ + isDirectory: () => boolean; + /** + * is block device + */ + isBlockDevice: () => boolean; + /** + * is character device + */ + isCharacterDevice: () => boolean; + /** + * is symbolic link + */ + isSymbolicLink: () => boolean; + /** + * is FIFO + */ + isFIFO: () => boolean; + /** + * is socket + */ + isSocket: () => boolean; + /** + * dev + */ + dev: T; + /** + * ino + */ + ino: T; + /** + * mode + */ + mode: T; + /** + * nlink + */ + nlink: T; + /** + * uid + */ + uid: T; + /** + * gid + */ + gid: T; + /** + * rdev + */ + rdev: T; + /** + * size + */ + size: T; + /** + * blksize + */ + blksize: T; + /** + * blocks + */ + blocks: T; + /** + * atime ms + */ + atimeMs: T; + /** + * mtime ms + */ + mtimeMs: T; + /** + * ctime ms + */ + ctimeMs: T; + /** + * birthtime ms + */ + birthtimeMs: T; + /** + * atime + */ + atime: Date; + /** + * mtime + */ + mtime: Date; + /** + * ctime + */ + ctime: Date; + /** + * birthtime + */ + birthtime: Date; +}; +type IStats = IStatsBase; +type IBigIntStats = IStatsBase & { + atimeNs: bigint; + mtimeNs: bigint; + ctimeNs: bigint; + birthtimeNs: bigint; +}; +type Dirent = { + /** + * true when is file, otherwise false + */ + isFile: () => boolean; + /** + * true when is directory, otherwise false + */ + isDirectory: () => boolean; + /** + * true when is block device, otherwise false + */ + isBlockDevice: () => boolean; + /** + * true when is character device, otherwise false + */ + isCharacterDevice: () => boolean; + /** + * true when is symbolic link, otherwise false + */ + isSymbolicLink: () => boolean; + /** + * true when is FIFO, otherwise false + */ + isFIFO: () => boolean; + /** + * true when is socket, otherwise false + */ + isSocket: () => boolean; + /** + * name + */ + name: T; + /** + * path + */ + parentPath: string; + /** + * path + */ + path?: string | undefined; +}; +type StatOptions = { + /** + * need bigint values + */ + bigint?: (boolean | undefined) | undefined; +}; +type StatSyncOptions = { + /** + * need bigint values + */ + bigint?: (boolean | undefined) | undefined; + /** + * throw if no entry + */ + throwIfNoEntry?: (boolean | undefined) | undefined; +}; +type ReadFile = { + ( + 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; +}; +type BufferEncodingOption = + | "buffer" + | { + encoding: "buffer"; + }; +type ReadFileSync = { + ( + 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; +}; +type Readdir = { + ( + path: PathLike, + options: + | { + encoding: BufferEncoding | null; + withFileTypes?: false | undefined; + recursive?: boolean | undefined; + } + | BufferEncoding + | undefined + | null, + callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void, + ): void; + ( + path: PathLike, + options: + | { + encoding: "buffer"; + withFileTypes?: false | undefined; + recursive?: boolean | undefined; + } + | "buffer", + callback: (err: NodeJS.ErrnoException | null, files?: Buffer[]) => void, + ): void; + ( + path: PathLike, + options: + | (ObjectEncodingOptions & { + withFileTypes?: false | undefined; + recursive?: boolean | undefined; + }) + | BufferEncoding + | undefined + | null, + callback: ( + err: NodeJS.ErrnoException | null, + files?: string[] | Buffer[], + ) => void, + ): void; + ( + path: PathLike, + callback: (err: NodeJS.ErrnoException | null, files?: string[]) => void, + ): void; + ( + path: PathLike, + options: ObjectEncodingOptions & { + withFileTypes: true; + recursive?: boolean | undefined; + }, + callback: ( + err: NodeJS.ErrnoException | null, + files?: Dirent[], + ) => void, + ): void; + ( + path: PathLike, + options: { + encoding: "buffer"; + withFileTypes: true; + recursive?: boolean | undefined; + }, + callback: ( + err: NodeJS.ErrnoException | null, + files: Dirent[], + ) => void, + ): void; +}; +type ReaddirSync = { + ( + 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[]; + ( + path: PathLike, + options: { + encoding: "buffer"; + withFileTypes: true; + recursive?: boolean | undefined; + }, + ): Dirent[]; +}; +type ReadJson = ( + pathOrFileDescription: PathOrFileDescriptor, + callback: ReadJsonCallback, +) => void; +type ReadJsonSync = (pathOrFileDescription: PathOrFileDescriptor) => JsonObject; +type Readlink = { + (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; +}; +type ReadlinkSync = { + (path: PathLike, options?: EncodingOption): string; + (path: PathLike, options: BufferEncodingOption): Buffer; + (path: PathLike, options?: EncodingOption): string | Buffer; +}; +type LStat = { + (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; +}; +type LStatSync = { + (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; +}; +type Stat = { + (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; +}; +type StatSync = { + (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; +}; +type RealPath = { + (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; +}; +type RealPathSync = { + (path: PathLike, options?: EncodingOption): string; + (path: PathLike, options: BufferEncodingOption): Buffer; + (path: PathLike, options?: EncodingOption): string | Buffer; +}; +type FileSystem = { + /** + * read file method + */ + readFile: ReadFile; + /** + * readdir method + */ + readdir: Readdir; + /** + * read json method + */ + readJson?: ReadJson | undefined; + /** + * read link method + */ + readlink: Readlink; + /** + * lstat method + */ + lstat?: LStat | undefined; + /** + * stat method + */ + stat: Stat; + /** + * realpath method + */ + realpath?: RealPath | undefined; +}; +type SyncFileSystem = { + /** + * read file sync method + */ + readFileSync: ReadFileSync; + /** + * read dir sync method + */ + readdirSync: ReaddirSync; + /** + * read json sync method + */ + readJsonSync?: ReadJsonSync | undefined; + /** + * read link sync method + */ + readlinkSync: ReadlinkSync; + /** + * lstat sync method + */ + lstatSync?: LStatSync | undefined; + /** + * stat sync method + */ + statSync: StatSync; + /** + * real path sync method + */ + realpathSync?: RealPathSync | undefined; +}; +type ParsedIdentifier = { + /** + * request + */ + request: string; + /** + * query + */ + query: string; + /** + * fragment + */ + fragment: string; + /** + * is directory + */ + directory: boolean; + /** + * is module + */ + module: boolean; + /** + * is file + */ + file: boolean; + /** + * is internal + */ + internal: boolean; +}; +type JsonPrimitive = string | number | boolean | null; +type JsonArray = JsonValue[]; +type JsonValue = JsonPrimitive | JsonObject | JsonArray; +type JsonObject = { [Key in string]?: JsonValue | undefined }; +type TsconfigPathsMap = { + /** + * main tsconfig paths data + */ + main: TsconfigPathsData; + /** + * main tsconfig base URL (absolute path) + */ + mainContext: string; + /** + * referenced tsconfig paths data mapped by baseUrl + */ + refs: { + [baseUrl: string]: TsconfigPathsData; + }; + /** + * all contexts (main + refs) for quick lookup + */ + allContexts: { + [context: string]: TsconfigPathsData; + }; + /** + * precomputed `Object.keys(allContexts)` — read-only; used on the `_selectPathsDataForContext` hot path + */ + contextList: string[]; + /** + * file dependencies + */ + fileDependencies: Set; +}; +type TsconfigPathsData = { + /** + * tsconfig file data + */ + alias: import("./AliasUtils").CompiledAliasOptions; + /** + * tsconfig file data + */ + modules: string[]; +}; +type BaseResolveRequest = { + /** + * path + */ + path: string | false; + /** + * content + */ + context?: Context | undefined; + /** + * description file path + */ + descriptionFilePath?: string | undefined; + /** + * description file root + */ + descriptionFileRoot?: string | undefined; + /** + * description file data + */ + descriptionFileData?: JsonObject | undefined; + /** + * tsconfig paths map + */ + tsconfigPathsMap?: (TsconfigPathsMap | null | undefined) | undefined; + /** + * relative path + */ + relativePath?: string | undefined; + /** + * true when need to ignore symlinks, otherwise false + */ + ignoreSymlinks?: boolean | undefined; + /** + * true when full specified, otherwise false + */ + fullySpecified?: boolean | undefined; + /** + * package id the request was resolved to in the package map, to be propagated to resolutions made from the resulting file (`@experimental`, see the `packageMap` option) + */ + packageId?: string | undefined; + /** + * inner request for internal usage + */ + __innerRequest?: string | undefined; + /** + * inner request for internal usage + */ + __innerRequest_request?: string | undefined; + /** + * inner relative path for internal usage + */ + __innerRequest_relativePath?: string | undefined; + /** + * internal: shared marker `RestrictionsPlugin` flips when it filters out an existing target, letting `ExportsFieldPlugin` fall back instead of erroring + */ + __restrictionsMarker?: + | { + blocked: boolean; + } + | undefined; +}; +type ResolveRequest = BaseResolveRequest & Partial; +type WriteOnlySet = { + add: (item: T) => void; +}; +type ResolveContextYield = (request: ResolveRequest) => void; +import { AsyncSeriesBailHook } from "tapable"; +import { SyncHook } from "tapable"; +import { AsyncSeriesHook } from "tapable"; diff --git a/types/ResolverFactory.d.ts b/types/ResolverFactory.d.ts new file mode 100644 index 00000000..bad1977f --- /dev/null +++ b/types/ResolverFactory.d.ts @@ -0,0 +1,340 @@ +export function createResolver(options: UserResolveOptions): Resolver; +export type AliasOptionEntry = import("./AliasPlugin").AliasOption; +export type ExtensionAliasOption = + import("./ExtensionAliasPlugin").ExtensionAliasOption; +export type PackageMapOptions = import("./PackageMapPlugin").PackageMapOptions; +export type PackageMapPackages = import("./util/packageMap").PackageMapPackages; +export type PnpApi = import("./PnpPlugin").PnpApiImpl; +export type EnsuredHooks = import("./Resolver").EnsuredHooks; +export type FileSystem = import("./Resolver").FileSystem; +export type KnownHooks = import("./Resolver").KnownHooks; +export type ResolveRequest = import("./Resolver").ResolveRequest; +export type SyncFileSystem = import("./Resolver").SyncFileSystem; +export type Cache = import("./UnsafeCachePlugin").Cache; +export type AliasOptionNewRequest = string | string[] | false; +export type AliasOptions = { + [k: string]: AliasOptionNewRequest; +}; +export type UserAliasOptionNewRequest = string | URL | (string | URL)[] | false; +export type UserAliasOptions = { + [k: string]: UserAliasOptionNewRequest; +}; +export type UserAliasOptionEntry = { + alias: UserAliasOptionNewRequest; + name: string; + onlyModule?: boolean; +}; +export type ExtensionAliasOptions = { + [k: string]: string | string[]; +}; +export type Falsy = false | 0 | "" | null | undefined; +export type Plugin = + | { + apply: (resolver: Resolver) => void; + } + | ((this: Resolver, resolver: Resolver) => void) + | Falsy; +export type TsconfigOptions = { + /** + * A relative path to the tsconfig file based on cwd, or an absolute path of tsconfig file + */ + configFile?: string | undefined; + /** + * References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths + */ + references?: (string[] | "auto") | undefined; + /** + * Override baseUrl from tsconfig.json. If provided, this value will be used instead of the baseUrl in the tsconfig file + */ + baseUrl?: string | undefined; +}; +export type UserTsconfigOptions = { + /** + * A path, or `file:` URL, pointing at the tsconfig file + */ + configFile?: (string | URL) | undefined; + /** + * References to other tsconfig files. 'auto' inherits from TypeScript config, or an array of relative/absolute paths or `file:` URLs + */ + references?: ((string | URL)[] | "auto") | undefined; + /** + * Override baseUrl from tsconfig.json with a path or `file:` URL + */ + baseUrl?: (string | URL) | undefined; +}; +/** + * A Node.js package map (https://nodejs.org/api/packages.html#package-maps), + * either as the path of the configuration file or as its already-parsed + * contents. + */ +export type UserPackageMapOptions = { + /** + * A path, or `file:` `URL` instance, pointing at the package map file. Required together with `packages`, whose relative `url` values are resolved against it + */ + configFile?: (string | URL) | undefined; + /** + * An already-parsed `packages` object, used instead of reading `configFile` from disk + */ + packages?: PackageMapPackages | undefined; +}; +export type UserResolveOptions = { + /** + * A list of module alias configurations or an object which maps key to value + */ + alias?: (UserAliasOptions | UserAliasOptionEntry[]) | undefined; + /** + * A list of module alias configurations or an object which maps key to value, applied only after modules option + */ + fallback?: (UserAliasOptions | UserAliasOptionEntry[]) | undefined; + /** + * An object which maps extension to extension aliases + */ + extensionAlias?: ExtensionAliasOptions | undefined; + /** + * Also apply `extensionAlias` to paths resolved through the package.json `exports` field. Off by default (Node.js-aligned); when enabled, matches TypeScript's behavior for packages that ship TS sources alongside compiled JS. + */ + extensionAliasForExports?: boolean | undefined; + /** + * A list of alias fields in description files + */ + aliasFields?: (string | string[])[] | undefined; + /** + * A function which decides whether a request should be cached or not. An object is passed with at least `path` and `request` properties. + */ + cachePredicate?: ((predicate: ResolveRequest) => boolean) | undefined; + /** + * Whether or not the unsafeCache should include request context as part of the cache key. + */ + cacheWithContext?: boolean | undefined; + /** + * A list of description files to read from + */ + descriptionFiles?: string[] | undefined; + /** + * A list of exports field condition names. + */ + conditionNames?: string[] | undefined; + /** + * Enforce that a extension from extensions must be used + */ + enforceExtension?: boolean | undefined; + /** + * A list of exports fields in description files + */ + exportsFields?: (string | string[])[] | undefined; + /** + * A list of imports fields in description files + */ + importsFields?: (string | string[])[] | undefined; + /** + * A list of extensions which should be tried for files + */ + extensions?: string[] | undefined; + /** + * The file system which should be used + */ + fileSystem: FileSystem; + /** + * Use this cache object to unsafely cache the successful requests + */ + unsafeCache?: (Cache | boolean) | undefined; + /** + * Resolve symlinks to their symlinked location + */ + symlinks?: boolean | undefined; + /** + * A prepared Resolver to which the plugins are attached + */ + resolver?: Resolver | undefined; + /** + * A list of directories to resolve modules from, can be absolute path, folder name, or a `file:` URL + */ + modules?: ((string | URL)[] | string | URL) | undefined; + /** + * A list of main fields in description files + */ + mainFields?: + | ( + | string + | string[] + | { + name: string | string[]; + forceRelative: boolean; + } + )[] + | undefined; + /** + * A list of main files in directories + */ + mainFiles?: string[] | undefined; + /** + * A list of additional resolve plugins which should be applied + */ + plugins?: Plugin[] | undefined; + /** + * A Node.js package map file path (or `file:` `URL` instance), or an object with the already-parsed `packages`. When set, bare specifiers resolve through the map instead of `node_modules` (`@experimental`) + */ + packageMap?: (string | URL | UserPackageMapOptions) | undefined; + /** + * A PnP API that should be used - null is "never", undefined is "auto" + */ + pnpApi?: (PnpApi | null) | undefined; + /** + * A list of root paths, each an absolute path or a `file:` URL + */ + roots?: (string | URL)[] | undefined; + /** + * The request is already fully specified and no extensions or directories are resolved for it + */ + fullySpecified?: boolean | undefined; + /** + * Resolve to a context instead of a file + */ + resolveToContext?: boolean | undefined; + /** + * A list of resolve restrictions, each an absolute path, a `file:` URL, or a RegExp + */ + restrictions?: (string | URL | RegExp)[] | undefined; + /** + * Use only the sync constraints of the file system calls + */ + useSyncFileSystemCalls?: boolean | undefined; + /** + * Prefer to resolve module requests as relative requests before falling back to modules + */ + preferRelative?: boolean | undefined; + /** + * Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots + */ + preferAbsolute?: boolean | undefined; + /** + * TypeScript config file path (or `file:` URL) or config object with configFile and references + */ + tsconfig?: (string | URL | boolean | UserTsconfigOptions) | undefined; +}; +export type ResolveOptions = { + /** + * alias + */ + alias: AliasOptionEntry[]; + /** + * fallback + */ + fallback: AliasOptionEntry[]; + /** + * alias fields + */ + aliasFields: Set; + /** + * extension alias + */ + extensionAlias: ExtensionAliasOption[]; + /** + * apply extension alias to exports field targets + */ + extensionAliasForExports: boolean; + /** + * cache predicate + */ + cachePredicate: (predicate: ResolveRequest) => boolean; + /** + * cache with context + */ + cacheWithContext: boolean; + /** + * A list of exports field condition names. + */ + conditionNames: Set; + /** + * description files + */ + descriptionFiles: string[]; + /** + * enforce extension + */ + enforceExtension: boolean; + /** + * exports fields + */ + exportsFields: Set; + /** + * imports fields + */ + importsFields: Set; + /** + * extensions + */ + extensions: Set; + /** + * fileSystem + */ + fileSystem: FileSystem; + /** + * unsafe cache + */ + unsafeCache: Cache | false; + /** + * symlinks + */ + symlinks: boolean; + /** + * resolver + */ + resolver?: Resolver | undefined; + /** + * modules + */ + modules: (string | string[])[]; + /** + * main fields + */ + mainFields: { + name: string[]; + forceRelative: boolean; + }[]; + /** + * main files + */ + mainFiles: Set; + /** + * plugins + */ + plugins: Plugin[]; + /** + * package map + */ + packageMap: PackageMapOptions | null; + /** + * pnp API + */ + pnpApi: PnpApi | null; + /** + * roots + */ + roots: Set; + /** + * fully specified + */ + fullySpecified: boolean; + /** + * resolve to context + */ + resolveToContext: boolean; + /** + * restrictions + */ + restrictions: Set; + /** + * prefer relative + */ + preferRelative: boolean; + /** + * prefer absolute + */ + preferAbsolute: boolean; + /** + * tsconfig file path or config object + */ + tsconfig: string | boolean | TsconfigOptions; +}; +import Resolver = require("./Resolver"); diff --git a/types/RestrictionsPlugin.d.ts b/types/RestrictionsPlugin.d.ts new file mode 100644 index 00000000..ceb2fb60 --- /dev/null +++ b/types/RestrictionsPlugin.d.ts @@ -0,0 +1,52 @@ +export = RestrictionsPlugin; +declare class RestrictionsPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {Set} restrictions restrictions + */ + constructor( + source: string | ResolveStepHook, + restrictions: Set, + ); + source: string | import("./Resolver").ResolveStepHook; + restrictions: Set; + /** @type {Restriction[]} */ + _restrictions: Restriction[]; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace RestrictionsPlugin { + export { + Resolver, + ResolveStepHook, + PathRestriction, + RegExpRestriction, + Restriction, + }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type PathRestriction = { + /** + * type of the restriction + */ + type: "path"; + /** + * normalized path the request has to be inside of + */ + rule: string; +}; +type RegExpRestriction = { + /** + * type of the restriction + */ + type: "regexp"; + /** + * pattern the request has to match + */ + rule: RegExp; +}; +type Restriction = PathRestriction | RegExpRestriction; diff --git a/types/ResultPlugin.d.ts b/types/ResultPlugin.d.ts new file mode 100644 index 00000000..94fe0b2f --- /dev/null +++ b/types/ResultPlugin.d.ts @@ -0,0 +1,18 @@ +export = ResultPlugin; +declare class ResultPlugin { + /** + * @param {ResolveStepHook} source source + */ + constructor(source: ResolveStepHook); + source: import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace ResultPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/RootsPlugin.d.ts b/types/RootsPlugin.d.ts new file mode 100644 index 00000000..72625d25 --- /dev/null +++ b/types/RootsPlugin.d.ts @@ -0,0 +1,30 @@ +export = RootsPlugin; +/** @typedef {import("./Resolver")} Resolver */ +/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */ +/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */ +declare class RootsPlugin { + /** + * @param {string | ResolveStepHook} source source hook + * @param {Set} roots roots + * @param {string | ResolveStepHook} target target hook + */ + constructor( + source: string | ResolveStepHook, + roots: Set, + target: string | ResolveStepHook, + ); + roots: string[]; + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace RootsPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/SelfReferencePlugin.d.ts b/types/SelfReferencePlugin.d.ts new file mode 100644 index 00000000..642e7d9c --- /dev/null +++ b/types/SelfReferencePlugin.d.ts @@ -0,0 +1,31 @@ +export = SelfReferencePlugin; +declare class SelfReferencePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | string[]} fieldNamePath name path + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + fieldNamePath: string | string[], + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + fieldName: string | string[]; + /** @type {WeakMap} */ + _nameCache: WeakMap; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace SelfReferencePlugin { + export { Resolver, JsonObject, ResolveRequest, ResolveStepHook }; +} +declare const NO_SELF_REF: unique symbol; +type Resolver = import("./Resolver"); +type JsonObject = import("./Resolver").JsonObject; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/SymlinkPlugin.d.ts b/types/SymlinkPlugin.d.ts new file mode 100644 index 00000000..09750b71 --- /dev/null +++ b/types/SymlinkPlugin.d.ts @@ -0,0 +1,24 @@ +export = SymlinkPlugin; +declare class SymlinkPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace SymlinkPlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/SyncAsyncFileSystemDecorator.d.ts b/types/SyncAsyncFileSystemDecorator.d.ts new file mode 100644 index 00000000..716926b8 --- /dev/null +++ b/types/SyncAsyncFileSystemDecorator.d.ts @@ -0,0 +1,52 @@ +export = SyncAsyncFileSystemDecorator; +/** @typedef {import("./Resolver").FileSystem} FileSystem */ +/** @typedef {import("./Resolver").StringCallback} StringCallback */ +/** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */ +/** @typedef {Function} SyncOrAsyncFunction */ +/** @typedef {any} ResultOfSyncOrAsyncFunction */ +/** + * @param {SyncFileSystem} fs file system implementation + * @constructor + */ +declare function SyncAsyncFileSystemDecorator(fs: SyncFileSystem): void; +declare class SyncAsyncFileSystemDecorator { + /** @typedef {import("./Resolver").FileSystem} FileSystem */ + /** @typedef {import("./Resolver").StringCallback} StringCallback */ + /** @typedef {import("./Resolver").SyncFileSystem} SyncFileSystem */ + /** @typedef {Function} SyncOrAsyncFunction */ + /** @typedef {any} ResultOfSyncOrAsyncFunction */ + /** + * @param {SyncFileSystem} fs file system implementation + * @constructor + */ + constructor(fs: SyncFileSystem); + fs: import("./Resolver").SyncFileSystem; + lstat: import("./Resolver").LStat | undefined; + lstatSync: import("./Resolver").LStatSync | undefined; + stat: import("./Resolver").Stat; + statSync: import("./Resolver").StatSync; + readdir: import("./Resolver").Readdir; + readdirSync: import("./Resolver").ReaddirSync; + readFile: import("./Resolver").ReadFile; + readFileSync: import("./Resolver").ReadFileSync; + readlink: import("./Resolver").Readlink; + readlinkSync: import("./Resolver").ReadlinkSync; + readJson: import("./Resolver").ReadJson | undefined; + readJsonSync: import("./Resolver").ReadJsonSync | undefined; + realpath: import("./Resolver").RealPath | undefined; + realpathSync: import("./Resolver").RealPathSync | undefined; +} +declare namespace SyncAsyncFileSystemDecorator { + export { + FileSystem, + StringCallback, + SyncFileSystem, + SyncOrAsyncFunction, + ResultOfSyncOrAsyncFunction, + }; +} +type FileSystem = import("./Resolver").FileSystem; +type StringCallback = import("./Resolver").StringCallback; +type SyncFileSystem = import("./Resolver").SyncFileSystem; +type SyncOrAsyncFunction = Function; +type ResultOfSyncOrAsyncFunction = any; diff --git a/types/TryNextPlugin.d.ts b/types/TryNextPlugin.d.ts new file mode 100644 index 00000000..c3ade874 --- /dev/null +++ b/types/TryNextPlugin.d.ts @@ -0,0 +1,26 @@ +export = TryNextPlugin; +declare class TryNextPlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string} message message + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + message: string, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + message: string; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace TryNextPlugin { + export { Resolver, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/TsconfigPathsPlugin.d.ts b/types/TsconfigPathsPlugin.d.ts new file mode 100644 index 00000000..8c65d39d --- /dev/null +++ b/types/TsconfigPathsPlugin.d.ts @@ -0,0 +1,204 @@ +export = TsconfigPathsPlugin; +declare class TsconfigPathsPlugin { + /** + * @param {true | string | TsconfigOptions} configFileOrOptions tsconfig file path or options object + */ + constructor(configFileOrOptions: true | string | TsconfigOptions); + /** @type {boolean} */ + isAutoConfigFile: boolean; + /** @type {string} */ + configFile: string; + /** @type {TsconfigReference[] | "auto"} */ + references: TsconfigReference[] | "auto"; + /** @type {string | undefined} */ + baseUrl: string | undefined; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; + /** + * Get TsconfigPathsMap for the request (with caching) + * @param {Resolver} resolver the resolver + * @param {ResolveRequest} request the request + * @param {ResolveContext} resolveContext the resolve context + * @param {(err: Error | null, result?: TsconfigPathsMap | null) => void} callback the callback + * @returns {void} + */ + _getTsconfigPathsMap( + resolver: Resolver, + request: ResolveRequest, + resolveContext: ResolveContext, + callback: (err: Error | null, result?: TsconfigPathsMap | null) => void, + ): void; + /** + * Walk up from startDir to the filesystem root looking for tsconfig.json. + * Like TypeScript's own `findConfigFile` / `forEachAncestorDirectory`. + * @param {Resolver} resolver the resolver + * @param {string} startDir the directory to start searching from + * @param {(err: Error | null, result?: TsconfigPathsMap | null) => void} callback the callback + * @returns {void} + */ + _findTsconfigUpward( + resolver: Resolver, + startDir: string, + callback: (err: Error | null, result?: TsconfigPathsMap | null) => void, + ): void; + /** + * Load tsconfig.json and build complete TsconfigPathsMap + * Includes main project paths and all referenced projects + * @param {Resolver} resolver the resolver + * @param {string} absTsconfigPath absolute path to tsconfig.json + * @param {(err: Error | null, result?: TsconfigPathsMap) => void} callback the callback + * @returns {void} + */ + _loadTsconfigPathsMap( + resolver: Resolver, + absTsconfigPath: string, + callback: (err: Error | null, result?: TsconfigPathsMap) => void, + ): void; + /** + * Select the correct TsconfigPathsData based on request.path (context-aware) + * Matches the behavior of tsconfig-paths-webpack-plugin + * @param {string | false} requestPath the request path + * @param {TsconfigPathsMap} tsconfigPathsMap the tsconfig paths map + * @returns {TsconfigPathsData | null} the selected paths data + */ + _selectPathsDataForContext( + requestPath: string | false, + tsconfigPathsMap: TsconfigPathsMap, + ): TsconfigPathsData | null; + /** + * Load tsconfig from extends path + * @param {Resolver} resolver the resolver + * @param {string} configFilePath current config file path + * @param {string} extendedConfigValue extends value + * @param {Set} fileDependencies the file dependencies + * @param {Set} visitedConfigPaths config paths being loaded (for circular extends detection) + * @param {(err: Error | null, result?: Tsconfig) => void} callback callback + * @returns {void} + */ + _loadTsconfigFromExtends( + resolver: Resolver, + configFilePath: string, + extendedConfigValue: string, + fileDependencies: Set, + visitedConfigPaths: Set, + callback: (err: Error | null, result?: Tsconfig) => void, + ): void; + /** + * Walk up from startDir looking for `/` (a + * `node_modules/...` sub-path), matching Node.js module resolution so a + * package hoisted to a parent workspace's node_modules is found. + * @param {Resolver} resolver the resolver + * @param {string} startDir directory to start searching from + * @param {string} subPath node_modules-relative sub-path to look for + * @param {(found: string | null) => void} callback receives the found path or null + * @returns {void} + */ + _findExtendsInNodeModules( + resolver: Resolver, + startDir: string, + subPath: string, + callback: (found: string | null) => void, + ): void; + /** + * Load referenced tsconfig projects and store in referenceMatchMap + * Simple implementation matching tsconfig-paths-webpack-plugin: + * Just load each reference and store independently + * @param {Resolver} resolver the resolver + * @param {string} context the context + * @param {TsconfigReference[]} references array of references + * @param {Set} fileDependencies the file dependencies + * @param {{ [baseUrl: string]: TsconfigPathsData }} referenceMatchMap the map to populate + * @param {(err: Error | null) => void} callback callback + * @param {Set=} visitedRefPaths visited reference config paths (for circular reference detection) + * @returns {void} + */ + _loadTsconfigReferences( + resolver: Resolver, + context: string, + references: TsconfigReference[], + fileDependencies: Set, + referenceMatchMap: { + [baseUrl: string]: TsconfigPathsData; + }, + callback: (err: Error | null) => void, + visitedRefPaths?: Set | undefined, + ): void; + /** + * Load tsconfig.json with extends support + * @param {Resolver} resolver the resolver + * @param {string} configFilePath absolute path to tsconfig.json + * @param {Set} fileDependencies the file dependencies + * @param {Set | undefined} visitedConfigPaths config paths being loaded (for circular extends detection) + * @param {(err: Error | null, result?: Tsconfig) => void} callback callback + * @returns {void} + */ + _loadTsconfig( + resolver: Resolver, + configFilePath: string, + fileDependencies: Set, + visitedConfigPaths: Set | undefined, + callback: (err: Error | null, result?: Tsconfig) => void, + ): void; +} +declare namespace TsconfigPathsPlugin { + export { + Resolver, + ResolveStepHook, + AliasOption, + ResolveRequest, + ResolveContext, + FileSystem, + TsconfigPathsData, + TsconfigPathsMap, + TsconfigOptions, + TsconfigCompilerOptions, + TsconfigReference, + Tsconfig, + }; +} +type Resolver = import("./Resolver"); +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type AliasOption = import("./AliasUtils").AliasOption; +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveContext = import("./Resolver").ResolveContext; +type FileSystem = import("./Resolver").FileSystem; +type TsconfigPathsData = import("./Resolver").TsconfigPathsData; +type TsconfigPathsMap = import("./Resolver").TsconfigPathsMap; +type TsconfigOptions = import("./ResolverFactory").TsconfigOptions; +type TsconfigCompilerOptions = { + /** + * Base URL for resolving paths + */ + baseUrl?: string | undefined; + /** + * TypeScript paths mapping + */ + paths?: + | { + [key: string]: string[]; + } + | undefined; +}; +type TsconfigReference = { + /** + * Path to the referenced project + */ + path: string; +}; +type Tsconfig = { + /** + * Compiler options + */ + compilerOptions?: TsconfigCompilerOptions | undefined; + /** + * Extended configuration paths + */ + extends?: (string | string[]) | undefined; + /** + * Project references + */ + references?: TsconfigReference[] | undefined; +}; diff --git a/types/UnsafeCachePlugin.d.ts b/types/UnsafeCachePlugin.d.ts new file mode 100644 index 00000000..efb46b72 --- /dev/null +++ b/types/UnsafeCachePlugin.d.ts @@ -0,0 +1,43 @@ +export = UnsafeCachePlugin; +declare class UnsafeCachePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {(request: ResolveRequest) => boolean} filterPredicate filterPredicate + * @param {Cache} cache cache + * @param {boolean} withContext withContext + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + filterPredicate: (request: ResolveRequest) => boolean, + cache: Cache, + withContext: boolean, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + filterPredicate: (request: ResolveRequest) => boolean; + withContext: boolean; + cache: Cache; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace UnsafeCachePlugin { + export { + Resolver, + ResolveRequest, + ResolveStepHook, + ResolveContextYield, + Cache, + }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; +type ResolveContextYield = import("./Resolver").ResolveContextYield; +type Cache = { + [k: string]: undefined | ResolveRequest | ResolveRequest[]; +}; diff --git a/types/UseFilePlugin.d.ts b/types/UseFilePlugin.d.ts new file mode 100644 index 00000000..58fb9403 --- /dev/null +++ b/types/UseFilePlugin.d.ts @@ -0,0 +1,27 @@ +export = UseFilePlugin; +declare class UseFilePlugin { + /** + * @param {string | ResolveStepHook} source source + * @param {string} filename filename + * @param {string | ResolveStepHook} target target + */ + constructor( + source: string | ResolveStepHook, + filename: string, + target: string | ResolveStepHook, + ); + source: string | import("./Resolver").ResolveStepHook; + filename: string; + target: string | import("./Resolver").ResolveStepHook; + /** + * @param {Resolver} resolver the resolver + * @returns {void} + */ + apply(resolver: Resolver): void; +} +declare namespace UseFilePlugin { + export { Resolver, ResolveRequest, ResolveStepHook }; +} +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; +type ResolveStepHook = import("./Resolver").ResolveStepHook; diff --git a/types/createInnerContext.d.ts b/types/createInnerContext.d.ts new file mode 100644 index 00000000..25c4bf42 --- /dev/null +++ b/types/createInnerContext.d.ts @@ -0,0 +1,10 @@ +declare namespace _exports { + export { ResolveContext }; +} +declare function _exports( + parent: ResolveContext, + stack: ResolveContext["stack"], + message: null | string, +): ResolveContext; +export = _exports; +type ResolveContext = import("./Resolver").ResolveContext; diff --git a/types/forEachBail.d.ts b/types/forEachBail.d.ts new file mode 100644 index 00000000..472cae06 --- /dev/null +++ b/types/forEachBail.d.ts @@ -0,0 +1,15 @@ +declare namespace _exports { + export { ResolveRequest, Iterator }; +} +declare function _exports( + array: T[], + iterator: Iterator, + callback: (err?: null | Error, result?: null | Z, i?: number) => void, +): void; +export = _exports; +type ResolveRequest = import("./Resolver").ResolveRequest; +type Iterator = ( + item: T, + callback: (err?: null | Error, result?: null | Z) => void, + i: number, +) => void; diff --git a/types/getInnerRequest.d.ts b/types/getInnerRequest.d.ts new file mode 100644 index 00000000..1271b98b --- /dev/null +++ b/types/getInnerRequest.d.ts @@ -0,0 +1,7 @@ +declare namespace _exports { + export { Resolver, ResolveRequest }; +} +declare function _exports(resolver: Resolver, request: ResolveRequest): string; +export = _exports; +type Resolver = import("./Resolver"); +type ResolveRequest = import("./Resolver").ResolveRequest; diff --git a/types/getPaths.d.ts b/types/getPaths.d.ts new file mode 100644 index 00000000..f7fe471a --- /dev/null +++ b/types/getPaths.d.ts @@ -0,0 +1,34 @@ +export = getPaths; +/** @typedef {import("./Resolver").FileSystem} FileSystem */ +/** @typedef {{ paths: string[], segments: string[] }} GetPathsResult */ +/** + * Walk `path` from tip to root, returning every ancestor directory (plus the + * input itself) in `paths`, and each corresponding segment name in `segments`. + * + * The return value may be shared across callers via `getPathsCached` — treat + * it as read-only. Callers that need to mutate (currently only + * `SymlinkPlugin`) should `slice()` the arrays locally before writing. + * @param {string} path path + * @returns {GetPathsResult} paths and segments + */ +declare function getPaths(path: string): GetPathsResult; +declare namespace getPaths { + export { getPathsCached, FileSystem, GetPathsResult }; +} +/** + * Memoized `getPaths`. The returned object is shared across callers — do + * not mutate the `paths` or `segments` arrays in-place; `slice()` first if + * you need a mutable copy. + * @param {FileSystem} fileSystem filesystem used as the cache namespace + * @param {string} path path + * @returns {GetPathsResult} paths and segments + */ +declare function getPathsCached( + fileSystem: FileSystem, + path: string, +): GetPathsResult; +type FileSystem = import("./Resolver").FileSystem; +type GetPathsResult = { + paths: string[]; + segments: string[]; +}; diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 00000000..7b7e2fab --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,131 @@ +declare namespace _exports { + export { + ResolveOptionsOptionalFS, + CachedInputFileSystem, + BaseFileSystem, + CloneBasenamePlugin, + LogInfoPlugin, + PnpApi, + Resolver, + Context, + FileSystem, + ResolveCallback, + ResolveContext, + ResolveRequest, + SyncFileSystem, + Plugin, + ResolveOptions, + TsconfigPathsPlugin, + ResolveFunctionAsync, + ResolveFunction, + ResolveFunctionPromise, + }; +} +declare const _exports: ResolveFunctionAsync & { + readonly sync: ResolveFunction; + readonly promise: ResolveFunctionPromise; + create: typeof create & { + readonly sync: typeof createSync; + readonly promise: typeof createPromise; + }; + readonly ResolverFactory: typeof import("./ResolverFactory"); + readonly CachedInputFileSystem: typeof import("./CachedInputFileSystem"); + readonly CloneBasenamePlugin: typeof import("./CloneBasenamePlugin"); + readonly LogInfoPlugin: typeof import("./LogInfoPlugin"); + readonly TsconfigPathsPlugin: typeof import("./TsconfigPathsPlugin"); + readonly forEachBail: ( + array: T[], + iterator: import("./forEachBail").Iterator, + callback: (err?: null | Error, result?: null | Z, i?: number) => void, + ) => void; +}; +export = _exports; +type ResolveOptionsOptionalFS = Omit & + Partial>; +type CachedInputFileSystem = import("./CachedInputFileSystem"); +type BaseFileSystem = import("./CachedInputFileSystem").BaseFileSystem; +type CloneBasenamePlugin = import("./CloneBasenamePlugin"); +type LogInfoPlugin = import("./LogInfoPlugin"); +type PnpApi = import("./PnpPlugin").PnpApiImpl; +type Resolver = import("./Resolver"); +type Context = import("./Resolver").Context; +type FileSystem = import("./Resolver").FileSystem; +type ResolveCallback = import("./Resolver").ResolveCallback; +type ResolveContext = import("./Resolver").ResolveContext; +type ResolveRequest = import("./Resolver").ResolveRequest; +type SyncFileSystem = import("./Resolver").SyncFileSystem; +type Plugin = import("./ResolverFactory").Plugin; +type ResolveOptions = import("./ResolverFactory").UserResolveOptions; +type TsconfigPathsPlugin = import("./TsconfigPathsPlugin"); +type ResolveFunctionAsync = { + ( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext: ResolveContext, + callback: ResolveCallback, + ): void; + ( + context: Context, + parent: string | URL, + specifier: string | URL, + callback: ResolveCallback, + ): void; + ( + parent: string | URL, + specifier: string | URL, + resolveContext: ResolveContext, + callback: ResolveCallback, + ): void; + ( + parent: string | URL, + specifier: string | URL, + callback: ResolveCallback, + ): void; +}; +type ResolveFunction = { + ( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext, + ): string | false; + ( + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext, + ): string | false; +}; +type ResolveFunctionPromise = { + ( + context: Context, + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext, + ): Promise; + ( + parent: string | URL, + specifier: string | URL, + resolveContext?: ResolveContext, + ): Promise; +}; +/** @typedef {Omit & Partial>} ResolveOptionsOptionalFS */ +/** + * @param {ResolveOptionsOptionalFS} options Resolver options + * @returns {ResolveFunctionAsync} Resolver function + */ +declare function create( + options: ResolveOptionsOptionalFS, +): ResolveFunctionAsync; +/** + * @param {ResolveOptionsOptionalFS} options Resolver options + * @returns {ResolveFunction} Resolver function + */ +declare function createSync(options: ResolveOptionsOptionalFS): ResolveFunction; +/** + * @param {ResolveOptionsOptionalFS} options Resolver options + * @returns {ResolveFunctionPromise} Resolver function + */ +declare function createPromise( + options: ResolveOptionsOptionalFS, +): ResolveFunctionPromise; diff --git a/types/util/entrypoints.d.ts b/types/util/entrypoints.d.ts new file mode 100644 index 00000000..15091184 --- /dev/null +++ b/types/util/entrypoints.d.ts @@ -0,0 +1,58 @@ +export function processExportsField(exportsField: ExportsField): FieldProcessor; +export function processImportsField(importsField: ImportsField): FieldProcessor; +export type DirectMapping = string | (string | ConditionalMapping)[]; +export type ConditionalMapping = { + [k: string]: MappingValue; +}; +export type MappingValue = ConditionalMapping | DirectMapping | null; +export type ExportsField = + Record | ConditionalMapping | DirectMapping; +export type ImportsField = Record; +/** + * Processing exports/imports field + */ +export type FieldProcessor = ( + request: string, + conditionNames: Set, +) => [string[], string | null]; +export type RecordMapping = Record; +/** + * Per-key precomputed info used by `findMatch`. Equivalent to what the + * previous implementation recomputed inline on every resolve. + */ +export type FieldKeyInfo = { + /** + * the original key + */ + key: string; + /** + * position of the single "*" in the key, or -1 when absent + */ + patternIndex: number; + /** + * substring before "*" (empty when patternIndex === -1) + */ + wildcardPrefix: string; + /** + * substring after "*" (empty when patternIndex === -1) + */ + wildcardSuffix: string; + /** + * true when key is a legacy `./foo/`-style folder key with no "*" + */ + isLegacySubpath: boolean; + /** + * true when key contains "*" + */ + isPattern: boolean; + /** + * true when key ends with "/" + */ + isSubpathMapping: boolean; + /** + * true when key has at most one "*" + */ + isValidPattern: boolean; +}; +export type MatchTuple = + [MappingValue, string, boolean, boolean, string] | null; diff --git a/types/util/fileURLToPath.d.ts b/types/util/fileURLToPath.d.ts new file mode 100644 index 00000000..a217605c --- /dev/null +++ b/types/util/fileURLToPath.d.ts @@ -0,0 +1,14 @@ +export = fileURLToPath; +/** + * @param {string | URL} path a `file:` URL string or `URL` instance + * @param {{ windows?: boolean }=} options force the platform branch + * @returns {string} the filesystem path + */ +declare function fileURLToPath( + path: string | URL, + options?: + | { + windows?: boolean; + } + | undefined, +): string; diff --git a/types/util/fs.d.ts b/types/util/fs.d.ts new file mode 100644 index 00000000..b191ce2a --- /dev/null +++ b/types/util/fs.d.ts @@ -0,0 +1,38 @@ +export type FileSystem = import("../Resolver").FileSystem; +export type JsonObject = import("../Resolver").JsonObject; +export type ReadJsonOptions = { + /** + * Whether to strip JSONC comments + */ + stripComments?: boolean | undefined; +}; +/** + * Decode a file's raw contents to text without assuming a Node runtime. A + * `Buffer` (Node) uses its fast native `toString`; any other binary input + * (`Uint8Array` from a browser/Deno/Bun file system) goes through + * `TextDecoder`, and strings are returned as-is. + * @param {string | Buffer | Uint8Array} data raw file contents + * @returns {string} decoded text + */ +export function decodeText(data: string | Buffer | Uint8Array): string; +/** + * Read and parse JSON file (supports JSONC with comments). + * Callback-based so a synchronous `fileSystem` stays synchronous all the + * way through — Promise wrapping would defer resolution by a Promise tick + * and break `resolveSync` when `tsconfig` is used together with + * `useSyncFileSystemCalls: true`. + * @param {FileSystem} fileSystem the file system + * @param {string} jsonFilePath absolute path to JSON file + * @param {ReadJsonOptions} options Options + * @param {(err: NodeJS.ErrnoException | Error | null, content?: JsonObject) => void} callback callback + * @returns {void} + */ +export function readJson( + fileSystem: FileSystem, + jsonFilePath: string, + options: ReadJsonOptions, + callback: ( + err: NodeJS.ErrnoException | Error | null, + content?: JsonObject, + ) => void, +): void; diff --git a/types/util/graceful-fs-browser.d.ts b/types/util/graceful-fs-browser.d.ts new file mode 100644 index 00000000..a8ee8eb8 --- /dev/null +++ b/types/util/graceful-fs-browser.d.ts @@ -0,0 +1,22 @@ +/** + * Takes the arguments its callers pass - `readFile(path, callback)` and the + * rest - so the declaration describes a call that actually compiles, even + * though every one of them throws. + * @param {...unknown} _args arguments, ignored + * @returns {never} always throws + */ +declare function unavailable(..._args: unknown[]): never; +export { + unavailable as lstat, + unavailable as lstatSync, + unavailable as readFile, + unavailable as readFileSync, + unavailable as readdir, + unavailable as readdirSync, + unavailable as readlink, + unavailable as readlinkSync, + unavailable as realpath, + unavailable as realpathSync, + unavailable as stat, + unavailable as statSync, +}; diff --git a/types/util/identifier.d.ts b/types/util/identifier.d.ts new file mode 100644 index 00000000..99644890 --- /dev/null +++ b/types/util/identifier.d.ts @@ -0,0 +1,7 @@ +/** + * @param {string} identifier identifier + * @returns {[string, string, string] | null} parsed identifier + */ +export function parseIdentifier( + identifier: string, +): [string, string, string] | null; diff --git a/types/util/memoize.d.ts b/types/util/memoize.d.ts new file mode 100644 index 00000000..4ada2d11 --- /dev/null +++ b/types/util/memoize.d.ts @@ -0,0 +1,15 @@ +export = memoize; +/** + * @template T + * @typedef {() => T} FunctionReturning + */ +/** + * @template T + * @param {FunctionReturning} fn memorized function + * @returns {FunctionReturning} new function + */ +declare function memoize(fn: FunctionReturning): FunctionReturning; +declare namespace memoize { + export { FunctionReturning }; +} +type FunctionReturning = () => T; diff --git a/types/util/module-browser.d.ts b/types/util/module-browser.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/types/util/module-browser.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/types/util/packageMap.d.ts b/types/util/packageMap.d.ts new file mode 100644 index 00000000..deca530c --- /dev/null +++ b/types/util/packageMap.d.ts @@ -0,0 +1,118 @@ +export type JsonObject = import("../Resolver").JsonObject; +export type PackageMapDependencies = { + [specifier: string]: string; +}; +/** + * A single entry of the configuration file's `packages` object. + */ +export type PackageMapPackage = { + /** + * an absolute or relative `file:` URL, resolved against the configuration file + */ + url: string; + /** + * bare specifier to package id + */ + dependencies?: PackageMapDependencies | undefined; +}; +export type PackageMapPackages = { + [id: string]: PackageMapPackage; +}; +/** + * The parsed contents of a package map configuration file. + */ +export type PackageMapJson = { + /** + * package entries by package id + */ + packages: PackageMapPackages; +}; +export type PackageMapEntry = { + /** + * the package id this entry is keyed by + */ + id: string; + /** + * absolute filesystem path the entry's `url` points at + */ + path: string; + /** + * bare specifier to package id + */ + dependencies: Map; +}; +export type PackageMap = { + /** + * entries by package id + */ + packages: Map; + /** + * package ids by location, longest path first + */ + locations: { + path: string; + ids: string[]; + }[]; +}; +/** @typedef {import("../Resolver").JsonObject} JsonObject */ +/** @typedef {{ [specifier: string]: string }} PackageMapDependencies */ +/** + * A single entry of the configuration file's `packages` object. + * @typedef {object} PackageMapPackage + * @property {string} url an absolute or relative `file:` URL, resolved against the configuration file + * @property {PackageMapDependencies=} dependencies bare specifier to package id + */ +/** @typedef {{ [id: string]: PackageMapPackage }} PackageMapPackages */ +/** + * The parsed contents of a package map configuration file. + * @typedef {object} PackageMapJson + * @property {PackageMapPackages} packages package entries by package id + */ +/** + * @typedef {object} PackageMapEntry + * @property {string} id the package id this entry is keyed by + * @property {string} path absolute filesystem path the entry's `url` points at + * @property {Map} dependencies bare specifier to package id + */ +/** + * @typedef {object} PackageMap + * @property {Map} packages entries by package id + * @property {{ path: string, ids: string[] }[]} locations package ids by location, longest path first + */ +/** + * @param {string} message message + * @param {string} code error code + * @returns {Error & { code: string }} the error + */ +export function createError( + message: string, + code: string, +): Error & { + code: string; +}; +/** + * Find the package ids whose location contains `filePath`. More than one id is + * returned when several package entries share the same `url`, which the caller + * has to disambiguate with an explicit package id. + * @param {PackageMap} packageMap the package map + * @param {string} filePath an absolute filesystem path + * @returns {string[]} the matching package ids, empty when the path is outside every package + */ +export function findPackageIds( + packageMap: PackageMap, + filePath: string, +): string[]; +/** + * Parse and validate a package map configuration file. + * + * Dangling dependency targets are rejected here rather than at resolution + * time: the map is static, so a broken table is a configuration error that is + * better surfaced once and in full. + * @param {JsonObject} data the parsed configuration file contents + * @param {string} configFilePath absolute path of the configuration file, used as the base for relative urls + * @returns {PackageMap} the parsed package map + */ +export function parsePackageMap( + data: JsonObject, + configFilePath: string, +): PackageMap; diff --git a/types/util/path-browser.d.ts b/types/util/path-browser.d.ts new file mode 100644 index 00000000..05a5d220 --- /dev/null +++ b/types/util/path-browser.d.ts @@ -0,0 +1,45 @@ +/** + * Posix `basename` — the browser is treated as a posix platform, matching how + * Node picks the posix variant for `path.basename` on non-Windows systems. + * @param {string} path path + * @param {string=} suffix optional suffix to strip + * @returns {string} basename + */ +export function basename(path: string, suffix?: string | undefined): string; +/** + * @param {string} path path + * @returns {string} normalized posix path + */ +declare function posixNormalize(path: string): string; +/** + * @param {string} path path + * @returns {string} posix dirname + */ +declare function posixDirname(path: string): string; +/** + * Normalizes drive paths (`C:\…`), UNC paths (`\\server\share\…`), DOS device + * paths (`\\.\…`, `\\?\…`) and relative/normal segments like Node's + * `path.win32.normalize`, including the CVE-2024-36139 colon-segment guard. + * + * Scope note: reserved Windows device names (`CON`, `COM1`, `LPT1`, …) are not + * special-cased, so e.g. `\\.\COM1:` differs from Node. Such names cannot occur + * in a browser (the only place this shim is used) and the resolver never routes + * them to `win32.normalize`, so this does not affect resolution. + * @param {string} path path + * @returns {string} normalized win32 path + */ +declare function win32Normalize(path: string): string; +/** + * @param {string} path path + * @returns {string} win32 dirname + */ +declare function win32Dirname(path: string): string; +export declare namespace posix { + export { posixNormalize as normalize }; + export { posixDirname as dirname }; +} +export declare namespace win32 { + export { win32Normalize as normalize }; + export { win32Dirname as dirname }; +} +export {}; diff --git a/types/util/path.d.ts b/types/util/path.d.ts new file mode 100644 index 00000000..572770b9 --- /dev/null +++ b/types/util/path.d.ts @@ -0,0 +1,125 @@ +export type CachedJoin = { + fn: (rootPath: string, request: string) => string; + cache: Map>; +}; +export type CachedDirname = { + fn: (maybePath: string) => string; + cache: Map; +}; +export type CachedBasename = { + fn: (maybePath: string, suffix?: string) => string; + cache: Map>; +}; +export type PathType = number; +/** + * @enum {number} + */ +export const PathType: Readonly<{ + Empty: 0; + Normal: 1; + Relative: 2; + AbsoluteWin: 3; + AbsolutePosix: 4; + Internal: 5; +}>; +/** @typedef {{ fn: (maybePath: string, suffix?: string) => string, cache: Map> }} CachedBasename */ +/** + * @returns {CachedBasename} cached basename + */ +export function createCachedBasename(): CachedBasename; +/** @typedef {{ fn: (maybePath: string) => string, cache: Map }} CachedDirname */ +/** + * @returns {CachedDirname} cached dirname + */ +export function createCachedDirname(): CachedDirname; +/** @typedef {{ fn: (rootPath: string, request: string) => string, cache: Map> }} CachedJoin */ +/** + * @returns {CachedJoin} cached join + */ +export function createCachedJoin(): CachedJoin; +export const deprecatedInvalidSegmentRegEx: RegExp; +/** + * @param {string} maybePath a path + * @returns {string} the directory name + */ +export function dirname(maybePath: string): string; +/** + * @param {string} maybePath a path + * @returns {PathType} type of path + */ +export function getType(maybePath: string): PathType; +export const invalidSegmentRegEx: RegExp; +/** + * Whether a string names a `file:` URL rather than a path. The scheme has to + * open the string and be followed by a slash, as Node's own URL parser needs, + * so a path segment spelled `file:` stays a path and `file:x.js` — which Node + * reads as `/x.js` — stays the relative request it looks like. + * @param {string} maybePath a path or a `file:` URL string + * @returns {boolean} true when the string is a `file:` URL + */ +export function isFileURL(maybePath: string): boolean; +/** + * Whether childPath is parentPath itself or a path under it, the answer node's + * `relative(parentPath, childPath)` gives: not escaping upward and not + * absolute. A trailing separator on the parent is not part of the boundary, so + * `/a/b/` contains exactly what `/a/b` contains. + * @param {string} parentPath parent directory path + * @param {string} childPath child path to check + * @returns {boolean} true if childPath is parentPath or is under it + */ +export function isInside(parentPath: string, childPath: string): boolean; +/** + * Whether `request` is a relative request — i.e. matches `^\.\.?(?:\/|$)`. + * + * This is called on every `doResolve` via `UnsafeCachePlugin` and + * `getInnerRequest`, so the char-code form is meaningfully faster than the + * equivalent regex test: no regex state machine, no string object churn. + * @param {string} request request string + * @returns {boolean} true if request is relative + */ +export function isRelativeRequest(request: string): boolean; +/** + * Check if childPath is a subdirectory of parentPath. Compares like `isInside`, + * except that a path is not a subpath of itself. + * + * Called from `TsconfigPathsPlugin._selectPathsDataForContext` inside a loop + * over every tsconfig-paths context on every resolve, so it's worth keeping + * cheap: a native `startsWith` plus a separator char check answers it, and the + * character loop only runs for a Windows path that the prefix test missed. + * @param {string} parentPath parent directory path + * @param {string} childPath child path to check + * @returns {boolean} true if childPath is under parentPath + */ +export function isSubPath(parentPath: string, childPath: string): boolean; +/** + * Whether this is a Windows path, in which `/` and `\` are interchangeable and + * paths compare case-insensitively, as opposed to a posix path, in which `\` is + * an ordinary filename character. Decided by the root — a drive letter or a + * leading `\` — which is where `path.win32` and `path.posix` disagree about + * `parse(maybePath).root`, and never by the host platform, since Windows paths + * are resolved on posix hosts and in browsers too. A path starting with `//` + * stays posix: `path.win32` reads it as a UNC root, but here it cannot be told + * apart from a posix path, where `\` has to keep being a filename character. + * @param {string} maybePath a path + * @returns {boolean} true, when the path is a Windows path + */ +export function isWindowsPath(maybePath: string): boolean; +/** + * @param {string} rootPath the root path + * @param {string | undefined} request the request path + * @returns {string} the joined path + */ +export function join(rootPath: string, request: string | undefined): string; +/** + * @param {string} maybePath a path + * @returns {string} the normalized path + */ +export function normalize(maybePath: string): string; +/** + * Convert a `file:` URL — a `URL` instance or a `file:/` string, the form + * `import.meta.resolve` returns — to the path it names. Anything else is + * returned unchanged, so a path passes through. + * @param {string | URL} maybeURL a path, a `file:` URL string or a `file:` `URL` instance + * @returns {string} a filesystem path + */ +export function toPath(maybeURL: string | URL): string; diff --git a/types/util/pathToFileURL.d.ts b/types/util/pathToFileURL.d.ts new file mode 100644 index 00000000..a12d55e3 --- /dev/null +++ b/types/util/pathToFileURL.d.ts @@ -0,0 +1,14 @@ +export = pathToFileURL; +/** + * @param {string} filepath an absolute filesystem path + * @param {{ windows?: boolean }=} options force the platform branch + * @returns {URL} the `file:` URL + */ +declare function pathToFileURL( + filepath: string, + options?: + | { + windows?: boolean; + } + | undefined, +): URL; diff --git a/types/util/process-browser.d.ts b/types/util/process-browser.d.ts new file mode 100644 index 00000000..11b331b1 --- /dev/null +++ b/types/util/process-browser.d.ts @@ -0,0 +1,3 @@ +export let versions: Record; +/** @param {Function} fn function */ +export function nextTick(fn: Function, ...args: any[]): void; diff --git a/types/util/strip-json-comments.d.ts b/types/util/strip-json-comments.d.ts new file mode 100644 index 00000000..cef87e3f --- /dev/null +++ b/types/util/strip-json-comments.d.ts @@ -0,0 +1,24 @@ +export = stripJsonComments; +/** + * Strip comments from JSON string + * @param {string} jsonString JSON string with potential comments + * @param {StripJsonCommentsOptions} options Options + * @returns {string} JSON string without comments + */ +declare function stripJsonComments( + jsonString: string, + { whitespace, trailingCommas }?: StripJsonCommentsOptions, +): string; +declare namespace stripJsonComments { + export { StripJsonCommentsOptions }; +} +type StripJsonCommentsOptions = { + /** + * Replace comments with whitespace + */ + whitespace?: boolean | undefined; + /** + * Strip trailing commas + */ + trailingCommas?: boolean | undefined; +}; diff --git a/types/util/url-browser.d.ts b/types/util/url-browser.d.ts new file mode 100644 index 00000000..9af30a4e --- /dev/null +++ b/types/util/url-browser.d.ts @@ -0,0 +1 @@ +export let fileURLToPath: typeof import("./fileURLToPath");