@reliverse/rse-sdk
Version:
@reliverse/rse-sdk allows you to create new plugins for @reliverse/rse CLI, interact with reliverse.org, and even extend your own CLI functionality (you may also try @reliverse/dler-sdk for this case).
241 lines (240 loc) • 8 kB
JavaScript
import { re } from "@reliverse/relico";
import { relinka } from "@reliverse/relinka";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command.js";
export function displayPostInstallInstructions(config) {
const {
database,
relativePath,
packageManager,
depsInstalled,
orm,
addons,
runtime,
frontend,
backend
} = config;
const isConvex = backend === "convex";
const runCmd = packageManager === "npm" ? "npm run" : packageManager;
const cdCmd = `cd ${relativePath}`;
const hasHuskyOrBiome = addons?.includes("husky") || addons?.includes("biome");
const databaseInstructions = !isConvex && database !== "none" ? getDatabaseInstructions(database, orm, runCmd, runtime) : "";
const tauriInstructions = addons?.includes("tauri") ? getTauriInstructions(runCmd) : "";
const lintingInstructions = hasHuskyOrBiome ? getLintingInstructions(runCmd) : "";
const nativeInstructions = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles") ? getNativeInstructions(isConvex) : "";
const pwaInstructions = addons?.includes("pwa") && (frontend?.includes("react-router") || frontend?.includes("tanstack-router")) ? getPwaInstructions() : "";
const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
const hasWeb = frontend?.some(
(f) => [
"tanstack-router",
"react-router",
"next",
"tanstack-start",
"nuxt",
"svelte",
"solid"
].includes(f)
);
const hasNative = frontend?.includes("native-nativewind") || frontend?.includes("native-unistyles");
const bunWebNativeWarning = packageManager === "bun" && hasNative && hasWeb ? getBunWebNativeWarning() : "";
const noOrmWarning = !isConvex && database !== "none" && orm === "none" ? getNoOrmWarning() : "";
const hasReactRouter = frontend?.includes("react-router");
const hasSvelte = frontend?.includes("svelte");
const webPort = hasReactRouter || hasSvelte ? "5173" : "3001";
const tazeCommand = getPackageExecutionCommand(packageManager, "taze -r");
let output = `${re.bold("Next steps")}
${re.cyan("1.")} ${cdCmd}
`;
let stepCounter = 2;
if (!depsInstalled) {
output += `${re.cyan(`${stepCounter++}.`)} ${packageManager} install
`;
}
if (isConvex) {
output += `${re.cyan(`${stepCounter++}.`)} ${runCmd} dev:setup ${re.dim(
"(this will guide you through Convex project setup)"
)}
`;
output += `${re.cyan(`${stepCounter++}.`)} ${runCmd} dev
`;
} else {
if (runtime !== "workers") {
output += `${re.cyan(`${stepCounter++}.`)} ${runCmd} dev
`;
}
if (runtime === "workers") {
output += `${re.cyan(`${stepCounter++}.`)} bun dev
`;
output += `${re.cyan(
`${stepCounter++}.`
)} cd apps/server && bun run cf-typegen
`;
} else {
output += "\n";
}
}
output += `${re.bold("Your project will be available at:")}
`;
if (hasWeb) {
output += `${re.cyan("\u2022")} Frontend: http://localhost:${webPort}
`;
} else if (!hasNative && !addons?.includes("starlight")) {
output += `${re.yellow(
"NOTE:"
)} You are creating a backend-only app (no frontend selected)
`;
}
if (!isConvex) {
output += `${re.cyan("\u2022")} Backend API: http://localhost:3000
`;
}
if (addons?.includes("starlight")) {
output += `${re.cyan("\u2022")} Docs: http://localhost:4321
`;
}
if (nativeInstructions) output += `
${nativeInstructions.trim()}
`;
if (databaseInstructions) output += `
${databaseInstructions.trim()}
`;
if (tauriInstructions) output += `
${tauriInstructions.trim()}
`;
if (lintingInstructions) output += `
${lintingInstructions.trim()}
`;
if (pwaInstructions) output += `
${pwaInstructions.trim()}
`;
if (starlightInstructions) output += `
${starlightInstructions.trim()}
`;
if (noOrmWarning) output += `
${noOrmWarning.trim()}
`;
if (bunWebNativeWarning) output += `
${bunWebNativeWarning.trim()}
`;
output += `
${re.bold("Update all dependencies:\n")}${re.cyan(
tazeCommand
)}
`;
output += `${re.bold(
"Like Better-T Stack?"
)} Please consider giving us a star on GitHub:
`;
output += re.cyan("https://github.com/AmanVarshney01/create-better-t-stack");
relinka("info", output);
}
function getNativeInstructions(isConvex) {
const envVar = isConvex ? "EXPO_PUBLIC_CONVEX_URL" : "EXPO_PUBLIC_SERVER_URL";
const exampleUrl = isConvex ? "https://<YOUR_CONVEX_URL>" : "http://<YOUR_LOCAL_IP>:3000";
const envFileName = ".env";
const ipNote = isConvex ? "your Convex deployment URL (find after running 'dev:setup')" : "your local IP address";
let instructions = `${re.yellow(
"NOTE:"
)} For Expo connectivity issues, update apps/native/${envFileName}
with ${ipNote}:
${`${envVar}=${exampleUrl}`}
`;
if (isConvex) {
instructions += `
${re.yellow(
"IMPORTANT:"
)} When using local development with Convex and native apps, ensure you use your local IP address
instead of localhost or 127.0.0.1 for proper connectivity.
`;
}
return instructions;
}
function getLintingInstructions(runCmd) {
return `${re.bold("Linting and formatting:")}
${re.cyan(
"\u2022"
)} Format and lint fix: ${`${runCmd} check`}
`;
}
function getDatabaseInstructions(database, orm, runCmd, runtime) {
const instructions = [];
if (orm === "prisma") {
if (database === "sqlite") {
instructions.push(
`${re.yellow(
"NOTE:"
)} Turso support with Prisma is in Early Access and requires additional setup.`,
`${"Learn more at: https://www.prisma.io/docs/orm/overview/databases/turso"}`
);
}
if (runtime === "bun") {
instructions.push(
`${re.yellow(
"NOTE:"
)} Prisma with Bun may require additional configuration. If you encounter errors,
follow the guidance provided in the error messages`
);
}
instructions.push(`${re.cyan("\u2022")} Apply schema: ${`${runCmd} db:push`}`);
instructions.push(`${re.cyan("\u2022")} Database UI: ${`${runCmd} db:studio`}`);
} else if (orm === "drizzle") {
instructions.push(`${re.cyan("\u2022")} Apply schema: ${`${runCmd} db:push`}`);
instructions.push(`${re.cyan("\u2022")} Database UI: ${`${runCmd} db:studio`}`);
if (database === "sqlite") {
instructions.push(
`${re.cyan(
"\u2022"
)} Start local DB (if needed): ${`cd apps/server && ${runCmd} db:local`}`
);
}
} else if (orm === "none") {
instructions.push(
`${re.yellow("NOTE:")} Manual database schema setup required.`
);
}
return instructions.length ? `${re.bold("Database commands:")}
${instructions.join("\n")}` : "";
}
function getTauriInstructions(runCmd) {
return `
${re.bold("Desktop app with Tauri:")}
${re.cyan(
"\u2022"
)} Start desktop app: ${`cd apps/web && ${runCmd} desktop:dev`}
${re.cyan(
"\u2022"
)} Build desktop app: ${`cd apps/web && ${runCmd} desktop:build`}
${re.yellow(
"NOTE:"
)} Tauri requires Rust and platform-specific dependencies.
See: ${"https://v2.tauri.app/start/prerequisites/"}`;
}
function getPwaInstructions() {
return `
${re.bold("PWA with React Router v7:")}
${re.yellow(
"NOTE:"
)} There is a known compatibility issue between VitePWA and React Router v7.
See: https://github.com/vite-pwa/vite-plugin-pwa/issues/809`;
}
function getStarlightInstructions(runCmd) {
return `
${re.bold("Documentation with Starlight:")}
${re.cyan(
"\u2022"
)} Start docs site: ${`cd apps/docs && ${runCmd} dev`}
${re.cyan(
"\u2022"
)} Build docs site: ${`cd apps/docs && ${runCmd} build`}`;
}
function getNoOrmWarning() {
return `
${re.yellow(
"WARNING:"
)} Database selected without an ORM. Features requiring database access (e.g., examples, auth) need manual setup.`;
}
function getBunWebNativeWarning() {
return `
${re.yellow(
"WARNING:"
)} 'bun' might cause issues with web + native apps in a monorepo. Use 'pnpm' if problems arise.`;
}