import { Command } from "effect/unstable/cli"; import type { Config } from "./config.js"; import { VERSION } from "./constants.js"; import { flags, specsArgument } from "./flags.js"; import { run } from "./run.js"; /** * What the tool is for, in one line, at the top of `--help`. * * The same sentence as the README's opening, because both answer the same * question and two versions of it would drift. * "Complete dependency closure" is the load-bearing part: the thing that * distinguishes this from `npm pack` is that it follows the graph. */ const DESCRIPTION = "Bundle npm packages and their complete dependency closure into tarballs you can carry " + "across an air gap and import into a registry on a restricted network."; /** The root command. */ export const bundleCommand = Command.make("packall", { specs: specsArgument, ...flags }, (parsed) => run(toConfig(parsed)), ).pipe(Command.withDescription(DESCRIPTION)); /** The runnable CLI. */ export const cli = Command.run(bundleCommand, { version: VERSION }); /** * Narrows the parsed arguments into `Config`. * * `Argument.variadic` widens its element type to `unknown`, so the positional * specs are narrowed here rather than asserted: `Argument.string` only ever * produces strings, and a guard that is a no-op at runtime is still cheaper * than a cast that stops the compiler checking the other thirty fields. */ const toConfig = ( parsed: Omit & { readonly specs: ReadonlyArray }, ): Config => ({ ...parsed, specs: parsed.specs.flatMap((spec) => (typeof spec === "string" ? spec : [])), });