@reliverse/rse-sdk
Version:
@reliverse/rse-sdk without cli. @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).
186 lines (185 loc) • 5.7 kB
JavaScript
import { re } from "@reliverse/relico";
import fs from "@reliverse/relifso";
import { relinka } from "@reliverse/relinka";
import { execa } from "execa";
import path from "node:path";
import {
addEnvVariablesToFile
} from "../project-generation/env-setup.js";
import { getPackageExecutionCommand } from "../../utils/get-package-execution-command.js";
async function writeSupabaseEnvFile(projectDir, databaseUrl) {
try {
const envPath = path.join(projectDir, "apps/server", ".env");
const dbUrlToUse = databaseUrl || "postgresql://postgres:postgres@127.0.0.1:54322/postgres";
const variables = [
{
key: "DATABASE_URL",
value: dbUrlToUse,
condition: true
},
{
key: "DIRECT_URL",
value: dbUrlToUse,
condition: true
}
];
await addEnvVariablesToFile(envPath, variables);
return true;
} catch (error) {
relinka("error", re.red("Failed to update .env file for Supabase."));
if (error instanceof Error) {
relinka("error", error.message);
}
return false;
}
}
function extractDbUrl(output) {
const dbUrlMatch = /DB URL:\s*(postgresql:\/\/[^\s]+)/.exec(output);
const url = dbUrlMatch?.[1];
if (url) {
return url;
}
return null;
}
async function initializeSupabase(serverDir, packageManager) {
relinka("info", "Initializing Supabase project...");
try {
const supabaseInitCommand = getPackageExecutionCommand(
packageManager,
"supabase init"
);
await execa(supabaseInitCommand, {
cwd: serverDir,
stdio: "inherit",
shell: true
});
relinka("success", "Supabase project initialized");
return true;
} catch (error) {
relinka("error", re.red("Failed to initialize Supabase project."));
if (error instanceof Error) {
relinka("error", error.message);
} else {
relinka("error", String(error));
}
if (error instanceof Error && error.message.includes("ENOENT")) {
relinka(
"error",
re.red(
"Supabase CLI not found. Please install it globally or ensure it's in your PATH."
)
);
relinka("info", "You can install it using: npm install -g supabase");
}
return false;
}
}
async function startSupabase(serverDir, packageManager) {
relinka("info", "Starting Supabase services (this may take a moment)...");
const supabaseStartCommand = getPackageExecutionCommand(
packageManager,
"supabase start"
);
try {
const subprocess = execa(supabaseStartCommand, {
cwd: serverDir,
shell: true
});
let stdoutData = "";
if (subprocess.stdout) {
subprocess.stdout.on("data", (data) => {
const text = data.toString();
process.stdout.write(text);
stdoutData += text;
});
}
if (subprocess.stderr) {
subprocess.stderr.pipe(process.stderr);
}
await subprocess;
await new Promise((resolve) => setTimeout(resolve, 100));
return stdoutData;
} catch (error) {
relinka("error", re.red("Failed to start Supabase services."));
const execaError = error;
if (execaError?.message) {
relinka("error", `Error details: ${execaError.message}`);
if (execaError.message.includes("Docker is not running")) {
relinka(
"error",
re.red("Docker is not running. Please start Docker and try again.")
);
}
} else {
relinka("error", String(error));
}
return null;
}
}
function displayManualSupabaseInstructions(output) {
relinka(
"info",
`"Manual Supabase Setup Instructions:"
1. Ensure Docker is installed and running.
2. Install the Supabase CLI (e.g., \`npm install -g supabase\`).
3. Run \`supabase init\` in your project's \`apps/server\` directory.
4. Run \`supabase start\` in your project's \`apps/server\` directory.
5. Copy the 'DB URL' from the output.${output ? `
${re.bold("Relevant output from `supabase start`:")}
${re.dim(output)}` : ""}
6. Add the DB URL to the .env file in \`apps/server/.env\` as \`DATABASE_URL\`:
${re.gray('DATABASE_URL="your_supabase_db_url"')}`
);
}
export async function setupSupabase(config) {
const { projectDir, packageManager } = config;
const serverDir = path.join(projectDir, "apps", "server");
try {
await fs.ensureDir(serverDir);
const initialized = await initializeSupabase(serverDir, packageManager);
if (!initialized) {
displayManualSupabaseInstructions();
return;
}
const supabaseOutput = await startSupabase(serverDir, packageManager);
if (!supabaseOutput) {
displayManualSupabaseInstructions();
return;
}
const dbUrl = extractDbUrl(supabaseOutput);
if (dbUrl) {
const envUpdated = await writeSupabaseEnvFile(projectDir, dbUrl);
if (envUpdated) {
relinka("success", re.green("Supabase local development setup ready!"));
} else {
relinka(
"error",
re.red(
"Supabase setup completed, but failed to update .env automatically."
)
);
displayManualSupabaseInstructions(supabaseOutput);
}
} else {
relinka(
"error",
re.yellow(
"Supabase started, but could not extract DB URL automatically."
)
);
displayManualSupabaseInstructions(supabaseOutput);
}
} catch (error) {
if (error instanceof Error) {
relinka("error", re.red(`Error during Supabase setup: ${error.message}`));
} else {
relinka(
"error",
re.red(
`An unknown error occurred during Supabase setup: ${String(error)}`
)
);
}
displayManualSupabaseInstructions();
}
}