specifierFor
uses node:path
How a file imports leaf from the project's file to: by path, or from another package (the nearest
package.json isn't the same, and it's a dependency) by that package's name, when an entry of its exports
exports it (re-exporting it through barrels counts).
import { exportsFrom, packageDirOf } from "#codebase/tcmts/cli/mirror"; import fs from "node:fs"; import path from "node:path"; export function specifierFor(from: string, to: string, leaf: string): string { const rel = path.relative(path.dirname(from), to).split(path.sep).join("/"); const relative = rel.startsWith(".") ? rel : `./${rel}`; const theirs = packageDirOf(to); const ours = packageDirOf(from); if (!theirs || !ours || theirs === ours) return relative; const read = (dir: string) => { try { return JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")) as Record<string, unknown>; } catch { return {}; } }; const pkg = read(theirs); const deps = read(ours); const name = typeof pkg.name === "string" ? pkg.name : undefined; if (!name || !["dependencies", "devDependencies", "peerDependencies"].some((k) => typeof deps[k] === "object" && deps[k] && name in (deps[k] as object))) return relative; const entries: Record<string, unknown> = typeof pkg.exports === "string" ? { ".": pkg.exports } : pkg.exports && typeof pkg.exports === "object" ? (pkg.exports as Record<string, unknown>) : typeof pkg.main === "string" ? { ".": pkg.main } : {}; for (const [sub, target] of Object.entries(entries)) { if (typeof target !== "string" || sub.includes("*")) continue; if (exportsFrom(path.resolve(theirs, target), to, leaf, new Set())) return sub === "." ? name : `${name}${sub.slice(1)}`; } return relative; }