Skip to content

Instantly share code, notes, and snippets.

@WomB0ComB0
Created March 24, 2025 08:35
Show Gist options
  • Save WomB0ComB0/6e74506291a837a6fb6b85fa97391295 to your computer and use it in GitHub Desktop.
Save WomB0ComB0/6e74506291a837a6fb6b85fa97391295 to your computer and use it in GitHub Desktop.
database.gen.ts and related files - with AI-generated descriptions
'use server';
import { exec } from 'node:child_process';
import fs from 'node:fs';
import path from 'node:path';
import { promisify } from 'node:util';
import { logger } from '@/utils';
import { Redacted } from '@/classes';
const execPromise = promisify(exec);
const retry = async (fn: () => Promise<any>, retries = 3, delay = 1000) => {
try {
return await fn();
} catch (error) {
if (retries > 0) {
logger.warn(`Retrying... (${retries} attempts left)`, { error });
await new Promise((resolve) => setTimeout(resolve, delay));
return retry(fn, retries - 1, delay);
}
throw error;
}
};
const updateShouldUseSupabase = (shouldUseSupabase: boolean) => {
const filePath = path.join(process.cwd(), 'src/config/supabase.ts');
const fileContent = fs.readFileSync(filePath, 'utf8').split('\n');
const updatedContent = fileContent.map((line) => {
if (line.includes('export const SHOULD_USE_SUPABASE =')) {
return `export const SHOULD_USE_SUPABASE = ${shouldUseSupabase};`;
}
return line;
});
fs.writeFileSync(filePath, updatedContent.join('\n'));
logger.info(`Updated SHOULD_USE_SUPABASE to ${shouldUseSupabase} in src/config/supabase.ts`);
};
(async () => {
const projectRef = Redacted.make(process.env.NEXT_PUBLIC_SUPABASE_URL?.split('//')[1]?.split('.')[0]);
if (!process.env.SUPABASE_ACCESS_TOKEN) {
logger.error('SUPABASE_ACCESS_TOKEN environment variable is not set');
process.exit(1);
}
const isDev = process.env.NODE_ENV !== 'production';
try {
logger.info('Starting database setup...', { env: process.env.NODE_ENV, projectRef });
logger.info('Logging in to Supabase CLI...');
const { stdout: loginOutput, stderr: loginError } = await retry(() =>
execPromise(`bunx supabase login --token ${Redacted.make(process.env.SUPABASE_ACCESS_TOKEN).getValue()}`),
);
if (loginError) {
logger.warn('Supabase login produced warnings:', { error: loginError });
}
logger.info('Supabase CLI login completed:', { output: loginOutput });
logger.info('Generating Prisma client...');
const { stdout: generateOutput, stderr: generateError } = await retry(() =>
execPromise('bunx prisma generate'),
);
if (generateError) {
logger.warn('Prisma generate produced warnings:', { error: generateError });
}
logger.info('Prisma client generated:', { output: generateOutput });
if (isDev) {
logger.info('Pushing schema changes (development only)...');
try {
const { stdout: pushOutput, stderr: pushError } = await retry(() =>
execPromise('bunx prisma db push --accept-data-loss --skip-generate'),
);
if (pushError) {
logger.warn('Schema push produced warnings:', { error: pushError });
}
logger.info('Schema push completed:', { output: pushOutput });
} catch (pushError) {
logger.warn('Schema push failed, continuing with migrations:', { error: pushError });
}
}
logger.info('Applying migrations...');
const { stdout: migrateOutput, stderr: migrateError } = await retry(() =>
execPromise('bunx prisma migrate deploy'),
);
if (migrateError) {
logger.warn('Migration produced warnings:', { error: migrateError });
}
logger.info('Migrations completed:', { output: migrateOutput });
logger.info('Generating Supabase types...');
const supabaseCommand = `npx supabase gen types --lang=typescript --project-id "${projectRef.getValue()}" --schema public,auth,storage,next_auth > src/types/supabase.ts`;
const { stdout: supabaseOutput, stderr: supabaseError } = await retry(() =>
execPromise(supabaseCommand),
);
if (supabaseError) {
logger.warn('Supabase types generation produced warnings:', { error: supabaseError });
}
logger.info('Supabase types generated successfully:', { output: supabaseOutput });
logger.info('Database setup completed successfully!');
updateShouldUseSupabase(true);
logger.info('Updated SHOULD_USE_SUPABASE to true in src/config/supabase.ts');
} catch (error) {
logger.error('Failed to complete database setup:', { error });
updateShouldUseSupabase(false);
logger.info('Updated SHOULD_USE_SUPABASE to false in src/config/supabase.ts');
if (error instanceof Error) {
logger.error('Error details:', {
message: error.message,
stack: error.stack,
// @ts-ignore
code: error.code,
});
}
process.exit(1);
}
})();

database.gen.ts Description

File Type: ts

Generated Description:

database.gen.ts Analysis

Summary

This file is a TypeScript script responsible for setting up and managing a Supabase database. It automates several key tasks, including Supabase CLI login, Prisma schema management (generation, push, and migration), Supabase types generation, and updating a configuration file to reflect the success or failure of the database setup. The script uses asynchronous operations, error handling with retries, and logging for robust execution.

Key Components and Functions

  • retry(fn, retries = 3, delay = 1000): A higher-order function that wraps an asynchronous function (fn) and retries it up to retries times with a specified delay between attempts. This improves resilience against transient errors.

  • updateShouldUseSupabase(shouldUseSupabase: boolean): This function updates the SHOULD_USE_SUPABASE constant in src/config/supabase.ts. It dynamically sets this boolean value based on the success or failure of the database setup. This allows the application to gracefully handle cases where the database is unavailable.

  • async function (main execution block): This is the main function where the database setup process occurs. It's structured as an Immediately Invoked Async Function Expression (IIFE).

  • Supabase CLI Interaction: The script uses bunx supabase login to log into the Supabase CLI, npx supabase gen types to generate TypeScript types from the Supabase schema, and various bunx prisma commands for database management.

  • Prisma Handling: The script leverages Prisma for database migrations (bunx prisma migrate deploy) and schema management (bunx prisma db push). The --accept-data-loss and --skip-generate flags in db push suggest a focus on development environments where data loss is acceptable for schema changes.

  • Environment Variable Handling: The script relies heavily on environment variables (SUPABASE_ACCESS_TOKEN, NEXT_PUBLIC_SUPABASE_URL, NODE_ENV) for configuration.

Notable Patterns and Techniques

  • Asynchronous Programming: The script extensively uses async/await for cleaner and more readable asynchronous code.

  • Error Handling and Retries: The retry function showcases robust error handling by retrying operations upon failure, making the script more resilient to temporary network issues or other intermittent problems.

  • Logging: The script uses a logger function (presumably from a custom logging utility) to provide detailed information about each stage of the process, including errors and warnings. This is crucial for debugging and monitoring.

  • Dependency Injection (Implicit): Although not explicit, the use of the logger and Redacted classes suggests a degree of dependency injection, promoting modularity and testability.

  • Configuration Management: The updateShouldUseSupabase function dynamically updates the application's configuration based on the database setup status. This is a good practice for adapting the application's behavior based on runtime conditions.

  • Redaction: The Redacted class is used to protect sensitive data like the Supabase access token and project ID before logging or including them in commands.

Potential Use Cases

  • Deployment Automation: This script can be integrated into a CI/CD pipeline to automate the setup of the Supabase database during deployments.

  • Development Workflow: It streamlines the development workflow by automating the generation of Prisma client and Supabase types. It simplifies the process of syncing local development databases with the remote Supabase instance.

  • Database Migrations: It ensures that database migrations are applied consistently across environments, making it easier to manage schema changes.

This script effectively combines several tools and techniques to provide a robust and automated solution for Supabase database management. Its modular design, error handling, and logging make it well-suited for production environments.

Description generated on 3/24/2025, 4:35:53 AM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment