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 CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- import { readdir, readFile, stat, rm, symlink, rename, mkdir, cp } from "node:fs/promises";
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)), args.length === 0 && (console.info("No workspace directories provided."), 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 args) {
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,MAAM,IAAI,SAAS,QAAQ,OAAO,UAAU;AACxE,SAAS,eAAe;AACxB,SAAS,MAAM,UAAU,eAAe;AAIpC,OAAO,MAAQ,QACjB,QAAQ,MAAM,4CAA4C,GAC1D,QAAQ,KAAK,CAAC;AAGhB,MAAM,aAAa;AAEnB,eAAe,kBAAkB,SAAkD;AACjF,QAAM,UAAkC,CAAC;AAEzC,iBAAe,QAAQ,KAAa;AAClC,QAAI;AACJ,QAAI;AACF,gBAAU,MAAM,QAAQ,GAAG;AAAA,IAC7B,QAAQ;AACN;AAAA,IACF;AAEA,UAAM,QAAQ;AAAA,MACZ,QAAQ,IAAI,OAAO,UAAU;AAC3B,YAAI,UAAU,WAAY;AAC1B,cAAM,WAAW,KAAK,KAAK,KAAK;AAChC,YAAI;AACJ,YAAI;AACF,sBAAY,MAAM,KAAK,QAAQ;AAAA,QACjC,QAAQ;AACN;AAAA,QACF;AACA,YAAI,UAAU,YAAY,GAAG;AAC3B,gBAAM,cAAc,KAAK,UAAU,cAAc;AACjD,cAAI;AAEF,iBADoB,MAAM,KAAK,WAAW,GAC1B,OAAO,GAAG;AACxB,oBAAM,MAAM,MAAM,SAAS,aAAa,OAAO,GACzC,UAAU,KAAK,MAAM,GAAG;AAC9B,cAAI,QAAQ,SACV,QAAQ,QAAQ,IAAI,IAAI;AAAA,YAE5B;AAAA,UACF,QAAQ;AACN,kBAAM,QAAQ,QAAQ;AAAA,UACxB;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,eAAM,QAAQ,OAAO,GACd;AACT;AAEA,eAAe,aAAa,kBAA0C;AACpE,QAAM,YAAY,KAAK,QAAQ,IAAI,GAAG,gBAAgB,UAAU,UAAU,OAAO;AACjF,QAAM,MAAM,WAAW,EAAE,WAAW,GAAK,CAAC;AAC1C,aAAW,WAAW,OAAO,KAAK,gBAAgB,GAAG;AACnD,UAAM,YAAY,KAAK,QAAQ,IAAI,GAAG,gBAAgB,GAAG,QAAQ,MAAM,GAAG,CAAC;AAC3E,QAAI;AAEF,MADqB,MAAM,KAAK,SAAS,KAEvC,MAAM,GAAG,WAAW,KAAK,WAAW,QAAQ,QAAQ,KAAK,IAAI,CAAC,GAAG;AAAA,QAC/D,WAAW;AAAA,QACX,aAAa;AAAA,MACf,CAAC;AAEH,YAAM,eAAe,iBAAiB,OAAO;AAC7C,MAAI,iBACF,QAAQ;AAAA,QACN,WAAW,SAAS,QAAQ,IAAI,GAAG,SAAS,CAAC,OAAO,aAAa,QAAQ,QAAQ,GAAG,GAAG,CAAC;AAAA,MAC1F,GACA,MAAM,GAAG,WAAW,EAAE,WAAW,IAAM,OAAO,GAAK,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC,GACpE,MAAM,QAAQ,cAAc,SAAS;AAAA,IAEzC,QAAQ;AAAA,IAAC;AAAA,EACX;AACF;AAEA,eAAe,YAAY;AACzB,QAAM,YAAY,KAAK,QAAQ,IAAI,GAAG,gBAAgB,UAAU,UAAU,OAAO;AACjF,MAAI;AACJ,MAAI;AACF,iBAAa,MAAM,QAAQ,SAAS;AAAA,EACtC,QAAQ;AACN,YAAQ,KAAK,kBAAkB;AAC/B;AAAA,EACF;AACA,aAAW,QAAQ,YAAY;AAC7B,UAAM,eAAe,KAAK,QAAQ,MAAM,GAAG,GACrC,SAAS,KAAK,QAAQ,IAAI,GAAG,gBAAgB,GAAG,aAAa,MAAM,GAAG,CAAC;AAC7E,UAAM,GAAG,QAAQ,EAAE,WAAW,IAAM,OAAO,GAAK,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC,GACjE,MAAM,OAAO,KAAK,WAAW,IAAI,GAAG,MAAM,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC,GAC1D,QAAQ,KAAK,aAAa,YAAY,EAAE;AAAA,EAC1C;AACF;AAEA,eAAe,OAAO;AACpB,QAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,EAAI,KAAK,SAAS,UAAU,MAC1B,MAAM,UAAU,GAChB,QAAQ,KAAK,CAAC,IAEZ,KAAK,WAAW,MAClB,QAAQ,KAAK,oCAAoC,GACjD,QAAQ,KAAK,CAAC;AAEhB,QAAM,mBAA2C,CAAC;AAClD,aAAW,gBAAgB,MAAM;AAC/B,UAAM,WAAW,QAAQ,YAAY,GAC/B,QAAQ,MAAM,kBAAkB,QAAQ;AAC9C,WAAO,OAAO,kBAAkB,KAAK;AAAA,EACvC;AACA,QAAM,aAAa,gBAAgB,GACnC,QAAQ,KAAK;AAAA,iBAAe,OAAO,KAAK,gBAAgB,EAAE,MAAM,WAAW;AAC7E;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,UAAU,GAAG,GAC3B,QAAQ,KAAK,CAAC;AAChB,CAAC;",
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 { readdir, readFile, stat, rm, symlink, rename, mkdir, cp } from "node:fs/promises";
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)), args.length === 0 && (console.info("No workspace directories provided."), 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 args) {
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
  }
@@ -1 +1 @@
1
- {"version":3,"names":["readdir","readFile","stat","rm","symlink","rename","mkdir","cp","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","linkPackages","externalPackages","backupDir","cwd","recursive","pkgName","Object","keys","localPath","split","replace","dereference","externalPath","info","force","catch","undoLinks","movedItems","item","originalName","nmPath","main","args","argv","slice","includes","length","allLocalPackages","workspaceDir","resolved","found","assign","err"],"sources":["../src/index.ts"],"sourcesContent":[null],"mappings":";AAOA,SAASA,OAAA,EAASC,QAAA,EAAUC,IAAA,EAAMC,EAAA,EAAIC,OAAA,EAASC,MAAA,EAAQC,KAAA,EAAOC,EAAA,QAAU;AACxE,SAASC,OAAA,QAAe;AACxB,SAASC,IAAA,EAAMC,QAAA,EAAUC,OAAA,QAAe;AAIpC,OAAOC,GAAA,GAAQ,QACjBC,OAAA,CAAQC,KAAA,CAAM,4CAA4C,GAC1DC,OAAA,CAAQC,IAAA,CAAK,CAAC;AAGhB,MAAMC,UAAA,GAAa;AAEnB,eAAeC,kBAAkBC,OAAA,EAAkD;EACjF,MAAMC,OAAA,GAAkC,CAAC;EAEzC,eAAeC,QAAQC,GAAA,EAAa;IAClC,IAAIC,OAAA;IACJ,IAAI;MACFA,OAAA,GAAU,MAAMvB,OAAA,CAAQsB,GAAG;IAC7B,QAAQ;MACN;IACF;IAEA,MAAME,OAAA,CAAQC,GAAA,CACZF,OAAA,CAAQG,GAAA,CAAI,MAAOC,KAAA,IAAU;MAC3B,IAAIA,KAAA,KAAUV,UAAA,EAAY;MAC1B,MAAMW,QAAA,GAAWnB,IAAA,CAAKa,GAAA,EAAKK,KAAK;MAChC,IAAIE,SAAA;MACJ,IAAI;QACFA,SAAA,GAAY,MAAM3B,IAAA,CAAK0B,QAAQ;MACjC,QAAQ;QACN;MACF;MACA,IAAIC,SAAA,CAAUC,WAAA,CAAY,GAAG;QAC3B,MAAMC,WAAA,GAActB,IAAA,CAAKmB,QAAA,EAAU,cAAc;QACjD,IAAI;UAEF,KADoB,MAAM1B,IAAA,CAAK6B,WAAW,GAC1BC,MAAA,CAAO,GAAG;YACxB,MAAMC,GAAA,GAAM,MAAMhC,QAAA,CAAS8B,WAAA,EAAa,OAAO;cACzCG,OAAA,GAAUC,IAAA,CAAKC,KAAA,CAAMH,GAAG;YAC1BC,OAAA,CAAQG,IAAA,KACVjB,OAAA,CAAQc,OAAA,CAAQG,IAAI,IAAIT,QAAA;UAE5B;QACF,QAAQ;UACN,MAAMP,OAAA,CAAQO,QAAQ;QACxB;MACF;IACF,CAAC,CACH;EACF;EAEA,aAAMP,OAAA,CAAQF,OAAO,GACdC,OAAA;AACT;AAEA,eAAekB,aAAaC,gBAAA,EAA0C;EACpE,MAAMC,SAAA,GAAY/B,IAAA,CAAKM,OAAA,CAAQ0B,GAAA,CAAI,GAAG,gBAAgB,UAAU,UAAU,OAAO;EACjF,MAAMnC,KAAA,CAAMkC,SAAA,EAAW;IAAEE,SAAA,EAAW;EAAK,CAAC;EAC1C,WAAWC,OAAA,IAAWC,MAAA,CAAOC,IAAA,CAAKN,gBAAgB,GAAG;IACnD,MAAMO,SAAA,GAAYrC,IAAA,CAAKM,OAAA,CAAQ0B,GAAA,CAAI,GAAG,gBAAgB,GAAGE,OAAA,CAAQI,KAAA,CAAM,GAAG,CAAC;IAC3E,IAAI;MACmB,OAAM7C,IAAA,CAAK4C,SAAS,OAEvC,MAAMvC,EAAA,CAAGuC,SAAA,EAAWrC,IAAA,CAAK+B,SAAA,EAAWG,OAAA,CAAQK,OAAA,CAAQ,KAAK,IAAI,CAAC,GAAG;QAC/DN,SAAA,EAAW;QACXO,WAAA,EAAa;MACf,CAAC;MAEH,MAAMC,YAAA,GAAeX,gBAAA,CAAiBI,OAAO;MACzCO,YAAA,KACFrC,OAAA,CAAQsC,IAAA,CACN,WAAWzC,QAAA,CAASK,OAAA,CAAQ0B,GAAA,CAAI,GAAGK,SAAS,CAAC,OAAOI,YAAA,CAAaF,OAAA,CAAQxC,OAAA,CAAQ,GAAG,GAAG,CAAC,EAC1F,GACA,MAAML,EAAA,CAAG2C,SAAA,EAAW;QAAEJ,SAAA,EAAW;QAAMU,KAAA,EAAO;MAAK,CAAC,EAAEC,KAAA,CAAM,MAAM,CAAC,CAAC,GACpE,MAAMjD,OAAA,CAAQ8C,YAAA,EAAcJ,SAAS;IAEzC,QAAQ,CAAC;EACX;AACF;AAEA,eAAeQ,UAAA,EAAY;EACzB,MAAMd,SAAA,GAAY/B,IAAA,CAAKM,OAAA,CAAQ0B,GAAA,CAAI,GAAG,gBAAgB,UAAU,UAAU,OAAO;EACjF,IAAIc,UAAA;EACJ,IAAI;IACFA,UAAA,GAAa,MAAMvD,OAAA,CAAQwC,SAAS;EACtC,QAAQ;IACN3B,OAAA,CAAQsC,IAAA,CAAK,kBAAkB;IAC/B;EACF;EACA,WAAWK,IAAA,IAAQD,UAAA,EAAY;IAC7B,MAAME,YAAA,GAAeD,IAAA,CAAKR,OAAA,CAAQ,MAAM,GAAG;MACrCU,MAAA,GAASjD,IAAA,CAAKM,OAAA,CAAQ0B,GAAA,CAAI,GAAG,gBAAgB,GAAGgB,YAAA,CAAaV,KAAA,CAAM,GAAG,CAAC;IAC7E,MAAM5C,EAAA,CAAGuD,MAAA,EAAQ;MAAEhB,SAAA,EAAW;MAAMU,KAAA,EAAO;IAAK,CAAC,EAAEC,KAAA,CAAM,MAAM,CAAC,CAAC,GACjE,MAAMhD,MAAA,CAAOI,IAAA,CAAK+B,SAAA,EAAWgB,IAAI,GAAGE,MAAM,EAAEL,KAAA,CAAM,MAAM,CAAC,CAAC,GAC1DxC,OAAA,CAAQsC,IAAA,CAAK,aAAaM,YAAY,EAAE;EAC1C;AACF;AAEA,eAAeE,KAAA,EAAO;EACpB,MAAMC,IAAA,GAAO7C,OAAA,CAAQ8C,IAAA,CAAKC,KAAA,CAAM,CAAC;EAC7BF,IAAA,CAAKG,QAAA,CAAS,UAAU,MAC1B,MAAMT,SAAA,CAAU,GAChBvC,OAAA,CAAQC,IAAA,CAAK,CAAC,IAEZ4C,IAAA,CAAKI,MAAA,KAAW,MAClBnD,OAAA,CAAQsC,IAAA,CAAK,oCAAoC,GACjDpC,OAAA,CAAQC,IAAA,CAAK,CAAC;EAEhB,MAAMiD,gBAAA,GAA2C,CAAC;EAClD,WAAWC,YAAA,IAAgBN,IAAA,EAAM;IAC/B,MAAMO,QAAA,GAAWxD,OAAA,CAAQuD,YAAY;MAC/BE,KAAA,GAAQ,MAAMlD,iBAAA,CAAkBiD,QAAQ;IAC9CvB,MAAA,CAAOyB,MAAA,CAAOJ,gBAAA,EAAkBG,KAAK;EACvC;EACA,MAAM9B,YAAA,CAAa2B,gBAAgB,GACnCpD,OAAA,CAAQsC,IAAA,CAAK;AAAA,iBAAeP,MAAA,CAAOC,IAAA,CAAKoB,gBAAgB,EAAED,MAAM,WAAW;AAC7E;AAEAL,IAAA,CAAK,EAAEN,KAAA,CAAOiB,GAAA,IAAQ;EACpBzD,OAAA,CAAQC,KAAA,CAAM,UAAUwD,GAAG,GAC3BvD,OAAA,CAAQC,IAAA,CAAK,CAAC;AAChB,CAAC","ignoreList":[]}
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.491",
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.126.18"
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 { readdir, readFile, stat, rm, symlink, rename, mkdir, cp } from 'node:fs/promises'
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 args) {
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
  }