Files
scriptc/packages/cli/src/paths.ts
Chris TateandAlbert 31f268be2b feat: support wasm32-wasi as a production target (#133)
* feat: support wasm32-wasi as a production target

- Add production LLVM WASI codegen with a 32-bit ABI, coroutines, and dynamic modules
- Integrate WASI builds and execution into the CLI with capability diagnostics
- Add differential coverage and document the fourth production target

Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com>

* fix: address wasm target review findings

* fix WASI guest paths and fetch alias detection

* fix WASI async bridge and fetch detection

---------

Co-authored-by: Albert <57402359+bulatovv@users.noreply.github.com>
2026-08-11 14:12:59 -05:00

53 lines
2.0 KiB
TypeScript

import { tmpdir } from "node:os";
import { buildTargetPlatform, wasiGuestPath } from "@scriptc/compiler";
/** Default executable filename for the build target. Explicit --out paths
* stay exact; only scriptc's generated default needs the Windows PE suffix. */
export function defaultExecutableName(stem: string, platform: string = buildTargetPlatform()): string {
if (platform === "win32") return `${stem}.exe`;
if (platform === "wasi") return `${stem}.wasm`;
return stem;
}
/** Host paths exposed by `scriptc run` to a WASI Preview 1 module. Guest
* `/tmp` maps to the host's real platform temp directory instead of assuming
* the POSIX spelling exists (notably false on Windows). */
export function wasiPreopens(
cwd: string = process.cwd(),
hostTmp: string = tmpdir(),
): Record<string, string> {
return { "/": cwd, "/tmp": hostTmp };
}
/** Environment inherited by a WASI module. Host-absolute directory values
* must not claim paths outside the guest namespace: `/` is the module's
* capability root/home/cwd and `/tmp` is its writable temporary directory. */
export function wasiEnvironment(
env: NodeJS.ProcessEnv = process.env,
cwd: string = process.cwd(),
hostTmp: string = tmpdir(),
): Record<string, string> {
const guest = Object.fromEntries(
Object.entries(env).filter((entry): entry is [string, string] => entry[1] !== undefined),
);
guest["PWD"] = "/";
guest["HOME"] = "/";
guest["TMPDIR"] = "/tmp";
if (guest["USERPROFILE"] !== undefined) guest["USERPROFILE"] = "/";
if (guest["TMP"] !== undefined) guest["TMP"] = "/tmp";
if (guest["TEMP"] !== undefined) guest["TEMP"] = "/tmp";
// These optional shell/package-manager paths retain their meaning only
// when they fall under a capability the runner actually exposes.
for (const key of ["OLDPWD", "INIT_CWD"] as const) {
const value = guest[key];
if (value === undefined) continue;
const mapped = wasiGuestPath(value, cwd, hostTmp);
if (mapped === null) delete guest[key];
else guest[key] = mapped;
}
return guest;
}