nestia
Version:
Nestia CLI tool
124 lines (116 loc) • 3.67 kB
text/typescript
import commander from "commander";
import fs from "fs";
import inquirer from "inquirer";
import { DetectResult, detect } from "package-manager-detector";
import { PackageManager } from "./PackageManager";
export namespace ArgumentParser {
export interface IArguments {
manager: "npm" | "pnpm" | "yarn" | "bun";
project: string | null;
runtime: boolean;
}
export async function parse(pack: PackageManager): Promise<IArguments> {
// PREPARE ASSETS
commander.program.option("--manager [manager]", "package manager");
commander.program.option(
"--project [project]",
"tsconfig.json file location",
);
commander.program.option(
"--runtime [boolean]",
"transform runtime swagger",
);
// INTERNAL PROCEDURES
const questioned = { value: false };
const action = (
closure: (options: Partial<IArguments>) => Promise<IArguments>,
) => {
return new Promise<IArguments>((resolve, reject) => {
commander.program.action(async (options) => {
try {
resolve(await closure(options));
} catch (exp) {
reject(exp);
}
});
commander.program.parseAsync().catch(reject);
});
};
const select =
(name: string) =>
(message: string) =>
async <Choice extends string>(
choices: Choice[],
filter?: (value: string) => Choice,
): Promise<Choice> => {
questioned.value = true;
return (
await inquirer.createPromptModule()({
type: "list",
name: name,
message: message,
choices: choices,
filter,
})
)[name];
};
const configure = async () => {
const fileList: string[] = await (
await fs.promises.readdir(process.cwd())
)
.filter(
(str) =>
str.substring(0, 8) === "tsconfig" &&
str.substring(str.length - 5) === ".json",
)
.sort((x, y) =>
x === "tsconfig.json"
? -1
: y === "tsconfig.json"
? 1
: x < y
? -1
: 1,
);
if (fileList.length === 0) {
if (process.cwd() !== pack.directory)
throw new Error(`Unable to find "tsconfig.json" file.`);
return null;
} else if (fileList.length === 1) return fileList[0];
return select("tsconfig")("TS Config File")(fileList);
};
// DO CONSTRUCT
return action(async (options) => {
options.manager ??=
(await detectManager()) ??
(await select("manager")("Package Manager")(
[
"npm" as const,
"pnpm" as const,
"yarn (berry is not supported)" as "yarn",
"bun" as const,
],
(value) => value.split(" ")[0] as "yarn",
));
pack.manager = options.manager;
options.project ??= await configure();
options.runtime =
((options.runtime as string | undefined) ??
(await select("runtime")("Transform Runtime Swagger")([
"true",
"false",
]))) !== "false";
if (questioned.value) console.log("");
return options as IArguments;
});
}
const detectManager = async (): Promise<
"npm" | "pnpm" | "yarn" | "bun" | null
> => {
const result: DetectResult | null = await detect({ cwd: process.cwd() });
if (result?.name === "npm")
return null; // NPM case is still selectable
else if (result?.name === "deno") return null; // Deno case is not supported
return result?.name ?? null;
};
}