From e07cc59ec98c4e03576b5992e1140825b1a1a5c4 Mon Sep 17 00:00:00 2001 From: ehmicky Date: Thu, 21 Dec 2023 03:33:47 +0000 Subject: [PATCH] Allow `execPath` to be a file URL (#16) --- index.d.ts | 4 ++-- index.js | 3 ++- index.test-d.ts | 2 ++ readme.md | 2 +- test.js | 9 ++++++++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/index.d.ts b/index.d.ts index fad851b..0c1b160 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,7 +20,7 @@ export interface RunPathOptions { @default process.execPath */ - readonly execPath?: string; + readonly execPath?: string | URL; } export type ProcessEnv = Record; @@ -45,7 +45,7 @@ export interface EnvOptions { @default process.execPath */ - readonly execPath?: string; + readonly execPath?: string | URL; } /** diff --git a/index.js b/index.js index 77dfae2..ee779b8 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,7 @@ export function npmRunPath(options = {}) { } = options; let previous; + const execPathString = execPath instanceof URL ? url.fileURLToPath(execPath) : execPath; const cwdString = cwd instanceof URL ? url.fileURLToPath(cwd) : cwd; let cwdPath = path.resolve(cwdString); const result = []; @@ -22,7 +23,7 @@ export function npmRunPath(options = {}) { } // Ensure the running `node` binary is used. - result.push(path.resolve(cwdString, execPath, '..')); + result.push(path.resolve(cwdString, execPathString, '..')); return [...result, path_].join(path.delimiter); } diff --git a/index.test-d.ts b/index.test-d.ts index cb7c8ae..d977bd9 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -7,9 +7,11 @@ expectType(npmRunPath({cwd: '/foo'})); expectType(npmRunPath({cwd: new URL('file:///foo')})); expectType(npmRunPath({path: '/usr/local/bin'})); expectType(npmRunPath({execPath: '/usr/local/bin'})); +expectType(npmRunPath({execPath: new URL('file:///usr/local/bin')})); expectType(npmRunPathEnv()); expectType(npmRunPathEnv({cwd: '/foo'})); expectType(npmRunPathEnv({cwd: new URL('file:///foo')})); expectType(npmRunPathEnv({env: process.env})); // eslint-disable-line @typescript-eslint/no-unsafe-assignment expectType(npmRunPathEnv({execPath: '/usr/local/bin'})); +expectType(npmRunPathEnv({execPath: new URL('file:///usr/local/bin')})); diff --git a/readme.md b/readme.md index f2ab84b..4a95c24 100644 --- a/readme.md +++ b/readme.md @@ -56,7 +56,7 @@ Set it to an empty string to exclude the default PATH. ##### execPath -Type: `string`\ +Type: `string | URL`\ Default: `process.execPath` The path to the current Node.js executable. Its directory is pushed to the front of PATH. diff --git a/test.js b/test.js index 87a7b01..633a7f3 100644 --- a/test.js +++ b/test.js @@ -1,6 +1,6 @@ import process from 'node:process'; import path from 'node:path'; -import {fileURLToPath} from 'node:url'; +import {fileURLToPath, pathToFileURL} from 'node:url'; import test from 'ava'; import {npmRunPath, npmRunPathEnv} from './index.js'; @@ -44,6 +44,13 @@ test('can change `execPath` with the `execPath` option', t => { t.is(pathEnv[pathEnv.length - 2], path.resolve(process.cwd(), 'test')); }); +test('the `execPath` option can be a file URL', t => { + const pathEnv = npmRunPath({path: '', execPath: pathToFileURL('test/test')}).split( + path.delimiter, + ); + t.is(pathEnv[pathEnv.length - 2], path.resolve(process.cwd(), 'test')); +}); + test('the `execPath` option is relative to the `cwd` option', t => { const pathEnv = npmRunPath({ path: '',