@reliverse/rse
Version:
@reliverse/rse is your all-in-one companion for bootstrapping and improving any kind of projects (especially web apps built with frameworks like Next.js) — whether you're kicking off something new or upgrading an existing app. It is also a little AI-power
162 lines (161 loc) • 5.37 kB
JavaScript
import { relinka } from "@reliverse/relinka";
import { confirmPrompt, selectPrompt } from "@reliverse/rempts";
import { installIntegration, removeIntegration } from "./editor-mod.js";
import { INTEGRATION_CONFIGS } from "./feature-add.js";
import { REMOVAL_CONFIGS } from "./feature-rm.js";
export async function handleIntegrations(cwd, isDev) {
const integrationOptions = {
database: [
{
label: "Drizzle",
value: "drizzle",
subOptions: [
{
label: "PostgreSQL",
value: "postgres",
providers: ["neon", "railway"]
},
{ label: "SQLite", value: "sqlite" },
{ label: "MySQL", value: "mysql" }
]
},
{ label: "Prisma", value: "prisma" },
{ label: "Supabase", value: "supabase" },
{ label: "None (Remove existing)", value: "none" }
],
payments: [
{ label: "Stripe", value: "stripe" },
{ label: "Polar", value: "polar" },
{ label: "None (Remove existing)", value: "none" }
],
auth: [
{ label: "NextAuth.js", value: "next-auth" },
{ label: "Clerk", value: "clerk" },
{ label: "Better-Auth", value: "better-auth" },
{ label: "None (Remove existing)", value: "none" }
],
email: [
{ label: "Resend", value: "resend" },
{ label: "None (Remove existing)", value: "none" }
],
styling: [
{ label: "Tailwind CSS", value: "tailwind" },
{ label: "shadcn/ui", value: "shadcn" },
{ label: "None (Remove existing)", value: "none" }
],
testing: [
{ label: "Bun Test", value: "bun-test" },
{ label: "Vitest", value: "vitest" },
{ label: "Jest", value: "jest" },
{ label: "None (Remove existing)", value: "none" }
],
i18n: [
{ label: "next-intl", value: "next-intl" },
{ label: "next-international", value: "next-international" },
{ label: "Lingui", value: "lingui" },
{ label: "None (Remove existing)", value: "none" }
]
};
const category = await selectPrompt({
title: "Which kind of integration would you like to add?",
options: [
{ label: "Database", value: "database" },
{ label: "Payments", value: "payments" },
{ label: "Authentication", value: "auth" },
{ label: "Email", value: "email" },
{ label: "Styling", value: "styling" },
{ label: "Testing", value: "testing" },
{ label: "Internationalization", value: "i18n" }
]
});
const options = integrationOptions[category];
if (!options) {
throw new Error(`No integration options found for category: ${category}`);
}
const selectedIntegration = await selectPrompt({
title: `Select ${category} integration:`,
options: options.map((opt) => ({
label: opt.label,
value: opt.value
}))
});
if (selectedIntegration === "none") {
const shouldRemove = await confirmPrompt({
title: `Are you sure you want to remove all ${category} integrations?`,
content: `This will remove all ${category}-related files and dependencies`,
defaultValue: false
});
if (shouldRemove && REMOVAL_CONFIGS[category]) {
await removeIntegration(cwd, REMOVAL_CONFIGS[category]);
return;
}
}
if (category === "database" && selectedIntegration === "drizzle") {
const option = options.find((opt) => opt.value === "drizzle");
if (!option?.subOptions) {
throw new Error("Database configuration not found");
}
const dbType = await selectPrompt({
title: "Select database type:",
options: option.subOptions.map((sub) => ({
label: sub.label,
value: sub.value
}))
});
if (dbType === "postgres") {
const postgresOption = option.subOptions.find(
(sub) => sub.value === "postgres"
);
if (!postgresOption?.providers) {
throw new Error("PostgreSQL providers not found");
}
const provider = await selectPrompt({
title: "Select database provider:",
options: postgresOption.providers.map((p) => ({
label: p,
value: p.toLowerCase()
}))
});
const config2 = {
...INTEGRATION_CONFIGS.drizzle,
name: "drizzle",
dependencies: [
// @ts-expect-error TODO: fix strictNullChecks undefined
...INTEGRATION_CONFIGS.drizzle.dependencies,
provider === "neon" ? "@neondatabase/serverless" : "postgres"
],
files: [],
devDependencies: [],
scripts: {},
envVars: {}
};
await installIntegration(cwd, config2, isDev);
relinka(
"info",
`Selected ${selectedIntegration} for ${category} - Implementation coming soon!`
);
return;
}
await installIntegration(cwd, INTEGRATION_CONFIGS.drizzle, isDev);
relinka(
"info",
`Selected ${selectedIntegration} for ${category} - Implementation coming soon!`
);
return;
}
const integrationKey = selectedIntegration;
const config = INTEGRATION_CONFIGS[integrationKey];
if (!config) {
relinka(
"error",
`Integration configuration not found for ${integrationKey}`
);
return;
}
await installIntegration(cwd, config, isDev);
relinka(
"info",
`Selected ${selectedIntegration} for ${category} - Implementation coming soon!`
);
return;
}