2 const fs
= require("fs");
3 const path
= require("path");
5 // When installing files rewritten to the Nix store with npm
6 // npm writes the symlinks relative to the build directory.
8 // This makes relocating node_modules tricky when refering to the store.
9 // This script walks node_modules and canonicalizes symlinks.
11 async
function canonicalize(storePrefix
, root
) {
12 console
.log(storePrefix
, root
)
13 const entries
= await fs
.promises
.readdir(root
);
14 const paths
= entries
.map((entry
) => path
.join(root
, entry
));
16 const stats
= await Promise
.all(
17 paths
.map(async (path
) => {
20 stat
: await fs
.promises
.lstat(path
),
25 const symlinks
= stats
.filter((stat
) => stat
.stat
.isSymbolicLink());
26 const dirs
= stats
.filter((stat
) => stat
.stat
.isDirectory());
28 // Canonicalize symlinks to their real path
30 symlinks
.map(async (stat
) => {
31 const target
= await fs
.promises
.realpath(stat
.path
);
32 if (target
.startsWith(storePrefix
)) {
33 await fs
.promises
.unlink(stat
.path
);
34 await fs
.promises
.symlink(target
, stat
.path
);
39 // Recurse into directories
40 await Promise
.all(dirs
.map((dir
) => canonicalize(storePrefix
, dir
.path
)));
43 async
function main() {
44 const args
= process
.argv
.slice(2);
45 const storePrefix
= args
[0];
47 if (fs
.existsSync("node_modules")) {
48 await
canonicalize(storePrefix
, "node_modules");