cleaned up autumn setup script for oss

This commit is contained in:
John Yeo
2025-06-16 19:42:13 +01:00
parent c48e4dcff0
commit 4cbebb8187
2 changed files with 84 additions and 19 deletions

101
setup.js
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env node
import { randomBytes } from 'crypto';
import { writeFileSync } from 'fs';
import { writeFileSync, copyFileSync } from 'fs';
import inquirer from 'inquirer';
import { spawnSync } from 'child_process';
import chalk from 'chalk';
@@ -14,7 +14,7 @@ const genUrlSafeBase64 = (bytes) => {
}
const genRandomSubdomain = (length = 32) => {
const genRandomSubdomain = (length = 10) => {
const chars = 'abcdefghijklmnopqrstuvwxyz';
let result = '';
for (let i = 0; i < length; i++) {
@@ -32,29 +32,77 @@ const genAlphanumericPassword = (length = 24) => {
return result;
}
// Helper to get or create a Supabase org
const getOrCreateSupabaseOrg = async () => {
// List orgs (table output)
const orgListResult = spawnSync(
'npx',
['supabase', 'orgs', 'list'],
{ encoding: 'utf-8' }
);
if (orgListResult.status !== 0) {
console.error(chalk.red('❌ Failed to list Supabase orgs.'));
process.exit(1);
}
const lines = orgListResult.stdout.split('\n').map(l => l.trim()).filter(Boolean);
// Find separator line (e.g., "------|------")
const sepIdx = lines.findIndex(line => line.includes('|') && line.includes('-'));
// If only header and separator, no orgs exist
if (lines.length <= sepIdx + 1) {
console.log(chalk.yellowBright('No Supabase organizations found.'));
const { createOrg } = await inquirer.prompt([
{
type: 'confirm',
name: 'createOrg',
message: chalk.cyan('Would you like to create a new Supabase organization now?'),
default: true,
},
]);
if (!createOrg) {
console.log(chalk.red('❌ Cannot continue without a Supabase organization. Exiting.'));
process.exit(1);
}
const { orgName } = await inquirer.prompt([
{
type: 'input',
name: 'orgName',
message: chalk.cyan('Enter a name for your new Supabase organization:'),
validate: (input) => input && input.length > 2,
},
]);
console.log(chalk.blueBright(`\nCreating Supabase organization '${orgName}'...`));
const createOrgResult = spawnSync(
'npx',
['supabase', 'orgs', 'create', orgName],
{ stdio: 'inherit', encoding: 'utf-8' }
);
if (createOrgResult.status !== 0) {
console.error(chalk.red('❌ Failed to create Supabase organization.'));
process.exit(1);
}
// Done! Org created, return
return;
}
// At least one org exists, just proceed
return;
};
const generateSupabaseDatabaseUrl = async () => {
// Step 3: Run supabase login
console.log(chalk.magentaBright('\n================ Supabase Setup ================\n'));
console.log(chalk.blueBright('\nLaunching Supabase login...'));
spawnSync('npx', ['supabase', 'login'], { stdio: 'inherit' });
// Step 3.5: Ensure org exists and select one
await getOrCreateSupabaseOrg();
// Step 4: Prompt for project name and region
const projectName = "autumn-oss-db";
// const { region } = await inquirer.prompt([
// {
// type: 'list',
// name: 'region',
// message: 'Choose a Supabase region:',
// choices: [
// { name: 'eu-west-2 (London)', value: 'eu-west-2' },
// { name: 'us-east-1 (N. Virginia)', value: 'us-east-1' },
// { name: 'ap-southeast-1 (Singapore)', value: 'ap-southeast-1' },
// { name: 'ap-southeast-2 (Sydney)', value: 'ap-southeast-2' },
// { name: 'eu-central-1 (Frankfurt)', value: 'eu-central-1' },
// { name: 'us-west-1 (N. California)', value: 'us-west-1' },
// ],
// default: 'eu-west-2',
// },
// ]);
// Step 5: Generate DB password (alphanumeric only)
const dbPassword = genAlphanumericPassword(24); // 24 chars, alphanumeric
@@ -98,6 +146,12 @@ const generateSupabaseDatabaseUrl = async () => {
console.log(chalk.greenBright(`\nGenerated DB password: ${dbPassword}\n`));
console.log(chalk.greenBright(`\nYour DATABASE_URL is:\n${databaseUrl}\n`));
console.log(chalk.yellow('--------------------------------'));
// Step 9: Prompt to run docker compose up
console.log(chalk.magentaBright('\nNext steps:'));
console.log(chalk.yellow('Run "docker compose -f docker-compose.dev.yml up" to start Autumn'));
return databaseUrl;
}
@@ -110,7 +164,7 @@ const handleDatabaseSetup = async () => {
name: 'dbOption',
message: chalk.cyan('How do you want to set up your database?'),
choices: [
{ name: 'Set up Supabase for Autumn', value: 'supabase' },
{ name: 'Set up Supabase (Cloud) for Autumn', value: 'supabase' },
{ name: 'Paste in your own DATABASE_URL', value: 'paste' },
{ name: 'Paste in your own DATABASE_URL later', value: 'later' },
],
@@ -236,10 +290,19 @@ async function main() {
const envVars = envSections.join('\n');
writeFileSync('server/.env', envVars);
try {
copyFileSync('vite/.env.example', 'vite/.env');
} catch (error) {
console.log(chalk.red('❌ Failed to copy vite/.env.example to vite/.env'));
console.log(chalk.red('❌ Please copy the file manually'));
}
console.log(chalk.greenBright('🎉 Setup complete! 🎉'));
console.log(chalk.cyan('You can find your env variables in server/.env'));
// Prompt to run pnpm run db:push at the end
const { runDbPush } = await inquirer.prompt([
{

2
vite/.env.example Normal file
View File

@@ -0,0 +1,2 @@
VITE_FRONTEND_URL=http://localhost:3000
VITE_BACKEND_URL=http://localhost:8080