src/lib/prompt-for-options.ts 3.5 K raw
1
import { consola } from "consola";
2
import pc from "picocolors";
3
import type { ProjectOptions } from "@/types";
4
import { TEMPLATES } from "@/utils/templates";
5
import { tryCatch } from "@/utils/try-catch";
6
7
export async function promptForOptions(
8
	options: ProjectOptions,
9
): Promise<ProjectOptions> {
10
	let projectName = options.projectName;
11
12
	if (!projectName && !options.yes) {
13
		const { data, error } = await tryCatch(
14
			consola.prompt(pc.yellow("What is the name of your project?"), {
15
				type: "text",
16
				default: "my-bhvr-app",
17
				placeholder: "my-bhvr-app",
18
				cancel: "reject",
19
			}),
20
		);
21
22
		if (!data || error) {
23
			consola.error(pc.red("Project creation cancelled."));
24
			process.exit(1);
25
		}
26
27
		projectName = data;
28
	}
29
30
	let templateChoice = options.template || "default";
31
32
	if (!options.yes && !options.branch) {
33
		const templateChoices = Object.keys(TEMPLATES).map((key) => ({
34
			label: `${key} (${TEMPLATES[key]?.description})`,
35
			value: key,
36
		}));
37
38
		const { data, error } = await tryCatch(
39
			consola.prompt(pc.yellow("Select a template:"), {
40
				type: "select",
41
				options: templateChoices,
42
				initial: "default",
43
				cancel: "reject",
44
			}),
45
		);
46
47
		if (!data || error) {
48
			consola.error("Project creation cancelled.");
49
			process.exit(1);
50
		}
51
52
		templateChoice = data;
53
	}
54
55
	let useRpc = options.rpc;
56
57
	if (!options.yes && !options.rpc) {
58
		const { data: rpcResponse, error } = await tryCatch(
59
			consola.prompt("Use Hono RPC client for type-safe API communication?", {
60
				type: "confirm",
61
				initial: false,
62
			}),
63
		);
64
65
		if (error) {
66
			consola.error("Project creation cancelled.");
67
			process.exit(1);
68
		}
69
70
		useRpc = rpcResponse;
71
	}
72
73
	let linter = options.linter;
74
75
	if (!options.yes && !options.linter) {
76
		const { data: linterResponse, error } = await tryCatch(
77
			consola.prompt("Select a linter:", {
78
				type: "select",
79
				options: [
80
					{ label: "ESLint (default)", value: "eslint" },
81
					{ label: "Biome", value: "biome" },
82
				],
83
				initial: "eslint",
84
				cancel: "reject",
85
			}),
86
		);
87
88
		if (error) {
89
			console.log(pc.yellow("Project creation cancelled."));
90
			process.exit(1);
91
		}
92
93
		linter = linterResponse as "eslint" | "biome";
94
	}
95
96
	let router = options.router;
97
98
	if (!options.yes && !options.router) {
99
		const { data: routerResponse, error } = await tryCatch(
100
			consola.prompt("Select a client router:", {
101
				type: "select",
102
				options: [
103
					{ label: "None (default)", value: "none" },
104
					{ label: "React Router", value: "reactrouter" },
105
					{ label: "React Router MPA", value: "reactroutermpa" },
106
					{ label: "TanStack Router", value: "tanstackrouter" },
107
				],
108
				initial: "none",
109
				cancel: "reject",
110
			}),
111
		);
112
113
		if (error) {
114
			console.log(pc.yellow("Project creation cancelled."));
115
			process.exit(1);
116
		}
117
118
		router = routerResponse as
119
			| "none"
120
			| "reactrouter"
121
			| "reactroutermpa"
122
			| "tanstackrouter";
123
	}
124
125
	let useTanstackQuery = options.tanstackQuery;
126
127
	if (!options.yes && !options.tanstackQuery) {
128
		const { data: tanstackQueryResponse, error } = await tryCatch(
129
			consola.prompt(
130
				"Would you like to enable TanStack Query for data fetching and state management?",
131
				{
132
					type: "confirm",
133
					initial: false,
134
				},
135
			),
136
		);
137
138
		if (error) {
139
			consola.error("Project creation cancelled.");
140
			process.exit(1);
141
		}
142
143
		useTanstackQuery = tanstackQueryResponse;
144
	}
145
146
	return {
147
		...options,
148
		projectName,
149
		template: templateChoice,
150
		tailwind: templateChoice === "tailwind" || templateChoice === "shadcn",
151
		shadcn: templateChoice === "shadcn",
152
		rpc: useRpc,
153
		linter,
154
		router,
155
		tanstackQuery: useTanstackQuery,
156
	};
157
}