🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@changesets/get-dependents-graph

Package Overview
Dependencies
Maintainers
2
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@changesets/get-dependents-graph - npm Package Compare versions

Comparing version
3.0.0-next.6
to
3.0.0-next.7
+0
-1
dist/index.d.mts
import { Packages } from "@changesets/types";
//#region src/index.d.ts

@@ -4,0 +3,0 @@ declare function getDependentsGraph(packages: Packages, opts?: {

+5
-2
{
"name": "@changesets/get-dependents-graph",
"version": "3.0.0-next.6",
"version": "3.0.0-next.7",
"description": "Get the graph of dependents in a monorepo",

@@ -11,2 +11,5 @@ "license": "MIT",

},
"files": [
"dist"
],
"type": "module",

@@ -19,3 +22,3 @@ "exports": {

"semver": "^7.8.1",
"@changesets/types": "^7.0.0-next.6"
"@changesets/types": "^7.0.0-next.7"
},

@@ -22,0 +25,0 @@ "devDependencies": {

# @changesets/get-dependents-graph
## 3.0.0-next.6
### Patch Changes
- Updated dependencies [[`4c26f2f`](https://github.com/changesets/changesets/commit/4c26f2faac89b53d3305cf73c9e9cfca5aa88f5f), [`813bbf3`](https://github.com/changesets/changesets/commit/813bbf314d051bfee3b46a793f94b396ef2a4df1)]:
- @changesets/types@7.0.0-next.6
## 3.0.0-next.5
### Patch Changes
- Updated dependencies [[`88f2abb`](https://github.com/changesets/changesets/commit/88f2abb5e14748b08e3441fd871df60dd1c4737f)]:
- @changesets/types@7.0.0-next.5
## 3.0.0-next.4
### Patch Changes
- [#2004](https://github.com/changesets/changesets/pull/2004) [`169b128`](https://github.com/changesets/changesets/commit/169b128522f0e53ef228f3acd8118709b0f72156) Thanks [@ghostdevv](https://github.com/ghostdevv)! - Replace `picocolors` with `node:util`'s `styleText`
- Updated dependencies [[`062530b`](https://github.com/changesets/changesets/commit/062530b825d53abc9d8934f3a50cc61ff3ff82b8)]:
- @changesets/types@7.0.0-next.4
## 3.0.0-next.3
### Major Changes
- [#1954](https://github.com/changesets/changesets/pull/1954) [`ed6728c`](https://github.com/changesets/changesets/commit/ed6728ce3c089caaee19f71194a0cd7029480069) Thanks [@beeequeue](https://github.com/beeequeue)! - Bumped supported Node versions to `^22.11 || ^24 || >=26`
### Minor Changes
- [#1969](https://github.com/changesets/changesets/pull/1969) [`2c7c043`](https://github.com/changesets/changesets/commit/2c7c043d7071440009f8a69eff0b0c6746ac7625) Thanks [@marcalexiei](https://github.com/marcalexiei)! - Add a named export that mirrors the current `default` export
The `default` export is slated for removal in the next major release, so this ensures a smoother transition path.
### Patch Changes
- Updated dependencies [[`ed6728c`](https://github.com/changesets/changesets/commit/ed6728ce3c089caaee19f71194a0cd7029480069), [`a0b5326`](https://github.com/changesets/changesets/commit/a0b5326570e8e7bf5e35c1cefe8f70d9a51a5cd7)]:
- @changesets/types@7.0.0-next.3
## 3.0.0-next.2
### Major Changes
- [#1655](https://github.com/changesets/changesets/pull/1655) [`db46911`](https://github.com/changesets/changesets/commit/db46911e57603f20a158a47bbbebd112272c84e2) Thanks [@bluwy](https://github.com/bluwy)! - Update `@manypkg/get-packages` which drops support for detecting packages in Bolt monorepos and adds support for npm monorepos
### Patch Changes
- Updated dependencies [[`c19b112`](https://github.com/changesets/changesets/commit/c19b1123d27986da0e14e99d65b0f9a408def35c)]:
- @changesets/types@7.0.0-next.2
## 2.1.4
### Patch Changes
- [#1888](https://github.com/changesets/changesets/pull/1888) [`036fdd4`](https://github.com/changesets/changesets/commit/036fdd451367226d0f2cd8af1e0a7f37a65e3464) Thanks [@mixelburg](https://github.com/mixelburg)! - Fix dependency graph validation for workspace path references. Valid `workspace:packages/pkg` specifiers are now treated as local dependencies instead of being rejected as invalid ranges.
## 3.0.0-next.1
### Major Changes
- [#1656](https://github.com/changesets/changesets/pull/1656) [`268a29f`](https://github.com/changesets/changesets/commit/268a29fedc948f22c672a3b1e3e51df4427f478d) Thanks [@bluwy](https://github.com/bluwy)! - Bumps minimum node version to `>=20.0.0`
### Patch Changes
- Updated dependencies [[`268a29f`](https://github.com/changesets/changesets/commit/268a29fedc948f22c672a3b1e3e51df4427f478d)]:
- @changesets/types@7.0.0-next.1
## 3.0.0-next.0
### Major Changes
- [#1479](https://github.com/changesets/changesets/pull/1479) [`7f34a00`](https://github.com/changesets/changesets/commit/7f34a00aab779a941a406b17f5a85895144fc0a5) Thanks [@bluwy](https://github.com/bluwy)! - Add `"engines"` field for explicit node version support. The supported node versions are `>=18.0.0`.
- [#1482](https://github.com/changesets/changesets/pull/1482) [`df424a4`](https://github.com/changesets/changesets/commit/df424a4a09eea15b0fa9159ee0b98af0d95f58a7) Thanks [@Andarist](https://github.com/Andarist)! - From now on this package is going to be published as ES module.
### Patch Changes
- Updated dependencies [[`7f34a00`](https://github.com/changesets/changesets/commit/7f34a00aab779a941a406b17f5a85895144fc0a5), [`df424a4`](https://github.com/changesets/changesets/commit/df424a4a09eea15b0fa9159ee0b98af0d95f58a7)]:
- @changesets/types@7.0.0-next.0
## 2.1.3
### Patch Changes
- Updated dependencies [[`84a4a1b`](https://github.com/changesets/changesets/commit/84a4a1b1d399bfd0a58677b0182b9c053194febf)]:
- @changesets/types@6.1.0
## 2.1.2
### Patch Changes
- [#1417](https://github.com/changesets/changesets/pull/1417) [`bc75c1a`](https://github.com/changesets/changesets/commit/bc75c1a74c2d46e08620c7aa0e9f4f5ef40a9b55) Thanks [@trivikr](https://github.com/trivikr)! - Replace `chalk` with `picocolors` to reduce install size
- [#1445](https://github.com/changesets/changesets/pull/1445) [`52c302a`](https://github.com/changesets/changesets/commit/52c302a48a662f71585f18f91dad3cbe49d75890) Thanks [@bluwy](https://github.com/bluwy)! - Remove unused `@babel/runtime` dependency
## 2.1.1
### Patch Changes
- [#1400](https://github.com/changesets/changesets/pull/1400) [`dd6e5bb`](https://github.com/changesets/changesets/commit/dd6e5bbf74e246d7a742aa50424989462679b0ca) Thanks [@Andarist](https://github.com/Andarist)! - Fixed a crash in `getDependentsGraph` in a scenario when a workspace depends on the root workspace
## 2.1.0
### Minor Changes
- [#1370](https://github.com/changesets/changesets/pull/1370) [`5e9d33a`](https://github.com/changesets/changesets/commit/5e9d33a2e659abdcf26f204a76a9465cf4b26d6b) Thanks [@Andarist](https://github.com/Andarist)! - Added a new `ignoreDevDependencies` option
## 2.0.0
### Major Changes
- [#1185](https://github.com/changesets/changesets/pull/1185) [`a971652`](https://github.com/changesets/changesets/commit/a971652ec1403aab3fb89eb2f1640bd5012b895a) Thanks [@Andarist](https://github.com/Andarist)! - `package.json#exports` have been added to limit what (and how) code might be imported from the package.
### Patch Changes
- Updated dependencies [[`a971652`](https://github.com/changesets/changesets/commit/a971652ec1403aab3fb89eb2f1640bd5012b895a)]:
- @changesets/types@6.0.0
## 1.3.6
### Patch Changes
- [#1176](https://github.com/changesets/changesets/pull/1176) [`41988ce`](https://github.com/changesets/changesets/commit/41988ceb8c1cedd3857c939448bf3965494ff0a4) Thanks [@joshwooding](https://github.com/joshwooding)! - Bump [`semver`](https://github.com/npm/node-semver) dependency to v7.5.3
## 1.3.5
### Patch Changes
- Updated dependencies [[`521205d`](https://github.com/changesets/changesets/commit/521205dc8c70fe71b181bd3c4bb7c9c6d2e721d2)]:
- @changesets/types@5.2.1
## 1.3.4
### Patch Changes
- Updated dependencies [[`8c08469`](https://github.com/changesets/changesets/commit/8c0846977597ddaf51aaeb35f1f0f9428bf8ba14)]:
- @changesets/types@5.2.0
## 1.3.3
### Patch Changes
- Updated dependencies [[`dd9b76f`](https://github.com/changesets/changesets/commit/dd9b76f162a546ae8b412e0cb10277f971f3585e)]:
- @changesets/types@5.1.0
## 1.3.2
### Patch Changes
- Updated dependencies [[`c87eba6`](https://github.com/changesets/changesets/commit/c87eba6f80a34563b7382f87472c29f6dafb546c)]:
- @changesets/types@5.0.0
## 1.3.1
### Patch Changes
- Updated dependencies [[`27a5a82`](https://github.com/changesets/changesets/commit/27a5a82188914570d192162f9d045dfd082a3c15)]:
- @changesets/types@4.1.0
## 1.3.0
### Minor Changes
- [#704](https://github.com/changesets/changesets/pull/704) [`6f9c9d6`](https://github.com/changesets/changesets/commit/6f9c9d60c0e02c79d555c48deb01559057f1d252) Thanks [@Andarist](https://github.com/Andarist)! - Dependencies specified using a tag will no longer mark the graph as invalid. With such dependencies the user's intent is to fetch those from the registry even if otherwise they could be linked locally.
## 1.2.4
### Patch Changes
- [#667](https://github.com/changesets/changesets/pull/667) [`fe8db75`](https://github.com/changesets/changesets/commit/fe8db7500f81caea9064f8bec02bcb77e0fd8fce) Thanks [@fz6m](https://github.com/fz6m)! - Upgraded `@manypkg/get-packages` dependency to fix getting correct packages in pnpm workspaces with exclude rules.
- Updated dependencies [[`9a993ba`](https://github.com/changesets/changesets/commit/9a993ba09629c1620d749432520470cec49d3a96)]:
- @changesets/types@4.0.2
## 1.2.3
### Patch Changes
- [#585](https://github.com/changesets/changesets/pull/585) [`74dda8c`](https://github.com/changesets/changesets/commit/74dda8c0d8bd1741ca7b19f0ccb37b2330dc9549) Thanks [@javier-garcia-meteologica](https://github.com/javier-garcia-meteologica)! - Add support for `workspace:^` and `workspace:~` dependency ranges.
## 1.2.2
### Patch Changes
- Updated dependencies [[`e89e28a`](https://github.com/changesets/changesets/commit/e89e28a05f5fa43307db73812a6bcd269b62ddee)]:
- @changesets/types@4.0.1
## 1.2.1
### Patch Changes
- Updated dependencies [[`de2b4a5`](https://github.com/changesets/changesets/commit/de2b4a5a7b244a37d94625bcb70ecde9dde5b612)]:
- @changesets/types@4.0.0
## 1.2.0
### Minor Changes
- [`12f9a43`](https://github.com/changesets/changesets/commit/12f9a433a6c3ac38f9405fcd77c9108c423d7101) [#507](https://github.com/changesets/changesets/pull/507) Thanks [@zkochan](https://github.com/zkochan)! - New setting added: bumpVersionsWithWorkspaceProtocolOnly. When it is set to `true`, versions are bumped in `dependencies`, only if those versions are prefixed by the workspace protocol. For instance, `"foo": "workspace:^1.0.0"`.
### Patch Changes
- Updated dependencies [[`12f9a43`](https://github.com/changesets/changesets/commit/12f9a433a6c3ac38f9405fcd77c9108c423d7101)]:
- @changesets/types@3.3.0
## 1.1.3
### Patch Changes
- Updated dependencies [[`2b49d66`](https://github.com/changesets/changesets/commit/2b49d668ecaa1333bc5c7c5be4648dda1b11528d)]:
- @changesets/types@3.0.0
## 1.1.2
### Patch Changes
- [`d678da5`](https://github.com/changesets/changesets/commit/d678da5e9936862bb66e5edb538c5b8be23d4ffe) [#324](https://github.com/changesets/changesets/pull/324) Thanks [@zkochan](https://github.com/zkochan)! - Dev dependencies that are installed via the link or file protocol are ignored.
## 1.1.1
### Patch Changes
- [`1706fb7`](https://github.com/changesets/changesets/commit/1706fb751ecc2f5a792c42f467b2063078d58716) [#321](https://github.com/changesets/changesets/pull/321) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Fix TypeScript declarations
- Updated dependencies [[`1706fb7`](https://github.com/changesets/changesets/commit/1706fb751ecc2f5a792c42f467b2063078d58716)]:
- @changesets/types@2.0.1
## 1.1.0
### Minor Changes
- [`c3cc232`](https://github.com/changesets/changesets/commit/c3cc23204c6cb80487aced1b37ebe8ffde0e2111) [#311](https://github.com/changesets/changesets/pull/311) Thanks [@zkochan](https://github.com/zkochan)! - Added support for workspace ranges. Package graph validation understands them now and allows them to satisfy dependents' required ranges.
### Patch Changes
- Updated dependencies [[`011d57f`](https://github.com/changesets/changesets/commit/011d57f1edf9e37f75a8bef4f918e72166af096e)]:
- @changesets/types@2.0.0
## 1.0.1
### Patch Changes
- [`04ddfd7`](https://github.com/changesets/changesets/commit/04ddfd7c3acbfb84ef9c92873fe7f9dea1f5145c) [#305](https://github.com/changesets/changesets/pull/305) Thanks [@Noviny](https://github.com/Noviny)! - Add link to changelog in readme
- [`b49e1cf`](https://github.com/changesets/changesets/commit/b49e1cff65dca7fe9e341a35aa91704aa0e51cb3) [#306](https://github.com/changesets/changesets/pull/306) Thanks [@Andarist](https://github.com/Andarist)! - Ignore `node_modules` when glob searching for packages. This fixes an issue with package cycles.
- Updated dependencies [[`04ddfd7`](https://github.com/changesets/changesets/commit/04ddfd7c3acbfb84ef9c92873fe7f9dea1f5145c), [`e56928b`](https://github.com/changesets/changesets/commit/e56928bbd6f9096def06ac37487bdbf28efec9d1)]:
- @changesets/types@1.0.1
## 1.0.0
### Major Changes
- [`cc8c921`](https://github.com/changesets/changesets/commit/cc8c92143d4c4b7cca8b9917dfc830a40b5cda20) [#290](https://github.com/changesets/changesets/pull/290) Thanks [@mitchellhamilton](https://github.com/mitchellhamilton)! - Initial release of `@changesets/get-dependents-graph`. If you're migrating from `get-dependents-graph`, you will need to pass the `Packages` object(which is returned from `@manypkg/get-packages`) to `getDependentsGraph` and also import `getDependentsGraph` as a named export instead of a default export.
### Patch Changes
- Updated dependencies [[`41e2e3d`](https://github.com/changesets/changesets/commit/41e2e3dd1053ff2f35a1a07e60793c9099f26997), [`cc8c921`](https://github.com/changesets/changesets/commit/cc8c92143d4c4b7cca8b9917dfc830a40b5cda20), [`cc8c921`](https://github.com/changesets/changesets/commit/cc8c92143d4c4b7cca8b9917dfc830a40b5cda20), [`2363366`](https://github.com/changesets/changesets/commit/2363366756d1b15bddf6d803911baccfca03cbdf)]:
- @changesets/types@1.0.0
import path from "node:path";
import { stripVTControlCharacters } from "node:util";
import { temporarilySilenceLogs } from "@changesets/test-utils";
import type { Package } from "@changesets/types";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { getDependencyGraph } from "./get-dependency-graph.ts";
const consoleError = console.error;
beforeEach(() => {
console.error = vi.fn();
});
afterEach(() => {
console.error = consoleError;
});
describe("getting the dependency graph", function () {
it("should skip dependencies specified through the link protocol", function () {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { graph, valid } = getDependencyGraph(
{
tool: { type: "yarn" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "foo",
packageJson: {
name: "foo",
version: "1.0.0",
devDependencies: {
bar: "link:../bar",
},
},
},
{
dir: "bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(graph.get("foo")!.dependencies).toStrictEqual([]);
expect(valid).toBeTruthy();
expect((console.error as any).mock.calls).toMatchInlineSnapshot(`[]`);
});
it("should skip dependencies specified using a tag", function () {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { graph, valid } = getDependencyGraph(
{
tool: { type: "yarn" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "examples/foo",
packageJson: {
name: "foo-example",
version: "1.0.0",
dependencies: {
bar: "latest",
},
},
},
{
dir: "packages/bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(graph.get("foo-example")!.dependencies).toStrictEqual([]);
expect(valid).toBeTruthy();
expect((console.error as any).mock.calls).toMatchInlineSnapshot(`[]`);
});
it(
"should set valid to false if the link protocol is used in a non-dev dep",
temporarilySilenceLogs(() => {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { valid } = getDependencyGraph(
{
tool: { type: "yarn" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "foo",
packageJson: {
name: "foo",
version: "1.0.0",
dependencies: {
bar: "link:../bar",
},
},
},
{
dir: "bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(valid).toBeFalsy();
expect((console.error as any).mock.calls).toHaveLength(1);
expect(
stripVTControlCharacters((console.error as any).mock.calls[0][0]),
).toBe(
`Package foo must depend on the current version of bar: 1.0.0 vs link:../bar`,
);
}),
);
it(
"should error on dependencies not specified using workspace protocol when bumpVersionsWithWorkspaceProtocolOnly is false",
temporarilySilenceLogs(() => {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { valid } = getDependencyGraph(
{
tool: { type: "yarn" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "foo",
packageJson: {
name: "foo",
version: "1.0.0",
dependencies: {
bar: "0.9.0",
},
},
},
{
dir: "bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(valid).toBe(false);
expect(
stripVTControlCharacters((console.error as any).mock.calls[0][0]),
).toMatchInlineSnapshot(
`"Package foo must depend on the current version of bar: 1.0.0 vs 0.9.0"`,
);
}),
);
it(
"should skip dependencies not specified using workspace protocol when bumpVersionsWithWorkspaceProtocolOnly is true",
temporarilySilenceLogs(() => {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { valid } = getDependencyGraph(
{
tool: { type: "yarn" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "foo",
packageJson: {
name: "foo",
version: "1.0.0",
dependencies: {
bar: "0.9.0",
},
},
},
{
dir: "bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
{
bumpVersionsWithWorkspaceProtocolOnly: true,
},
);
expect(valid).toBe(true);
expect((console.error as any).mock.calls).toMatchInlineSnapshot(`[]`);
}),
);
it("should treat workspace path dependencies as valid local dependencies", () => {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { graph, valid } = getDependencyGraph(
{
tool: { type: "pnpm" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "packages/foo",
packageJson: {
name: "foo",
version: "1.0.0",
dependencies: {
bar: "workspace:packages/bar",
},
},
},
{
dir: "packages/bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(graph.get("foo")!.dependencies).toStrictEqual(["bar"]);
expect(valid).toBeTruthy();
expect((console.error as any).mock.calls).toMatchInlineSnapshot(`[]`);
});
it(
"should error on mismatched workspace path dependencies",
temporarilySilenceLogs(() => {
const rootPackage: Package = {
dir: path.resolve(),
packageJson: { name: "root", version: "1.0.0" },
};
const { graph, valid } = getDependencyGraph(
{
tool: { type: "pnpm" },
rootDir: rootPackage.dir,
rootPackage,
packages: [
{
dir: "packages/foo",
packageJson: {
name: "foo",
version: "1.0.0",
dependencies: {
bar: "workspace:packages/not-bar",
},
},
},
{
dir: "packages/bar",
packageJson: {
name: "bar",
version: "1.0.0",
},
},
],
},
rootPackage,
);
expect(graph.get("foo")!.dependencies).toStrictEqual([]);
expect(valid).toBe(false);
expect(
stripVTControlCharacters((console.error as any).mock.calls[0][0]),
).toMatchInlineSnapshot(
`"Package foo must depend on the current version of bar: 1.0.0 vs workspace:packages/not-bar"`,
);
}),
);
});
import path from "node:path";
import c from "@changesets/color";
import type { Package, Packages, PackageJSON } from "@changesets/types";
import Range from "semver/classes/range.js";
const DEPENDENCY_TYPES = [
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies",
] as const;
const getAllDependencies = (
config: PackageJSON,
ignoreDevDependencies: boolean,
) => {
const allDependencies = new Map<string, string>();
for (const type of DEPENDENCY_TYPES) {
const deps = config[type];
if (!deps) continue;
for (const name of Object.keys(deps)) {
const depRange = deps[name];
if (
type === "devDependencies" &&
(ignoreDevDependencies ||
depRange.startsWith("link:") ||
depRange.startsWith("file:"))
) {
continue;
}
allDependencies.set(name, depRange);
}
}
return allDependencies;
};
const isProtocolRange = (range: string) => range.includes(":");
const getValidRange = (potentialRange: string) => {
if (isProtocolRange(potentialRange)) {
return null;
}
try {
return new Range(potentialRange);
} catch {
return null;
}
};
export function getDependencyGraph(
packages: Packages,
rootPackage: Package,
{
ignoreDevDependencies = false,
bumpVersionsWithWorkspaceProtocolOnly = false,
}: {
ignoreDevDependencies?: boolean;
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
} = {},
): {
graph: Map<string, { pkg: Package; dependencies: Array<string> }>;
valid: boolean;
} {
const graph = new Map<
string,
{ pkg: Package; dependencies: Array<string> }
>();
let valid = true;
const packagesByName: { [key: string]: Package } = {
[rootPackage.packageJson.name]: rootPackage,
};
const relativePathsByName: { [key: string]: string } = {
[rootPackage.packageJson.name]: ".",
};
const queue = [rootPackage];
for (const pkg of packages.packages) {
queue.push(pkg);
packagesByName[pkg.packageJson.name] = pkg;
relativePathsByName[pkg.packageJson.name] = path
.relative(rootPackage.dir, pkg.dir)
.replace(/\\/g, "/");
}
for (const pkg of queue) {
const { name } = pkg.packageJson;
const dependencies = [];
const allDependencies = getAllDependencies(
pkg.packageJson,
ignoreDevDependencies,
);
// eslint-disable-next-line prefer-const
for (let [depName, depRange] of allDependencies) {
const match = packagesByName[depName];
if (!match) continue;
const expected = match.packageJson.version;
const rawDepRange = depRange;
const usesWorkspaceRange = depRange.startsWith("workspace:");
if (usesWorkspaceRange) {
depRange = depRange.replace(/^workspace:/, "");
if (depRange === "*" || depRange === "^" || depRange === "~") {
dependencies.push(depName);
continue;
}
if (path.posix.normalize(depRange) === relativePathsByName[depName]) {
dependencies.push(depName);
continue;
}
if (!getValidRange(depRange)) {
valid = false;
// TODO: replace with returning errors/warnings
console.error(
`Package ${c.blue(name)} must depend on the current version of ${c.blue(depName)}: ${c.green(expected)} vs ${c.red(rawDepRange)}`,
);
continue;
}
} else if (bumpVersionsWithWorkspaceProtocolOnly) {
continue;
}
const range = getValidRange(depRange);
if ((range && !range.test(expected)) || isProtocolRange(depRange)) {
valid = false;
// TODO: replace with returning errors/warnings
console.error(
`Package ${c.blue(name)} must depend on the current version of ${c.blue(depName)}: ${c.green(expected)} vs ${c.red(rawDepRange)}`,
);
continue;
}
// `depRange` could have been a tag and if a tag has been used there might have been a reason for that
// we should not count this as a local monorepro dependant
if (!range) {
continue;
}
dependencies.push(depName);
}
graph.set(name, { pkg, dependencies });
}
return { graph, valid };
}
import type { Package, Packages } from "@changesets/types";
import { getDependencyGraph } from "./get-dependency-graph.ts";
export function getDependentsGraph(
packages: Packages,
opts?: {
ignoreDevDependencies?: boolean;
bumpVersionsWithWorkspaceProtocolOnly?: boolean;
},
): Map<string, Array<string>> {
const graph: Map<string, { pkg: Package; dependents: string[] }> = new Map();
const rootPackage = packages.rootPackage;
if (rootPackage == null) {
return new Map();
}
const { graph: dependencyGraph } = getDependencyGraph(
packages,
rootPackage,
opts,
);
const dependentsLookup: {
[key: string]: { pkg: Package; dependents: Array<string> };
} = {
[rootPackage.packageJson.name]: {
pkg: rootPackage,
dependents: [],
},
};
packages.packages.forEach((pkg) => {
dependentsLookup[pkg.packageJson.name] = {
pkg,
dependents: [],
};
});
packages.packages.forEach((pkg) => {
const dependent = pkg.packageJson.name;
const valFromDependencyGraph = dependencyGraph.get(dependent);
if (valFromDependencyGraph) {
const dependencies = valFromDependencyGraph.dependencies;
dependencies.forEach((dependency) => {
dependentsLookup[dependency].dependents.push(dependent);
});
}
});
Object.keys(dependentsLookup).forEach((key) => {
graph.set(key, dependentsLookup[key]);
});
const simplifiedDependentsGraph: Map<string, string[]> = new Map();
graph.forEach((pkgInfo, pkgName) => {
simplifiedDependentsGraph.set(pkgName, pkgInfo.dependents);
});
return simplifiedDependentsGraph;
}
import { defineConfig } from "tsdown/config";
import { baseConfig } from "../../tsdown.config.ts";
export default defineConfig(baseConfig);