add starlight docs addon

This commit is contained in:
Aman Varshney
2025-04-10 20:35:15 +05:30
parent 6847603b5c
commit aac6a7d267
11 changed files with 118 additions and 20 deletions

View File

@@ -7,6 +7,7 @@ import type {
ProjectPackageManager,
} from "../types";
import { addPackageDependency } from "../utils/add-package-deps";
import { setupStarlight } from "./starlight-setup";
import { setupTauri } from "./tauri-setup";
export async function setupAddons(
@@ -30,6 +31,9 @@ export async function setupAddons(
if (addons.includes("husky")) {
await setupHusky(projectDir);
}
if (addons.includes("starlight")) {
await setupStarlight(projectDir, packageManager);
}
}
export function getWebAppDir(

View File

@@ -36,10 +36,9 @@ async function initMongoDBAtlas(
stdio: "inherit",
});
log.info(pc.yellow("Please enter your connection string"));
const connectionString = await text({
message: "Paste your complete MongoDB connection string:",
placeholder: "mongodb://USERNAME:PASSWORD@HOST/DATABASE",
validate(value) {
if (!value) return "Please enter a connection string";
if (!value.startsWith("mongodb")) {

View File

@@ -43,6 +43,9 @@ export function displayPostInstallInstructions(
addons?.includes("pwa") && frontends?.includes("react-router")
? getPwaInstructions()
: "";
const starlightInstructions = addons?.includes("starlight")
? getStarlightInstructions(runCmd)
: "";
const hasTanstackRouter = frontends?.includes("tanstack-router");
const hasTanstackStart = frontends?.includes("tanstack-start");
@@ -64,7 +67,7 @@ ${
? `${hasWebFrontend ? `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n` : ""}`
: `${pc.yellow("NOTE:")} You are creating a backend-only app (no frontend selected)\n`
}${pc.cyan("•")} API: http://localhost:3000
${nativeInstructions ? `\n${nativeInstructions.trim()}` : ""}${databaseInstructions ? `\n${databaseInstructions.trim()}` : ""}${tauriInstructions ? `\n${tauriInstructions.trim()}` : ""}${lintingInstructions ? `\n${lintingInstructions.trim()}` : ""}${pwaInstructions ? `\n${pwaInstructions.trim()}` : ""}
${addons?.includes("starlight") ? `${pc.cyan("•")} Docs: http://localhost:4321\n` : ""}${nativeInstructions ? `\n${nativeInstructions.trim()}` : ""}${databaseInstructions ? `\n${databaseInstructions.trim()}` : ""}${tauriInstructions ? `\n${tauriInstructions.trim()}` : ""}${lintingInstructions ? `\n${lintingInstructions.trim()}` : ""}${pwaInstructions ? `\n${pwaInstructions.trim()}` : ""}${starlightInstructions ? `\n${starlightInstructions.trim()}` : ""}
\n${pc.bold("Like Better-T Stack?")} Please consider giving us a star on GitHub:
${pc.cyan("https://github.com/AmanVarshney01/create-better-t-stack")}`,
"Next steps",
@@ -120,3 +123,7 @@ function getTauriInstructions(runCmd?: string): string {
function getPwaInstructions(): string {
return `${pc.bold("PWA with React Router v7:")}\n${pc.yellow("NOTE:")} There is a known compatibility issue between VitePWA and React Router v7.\nSee: https://github.com/vite-pwa/vite-plugin-pwa/issues/809\n`;
}
function getStarlightInstructions(runCmd?: string): string {
return `${pc.bold("Documentation with Starlight:")}\n${pc.cyan("•")} Start docs site: ${`cd apps/docs && ${runCmd} dev`}\n${pc.cyan("•")} Build docs site: ${`cd apps/docs && ${runCmd} build`}\n`;
}

View File

@@ -0,0 +1,64 @@
import path from "node:path";
import { log, spinner } from "@clack/prompts";
import { execa } from "execa";
import pc from "picocolors";
import type { ProjectPackageManager } from "../types";
export async function setupStarlight(
projectDir: string,
packageManager: ProjectPackageManager,
): Promise<void> {
const s = spinner();
try {
s.start("Setting up Starlight documentation site...");
let cmd: string;
let args: string[];
switch (packageManager) {
case "npm":
cmd = "npx";
args = ["create-astro@latest"];
break;
case "pnpm":
cmd = "pnpm";
args = ["dlx", "create-astro@latest"];
break;
case "bun":
cmd = "bunx";
args = ["create-astro@latest"];
break;
default:
cmd = "npx";
args = ["create-astro@latest"];
}
args = [
...args,
"docs",
"--template",
"starlight",
"--no-install",
"--add",
"tailwind",
"--no-git",
"--skip-houston",
];
await execa(cmd, args, {
cwd: path.join(projectDir, "apps"),
env: {
CI: "true",
},
});
s.stop("Starlight documentation site setup successfully!");
} catch (error) {
s.stop(pc.red("Failed to set up Starlight documentation site"));
if (error instanceof Error) {
log.error(pc.red(error.message));
}
throw error;
}
}

View File

@@ -22,10 +22,9 @@ import { generateReproducibleCommand } from "./utils/generate-reproducible-comma
import { getLatestCLIVersion } from "./utils/get-latest-cli-version";
import { renderTitle } from "./utils/render-title";
process.on("SIGINT", () => {
log.error(pc.red("Operation cancelled"));
process.exit(0);
});
const exit = () => process.exit(0);
process.on("SIGINT", exit);
process.on("SIGTERM", exit);
const program = new Command();
@@ -51,7 +50,7 @@ async function main() {
)
.option(
"--addons <types...>",
"Additional addons (pwa, tauri, biome, husky, none)",
"Additional addons (pwa, tauri, starlight, biome, husky, none)",
)
.option("--examples <types...>", "Examples to include (todo, ai)")
.option("--no-examples", "Skip all examples")
@@ -354,7 +353,7 @@ function processAndValidateFlags(
}
if (options.addons && options.addons.length > 0) {
const validAddons = ["pwa", "tauri", "biome", "husky", "none"];
const validAddons = ["pwa", "tauri", "biome", "husky", "starlight", "none"];
const invalidAddons = options.addons.filter(
(addon: string) => !validAddons.includes(addon),
);
@@ -380,7 +379,8 @@ function processAndValidateFlags(
addon === "pwa" ||
addon === "tauri" ||
addon === "biome" ||
addon === "husky",
addon === "husky" ||
addon === "starlight",
);
const webSpecificAddons = ["pwa", "tauri"];

View File

@@ -14,6 +14,11 @@ export async function getAddonsChoice(
frontends?.includes("tanstack-router");
const addonOptions = [
{
value: "starlight" as const,
label: "Starlight",
hint: "Add Astro Starlight documentation site",
},
{
value: "biome" as const,
label: "Biome",

View File

@@ -62,12 +62,6 @@ export async function gatherConfig(
results.database !== "none",
results.frontend,
),
dbSetup: ({ results }) =>
getDBSetupChoice(
results.database ?? "none",
flags.dbSetup,
results.orm,
),
addons: ({ results }) => getAddonsChoice(flags.addons, results.frontend),
examples: ({ results }) =>
getExamplesChoice(
@@ -76,6 +70,12 @@ export async function gatherConfig(
results.frontend,
results.backend,
),
dbSetup: ({ results }) =>
getDBSetupChoice(
results.database ?? "none",
flags.dbSetup,
results.orm,
),
git: () => getGitChoice(flags.git),
packageManager: () => getPackageManagerChoice(flags.packageManager),
noInstall: () => getNoInstallChoice(flags.noInstall),

View File

@@ -6,7 +6,7 @@ export type ProjectDatabase =
| "none";
export type ProjectOrm = "drizzle" | "prisma" | "none";
export type ProjectPackageManager = "npm" | "pnpm" | "bun";
export type ProjectAddons = "pwa" | "biome" | "tauri" | "husky";
export type ProjectAddons = "pwa" | "biome" | "tauri" | "husky" | "starlight";
export type ProjectBackend = "hono" | "elysia" | "express";
export type ProjectRuntime = "node" | "bun";
export type ProjectExamples = "todo" | "ai";