add sponsors, builder, docs command in cli

This commit is contained in:
Aman Varshney
2025-06-12 12:27:51 +05:30
parent dc8859052e
commit fd86d51d8e
5 changed files with 136 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"create-better-t-stack": patch
---
add sponsors, builder, docs command

View File

@@ -34,7 +34,9 @@ import { trackProjectCreation } from "./utils/analytics";
import { displayConfig } from "./utils/display-config";
import { generateReproducibleCommand } from "./utils/generate-reproducible-command";
import { getLatestCLIVersion } from "./utils/get-latest-cli-version";
import { openUrl } from "./utils/open-url";
import { renderTitle } from "./utils/render-title";
import { displaySponsors, fetchSponsors } from "./utils/sponsors";
import { getProvidedFlags, processAndValidateFlags } from "./validation";
const t = trpcServer.initTRPC.create();
@@ -299,6 +301,41 @@ const router = t.router({
};
await createProjectHandler(combinedInput);
}),
sponsors: t.procedure
.meta({ description: "Show Better-T Stack sponsors" })
.mutation(async () => {
try {
renderTitle();
intro(pc.magenta("Better-T Stack Sponsors"));
const sponsors = await fetchSponsors();
displaySponsors(sponsors);
} catch (error) {
consola.error(error);
process.exit(1);
}
}),
docs: t.procedure
.meta({ description: "Open Better-T Stack documentation" })
.mutation(async () => {
const DOCS_URL = "https://better-t-stack.amanv.dev/docs";
try {
await openUrl(DOCS_URL);
log.success(pc.blue("Opened docs in your default browser."));
} catch {
log.message(`Please visit ${DOCS_URL}`);
}
}),
builder: t.procedure
.meta({ description: "Open the web-based stack builder" })
.mutation(async () => {
const BUILDER_URL = "https://better-t-stack.amanv.dev/new";
try {
await openUrl(BUILDER_URL);
log.success(pc.blue("Opened builder in your default browser."));
} catch {
log.message(`Please visit ${BUILDER_URL}`);
}
}),
});
createCli({

View File

@@ -0,0 +1,25 @@
import { log } from "@clack/prompts";
import { execa } from "execa";
export async function openUrl(url: string): Promise<void> {
const platform = process.platform;
let command: string;
let args: string[] = [];
if (platform === "darwin") {
command = "open";
args = [url];
} else if (platform === "win32") {
command = "cmd";
args = ["/c", "start", "", url.replace(/&/g, "^&")];
} else {
command = "xdg-open";
args = [url];
}
try {
await execa(command, args, { stdio: "ignore" });
} catch {
log.message(`Please open ${url} in your browser.`);
}
}

View File

@@ -0,0 +1,68 @@
import { log, outro, spinner } from "@clack/prompts";
import pc from "picocolors";
export interface SponsorEntry {
readonly sponsor: {
readonly login: string;
readonly name?: string | null;
readonly avatarUrl?: string | null;
readonly websiteUrl?: string | null;
readonly linkUrl?: string | null;
readonly type?: string;
};
readonly isOneTime: boolean;
readonly monthlyDollars?: number;
readonly tierName?: string;
}
export const SPONSORS_JSON_URL = "https://sponsors.amanv.dev/sponsors.json";
export async function fetchSponsors(
url: string = SPONSORS_JSON_URL,
): Promise<SponsorEntry[]> {
const s = spinner();
s.start("Fetching sponsors…");
const response = await fetch(url);
if (!response.ok) {
s.stop(pc.red(`Failed to fetch sponsors: ${response.statusText}`));
throw new Error(`Failed to fetch sponsors: ${response.statusText}`);
}
const sponsors = (await response.json()) as SponsorEntry[];
s.stop("Sponsors fetched successfully!");
return sponsors;
}
export function displaySponsors(sponsors: SponsorEntry[]): void {
if (sponsors.length === 0) {
log.info("No sponsors found. You can be the first one! ✨");
outro(
pc.cyan(
"Visit https://github.com/sponsors/AmanVarshney01 to become a sponsor.",
),
);
return;
}
sponsors.forEach((entry: SponsorEntry, idx: number) => {
const sponsor = entry.sponsor;
const displayName = sponsor.name ?? sponsor.login;
const tier = entry.tierName ? ` (${entry.tierName})` : "";
log.step(`${idx + 1}. ${pc.green(displayName)}${pc.yellow(tier)}`);
log.message(` ${pc.dim("GitHub:")} https://github.com/${sponsor.login}`);
const website = sponsor.websiteUrl ?? sponsor.linkUrl;
if (website) {
log.message(` ${pc.dim("Website:")} ${website}`);
}
});
log.message("");
outro(
pc.magenta(
"Visit https://github.com/sponsors/AmanVarshney01 to become a sponsor.",
),
);
}

View File

@@ -158,7 +158,7 @@ export default function SponsorsSection() {
>
<Github className="h-4 w-4" />
<span className="truncate">
github.com/{entry.sponsor.login}
{entry.sponsor.login}
</span>
</a>
{(entry.sponsor.websiteUrl ||