92 lines
2.3 KiB
TypeScript
92 lines
2.3 KiB
TypeScript
import { existsSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { pathToFileURL } from "node:url";
|
|
import { resolveTypeStrippingFlag } from "./ts-subprocess-flags.ts";
|
|
|
|
export interface SfCliEntry {
|
|
command: string;
|
|
args: string[];
|
|
cwd: string;
|
|
}
|
|
|
|
/** @deprecated Use SfCliEntry instead */
|
|
export interface ResolveSfCliEntryOptions {
|
|
packageRoot: string;
|
|
cwd: string;
|
|
execPath?: string;
|
|
hostKind?: string;
|
|
mode?: "interactive" | "rpc";
|
|
sessionDir?: string;
|
|
messages?: string[];
|
|
existsSync?: (path: string) => boolean;
|
|
}
|
|
|
|
/** @deprecated Use ResolveSfCliEntryOptions instead */
|
|
function buildExtraArgs(options: ResolveSfCliEntryOptions): string[] {
|
|
if (options.mode !== "rpc") return [];
|
|
|
|
if (!options.sessionDir) {
|
|
throw new Error("RPC CLI entry requires sessionDir");
|
|
}
|
|
|
|
return ["--mode", "rpc", "--continue", "--session-dir", options.sessionDir];
|
|
}
|
|
|
|
export function resolveSfCliEntry(
|
|
options: ResolveSfCliEntryOptions,
|
|
): SfCliEntry {
|
|
const checkExists = options.existsSync ?? existsSync;
|
|
const execPath = options.execPath ?? process.execPath;
|
|
const extraArgs = buildExtraArgs(options);
|
|
const messageArgs =
|
|
options.mode === "interactive" ? (options.messages ?? []) : [];
|
|
|
|
const sourceEntry = join(options.packageRoot, "src", "loader.ts");
|
|
const resolveTsLoader = join(
|
|
options.packageRoot,
|
|
"src",
|
|
"resources",
|
|
"extensions",
|
|
"sf",
|
|
"tests",
|
|
"resolve-ts.mjs",
|
|
);
|
|
const builtEntry = join(options.packageRoot, "dist", "loader.js");
|
|
|
|
const sourceCliEntry =
|
|
checkExists(sourceEntry) && checkExists(resolveTsLoader)
|
|
? ({
|
|
command: execPath,
|
|
args: [
|
|
"--import",
|
|
pathToFileURL(resolveTsLoader).href,
|
|
resolveTypeStrippingFlag(options.packageRoot),
|
|
sourceEntry,
|
|
...extraArgs,
|
|
...messageArgs,
|
|
],
|
|
cwd: options.cwd,
|
|
} satisfies SfCliEntry)
|
|
: null;
|
|
|
|
const builtCliEntry = checkExists(builtEntry)
|
|
? ({
|
|
command: execPath,
|
|
args: [builtEntry, ...extraArgs, ...messageArgs],
|
|
cwd: options.cwd,
|
|
} satisfies SfCliEntry)
|
|
: null;
|
|
|
|
if (options.hostKind === "packaged-standalone") {
|
|
if (builtCliEntry) return builtCliEntry;
|
|
if (sourceCliEntry) return sourceCliEntry;
|
|
} else {
|
|
if (sourceCliEntry) return sourceCliEntry;
|
|
if (builtCliEntry) return builtCliEntry;
|
|
}
|
|
|
|
throw new Error(
|
|
`SF CLI entry not found; checked=${sourceEntry},${builtEntry}`,
|
|
);
|
|
}
|
|
|