Skip to content

Commit 5750f8b

Browse files
committed
feat: add alias support - wip
1 parent 38e5d67 commit 5750f8b

26 files changed

+2382
-14
lines changed

lib/dep-graph-builders/npm-lock-v2/index.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export const parseNpmLockV2Project = async (
3434
strictOutOfSync,
3535
includeOptionalDeps,
3636
pruneNpmStrictOutOfSync,
37+
honorAliases,
3738
} = options;
3839

3940
const pkgJson: PackageJsonBase = parsePkgJson(pkgJsonContent);
@@ -44,6 +45,7 @@ export const parseNpmLockV2Project = async (
4445
includeOptionalDeps,
4546
strictOutOfSync,
4647
pruneNpmStrictOutOfSync,
48+
honorAliases,
4749
});
4850

4951
return depgraph;
@@ -59,6 +61,7 @@ export const buildDepGraphNpmLockV2 = async (
5961
strictOutOfSync,
6062
includeOptionalDeps,
6163
pruneNpmStrictOutOfSync,
64+
honorAliases,
6265
} = options;
6366
const depGraphBuilder = new DepGraphBuilder(
6467
{ name: 'npm' },
@@ -69,6 +72,7 @@ export const buildDepGraphNpmLockV2 = async (
6972
includeDevDeps,
7073
includeOptionalDeps,
7174
includePeerDeps: true,
75+
honorAliases,
7276
});
7377

7478
const rootNode: PkgNode = {
@@ -83,11 +87,14 @@ export const buildDepGraphNpmLockV2 = async (
8387

8488
const pkgKeysByName: Map<string, string[]> = Object.keys(npmLockPkgs).reduce(
8589
(acc, key) => {
86-
const name = key.replace(/.*node_modules\//, '');
90+
let name = key.replace(/.*node_modules\//, '');
8791
if (!name) {
8892
return acc;
8993
}
9094

95+
if (npmLockPkgs[key].name && options.honorAliases) {
96+
name = npmLockPkgs[key].name;
97+
}
9198
if (!acc.has(name)) {
9299
acc.set(name, []);
93100
}
@@ -112,6 +119,7 @@ export const buildDepGraphNpmLockV2 = async (
112119
pkgKeysByName,
113120
pkgJson.overrides,
114121
pruneNpmStrictOutOfSync,
122+
options.honorAliases,
115123
);
116124
return depGraphBuilder.build();
117125
};
@@ -135,6 +143,7 @@ const dfsVisit = async (
135143
pkgKeysByName: Map<string, string[]>,
136144
overrides: Overrides | undefined,
137145
pruneNpmStrictOutOfSync?: boolean,
146+
honorAliases?: boolean,
138147
): Promise<void> => {
139148
visitedMap.add(node.id);
140149

@@ -162,6 +171,7 @@ const dfsVisit = async (
162171
pkgKeysByName,
163172
overrides,
164173
pruneNpmStrictOutOfSync,
174+
honorAliases ?? false,
165175
);
166176

167177
if (!visitedMap.has(childNode.id)) {
@@ -203,6 +213,7 @@ const getChildNode = (
203213
pkgKeysByName: Map<string, string[]>,
204214
overrides?: Overrides,
205215
pruneNpmStrictOutOfSync?: boolean,
216+
honorAliases?: boolean,
206217
) => {
207218
let version = depInfo.version;
208219

@@ -276,14 +287,23 @@ const getChildNode = (
276287
const dependencies = getGraphDependencies(
277288
depData.dependencies || {},
278289
depInfo.isDev,
290+
honorAliases ?? false,
279291
);
280292

281293
const devDependencies = includeDevDeps
282-
? getGraphDependencies(depData.devDependencies || {}, depInfo.isDev)
294+
? getGraphDependencies(
295+
depData.devDependencies || {},
296+
depInfo.isDev,
297+
honorAliases ?? false,
298+
)
283299
: {};
284300

285301
const optionalDependencies = includeOptionalDeps
286-
? getGraphDependencies(depData.optionalDependencies || {}, depInfo.isDev)
302+
? getGraphDependencies(
303+
depData.optionalDependencies || {},
304+
depInfo.isDev,
305+
honorAliases ?? false,
306+
)
287307
: {};
288308

289309
return {

lib/dep-graph-builders/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export type DepGraphBuildOptions = {
3535
strictOutOfSync: boolean;
3636
includePeerDeps?: boolean;
3737
pruneNpmStrictOutOfSync?: boolean;
38+
honorAliases?: boolean;
3839
};
3940

4041
export type LockFileParseOptions = {
@@ -50,13 +51,15 @@ export type YarnLockV2WorkspaceArgs = {
5051
isWorkspacePkg: boolean;
5152
isRoot: boolean;
5253
rootResolutions: Record<string, string>;
54+
honorAliases?: boolean;
5355
};
5456

5557
export type YarnLockV2ProjectParseOptions = {
5658
includeDevDeps: boolean;
5759
includeOptionalDeps: boolean;
5860
strictOutOfSync: boolean;
5961
pruneWithinTopLevelDeps: boolean;
62+
honorAliases?: boolean;
6063
};
6164

6265
/*
@@ -73,6 +76,7 @@ export type YarnLockV1ProjectParseOptions = {
7376
includePeerDeps: boolean;
7477
strictOutOfSync: boolean;
7578
pruneLevel: PruneLevel;
79+
honorAliases?: boolean;
7680
};
7781

7882
export type Yarn1DepGraphBuildOptions = {
@@ -81,6 +85,7 @@ export type Yarn1DepGraphBuildOptions = {
8185
includePeerDeps: boolean;
8286
strictOutOfSync: boolean;
8387
pruneWithinTopLevelDeps: boolean;
88+
honorAliases?: boolean;
8489
};
8590

8691
export type PnpmWorkspaceArgs = {

lib/dep-graph-builders/util.ts

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,18 +50,32 @@ export const getTopLevelDeps = (
5050
includeDevDeps: boolean;
5151
includeOptionalDeps?: boolean;
5252
includePeerDeps?: boolean;
53+
honorAliases?: boolean;
5354
},
5455
): Dependencies => {
55-
const prodDeps = getGraphDependencies(pkgJson.dependencies || {}, false);
56+
const { honorAliases = false } = options;
57+
const prodDeps = getGraphDependencies(
58+
pkgJson.dependencies || {},
59+
false,
60+
honorAliases,
61+
);
5662

57-
const devDeps = getGraphDependencies(pkgJson.devDependencies || {}, true);
63+
const devDeps = getGraphDependencies(
64+
pkgJson.devDependencies || {},
65+
true,
66+
honorAliases,
67+
);
5868

5969
const optionalDeps = options.includeOptionalDeps
60-
? getGraphDependencies(pkgJson.optionalDependencies || {}, false)
70+
? getGraphDependencies(
71+
pkgJson.optionalDependencies || {},
72+
false,
73+
honorAliases,
74+
)
6175
: {};
6276

6377
const peerDeps = options.includePeerDeps
64-
? getGraphDependencies(pkgJson.peerDependencies || {}, false)
78+
? getGraphDependencies(pkgJson.peerDependencies || {}, false, honorAliases)
6579
: {};
6680

6781
const deps = { ...prodDeps, ...optionalDeps, ...peerDeps };
@@ -91,10 +105,24 @@ export const getTopLevelDeps = (
91105
export const getGraphDependencies = (
92106
dependencies: Record<string, string>,
93107
isDev,
108+
isAliasSupportEnabled = false,
94109
): Dependencies => {
95110
return Object.entries(dependencies).reduce(
96111
(pnpmDeps: Dependencies, [name, semver]) => {
97-
pnpmDeps[name] = { version: semver, isDev: isDev };
112+
const isAlias = semver.startsWith('npm:') && isAliasSupportEnabled;
113+
if (isAlias) {
114+
const aliasedName = semver.substring(4, semver.lastIndexOf('@'));
115+
116+
const aliasedVersion = semver.substring(
117+
semver.lastIndexOf('@') + 1,
118+
semver.length,
119+
);
120+
121+
pnpmDeps[aliasedName] = { version: aliasedVersion, isDev: isDev };
122+
} else {
123+
pnpmDeps[name] = { version: semver, isDev: isDev };
124+
}
125+
98126
return pnpmDeps;
99127
},
100128
{},
@@ -121,6 +149,7 @@ export const getChildNode = (
121149
pkgs: NormalisedPkgs,
122150
strictOutOfSync: boolean,
123151
includeOptionalDeps: boolean,
152+
honorAliases: boolean = false,
124153
) => {
125154
const childNodeKey = `${name}@${depInfo.version}`;
126155
let childNode: PkgNode;
@@ -143,9 +172,14 @@ export const getChildNode = (
143172
const dependencies = getGraphDependencies(
144173
depData.dependencies || {},
145174
depInfo.isDev,
175+
honorAliases,
146176
);
147177
const optionalDependencies = includeOptionalDeps
148-
? getGraphDependencies(depData.optionalDependencies || {}, depInfo.isDev)
178+
? getGraphDependencies(
179+
depData.optionalDependencies || {},
180+
depInfo.isDev,
181+
honorAliases,
182+
)
149183
: {};
150184
childNode = {
151185
id: `${name}@${depData.version}`,

lib/dep-graph-builders/yarn-lock-v1/build-depgraph-simple-pruned.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const buildDepGraphYarnLockV1SimpleCyclesPruned = async (
4545
extractedYarnLockV1Pkgs,
4646
strictOutOfSync,
4747
includeOptionalDeps,
48+
options.honorAliases ?? false,
4849
);
4950

5051
return depGraphBuilder.build();
@@ -66,6 +67,7 @@ const dfsVisit = async (
6667
extractedYarnLockV1Pkgs: NormalisedPkgs,
6768
strictOutOfSync: boolean,
6869
includeOptionalDeps: boolean,
70+
honorAliases: boolean = false,
6971
): Promise<void> => {
7072
colorMap[node.id] = Color.GRAY;
7173

@@ -81,6 +83,7 @@ const dfsVisit = async (
8183
strictOutOfSync,
8284

8385
includeOptionalDeps,
86+
honorAliases,
8487
);
8588

8689
if (!colorMap.hasOwnProperty(childNode.id)) {

lib/dep-graph-builders/yarn-lock-v1/build-depgraph-simple.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const buildDepGraphYarnLockV1Simple = async (
1515
includePeerDeps,
1616
strictOutOfSync,
1717
pruneWithinTopLevelDeps,
18+
honorAliases = false,
1819
} = options;
1920

2021
const depGraphBuilder = new DepGraphBuilder(
@@ -26,6 +27,7 @@ export const buildDepGraphYarnLockV1Simple = async (
2627
includeDevDeps,
2728
includePeerDeps,
2829
includeOptionalDeps,
30+
honorAliases,
2931
});
3032

3133
const rootNode: PkgNode = {
@@ -43,6 +45,7 @@ export const buildDepGraphYarnLockV1Simple = async (
4345
strictOutOfSync,
4446
includeOptionalDeps,
4547
pruneWithinTopLevelDeps,
48+
honorAliases ?? false,
4649
);
4750

4851
return depGraphBuilder.build();
@@ -61,6 +64,7 @@ const dfsVisit = async (
6164
strictOutOfSync: boolean,
6265
includeOptionalDeps: boolean,
6366
pruneWithinTopLevel: boolean,
67+
honorAliases: boolean,
6468
visited?: Set<string>,
6569
): Promise<void> => {
6670
for (const [name, depInfo] of Object.entries(node.dependencies || {})) {
@@ -74,6 +78,7 @@ const dfsVisit = async (
7478
extractedYarnLockV1Pkgs,
7579
strictOutOfSync,
7680
includeOptionalDeps,
81+
honorAliases,
7782
);
7883

7984
if (localVisited.has(childNode.id)) {
@@ -120,6 +125,7 @@ const dfsVisit = async (
120125
strictOutOfSync,
121126
includeOptionalDeps,
122127
pruneWithinTopLevel,
128+
honorAliases,
123129
localVisited,
124130
);
125131
}

lib/dep-graph-builders/yarn-lock-v1/simple.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export const parseYarnLockV1Project = async (
1515
includePeerDeps,
1616
pruneLevel,
1717
strictOutOfSync,
18+
honorAliases,
1819
} = options;
1920

2021
const pkgs = extractPkgsFromYarnLockV1(yarnLockContent);
@@ -27,13 +28,15 @@ export const parseYarnLockV1Project = async (
2728
includeDevDeps,
2829
strictOutOfSync,
2930
includeOptionalDeps,
31+
honorAliases,
3032
})
3133
: await buildDepGraphYarnLockV1Simple(pkgs, pkgJson, {
3234
includeDevDeps,
3335
includeOptionalDeps,
3436
includePeerDeps,
3537
strictOutOfSync,
3638
pruneWithinTopLevelDeps: pruneLevel === 'withinTopLevelDeps',
39+
honorAliases,
3740
});
3841

3942
return depGraph;

lib/dep-graph-builders/yarn-lock-v2/simple.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export const parseYarnLockV2Project = async (
1919
includeOptionalDeps,
2020
strictOutOfSync,
2121
pruneWithinTopLevelDeps,
22+
honorAliases,
2223
} = options;
2324

2425
const pkgs = extractPkgsFromYarnLockV2(yarnLockContent);
@@ -33,6 +34,7 @@ export const parseYarnLockV2Project = async (
3334
strictOutOfSync,
3435
includeOptionalDeps,
3536
pruneWithinTopLevelDeps,
37+
honorAliases,
3638
},
3739
workspaceArgs,
3840
);

lib/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ async function buildDepTree(
107107
lockfileType?: LockfileType,
108108
strictOutOfSync: boolean = true,
109109
defaultManifestFileName: string = 'package.json',
110+
honorAliases?: boolean,
110111
): Promise<PkgTree> {
111112
if (!lockfileType) {
112113
lockfileType = LockfileType.npm;
@@ -147,6 +148,7 @@ async function buildDepTree(
147148
lockFile,
148149
includeDev,
149150
strictOutOfSync,
151+
honorAliases ?? false,
150152
);
151153
}
152154

@@ -156,6 +158,7 @@ async function buildDepTreeFromFiles(
156158
lockFilePath: string,
157159
includeDev = false,
158160
strictOutOfSync = true,
161+
honorAliases?: boolean,
159162
): Promise<PkgTree> {
160163
if (!root || !manifestFilePath || !lockFilePath) {
161164
throw new Error('Missing required parameters for buildDepTreeFromFiles()');
@@ -198,6 +201,7 @@ async function buildDepTreeFromFiles(
198201
lockFileType,
199202
strictOutOfSync,
200203
manifestFilePath,
204+
honorAliases ?? false,
201205
);
202206
}
203207

0 commit comments

Comments
 (0)