yarn-why-duplicate 1.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,16 +1,16 @@
1
- <h3 align="center">
1
+ <h1 align="center">
2
2
  yarn-why-duplicate
3
- </h3>
3
+ </h1>
4
4
 
5
5
  <p align="center">
6
6
  Simple bin to know why a package is duplicated
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
- <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/v/yarn-why-duplicate.svg?style=flat-square"></a>
11
- <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/dw/yarn-why-duplicate.svg?style=flat-square"></a>
12
- <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/node/v/yarn-why-duplicate.svg?style=flat-square"></a>
13
- <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/types/yarn-why-duplicate.svg?style=flat-square"></a>
10
+ <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/v/yarn-why-duplicate.svg?style=flat-square" alt="npm version"></a>
11
+ <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/dw/yarn-why-duplicate.svg?style=flat-square" alt="npm downloads"></a>
12
+ <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/node/v/yarn-why-duplicate.svg?style=flat-square" alt="node version"></a>
13
+ <a href="https://npmjs.org/package/yarn-why-duplicate"><img src="https://img.shields.io/npm/types/yarn-why-duplicate.svg?style=flat-square" alt="types"></a>
14
14
  </p>
15
15
 
16
16
  ## Usage
@@ -20,3 +20,50 @@ With yarn berry:
20
20
  ```
21
21
  yarn dlx yarn-why-duplicate <dependencyName>
22
22
  ```
23
+
24
+ One package name, no flags. It runs `yarn why <dependencyName> --json` in the
25
+ working directory, groups the answer by resolved version, and prints each
26
+ version with the dependents that asked for it and the range they asked with:
27
+
28
+ ```
29
+ Found 2 versions:
30
+
31
+ semver@npm:7.8.5
32
+ - eslint@npm:10.4.0 (semver@npm:^7.6.3)
33
+ - ts-api-utils@npm:2.1.0 (semver@npm:^7.7.1)
34
+
35
+ semver@npm:6.3.1
36
+ - @babel/core@npm:7.28.4 (semver@npm:^6.3.1)
37
+ ```
38
+
39
+ `No version found` means yarn reported nothing for that name — usually a typo,
40
+ or a package that is not in the tree.
41
+
42
+ Requires yarn berry (>= 2): yarn 1's `yarn why` output is a different format and
43
+ is rejected with an explicit message rather than misparsed. Exits 1 on that and
44
+ on any error yarn reports.
45
+
46
+ ### Prefer yarn-berry-why-duplicate
47
+
48
+ This is the original tool, kept working and unchanged. It shells out to
49
+ `yarn why`, so it explains one package at a time, spawns yarn per run, and knows
50
+ nothing about lockstep families or about fixing anything.
51
+
52
+ [yarn-berry-why-duplicate](../yarn-berry-deduplicate) reads `yarn.lock` directly
53
+ and is what to reach for now: it lists every duplicate at once, takes globs and
54
+ package filters, reports the lockstep clusters, tells you which copies can be
55
+ merged — and its sibling `yarn-berry-deduplicate` applies the merges.
56
+
57
+ ## Notes
58
+
59
+ - CLI only: there is no importable API. The `exports` map only exposes
60
+ `./package.json`, so `import "yarn-why-duplicate"` fails by design. Internally
61
+ the bin is three steps,
62
+ `readAndParseYarnWhy` → `identifyDuplicates` → `displayDuplicates`, each in
63
+ its own file under `lib/` and each unit-tested against recorded `yarn why`
64
+ output in `test/fixtures/`.
65
+ - Plain JavaScript, no TypeScript and no build; node `>=22.18.0`.
66
+ - `Found N versions` counts every version of the named package, duplicated or
67
+ not — one version is a normal answer, not an error.
68
+ - Colors and descriptor formatting come from `@yarnpkg/core`, configured from
69
+ the working directory, so output matches what yarn itself prints.
@@ -1,19 +1,19 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { displayDuplicates } from '../lib/displayDuplicates.js';
4
- import { identifyDuplicates } from '../lib/identifyDuplicates.js';
5
- import { readAndParseYarnWhy } from '../lib/readAndParseYarnWhy.js';
3
+ import { displayDuplicates } from "../lib/displayDuplicates.js";
4
+ import { identifyDuplicates } from "../lib/identifyDuplicates.js";
5
+ import { readAndParseYarnWhy } from "../lib/readAndParseYarnWhy.js";
6
6
 
7
7
  const pkgName = process.argv.slice(2)[0];
8
8
 
9
9
  const yarnWhyResult = readAndParseYarnWhy(pkgName);
10
10
 
11
11
  for (const line of yarnWhyResult) {
12
- if (line.type === 'error') {
12
+ if (line.type === "error") {
13
13
  console.error(`yarn error: ${line.data}`);
14
14
  process.exit(1);
15
- } else if (line.type === 'step') {
16
- console.error('yarn 1 is not supported, use yarn berry (>=2)');
15
+ } else if (line.type === "step") {
16
+ console.error("yarn 1 is not supported, use yarn berry (>=2)");
17
17
  process.exit(1);
18
18
  }
19
19
  }
@@ -1,4 +1,4 @@
1
- import { structUtils, Configuration } from '@yarnpkg/core';
1
+ import { Configuration, structUtils } from "@yarnpkg/core";
2
2
 
3
3
  export const displayDuplicates = (
4
4
  groupByVersions,
@@ -6,13 +6,13 @@ export const displayDuplicates = (
6
6
  configuration = Configuration.create(process.cwd()),
7
7
  ) => {
8
8
  if (groupByVersions.length === 0) {
9
- log('No version found');
9
+ log("No version found");
10
10
  return;
11
11
  }
12
12
 
13
13
  log(
14
14
  `Found ${groupByVersions.length} version${
15
- groupByVersions.length === 1 ? '' : 's'
15
+ groupByVersions.length === 1 ? "" : "s"
16
16
  }:`,
17
17
  );
18
18
  log();
@@ -25,7 +25,7 @@ export const displayDuplicates = (
25
25
  configuration,
26
26
  source,
27
27
  )} (${structUtils.prettyDescriptor(configuration, descriptor)})`,
28
- ); // TODO prettyDescriptor from structUtils
28
+ );
29
29
  }
30
30
  log();
31
31
  }
@@ -1,5 +1,5 @@
1
- import { structUtils } from '@yarnpkg/core';
2
- import { compare as compareRange } from 'semver';
1
+ import { structUtils } from "@yarnpkg/core";
2
+ import { compare as compareRange } from "semver";
3
3
 
4
4
  export const identifyDuplicates = (yarnWhyResult) => {
5
5
  const groupByVersions = new Map();
@@ -1,16 +1,16 @@
1
- import { spawnSync } from 'child_process';
1
+ import { spawnSync } from "node:child_process";
2
2
 
3
3
  export const parseYarnWhy = (content) => {
4
4
  return content
5
- .split('\n')
5
+ .split("\n")
6
6
  .filter(Boolean)
7
7
  .map((line) => JSON.parse(line));
8
8
  };
9
9
 
10
10
  export const readAndParseYarnWhy = (pkgName) => {
11
- const { stdout, stderr } = spawnSync('yarn', ['why', pkgName, '--json'], {
12
- encoding: 'utf8',
13
- stdio: 'pipe',
11
+ const { stdout, stderr } = spawnSync("yarn", ["why", pkgName, "--json"], {
12
+ encoding: "utf8",
13
+ stdio: "pipe",
14
14
  pwd: process.cwd(),
15
15
  });
16
16
  if (stderr) {
package/package.json CHANGED
@@ -1,58 +1,44 @@
1
1
  {
2
2
  "name": "yarn-why-duplicate",
3
- "version": "1.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Simple bin to know why a package is duplicated",
5
5
  "keywords": [
6
- "yarn",
7
- "berry"
6
+ "berry",
7
+ "yarn"
8
8
  ],
9
- "author": "Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)",
10
- "license": "ISC",
11
- "repository": "https://github.com/christophehurpeau/yarn-why-duplicate.git",
12
- "homepage": "https://github.com/christophehurpeau/yarn-why-duplicate#readme",
9
+ "homepage": "https://github.com/christophehurpeau/pm-tools",
13
10
  "bugs": {
14
- "url": "https://github.com/christophehurpeau/yarn-why-duplicate/issues"
11
+ "url": "https://github.com/christophehurpeau/pm-tools/issues"
15
12
  },
16
- "type": "module",
17
- "engines": {
18
- "node": ">=18.0.0"
13
+ "license": "MIT",
14
+ "author": "Christophe Hurpeau <christophe@hurpeau.com> (https://christophe.hurpeau.com)",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/christophehurpeau/pm-tools.git",
18
+ "directory": "packages/yarn-why-duplicate"
19
19
  },
20
- "packageManager": "yarn@3.5.0",
21
- "main": "./lib/index.js",
20
+ "bin": "./bin/yarn-why-duplicate.mjs",
21
+ "files": [
22
+ "lib",
23
+ "bin"
24
+ ],
25
+ "type": "module",
26
+ "sideEffects": false,
22
27
  "exports": {
23
- ".": "./lib/index.js",
24
28
  "./package.json": "./package.json"
25
29
  },
26
- "sideEffects": false,
27
- "bin": "./bin/yarn-why-duplicate.mjs",
28
30
  "scripts": {
29
- "checks": "node scripts/check-package.js",
30
- "clean:build": "true",
31
- "lint": "yarn run lint:prettier && yarn run lint:eslint",
32
- "lint:eslint": "eslint --report-unused-disable-directives --resolve-plugins-relative-to . --quiet *.{js,cjs,mjs} lib bin scripts",
33
- "lint:prettier": "pob-root-prettier --check .",
34
- "lint:prettier:fix": "pob-root-prettier --write .",
35
- "postinstallDev": "pob-root-postinstall",
36
- "test": "node --test",
37
- "test:coverage": "node --test",
38
- "test:watch": "node --test --watch"
31
+ "lint": "bun run lint:oxlint && bun run lint:eslint",
32
+ "lint:eslint": "bun run --cwd '../..' eslint --quiet 'packages/yarn-why-duplicate'",
33
+ "lint:oxlint": "bun run --cwd '../..' oxlint --quiet 'packages/yarn-why-duplicate'",
34
+ "test": "bun run --cwd '../..' test -- 'packages/yarn-why-duplicate'"
39
35
  },
40
- "prettier": "@pob/root/prettier-config",
41
- "commitlint": {
42
- "extends": [
43
- "@pob/commitlint-config"
44
- ]
45
- },
46
- "pob": {},
47
36
  "dependencies": {
48
- "@yarnpkg/core": "4.0.0-rc.42",
49
- "semver": "7.5.0"
37
+ "@yarnpkg/core": "4.9.2",
38
+ "semver": "7.8.5"
39
+ },
40
+ "engines": {
41
+ "node": ">=22.18.0"
50
42
  },
51
- "devDependencies": {
52
- "@pob/commitlint-config": "5.1.1",
53
- "@pob/eslint-config": "50.0.4",
54
- "@pob/root": "7.8.0",
55
- "check-package-dependencies": "6.3.2",
56
- "eslint": "8.39.0"
57
- }
43
+ "pob": {}
58
44
  }
package/.editorconfig DELETED
@@ -1,13 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # http://editorconfig.org
4
-
5
- root = true
6
-
7
- [*]
8
- indent_style = space
9
- indent_size = 2
10
- end_of_line = lf
11
- charset = utf-8
12
- trim_trailing_whitespace = true
13
- insert_final_newline = true
package/.eslintrc.json DELETED
@@ -1,4 +0,0 @@
1
- {
2
- "root": true,
3
- "extends": ["@pob/eslint-config/root-module"]
4
- }
package/.prettierignore DELETED
@@ -1,2 +0,0 @@
1
- CHANGELOG.md
2
- /.yarn/**/*
package/CHANGELOG.md DELETED
@@ -1,30 +0,0 @@
1
- # Changelog
2
-
3
- ## [1.2.0](https://github.com/christophehurpeau/yarn-why-duplicate/compare/v1.1.0...v1.2.0) (2023-04-25)
4
-
5
-
6
- ### Features
7
-
8
- * force 1.2.0 ([72688d8](https://github.com/christophehurpeau/yarn-why-duplicate/commit/72688d83af568ebb83fe8ee261b6ac18adf44f0e))
9
-
10
- ## [1.1.0](https://github.com/christophehurpeau/yarn-why-duplicate/compare/v1.0.0...v1.1.0) (2023-04-25)
11
-
12
-
13
- ### Features
14
-
15
- * force 1.1.0 ([d333635](https://github.com/christophehurpeau/yarn-why-duplicate/commit/d3336353ffe709910577310116dab70dd8f25f5c))
16
-
17
- ## 1.0.0 (2023-04-25)
18
-
19
-
20
- ### Features
21
-
22
- * **deps:** update dependency semver to v7.5.0 ([#4](https://github.com/christophehurpeau/yarn-why-duplicate/issues/4)) ([f9eee30](https://github.com/christophehurpeau/yarn-why-duplicate/commit/f9eee30e153dea0dc8dabb69b2484dd6dd3be0dc))
23
- * first commit ([c3a6354](https://github.com/christophehurpeau/yarn-why-duplicate/commit/c3a6354ae139baffc75c4582af439db4f496329c))
24
-
25
-
26
- ### Bug Fixes
27
-
28
- * add try/catch on compareRange ([357eed7](https://github.com/christophehurpeau/yarn-why-duplicate/commit/357eed715012b156d4abd447f9d7232fdc066d72))
29
- * use virtuals ([340d56a](https://github.com/christophehurpeau/yarn-why-duplicate/commit/340d56a8abc6c81b9973ed5ecb80604e6905990b))
30
- * virtual child ([8798439](https://github.com/christophehurpeau/yarn-why-duplicate/commit/8798439ccf4f7ee40292ce9fb734e573a37c1d71))
@@ -1,4 +0,0 @@
1
- {
2
- "root": true,
3
- "extends": ["@pob/eslint-config/node-module"]
4
- }
@@ -1,3 +0,0 @@
1
- import { createCheckPackage } from 'check-package-dependencies';
2
-
3
- await createCheckPackage().checkRecommended({}).run();