mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
add starlight docs addon
This commit is contained in:
5
.changeset/slimy-ideas-do.md
Normal file
5
.changeset/slimy-ideas-do.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"create-better-t-stack": minor
|
||||
---
|
||||
|
||||
add starlight docs addon
|
||||
@@ -32,6 +32,7 @@ Follow the prompts to configure your project or use the `--yes` flag for default
|
||||
- **Authentication**: Optional auth setup with Better-Auth
|
||||
- **Progressive Web App**: Add PWA support with service workers and installable apps
|
||||
- **Desktop Apps**: Build native desktop apps with Tauri integration
|
||||
- **Documentation**: Add an Astro Starlight documentation site to your project
|
||||
- **Code Quality**: Biome for linting and formatting
|
||||
- **Git Hooks**: Husky with lint-staged for pre-commit checks
|
||||
- **Examples**: Todo app with full CRUD functionality, AI Chat using AI SDK
|
||||
@@ -45,12 +46,12 @@ Usage: create-better-t-stack [project-directory] [options]
|
||||
Options:
|
||||
-V, --version Output the version number
|
||||
-y, --yes Use default configuration
|
||||
--database <type> Database type (none, sqlite, postgres, mongodb)
|
||||
--database <type> Database type (none, sqlite, postgres, mysql, mongodb)
|
||||
--orm <type> ORM type (none, drizzle, prisma)
|
||||
--auth Include authentication
|
||||
--no-auth Exclude authentication
|
||||
--frontend <types...> Frontend types (tanstack-router, react-router, tanstack-start, native, none)
|
||||
--addons <types...> Additional addons (pwa, tauri, biome, husky, none)
|
||||
--addons <types...> Additional addons (pwa, tauri, starlight, biome, husky, none)
|
||||
--examples <types...> Examples to include (todo, ai)
|
||||
--no-examples Skip all examples
|
||||
--git Initialize git repository
|
||||
@@ -95,3 +96,8 @@ Create a project with Turso database setup:
|
||||
```bash
|
||||
npx create-better-t-stack my-app --db-setup turso
|
||||
```
|
||||
|
||||
Create a project with documentation site:
|
||||
```bash
|
||||
npx create-better-t-stack my-app --addons starlight
|
||||
```
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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")) {
|
||||
|
||||
@@ -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`;
|
||||
}
|
||||
|
||||
64
apps/cli/src/helpers/starlight-setup.ts
Normal file
64
apps/cli/src/helpers/starlight-setup.ts
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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"];
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -233,6 +233,14 @@ export const TECH_OPTIONS = {
|
||||
color: "from-amber-500 to-amber-700",
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
id: "starlight",
|
||||
name: "Starlight",
|
||||
description: "Documentation site with Astro",
|
||||
icon: "📚",
|
||||
color: "from-teal-500 to-teal-700",
|
||||
default: false,
|
||||
},
|
||||
{
|
||||
id: "biome",
|
||||
name: "Biome",
|
||||
@@ -379,7 +387,7 @@ export const PRESET_TEMPLATES = [
|
||||
dbSetup: "turso",
|
||||
auth: "true",
|
||||
packageManager: "bun",
|
||||
addons: ["pwa", "biome", "husky", "tauri"],
|
||||
addons: ["pwa", "biome", "husky", "tauri", "starlight"],
|
||||
examples: ["todo", "ai"],
|
||||
git: "true",
|
||||
install: "true",
|
||||
|
||||
Reference in New Issue
Block a user