@mesh-tech/mesh-cli
Version:
CLI for Mesh platform development utilities
81 lines (76 loc) • 3.18 kB
JavaScript
/**
* mesh dev launcher.
*
* In the monorepo this IS the package `bin`, and it ALWAYS runs the CLI from
* TypeScript source via tsx — so the CLI is never stale, needs no build, and
* `pnpm exec mesh` works even in a never-built worktree.
*
* There is NO source-vs-dist detection here: the swap is native and
* build-time. `scripts/build-for-publish.ts` rewrites the PUBLISHED package's
* `bin` to `./dist/bin/mesh.js` (mirroring how it rewrites `exports` from
* source→dist), so consumers run the built dist and never touch this launcher.
*/
import { execFileSync } from "node:child_process";
import { realpathSync } from "node:fs";
import { createRequire } from "node:module";
import { dirname, resolve } from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url";
/**
* Node argv that runs the TypeScript entry under tsx with the workspace
* `source` export condition. Pure, so it can be unit-tested without spawning.
*
* `tsxImport` is an ABSOLUTE tsx loader specifier resolved relative to THIS
* launcher — not the bare `"tsx"`. A bare `--import tsx` resolves tsx from the
* process CWD, so running the launcher from a directory without tsx on its
* module path (e.g. `~`) fails with "Cannot find package 'tsx'". Resolving it
* against the launcher makes `mesh` work from any cwd.
*
* @param {string} tsxImport absolute tsx loader (file: URL or path)
* @param {string} srcEntry absolute path to `bin/mesh.ts`
* @param {string[]} args CLI args (process.argv.slice(2))
*/
export function sourceRunArgv(tsxImport, srcEntry, args) {
return ["--import", tsxImport, "--conditions", "source", srcEntry, ...args];
}
/** Absolute tsx loader specifier, resolved relative to this launcher. */
function tsxImportSpecifier() {
return pathToFileURL(createRequire(import.meta.url).resolve("tsx")).href;
}
// Run only when invoked directly (not when imported by a test). Compare
// REALPATHS: pnpm's `.bin/mesh` shim execs this via a symlinked path, so
// `process.argv[1]` (symlink) would never string-equal `import.meta.url`
// (realpath) — collapse both through realpath first.
function invokedDirectly() {
try {
return realpathSync(fileURLToPath(import.meta.url)) === realpathSync(process.argv[1] ?? "");
} catch {
return false;
}
}
if (invokedDirectly()) {
const srcEntry = resolve(dirname(fileURLToPath(import.meta.url)), "mesh.ts");
let tsxImport;
try {
tsxImport = tsxImportSpecifier();
} catch {
process.stderr.write(
"mesh: could not resolve tsx. Run `pnpm install` in this workspace, then retry.\n",
);
process.exit(1);
}
try {
execFileSync(process.execPath, sourceRunArgv(tsxImport, srcEntry, process.argv.slice(2)), {
stdio: "inherit",
});
} catch (err) {
if (err?.signal) {
// The CLI died from a signal (e.g. SIGINT) → re-raise it so the exit code
// reflects the signal (130 on Ctrl-C) instead of a bare 1.
process.kill(process.pid, err.signal);
} else {
// Exited non-zero → propagate its code; spawn failure → 1.
process.exit(typeof err?.status === "number" ? err.status : 1);
}
}
}