From 9ae23b2ca2a20444492eeda84b264464e1257ad3 Mon Sep 17 00:00:00 2001 From: Kristoffer K Date: Tue, 31 Jan 2023 21:34:18 +0100 Subject: [PATCH] feat(pnp): support the `--conditions` flag (#5228) * feat(pnp): support the `--conditions` flag * test: check `NODE_OPTIONS` works --- .eslintignore | 1 + .pnp.cjs | 8 ++ .../arg-npm-5.0.2-2f5805a547-6c69ada1a9.zip | Bin 0 -> 6633 bytes .yarn/versions/e4478040.yml | 27 ++++ .../pkg-tests-specs/sources/pnp.test.js | 56 ++++++++ packages/yarnpkg-pnp/package.json | 1 + .../yarnpkg-pnp/sources/loader/makeApi.ts | 10 +- .../sources/loader/node-options.d.ts | 1 + .../sources/loader/node-options.js | 134 ++++++++++++++++++ scripts/setup-ts-execution.js | 6 +- yarn.lock | 8 ++ 11 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 .yarn/cache/arg-npm-5.0.2-2f5805a547-6c69ada1a9.zip create mode 100644 .yarn/versions/e4478040.yml create mode 100644 packages/yarnpkg-pnp/sources/loader/node-options.d.ts create mode 100644 packages/yarnpkg-pnp/sources/loader/node-options.js diff --git a/.eslintignore b/.eslintignore index cd1f22758713..705a10df9331 100644 --- a/.eslintignore +++ b/.eslintignore @@ -24,3 +24,4 @@ # Minimize the diff with upstream packages/yarnpkg-pnp/sources/node/** +packages/yarnpkg-pnp/sources/loader/node-options* diff --git a/.pnp.cjs b/.pnp.cjs index 044700bfa056..1399f189d07f 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -15347,6 +15347,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@types/node", "npm:13.7.0"],\ ["@yarnpkg/fslib", "workspace:packages/yarnpkg-fslib"],\ ["@yarnpkg/libzip", "workspace:packages/yarnpkg-libzip"],\ + ["arg", "npm:5.0.2"],\ ["esbuild", [\ "esbuild-wasm",\ "npm:0.15.6"\ @@ -15966,6 +15967,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["arg", "npm:4.1.3"]\ ],\ "linkType": "HARD"\ + }],\ + ["npm:5.0.2", {\ + "packageLocation": "./.yarn/cache/arg-npm-5.0.2-2f5805a547-6c69ada1a9.zip/node_modules/arg/",\ + "packageDependencies": [\ + ["arg", "npm:5.0.2"]\ + ],\ + "linkType": "HARD"\ }]\ ]],\ ["argparse", [\ diff --git a/.yarn/cache/arg-npm-5.0.2-2f5805a547-6c69ada1a9.zip b/.yarn/cache/arg-npm-5.0.2-2f5805a547-6c69ada1a9.zip new file mode 100644 index 0000000000000000000000000000000000000000..1ffd22e8fbed992202b1ac2e0e5083302d5eedd9 GIT binary patch literal 6633 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 literal 0 HcmV?d00001 diff --git a/.yarn/versions/e4478040.yml b/.yarn/versions/e4478040.yml new file mode 100644 index 000000000000..24420b4989da --- /dev/null +++ b/.yarn/versions/e4478040.yml @@ -0,0 +1,27 @@ +releases: + "@yarnpkg/cli": patch + "@yarnpkg/plugin-pnp": patch + "@yarnpkg/pnp": minor + +declined: + - "@yarnpkg/plugin-compat" + - "@yarnpkg/plugin-constraints" + - "@yarnpkg/plugin-dlx" + - "@yarnpkg/plugin-essentials" + - "@yarnpkg/plugin-init" + - "@yarnpkg/plugin-interactive-tools" + - "@yarnpkg/plugin-nm" + - "@yarnpkg/plugin-npm-cli" + - "@yarnpkg/plugin-pack" + - "@yarnpkg/plugin-patch" + - "@yarnpkg/plugin-pnpm" + - "@yarnpkg/plugin-stage" + - "@yarnpkg/plugin-typescript" + - "@yarnpkg/plugin-version" + - "@yarnpkg/plugin-workspace-tools" + - "@yarnpkg/builder" + - "@yarnpkg/core" + - "@yarnpkg/doctor" + - "@yarnpkg/nm" + - "@yarnpkg/pnpify" + - "@yarnpkg/sdks" diff --git a/packages/acceptance-tests/pkg-tests-specs/sources/pnp.test.js b/packages/acceptance-tests/pkg-tests-specs/sources/pnp.test.js index 8d95fc8b40c5..a6e3f622db31 100644 --- a/packages/acceptance-tests/pkg-tests-specs/sources/pnp.test.js +++ b/packages/acceptance-tests/pkg-tests-specs/sources/pnp.test.js @@ -2126,4 +2126,60 @@ describe(`Plug'n'Play`, () => { }, ), ); + + test( + `it should respect user provided conditions`, + makeTemporaryEnv( + { + imports: { + '#foo': { + custom: `./custom.js`, + default: `./404.js`, + }, + }, + }, + async ({path, run, source}) => { + await expect(run(`install`)).resolves.toMatchObject({code: 0}); + + await xfs.writeFilePromise(ppath.join(path, `custom.js`), `console.log('foo')`); + await xfs.writeFilePromise(ppath.join(path, `index.js`), `require('#foo')`); + + await expect(run(`node`, `--conditions`, `custom`, `./index.js`)).resolves.toMatchObject({ + code: 0, + stdout: `foo\n`, + stderr: ``, + }); + + await expect(run(`node`, `-C`, `custom`, `./index.js`)).resolves.toMatchObject({ + code: 0, + stdout: `foo\n`, + stderr: ``, + }); + + await expect( + run(`node`, `./index.js`, { + env: { + NODE_OPTIONS: `--conditions custom`, + }, + }), + ).resolves.toMatchObject({ + code: 0, + stdout: `foo\n`, + stderr: ``, + }); + + await expect( + run(`node`, `./index.js`, { + env: { + NODE_OPTIONS: `-C custom`, + }, + }), + ).resolves.toMatchObject({ + code: 0, + stdout: `foo\n`, + stderr: ``, + }); + }, + ), + ); }); diff --git a/packages/yarnpkg-pnp/package.json b/packages/yarnpkg-pnp/package.json index a11255623c77..32cc1b2923df 100644 --- a/packages/yarnpkg-pnp/package.json +++ b/packages/yarnpkg-pnp/package.json @@ -11,6 +11,7 @@ "@rollup/plugin-commonjs": "^21.0.1", "@rollup/plugin-node-resolve": "^11.0.1", "@yarnpkg/libzip": "workspace:^", + "arg": "^5.0.2", "esbuild": "npm:esbuild-wasm@^0.15.5", "resolve.exports": "^1.1.0", "rollup": "^2.59.0", diff --git a/packages/yarnpkg-pnp/sources/loader/makeApi.ts b/packages/yarnpkg-pnp/sources/loader/makeApi.ts index 1b82c4dd5608..c2c3a73380db 100644 --- a/packages/yarnpkg-pnp/sources/loader/makeApi.ts +++ b/packages/yarnpkg-pnp/sources/loader/makeApi.ts @@ -9,6 +9,7 @@ import {packageImportsResolve} import {PackageInformation, PackageLocator, PnpApi, RuntimeState, PhysicalPackageLocator, DependencyTarget, ResolveToUnqualifiedOptions, ResolveUnqualifiedOptions, ResolveRequestOptions} from '../types'; import {ErrorCode, makeError, getPathForDisplay} from './internalTools'; +import {getOptionValue} from './node-options.js'; import * as nodeUtils from './nodeUtils'; export type MakeApiOptions = { @@ -193,7 +194,12 @@ export function makeApi(runtimeState: RuntimeState, opts: MakeApiOptions): PnpAp return false; } - const defaultExportsConditions = new Set([`default`, `node`, `require`]); + const defaultExportsConditions = new Set([ + `default`, + `node`, + `require`, + ...getOptionValue(`--conditions`), + ]); /** * Implements the node resolution for the "exports" field @@ -234,8 +240,6 @@ export function makeApi(runtimeState: RuntimeState, opts: MakeApiOptions): PnpAp let resolvedExport; try { resolvedExport = resolveExport(pkgJson, ppath.normalize(subpath), { - // TODO: implement support for the --conditions flag - // Waiting on https://github.com/nodejs/node/issues/36935 // @ts-expect-error - Type should be Iterable conditions, unsafe: true, diff --git a/packages/yarnpkg-pnp/sources/loader/node-options.d.ts b/packages/yarnpkg-pnp/sources/loader/node-options.d.ts new file mode 100644 index 000000000000..f6d0203ae686 --- /dev/null +++ b/packages/yarnpkg-pnp/sources/loader/node-options.d.ts @@ -0,0 +1 @@ +export function getOptionValue(key: '--conditions'): string[] diff --git a/packages/yarnpkg-pnp/sources/loader/node-options.js b/packages/yarnpkg-pnp/sources/loader/node-options.js new file mode 100644 index 000000000000..33f5a4a2fe4f --- /dev/null +++ b/packages/yarnpkg-pnp/sources/loader/node-options.js @@ -0,0 +1,134 @@ +// Adapted from https://github.com/TypeStrong/ts-node/blob/97f9afd046b66a0fe05a7d76e7a32f94b872016f/dist-raw/node-options.js +// which has the following license: + +/** + @license + The MIT License (MIT) + + Copyright (c) 2014 Blake Embrey (hello@blakeembrey.com) + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +// It adapts code from Node.js with the following license: + +/** + @license + Copyright Joyent, Inc. and other Node contributors. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +// Replacement for node's internal 'internal/options' module + +import arg from 'arg'; + +export function getOptionValue(opt) { + parseOptions(); + return options[opt]; +} + +let options; +function parseOptions() { + if (!options) { + options = { + '--conditions': [], + ...parseArgv(getNodeOptionsEnvArgv()), + ...parseArgv(process.execArgv), + }; + } +} + +function parseArgv(argv) { + return arg( + { + '--conditions': [String], + '-C': '--conditions', + }, + { + argv, + permissive: true, + } + ); +} + +function getNodeOptionsEnvArgv() { + const errors = []; + const envArgv = ParseNodeOptionsEnvVar(process.env.NODE_OPTIONS || '', errors); + if (errors.length !== 0) { + // TODO: handle errors somehow + } + return envArgv; +} + +// Direct JS port of C implementation: https://github.com/nodejs/node/blob/67ba825037b4082d5d16f922fb9ce54516b4a869/src/node_options.cc#L1024-L1063 +function ParseNodeOptionsEnvVar(node_options, errors) { + const env_argv = []; + + let is_in_string = false; + let will_start_new_arg = true; + for (let index = 0; index < node_options.length; ++index) { + let c = node_options[index]; + + // Backslashes escape the following character + if (c === '\\' && is_in_string) { + if (index + 1 === node_options.length) { + errors.push('invalid value for NODE_OPTIONS ' + '(invalid escape)\n'); + return env_argv; + } else { + c = node_options[++index]; + } + } else if (c === ' ' && !is_in_string) { + will_start_new_arg = true; + continue; + } else if (c === '"') { + is_in_string = !is_in_string; + continue; + } + + if (will_start_new_arg) { + env_argv.push(c); + will_start_new_arg = false; + } else { + env_argv[env_argv.length - 1] += c; + } + } + + if (is_in_string) { + errors.push('invalid value for NODE_OPTIONS ' + '(unterminated string)\n'); + } + return env_argv; +} diff --git a/scripts/setup-ts-execution.js b/scripts/setup-ts-execution.js index a2bce3cd3548..81a4849ffc59 100644 --- a/scripts/setup-ts-execution.js +++ b/scripts/setup-ts-execution.js @@ -16,8 +16,10 @@ require(`@babel/register`)({ extensions: [`.tsx`, `.ts`, `.js`], only: [ p => { - if (p?.endsWith(`.js`)) - return /packages(\\|\/)yarnpkg-pnp(\\|\/)sources(\\|\/)node/.test(p); + if (p?.endsWith(`.js`)) { + const normalizedP = p.replace(/\\/g, `/`); + return normalizedP.includes(`packages/yarnpkg-pnp/sources/node`) || normalizedP.endsWith(`packages/yarnpkg-pnp/sources/loader/node-options.js`); + } return true; }, diff --git a/yarn.lock b/yarn.lock index 73f484d9a480..55591f17c65a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6300,6 +6300,7 @@ __metadata: "@types/node": ^13.7.0 "@yarnpkg/fslib": "workspace:^" "@yarnpkg/libzip": "workspace:^" + arg: ^5.0.2 esbuild: "npm:esbuild-wasm@^0.15.5" resolve.exports: ^1.1.0 rollup: ^2.59.0 @@ -6813,6 +6814,13 @@ __metadata: languageName: node linkType: hard +"arg@npm:^5.0.2": + version: 5.0.2 + resolution: "arg@npm:5.0.2" + checksum: 6c69ada1a9943d332d9e5382393e897c500908d91d5cb735a01120d5f71daf1b339b7b8980cbeaba8fd1afc68e658a739746179e4315a26e8a28951ff9930078 + languageName: node + linkType: hard + "argparse@npm:^1.0.7": version: 1.0.10 resolution: "argparse@npm:1.0.10"