refactor(config): stop shelling out to npm for auth settings (#11146)

* refactor(config): stop shelling out to npm for auth settings

Read and write auth-related settings (registry, tokens, credentials,
scoped registries) directly to INI config files instead of delegating
to `npm config`. Removes the @pnpm/exec.run-npm dependency from
@pnpm/config.commands.

* fix(config): give pnpm global rc priority over ~/.npmrc for auth settings

Auth settings from the pnpm global rc file (e.g. ~/.config/pnpm/rc) now
override ~/.npmrc in rawConfig. This ensures tokens written by `pnpm login`
are correctly picked up by `pnpm publish`, since login writes to the pnpm
global rc but ~/.npmrc previously took priority in the npm-conf chain.

* chore: remove @pnpm/exec.run-npm package

No longer used after removing npm config CLI delegation.

* chore: remove accidentally committed __typecheck__/tsconfig.json

* fix(config): narrow non-string rejection to credential keys, add priority test

Non-string value rejection now only applies to credential keys (_auth,
_authToken, _password, username), registry URLs, and scoped/registry-
prefixed keys — not to INI settings like strict-ssl, proxy, or ca that
can legitimately have boolean/null values.

Added a test verifying that auth tokens from the pnpm global rc take
priority over ~/.npmrc.
This commit is contained in:
Zoltan Kochan
2026-03-29 23:28:23 +02:00
committed by GitHub
parent 13e157ddb2
commit 2df8b71467
20 changed files with 295 additions and 387 deletions

View File

@@ -0,0 +1,9 @@
---
"@pnpm/config.commands": minor
"@pnpm/config.reader": patch
"pnpm": minor
---
`pnpm config get/set/delete` no longer shells out to `npm config` for auth-related settings. Auth settings (registry, tokens, credentials, scoped registries) are now read from and written to the INI config files directly.
Auth settings from the pnpm global rc file (`~/.config/pnpm/rc`) now take priority over `~/.npmrc`, so tokens written by `pnpm login` are correctly picked up by `pnpm publish`.

View File

@@ -36,7 +36,6 @@
"@pnpm/config.reader": "workspace:*",
"@pnpm/constants": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/exec.run-npm": "workspace:*",
"@pnpm/object.key-sorting": "workspace:*",
"@pnpm/object.property-path": "workspace:*",
"@pnpm/text.naming-cases": "workspace:*",

View File

@@ -5,7 +5,6 @@ export type ConfigCommandOptions = Pick<Config,
| 'cliOptions'
| 'dir'
| 'global'
| 'npmPath'
| 'rawConfig'
| 'workspaceDir'
> & {

View File

@@ -1,7 +1,4 @@
import path from 'node:path'
import { types } from '@pnpm/config.reader'
import { runNpm } from '@pnpm/exec.run-npm'
import { isIniConfigKey, types } from '@pnpm/config.reader'
import { getObjectValueByPropertyPath } from '@pnpm/object.property-path'
import { isCamelCase, isStrictlyKebabCase } from '@pnpm/text.naming-cases'
import kebabCase from 'lodash.kebabcase'
@@ -9,19 +6,9 @@ import kebabCase from 'lodash.kebabcase'
import type { ConfigCommandOptions } from './ConfigCommandOptions.js'
import { parseConfigPropertyPath } from './parseConfigPropertyPath.js'
import { processConfig } from './processConfig.js'
import { settingShouldFallBackToNpm } from './settingShouldFallBackToNpm.js'
export function configGet (opts: ConfigCommandOptions, key: string): { output: string, exitCode: number } {
const isScopedKey = key.startsWith('@')
// Exclude scoped keys from npm fallback because they are pnpm-native config
// that can be read directly from rawConfig (e.g., '@scope:registry')
if (opts.global && settingShouldFallBackToNpm(key) && !isScopedKey) {
const { status: exitCode } = runNpm(opts.npmPath, ['config', 'get', key], {
location: 'user',
userConfigPath: path.join(opts.configDir, 'rc'),
})
return { output: '', exitCode: exitCode ?? 0 }
}
const configResult = getRcConfig(opts.rawConfig, key, isScopedKey) ?? getConfigByPropertyPath(opts.rawConfig, key)
const output = displayConfig(configResult?.value, opts)
return { output, exitCode: 0 }
@@ -45,6 +32,10 @@ function getRcConfig (rawConfig: Record<string, unknown>, key: string, isScopedK
const value = rawConfig[key]
return { value }
}
if (isIniConfigKey(key)) {
const value = rawConfig[key]
return { value }
}
return undefined
}

View File

@@ -1,10 +1,9 @@
import path from 'node:path'
import util from 'node:util'
import { type ConfigFileKey, isConfigFileKey, types } from '@pnpm/config.reader'
import { type ConfigFileKey, isConfigFileKey, isIniConfigKey, types } from '@pnpm/config.reader'
import { GLOBAL_CONFIG_YAML_FILENAME, WORKSPACE_MANIFEST_FILENAME } from '@pnpm/constants'
import { PnpmError } from '@pnpm/error'
import { runNpm, type RunNPMOptions } from '@pnpm/exec.run-npm'
import { parsePropertyPath } from '@pnpm/object.property-path'
import { isCamelCase, isStrictlyKebabCase } from '@pnpm/text.naming-cases'
import { updateWorkspaceManifest } from '@pnpm/workspace.workspace-manifest-writer'
@@ -15,48 +14,34 @@ import { writeIniFile } from 'write-ini-file'
import type { ConfigCommandOptions } from './ConfigCommandOptions.js'
import { getConfigFileInfo } from './getConfigFileInfo.js'
import { settingShouldFallBackToNpm } from './settingShouldFallBackToNpm.js'
export async function configSet (opts: ConfigCommandOptions, key: string, valueParam: string | null): Promise<void> {
let shouldFallbackToNpm = settingShouldFallBackToNpm(key)
if (!shouldFallbackToNpm) {
let isAuthSetting = isIniConfigKey(key)
if (!isAuthSetting) {
key = validateSimpleKey(key)
shouldFallbackToNpm = settingShouldFallBackToNpm(key)
isAuthSetting = isIniConfigKey(key)
}
let value: unknown = valueParam
if (valueParam != null && opts.json) {
value = JSON.parse(valueParam)
}
if (shouldFallbackToNpm) {
if (opts.global) {
const configPath = path.join(opts.configDir, 'rc')
const runNpmOpts: RunNPMOptions = {
location: 'user',
userConfigPath: configPath,
}
const _runNpm = runNpm.bind(null, opts.npmPath)
if (value == null) {
_runNpm(['config', 'delete', key], runNpmOpts)
return
}
if (typeof value === 'string') {
_runNpm(['config', 'set', `${key}=${value}`], runNpmOpts)
return
}
if (isAuthSetting) {
const configPath = opts.global
? path.join(opts.configDir, 'rc')
: path.join(opts.dir, '.npmrc')
if (value != null && typeof value !== 'string' && isStringOnlyIniKey(key)) {
throw new PnpmError('CONFIG_SET_AUTH_NON_STRING', `Cannot set ${key} to a non-string value (${JSON.stringify(value)})`)
} else {
const configPath = path.join(opts.dir, '.npmrc')
const settings = await safeReadIniFile(configPath)
if (value == null) {
if (settings[key] == null) return
delete settings[key]
} else {
settings[key] = value
}
await writeIniFile(configPath, settings)
return
}
const settings = await safeReadIniFile(configPath)
if (value == null) {
if (settings[key] == null) return
delete settings[key]
} else {
settings[key] = value
}
await writeIniFile(configPath, settings)
return
}
const { configDir, configFileName } = getConfigFileInfo(key, opts)
@@ -214,6 +199,15 @@ function validateWorkspaceKey (key: string): string {
return key
}
const STRING_ONLY_INI_KEYS = ['_auth', '_authToken', '_password', 'username', 'registry']
function isStringOnlyIniKey (key: string): boolean {
if (STRING_ONLY_INI_KEYS.includes(key)) return true
if (key.startsWith('@')) return true
if (key.startsWith('//')) return true
return false
}
async function safeReadIniFile (configPath: string): Promise<Record<string, unknown>> {
try {
return await readIniFile(configPath) as Record<string, unknown>

View File

@@ -1,10 +0,0 @@
// NOTE: The logic may be duplicated with `isIniConfigKey` from `@pnpm/config.reader`,
// but we have not the time to refactor it right now.
// TODO: Refactor it when we have the time.
export function settingShouldFallBackToNpm (key: string): boolean {
return (
['registry', '_auth', '_authToken', 'username', '_password'].includes(key) ||
key[0] === '@' ||
key.startsWith('//')
)
}

View File

@@ -40,7 +40,7 @@ test('config delete on registry key set', async () => {
rawConfig: {},
}, ['delete', 'registry'])
expect(fs.readdirSync(configDir)).not.toContain('rc')
expect(readIniFileSync(path.join(configDir, 'rc'))).toEqual({})
})
test('config delete on npm-compatible key not set', async () => {

View File

@@ -1,11 +1,9 @@
import { jest } from '@jest/globals'
import path from 'node:path'
jest.unstable_mockModule('@pnpm/exec.run-npm', () => ({
runNpm: jest.fn(),
}))
import { config } from '@pnpm/config.commands'
import { tempDir } from '@pnpm/prepare'
const { config } = await import('@pnpm/config.commands')
const { runNpm } = await import('@pnpm/exec.run-npm')
import { type ConfigFilesData, readConfigFiles, writeConfigFiles } from './utils/index.js'
describe.each(
[
@@ -14,54 +12,165 @@ describe.each(
'_password',
'username',
'registry',
'@foo:registry',
'//registry.npmjs.org/:_authToken',
]
)('settings related to auth are handled by npm CLI', (key) => {
describe('without --json', () => {
const configOpts = {
dir: process.cwd(),
cliOptions: {},
configDir: import.meta.dirname, // this doesn't matter, it won't be used
rawConfig: {},
}
)('auth settings are written to the rc file directly', (key) => {
describe('global (without --json)', () => {
it(`should set ${key}`, async () => {
await config.handler(configOpts, ['set', `${key}=123`])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'set', `${key}=123`], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: {},
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['set', `${key}=123`])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: { [key]: '123' },
})
})
it(`should delete ${key}`, async () => {
await config.handler(configOpts, ['delete', key])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'delete', key], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: { [key]: 'some-value' },
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['delete', key])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: {},
})
})
})
describe('with --json', () => {
const configOpts = {
json: true,
dir: process.cwd(),
cliOptions: {},
configDir: import.meta.dirname, // this doesn't matter, it won't be used
rawConfig: {},
}
describe('global (with --json)', () => {
it(`should set ${key}`, async () => {
await config.handler(configOpts, ['set', key, '"123"'])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'set', `${key}=123`], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: {},
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
json: true,
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['set', key, '"123"'])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: { [key]: '123' },
})
})
it(`should delete ${key}`, async () => {
await config.handler(configOpts, ['delete', key])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'delete', key], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: { [key]: 'some-value' },
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
json: true,
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['delete', key])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: {},
})
})
})
})
describe.each(
[
'@foo:registry',
]
)('scoped auth settings are written to the rc file directly', (key) => {
it(`should set ${key} globally`, async () => {
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: {},
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['set', `${key}=https://registry.example.com/`])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: { [key]: 'https://registry.example.com/' },
})
})
it(`should delete ${key} globally`, async () => {
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: { [key]: 'https://registry.example.com/' },
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['delete', key])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: {},
})
})
})
@@ -77,15 +186,17 @@ describe.each(
'//registry.npmjs.org/:_authToken',
]
)('non-string values should be rejected', (key) => {
const configOpts = {
json: true,
dir: process.cwd(),
cliOptions: {},
configDir: import.meta.dirname, // this doesn't matter, it won't be used
rawConfig: {},
}
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
it(`${key} should reject a non-string value`, async () => {
await expect(config.handler(configOpts, ['set', key, '{}'])).rejects.toMatchObject({
await expect(config.handler({
json: true,
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['set', key, '{}'])).rejects.toMatchObject({
code: 'ERR_PNPM_CONFIG_SET_AUTH_NON_STRING',
})
})
@@ -96,25 +207,53 @@ describe.each(
'._auth',
"['_auth']",
]
)('%p is handled by npm CLI', (propertyPath) => {
const configOpts = {
dir: process.cwd(),
cliOptions: {},
configDir: import.meta.dirname, // this doesn't matter, it won't be used
rawConfig: {},
}
)('%p is handled as an auth setting', (propertyPath) => {
it('should set _auth', async () => {
await config.handler(configOpts, ['set', propertyPath, '123'])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'set', '_auth=123'], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: {},
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['set', propertyPath, '123'])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: { _auth: '123' },
})
})
it('should delete _auth', async () => {
await config.handler(configOpts, ['delete', propertyPath])
expect(runNpm).toHaveBeenCalledWith(undefined, ['config', 'delete', '_auth'], expect.objectContaining({
location: 'user',
userConfigPath: expect.any(String),
}))
const tmp = tempDir()
const configDir = path.join(tmp, 'global-config')
const initConfig = {
globalRc: { _auth: 'some-value' },
globalYaml: undefined,
localRc: undefined,
localYaml: undefined,
} satisfies ConfigFilesData
writeConfigFiles(configDir, tmp, initConfig)
await config.handler({
dir: tmp,
cliOptions: {},
configDir,
global: true,
rawConfig: {},
}, ['delete', propertyPath])
expect(readConfigFiles(configDir, tmp)).toEqual({
...initConfig,
globalRc: {},
})
})
})

View File

@@ -24,9 +24,6 @@
{
"path": "../../core/logger"
},
{
"path": "../../exec/run-npm"
},
{
"path": "../../object/key-sorting"
},

View File

@@ -294,9 +294,14 @@ export async function getConfig (opts: {
pnpmConfig.userAgent = pnpmConfig.rawLocalConfig['user-agent']
? pnpmConfig.rawLocalConfig['user-agent']
: `${packageManager.name}/${packageManager.version} npm/? node/${process.version} ${process.platform} ${process.arch}`
const pnpmGlobalRcData = npmConfig.sources['pnpm-global']?.data
const pnpmGlobalRc = pnpmGlobalRcData
? pickIniConfig(Object.fromEntries(Object.entries(pnpmGlobalRcData)))
: {}
pnpmConfig.rawConfig = Object.assign(
{},
...npmConfig.list.map(pickIniConfig).reverse(),
pnpmGlobalRc,
pickIniConfig(cliOptions),
{ 'user-agent': pnpmConfig.userAgent },
{ globalconfig: path.join(configDir, 'rc') },

View File

@@ -444,6 +444,47 @@ test('registries in current directory\'s .npmrc have bigger priority then global
})
})
test('auth tokens from pnpm global rc override ~/.npmrc', async () => {
prepareEmpty()
// Set up a userconfig (.npmrc) with a stale token
fs.writeFileSync('.npmrc', '//registry.npmjs.org/:_authToken=stale-token', 'utf8')
// Set up a pnpm global rc with a fresh token via XDG_CONFIG_HOME
const configHome = path.resolve('xdg-config')
fs.mkdirSync(path.join(configHome, 'pnpm'), { recursive: true })
fs.writeFileSync(
path.join(configHome, 'pnpm', 'rc'),
'//registry.npmjs.org/:_authToken=fresh-token'
)
const originalXdg = process.env.XDG_CONFIG_HOME
process.env.XDG_CONFIG_HOME = configHome
try {
const { config } = await getConfig({
cliOptions: {
userconfig: path.resolve('.npmrc'),
},
env: {
...env,
XDG_CONFIG_HOME: configHome,
},
packageManager: {
name: 'pnpm',
version: '1.0.0',
},
})
expect(config.rawConfig['//registry.npmjs.org/:_authToken']).toBe('fresh-token')
} finally {
if (originalXdg != null) {
process.env.XDG_CONFIG_HOME = originalXdg
} else {
delete process.env.XDG_CONFIG_HOME
}
}
})
test('throw error if --save-prod is used with --save-peer', async () => {
await expect(getConfig({
cliOptions: {

View File

@@ -1,68 +0,0 @@
# @pnpm/run-npm
## 7.0.0
### Major Changes
- 43cdd87: Node.js v16 support dropped. Use at least Node.js v18.12.
### Patch Changes
- e70a829: The npm CLI executed from pnpm should not use Corepack [#7747](https://github.com/pnpm/pnpm/pull/7747).
## 6.1.0
### Minor Changes
- 5a5e42551: Allow to set custom env.
- 5a5e42551: Allow using token helpers in `pnpm publish` [#7316](https://github.com/pnpm/pnpm/issues/7316).
## 6.0.0
### Major Changes
- eceaa8b8b: Node.js 14 support dropped.
## 5.0.0
### Major Changes
- f884689e0: Require `@pnpm/logger` v5.
## 4.0.1
### Patch Changes
- 9177ddbc9: If running npm errors, throw an error.
## 4.0.0
### Major Changes
- 542014839: Node.js 12 is not supported.
## 3.1.0
### Minor Changes
- 724c5abd8: support "publishConfig.directory" field
## 3.0.0
### Major Changes
- 97b986fbc: Node.js 10 support is dropped. At least Node.js 12.17 is required for the package to work.
## 2.0.3
### Patch Changes
- a2ef8084f: Use the same versions of dependencies across the pnpm monorepo.
## 2.0.2
### Patch Changes
- c56438567: Update cross-spawn to ^7.0.3
## 2.0.2

View File

@@ -1,15 +0,0 @@
# @pnpm/run-npm
> Runs the npm CLI
[![npm version](https://img.shields.io/npm/v/@pnpm/run-npm.svg)](https://www.npmjs.com/package/@pnpm/run-npm)
## Installation
```sh
pnpm add @pnpm/run-npm
```
## License
MIT

View File

@@ -1,46 +0,0 @@
{
"name": "@pnpm/exec.run-npm",
"version": "1000.0.0",
"description": "Runs the npm CLI",
"keywords": [
"pnpm",
"pnpm11"
],
"license": "MIT",
"funding": "https://opencollective.com/pnpm",
"repository": "https://github.com/pnpm/pnpm/tree/main/exec/run-npm",
"homepage": "https://github.com/pnpm/pnpm/tree/main/exec/run-npm#readme",
"bugs": {
"url": "https://github.com/pnpm/pnpm/issues"
},
"type": "module",
"main": "lib/index.js",
"types": "lib/index.d.ts",
"exports": {
".": "./lib/index.js"
},
"files": [
"lib",
"!*.map"
],
"scripts": {
"lint": "eslint \"src/**/*.ts\"",
"test": "pn compile",
"prepublishOnly": "pn compile",
"compile": "tsgo --build && pn lint --fix"
},
"dependencies": {
"cross-spawn": "catalog:",
"path-name": "catalog:"
},
"devDependencies": {
"@pnpm/exec.run-npm": "workspace:*",
"@types/cross-spawn": "catalog:"
},
"engines": {
"node": ">=22.13"
},
"jest": {
"preset": "@pnpm/jest-config"
}
}

View File

@@ -1,81 +0,0 @@
import type childProcess from 'node:child_process'
import path from 'node:path'
import spawn from 'cross-spawn'
import PATH from 'path-name'
export type NPMLocation = 'global' | 'user' | 'project'
export interface RunNPMOptions {
cwd?: string
env?: Record<string, string>
location?: NPMLocation
userConfigPath?: string
}
export function runNpm (npmPath: string | undefined, args: string[], options?: RunNPMOptions): childProcess.SpawnSyncReturns<Buffer> {
const npm = npmPath ?? 'npm'
return runScriptSync(npm, args, {
cwd: options?.cwd ?? process.cwd(),
stdio: 'inherit',
userAgent: undefined,
env: { ...options?.env, COREPACK_ENABLE_STRICT: '0' },
location: options?.location,
userConfigPath: options?.userConfigPath,
})
}
export function runScriptSync (
command: string,
args: string[],
opts: {
cwd: string
location?: NPMLocation
stdio: childProcess.StdioOptions
userAgent?: string
userConfigPath?: string
env: Record<string, string>
}
): childProcess.SpawnSyncReturns<Buffer> {
const env = {
...createEnv(opts),
...opts.env,
}
const result = spawn.sync(command, args, {
...opts,
env,
})
if (result.error) throw result.error
return result
}
function createEnv (
opts: {
cwd: string
location?: NPMLocation
userAgent?: string
userConfigPath?: string
}
): NodeJS.ProcessEnv {
const env = { ...process.env }
env[PATH] = [
path.join(opts.cwd, 'node_modules', '.bin'),
path.dirname(process.execPath),
process.env[PATH],
].join(path.delimiter)
if (opts.userAgent) {
env.npm_config_user_agent = opts.userAgent
}
if (opts.location) {
env.npm_config_location = opts.location
}
if (opts.userConfigPath) {
env.npm_config_userconfig = opts.userConfigPath
}
return env
}

View File

@@ -1,12 +0,0 @@
{
"extends": "@pnpm/tsconfig",
"compilerOptions": {
"outDir": "lib",
"rootDir": "src"
},
"include": [
"src/**/*.ts",
"../../__typings__/**/*.d.ts"
],
"references": []
}

View File

@@ -1,8 +0,0 @@
{
"extends": "./tsconfig.json",
"include": [
"src/**/*.ts",
"test/**/*.ts",
"../../__typings__/**/*.d.ts"
]
}

22
pnpm-lock.yaml generated
View File

@@ -2275,9 +2275,6 @@ importers:
'@pnpm/error':
specifier: workspace:*
version: link:../../core/error
'@pnpm/exec.run-npm':
specifier: workspace:*
version: link:../../exec/run-npm
'@pnpm/object.key-sorting':
specifier: workspace:*
version: link:../../object/key-sorting
@@ -4128,22 +4125,6 @@ importers:
specifier: 'catalog:'
version: 7.0.1
exec/run-npm:
dependencies:
cross-spawn:
specifier: 'catalog:'
version: 7.0.6
path-name:
specifier: 'catalog:'
version: 1.0.0
devDependencies:
'@pnpm/exec.run-npm':
specifier: workspace:*
version: 'link:'
'@types/cross-spawn':
specifier: 'catalog:'
version: 6.0.6
fetching/binary-fetcher:
dependencies:
'@pnpm/error':
@@ -7231,9 +7212,6 @@ importers:
'@pnpm/exec.commands':
specifier: workspace:*
version: link:../exec/commands
'@pnpm/exec.run-npm':
specifier: workspace:*
version: link:../exec/run-npm
'@pnpm/hooks.pnpmfile':
specifier: workspace:*
version: link:../hooks/pnpmfile

View File

@@ -102,7 +102,6 @@
"@pnpm/engine.runtime.commands": "workspace:*",
"@pnpm/error": "workspace:*",
"@pnpm/exec.commands": "workspace:*",
"@pnpm/exec.run-npm": "workspace:*",
"@pnpm/hooks.pnpmfile": "workspace:*",
"@pnpm/installing.client": "workspace:*",
"@pnpm/installing.commands": "workspace:*",

View File

@@ -98,9 +98,6 @@
{
"path": "../exec/commands"
},
{
"path": "../exec/run-npm"
},
{
"path": "../hooks/pnpmfile"
},