lllink 1.27.1 → 2.0.0-beta.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.mjs +245 -243
  2. package/package.json +2 -2
package/dist/index.mjs CHANGED
@@ -2,268 +2,270 @@
2
2
  import { cp, mkdir, readFile, readdir, 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
6
  if (typeof Bun === "undefined") {
6
- console.error(`Must run in Bun due to using ~ resolutions`);
7
- process.exit(1);
7
+ console.error(`Must run in Bun due to using ~ resolutions`);
8
+ process.exit(1);
8
9
  }
9
10
  const IGNORE_DIR = "node_modules";
10
11
  async function findLocalPackages(rootDir) {
11
- const results = {};
12
- async function recurse(dir) {
13
- let entries;
14
- try {
15
- entries = await readdir(dir);
16
- } catch {
17
- return;
18
- }
19
- await Promise.all(entries.map(async entry => {
20
- if (entry === IGNORE_DIR) return;
21
- const fullPath = join(dir, entry);
22
- let entryStat;
23
- try {
24
- entryStat = await stat(fullPath);
25
- } catch {
26
- return;
27
- }
28
- if (entryStat.isDirectory()) {
29
- const pkgJsonPath = join(fullPath, "package.json");
30
- try {
31
- const pkgJsonStat = await stat(pkgJsonPath);
32
- if (pkgJsonStat.isFile()) {
33
- const raw = await readFile(pkgJsonPath, "utf-8");
34
- const pkgData = JSON.parse(raw);
35
- if (pkgData.name && !pkgData.name.startsWith("@types/")) {
36
- results[pkgData.name] = fullPath;
37
- }
38
- }
39
- } catch {
40
- await recurse(fullPath);
41
- }
42
- }
43
- }));
44
- }
45
- await recurse(rootDir);
46
- return results;
12
+ const results = {};
13
+ async function recurse(dir) {
14
+ let entries;
15
+ try {
16
+ entries = await readdir(dir);
17
+ } catch {
18
+ return;
19
+ }
20
+ await Promise.all(entries.map(async (entry) => {
21
+ if (entry === IGNORE_DIR) return;
22
+ const fullPath = join(dir, entry);
23
+ let entryStat;
24
+ try {
25
+ entryStat = await stat(fullPath);
26
+ } catch {
27
+ return;
28
+ }
29
+ if (entryStat.isDirectory()) {
30
+ const pkgJsonPath = join(fullPath, "package.json");
31
+ try {
32
+ const pkgJsonStat = await stat(pkgJsonPath);
33
+ if (pkgJsonStat.isFile()) {
34
+ const raw = await readFile(pkgJsonPath, "utf-8");
35
+ const pkgData = JSON.parse(raw);
36
+ if (pkgData.name && !pkgData.name.startsWith("@types/")) {
37
+ results[pkgData.name] = fullPath;
38
+ }
39
+ }
40
+ } catch {
41
+ await recurse(fullPath);
42
+ }
43
+ }
44
+ }));
45
+ }
46
+ await recurse(rootDir);
47
+ return results;
47
48
  }
48
49
  async function linkPackages(externalPackages) {
49
- const backupDir = join(process.cwd(), "node_modules", ".cache", "lllink", "moved");
50
- await mkdir(backupDir, {
51
- recursive: true
52
- });
53
- for (const pkgName of Object.keys(externalPackages)) {
54
- const localPath = join(process.cwd(), "node_modules", ...pkgName.split("/"));
55
- try {
56
- const existingStat = await stat(localPath);
57
- if (existingStat) {
58
- await cp(localPath, join(backupDir, pkgName.replace("/", "__")), {
59
- recursive: true,
60
- dereference: true
61
- });
62
- }
63
- const externalPath = externalPackages[pkgName];
64
- if (externalPath) {
65
- console.info(`symlink ${relative(process.cwd(), localPath)} to ${externalPath.replace(homedir(), "~")}`);
66
- await rm(localPath, {
67
- recursive: true,
68
- force: true
69
- }).catch(() => {});
70
- await symlink(externalPath, localPath);
71
- }
72
- } catch {}
73
- }
50
+ const backupDir = join(process.cwd(), "node_modules", ".cache", "lllink", "moved");
51
+ await mkdir(backupDir, { recursive: true });
52
+ for (const pkgName of Object.keys(externalPackages)) {
53
+ const localPath = join(process.cwd(), "node_modules", ...pkgName.split("/"));
54
+ try {
55
+ const existingStat = await stat(localPath);
56
+ if (existingStat) {
57
+ await cp(localPath, join(backupDir, pkgName.replace("/", "__")), {
58
+ recursive: true,
59
+ dereference: true
60
+ });
61
+ }
62
+ const externalPath = externalPackages[pkgName];
63
+ if (externalPath) {
64
+ console.info(`symlink ${relative(process.cwd(), localPath)} to ${externalPath.replace(homedir(), "~")}`);
65
+ await rm(localPath, {
66
+ recursive: true,
67
+ force: true
68
+ }).catch(() => {});
69
+ await symlink(externalPath, localPath);
70
+ }
71
+ } catch {}
72
+ }
74
73
  }
75
74
  async function undoLinks() {
76
- const backupDir = join(process.cwd(), "node_modules", ".cache", "lllink", "moved");
77
- let movedItems;
78
- try {
79
- movedItems = await readdir(backupDir);
80
- } catch {
81
- console.info("Nothing to undo.");
82
- return;
83
- }
84
- for (const item of movedItems) {
85
- const originalName = item.replace("__", "/");
86
- const nmPath = join(process.cwd(), "node_modules", ...originalName.split("/"));
87
- await rm(nmPath, {
88
- recursive: true,
89
- force: true
90
- }).catch(() => {});
91
- await rename(join(backupDir, item), nmPath).catch(() => {});
92
- console.info(`Restored: ${originalName}`);
93
- }
75
+ const backupDir = join(process.cwd(), "node_modules", ".cache", "lllink", "moved");
76
+ let movedItems;
77
+ try {
78
+ movedItems = await readdir(backupDir);
79
+ } catch {
80
+ console.info("Nothing to undo.");
81
+ return;
82
+ }
83
+ for (const item of movedItems) {
84
+ const originalName = item.replace("__", "/");
85
+ const nmPath = join(process.cwd(), "node_modules", ...originalName.split("/"));
86
+ await rm(nmPath, {
87
+ recursive: true,
88
+ force: true
89
+ }).catch(() => {});
90
+ await rename(join(backupDir, item), nmPath).catch(() => {});
91
+ console.info(`Restored: ${originalName}`);
92
+ }
94
93
  }
95
94
  async function checkAllPackageVersionsAligned(workspaceDirs, packagesToCheck) {
96
- const allPackageVersions = [];
97
- const allDirs = [process.cwd(), ...workspaceDirs];
98
- const allDepsToCheck = /* @__PURE__ */new Set();
99
- for (const pkgName of Object.keys(packagesToCheck)) {
100
- allDepsToCheck.add(pkgName);
101
- }
102
- for (const [pkgName, pkgPath] of Object.entries(packagesToCheck)) {
103
- const deps = await getPackageDependencies(pkgPath);
104
- for (const dep of deps) {
105
- allDepsToCheck.add(dep);
106
- }
107
- }
108
- for (const workspaceDir of allDirs) {
109
- const resolved = resolve(workspaceDir);
110
- const workspaceName = workspaceDir === process.cwd() ? "current" : workspaceDir.split("/").pop() || workspaceDir;
111
- const packages = await collectSpecificNodeModulePackages(resolved, workspaceName, allDepsToCheck);
112
- allPackageVersions.push(...packages);
113
- }
114
- const packageGroups = {};
115
- for (const pkg of allPackageVersions) {
116
- if (!packageGroups[pkg.name]) {
117
- packageGroups[pkg.name] = [];
118
- }
119
- packageGroups[pkg.name].push(pkg);
120
- }
121
- const mismatches = [];
122
- for (const [pkgName, versions] of Object.entries(packageGroups)) {
123
- const versionsByWorkspace = {};
124
- for (const version of versions) {
125
- versionsByWorkspace[version.workspace] = version.version;
126
- }
127
- const uniqueVersions = new Set(Object.values(versionsByWorkspace));
128
- if (uniqueVersions.size > 1) {
129
- const uniqueVersionsArray = Object.entries(versionsByWorkspace).map(([workspace, version]) => ({
130
- name: pkgName,
131
- version,
132
- workspace,
133
- path: versions.find(v => v.workspace === workspace)?.path || ""
134
- }));
135
- mismatches.push({
136
- name: pkgName,
137
- versions: uniqueVersionsArray
138
- });
139
- }
140
- }
141
- if (mismatches.length === 0) {
142
- console.info("\u2713 All package versions are aligned across workspaces!");
143
- return true;
144
- }
145
- console.info(`
95
+ const allPackageVersions = [];
96
+ const allDirs = [process.cwd(), ...workspaceDirs];
97
+ const allDepsToCheck = /* @__PURE__ */ new Set();
98
+ for (const pkgName of Object.keys(packagesToCheck)) {
99
+ allDepsToCheck.add(pkgName);
100
+ }
101
+ for (const [pkgName, pkgPath] of Object.entries(packagesToCheck)) {
102
+ const deps = await getPackageDependencies(pkgPath);
103
+ for (const dep of deps) {
104
+ allDepsToCheck.add(dep);
105
+ }
106
+ }
107
+ for (const workspaceDir of allDirs) {
108
+ const resolved = resolve(workspaceDir);
109
+ const workspaceName = workspaceDir === process.cwd() ? "current" : workspaceDir.split("/").pop() || workspaceDir;
110
+ const packages = await collectSpecificNodeModulePackages(resolved, workspaceName, allDepsToCheck);
111
+ allPackageVersions.push(...packages);
112
+ }
113
+ const packageGroups = {};
114
+ for (const pkg of allPackageVersions) {
115
+ if (!packageGroups[pkg.name]) {
116
+ packageGroups[pkg.name] = [];
117
+ }
118
+ packageGroups[pkg.name].push(pkg);
119
+ }
120
+ const mismatches = [];
121
+ for (const [pkgName, versions] of Object.entries(packageGroups)) {
122
+ const versionsByWorkspace = {};
123
+ for (const version of versions) {
124
+ versionsByWorkspace[version.workspace] = version.version;
125
+ }
126
+ const uniqueVersions = new Set(Object.values(versionsByWorkspace));
127
+ if (uniqueVersions.size > 1) {
128
+ const uniqueVersionsArray = Object.entries(versionsByWorkspace).map(([workspace, version]) => ({
129
+ name: pkgName,
130
+ version,
131
+ workspace,
132
+ path: versions.find((v) => v.workspace === workspace)?.path || ""
133
+ }));
134
+ mismatches.push({
135
+ name: pkgName,
136
+ versions: uniqueVersionsArray
137
+ });
138
+ }
139
+ }
140
+ if (mismatches.length === 0) {
141
+ console.info("✓ All package versions are aligned across workspaces!");
142
+ return true;
143
+ }
144
+ console.info(`
146
145
  \u274C Found ${mismatches.length} packages with mismatched versions, this may cause issues linking:
147
146
  `);
148
- for (const {
149
- name,
150
- versions
151
- } of mismatches) {
152
- console.info(`Package: ${name}`);
153
- for (const version of versions) {
154
- console.info(` ${version.workspace}: ${version.version}`);
155
- }
156
- console.info("");
157
- }
158
- return false;
147
+ for (const { name, versions } of mismatches) {
148
+ console.info(`Package: ${name}`);
149
+ for (const version of versions) {
150
+ console.info(` ${version.workspace}: ${version.version}`);
151
+ }
152
+ console.info("");
153
+ }
154
+ return false;
159
155
  }
160
156
  async function getPackageDependencies(packagePath) {
161
- const dependencies = /* @__PURE__ */new Set();
162
- try {
163
- const pkgJsonPath = join(packagePath, "package.json");
164
- const raw = await readFile(pkgJsonPath, "utf-8");
165
- const pkgData = JSON.parse(raw);
166
- const depTypes = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"];
167
- for (const depType of depTypes) {
168
- if (pkgData[depType]) {
169
- for (const depName of Object.keys(pkgData[depType])) {
170
- if (!depName.startsWith("@types/")) {
171
- dependencies.add(depName);
172
- }
173
- }
174
- }
175
- }
176
- } catch {}
177
- return Array.from(dependencies);
157
+ const dependencies = /* @__PURE__ */ new Set();
158
+ try {
159
+ const pkgJsonPath = join(packagePath, "package.json");
160
+ const raw = await readFile(pkgJsonPath, "utf-8");
161
+ const pkgData = JSON.parse(raw);
162
+ const depTypes = [
163
+ "dependencies",
164
+ "devDependencies",
165
+ "peerDependencies",
166
+ "optionalDependencies"
167
+ ];
168
+ for (const depType of depTypes) {
169
+ if (pkgData[depType]) {
170
+ for (const depName of Object.keys(pkgData[depType])) {
171
+ if (!depName.startsWith("@types/")) {
172
+ dependencies.add(depName);
173
+ }
174
+ }
175
+ }
176
+ }
177
+ } catch {}
178
+ return Array.from(dependencies);
178
179
  }
179
180
  async function collectSpecificNodeModulePackages(workspaceDir, workspaceName, packagesToFind) {
180
- const packages = [];
181
- const nodeModulesPath = join(workspaceDir, "node_modules");
182
- async function recurseNodeModules(dir, depth = 0) {
183
- if (depth > 10) return;
184
- let entries;
185
- try {
186
- entries = await readdir(dir);
187
- } catch {
188
- return;
189
- }
190
- for (const entry of entries) {
191
- const fullPath = join(dir, entry);
192
- let entryStat;
193
- try {
194
- entryStat = await stat(fullPath);
195
- } catch {
196
- continue;
197
- }
198
- if (entryStat.isDirectory()) {
199
- if (entry.startsWith("@")) {
200
- await recurseNodeModules(fullPath, depth + 1);
201
- } else if (entry !== ".bin" && entry !== ".cache") {
202
- const pkgJsonPath = join(fullPath, "package.json");
203
- try {
204
- const pkgJsonStat = await stat(pkgJsonPath);
205
- if (pkgJsonStat.isFile()) {
206
- const raw = await readFile(pkgJsonPath, "utf-8");
207
- const pkgData = JSON.parse(raw);
208
- if (pkgData.name && pkgData.version && packagesToFind.has(pkgData.name) && !pkgData.name.startsWith("@types/")) {
209
- packages.push({
210
- name: pkgData.name,
211
- version: pkgData.version,
212
- workspace: workspaceName,
213
- path: fullPath
214
- });
215
- }
216
- }
217
- } catch {
218
- const nestedNodeModules = join(fullPath, "node_modules");
219
- try {
220
- const nestedStat = await stat(nestedNodeModules);
221
- if (nestedStat.isDirectory()) {
222
- await recurseNodeModules(nestedNodeModules, depth + 1);
223
- }
224
- } catch {}
225
- }
226
- }
227
- }
228
- }
229
- }
230
- try {
231
- await recurseNodeModules(nodeModulesPath);
232
- } catch {}
233
- return packages;
181
+ const packages = [];
182
+ const nodeModulesPath = join(workspaceDir, "node_modules");
183
+ async function recurseNodeModules(dir, depth = 0) {
184
+ if (depth > 10) return;
185
+ let entries;
186
+ try {
187
+ entries = await readdir(dir);
188
+ } catch {
189
+ return;
190
+ }
191
+ for (const entry of entries) {
192
+ const fullPath = join(dir, entry);
193
+ let entryStat;
194
+ try {
195
+ entryStat = await stat(fullPath);
196
+ } catch {
197
+ continue;
198
+ }
199
+ if (entryStat.isDirectory()) {
200
+ if (entry.startsWith("@")) {
201
+ await recurseNodeModules(fullPath, depth + 1);
202
+ } else if (entry !== ".bin" && entry !== ".cache") {
203
+ const pkgJsonPath = join(fullPath, "package.json");
204
+ try {
205
+ const pkgJsonStat = await stat(pkgJsonPath);
206
+ if (pkgJsonStat.isFile()) {
207
+ const raw = await readFile(pkgJsonPath, "utf-8");
208
+ const pkgData = JSON.parse(raw);
209
+ if (pkgData.name && pkgData.version && packagesToFind.has(pkgData.name) && !pkgData.name.startsWith("@types/")) {
210
+ packages.push({
211
+ name: pkgData.name,
212
+ version: pkgData.version,
213
+ workspace: workspaceName,
214
+ path: fullPath
215
+ });
216
+ }
217
+ }
218
+ } catch {
219
+ const nestedNodeModules = join(fullPath, "node_modules");
220
+ try {
221
+ const nestedStat = await stat(nestedNodeModules);
222
+ if (nestedStat.isDirectory()) {
223
+ await recurseNodeModules(nestedNodeModules, depth + 1);
224
+ }
225
+ } catch {}
226
+ }
227
+ }
228
+ }
229
+ }
230
+ }
231
+ try {
232
+ await recurseNodeModules(nodeModulesPath);
233
+ } catch {}
234
+ return packages;
234
235
  }
235
236
  async function main() {
236
- const args = process.argv.slice(2);
237
- if (args.includes("--unlink")) {
238
- await undoLinks();
239
- process.exit(0);
240
- }
241
- const workspaceDirs = args.filter(arg => !arg.startsWith("--"));
242
- if (args.length === 0) {
243
- console.info("No workspace directories provided.");
244
- process.exit(0);
245
- }
246
- const allLocalPackages = {};
247
- for (const workspaceDir of workspaceDirs) {
248
- const resolved = resolve(workspaceDir);
249
- const found = await findLocalPackages(resolved);
250
- Object.assign(allLocalPackages, found);
251
- }
252
- if (!(await checkAllPackageVersionsAligned(workspaceDirs, allLocalPackages))) {
253
- if (args.includes("--check")) {
254
- process.exit(1);
255
- }
256
- } else {
257
- if (args.includes("--check")) {
258
- return;
259
- }
260
- }
261
- await linkPackages(allLocalPackages);
262
- console.info(`
237
+ const args = process.argv.slice(2);
238
+ if (args.includes("--unlink")) {
239
+ await undoLinks();
240
+ process.exit(0);
241
+ }
242
+ const workspaceDirs = args.filter((arg) => !arg.startsWith("--"));
243
+ if (args.length === 0) {
244
+ console.info("No workspace directories provided.");
245
+ process.exit(0);
246
+ }
247
+ const allLocalPackages = {};
248
+ for (const workspaceDir of workspaceDirs) {
249
+ const resolved = resolve(workspaceDir);
250
+ const found = await findLocalPackages(resolved);
251
+ Object.assign(allLocalPackages, found);
252
+ }
253
+ if (!await checkAllPackageVersionsAligned(workspaceDirs, allLocalPackages)) {
254
+ if (args.includes("--check")) {
255
+ process.exit(1);
256
+ }
257
+ } else {
258
+ if (args.includes("--check")) {
259
+ return;
260
+ }
261
+ }
262
+ await linkPackages(allLocalPackages);
263
+ console.info(`
263
264
  \u2713 linked ${Object.keys(allLocalPackages).length} packages`);
264
265
  }
265
- main().catch(err => {
266
- console.error("Error:", err);
267
- process.exit(1);
266
+ main().catch((err) => {
267
+ console.error("Error:", err);
268
+ process.exit(1);
268
269
  });
270
+
269
271
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lllink",
3
- "version": "1.27.1",
3
+ "version": "2.0.0-beta.45.1",
4
4
  "type": "module",
5
5
  "module": "dist",
6
6
  "exports": {
@@ -25,7 +25,7 @@
25
25
  },
26
26
  "devDependencies": {
27
27
  "@biomejs/biome": "2.3.3",
28
- "@tamagui/build": "2.6.2"
28
+ "@tamagui/build": "3.0.0-beta.1309.1"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"