src/installers/tanstack-router.ts 3.0 K raw
1
import path from "node:path";
2
import fs from "fs-extra";
3
import type { ProjectOptions } from "@/types";
4
import yoctoSpinner from "yocto-spinner";
5
import pc from "picocolors";
6
import { consola } from "consola";
7
import { addPackageDependency } from "@/utils/add-package-dependency";
8
import { EXTRAS_DIR } from "@/utils";
9
import { nameGenerator } from "@/utils/name-generator";
10
import { execa } from "execa";
11
12
export const tanstackRouterInstaller = async (
13
	options: Required<ProjectOptions>,
14
): Promise<boolean> => {
15
	const spinner = yoctoSpinner({
16
		text: "Setting up TanStack Router...",
17
	}).start();
18
19
	try {
20
		const { projectName, rpc, shadcn, tailwind, tanstackQuery } = options;
21
22
		const projectPath = path.resolve(process.cwd(), projectName);
23
		spinner.text = "Installing TanStack Router...";
24
		await addPackageDependency({
25
			dependencies: [
26
				"@tanstack/react-router",
27
				"@tanstack/react-router-devtools",
28
			],
29
			target: "client",
30
			projectName,
31
		});
32
33
		await addPackageDependency({
34
			dependencies: ["@tanstack/router-plugin"],
35
			devMode: true,
36
			target: "client",
37
			projectName,
38
		});
39
40
		const viteConfigTemplate = nameGenerator("vite.config.ts", {
41
			tailwind,
42
			shadcn,
43
			tanstackRouter: true,
44
		});
45
		const viteConfigSrc = path.join(
46
			EXTRAS_DIR,
47
			"client",
48
			"vite.config.ts",
49
			viteConfigTemplate,
50
		);
51
		const viteConfigTarget = path.join(projectPath, "client", "vite.config.ts");
52
		fs.copySync(viteConfigSrc, viteConfigTarget);
53
54
		const rootTsxSrc = path.join(
55
			EXTRAS_DIR,
56
			"client",
57
			"src",
58
			"routes",
59
			"__root.tsx",
60
		);
61
		const rootTsxTarget = path.join(
62
			projectPath,
63
			"client",
64
			"src",
65
			"routes",
66
			"__root.tsx",
67
		);
68
		fs.copySync(rootTsxSrc, rootTsxTarget);
69
70
		const indexTsxSrc = path.join(
71
			EXTRAS_DIR,
72
			"client",
73
			"src",
74
			"routes",
75
			"index.tsx",
76
			nameGenerator("index.tsx", { tanstackQuery, tailwind, shadcn, rpc }),
77
		);
78
		const indexTsxTarget = path.join(
79
			projectPath,
80
			"client",
81
			"src",
82
			"routes",
83
			"index.tsx",
84
		);
85
		fs.copySync(indexTsxSrc, indexTsxTarget);
86
87
		const mainTsxSrc = path.join(
88
			EXTRAS_DIR,
89
			"client",
90
			"src",
91
			"main.tsx",
92
			nameGenerator("main.tsx", { tanstackQuery, tanstackRouter: true }),
93
		);
94
		const mainTsxTarget = path.join(projectPath, "client", "src", "main.tsx");
95
		fs.copySync(mainTsxSrc, mainTsxTarget);
96
97
		const appTsxTarget = path.join(projectPath, "client", "src", "App.tsx");
98
		fs.remove(appTsxTarget);
99
100
		spinner.text = "Generating TanStack Route Tree...";
101
102
		// await execa("vite", ["--config", "vite.config.ts", "--force"], {
103
		// 	cwd: path.join(projectPath, "client"),
104
		// });
105
		//
106
		await execa("bunx", ["vite", "build"], {
107
			cwd: path.join(projectPath, "client"),
108
		});
109
110
		await execa("bunx", ["tsc", "-b"], {
111
			cwd: path.join(projectPath, "client"),
112
		});
113
114
		spinner.success("TanStack Router setup completed");
115
		return true;
116
	} catch (err: unknown) {
117
		spinner.error("Failed to set up TanStack Router");
118
		if (err instanceof Error) {
119
			consola.error(pc.red("Error:"), err.message);
120
		} else {
121
			consola.error(pc.red("Error: Unknown error"));
122
		}
123
		return false;
124
	}
125
};