create-better-t-stack 3.21.6 → 3.21.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{src-DS7GWAzq.mjs → src-BEc5W50Y.mjs} +159 -25
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as DatabaseSetupError, a as VirtualFileSystem, b as UserCancelledError, c as create, d as docs, f as generate, g as CompatibilityError, h as CLIError, i as TEMPLATE_COUNT, l as createBtsCli, m as sponsors, n as GeneratorError, o as add, p as router, r as Result, s as builder, t as EMBEDDED_TEMPLATES, u as createVirtual, v as DirectoryConflictError, x as ValidationError, y as ProjectCreationError } from "./src-
|
|
2
|
+
import { _ as DatabaseSetupError, a as VirtualFileSystem, b as UserCancelledError, c as create, d as docs, f as generate, g as CompatibilityError, h as CLIError, i as TEMPLATE_COUNT, l as createBtsCli, m as sponsors, n as GeneratorError, o as add, p as router, r as Result, s as builder, t as EMBEDDED_TEMPLATES, u as createVirtual, v as DirectoryConflictError, x as ValidationError, y as ProjectCreationError } from "./src-BEc5W50Y.mjs";
|
|
3
3
|
|
|
4
4
|
export { CLIError, CompatibilityError, DatabaseSetupError, DirectoryConflictError, EMBEDDED_TEMPLATES, GeneratorError, ProjectCreationError, Result, TEMPLATE_COUNT, UserCancelledError, ValidationError, VirtualFileSystem, add, builder, create, createBtsCli, createVirtual, docs, generate, router, sponsors };
|
|
@@ -430,28 +430,65 @@ async function openUrl(url) {
|
|
|
430
430
|
//#endregion
|
|
431
431
|
//#region src/utils/sponsors.ts
|
|
432
432
|
const SPONSORS_JSON_URL = "https://sponsors.better-t-stack.dev/sponsors.json";
|
|
433
|
+
const GITHUB_SPONSOR_URL = "https://github.com/sponsors/AmanVarshney01";
|
|
434
|
+
const nullableString = z.string().nullish().transform((value) => value ?? void 0);
|
|
435
|
+
const nullableNumber = z.number().nullish().transform((value) => value ?? void 0);
|
|
436
|
+
const sponsorSchema = z.object({
|
|
437
|
+
name: nullableString,
|
|
438
|
+
githubId: z.string(),
|
|
439
|
+
avatarUrl: z.string(),
|
|
440
|
+
websiteUrl: nullableString,
|
|
441
|
+
githubUrl: z.string(),
|
|
442
|
+
tierName: nullableString,
|
|
443
|
+
sinceWhen: z.string(),
|
|
444
|
+
transactionCount: z.number(),
|
|
445
|
+
totalProcessedAmount: nullableNumber,
|
|
446
|
+
formattedAmount: nullableString
|
|
447
|
+
});
|
|
448
|
+
const sponsorSummarySchema = z.object({
|
|
449
|
+
total_sponsors: z.number(),
|
|
450
|
+
total_lifetime_amount: z.number(),
|
|
451
|
+
total_current_monthly: z.number(),
|
|
452
|
+
special_sponsors: z.number(),
|
|
453
|
+
current_sponsors: z.number(),
|
|
454
|
+
past_sponsors: z.number(),
|
|
455
|
+
backers: z.number(),
|
|
456
|
+
top_sponsor: z.object({
|
|
457
|
+
name: z.string(),
|
|
458
|
+
amount: z.number()
|
|
459
|
+
}).nullish().transform((value) => value ?? void 0)
|
|
460
|
+
});
|
|
461
|
+
const sponsorEntrySchema = z.object({
|
|
462
|
+
generated_at: z.string(),
|
|
463
|
+
summary: sponsorSummarySchema,
|
|
464
|
+
specialSponsors: z.array(sponsorSchema),
|
|
465
|
+
sponsors: z.array(sponsorSchema),
|
|
466
|
+
pastSponsors: z.array(sponsorSchema),
|
|
467
|
+
backers: z.array(sponsorSchema)
|
|
468
|
+
});
|
|
433
469
|
async function fetchSponsors(url = SPONSORS_JSON_URL) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
470
|
+
return fetchSponsorsData({
|
|
471
|
+
url,
|
|
472
|
+
withSpinner: true
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
async function fetchSponsorsQuietly({ url = SPONSORS_JSON_URL, timeoutMs = 1500 } = {}) {
|
|
476
|
+
return fetchSponsorsData({
|
|
477
|
+
url,
|
|
478
|
+
withSpinner: false,
|
|
479
|
+
timeoutMs
|
|
480
|
+
});
|
|
444
481
|
}
|
|
445
482
|
function displaySponsors(sponsors) {
|
|
446
483
|
const { total_sponsors } = sponsors.summary;
|
|
447
484
|
if (total_sponsors === 0) {
|
|
448
485
|
log.info("No sponsors found. You can be the first one! ✨");
|
|
449
|
-
outro(pc.cyan(
|
|
486
|
+
outro(pc.cyan(`Visit ${GITHUB_SPONSOR_URL} to become a sponsor.`));
|
|
450
487
|
return;
|
|
451
488
|
}
|
|
452
489
|
displaySponsorsBox(sponsors);
|
|
453
490
|
if (total_sponsors - sponsors.specialSponsors.length > 0) log.message(pc.blue(`+${total_sponsors - sponsors.specialSponsors.length} more amazing sponsors.\n`));
|
|
454
|
-
outro(pc.magenta(
|
|
491
|
+
outro(pc.magenta(`Visit ${GITHUB_SPONSOR_URL} to become a sponsor.`));
|
|
455
492
|
}
|
|
456
493
|
function displaySponsorsBox(sponsors) {
|
|
457
494
|
if (sponsors.specialSponsors.length === 0) return;
|
|
@@ -467,6 +504,92 @@ function displaySponsorsBox(sponsors) {
|
|
|
467
504
|
});
|
|
468
505
|
consola$1.box(output);
|
|
469
506
|
}
|
|
507
|
+
function formatPostInstallSpecialSponsorsSection(sponsors) {
|
|
508
|
+
if (sponsors.specialSponsors.length === 0) return "";
|
|
509
|
+
const wrappedSponsorLines = wrapSponsorTokens(sponsors.specialSponsors.map((sponsor) => {
|
|
510
|
+
return `• ${sponsor.name ?? sponsor.githubId}`;
|
|
511
|
+
}), getPostInstallSponsorLineWidth());
|
|
512
|
+
let output = `${pc.bold("Special sponsors")}\n`;
|
|
513
|
+
wrappedSponsorLines.forEach((line) => {
|
|
514
|
+
output += `${line}\n`;
|
|
515
|
+
});
|
|
516
|
+
return output.trimEnd();
|
|
517
|
+
}
|
|
518
|
+
function getPostInstallSponsorLineWidth() {
|
|
519
|
+
const terminalWidth = process.stdout.columns;
|
|
520
|
+
if (!terminalWidth || terminalWidth <= 0) return 72;
|
|
521
|
+
const availableWidth = Math.max(8, terminalWidth - 24);
|
|
522
|
+
return Math.min(72, availableWidth);
|
|
523
|
+
}
|
|
524
|
+
function wrapSponsorTokens(tokens, maxLineWidth) {
|
|
525
|
+
const lines = [];
|
|
526
|
+
const separator = " ";
|
|
527
|
+
let currentLine = "";
|
|
528
|
+
tokens.forEach((token) => {
|
|
529
|
+
const candidateLine = currentLine ? `${currentLine}${separator}${token}` : token;
|
|
530
|
+
if (candidateLine.length <= maxLineWidth) {
|
|
531
|
+
currentLine = candidateLine;
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
if (currentLine) {
|
|
535
|
+
lines.push(currentLine);
|
|
536
|
+
currentLine = token;
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
lines.push(token);
|
|
540
|
+
});
|
|
541
|
+
if (currentLine) lines.push(currentLine);
|
|
542
|
+
return lines;
|
|
543
|
+
}
|
|
544
|
+
async function fetchSponsorsData({ url = SPONSORS_JSON_URL, withSpinner = false, timeoutMs }) {
|
|
545
|
+
const s = withSpinner ? spinner() : null;
|
|
546
|
+
if (s) s.start("Fetching sponsors…");
|
|
547
|
+
const controller = timeoutMs ? new AbortController() : null;
|
|
548
|
+
const timeout = timeoutMs ? setTimeout(() => {
|
|
549
|
+
controller?.abort();
|
|
550
|
+
}, timeoutMs) : null;
|
|
551
|
+
try {
|
|
552
|
+
const response = await fetch(url, controller ? { signal: controller.signal } : void 0);
|
|
553
|
+
if (!response.ok) {
|
|
554
|
+
const message = `Failed to fetch sponsors: ${response.statusText || String(response.status)}`;
|
|
555
|
+
if (s) s.stop(pc.red(message));
|
|
556
|
+
return Result.err(new CLIError({ message }));
|
|
557
|
+
}
|
|
558
|
+
const rawSponsors = await response.json();
|
|
559
|
+
const parseResult = sponsorEntrySchema.safeParse(rawSponsors);
|
|
560
|
+
if (!parseResult.success) {
|
|
561
|
+
const message = `Failed to fetch sponsors: invalid response format at "${parseResult.error.issues[0]?.path?.join(".") || "unknown"}"`;
|
|
562
|
+
if (s) s.stop(pc.red(message));
|
|
563
|
+
return Result.err(new CLIError({
|
|
564
|
+
message,
|
|
565
|
+
cause: parseResult.error
|
|
566
|
+
}));
|
|
567
|
+
}
|
|
568
|
+
if (s) s.stop("Sponsors fetched successfully!");
|
|
569
|
+
return Result.ok(parseResult.data);
|
|
570
|
+
} catch (error) {
|
|
571
|
+
const normalizedError = normalizeSponsorFetchError(error);
|
|
572
|
+
if (s) s.stop(pc.red(normalizedError.message));
|
|
573
|
+
return Result.err(normalizedError);
|
|
574
|
+
} finally {
|
|
575
|
+
if (timeout) clearTimeout(timeout);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
function normalizeSponsorFetchError(error) {
|
|
579
|
+
if (error instanceof Error && error.name === "AbortError") return new CLIError({
|
|
580
|
+
message: "Failed to fetch sponsors: request timed out",
|
|
581
|
+
cause: error
|
|
582
|
+
});
|
|
583
|
+
if (CLIError.is(error)) return error;
|
|
584
|
+
if (error instanceof Error) return new CLIError({
|
|
585
|
+
message: error.message.startsWith("Failed to fetch sponsors:") ? error.message : `Failed to fetch sponsors: ${error.message}`,
|
|
586
|
+
cause: error
|
|
587
|
+
});
|
|
588
|
+
return new CLIError({
|
|
589
|
+
message: `Failed to fetch sponsors: ${String(error)}`,
|
|
590
|
+
cause: error
|
|
591
|
+
});
|
|
592
|
+
}
|
|
470
593
|
|
|
471
594
|
//#endregion
|
|
472
595
|
//#region src/commands/meta.ts
|
|
@@ -480,21 +603,15 @@ async function openExternalUrl(url, successMessage) {
|
|
|
480
603
|
else log.message(`Please visit ${url}`);
|
|
481
604
|
}
|
|
482
605
|
async function showSponsorsCommand() {
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
},
|
|
489
|
-
catch: (error) => new CLIError({
|
|
490
|
-
message: error instanceof Error ? error.message : "Failed to display sponsors",
|
|
491
|
-
cause: error
|
|
492
|
-
})
|
|
493
|
-
});
|
|
494
|
-
if (result.isErr()) {
|
|
495
|
-
displayError(result.error);
|
|
606
|
+
renderTitle();
|
|
607
|
+
intro(pc.magenta("Better-T-Stack Sponsors"));
|
|
608
|
+
const sponsorsResult = await fetchSponsors();
|
|
609
|
+
if (sponsorsResult.isErr()) {
|
|
610
|
+
displayError(sponsorsResult.error);
|
|
496
611
|
process.exit(1);
|
|
612
|
+
return;
|
|
497
613
|
}
|
|
614
|
+
displaySponsors(sponsorsResult.value);
|
|
498
615
|
}
|
|
499
616
|
async function openDocsCommand() {
|
|
500
617
|
await openExternalUrl(DOCS_URL, "Opened docs in your default browser.");
|
|
@@ -1804,6 +1921,7 @@ const SKILL_SOURCES = {
|
|
|
1804
1921
|
"nuxt/ui": { label: "Nuxt UI" },
|
|
1805
1922
|
"heroui-inc/heroui": { label: "HeroUI Native" },
|
|
1806
1923
|
"better-auth/skills": { label: "Better Auth" },
|
|
1924
|
+
"clerk/skills": { label: "Clerk" },
|
|
1807
1925
|
"neondatabase/agent-skills": { label: "Neon Database" },
|
|
1808
1926
|
"supabase/agent-skills": { label: "Supabase" },
|
|
1809
1927
|
"planetscale/database-skills": { label: "PlanetScale" },
|
|
@@ -1931,6 +2049,7 @@ function getRecommendedSourceKeys(config) {
|
|
|
1931
2049
|
if (frontend.includes("native-uniwind")) sources.push("heroui-inc/heroui");
|
|
1932
2050
|
if (hasNativeFrontend(frontend)) sources.push("expo/skills");
|
|
1933
2051
|
if (auth === "better-auth") sources.push("better-auth/skills");
|
|
2052
|
+
if (auth === "clerk") sources.push("clerk/skills");
|
|
1934
2053
|
if (dbSetup === "neon") sources.push("neondatabase/agent-skills");
|
|
1935
2054
|
if (dbSetup === "supabase") sources.push("supabase/agent-skills");
|
|
1936
2055
|
if (dbSetup === "planetscale") sources.push("planetscale/database-skills");
|
|
@@ -1961,6 +2080,18 @@ const CURATED_SKILLS_BY_SOURCE = {
|
|
|
1961
2080
|
"nuxt/ui": () => ["nuxt-ui"],
|
|
1962
2081
|
"heroui-inc/heroui": () => ["heroui-native"],
|
|
1963
2082
|
"better-auth/skills": () => ["better-auth-best-practices"],
|
|
2083
|
+
"clerk/skills": (config) => {
|
|
2084
|
+
const skills = [
|
|
2085
|
+
"clerk",
|
|
2086
|
+
"clerk-setup",
|
|
2087
|
+
"clerk-custom-ui",
|
|
2088
|
+
"clerk-webhooks",
|
|
2089
|
+
"clerk-testing",
|
|
2090
|
+
"clerk-orgs"
|
|
2091
|
+
];
|
|
2092
|
+
if (config.frontend.includes("next")) skills.push("clerk-nextjs-patterns");
|
|
2093
|
+
return skills;
|
|
2094
|
+
},
|
|
1964
2095
|
"neondatabase/agent-skills": () => ["neon-postgres"],
|
|
1965
2096
|
"supabase/agent-skills": () => ["supabase-postgres-best-practices"],
|
|
1966
2097
|
"planetscale/database-skills": (config) => {
|
|
@@ -5554,6 +5685,9 @@ async function displayPostInstallInstructions(config) {
|
|
|
5554
5685
|
if (polarInstructions) output += `\n${polarInstructions.trim()}\n`;
|
|
5555
5686
|
if (noOrmWarning) output += `\n${noOrmWarning.trim()}\n`;
|
|
5556
5687
|
if (bunWebNativeWarning) output += `\n${bunWebNativeWarning.trim()}\n`;
|
|
5688
|
+
const sponsorsResult = await fetchSponsorsQuietly();
|
|
5689
|
+
const specialSponsorsSection = sponsorsResult.isOk() ? formatPostInstallSpecialSponsorsSection(sponsorsResult.value) : "";
|
|
5690
|
+
if (specialSponsorsSection) output += `\n${specialSponsorsSection.trim()}\n`;
|
|
5557
5691
|
output += `\n${pc.bold("Like Better-T-Stack?")} Please consider giving us a star\n on GitHub:\n`;
|
|
5558
5692
|
output += pc.cyan("https://github.com/AmanVarshney01/create-better-t-stack");
|
|
5559
5693
|
consola$1.box(output);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-better-t-stack",
|
|
3
|
-
"version": "3.21.
|
|
3
|
+
"version": "3.21.7",
|
|
4
4
|
"description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"better-auth",
|
|
@@ -70,8 +70,8 @@
|
|
|
70
70
|
"prepublishOnly": "npm run build"
|
|
71
71
|
},
|
|
72
72
|
"dependencies": {
|
|
73
|
-
"@better-t-stack/template-generator": "^3.21.
|
|
74
|
-
"@better-t-stack/types": "^3.21.
|
|
73
|
+
"@better-t-stack/template-generator": "^3.21.7",
|
|
74
|
+
"@better-t-stack/types": "^3.21.7",
|
|
75
75
|
"@clack/core": "^1.0.0",
|
|
76
76
|
"@clack/prompts": "^1.0.0",
|
|
77
77
|
"@orpc/server": "^1.13.4",
|