mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
feat(cli): add vibe rules addon (#481)
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { cancel, groupMultiselect, isCancel } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { groupMultiselect, isCancel } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import { type Addons, AddonsSchema, type Frontend } from "../types";
|
||||
import {
|
||||
getCompatibleAddons,
|
||||
validateAddonCompatibility,
|
||||
} from "../utils/addon-compatibility";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
type AddonOption = {
|
||||
value: Addons;
|
||||
@@ -42,6 +42,10 @@ function getAddonDisplay(addon: Addons): { label: string; hint: string } {
|
||||
label = "Ultracite";
|
||||
hint = "Zero-config Biome preset with AI integration";
|
||||
break;
|
||||
case "vibe-rules":
|
||||
label = "vibe-rules";
|
||||
hint = "Install and apply BTS rules to editors";
|
||||
break;
|
||||
case "husky":
|
||||
label = "Husky";
|
||||
hint = "Modern native Git hooks made easy";
|
||||
@@ -65,7 +69,7 @@ function getAddonDisplay(addon: Addons): { label: string; hint: string } {
|
||||
const ADDON_GROUPS = {
|
||||
Documentation: ["starlight", "fumadocs"],
|
||||
Linting: ["biome", "oxlint", "ultracite"],
|
||||
Other: ["turborepo", "pwa", "tauri", "husky"],
|
||||
Other: ["vibe-rules", "turborepo", "pwa", "tauri", "husky"],
|
||||
};
|
||||
|
||||
export async function getAddonsChoice(
|
||||
@@ -119,10 +123,7 @@ export async function getAddonsChoice(
|
||||
selectableGroups: false,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -175,10 +176,7 @@ export async function getAddonsToAdd(
|
||||
selectableGroups: false,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import type { API, Backend, Frontend } from "../types";
|
||||
import { allowedApisForFrontends } from "../utils/compatibility-rules";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getApiChoice(
|
||||
Api?: API | undefined,
|
||||
@@ -43,10 +43,7 @@ export async function getApiChoice(
|
||||
initialValue: apiOptions[0].value,
|
||||
});
|
||||
|
||||
if (isCancel(apiType)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(apiType)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return apiType;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, confirm, isCancel } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { confirm, isCancel } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getAuthChoice(
|
||||
auth: boolean | undefined,
|
||||
@@ -21,10 +21,7 @@ export async function getAuthChoice(
|
||||
initialValue: DEFAULT_CONFIG.auth,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Frontend } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getBackendFrameworkChoice(
|
||||
backendFramework?: Backend,
|
||||
@@ -63,10 +63,7 @@ export async function getBackendFrameworkChoice(
|
||||
initialValue: DEFAULT_CONFIG.backend,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { cancel, group } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { group } from "@clack/prompts";
|
||||
import type {
|
||||
Addons,
|
||||
API,
|
||||
@@ -14,6 +13,7 @@ import type {
|
||||
Runtime,
|
||||
WebDeploy,
|
||||
} from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
import { getAddonsChoice } from "./addons";
|
||||
import { getApiChoice } from "./api";
|
||||
import { getAuthChoice } from "./auth";
|
||||
@@ -102,10 +102,7 @@ export async function gatherConfig(
|
||||
install: () => getinstallChoice(flags.install),
|
||||
},
|
||||
{
|
||||
onCancel: () => {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
},
|
||||
onCancel: () => exitCancelled("Operation cancelled"),
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import type { Backend, DatabaseSetup, ORM, Runtime } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getDBSetupChoice(
|
||||
databaseType: string,
|
||||
@@ -101,10 +101,7 @@ export async function getDBSetupChoice(
|
||||
initialValue: "none",
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Database, Runtime } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getDatabaseChoice(
|
||||
database?: Database,
|
||||
@@ -55,10 +55,7 @@ export async function getDatabaseChoice(
|
||||
initialValue: DEFAULT_CONFIG.database,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { cancel, isCancel, multiselect } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, multiselect } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { API, Backend, Database, Examples, Frontend } from "../types";
|
||||
import {
|
||||
isExampleAIAllowed,
|
||||
isExampleTodoAllowed,
|
||||
} from "../utils/compatibility-rules";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getExamplesChoice(
|
||||
examples?: Examples[],
|
||||
@@ -63,10 +63,7 @@ export async function getExamplesChoice(
|
||||
),
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { cancel, isCancel, multiselect, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, multiselect, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Frontend } from "../types";
|
||||
import { isFrontendAllowedWithBackend } from "../utils/compatibility-rules";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getFrontendChoice(
|
||||
frontendOptions?: Frontend[],
|
||||
@@ -28,10 +28,7 @@ export async function getFrontendChoice(
|
||||
initialValues: ["web"],
|
||||
});
|
||||
|
||||
if (isCancel(frontendTypes)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(frontendTypes)) return exitCancelled("Operation cancelled");
|
||||
|
||||
const result: Frontend[] = [];
|
||||
|
||||
@@ -69,7 +66,7 @@ export async function getFrontendChoice(
|
||||
},
|
||||
{
|
||||
value: "tanstack-start" as const,
|
||||
label: "TanStack Start (vite)",
|
||||
label: "TanStack Start",
|
||||
hint: "SSR, Server Functions, API Routes and more with TanStack Router",
|
||||
},
|
||||
];
|
||||
@@ -84,10 +81,7 @@ export async function getFrontendChoice(
|
||||
initialValue: DEFAULT_CONFIG.frontend[0],
|
||||
});
|
||||
|
||||
if (isCancel(webFramework)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(webFramework)) return exitCancelled("Operation cancelled");
|
||||
|
||||
result.push(webFramework);
|
||||
}
|
||||
@@ -110,10 +104,7 @@ export async function getFrontendChoice(
|
||||
initialValue: "native-nativewind",
|
||||
});
|
||||
|
||||
if (isCancel(nativeFramework)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(nativeFramework)) return exitCancelled("Operation cancelled");
|
||||
result.push(nativeFramework);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cancel, confirm, isCancel } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { confirm, isCancel } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getGitChoice(git?: boolean) {
|
||||
if (git !== undefined) return git;
|
||||
@@ -10,10 +10,7 @@ export async function getGitChoice(git?: boolean) {
|
||||
initialValue: DEFAULT_CONFIG.git,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cancel, confirm, isCancel } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { confirm, isCancel } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getinstallChoice(install?: boolean) {
|
||||
if (install !== undefined) return install;
|
||||
@@ -10,10 +10,7 @@ export async function getinstallChoice(install?: boolean) {
|
||||
initialValue: DEFAULT_CONFIG.install,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Database, ORM, Runtime } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
const ormOptions = {
|
||||
prisma: {
|
||||
@@ -51,10 +51,7 @@ export async function getORMChoice(
|
||||
initialValue: database === "mongodb" ? "prisma" : DEFAULT_CONFIG.orm,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import type { PackageManager } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
import { getUserPkgManager } from "../utils/get-package-manager";
|
||||
|
||||
export async function getPackageManagerChoice(
|
||||
@@ -28,10 +28,7 @@ export async function getPackageManagerChoice(
|
||||
initialValue: detectedPackageManager,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import path from "node:path";
|
||||
import { cancel, isCancel, text } from "@clack/prompts";
|
||||
import { isCancel, text } from "@clack/prompts";
|
||||
import consola from "consola";
|
||||
import fs from "fs-extra";
|
||||
import pc from "picocolors";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import { ProjectNameSchema } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
function isPathWithinCwd(targetPath: string): boolean {
|
||||
const resolved = path.resolve(targetPath);
|
||||
@@ -76,10 +77,7 @@ export async function getProjectName(initialName?: string): Promise<string> {
|
||||
},
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled."));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled.");
|
||||
|
||||
projectPath = response || defaultName;
|
||||
isValid = true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Runtime } from "../types";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
export async function getRuntimeChoice(
|
||||
runtime?: Runtime,
|
||||
@@ -48,10 +48,7 @@ export async function getRuntimeChoice(
|
||||
initialValue: DEFAULT_CONFIG.runtime,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { cancel, isCancel, select } from "@clack/prompts";
|
||||
import pc from "picocolors";
|
||||
import { isCancel, select } from "@clack/prompts";
|
||||
import { DEFAULT_CONFIG } from "../constants";
|
||||
import type { Backend, Frontend, Runtime, WebDeploy } from "../types";
|
||||
import { WEB_FRAMEWORKS } from "../utils/compatibility";
|
||||
import { exitCancelled } from "../utils/errors";
|
||||
|
||||
function hasWebFrontend(frontends: Frontend[]): boolean {
|
||||
return frontends.some((f) => WEB_FRAMEWORKS.includes(f));
|
||||
@@ -56,10 +56,7 @@ export async function getDeploymentChoice(
|
||||
initialValue: DEFAULT_CONFIG.webDeploy,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
@@ -105,10 +102,7 @@ export async function getDeploymentToAdd(
|
||||
initialValue: DEFAULT_CONFIG.webDeploy,
|
||||
});
|
||||
|
||||
if (isCancel(response)) {
|
||||
cancel(pc.red("Operation cancelled"));
|
||||
process.exit(0);
|
||||
}
|
||||
if (isCancel(response)) return exitCancelled("Operation cancelled");
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user