summaryrefslogtreecommitdiffstats
path: root/pkgs/by-name/ze/zerobyte/normalize-bun-binaries.ts
blob: 27dd28403724d2fb9a3def69622d1edb8dd0f795 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { lstat, mkdir, readdir, rm, symlink } from "fs/promises";
import { join, relative } from "path";

type PackageManifest = {
  name?: string;
  bin?: string | Record<string, string>;
};

async function isDirectory(path: string) {
  try {
    return (await lstat(path)).isDirectory();
  } catch {
    return false;
  }
}

const bunRoot = join(process.cwd(), "node_modules/.bun");

for (const entry of (await readdir(bunRoot)).sort()) {
  const modulesRoot = join(bunRoot, entry, "node_modules");
  if (!(await isDirectory(modulesRoot))) continue;

  const binRoot = join(modulesRoot, ".bin");
  await rm(binRoot, { recursive: true, force: true });
  await mkdir(binRoot, { recursive: true });

  const packageDirs: string[] = [];
  for (const name of (await readdir(modulesRoot)).sort()) {
    if (name === ".bin" || name === ".bun") continue;

    const dir = join(modulesRoot, name);
    if (!(await isDirectory(dir))) continue;

    if (name.startsWith("@")) {
      for (const child of (await readdir(dir)).sort()) {
        const scopedDir = join(dir, child);
        if (await isDirectory(scopedDir)) packageDirs.push(scopedDir);
      }
    } else {
      packageDirs.push(dir);
    }
  }

  for (const packageDir of packageDirs.sort()) {
    const manifestFile = Bun.file(join(packageDir, "package.json"));
    if (!(await manifestFile.exists())) continue;

    const manifest = (await manifestFile.json()) as PackageManifest;
    if (!manifest.bin) continue;

    const binaries =
      typeof manifest.bin === "string"
        ? [[manifest.name ?? packageDir.split("/").pop(), manifest.bin]]
        : Object.entries(manifest.bin).sort((a, b) => a[0].localeCompare(b[0]));

    for (const [name, target] of binaries) {
      if (!name || !target) continue;

      const source = join(packageDir, target);
      if (!(await Bun.file(source).exists())) continue;

      const destination = join(binRoot, name.slice(name.lastIndexOf("/") + 1));
      await rm(destination, { force: true });
      await symlink(relative(binRoot, source) || ".", destination);
    }
  }
}