lllink 1.1.491 → 1.1.493
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/dist/index.js +124 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +114 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +225 -3
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import {
|
|
2
|
+
import { cp, mkdir, readdir, readFile, rename, rm, stat, symlink } from "node:fs/promises";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join, relative, resolve } from "node:path";
|
|
5
5
|
typeof Bun > "u" && (console.error("Must run in Bun due to using ~ resolutions"), process.exit(1));
|
|
@@ -28,7 +28,7 @@ async function findLocalPackages(rootDir) {
|
|
|
28
28
|
try {
|
|
29
29
|
if ((await stat(pkgJsonPath)).isFile()) {
|
|
30
30
|
const raw = await readFile(pkgJsonPath, "utf-8"), pkgData = JSON.parse(raw);
|
|
31
|
-
pkgData.name && (results[pkgData.name] = fullPath);
|
|
31
|
+
pkgData.name && !pkgData.name.startsWith("@types/") && (results[pkgData.name] = fullPath);
|
|
32
32
|
}
|
|
33
33
|
} catch {
|
|
34
34
|
await recurse(fullPath);
|
|
@@ -74,14 +74,134 @@ async function undoLinks() {
|
|
|
74
74
|
}), console.info(`Restored: ${originalName}`);
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
|
+
async function checkAllPackageVersionsAligned(workspaceDirs, packagesToCheck) {
|
|
78
|
+
const allPackageVersions = [], allDirs = [process.cwd(), ...workspaceDirs], allDepsToCheck = /* @__PURE__ */ new Set();
|
|
79
|
+
for (const pkgName of Object.keys(packagesToCheck))
|
|
80
|
+
allDepsToCheck.add(pkgName);
|
|
81
|
+
for (const [pkgName, pkgPath] of Object.entries(packagesToCheck)) {
|
|
82
|
+
const deps = await getPackageDependencies(pkgPath);
|
|
83
|
+
for (const dep of deps)
|
|
84
|
+
allDepsToCheck.add(dep);
|
|
85
|
+
}
|
|
86
|
+
for (const workspaceDir of allDirs) {
|
|
87
|
+
const resolved = resolve(workspaceDir), workspaceName = workspaceDir === process.cwd() ? "current" : workspaceDir.split("/").pop() || workspaceDir, packages = await collectSpecificNodeModulePackages(
|
|
88
|
+
resolved,
|
|
89
|
+
workspaceName,
|
|
90
|
+
allDepsToCheck
|
|
91
|
+
);
|
|
92
|
+
allPackageVersions.push(...packages);
|
|
93
|
+
}
|
|
94
|
+
const packageGroups = {};
|
|
95
|
+
for (const pkg of allPackageVersions)
|
|
96
|
+
packageGroups[pkg.name] || (packageGroups[pkg.name] = []), packageGroups[pkg.name].push(pkg);
|
|
97
|
+
const mismatches = [];
|
|
98
|
+
for (const [pkgName, versions] of Object.entries(packageGroups)) {
|
|
99
|
+
const versionsByWorkspace = {};
|
|
100
|
+
for (const version of versions)
|
|
101
|
+
versionsByWorkspace[version.workspace] = version.version;
|
|
102
|
+
if (new Set(Object.values(versionsByWorkspace)).size > 1) {
|
|
103
|
+
const uniqueVersionsArray = Object.entries(versionsByWorkspace).map(
|
|
104
|
+
([workspace, version]) => ({
|
|
105
|
+
name: pkgName,
|
|
106
|
+
version,
|
|
107
|
+
workspace,
|
|
108
|
+
path: versions.find((v) => v.workspace === workspace)?.path || ""
|
|
109
|
+
})
|
|
110
|
+
);
|
|
111
|
+
mismatches.push({ name: pkgName, versions: uniqueVersionsArray });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (mismatches.length === 0)
|
|
115
|
+
return console.info("\u2713 All package versions are aligned across workspaces!"), !0;
|
|
116
|
+
console.info(
|
|
117
|
+
`
|
|
118
|
+
\u274C Found ${mismatches.length} packages with mismatched versions, this may cause issues linking:
|
|
119
|
+
`
|
|
120
|
+
);
|
|
121
|
+
for (const { name, versions } of mismatches) {
|
|
122
|
+
console.info(`Package: ${name}`);
|
|
123
|
+
for (const version of versions)
|
|
124
|
+
console.info(` ${version.workspace}: ${version.version}`);
|
|
125
|
+
console.info("");
|
|
126
|
+
}
|
|
127
|
+
return !1;
|
|
128
|
+
}
|
|
129
|
+
async function getPackageDependencies(packagePath) {
|
|
130
|
+
const dependencies = /* @__PURE__ */ new Set();
|
|
131
|
+
try {
|
|
132
|
+
const pkgJsonPath = join(packagePath, "package.json"), raw = await readFile(pkgJsonPath, "utf-8"), pkgData = JSON.parse(raw), depTypes = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
133
|
+
for (const depType of depTypes)
|
|
134
|
+
if (pkgData[depType])
|
|
135
|
+
for (const depName of Object.keys(pkgData[depType]))
|
|
136
|
+
depName.startsWith("@types/") || dependencies.add(depName);
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
return Array.from(dependencies);
|
|
140
|
+
}
|
|
141
|
+
async function collectSpecificNodeModulePackages(workspaceDir, workspaceName, packagesToFind) {
|
|
142
|
+
const packages = [], nodeModulesPath = join(workspaceDir, "node_modules");
|
|
143
|
+
async function recurseNodeModules(dir, depth = 0) {
|
|
144
|
+
if (depth > 10) return;
|
|
145
|
+
let entries;
|
|
146
|
+
try {
|
|
147
|
+
entries = await readdir(dir);
|
|
148
|
+
} catch {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
for (const entry of entries) {
|
|
152
|
+
const fullPath = join(dir, entry);
|
|
153
|
+
let entryStat;
|
|
154
|
+
try {
|
|
155
|
+
entryStat = await stat(fullPath);
|
|
156
|
+
} catch {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
if (entryStat.isDirectory()) {
|
|
160
|
+
if (entry.startsWith("@"))
|
|
161
|
+
await recurseNodeModules(fullPath, depth + 1);
|
|
162
|
+
else if (entry !== ".bin" && entry !== ".cache") {
|
|
163
|
+
const pkgJsonPath = join(fullPath, "package.json");
|
|
164
|
+
try {
|
|
165
|
+
if ((await stat(pkgJsonPath)).isFile()) {
|
|
166
|
+
const raw = await readFile(pkgJsonPath, "utf-8"), pkgData = JSON.parse(raw);
|
|
167
|
+
pkgData.name && pkgData.version && packagesToFind.has(pkgData.name) && !pkgData.name.startsWith("@types/") && packages.push({
|
|
168
|
+
name: pkgData.name,
|
|
169
|
+
version: pkgData.version,
|
|
170
|
+
workspace: workspaceName,
|
|
171
|
+
path: fullPath
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
} catch {
|
|
175
|
+
const nestedNodeModules = join(fullPath, "node_modules");
|
|
176
|
+
try {
|
|
177
|
+
(await stat(nestedNodeModules)).isDirectory() && await recurseNodeModules(nestedNodeModules, depth + 1);
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
await recurseNodeModules(nodeModulesPath);
|
|
187
|
+
} catch {
|
|
188
|
+
}
|
|
189
|
+
return packages;
|
|
190
|
+
}
|
|
77
191
|
async function main() {
|
|
78
192
|
const args = process.argv.slice(2);
|
|
79
|
-
args.includes("--unlink") && (await undoLinks(), process.exit(0))
|
|
193
|
+
args.includes("--unlink") && (await undoLinks(), process.exit(0));
|
|
194
|
+
const workspaceDirs = args.filter((arg) => !arg.startsWith("--"));
|
|
195
|
+
args.length === 0 && (console.info("No workspace directories provided."), process.exit(0));
|
|
80
196
|
const allLocalPackages = {};
|
|
81
|
-
for (const workspaceDir of
|
|
197
|
+
for (const workspaceDir of workspaceDirs) {
|
|
82
198
|
const resolved = resolve(workspaceDir), found = await findLocalPackages(resolved);
|
|
83
199
|
Object.assign(allLocalPackages, found);
|
|
84
200
|
}
|
|
201
|
+
if (!await checkAllPackageVersionsAligned(workspaceDirs, allLocalPackages))
|
|
202
|
+
args.includes("--check") && process.exit(1);
|
|
203
|
+
else if (args.includes("--check"))
|
|
204
|
+
return;
|
|
85
205
|
await linkPackages(allLocalPackages), console.info(`
|
|
86
206
|
\u2713 linked ${Object.keys(allLocalPackages).length} packages`);
|
|
87
207
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"mappings": ";AAOA,SAAS,SAAS,UAAU,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
|
-
import {
|
|
2
|
+
import { cp, mkdir, readdir, readFile, rename, rm, stat, symlink } from "node:fs/promises";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
4
|
import { join, relative, resolve } from "node:path";
|
|
5
5
|
typeof Bun > "u" && (console.error("Must run in Bun due to using ~ resolutions"), process.exit(1));
|
|
@@ -28,7 +28,7 @@ async function findLocalPackages(rootDir) {
|
|
|
28
28
|
if ((await stat(pkgJsonPath)).isFile()) {
|
|
29
29
|
const raw = await readFile(pkgJsonPath, "utf-8"),
|
|
30
30
|
pkgData = JSON.parse(raw);
|
|
31
|
-
pkgData.name && (results[pkgData.name] = fullPath);
|
|
31
|
+
pkgData.name && !pkgData.name.startsWith("@types/") && (results[pkgData.name] = fullPath);
|
|
32
32
|
}
|
|
33
33
|
} catch {
|
|
34
34
|
await recurse(fullPath);
|
|
@@ -76,15 +76,125 @@ async function undoLinks() {
|
|
|
76
76
|
}).catch(() => {}), await rename(join(backupDir, item), nmPath).catch(() => {}), console.info(`Restored: ${originalName}`);
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
async function checkAllPackageVersionsAligned(workspaceDirs, packagesToCheck) {
|
|
80
|
+
const allPackageVersions = [],
|
|
81
|
+
allDirs = [process.cwd(), ...workspaceDirs],
|
|
82
|
+
allDepsToCheck = /* @__PURE__ */new Set();
|
|
83
|
+
for (const pkgName of Object.keys(packagesToCheck)) allDepsToCheck.add(pkgName);
|
|
84
|
+
for (const [pkgName, pkgPath] of Object.entries(packagesToCheck)) {
|
|
85
|
+
const deps = await getPackageDependencies(pkgPath);
|
|
86
|
+
for (const dep of deps) allDepsToCheck.add(dep);
|
|
87
|
+
}
|
|
88
|
+
for (const workspaceDir of allDirs) {
|
|
89
|
+
const resolved = resolve(workspaceDir),
|
|
90
|
+
workspaceName = workspaceDir === process.cwd() ? "current" : workspaceDir.split("/").pop() || workspaceDir,
|
|
91
|
+
packages = await collectSpecificNodeModulePackages(resolved, workspaceName, allDepsToCheck);
|
|
92
|
+
allPackageVersions.push(...packages);
|
|
93
|
+
}
|
|
94
|
+
const packageGroups = {};
|
|
95
|
+
for (const pkg of allPackageVersions) packageGroups[pkg.name] || (packageGroups[pkg.name] = []), packageGroups[pkg.name].push(pkg);
|
|
96
|
+
const mismatches = [];
|
|
97
|
+
for (const [pkgName, versions] of Object.entries(packageGroups)) {
|
|
98
|
+
const versionsByWorkspace = {};
|
|
99
|
+
for (const version of versions) versionsByWorkspace[version.workspace] = version.version;
|
|
100
|
+
if (new Set(Object.values(versionsByWorkspace)).size > 1) {
|
|
101
|
+
const uniqueVersionsArray = Object.entries(versionsByWorkspace).map(([workspace, version]) => ({
|
|
102
|
+
name: pkgName,
|
|
103
|
+
version,
|
|
104
|
+
workspace,
|
|
105
|
+
path: versions.find(v => v.workspace === workspace)?.path || ""
|
|
106
|
+
}));
|
|
107
|
+
mismatches.push({
|
|
108
|
+
name: pkgName,
|
|
109
|
+
versions: uniqueVersionsArray
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (mismatches.length === 0) return console.info("\u2713 All package versions are aligned across workspaces!"), !0;
|
|
114
|
+
console.info(`
|
|
115
|
+
\u274C Found ${mismatches.length} packages with mismatched versions, this may cause issues linking:
|
|
116
|
+
`);
|
|
117
|
+
for (const {
|
|
118
|
+
name,
|
|
119
|
+
versions
|
|
120
|
+
} of mismatches) {
|
|
121
|
+
console.info(`Package: ${name}`);
|
|
122
|
+
for (const version of versions) console.info(` ${version.workspace}: ${version.version}`);
|
|
123
|
+
console.info("");
|
|
124
|
+
}
|
|
125
|
+
return !1;
|
|
126
|
+
}
|
|
127
|
+
async function getPackageDependencies(packagePath) {
|
|
128
|
+
const dependencies = /* @__PURE__ */new Set();
|
|
129
|
+
try {
|
|
130
|
+
const pkgJsonPath = join(packagePath, "package.json"),
|
|
131
|
+
raw = await readFile(pkgJsonPath, "utf-8"),
|
|
132
|
+
pkgData = JSON.parse(raw),
|
|
133
|
+
depTypes = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
|
|
134
|
+
for (const depType of depTypes) if (pkgData[depType]) for (const depName of Object.keys(pkgData[depType])) depName.startsWith("@types/") || dependencies.add(depName);
|
|
135
|
+
} catch {}
|
|
136
|
+
return Array.from(dependencies);
|
|
137
|
+
}
|
|
138
|
+
async function collectSpecificNodeModulePackages(workspaceDir, workspaceName, packagesToFind) {
|
|
139
|
+
const packages = [],
|
|
140
|
+
nodeModulesPath = join(workspaceDir, "node_modules");
|
|
141
|
+
async function recurseNodeModules(dir, depth = 0) {
|
|
142
|
+
if (depth > 10) return;
|
|
143
|
+
let entries;
|
|
144
|
+
try {
|
|
145
|
+
entries = await readdir(dir);
|
|
146
|
+
} catch {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
for (const entry of entries) {
|
|
150
|
+
const fullPath = join(dir, entry);
|
|
151
|
+
let entryStat;
|
|
152
|
+
try {
|
|
153
|
+
entryStat = await stat(fullPath);
|
|
154
|
+
} catch {
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
if (entryStat.isDirectory()) {
|
|
158
|
+
if (entry.startsWith("@")) await recurseNodeModules(fullPath, depth + 1);else if (entry !== ".bin" && entry !== ".cache") {
|
|
159
|
+
const pkgJsonPath = join(fullPath, "package.json");
|
|
160
|
+
try {
|
|
161
|
+
if ((await stat(pkgJsonPath)).isFile()) {
|
|
162
|
+
const raw = await readFile(pkgJsonPath, "utf-8"),
|
|
163
|
+
pkgData = JSON.parse(raw);
|
|
164
|
+
pkgData.name && pkgData.version && packagesToFind.has(pkgData.name) && !pkgData.name.startsWith("@types/") && packages.push({
|
|
165
|
+
name: pkgData.name,
|
|
166
|
+
version: pkgData.version,
|
|
167
|
+
workspace: workspaceName,
|
|
168
|
+
path: fullPath
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
} catch {
|
|
172
|
+
const nestedNodeModules = join(fullPath, "node_modules");
|
|
173
|
+
try {
|
|
174
|
+
(await stat(nestedNodeModules)).isDirectory() && (await recurseNodeModules(nestedNodeModules, depth + 1));
|
|
175
|
+
} catch {}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
try {
|
|
182
|
+
await recurseNodeModules(nodeModulesPath);
|
|
183
|
+
} catch {}
|
|
184
|
+
return packages;
|
|
185
|
+
}
|
|
79
186
|
async function main() {
|
|
80
187
|
const args = process.argv.slice(2);
|
|
81
|
-
args.includes("--unlink") && (await undoLinks(), process.exit(0))
|
|
188
|
+
args.includes("--unlink") && (await undoLinks(), process.exit(0));
|
|
189
|
+
const workspaceDirs = args.filter(arg => !arg.startsWith("--"));
|
|
190
|
+
args.length === 0 && (console.info("No workspace directories provided."), process.exit(0));
|
|
82
191
|
const allLocalPackages = {};
|
|
83
|
-
for (const workspaceDir of
|
|
192
|
+
for (const workspaceDir of workspaceDirs) {
|
|
84
193
|
const resolved = resolve(workspaceDir),
|
|
85
194
|
found = await findLocalPackages(resolved);
|
|
86
195
|
Object.assign(allLocalPackages, found);
|
|
87
196
|
}
|
|
197
|
+
if (!(await checkAllPackageVersionsAligned(workspaceDirs, allLocalPackages))) args.includes("--check") && process.exit(1);else if (args.includes("--check")) return;
|
|
88
198
|
await linkPackages(allLocalPackages), console.info(`
|
|
89
199
|
\u2713 linked ${Object.keys(allLocalPackages).length} packages`);
|
|
90
200
|
}
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["cp","mkdir","readdir","readFile","rename","rm","stat","symlink","homedir","join","relative","resolve","Bun","console","error","process","exit","IGNORE_DIR","findLocalPackages","rootDir","results","recurse","dir","entries","Promise","all","map","entry","fullPath","entryStat","isDirectory","pkgJsonPath","isFile","raw","pkgData","JSON","parse","name","startsWith","linkPackages","externalPackages","backupDir","cwd","recursive","pkgName","Object","keys","localPath","split","replace","dereference","externalPath","info","force","catch","undoLinks","movedItems","item","originalName","nmPath","checkAllPackageVersionsAligned","workspaceDirs","packagesToCheck","allPackageVersions","allDirs","allDepsToCheck","Set","add","pkgPath","deps","getPackageDependencies","dep","workspaceDir","resolved","workspaceName","pop","packages","collectSpecificNodeModulePackages","push","packageGroups","pkg","mismatches","versions","versionsByWorkspace","version","workspace","values","size","uniqueVersionsArray","path","find","v","length","packagePath","dependencies","depTypes","depType","depName","Array","from","packagesToFind","nodeModulesPath","recurseNodeModules","depth","has","nestedNodeModules","main","args","argv","slice","includes","filter","arg","allLocalPackages","found","assign","err"],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lllink",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.493",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"module": "dist",
|
|
6
6
|
"exports": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"@biomejs/biome": "1.9.4",
|
|
26
|
-
"@tamagui/build": "^1.
|
|
26
|
+
"@tamagui/build": "^1.127.2"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|
package/src/index.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* bun run link-workspaces.ts <workspaceDir1> <workspaceDir2> ...
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { cp, mkdir, readdir, readFile, rename, rm, stat, symlink } from 'node:fs/promises'
|
|
9
9
|
import { homedir } from 'node:os'
|
|
10
10
|
import { join, relative, resolve } from 'node:path'
|
|
11
11
|
|
|
@@ -18,6 +18,13 @@ if (typeof Bun === 'undefined') {
|
|
|
18
18
|
|
|
19
19
|
const IGNORE_DIR = 'node_modules'
|
|
20
20
|
|
|
21
|
+
type PackageVersionInfo = {
|
|
22
|
+
name: string
|
|
23
|
+
version: string
|
|
24
|
+
workspace: string
|
|
25
|
+
path: string
|
|
26
|
+
}
|
|
27
|
+
|
|
21
28
|
async function findLocalPackages(rootDir: string): Promise<Record<string, string>> {
|
|
22
29
|
const results: Record<string, string> = {}
|
|
23
30
|
|
|
@@ -46,7 +53,7 @@ async function findLocalPackages(rootDir: string): Promise<Record<string, string
|
|
|
46
53
|
if (pkgJsonStat.isFile()) {
|
|
47
54
|
const raw = await readFile(pkgJsonPath, 'utf-8')
|
|
48
55
|
const pkgData = JSON.parse(raw)
|
|
49
|
-
if (pkgData.name) {
|
|
56
|
+
if (pkgData.name && !pkgData.name.startsWith('@types/')) {
|
|
50
57
|
results[pkgData.name] = fullPath
|
|
51
58
|
}
|
|
52
59
|
}
|
|
@@ -105,22 +112,237 @@ async function undoLinks() {
|
|
|
105
112
|
}
|
|
106
113
|
}
|
|
107
114
|
|
|
115
|
+
async function checkAllPackageVersionsAligned(
|
|
116
|
+
workspaceDirs: string[],
|
|
117
|
+
packagesToCheck: Record<string, string>
|
|
118
|
+
) {
|
|
119
|
+
const allPackageVersions: PackageVersionInfo[] = []
|
|
120
|
+
|
|
121
|
+
// Include current directory along with provided workspace directories
|
|
122
|
+
const allDirs = [process.cwd(), ...workspaceDirs]
|
|
123
|
+
|
|
124
|
+
// Get all dependencies of packages we're going to link
|
|
125
|
+
const allDepsToCheck = new Set<string>()
|
|
126
|
+
|
|
127
|
+
// Add the packages we're linking
|
|
128
|
+
for (const pkgName of Object.keys(packagesToCheck)) {
|
|
129
|
+
allDepsToCheck.add(pkgName)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Add dependencies of packages we're linking
|
|
133
|
+
for (const [pkgName, pkgPath] of Object.entries(packagesToCheck)) {
|
|
134
|
+
const deps = await getPackageDependencies(pkgPath)
|
|
135
|
+
for (const dep of deps) {
|
|
136
|
+
allDepsToCheck.add(dep)
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Collect package versions only for packages we care about
|
|
141
|
+
for (const workspaceDir of allDirs) {
|
|
142
|
+
const resolved = resolve(workspaceDir)
|
|
143
|
+
const workspaceName =
|
|
144
|
+
workspaceDir === process.cwd() ? 'current' : workspaceDir.split('/').pop() || workspaceDir
|
|
145
|
+
const packages = await collectSpecificNodeModulePackages(
|
|
146
|
+
resolved,
|
|
147
|
+
workspaceName,
|
|
148
|
+
allDepsToCheck
|
|
149
|
+
)
|
|
150
|
+
allPackageVersions.push(...packages)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Group by package name
|
|
154
|
+
const packageGroups: Record<string, PackageVersionInfo[]> = {}
|
|
155
|
+
for (const pkg of allPackageVersions) {
|
|
156
|
+
if (!packageGroups[pkg.name]) {
|
|
157
|
+
packageGroups[pkg.name] = []
|
|
158
|
+
}
|
|
159
|
+
packageGroups[pkg.name].push(pkg)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Find mismatched versions across different workspaces only
|
|
163
|
+
const mismatches: Array<{ name: string; versions: PackageVersionInfo[] }> = []
|
|
164
|
+
for (const [pkgName, versions] of Object.entries(packageGroups)) {
|
|
165
|
+
// Group versions by workspace to avoid comparing within the same workspace
|
|
166
|
+
const versionsByWorkspace: Record<string, string> = {}
|
|
167
|
+
for (const version of versions) {
|
|
168
|
+
versionsByWorkspace[version.workspace] = version.version
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
const uniqueVersions = new Set(Object.values(versionsByWorkspace))
|
|
172
|
+
if (uniqueVersions.size > 1) {
|
|
173
|
+
// Only include one version per workspace for cleaner output
|
|
174
|
+
const uniqueVersionsArray = Object.entries(versionsByWorkspace).map(
|
|
175
|
+
([workspace, version]) => ({
|
|
176
|
+
name: pkgName,
|
|
177
|
+
version,
|
|
178
|
+
workspace,
|
|
179
|
+
path: versions.find((v) => v.workspace === workspace)?.path || '',
|
|
180
|
+
})
|
|
181
|
+
)
|
|
182
|
+
mismatches.push({ name: pkgName, versions: uniqueVersionsArray })
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Report results
|
|
187
|
+
if (mismatches.length === 0) {
|
|
188
|
+
console.info('✓ All package versions are aligned across workspaces!')
|
|
189
|
+
return true
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
console.info(
|
|
193
|
+
`\n❌ Found ${mismatches.length} packages with mismatched versions, this may cause issues linking:\n`
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
for (const { name, versions } of mismatches) {
|
|
197
|
+
console.info(`Package: ${name}`)
|
|
198
|
+
for (const version of versions) {
|
|
199
|
+
console.info(` ${version.workspace}: ${version.version}`)
|
|
200
|
+
}
|
|
201
|
+
console.info('')
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
return false
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
async function getPackageDependencies(packagePath: string): Promise<string[]> {
|
|
208
|
+
const dependencies = new Set<string>()
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
const pkgJsonPath = join(packagePath, 'package.json')
|
|
212
|
+
const raw = await readFile(pkgJsonPath, 'utf-8')
|
|
213
|
+
const pkgData = JSON.parse(raw)
|
|
214
|
+
|
|
215
|
+
// Collect all types of dependencies
|
|
216
|
+
const depTypes = ['dependencies', 'devDependencies', 'peerDependencies', 'optionalDependencies']
|
|
217
|
+
for (const depType of depTypes) {
|
|
218
|
+
if (pkgData[depType]) {
|
|
219
|
+
for (const depName of Object.keys(pkgData[depType])) {
|
|
220
|
+
if (!depName.startsWith('@types/')) {
|
|
221
|
+
dependencies.add(depName)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
} catch {
|
|
227
|
+
// Ignore errors reading package.json
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return Array.from(dependencies)
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function collectSpecificNodeModulePackages(
|
|
234
|
+
workspaceDir: string,
|
|
235
|
+
workspaceName: string,
|
|
236
|
+
packagesToFind: Set<string>
|
|
237
|
+
): Promise<PackageVersionInfo[]> {
|
|
238
|
+
const packages: PackageVersionInfo[] = []
|
|
239
|
+
const nodeModulesPath = join(workspaceDir, 'node_modules')
|
|
240
|
+
|
|
241
|
+
async function recurseNodeModules(dir: string, depth = 0) {
|
|
242
|
+
// Avoid infinite recursion in nested node_modules
|
|
243
|
+
if (depth > 10) return
|
|
244
|
+
|
|
245
|
+
let entries: string[]
|
|
246
|
+
try {
|
|
247
|
+
entries = await readdir(dir)
|
|
248
|
+
} catch {
|
|
249
|
+
return
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
for (const entry of entries) {
|
|
253
|
+
const fullPath = join(dir, entry)
|
|
254
|
+
let entryStat
|
|
255
|
+
try {
|
|
256
|
+
entryStat = await stat(fullPath)
|
|
257
|
+
} catch {
|
|
258
|
+
continue
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (entryStat.isDirectory()) {
|
|
262
|
+
if (entry.startsWith('@')) {
|
|
263
|
+
// Scoped package directory, recurse into it
|
|
264
|
+
await recurseNodeModules(fullPath, depth + 1)
|
|
265
|
+
} else if (entry !== '.bin' && entry !== '.cache') {
|
|
266
|
+
// Regular package directory
|
|
267
|
+
const pkgJsonPath = join(fullPath, 'package.json')
|
|
268
|
+
try {
|
|
269
|
+
const pkgJsonStat = await stat(pkgJsonPath)
|
|
270
|
+
if (pkgJsonStat.isFile()) {
|
|
271
|
+
const raw = await readFile(pkgJsonPath, 'utf-8')
|
|
272
|
+
const pkgData = JSON.parse(raw)
|
|
273
|
+
if (
|
|
274
|
+
pkgData.name &&
|
|
275
|
+
pkgData.version &&
|
|
276
|
+
packagesToFind.has(pkgData.name) &&
|
|
277
|
+
!pkgData.name.startsWith('@types/')
|
|
278
|
+
) {
|
|
279
|
+
packages.push({
|
|
280
|
+
name: pkgData.name,
|
|
281
|
+
version: pkgData.version,
|
|
282
|
+
workspace: workspaceName,
|
|
283
|
+
path: fullPath,
|
|
284
|
+
})
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
} catch {
|
|
288
|
+
// Not a valid package, might have nested node_modules
|
|
289
|
+
const nestedNodeModules = join(fullPath, 'node_modules')
|
|
290
|
+
try {
|
|
291
|
+
const nestedStat = await stat(nestedNodeModules)
|
|
292
|
+
if (nestedStat.isDirectory()) {
|
|
293
|
+
await recurseNodeModules(nestedNodeModules, depth + 1)
|
|
294
|
+
}
|
|
295
|
+
} catch {}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
try {
|
|
303
|
+
await recurseNodeModules(nodeModulesPath)
|
|
304
|
+
} catch {
|
|
305
|
+
// Workspace might not have node_modules yet
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return packages
|
|
309
|
+
}
|
|
310
|
+
|
|
108
311
|
async function main() {
|
|
109
312
|
const args = process.argv.slice(2)
|
|
313
|
+
|
|
110
314
|
if (args.includes('--unlink')) {
|
|
111
315
|
await undoLinks()
|
|
112
316
|
process.exit(0)
|
|
113
317
|
}
|
|
318
|
+
|
|
319
|
+
const workspaceDirs = args.filter((arg) => !arg.startsWith('--'))
|
|
320
|
+
|
|
114
321
|
if (args.length === 0) {
|
|
115
322
|
console.info('No workspace directories provided.')
|
|
116
323
|
process.exit(0)
|
|
117
324
|
}
|
|
325
|
+
|
|
326
|
+
// Find all local packages first
|
|
118
327
|
const allLocalPackages: Record<string, string> = {}
|
|
119
|
-
for (const workspaceDir of
|
|
328
|
+
for (const workspaceDir of workspaceDirs) {
|
|
120
329
|
const resolved = resolve(workspaceDir)
|
|
121
330
|
const found = await findLocalPackages(resolved)
|
|
122
331
|
Object.assign(allLocalPackages, found)
|
|
123
332
|
}
|
|
333
|
+
|
|
334
|
+
// Run check with scoped packages
|
|
335
|
+
if (!(await checkAllPackageVersionsAligned(workspaceDirs, allLocalPackages))) {
|
|
336
|
+
if (args.includes('--check')) {
|
|
337
|
+
// only exit if checking, otherwise its a warning
|
|
338
|
+
process.exit(1)
|
|
339
|
+
}
|
|
340
|
+
} else {
|
|
341
|
+
if (args.includes('--check')) {
|
|
342
|
+
return
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
124
346
|
await linkPackages(allLocalPackages)
|
|
125
347
|
console.info(`\n ✓ linked ${Object.keys(allLocalPackages).length} packages`)
|
|
126
348
|
}
|