diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d3561550d..456a356572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,11 +27,15 @@ Please add one entry in this file for each change in Yarn's behavior. Use the sa - Fixes an issue with how symlinks are setup into the cache on Windows [#6621](https://github.com/yarnpkg/yarn/pull/6621) - [**Yoad Snapir**](https://github.com/yoadsn) - + - Upgrades `inquirer`, fixing `upgrade-interactive` for users using both Node 10 and Windows [#6635](https://github.com/yarnpkg/yarn/pull/6635) - [**Philipp Feigl**](https://github.com/pfeigl) +- Exposes the path to the PnP file using `require.resolve('pnpapi')` + + [#6643](https://github.com/yarnpkg/yarn/pull/6643) - [**Maƫl Nison**](https://twitter.com/arcanis) + ## 1.12.1 - Ensures the engine check is ran before showing the UI for `upgrade-interactive` diff --git a/packages/pkg-tests/pkg-tests-specs/sources/pnpapi-v1.js b/packages/pkg-tests/pkg-tests-specs/sources/pnpapi-v1.js index e56fb700e8..56a6aba36a 100644 --- a/packages/pkg-tests/pkg-tests-specs/sources/pnpapi-v1.js +++ b/packages/pkg-tests/pkg-tests-specs/sources/pnpapi-v1.js @@ -1,9 +1,10 @@ +const {normalize} = require('path'); const {fs: {writeFile, writeJson}} = require('pkg-tests-core'); module.exports = makeTemporaryEnv => { describe(`Plug'n'Play API (v1)`, () => { test( - `it should expost VERSIONS`, + `it should expose VERSIONS`, makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { await run(`install`); @@ -12,7 +13,7 @@ module.exports = makeTemporaryEnv => { ); test( - `it should expost resolveToUnqualified`, + `it should expose resolveToUnqualified`, makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { await run(`install`); @@ -21,7 +22,7 @@ module.exports = makeTemporaryEnv => { ); test( - `it should expost resolveToUnqualified`, + `it should expose resolveToUnqualified`, makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { await run(`install`); @@ -30,7 +31,7 @@ module.exports = makeTemporaryEnv => { ); test( - `it should expost resolveToUnqualified`, + `it should expose resolveToUnqualified`, makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { await run(`install`); @@ -39,6 +40,17 @@ module.exports = makeTemporaryEnv => { ); describe(`resolveRequest`, () => { + test( + `it should return the path to the PnP file for when 'pnpapi' is requested`, + makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { + await run(`install`); + + await expect(source(`require('pnpapi').resolveRequest('pnpapi', '${path}/')`)).resolves.toEqual( + normalize(`${path}/.pnp.js`), + ); + }), + ); + test( `it should return null for builtins`, makeTemporaryEnv({}, {plugNPlay: true}, async ({path, run, source}) => { diff --git a/src/util/generate-pnp-map-api.tpl.js b/src/util/generate-pnp-map-api.tpl.js index 6b744d13fc..306db98d79 100644 --- a/src/util/generate-pnp-map-api.tpl.js +++ b/src/util/generate-pnp-map-api.tpl.js @@ -13,6 +13,7 @@ const StringDecoder = require('string_decoder'); const ignorePattern = $$BLACKLIST ? new RegExp($$BLACKLIST) : null; +const pnpFile = path.resolve(__dirname, __filename); const builtinModules = new Set(Module.builtinModules || Object.keys(process.binding('natives'))); const topLevelLocator = {name: null, reference: null}; @@ -313,6 +314,12 @@ exports.getPackageInformation = function getPackageInformation({name, reference} */ exports.resolveToUnqualified = function resolveToUnqualified(request, issuer, {considerBuiltins = true} = {}) { + // The 'pnpapi' request is reserved and will always return the path to the PnP file, from everywhere + + if (request === `pnpapi`) { + return pnpFile; + } + // Bailout if the request is a native module if (considerBuiltins && builtinModules.has(request)) {