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
|
- **Authentication**: Optional auth setup with Better-Auth
|
||||||
- **Progressive Web App**: Add PWA support with service workers and installable apps
|
- **Progressive Web App**: Add PWA support with service workers and installable apps
|
||||||
- **Desktop Apps**: Build native desktop apps with Tauri integration
|
- **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
|
- **Code Quality**: Biome for linting and formatting
|
||||||
- **Git Hooks**: Husky with lint-staged for pre-commit checks
|
- **Git Hooks**: Husky with lint-staged for pre-commit checks
|
||||||
- **Examples**: Todo app with full CRUD functionality, AI Chat using AI SDK
|
- **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:
|
Options:
|
||||||
-V, --version Output the version number
|
-V, --version Output the version number
|
||||||
-y, --yes Use default configuration
|
-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)
|
--orm <type> ORM type (none, drizzle, prisma)
|
||||||
--auth Include authentication
|
--auth Include authentication
|
||||||
--no-auth Exclude authentication
|
--no-auth Exclude authentication
|
||||||
--frontend <types...> Frontend types (tanstack-router, react-router, tanstack-start, native, none)
|
--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)
|
--examples <types...> Examples to include (todo, ai)
|
||||||
--no-examples Skip all examples
|
--no-examples Skip all examples
|
||||||
--git Initialize git repository
|
--git Initialize git repository
|
||||||
@@ -95,3 +96,8 @@ Create a project with Turso database setup:
|
|||||||
```bash
|
```bash
|
||||||
npx create-better-t-stack my-app --db-setup turso
|
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,
|
ProjectPackageManager,
|
||||||
} from "../types";
|
} from "../types";
|
||||||
import { addPackageDependency } from "../utils/add-package-deps";
|
import { addPackageDependency } from "../utils/add-package-deps";
|
||||||
|
import { setupStarlight } from "./starlight-setup";
|
||||||
import { setupTauri } from "./tauri-setup";
|
import { setupTauri } from "./tauri-setup";
|
||||||
|
|
||||||
export async function setupAddons(
|
export async function setupAddons(
|
||||||
@@ -30,6 +31,9 @@ export async function setupAddons(
|
|||||||
if (addons.includes("husky")) {
|
if (addons.includes("husky")) {
|
||||||
await setupHusky(projectDir);
|
await setupHusky(projectDir);
|
||||||
}
|
}
|
||||||
|
if (addons.includes("starlight")) {
|
||||||
|
await setupStarlight(projectDir, packageManager);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getWebAppDir(
|
export function getWebAppDir(
|
||||||
|
|||||||
@@ -36,10 +36,9 @@ async function initMongoDBAtlas(
|
|||||||
stdio: "inherit",
|
stdio: "inherit",
|
||||||
});
|
});
|
||||||
|
|
||||||
log.info(pc.yellow("Please enter your connection string"));
|
|
||||||
|
|
||||||
const connectionString = await text({
|
const connectionString = await text({
|
||||||
message: "Paste your complete MongoDB connection string:",
|
message: "Paste your complete MongoDB connection string:",
|
||||||
|
placeholder: "mongodb://USERNAME:PASSWORD@HOST/DATABASE",
|
||||||
validate(value) {
|
validate(value) {
|
||||||
if (!value) return "Please enter a connection string";
|
if (!value) return "Please enter a connection string";
|
||||||
if (!value.startsWith("mongodb")) {
|
if (!value.startsWith("mongodb")) {
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ export function displayPostInstallInstructions(
|
|||||||
addons?.includes("pwa") && frontends?.includes("react-router")
|
addons?.includes("pwa") && frontends?.includes("react-router")
|
||||||
? getPwaInstructions()
|
? getPwaInstructions()
|
||||||
: "";
|
: "";
|
||||||
|
const starlightInstructions = addons?.includes("starlight")
|
||||||
|
? getStarlightInstructions(runCmd)
|
||||||
|
: "";
|
||||||
|
|
||||||
const hasTanstackRouter = frontends?.includes("tanstack-router");
|
const hasTanstackRouter = frontends?.includes("tanstack-router");
|
||||||
const hasTanstackStart = frontends?.includes("tanstack-start");
|
const hasTanstackStart = frontends?.includes("tanstack-start");
|
||||||
@@ -64,7 +67,7 @@ ${
|
|||||||
? `${hasWebFrontend ? `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n` : ""}`
|
? `${hasWebFrontend ? `${pc.cyan("•")} Frontend: http://localhost:${webPort}\n` : ""}`
|
||||||
: `${pc.yellow("NOTE:")} You are creating a backend-only app (no frontend selected)\n`
|
: `${pc.yellow("NOTE:")} You are creating a backend-only app (no frontend selected)\n`
|
||||||
}${pc.cyan("•")} API: http://localhost:3000
|
}${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:
|
\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")}`,
|
${pc.cyan("https://github.com/AmanVarshney01/create-better-t-stack")}`,
|
||||||
"Next steps",
|
"Next steps",
|
||||||
@@ -120,3 +123,7 @@ function getTauriInstructions(runCmd?: string): string {
|
|||||||
function getPwaInstructions(): 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`;
|
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 { getLatestCLIVersion } from "./utils/get-latest-cli-version";
|
||||||
import { renderTitle } from "./utils/render-title";
|
import { renderTitle } from "./utils/render-title";
|
||||||
|
|
||||||
process.on("SIGINT", () => {
|
const exit = () => process.exit(0);
|
||||||
log.error(pc.red("Operation cancelled"));
|
process.on("SIGINT", exit);
|
||||||
process.exit(0);
|
process.on("SIGTERM", exit);
|
||||||
});
|
|
||||||
|
|
||||||
const program = new Command();
|
const program = new Command();
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ async function main() {
|
|||||||
)
|
)
|
||||||
.option(
|
.option(
|
||||||
"--addons <types...>",
|
"--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("--examples <types...>", "Examples to include (todo, ai)")
|
||||||
.option("--no-examples", "Skip all examples")
|
.option("--no-examples", "Skip all examples")
|
||||||
@@ -354,7 +353,7 @@ function processAndValidateFlags(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (options.addons && options.addons.length > 0) {
|
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(
|
const invalidAddons = options.addons.filter(
|
||||||
(addon: string) => !validAddons.includes(addon),
|
(addon: string) => !validAddons.includes(addon),
|
||||||
);
|
);
|
||||||
@@ -380,7 +379,8 @@ function processAndValidateFlags(
|
|||||||
addon === "pwa" ||
|
addon === "pwa" ||
|
||||||
addon === "tauri" ||
|
addon === "tauri" ||
|
||||||
addon === "biome" ||
|
addon === "biome" ||
|
||||||
addon === "husky",
|
addon === "husky" ||
|
||||||
|
addon === "starlight",
|
||||||
);
|
);
|
||||||
|
|
||||||
const webSpecificAddons = ["pwa", "tauri"];
|
const webSpecificAddons = ["pwa", "tauri"];
|
||||||
|
|||||||
@@ -14,6 +14,11 @@ export async function getAddonsChoice(
|
|||||||
frontends?.includes("tanstack-router");
|
frontends?.includes("tanstack-router");
|
||||||
|
|
||||||
const addonOptions = [
|
const addonOptions = [
|
||||||
|
{
|
||||||
|
value: "starlight" as const,
|
||||||
|
label: "Starlight",
|
||||||
|
hint: "Add Astro Starlight documentation site",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: "biome" as const,
|
value: "biome" as const,
|
||||||
label: "Biome",
|
label: "Biome",
|
||||||
|
|||||||
@@ -62,12 +62,6 @@ export async function gatherConfig(
|
|||||||
results.database !== "none",
|
results.database !== "none",
|
||||||
results.frontend,
|
results.frontend,
|
||||||
),
|
),
|
||||||
dbSetup: ({ results }) =>
|
|
||||||
getDBSetupChoice(
|
|
||||||
results.database ?? "none",
|
|
||||||
flags.dbSetup,
|
|
||||||
results.orm,
|
|
||||||
),
|
|
||||||
addons: ({ results }) => getAddonsChoice(flags.addons, results.frontend),
|
addons: ({ results }) => getAddonsChoice(flags.addons, results.frontend),
|
||||||
examples: ({ results }) =>
|
examples: ({ results }) =>
|
||||||
getExamplesChoice(
|
getExamplesChoice(
|
||||||
@@ -76,6 +70,12 @@ export async function gatherConfig(
|
|||||||
results.frontend,
|
results.frontend,
|
||||||
results.backend,
|
results.backend,
|
||||||
),
|
),
|
||||||
|
dbSetup: ({ results }) =>
|
||||||
|
getDBSetupChoice(
|
||||||
|
results.database ?? "none",
|
||||||
|
flags.dbSetup,
|
||||||
|
results.orm,
|
||||||
|
),
|
||||||
git: () => getGitChoice(flags.git),
|
git: () => getGitChoice(flags.git),
|
||||||
packageManager: () => getPackageManagerChoice(flags.packageManager),
|
packageManager: () => getPackageManagerChoice(flags.packageManager),
|
||||||
noInstall: () => getNoInstallChoice(flags.noInstall),
|
noInstall: () => getNoInstallChoice(flags.noInstall),
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export type ProjectDatabase =
|
|||||||
| "none";
|
| "none";
|
||||||
export type ProjectOrm = "drizzle" | "prisma" | "none";
|
export type ProjectOrm = "drizzle" | "prisma" | "none";
|
||||||
export type ProjectPackageManager = "npm" | "pnpm" | "bun";
|
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 ProjectBackend = "hono" | "elysia" | "express";
|
||||||
export type ProjectRuntime = "node" | "bun";
|
export type ProjectRuntime = "node" | "bun";
|
||||||
export type ProjectExamples = "todo" | "ai";
|
export type ProjectExamples = "todo" | "ai";
|
||||||
|
|||||||
@@ -233,6 +233,14 @@ export const TECH_OPTIONS = {
|
|||||||
color: "from-amber-500 to-amber-700",
|
color: "from-amber-500 to-amber-700",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "starlight",
|
||||||
|
name: "Starlight",
|
||||||
|
description: "Documentation site with Astro",
|
||||||
|
icon: "📚",
|
||||||
|
color: "from-teal-500 to-teal-700",
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "biome",
|
id: "biome",
|
||||||
name: "Biome",
|
name: "Biome",
|
||||||
@@ -379,7 +387,7 @@ export const PRESET_TEMPLATES = [
|
|||||||
dbSetup: "turso",
|
dbSetup: "turso",
|
||||||
auth: "true",
|
auth: "true",
|
||||||
packageManager: "bun",
|
packageManager: "bun",
|
||||||
addons: ["pwa", "biome", "husky", "tauri"],
|
addons: ["pwa", "biome", "husky", "tauri", "starlight"],
|
||||||
examples: ["todo", "ai"],
|
examples: ["todo", "ai"],
|
||||||
git: "true",
|
git: "true",
|
||||||
install: "true",
|
install: "true",
|
||||||
|
|||||||
Reference in New Issue
Block a user