npmFacts
uses node:path
What an npm package's export (as code refers to it: npm:<name>@<range>, a subpath, an export) reaches on a side
(exportFacts), from the package as the codebase has it installed; undefined if it isn't, or its export map
names no file for it there. Kept for this process (factsKept) while the package's package.json is the
same file: placing a codebase asks of each package many times over.
import { exportFacts, factsKept, moduleFile, resolvePackageSubpath, SIDE_CONDITIONS } from "#codebase/tcmts/cli/npm"; import type { NpmFacts, PackageJson } from "#codebase/tcmts/cli/npm"; import type { ExtRef } from "#codebase/tcmts/core/types"; import { npmAlias } from "#codebase/tcmts/loader/packages"; import fs from "node:fs"; import path from "node:path"; export function npmFacts( cacheDir: string, ext: ExtRef, side: keyof typeof SIDE_CONDITIONS, ): NpmFacts | undefined { if (!ext.module.startsWith("npm:")) return undefined; const dir = path.join(cacheDir, "node_modules", npmAlias(ext.module)); const manifest = path.join(dir, "package.json"); // (one stat a time, not a realpath, two reads and a parse; what isn't installed isn't kept: it may be installed next) let stamp: number; try { stamp = fs.statSync(manifest).mtimeMs; } catch { return undefined; } const key = `${dir}\n${ext.subpath}\n${ext.export}\n${side}`; const had = factsKept.get(key); if (had && had.stamp === stamp) return had.facts; try { const pkg = JSON.parse(fs.readFileSync(manifest, "utf8")) as PackageJson; const rel = resolvePackageSubpath(pkg, ext.subpath ? `./${ext.subpath}` : ".", [ ...SIDE_CONDITIONS[side], ]); if (!rel) return undefined; // (as Node finds it: `"main": "./index"` is index.js) const file = moduleFile(path.join(fs.realpathSync(dir), rel)); if (!file) return undefined; const facts = exportFacts(file, ext.export, side, cacheDir); factsKept.set(key, { stamp, facts }); return facts; } catch { return undefined; } }
uses
- tcmts.cli.npm.NpmFacts
- tcmts.cli.npm.PackageJson
- tcmts.cli.npm.SIDE_CONDITIONS
- tcmts.cli.npm.exportFacts
- tcmts.cli.npm.factsKept
- tcmts.cli.npm.moduleFile
- tcmts.cli.npm.resolvePackageSubpath
- tcmts.core.types.ExtRef
- tcmts.loader.packages.npmAlias