From 55de4febebc08cbd4acbc50cc3e697df072a2888 Mon Sep 17 00:00:00 2001 From: Zoltan Kochan Date: Mon, 4 May 2026 19:44:30 +0200 Subject: [PATCH] fix: render peer dependency issues on strict error (#11450) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #11439. When `strictPeerDependencies: true` causes `ERR_PNPM_PEER_DEP_ISSUES`, the peer dependency issues are again rendered inline — using the **same format as `pnpm peers check`** — so users (and CI tools like Renovate) can see what failed without running another command. The non-strict warning path is unchanged: it still emits the short "Run `pnpm peers check`" hint. ### Behavior `strictPeerDependencies: true`: ``` ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies ✕ unmet peer react Installed: 17.0.2 Wanted: ^18.2.0: react-dom@18.2.0 hint: To disable failing on peer dependency issues, add the following to pnpm-workspace.yaml in your project root: strictPeerDependencies: false ``` `strictPeerDependencies: false` (unchanged): ``` WARN Issues with peer dependencies found. Run "pnpm peers check" to list them. ``` ### Implementation - Added a new `@pnpm/deps.inspection.peers-issues-renderer` package at `deps/inspection/peers-issues-renderer/`, alongside its data producer `@pnpm/deps.inspection.peers-checker`. It exposes a single `renderPeerIssues()` that emits the flat issue list previously inlined in `pnpm peers check`. - Removed the duplicated formatter from `deps/inspection/commands/src/peers.ts` and made the `pnpm peers check` command consume the new renderer. - `cli/default-reporter/src/reportError.ts`: `reportPeerDependencyIssuesError` now calls the shared `renderPeerIssues()` and prefixes the hint block with the rendered output. Tests strip ANSI escapes before substring assertions so they stay correct under `FORCE_COLOR=1`. Result: a single renderer is shared between the install error and the `pnpm peers check` command — output is identical between the two paths. --- .../render-peer-issues-on-strict-error.md | 8 + cli/default-reporter/package.json | 1 + cli/default-reporter/src/reportError.ts | 12 +- .../test/reportingPeerDependencyIssues.ts | 12 +- cli/default-reporter/tsconfig.json | 3 + deps/inspection/commands/package.json | 1 + deps/inspection/commands/src/peers.ts | 56 +------ deps/inspection/commands/tsconfig.json | 3 + .../peers-issues-renderer/README.md | 13 ++ .../peers-issues-renderer/package.json | 47 ++++++ .../peers-issues-renderer/src/index.ts | 68 ++++++++ .../test/__snapshots__/index.ts.snap | 58 +++++++ .../peers-issues-renderer/test/index.ts | 156 ++++++++++++++++++ .../peers-issues-renderer/test/tsconfig.json | 18 ++ .../peers-issues-renderer/tsconfig.json | 16 ++ .../peers-issues-renderer/tsconfig.lint.json | 8 + pnpm-lock.yaml | 22 +++ 17 files changed, 438 insertions(+), 64 deletions(-) create mode 100644 .changeset/render-peer-issues-on-strict-error.md create mode 100644 deps/inspection/peers-issues-renderer/README.md create mode 100644 deps/inspection/peers-issues-renderer/package.json create mode 100644 deps/inspection/peers-issues-renderer/src/index.ts create mode 100644 deps/inspection/peers-issues-renderer/test/__snapshots__/index.ts.snap create mode 100644 deps/inspection/peers-issues-renderer/test/index.ts create mode 100644 deps/inspection/peers-issues-renderer/test/tsconfig.json create mode 100644 deps/inspection/peers-issues-renderer/tsconfig.json create mode 100644 deps/inspection/peers-issues-renderer/tsconfig.lint.json diff --git a/.changeset/render-peer-issues-on-strict-error.md b/.changeset/render-peer-issues-on-strict-error.md new file mode 100644 index 0000000000..947033e121 --- /dev/null +++ b/.changeset/render-peer-issues-on-strict-error.md @@ -0,0 +1,8 @@ +--- +"@pnpm/deps.inspection.peers-issues-renderer": minor +"@pnpm/deps.inspection.commands": patch +"@pnpm/cli.default-reporter": patch +"pnpm": patch +--- + +When `strictPeerDependencies` is `true`, the `ERR_PNPM_PEER_DEP_ISSUES` error once again renders the peer dependency issues inline using the same format as `pnpm peers check`, so users (and CI tools like Renovate) can see what failed without running `pnpm peers check` separately [#11439](https://github.com/pnpm/pnpm/issues/11439). diff --git a/cli/default-reporter/package.json b/cli/default-reporter/package.json index 826ea31f1c..205235eab7 100644 --- a/cli/default-reporter/package.json +++ b/cli/default-reporter/package.json @@ -36,6 +36,7 @@ "@pnpm/cli.meta": "workspace:*", "@pnpm/config.reader": "workspace:*", "@pnpm/core-loggers": "workspace:*", + "@pnpm/deps.inspection.peers-issues-renderer": "workspace:*", "@pnpm/error": "workspace:*", "@pnpm/installing.dedupe.issues-renderer": "workspace:*", "@pnpm/installing.dedupe.types": "workspace:*", diff --git a/cli/default-reporter/src/reportError.ts b/cli/default-reporter/src/reportError.ts index cb3a1aa74e..65bfe61dfa 100644 --- a/cli/default-reporter/src/reportError.ts +++ b/cli/default-reporter/src/reportError.ts @@ -1,5 +1,6 @@ import type { Config } from '@pnpm/config.reader' import type { Log } from '@pnpm/core-loggers' +import { renderPeerIssues } from '@pnpm/deps.inspection.peers-issues-renderer' import type { PnpmError } from '@pnpm/error' import { renderDedupeCheckIssues } from '@pnpm/installing.dedupe.issues-renderer' import type { DedupeCheckIssues } from '@pnpm/installing.dedupe.types' @@ -461,9 +462,7 @@ function reportPeerDependencyIssuesError ( msg: { issuesByProjects: PeerDependencyIssuesByProjects } ): ErrorInfo { const hasMissingPeers = getHasMissingPeers(msg.issuesByProjects) - const hints: string[] = [ - 'Run "pnpm peers check" to list the peer dependency issues.', - ] + const hints: string[] = [] if (hasMissingPeers) { hints.push(`To auto-install peer dependencies, add the following to "pnpm-workspace.yaml" in your project root: @@ -471,11 +470,12 @@ function reportPeerDependencyIssuesError ( } hints.push(`To disable failing on peer dependency issues, add the following to pnpm-workspace.yaml in your project root: - strictPeerDependencies: false -`) + strictPeerDependencies: false`) + const formattedHints = hints.map((hint) => `hint: ${hint}`).join('\n') + const rendered = renderPeerIssues(msg.issuesByProjects) return { title: err.message, - body: hints.map((hint) => `hint: ${hint}`).join('\n'), + body: rendered ? `${rendered}\n${formattedHints}` : formattedHints, } } diff --git a/cli/default-reporter/test/reportingPeerDependencyIssues.ts b/cli/default-reporter/test/reportingPeerDependencyIssues.ts index 16a86a69a0..9d4d05909e 100644 --- a/cli/default-reporter/test/reportingPeerDependencyIssues.ts +++ b/cli/default-reporter/test/reportingPeerDependencyIssues.ts @@ -1,3 +1,5 @@ +import { stripVTControlCharacters as stripAnsi } from 'node:util' + import { expect, test } from '@jest/globals' import { toOutput$ } from '@pnpm/cli.default-reporter' import { peerDependencyIssuesLogger } from '@pnpm/core-loggers' @@ -44,7 +46,7 @@ test('print peer dependency issues warning', async () => { expect.assertions(1) const output = await firstValueFrom(output$) - expect(output).toContain('pnpm peers check') + expect(stripAnsi(output)).toContain('pnpm peers check') }) test('print peer dependency issues error', async () => { @@ -81,8 +83,10 @@ test('print peer dependency issues error', async () => { }) logger.error(err, err) - expect.assertions(1) + expect.assertions(3) - const output = await firstValueFrom(output$) - expect(output).toContain('pnpm peers check') + const output = stripAnsi(await firstValueFrom(output$)) + expect(output).toContain('unmet peer a') + expect(output).toContain('Installed: 2') + expect(output).toContain('b@1.0.0') }) diff --git a/cli/default-reporter/tsconfig.json b/cli/default-reporter/tsconfig.json index d6c013bff8..034f726185 100644 --- a/cli/default-reporter/tsconfig.json +++ b/cli/default-reporter/tsconfig.json @@ -25,6 +25,9 @@ { "path": "../../core/types" }, + { + "path": "../../deps/inspection/peers-issues-renderer" + }, { "path": "../../installing/dedupe/issues-renderer" }, diff --git a/deps/inspection/commands/package.json b/deps/inspection/commands/package.json index 053fd9ac4b..3f04cd897c 100644 --- a/deps/inspection/commands/package.json +++ b/deps/inspection/commands/package.json @@ -41,6 +41,7 @@ "@pnpm/deps.inspection.list": "workspace:*", "@pnpm/deps.inspection.outdated": "workspace:*", "@pnpm/deps.inspection.peers-checker": "workspace:*", + "@pnpm/deps.inspection.peers-issues-renderer": "workspace:*", "@pnpm/error": "workspace:*", "@pnpm/global.commands": "workspace:*", "@pnpm/global.packages": "workspace:*", diff --git a/deps/inspection/commands/src/peers.ts b/deps/inspection/commands/src/peers.ts index 034d21ea30..4b0a872f18 100644 --- a/deps/inspection/commands/src/peers.ts +++ b/deps/inspection/commands/src/peers.ts @@ -2,8 +2,8 @@ import { FILTERING, UNIVERSAL_OPTIONS } from '@pnpm/cli.common-cli-options-help' import { docsUrl } from '@pnpm/cli.utils' import { type Config, type ConfigContext, types as allTypes } from '@pnpm/config.reader' import { checkPeerDependencies } from '@pnpm/deps.inspection.peers-checker' +import { renderPeerIssues } from '@pnpm/deps.inspection.peers-issues-renderer' import type { PeerDependencyIssuesByProjects } from '@pnpm/types' -import chalk from 'chalk' import { isEmpty, pick } from 'ramda' import { renderHelp } from 'render-help' @@ -117,7 +117,7 @@ async function checkCmd ( } return { - output: renderPeerIssuesFlat(issues), + output: `Issues with peer dependencies found\n\n${renderPeerIssues(issues)}`, exitCode: 1, } } @@ -129,55 +129,3 @@ function hasNoIssues (issues: PeerDependencyIssuesByProjects): boolean { isEmpty(projectIssues.missing) ) } - -function renderPeerIssuesFlat (issuesByProjects: PeerDependencyIssuesByProjects): string { - const sections: string[] = [] - - for (const [, { bad, missing, conflicts, intersections }] of Object.entries(issuesByProjects)) { - for (const [peerName, issues] of Object.entries(bad)) { - const foundVersion = issues[0].foundVersion - const header = `${chalk.yellowBright('✕ unmet peer')} ${chalk.bold(peerName)}` - const installed = ` ${chalk.cyan('Installed:')} ${chalk.dim(foundVersion)}` - sections.push(`${header}\n${installed}\n${formatRequiredBy(issues)}`) - } - - for (const [peerName, issues] of Object.entries(missing)) { - if (!intersections[peerName] && !conflicts.includes(peerName)) continue - const conflict = conflicts.includes(peerName) - const header = conflict - ? `${chalk.red('✕ conflicting peer')} ${chalk.bold(peerName)}` - : `${chalk.red('✕ missing peer')} ${chalk.bold(peerName)}` - sections.push(`${header}\n${formatRequiredBy(issues)}`) - } - } - - if (sections.length === 0) return '' - return `Issues with peer dependencies found\n\n${sections.join('\n\n')}` -} - -function formatRequiredBy (issues: Array<{ parents: Array<{ name: string, version: string }>, wantedRange: string }>): string { - const byRange = new Map>() - for (const issue of issues) { - const declaring = issue.parents[issue.parents.length - 1] - const pkg = `${declaring.name}@${declaring.version}` - if (!byRange.has(issue.wantedRange)) { - byRange.set(issue.wantedRange, new Set()) - } - byRange.get(issue.wantedRange)!.add(pkg) - } - const lines: string[] = [` ${chalk.cyan('Wanted:')}`] - for (const [range, pkgs] of byRange) { - lines.push(` ${chalk.cyanBright(formatRange(range))}${chalk.cyan(':')}`) - for (const pkg of pkgs) { - lines.push(` ${chalk.dim(pkg)}`) - } - } - return lines.join('\n') -} - -function formatRange (range: string): string { - if (range.includes(' ') || range === '*') { - return `"${range}"` - } - return range -} diff --git a/deps/inspection/commands/tsconfig.json b/deps/inspection/commands/tsconfig.json index bfd1dff15c..3f6ded79cd 100644 --- a/deps/inspection/commands/tsconfig.json +++ b/deps/inspection/commands/tsconfig.json @@ -89,6 +89,9 @@ }, { "path": "../peers-checker" + }, + { + "path": "../peers-issues-renderer" } ] } diff --git a/deps/inspection/peers-issues-renderer/README.md b/deps/inspection/peers-issues-renderer/README.md new file mode 100644 index 0000000000..da1bd64f8a --- /dev/null +++ b/deps/inspection/peers-issues-renderer/README.md @@ -0,0 +1,13 @@ +# @pnpm/deps.inspection.peers-issues-renderer + +> Visualizes peer dependency issues + +## Installation + +``` +pnpm add @pnpm/deps.inspection.peers-issues-renderer +``` + +## License + +[MIT](LICENSE) diff --git a/deps/inspection/peers-issues-renderer/package.json b/deps/inspection/peers-issues-renderer/package.json new file mode 100644 index 0000000000..9210fca4bc --- /dev/null +++ b/deps/inspection/peers-issues-renderer/package.json @@ -0,0 +1,47 @@ +{ + "name": "@pnpm/deps.inspection.peers-issues-renderer", + "version": "1100.0.0-0", + "description": "Visualizes peer dependency issues", + "keywords": [ + "pnpm", + "pnpm11" + ], + "license": "MIT", + "funding": "https://opencollective.com/pnpm", + "repository": "https://github.com/pnpm/pnpm/tree/main/deps/inspection/peers-issues-renderer", + "homepage": "https://github.com/pnpm/pnpm/tree/main/deps/inspection/peers-issues-renderer#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": { + "test": "pn compile && pn .test", + "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"", + "prepublishOnly": "tsgo --build", + "compile": "tsgo --build && pn lint --fix", + ".test": "cross-env NODE_OPTIONS=\"$NODE_OPTIONS --experimental-vm-modules --disable-warning=ExperimentalWarning --disable-warning=DEP0169\" jest" + }, + "dependencies": { + "@pnpm/types": "workspace:*", + "chalk": "catalog:" + }, + "devDependencies": { + "@jest/globals": "catalog:", + "@pnpm/deps.inspection.peers-issues-renderer": "workspace:*" + }, + "engines": { + "node": ">=22.13" + }, + "jest": { + "preset": "@pnpm/jest-config" + } +} diff --git a/deps/inspection/peers-issues-renderer/src/index.ts b/deps/inspection/peers-issues-renderer/src/index.ts new file mode 100644 index 0000000000..6db078c7af --- /dev/null +++ b/deps/inspection/peers-issues-renderer/src/index.ts @@ -0,0 +1,68 @@ +import type { BadPeerDependencyIssue, PeerDependencyIssuesByProjects } from '@pnpm/types' +import chalk from 'chalk' + +export function renderPeerIssues (issuesByProjects: PeerDependencyIssuesByProjects): string { + const sections: string[] = [] + + for (const [, { bad, missing, conflicts, intersections }] of Object.entries(issuesByProjects)) { + for (const [peerName, issues] of Object.entries(bad)) { + const header = `${chalk.yellowBright('✕ unmet peer')} ${chalk.bold(peerName)}` + for (const [foundVersion, group] of groupByFoundVersion(issues)) { + const installed = ` ${chalk.cyan('Installed:')} ${chalk.dim(foundVersion)}` + sections.push(`${header}\n${installed}\n${formatRequiredBy(group)}`) + } + } + + for (const [peerName, issues] of Object.entries(missing)) { + if (!intersections[peerName] && !conflicts.includes(peerName)) continue + const conflict = conflicts.includes(peerName) + const header = conflict + ? `${chalk.red('✕ conflicting peer')} ${chalk.bold(peerName)}` + : `${chalk.red('✕ missing peer')} ${chalk.bold(peerName)}` + sections.push(`${header}\n${formatRequiredBy(issues)}`) + } + } + + if (sections.length === 0) return '' + return sections.join('\n\n') +} + +function formatRequiredBy (issues: Array<{ parents: Array<{ name: string, version: string }>, wantedRange: string }>): string { + const byRange = new Map>() + for (const issue of issues) { + const declaring = issue.parents[issue.parents.length - 1] + const pkg = declaring ? `${declaring.name}@${declaring.version}` : '' + if (!byRange.has(issue.wantedRange)) { + byRange.set(issue.wantedRange, new Set()) + } + byRange.get(issue.wantedRange)!.add(pkg) + } + const lines: string[] = [` ${chalk.cyan('Wanted:')}`] + for (const [range, pkgs] of byRange) { + lines.push(` ${chalk.cyanBright(formatRange(range))}${chalk.cyan(':')}`) + for (const pkg of pkgs) { + lines.push(` ${chalk.dim(pkg)}`) + } + } + return lines.join('\n') +} + +function formatRange (range: string): string { + if (range.includes(' ') || range === '*') { + return `"${range}"` + } + return range +} + +function groupByFoundVersion (issues: BadPeerDependencyIssue[]): Map { + const groups = new Map() + for (const issue of issues) { + const list = groups.get(issue.foundVersion) + if (list) { + list.push(issue) + } else { + groups.set(issue.foundVersion, [issue]) + } + } + return groups +} diff --git a/deps/inspection/peers-issues-renderer/test/__snapshots__/index.ts.snap b/deps/inspection/peers-issues-renderer/test/__snapshots__/index.ts.snap new file mode 100644 index 0000000000..0557082976 --- /dev/null +++ b/deps/inspection/peers-issues-renderer/test/__snapshots__/index.ts.snap @@ -0,0 +1,58 @@ +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing + +exports[`renderPeerIssues() formats version ranges with spaces or "*" with quotes 1`] = ` +"✕ missing peer a + Wanted: + "*": + z@1.0.0 + +✕ missing peer b + Wanted: + "1 || 2": + z@1.0.0" +`; + +exports[`renderPeerIssues() handles missing parents gracefully 1`] = ` +"✕ missing peer foo + Wanted: + ">=1.0.0 <3.0.0": + " +`; + +exports[`renderPeerIssues() renders bad peer dependencies 1`] = ` +"✕ unmet peer a + Installed: 2 + Wanted: + 3: + b@1.0.0" +`; + +exports[`renderPeerIssues() renders conflicting peer dependencies 1`] = ` +"✕ conflicting peer a + Wanted: + ^1.0.0: + b@1.0.0 + ^2.0.0: + c@1.0.0" +`; + +exports[`renderPeerIssues() renders missing peer dependencies that are required 1`] = ` +"✕ missing peer a + Wanted: + ^1.0.0: + b@1.0.0" +`; + +exports[`renderPeerIssues() splits bad peer dependencies by foundVersion 1`] = ` +"✕ unmet peer a + Installed: 1.0.0 + Wanted: + ^2.0.0: + b@1.0.0 + +✕ unmet peer a + Installed: 2.0.0 + Wanted: + ^3.0.0: + c@1.0.0" +`; diff --git a/deps/inspection/peers-issues-renderer/test/index.ts b/deps/inspection/peers-issues-renderer/test/index.ts new file mode 100644 index 0000000000..ba7a10b7c7 --- /dev/null +++ b/deps/inspection/peers-issues-renderer/test/index.ts @@ -0,0 +1,156 @@ +import { stripVTControlCharacters as stripAnsi } from 'node:util' + +import { expect, test } from '@jest/globals' +import { renderPeerIssues } from '@pnpm/deps.inspection.peers-issues-renderer' + +test('renderPeerIssues() returns an empty string when there are no issues', () => { + expect(renderPeerIssues({ + '.': { + missing: {}, + bad: {}, + conflicts: [], + intersections: {}, + }, + })).toBe('') +}) + +test('renderPeerIssues() renders bad peer dependencies', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: {}, + bad: { + a: [ + { + parents: [ + { name: 'b', version: '1.0.0' }, + ], + foundVersion: '2', + resolvedFrom: [], + optional: false, + wantedRange: '3', + }, + ], + }, + conflicts: [], + intersections: {}, + }, + }))).toMatchSnapshot() +}) + +test('renderPeerIssues() splits bad peer dependencies by foundVersion', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: {}, + bad: { + a: [ + { + parents: [{ name: 'b', version: '1.0.0' }], + foundVersion: '1.0.0', + resolvedFrom: [], + optional: false, + wantedRange: '^2.0.0', + }, + { + parents: [{ name: 'c', version: '1.0.0' }], + foundVersion: '2.0.0', + resolvedFrom: [], + optional: false, + wantedRange: '^3.0.0', + }, + ], + }, + conflicts: [], + intersections: {}, + }, + }))).toMatchSnapshot() +}) + +test('renderPeerIssues() renders missing peer dependencies that are required', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: { + a: [ + { + parents: [ + { name: 'b', version: '1.0.0' }, + ], + optional: false, + wantedRange: '^1.0.0', + }, + ], + }, + bad: {}, + conflicts: [], + intersections: { a: '^1.0.0' }, + }, + }))).toMatchSnapshot() +}) + +test('renderPeerIssues() renders conflicting peer dependencies', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: { + a: [ + { + parents: [{ name: 'b', version: '1.0.0' }], + optional: false, + wantedRange: '^1.0.0', + }, + { + parents: [{ name: 'c', version: '1.0.0' }], + optional: false, + wantedRange: '^2.0.0', + }, + ], + }, + bad: {}, + conflicts: ['a'], + intersections: {}, + }, + }))).toMatchSnapshot() +}) + +test('renderPeerIssues() formats version ranges with spaces or "*" with quotes', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: { + a: [ + { + parents: [{ name: 'z', version: '1.0.0' }], + optional: false, + wantedRange: '*', + }, + ], + b: [ + { + parents: [{ name: 'z', version: '1.0.0' }], + optional: false, + wantedRange: '1 || 2', + }, + ], + }, + bad: {}, + conflicts: [], + intersections: { a: '*', b: '1 || 2' }, + }, + }))).toMatchSnapshot() +}) + +test('renderPeerIssues() handles missing parents gracefully', () => { + expect(stripAnsi(renderPeerIssues({ + '.': { + missing: { + foo: [ + { + parents: [], + optional: false, + wantedRange: '>=1.0.0 <3.0.0', + }, + ], + }, + bad: {}, + conflicts: [], + intersections: { foo: '^1.0.0' }, + }, + }))).toMatchSnapshot() +}) diff --git a/deps/inspection/peers-issues-renderer/test/tsconfig.json b/deps/inspection/peers-issues-renderer/test/tsconfig.json new file mode 100644 index 0000000000..78f62072ca --- /dev/null +++ b/deps/inspection/peers-issues-renderer/test/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "noEmit": false, + "outDir": "../node_modules/.test.lib", + "rootDir": "..", + "isolatedModules": true + }, + "include": [ + "**/*.ts", + "../../../../__typings__/**/*.d.ts" + ], + "references": [ + { + "path": ".." + } + ] +} diff --git a/deps/inspection/peers-issues-renderer/tsconfig.json b/deps/inspection/peers-issues-renderer/tsconfig.json new file mode 100644 index 0000000000..baaf326910 --- /dev/null +++ b/deps/inspection/peers-issues-renderer/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "@pnpm/tsconfig", + "compilerOptions": { + "outDir": "lib", + "rootDir": "src" + }, + "include": [ + "src/**/*.ts", + "../../../__typings__/**/*.d.ts" + ], + "references": [ + { + "path": "../../../core/types" + } + ] +} diff --git a/deps/inspection/peers-issues-renderer/tsconfig.lint.json b/deps/inspection/peers-issues-renderer/tsconfig.lint.json new file mode 100644 index 0000000000..5ea6d52203 --- /dev/null +++ b/deps/inspection/peers-issues-renderer/tsconfig.lint.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "src/**/*.ts", + "test/**/*.ts", + "../../../__typings__/**/*.d.ts" + ] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7653bbae1..6d4e4c5b90 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2245,6 +2245,9 @@ importers: '@pnpm/core-loggers': specifier: workspace:* version: link:../../core/core-loggers + '@pnpm/deps.inspection.peers-issues-renderer': + specifier: workspace:* + version: link:../../deps/inspection/peers-issues-renderer '@pnpm/error': specifier: workspace:* version: link:../../core/error @@ -3357,6 +3360,9 @@ importers: '@pnpm/deps.inspection.peers-checker': specifier: workspace:* version: link:../peers-checker + '@pnpm/deps.inspection.peers-issues-renderer': + specifier: workspace:* + version: link:../peers-issues-renderer '@pnpm/error': specifier: workspace:* version: link:../../../core/error @@ -3626,6 +3632,22 @@ importers: specifier: 'catalog:' version: 7.7.1 + deps/inspection/peers-issues-renderer: + dependencies: + '@pnpm/types': + specifier: workspace:* + version: link:../../../core/types + chalk: + specifier: 'catalog:' + version: 5.6.2 + devDependencies: + '@jest/globals': + specifier: 'catalog:' + version: 30.3.0 + '@pnpm/deps.inspection.peers-issues-renderer': + specifier: workspace:* + version: 'link:' + deps/inspection/tree-builder: dependencies: '@pnpm/config.matcher':