fix: print a better error message on prepare pkg failure (#5847)

ref #5845
This commit is contained in:
Zoltan Kochan
2023-01-01 23:28:33 +02:00
committed by GitHub
parent 08ceaf3fcb
commit ec97a31057
17 changed files with 254 additions and 56 deletions

View File

@@ -0,0 +1,11 @@
---
"@pnpm/plugin-commands-publishing": patch
"@pnpm/store-connection-manager": patch
"@pnpm/default-reporter": patch
"@pnpm/prepare-package": patch
"@pnpm/client": patch
"@pnpm/node.fetcher": patch
"pnpm": patch
---
Report to the console when a git-hosted dependency is built [#5847](https://github.com/pnpm/pnpm/pull/5847).

View File

@@ -0,0 +1,7 @@
---
"@pnpm/tarball-fetcher": patch
"@pnpm/git-fetcher": patch
"pnpm": patch
---
Print more contextual information when a git-hosted package fails to be prepared for installation [#5847](https://github.com/pnpm/pnpm/pull/5847).

View File

@@ -10,6 +10,7 @@ import { formatPrefix, formatPrefixNoTrim } from './utils/formatPrefix'
import { hlValue } from './outputConstants'
const NODE_MODULES = `${path.sep}node_modules${path.sep}`
const TMP_DIR_IN_STORE = `tmp${path.sep}_tmp_` // git-hosted dependencies are built in these temporary directories
// When streaming processes are spawned, use this color for prefix
const colorWheel = ['cyan', 'magenta', 'blue', 'yellow', 'green', 'red']
@@ -65,7 +66,7 @@ export function reportLifecycleScripts (
.forEach((log: LifecycleLog) => {
const key = `${log.stage}:${log.depPath}`
lifecycleMessages[key] = lifecycleMessages[key] || {
collapsed: log.wd.includes(NODE_MODULES),
collapsed: log.wd.includes(NODE_MODULES) || log.wd.includes(TMP_DIR_IN_STORE),
output: [],
startTime: process.hrtime(),
status: formatIndentedStatus(chalk.magentaBright('Running...')),
@@ -113,8 +114,13 @@ function renderCollapsedScriptOutput (
maxWidth: number
}
) {
messageCache.label = messageCache.label ??
`${highlightLastFolder(formatPrefixNoTrim(opts.cwd, log.wd))}: Running ${log.stage} script`
if (!messageCache.label) {
messageCache.label = highlightLastFolder(formatPrefixNoTrim(opts.cwd, log.wd))
if (log.wd.includes(TMP_DIR_IN_STORE)) {
messageCache.label += ` [${log.depPath}]`
}
messageCache.label += `: Running ${log.stage} script`
}
if (!opts.exit) {
updateMessageCache(log, messageCache, opts)
return `${messageCache.label}...`
@@ -191,7 +197,7 @@ function updateMessageCache (
if (log['exitCode'] === 0) {
messageCache.status = formatIndentedStatus(chalk.magentaBright(`Done in ${time}`))
} else {
messageCache.status = formatIndentedStatus(chalk.red(`Failed in ${time}`))
messageCache.status = formatIndentedStatus(chalk.red(`Failed in ${time} at ${log.wd}`))
}
} else {
messageCache.output.push(formatIndentedOutput(opts.maxWidth, log))

View File

@@ -17,7 +17,6 @@ const OUTPUT_INDENTATION = chalk.magentaBright('│')
const STATUS_INDENTATION = chalk.magentaBright('└─')
const STATUS_RUNNING = chalk.magentaBright('Running...')
const STATUS_DONE = chalk.magentaBright('Done in 1s')
const STATUS_FAILED = chalk.red('Failed in 1s')
const EOL = '\n'
function replaceTimeWith1Sec (text: string) {
@@ -651,6 +650,79 @@ ${chalk.gray('node_modules/.registry.npmjs.org/qar/1.0.0/node_modules/')}qar: Ru
})
})
test('collapses lifecycle output from preparation of a git-hosted dependency', (done) => {
const output$ = toOutput$({
context: { argv: ['install'] },
reportingOptions: { outputMaxWidth: 79 },
streamParser: createStreamParser(),
})
const wdOfFoo = path.resolve(process.cwd(), 'tmp/_tmp_01243')
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
optional: false,
script: 'node foo',
stage: 'preinstall',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
line: 'foo 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20',
stage: 'preinstall',
stdio: 'stdout',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
optional: false,
script: 'node foo',
stage: 'postinstall',
stdio: 'stdout',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
line: 'foo I',
stage: 'postinstall',
stdio: 'stdout',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
line: 'foo II',
stage: 'postinstall',
stdio: 'stdout',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
line: 'foo III',
stage: 'postinstall',
stdio: 'stdout',
wd: wdOfFoo,
})
lifecycleLogger.debug({
depPath: 'registry.npmjs.org/foo/1.0.0',
exitCode: 0,
optional: false,
stage: 'postinstall',
wd: wdOfFoo,
})
expect.assertions(1)
output$.pipe(skip(2), take(1), map(normalizeNewline)).subscribe({
complete: () => done(),
error: done,
next: (output: unknown) => {
expect(replaceTimeWith1Sec(output as string)).toBe(`\
${chalk.gray('tmp')}_tmp_01234: Running preinstall script...
${chalk.gray('tmp')}_tmp_01234: Running postinstall script, done in 1s`)
},
})
})
test('output of failed optional dependency is not shown', (done) => {
const output$ = toOutput$({
context: { argv: ['install'] },
@@ -734,7 +806,7 @@ test('output of failed non-optional dependency is printed', (done) => {
${chalk.gray('node_modules/.registry.npmjs.org/foo/1.0.0/node_modules/')}foo: Running install script, failed in 1s
.../foo/1.0.0/node_modules/foo ${INSTALL}$ node foo
${OUTPUT_INDENTATION} foo 0 1 2 3 4 5 6 7 8 9
${STATUS_INDENTATION} ${STATUS_FAILED}`)
${STATUS_INDENTATION} ${failedAt(wd)}`)
},
})
})
@@ -780,7 +852,7 @@ test('do not fail if the debug log has no output', (done) => {
${chalk.gray('node_modules/.registry.npmjs.org/foo/1.0.0/node_modules/')}foo: Running install script, failed in 1s
.../foo/1.0.0/node_modules/foo ${INSTALL}$ node foo
${OUTPUT_INDENTATION}
${STATUS_INDENTATION} ${STATUS_FAILED}`)
${STATUS_INDENTATION} ${failedAt(wd)}`)
},
})
})
@@ -844,3 +916,7 @@ Running ${POSTINSTALL} for ${hlPkgId('registry.npmjs.org/bar/1.0.0')}: ${childOu
},
})
})
function failedAt (wd: string) {
return chalk.red(`Failed in 1s at ${wd}`)
}

View File

@@ -34,9 +34,11 @@ export async function fetchNode (fetch: FetchFromRegistry, version: string, targ
}
const getAuthHeader = () => undefined
const fetchers = createTarballFetcher(fetch, getAuthHeader, {
rawConfig: {}, // This is not needed for fetching Node.js
retry: opts.retry,
timeout: opts.fetchTimeout,
// These are not needed for fetching Node.js
rawConfig: {},
unsafePerm: false,
})
const cafs = createCafsStore(opts.cafsDir)
const fetchTarball = pickFetcher(fetchers, { tarball })

View File

@@ -29,8 +29,7 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/exec/prepare-package#readme",
"dependencies": {
"@pnpm/error": "workspace:*",
"@pnpm/npm-lifecycle": "^2.0.0",
"@pnpm/lifecycle": "workspace:*",
"@pnpm/read-package-json": "workspace:*",
"@zkochan/rimraf": "^2.1.2",
"execa": "npm:safe-execa@0.1.2",

View File

@@ -1,10 +1,8 @@
import path from 'path'
import { PnpmError } from '@pnpm/error'
import lifecycle from '@pnpm/npm-lifecycle'
import { runLifecycleHook, RunLifecycleHookOptions } from '@pnpm/lifecycle'
import { safeReadPackageJsonFromDir } from '@pnpm/read-package-json'
import { PackageScripts } from '@pnpm/types'
import rimraf from '@zkochan/rimraf'
import execa from 'execa'
import preferredPM from 'preferred-pm'
import omit from 'ramda/src/omit'
@@ -16,23 +14,35 @@ const PREPUBLISH_SCRIPTS = [
'postpublish',
]
export async function preparePackage (opts: { rawConfig: object }, pkgDir: string) {
export interface PreparePackageOptions {
rawConfig: object
unsafePerm?: boolean
}
export async function preparePackage (opts: PreparePackageOptions, pkgDir: string) {
const manifest = await safeReadPackageJsonFromDir(pkgDir)
if (manifest?.scripts == null || !packageShouldBeBuilt(manifest.scripts)) return
const pm = (await preferredPM(pkgDir))?.name ?? 'npm'
// We can't prepare a package without running its lifecycle scripts.
// An alternative solution could be to throw an exception.
const config = omit(['ignore-scripts'], opts.rawConfig)
const env = lifecycle.makeEnv(manifest, { config })
const execOpts = { cwd: pkgDir, env, extendEnv: true }
const execOpts: RunLifecycleHookOptions = {
depPath: `${manifest.name}@${manifest.version}`,
pkgRoot: pkgDir,
// We can't prepare a package without running its lifecycle scripts.
// An alternative solution could be to throw an exception.
rawConfig: omit(['ignore-scripts'], opts.rawConfig),
rootModulesDir: pkgDir, // We don't need this property but there is currently no way to not set it.
unsafePerm: Boolean(opts.unsafePerm),
}
try {
await execa(pm, ['install'], execOpts)
const installScriptName = `${pm}-install`
manifest.scripts[installScriptName] = `${pm} install`
await runLifecycleHook(installScriptName, manifest, execOpts)
for (const scriptName of PREPUBLISH_SCRIPTS) {
if (manifest.scripts[scriptName] == null || manifest.scripts[scriptName] === '') continue
await execa(pm, ['run', scriptName], execOpts)
await runLifecycleHook(scriptName, manifest, execOpts)
}
} catch (err: any) { // eslint-disable-line
throw new PnpmError('PREPARE_PKG_FAILURE', err.shortMessage ?? err.message)
err.code = 'ERR_PNPM_PREPARE_PACKAGE'
throw err
}
await rimraf(path.join(pkgDir, 'node_modules'))
}

View File

@@ -15,14 +15,14 @@
{
"path": "../../__utils__/test-fixtures"
},
{
"path": "../../packages/error"
},
{
"path": "../../packages/types"
},
{
"path": "../../pkg-manifest/read-package-json"
},
{
"path": "../lifecycle"
}
]
}

View File

@@ -5,9 +5,15 @@ import rimraf from '@zkochan/rimraf'
import execa from 'execa'
import { URL } from 'url'
export function createGitFetcher (createOpts: { gitShallowHosts?: string[], rawConfig: object }) {
export interface CreateGitFetcherOptions {
gitShallowHosts?: string[]
rawConfig: object
unsafePerm?: boolean
}
export function createGitFetcher (createOpts: CreateGitFetcherOptions) {
const allowedHosts = new Set(createOpts?.gitShallowHosts ?? [])
const preparePkg = preparePackage.bind(null, { rawConfig: createOpts.rawConfig })
const preparePkg = preparePackage.bind(null, { rawConfig: createOpts.rawConfig, unsafePerm: createOpts.unsafePerm })
const gitFetcher: GitFetcher = async (cafs, resolution, opts) => {
const tempLocation = await cafs.tempDir()
@@ -19,7 +25,12 @@ export function createGitFetcher (createOpts: { gitShallowHosts?: string[], rawC
await execGit(['clone', resolution.repo, tempLocation])
}
await execGit(['checkout', resolution.commit], { cwd: tempLocation })
await preparePkg(tempLocation)
try {
await preparePkg(tempLocation)
} catch (err: any) { // eslint-disable-line
err.message = `Failed to prepare git-hosted package fetched from "${resolution.repo}": ${err.message}` // eslint-disable-line
throw err
}
// removing /.git to make directory integrity calculation faster
await rimraf(path.join(tempLocation, '.git'))
const filesIndex = await cafs.addFilesFromDir(tempLocation, opts.manifest)

View File

@@ -124,6 +124,20 @@ test('still able to shallow fetch for allowed hosts', async () => {
expect(name).toEqual('is-positive')
})
test('fail when preparing a git-hosted package', async () => {
const cafsDir = tempy.directory()
const fetch = createGitFetcher({ rawConfig: {} }).git
const manifest = pDefer<DependencyManifest>()
await expect(
fetch(createCafsStore(cafsDir),
{
commit: 'ba58874aae1210a777eb309dd01a9fdacc7e54e7',
repo: 'https://github.com/pnpm-e2e/prepare-script-fails.git',
type: 'git',
}, { manifest })
).rejects.toThrow('Failed to prepare git-hosted package fetched from "https://github.com/pnpm-e2e/prepare-script-fails.git": @pnpm.e2e/prepare-script-fails@1.0.0 npm-install: `npm install`')
})
function prefixGitArgs (): string[] {
return process.platform === 'win32' ? ['-c', 'core.longpaths=true'] : []
}

View File

@@ -10,17 +10,26 @@ interface Resolution {
tarball: string
}
export function createGitHostedTarballFetcher (fetchRemoteTarball: FetchFunction, rawConfig: object): FetchFunction {
export interface CreateGitHostedTarballFetcher {
rawConfig: object
unsafePerm?: boolean
}
export function createGitHostedTarballFetcher (fetchRemoteTarball: FetchFunction, fetcherOpts: CreateGitHostedTarballFetcher): FetchFunction {
const fetch = async (cafs: Cafs, resolution: Resolution, opts: FetchOptions) => {
const { filesIndex } = await fetchRemoteTarball(cafs, resolution, opts)
return { filesIndex: await prepareGitHostedPkg(filesIndex as FilesIndex, cafs, rawConfig) }
try {
return { filesIndex: await prepareGitHostedPkg(filesIndex as FilesIndex, cafs, fetcherOpts) }
} catch (err: any) { // eslint-disable-line
err.message = `Failed to prepare git-hosted package fetched from "${resolution.tarball}": ${err.message}` // eslint-disable-line
throw err
}
}
return fetch as FetchFunction
}
async function prepareGitHostedPkg (filesIndex: FilesIndex, cafs: Cafs, rawConfig: object) {
async function prepareGitHostedPkg (filesIndex: FilesIndex, cafs: Cafs, opts: CreateGitHostedTarballFetcher) {
const tempLocation = await cafs.tempDir()
await cafs.importPackage(tempLocation, {
filesResponse: {
@@ -29,7 +38,7 @@ async function prepareGitHostedPkg (filesIndex: FilesIndex, cafs: Cafs, rawConfi
},
force: true,
})
await preparePackage({ rawConfig }, tempLocation)
await preparePackage(opts, tempLocation)
const newFilesIndex = await cafs.addFilesFromDir(tempLocation)
// Important! We cannot remove the temp location at this stage.
// Even though we have the index of the package,

View File

@@ -32,6 +32,7 @@ export function createTarballFetcher (
getAuthHeader: GetAuthHeader,
opts: {
rawConfig: object
unsafePerm?: boolean
timeout?: number
retry?: RetryTimeoutOptions
offline?: boolean
@@ -51,7 +52,7 @@ export function createTarballFetcher (
return {
localTarball: createLocalTarballFetcher(),
remoteTarball: remoteTarballFetcher,
gitHostedTarball: createGitHostedTarballFetcher(remoteTarballFetcher, opts.rawConfig),
gitHostedTarball: createGitHostedTarballFetcher(remoteTarballFetcher, opts),
}
}

View File

@@ -364,6 +364,16 @@ test('fetch a big repository', async () => {
expect(result.filesIndex).toBeTruthy()
})
test('fail when preparing a git-hosted package', async () => {
process.chdir(tempy.directory())
const resolution = { tarball: 'https://codeload.github.com/pnpm-e2e/prepare-script-fails/tar.gz/ba58874aae1210a777eb309dd01a9fdacc7e54e7' }
await expect(
fetch.gitHostedTarball(cafs, resolution, { lockfileDir: process.cwd() })
).rejects.toThrow('Failed to prepare git-hosted package fetched from "https://codeload.github.com/pnpm-e2e/prepare-script-fails/tar.gz/ba58874aae1210a777eb309dd01a9fdacc7e54e7": @pnpm.e2e/prepare-script-fails@1.0.0 npm-install: `npm install`')
})
test('fail when extracting a broken tarball', async () => {
const scope = nock(registry)
.get('/foo.tgz')

View File

@@ -20,6 +20,7 @@ export type ClientOptions = {
rawConfig: object
retry?: RetryTimeoutOptions
timeout?: number
unsafePerm?: boolean
userAgent?: string
userConfig?: Record<string, string>
gitShallowHosts?: string[]
@@ -54,7 +55,7 @@ type Fetchers = {
function createFetchers (
fetchFromRegistry: FetchFromRegistry,
getAuthHeader: GetAuthHeader,
opts: Pick<ClientOptions, 'rawConfig' | 'retry' | 'gitShallowHosts' | 'resolveSymlinksInInjectedDirs'>,
opts: Pick<ClientOptions, 'rawConfig' | 'retry' | 'gitShallowHosts' | 'resolveSymlinksInInjectedDirs' | 'unsafePerm'>,
customFetchers?: CustomFetchers
): Fetchers {
const defaultFetchers = {

80
pnpm-lock.yaml generated
View File

@@ -1224,12 +1224,9 @@ importers:
exec/prepare-package:
dependencies:
'@pnpm/error':
'@pnpm/lifecycle':
specifier: workspace:*
version: link:../../packages/error
'@pnpm/npm-lifecycle':
specifier: ^2.0.0
version: 2.0.0_typanion@3.12.1
version: link:../lifecycle
'@pnpm/read-package-json':
specifier: workspace:*
version: link:../../pkg-manifest/read-package-json
@@ -6762,7 +6759,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
jest-message-util: 29.3.1
jest-util: 29.3.1
@@ -6783,14 +6780,14 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1_@babel+types@7.20.7
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
ansi-escapes: 4.3.2
chalk: 4.1.2
ci-info: 3.7.0
exit: 0.1.2
graceful-fs: 4.2.10
jest-changed-files: 29.2.0
jest-config: 29.3.1_56nfvjbu5gf7nsgorbtc4ijmhq
jest-config: 29.3.1_7arhz5k5lgu27jr56nuhhcqiee
jest-haste-map: 29.3.1
jest-message-util: 29.3.1
jest-regex-util: 29.2.0
@@ -6818,7 +6815,7 @@ packages:
dependencies:
'@jest/fake-timers': 29.3.1
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
jest-mock: 29.3.1
dev: true
@@ -6845,7 +6842,7 @@ packages:
dependencies:
'@jest/types': 29.3.1
'@sinonjs/fake-timers': 9.1.2
'@types/node': 14.18.36
'@types/node': 18.11.18
jest-message-util: 29.3.1
jest-mock: 29.3.1
jest-util: 29.3.1
@@ -6878,7 +6875,7 @@ packages:
'@jest/transform': 29.3.1_@babel+types@7.20.7
'@jest/types': 29.3.1
'@jridgewell/trace-mapping': 0.3.17
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
collect-v8-coverage: 1.0.1
exit: 0.1.2
@@ -6968,7 +6965,7 @@ packages:
'@jest/schemas': 29.0.0
'@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1
'@types/node': 14.18.36
'@types/node': 18.11.18
'@types/yargs': 17.0.17
chalk: 4.1.2
dev: true
@@ -12743,7 +12740,7 @@ packages:
'@jest/expect': 29.3.1
'@jest/test-result': 29.3.1
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
co: 4.6.0
dedent: 0.7.0
@@ -12833,6 +12830,47 @@ packages:
- supports-color
dev: true
/jest-config/29.3.1_7arhz5k5lgu27jr56nuhhcqiee:
resolution: {integrity: sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@types/node': '*'
ts-node: '>=9.0.0'
peerDependenciesMeta:
'@types/node':
optional: true
ts-node:
optional: true
dependencies:
'@babel/core': 7.20.7
'@jest/test-sequencer': 29.3.1
'@jest/types': 29.3.1
'@types/node': 18.11.18
babel-jest: 29.3.1_prjhoemhtbjqo3vlbvwbf3oci4
chalk: 4.1.2
ci-info: 3.7.0
deepmerge: 4.2.2
glob: 7.2.3
graceful-fs: 4.2.10
jest-circus: 29.3.1_@babel+types@7.20.7
jest-environment-node: 29.3.1
jest-get-type: 29.2.0
jest-regex-util: 29.2.0
jest-resolve: 29.3.1
jest-runner: 29.3.1_@babel+types@7.20.7
jest-util: 29.3.1
jest-validate: 29.3.1
micromatch: 4.0.5
parse-json: 5.2.0
pretty-format: 29.3.1
slash: 3.0.0
strip-json-comments: 3.1.1
ts-node: 10.9.1_xl7wyiapi7jo5c2pfz5vjm55na
transitivePeerDependencies:
- '@babel/types'
- supports-color
dev: true
/jest-diff/29.3.1:
resolution: {integrity: sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
@@ -12868,7 +12906,7 @@ packages:
'@jest/environment': 29.3.1
'@jest/fake-timers': 29.3.1
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
jest-mock: 29.3.1
jest-util: 29.3.1
dev: true
@@ -12884,7 +12922,7 @@ packages:
dependencies:
'@jest/types': 29.3.1
'@types/graceful-fs': 4.1.5
'@types/node': 14.18.36
'@types/node': 18.11.18
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.10
@@ -12935,7 +12973,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
jest-util: 29.3.1
dev: true
@@ -12990,7 +13028,7 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1_@babel+types@7.20.7
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.10
@@ -13022,7 +13060,7 @@ packages:
'@jest/test-result': 29.3.1
'@jest/transform': 29.3.1_@babel+types@7.20.7
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
cjs-module-lexer: 1.2.2
collect-v8-coverage: 1.0.1
@@ -13079,7 +13117,7 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
chalk: 4.1.2
ci-info: 3.7.0
graceful-fs: 4.2.10
@@ -13104,7 +13142,7 @@ packages:
dependencies:
'@jest/test-result': 29.3.1
'@jest/types': 29.3.1
'@types/node': 14.18.36
'@types/node': 18.11.18
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
@@ -13116,7 +13154,7 @@ packages:
resolution: {integrity: sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@types/node': 14.18.36
'@types/node': 18.11.18
jest-util: 29.3.1
merge-stream: 2.0.0
supports-color: 8.1.1

View File

@@ -42,6 +42,7 @@ Partial<Pick<Config,
| 'offline'
| 'selectedProjectsGraph'
| 'strictSsl'
| 'unsafePerm'
| 'userAgent'
| 'userConfig'
| 'verifyStoreIntegrity'

View File

@@ -37,6 +37,7 @@ export type CreateNewStoreControllerOptions = CreateResolverOptions & Pick<Confi
| 'registrySupportsTimeField'
| 'resolutionMode'
| 'strictSsl'
| 'unsafePerm'
| 'userAgent'
| 'verifyStoreIntegrity'
> & {
@@ -50,6 +51,7 @@ export async function createNewStoreController (
const { resolve, fetchers } = createClient({
customFetchers: opts.hooks?.fetchers,
userConfig: opts.userConfig,
unsafePerm: opts.unsafePerm,
authConfig: opts.rawConfig,
ca: opts.ca,
cacheDir: opts.cacheDir,