From 8f207e452a025c224d3e71642557f5c8fb027377 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Che=C5=82miniak?= Date: Thu, 31 Oct 2024 14:05:21 +0100 Subject: [PATCH] refactor: command overall readibility --- packages/cli/index.ts | 6 +-- packages/core/index.ts | 2 - packages/core/package.json | 2 + packages/core/utils/bar/prepareDrink.ts | 9 ++-- packages/core/utils/docs/create.ts | 2 +- packages/core/utils/env/createEnvFile.ts | 2 +- packages/core/utils/github/ghInstaller.ts | 26 +++++++---- packages/core/utils/github/install.ts | 24 +++++----- .../core/utils/github/repositoryManager.ts | 33 ++++++++------ packages/core/utils/payload/install.ts | 14 ++++-- .../utils/payload/preparePayloadConfig.ts | 10 ++++- .../core/utils/payload/prepareTsConfig.ts | 12 +++-- .../core/utils/payload/removeTurboFlag.ts | 12 +++-- packages/core/utils/payload/updatePackages.ts | 14 ++++-- packages/core/utils/prettier/prettify.ts | 7 ++- .../core/utils/shared/continueOnKeypress.ts | 8 +++- packages/core/utils/shared/updateEnvFile.ts | 2 +- .../core/utils/supabase/connectProject.ts | 45 ++++++++++--------- packages/core/utils/supabase/createProject.ts | 8 +++- packages/core/utils/supabase/install.ts | 35 +++++++++------ packages/core/utils/turbo/create.ts | 7 +++ packages/core/utils/vercel/connectWithGH.ts | 29 +++++++----- packages/core/utils/vercel/deploy.ts | 20 +++++---- packages/core/utils/vercel/setupAndCreate.ts | 25 +++++++---- pnpm-lock.yaml | 6 +++ 25 files changed, 234 insertions(+), 126 deletions(-) diff --git a/packages/cli/index.ts b/packages/cli/index.ts index a0424ad..075012b 100644 --- a/packages/cli/index.ts +++ b/packages/cli/index.ts @@ -20,13 +20,11 @@ const asciiArt = ` const displayHeader = () => { const metalGradient = gradient([ { color: '#3C3C3C', pos: 0 }, - { color: '#FFFFFF', pos: 0.5 }, - { color: '#BDBDBD', pos: 0.75 }, - { color: '#3C3C3C', pos: 1 }, + { color: '#FFFFFF', pos: 1 }, ]); console.log(metalGradient(asciiArt)); - console.log(chalk.bold('\nšŸ–‡ļø Welcome to Stapler!\n')); + console.log(chalk.bold('\nWelcome to Stapler!\n')); }; const program = new Command(); diff --git a/packages/core/index.ts b/packages/core/index.ts index 0a0d7da..47c5795 100644 --- a/packages/core/index.ts +++ b/packages/core/index.ts @@ -19,8 +19,6 @@ interface ProjectOptions { export const createProject = async (options: ProjectOptions) => { const { name, usePayload } = options; - console.log(`šŸ–‡ļø Stapling ${name}...`); - await createTurboRepo(name); process.chdir(name); diff --git a/packages/core/package.json b/packages/core/package.json index 2dd7457..7669bc7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -9,7 +9,9 @@ "dev": "tsc -w" }, "dependencies": { + "chalk": "^5.3.0", "fs-extra": "^11.2.0", + "gradient-string": "^3.0.0", "inquirer": "^10.2.2" }, "devDependencies": { diff --git a/packages/core/utils/bar/prepareDrink.ts b/packages/core/utils/bar/prepareDrink.ts index fd52304..f63ac63 100644 --- a/packages/core/utils/bar/prepareDrink.ts +++ b/packages/core/utils/bar/prepareDrink.ts @@ -1,3 +1,5 @@ +import chalk from 'chalk'; + const getName = (name: string) => { if (!name) { return '.'; @@ -12,13 +14,12 @@ export const prepareDrink = (name: string) => { setTimeout(() => { console.log('šŸø Adding gin and lime juice...'); setTimeout(() => { - console.log('šŸø Topping with', '\x1b[34mTonik\x1b[0m...'); + console.log('šŸø Topping with', chalk.blue('Tonik') + '...'); setTimeout(() => { console.log('šŸø Garnishing with lime wedge...'); setTimeout(() => { - console.log(`\x1b[32m%s\x1b[0m`, `šŸø Your Stapled ${getName(name)} is ready!`, `\x1b[0m`); - // I'm too lazy to mess with modules building to allow coloring library to be installed lol - console.log(`šŸø You can now run:`, `\x1b[36mcd ${name} && pnpm dev\x1b[0m`); + console.log(chalk.green(`šŸø Your Stapled ${getName(name)} is ready!`)); + console.log(`šŸø You can now run:`, chalk.cyan(`cd ${name} && pnpm dev`)); }, 1000); }, 1000); }, 1000); diff --git a/packages/core/utils/docs/create.ts b/packages/core/utils/docs/create.ts index 8141a14..f33a72e 100644 --- a/packages/core/utils/docs/create.ts +++ b/packages/core/utils/docs/create.ts @@ -3,7 +3,7 @@ import { templateGenerator } from '../generator/generator'; import { getTemplateDirectory } from '../shared/getTemplateDirectory'; export const createDocFiles = () => { - console.log('šŸ–‡ļø Writing docs...'); + console.log('Writing docs...'); const templateDirectory = getTemplateDirectory(`/templates/docs/files`); const destinationDirectory = process.cwd(); diff --git a/packages/core/utils/env/createEnvFile.ts b/packages/core/utils/env/createEnvFile.ts index 8c164b7..fe653b2 100644 --- a/packages/core/utils/env/createEnvFile.ts +++ b/packages/core/utils/env/createEnvFile.ts @@ -14,7 +14,7 @@ const requiredEnvVariables: Record = { // Function to create .env file with empty fields export const createEnvFile = (destinationDirectory: string) => { - console.log('šŸ–‡ļø Creating .env file...'); + console.log('Creating .env file...'); let envTemplate = ''; for (const [key, status] of Object.entries(requiredEnvVariables)) { envTemplate += `${key}=\n`; diff --git a/packages/core/utils/github/ghInstaller.ts b/packages/core/utils/github/ghInstaller.ts index be8982b..e9e4603 100644 --- a/packages/core/utils/github/ghInstaller.ts +++ b/packages/core/utils/github/ghInstaller.ts @@ -1,5 +1,11 @@ import { execSync } from 'child_process'; import * as os from 'os'; +import gradient from 'gradient-string'; + +const githubGradient = gradient([ + { color: '#3B8640', pos: 0 }, + { color: '#8256D0', pos: 1 }, +]); export const isGitHubCLIInstalled = (): boolean => { try { @@ -27,8 +33,10 @@ export const installGitHubCLI = (): boolean => { installCommand = 'sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo && sudo dnf install gh'; } else { - console.log('šŸ–‡ļø Automatic installation is not supported for your Linux distribution.'); - console.log('šŸ–‡ļø Please visit https://github.com/cli/cli#installation for installation instructions.'); + console.log( + githubGradient('Automatic installation is not supported for your Linux distribution.'), + githubGradient('\n Please visit https://github.com/cli/cli#installation for installation instructions.'), + ); return false; } break; @@ -36,19 +44,21 @@ export const installGitHubCLI = (): boolean => { installCommand = 'winget install --id GitHub.cli'; break; default: - console.log('šŸ–‡ļø Automatic installation is not supported for your operating system.'); - console.log('šŸ–‡ļø Please visit https://github.com/cli/cli#installation for installation instructions.'); + console.log( + githubGradient('Automatic installation is not supported for your operating system.'), + githubGradient('\nPlease visit https://github.com/cli/cli#installation for installation instructions.'), + ); return false; } - console.log('šŸ–‡ļø Installing GitHub CLI...'); + console.log(githubGradient('Installing GitHub CLI...')); try { execSync(installCommand, { stdio: 'inherit' }); - console.log('šŸ–‡ļø GitHub CLI installed successfully.'); + console.log(githubGradient('GitHub CLI installed successfully.')); return true; } catch (error) { - console.error('šŸ–‡ļø Failed to install GitHub CLI.'); - console.log('šŸ–‡ļø Please install it manually from: https://github.com/cli/cli#installation'); + console.error('Failed to install GitHub CLI.'); + console.log(githubGradient('Please install it manually from: https://github.com/cli/cli#installation')); return false; } }; diff --git a/packages/core/utils/github/install.ts b/packages/core/utils/github/install.ts index 965319b..d779c77 100644 --- a/packages/core/utils/github/install.ts +++ b/packages/core/utils/github/install.ts @@ -1,3 +1,4 @@ +import gradient from 'gradient-string'; import { installGitHubCLI, isGitHubCLIInstalled } from './ghInstaller'; import { authenticateGitHub, @@ -12,14 +13,19 @@ interface ProjectOptions { visibility: 'public' | 'private'; } +const githubGradient = gradient([ + { color: '#3B8640', pos: 0 }, + { color: '#8256D0', pos: 1 }, +]); + // Helper function to check if GitHub CLI is installed const checkGitHubCLI = () => { - console.log('šŸ–‡ļø Checking GitHub CLI installation...'); + console.log(githubGradient('Checking if GitHub CLI is installed...')); if (!isGitHubCLIInstalled()) { - console.log('šŸ–‡ļø GitHub CLI is not installed.'); + console.log(githubGradient('GitHub CLI is not installed.')); const installed = installGitHubCLI(); if (!installed) { - console.error('šŸ–‡ļø GitHub CLI installation failed. Exiting...'); + console.error('GitHub CLI installation failed. Exiting...'); process.exit(1); } } @@ -27,16 +33,16 @@ const checkGitHubCLI = () => { // Helper function to ensure GitHub authentication const ensureGitHubAuthentication = () => { - console.log('šŸ–‡ļø Checking GitHub authentication status...'); + console.log(githubGradient('Checking GitHub authentication status...')); // Check if the user is already authenticated if (isGitHubAuthenticated()) { - console.log('šŸ–‡ļø You are already logged in to GitHub.'); + console.log(githubGradient('You are already logged in to GitHub.')); return; // Exit early if authenticated } if (!isGitHubAuthenticated()) { - console.error(`šŸ–‡ļø It looks like you're not logged in...`); + console.error(`It looks like you're not logged in...`); authenticateGitHub(); } }; @@ -50,16 +56,14 @@ export const initializeRepository = async (options: ProjectOptions) => { // Retrieve GitHub username once const username = await fetchGitHubUsername(); if (!username) { - console.error('šŸ–‡ļø Failed to retrieve GitHub username. Aborting repository creation.'); + console.error('Failed to retrieve GitHub username. Aborting repository creation.'); process.exit(1); } // Check if the repository exists and create it const repoName = await createGitHubRepository(projectName, visibility, username); if (!repoName) { - console.error( - 'šŸ–‡ļø Failed to create GitHub repository. Check your permissions or if the repository already exists.', - ); + console.error('Failed to create GitHub repository. Check your permissions.'); process.exit(1); } diff --git a/packages/core/utils/github/repositoryManager.ts b/packages/core/utils/github/repositoryManager.ts index 9143449..10d9957 100644 --- a/packages/core/utils/github/repositoryManager.ts +++ b/packages/core/utils/github/repositoryManager.ts @@ -1,9 +1,15 @@ import { exec, execSync } from 'child_process'; import inquirer from 'inquirer'; import { promisify } from 'util'; +import gradient from 'gradient-string'; const execAsync = promisify(exec); +const githubGradient = gradient([ + { color: '#3B8640', pos: 0 }, + { color: '#8256D0', pos: 1 }, +]); + const generateUniqueRepoName = async (baseName: string): Promise => { // Remove any existing numbering pattern from the end const cleanBaseName = baseName.replace(/-\d+$/, ''); @@ -11,7 +17,7 @@ const generateUniqueRepoName = async (baseName: string): Promise => { // Try the base name first try { await execAsync(`gh repo view ${cleanBaseName}`); - console.error(`šŸ–‡ļø Repository "${cleanBaseName}" already exists.`); + console.error(`Repository "${cleanBaseName}" already exists.`); // If we get here, the repo exists, so we need a new name } catch (error) { // If repo doesn't exist, we can use the clean base name @@ -26,7 +32,7 @@ const generateUniqueRepoName = async (baseName: string): Promise => { const candidateName = `${cleanBaseName}-v${counter}`; try { await execAsync(`gh repo view ${candidateName}`); - console.error(`šŸ–‡ļø Repository "${candidateName}" already exists.`); + console.error(`Repository "${candidateName}" already exists.`); counter++; } catch (error) { if (error) { @@ -49,7 +55,7 @@ export const isGitHubAuthenticated = (): boolean => { }; export const authenticateGitHub = async (): Promise => { - console.log('šŸ–‡ļø Attempting to authenticate with GitHub...'); + console.log(githubGradient('Attempting to authenticate with GitHub...')); execSync('gh auth login', { stdio: 'inherit' }); @@ -57,10 +63,9 @@ export const authenticateGitHub = async (): Promise => { const isAuthenticated = isGitHubAuthenticated(); if (isAuthenticated) { - console.log('šŸ–‡ļø Authentication was successful.'); return true; } else { - console.error('šŸ–‡ļø Authentication failed after login attempt.'); + console.error('Authentication failed after login attempt.'); return false; } }; @@ -71,14 +76,14 @@ export const fetchGitHubUsername = async (): Promise => { const username = execSync('echo "$(gh api user --jq .login)"', { stdio: 'pipe' }).toString().trim(); if (username) { - console.log(`šŸ–‡ļø Hello \x1b[36m${username}\x1b[0m!`); + console.log(githubGradient(`Hello ${username}!`)); return username; } else { - console.log('šŸ–‡ļø No username returned or an error occurred.'); + console.log(githubGradient('No username returned or an error occurred.')); return null; } } catch (error) { - console.error('šŸ–‡ļø Error fetching GitHub username:', error); + console.error('Error fetching GitHub username:', error); return null; } }; @@ -88,7 +93,7 @@ export const createGitHubRepository = async ( repositoryVisibility: 'public' | 'private', username: string, ): Promise => { - console.log(`šŸ–‡ļø Checking if repository already exists...`); + console.log(githubGradient(`Checking if repository already exists...`)); // Check if the repository exists const repoCheckCommand = `echo "$(gh repo view ${username}/${projectName} --json name)"`; @@ -114,7 +119,7 @@ export const createGitHubRepository = async ( repoName = confirmedName; } - console.log(`šŸ–‡ļø Creating GitHub repository: \x1b[36m${repoName}\x1b[0m`); + console.log(githubGradient(`Creating GitHub repository: ${repoName}`)); const visibility = repositoryVisibility === 'public' ? '--public' : '--private'; const command = `gh repo create ${repoName} ${visibility}`; @@ -122,17 +127,17 @@ export const createGitHubRepository = async ( const result = execSync(command); if (result) { - console.log(`šŸ–‡ļø Repository successfully created at \x1b[36m${result}\x1b[0m`); + console.log(githubGradient(`Repository successfully created at ${result}`)); return repoName; // Return true to indicate success } - console.error('šŸ–‡ļø Failed to create GitHub repository.'); + console.error('Failed to create GitHub repository.'); return; // Return false on failure }; // New function to set up the local Git repository export const setupGitRepository = async (projectName: string, username: string) => { - console.log(`šŸ–‡ļø Setting up Git for the repository...`); + console.log(githubGradient(`Pushing files to repository...`)); // Set the remote origin and push to GitHub const commands = [ @@ -147,7 +152,7 @@ export const setupGitRepository = async (projectName: string, username: string) for (const cmd of commands) { const result = execSync(cmd, { stdio: 'pipe' }); if (!result) { - console.error(`šŸ–‡ļø Failed to execute command: ${cmd}`); + console.error(`Failed to execute command: ${cmd}`); process.exit(1); } } diff --git a/packages/core/utils/payload/install.ts b/packages/core/utils/payload/install.ts index 879626c..88f8d27 100644 --- a/packages/core/utils/payload/install.ts +++ b/packages/core/utils/payload/install.ts @@ -1,13 +1,19 @@ import { execSync } from 'child_process'; import { existsSync } from 'fs'; import { join } from 'path'; +import gradient from 'gradient-string'; import { preparePayloadConfig } from './preparePayloadConfig'; import { prepareTsConfig } from './prepareTsConfig'; import { removeTurboFlag } from './removeTurboFlag'; import { updatePackages } from './updatePackages'; +const payloadGradient = gradient([ + { color: '#12324A', pos: 0 }, + { color: '#E5AA5F', pos: 1 }, +]); + export const preparePayload = async () => { - console.log('šŸ–‡ļø Initializing Payload...'); + console.log(payloadGradient('Initializing Payload...')); process.chdir('./apps/web/'); @@ -15,7 +21,7 @@ export const preparePayload = async () => { updatePackages(); - console.log('šŸ–‡ļø Moving files to (app) directory...'); + console.log(payloadGradient('Moving files to (app) directory...')); execSync( `mkdir -p ./app/\\(app\\) && find ./app -maxdepth 1 ! -path './app' ! -path './app/\\(app\\)' -exec mv {} ./app/\\(app\\)/ \\;`, { @@ -23,7 +29,7 @@ export const preparePayload = async () => { }, ); - console.log('šŸ–‡ļø Installing Payload to Next.js...'); + console.log(payloadGradient('Installing Payload to Next.js...')); execSync(`npx create-payload-app@beta`, { stdio: 'inherit' }); // Payload doesn't work with Turbopack yet @@ -32,7 +38,7 @@ export const preparePayload = async () => { // Check if the payload configuration file exists const payloadConfigPath = join(process.cwd(), 'payload.config.ts'); if (!existsSync(payloadConfigPath)) { - console.error('šŸ–‡ļø Payload installation cancelled/failed.'); + console.error('Payload installation cancelled/failed.'); } else { await preparePayloadConfig(payloadConfigPath); } diff --git a/packages/core/utils/payload/preparePayloadConfig.ts b/packages/core/utils/payload/preparePayloadConfig.ts index 197dea2..b327350 100644 --- a/packages/core/utils/payload/preparePayloadConfig.ts +++ b/packages/core/utils/payload/preparePayloadConfig.ts @@ -1,8 +1,14 @@ import type { PathLike } from 'fs'; import fs from 'fs/promises'; +import gradient from 'gradient-string'; + +const payloadGradient = gradient([ + { color: '#12324A', pos: 0 }, + { color: '#E5AA5F', pos: 1 }, +]); export const preparePayloadConfig = async (configPath: PathLike) => { - console.log('šŸ–‡ļø Preparing payload.config.ts...'); + console.log(payloadGradient('Preparing payload.config.ts...')); try { // Read the payload.config.ts file @@ -20,6 +26,6 @@ export const preparePayloadConfig = async (configPath: PathLike) => { // Write the updated payload.config.ts back to the file await fs.writeFile(configPath, updatedConfig); } catch (err) { - console.error('šŸ–‡ļø Error during processing payload.config.ts', err); + console.error('Error during processing payload.config.ts', err); } }; diff --git a/packages/core/utils/payload/prepareTsConfig.ts b/packages/core/utils/payload/prepareTsConfig.ts index 154cce6..ac4f59c 100644 --- a/packages/core/utils/payload/prepareTsConfig.ts +++ b/packages/core/utils/payload/prepareTsConfig.ts @@ -1,8 +1,14 @@ import fs from 'fs'; import path from 'path'; +import gradient from 'gradient-string'; + +const payloadGradient = gradient([ + { color: '#12324A', pos: 0 }, + { color: '#E5AA5F', pos: 1 }, +]); export const prepareTsConfig = () => { - console.log('šŸ–‡ļø Preparing tsconfig.json...'); + console.log(payloadGradient('Preparing tsconfig.json...')); // Path to your tsconfig.json file const tsconfigPath = path.join(process.cwd(), 'tsconfig.json'); @@ -10,7 +16,7 @@ export const prepareTsConfig = () => { // Read the tsconfig.json file fs.readFile(tsconfigPath, 'utf8', (err, data) => { if (err) { - console.error('šŸ–‡ļø Error reading tsconfig.json', err); + console.error('Error reading tsconfig.json', err); return; } @@ -33,7 +39,7 @@ export const prepareTsConfig = () => { // Write the updated tsconfig.json back to the file fs.writeFile(tsconfigPath, JSON.stringify(tsconfig, null, 2), (err) => { if (err) { - console.error('šŸ–‡ļø Error writing to tsconfig.json', err); + console.error('Error writing to tsconfig.json', err); } }); }); diff --git a/packages/core/utils/payload/removeTurboFlag.ts b/packages/core/utils/payload/removeTurboFlag.ts index 29c98b1..c21ace2 100644 --- a/packages/core/utils/payload/removeTurboFlag.ts +++ b/packages/core/utils/payload/removeTurboFlag.ts @@ -1,8 +1,14 @@ import fs from 'fs'; import path from 'path'; +import gradient from 'gradient-string'; + +const payloadGradient = gradient([ + { color: '#12324A', pos: 0 }, + { color: '#E5AA5F', pos: 1 }, +]); export const removeTurboFlag = () => { - console.log('šŸ–‡ļø Removing --turbo flag from dev script...'); + console.log(payloadGradient('Removing --turbo flag from dev script...')); // Path to your package.json file const packageJsonPath = path.join(process.cwd(), 'package.json'); @@ -10,7 +16,7 @@ export const removeTurboFlag = () => { // Read the package.json file fs.readFile(packageJsonPath, 'utf8', (err: Error | null, data: string) => { if (err) { - console.error('šŸ–‡ļø Error reading package.json', err); + console.error('Error reading package.json', err); return; } @@ -25,7 +31,7 @@ export const removeTurboFlag = () => { // Write the updated package.json back to the file fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2), (err: Error | null) => { if (err) { - console.error('šŸ–‡ļø Error writing to package.json', err); + console.error('Error writing to package.json', err); } }); }); diff --git a/packages/core/utils/payload/updatePackages.ts b/packages/core/utils/payload/updatePackages.ts index 5f52146..99f1b5e 100644 --- a/packages/core/utils/payload/updatePackages.ts +++ b/packages/core/utils/payload/updatePackages.ts @@ -1,13 +1,19 @@ import { execSync } from 'child_process'; +import gradient from 'gradient-string'; + +const payloadGradient = gradient([ + { color: '#12324A', pos: 0 }, + { color: '#E5AA5F', pos: 1 }, +]); export const updatePackages = () => { - console.log('šŸ–‡ļø Updating Next and React to their respective release candidates...'); - execSync(`pnpm up next@rc react@rc react-dom@rc eslint-config-next@rc`, { + console.log(payloadGradient('Updating Next and React to their respective release candidates...')); + execSync(`pnpm up next@rc react@rc react-dom@rc eslint-config-next@rc --reporter silent`, { stdio: 'inherit', }); - console.log('šŸ–‡ļø Installing necessary packages...'); - execSync(`pnpm i pg sharp`, { + console.log(payloadGradient('Installing necessary packages...')); + execSync(`pnpm i pg sharp --reporter silent`, { stdio: 'inherit', }); }; diff --git a/packages/core/utils/prettier/prettify.ts b/packages/core/utils/prettier/prettify.ts index f2d5ebf..c948d83 100644 --- a/packages/core/utils/prettier/prettify.ts +++ b/packages/core/utils/prettier/prettify.ts @@ -1,7 +1,12 @@ import { execSync } from 'child_process'; +import gradient from 'gradient-string'; +const prettifyGradient = gradient([ + { color: '#F11D28', pos: 0 }, + { color: '#FFA12C', pos: 1 }, +]); export const prettify = async () => { - console.log('šŸ–‡ļø Prettifying your Stapler...'); + console.log(prettifyGradient('Prettifying...')); const ignorePatterns = [ 'node_modules/', diff --git a/packages/core/utils/shared/continueOnKeypress.ts b/packages/core/utils/shared/continueOnKeypress.ts index dbe069c..9f5d36f 100644 --- a/packages/core/utils/shared/continueOnKeypress.ts +++ b/packages/core/utils/shared/continueOnKeypress.ts @@ -1,7 +1,13 @@ import * as readline from 'readline'; +import gradient from 'gradient-string'; + +const supabaseGradient = gradient([ + { color: '#3ABC82', pos: 0 }, + { color: '#259764', pos: 1 }, +]); export const continueOnAnyKeypress = async (message: string): Promise => { - console.log(message); + console.log(supabaseGradient(message)); const rl = readline.createInterface({ input: process.stdin, diff --git a/packages/core/utils/shared/updateEnvFile.ts b/packages/core/utils/shared/updateEnvFile.ts index e6e3140..19e6947 100644 --- a/packages/core/utils/shared/updateEnvFile.ts +++ b/packages/core/utils/shared/updateEnvFile.ts @@ -45,7 +45,7 @@ export const updateEnvFile = async ({ currentDir, pairs }: EnvUpdateConfig): Pro const updatedContent = lines.join('\n'); await writeFile(envFilePath, updatedContent, 'utf8'); } catch (error) { - console.error('šŸ–‡ļø Error updating .env file:', error); + console.error('Error updating .env file:', error); throw error; // Re-throw the error for the caller to handle } }; diff --git a/packages/core/utils/supabase/connectProject.ts b/packages/core/utils/supabase/connectProject.ts index 4998254..65178d4 100644 --- a/packages/core/utils/supabase/connectProject.ts +++ b/packages/core/utils/supabase/connectProject.ts @@ -1,25 +1,22 @@ import { exec, execSync } from 'child_process'; import inquirer from 'inquirer'; +import { promisify } from 'util'; +import chalk from 'chalk'; +import gradient from 'gradient-string'; import { continueOnAnyKeypress } from '../shared/continueOnKeypress'; import { updateEnvFile } from '../shared/updateEnvFile'; import { getSupabaseKeys, parseProjectsList } from './utils'; -import { promisify } from 'util'; const execAsync = promisify(exec); -const instructions = [ - '\n=== Instructions for Supabase Integration with GitHub and Vercel ===', - 'šŸ–‡ļø 1. You will be redirected to your Supabase project dashboard', - 'šŸ–‡ļø 2. Find the "GitHub" section and click "Connect".', - ' - Follow the prompts to connect Supabase with your GitHub repository.', - 'šŸ–‡ļø 3. Then, find the "Vercel" section and click "Connect".', - ' - Follow the prompts to connect Supabase with your Vercel project.', - '\n šŸ–‡ļø Please note that these steps require manual configuration in the Supabase interface.\n', -]; +const supabaseGradient = gradient([ + { color: '#3ABC82', pos: 0 }, + { color: '#259764', pos: 1 }, +]); export const connectSupabaseProject = async (projectName: string, currentDir: string) => { try { - console.log('šŸ–‡ļø Getting information about newly created Supabase project...'); + console.log(supabaseGradient('Getting information about newly created Supabase project...')); const { stdout: projectsList } = await execAsync('npx supabase projects list'); const projects = parseProjectsList(projectsList); const newProject = projects.find((project) => project.name === projectName); @@ -30,7 +27,7 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st ); } - console.log('šŸ–‡ļø Getting Supabase project keys...'); + console.log(supabaseGradient('Getting Supabase project keys...')); const { stdout: projectAPIKeys } = await execAsync( `npx supabase projects api-keys --project-ref ${newProject.refId}`, ); @@ -43,7 +40,7 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st const SUPABASE_URL = `https://${newProject.refId}.supabase.co/`; - console.log(`šŸ–‡ļø Saving keys to .env...`); + console.log(supabaseGradient(`Saving keys to .env...`)); await updateEnvFile({ currentDir, pairs: [ @@ -53,14 +50,20 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st ], }); - console.log('šŸ–‡ļø Linking Supabase project...'); + console.log(supabaseGradient('Linking Supabase project...')); execSync(`npx supabase link --project-ref ${newProject.refId}`, { stdio: 'inherit' }); - for (const instruction of instructions) { - console.log(instruction); - } + console.log( + chalk.bold(supabaseGradient('=== Instructions for Supabase Integration with GitHub and Vercel ===')), + supabaseGradient('\n1. You will be redirected to your Supabase project dashboard'), + supabaseGradient('\n2. Find the "GitHub" section and click "Connect".'), + supabaseGradient('\n - Follow the prompts to connect Supabase with your GitHub repository.'), + supabaseGradient('\n3. Then, find the "Vercel" section and click "Connect".'), + supabaseGradient('\n - Follow the prompts to connect Supabase with your Vercel project.'), + chalk.italic(supabaseGradient('\nNOTE: These steps require manual configuration in the Supabase interface.')), + ); - await continueOnAnyKeypress('šŸ–‡ļø When you are ready to be redirected to the Supabase page press any key'); + await continueOnAnyKeypress('When you are ready to be redirected to the Supabase page press any key'); await execAsync(`open https://supabase.com/dashboard/project/${newProject.refId}/settings/integrations`); const { isIntegrationReady } = await inquirer.prompt([ @@ -74,13 +77,15 @@ export const connectSupabaseProject = async (projectName: string, currentDir: st if (!isIntegrationReady) { console.log( - `šŸ–‡ļø You can access your project dashboard at: https://supabase.com/dashboard/project/${newProject.refId}/settings/integrations`, + supabaseGradient( + `You can access your project dashboard at: https://supabase.com/dashboard/project/${newProject.refId}/settings/integrations`, + ), ); process.exit(1); } } catch (error) { const errorMessage = error instanceof Error ? error.message : 'An unknown error occurred'; - console.error('šŸ–‡ļø Error connecting Supabase project:', errorMessage); + console.error('Error connecting Supabase project:', errorMessage); throw error; } }; diff --git a/packages/core/utils/supabase/createProject.ts b/packages/core/utils/supabase/createProject.ts index 93eac7e..4c85dba 100644 --- a/packages/core/utils/supabase/createProject.ts +++ b/packages/core/utils/supabase/createProject.ts @@ -1,7 +1,13 @@ import { execSync } from 'child_process'; +import gradient from 'gradient-string'; + +const supabaseGradient = gradient([ + { color: '#3ABC82', pos: 0 }, + { color: '#259764', pos: 1 }, +]); export const createSupabaseProject = async (name: string) => { - console.log('šŸ–‡ļø Creating Supabase project...'); + console.log(supabaseGradient('Creating Supabase project...')); execSync(`npx supabase projects create ${name}`, { stdio: 'inherit', diff --git a/packages/core/utils/supabase/install.ts b/packages/core/utils/supabase/install.ts index 2962aa2..b189019 100644 --- a/packages/core/utils/supabase/install.ts +++ b/packages/core/utils/supabase/install.ts @@ -1,42 +1,50 @@ import { execSync } from 'child_process'; import fs from 'fs'; import path from 'path'; +import gradient from 'gradient-string'; import { supabaseFiles } from '../../templates/supabase/installConfig'; import { templateGenerator } from '../generator/generator'; import { getTemplateDirectory } from '../shared/getTemplateDirectory'; +const supabaseGradient = gradient([ + { color: '#3ABC82', pos: 0 }, + { color: '#259764', pos: 1 }, +]); + const supabaseLogin = () => { - console.log('šŸ–‡ļø Logging into Supabase...'); + console.log(supabaseGradient('Logging into Supabase...')); try { execSync('npx supabase projects list', { stdio: 'ignore' }); - console.log('šŸ–‡ļø Already logged into Supabase. Skipping login.'); + console.log(supabaseGradient('Already logged into Supabase.')); return; } catch (error) { try { execSync('npx supabase login', { stdio: 'inherit' }); } catch { - console.error('\nšŸ–‡ļø Failed to log in to Supabase.'); - console.log('\nšŸ–‡ļø Please log in manually with "supabase login" and re-run "create-stapler-app".'); + console.error('Failed to log in to Supabase.'); + console.log(supabaseGradient('\nPlease log in manually with "supabase login" and re-run "create-stapler-app".')); process.exit(1); } } }; const initializeSupabaseProject = (): void => { - console.log('šŸ–‡ļø Initialize Supabase project...'); + console.log(supabaseGradient('Initialize Supabase project...')); try { execSync(`npx supabase init`, { stdio: ['pipe'], encoding: 'utf-8' }); } catch (error: any) { const errorMessage = error.stderr; if (errorMessage.includes('file exists')) { - console.log('\nšŸ–‡ļø Supabase configuration file already exists. Skipping re-initialization.'); + console.log(supabaseGradient('Supabase configuration file already exists.')); return; } else { - console.error('\nšŸ–‡ļø Failed to initialize Supabase project with "supabase init".'); + console.error('Failed to initialize Supabase project with "supabase init".'); console.log( - '\nšŸ–‡ļø Please review the error message below, follow the initialization instructions, and try running "create-stapler-app" again.', + supabaseGradient( + '\nPlease review the error message below, follow the initialization instructions, and try running "create-stapler-app" again.', + ), ); process.exit(1); } @@ -44,17 +52,16 @@ const initializeSupabaseProject = (): void => { }; export const installSupabase = async (destinationDirectory: string) => { - console.log('šŸ–‡ļø Installing supabase-js...'); + console.log(supabaseGradient('Installing supabase-js...')); try { supabaseLogin(); initializeSupabaseProject(); } catch (error) { - console.error('\nšŸ–‡ļø Failed to init Supabase project.'); - console.error(`šŸ–‡ļø Error: ${error}`); + console.error('Failed to init Supabase project.', `\nError: ${error}`); process.exit(1); } - console.log('šŸ–‡ļø Adding Supabase Files...'); + console.log(supabaseGradient('Adding Supabase Files...')); const templateDirectory = getTemplateDirectory(`/templates/supabase/files/`); @@ -72,9 +79,9 @@ export const installSupabase = async (destinationDirectory: string) => { process.chdir('supabase'); - console.log('šŸ–‡ļø Installing Supabase dependencies...'); + console.log(supabaseGradient('Installing Supabase dependencies...')); - execSync('pnpm install', { stdio: 'inherit' }); + execSync('pnpm i --reporter silent', { stdio: 'inherit' }); process.chdir('..'); }; diff --git a/packages/core/utils/turbo/create.ts b/packages/core/utils/turbo/create.ts index 4f85391..e9fdcd3 100644 --- a/packages/core/utils/turbo/create.ts +++ b/packages/core/utils/turbo/create.ts @@ -1,6 +1,13 @@ import { execSync } from 'child_process'; +import gradient from 'gradient-string'; + +const turborepoGradient = gradient([ + { color: '#0099F7', pos: 0 }, + { color: '#F11712', pos: 1 }, +]); export const createTurboRepo = async (name: string) => { + console.log(turborepoGradient('Creating Turborepo...')); execSync(`npx create-turbo@latest ${name} -m pnpm`, { stdio: 'inherit', }); diff --git a/packages/core/utils/vercel/connectWithGH.ts b/packages/core/utils/vercel/connectWithGH.ts index 32b817e..331d9a0 100644 --- a/packages/core/utils/vercel/connectWithGH.ts +++ b/packages/core/utils/vercel/connectWithGH.ts @@ -1,10 +1,11 @@ import { execSync } from 'child_process'; +import chalk from 'chalk'; import { continueOnAnyKeypress } from '../shared/continueOnKeypress'; const MAX_RETRIES = 3; export const connectWithGH = async () => { - console.log('šŸ–‡ļø Connecting with GitHub repository...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Connecting with GitHub repository...')); for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) { try { @@ -22,21 +23,27 @@ export const connectWithGH = async () => { if (noConnectionError) { if (attempt === MAX_RETRIES) { - console.log("\nšŸ–‡ļø Hmm, we've tried connecting a few times but no luck."); - console.log("\nšŸ–‡ļø Let's try to set this up manually:"); - console.log('šŸ–‡ļø 1ļøāƒ£ Visit \x1b[36mhttps://vercel.com/account/login-connections\x1b[0m'); - console.log('šŸ–‡ļø 2ļøāƒ£ Click on "GitHub" and complete the authorization'); - console.log('šŸ–‡ļø 3ļøāƒ£ Once done, run \x1b[36mcvercel git connect\x1b\n'); + console.log( + chalk.bgBlack.hex('#FFF')( + "ā–² Hmm, we've tried connecting a few times but no luck.", + "\n\n ā–² Let's try to set this up manually:", + '\n ā–² 1ļøāƒ£ Visit \x1b[36mhttps://vercel.com/account/login-connections\x1b[0m', + '\n ā–² 2ļøāƒ£ Click on "GitHub" and complete the authorization', + '\n ā–² 3ļøāƒ£ Once done, run \x1b[36mcvercel git connect\x1b\n', + ), + ); } else { - console.log(`\nšŸ–‡ļø šŸ”„ Attempt ${attempt} of ${MAX_RETRIES}`); - console.log("\nšŸ–‡ļø It seems you haven't connected your GitHub login with Vercel yet. šŸ¤”"); console.log( - 'šŸ–‡ļø No worries though! Just head over to \x1b[36mhttps://vercel.com/account/login-connections\x1b[0m$', + chalk.bgBlack.hex('#FFF')( + `ā–² šŸ”„ Attempt ${attempt} of ${MAX_RETRIES}`, + "\n\nā–² It seems you haven't connected your GitHub login with Vercel yet. šŸ¤”", + '\nā–² No worries though! Just head over to \x1b[36mhttps://vercel.com/account/login-connections\x1b[0m$', + '\nā–² and click that "GitHub" button.', + ), ); - console.log('šŸ–‡ļø and click that "GitHub" button.'); } - await continueOnAnyKeypress("šŸ–‡ļø Once you've done that press any key"); + await continueOnAnyKeypress("ā–² Once you've done that press any key"); } } } diff --git a/packages/core/utils/vercel/deploy.ts b/packages/core/utils/vercel/deploy.ts index de1c68e..0e7eec6 100644 --- a/packages/core/utils/vercel/deploy.ts +++ b/packages/core/utils/vercel/deploy.ts @@ -1,16 +1,18 @@ +import fs from 'fs/promises'; +import chalk from 'chalk'; import { connectWithGH } from './connectWithGH'; import { getDeploymentUrl } from './utils/getDeploymentUrl'; -import fs from 'fs/promises'; export const deployVercelProject = async () => { try { await connectWithGH(); } catch (error) { - console.log('šŸ–‡ļø An unexpected error occurred:', error); - console.log('\nšŸ–‡ļø Failed to connect GitHub with Vercel'); + console.log( + chalk.bgBlack.hex('#FFF')('ā–² An unexpected error occurred:', error, '\nā–² Failed to connect GitHub with Vercel'), + ); } - console.log('šŸ–‡ļø Creating vercel.json...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Creating vercel.json...')); const vercelConfig = { buildCommand: 'pnpm build', @@ -19,13 +21,15 @@ export const deployVercelProject = async () => { await fs.writeFile('vercel.json', JSON.stringify(vercelConfig, null, 2)); - console.log('šŸ–‡ļø Creating production deployment...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Creating production deployment...')); const productionUrl = getDeploymentUrl(true); - console.log('šŸ–‡ļø Creating preview deployment...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Creating preview deployment...')); const previewUrl = getDeploymentUrl(false); - console.log(`šŸ–‡ļø You can access your preview deployment at: \x1b[36m${previewUrl}\x1b[0m`); + console.log(chalk.bgBlack.hex('#FFF')(`ā–² You can access your preview deployment at: \x1b[36m${previewUrl}\x1b[0m`)); - console.log(`šŸ–‡ļø You can access your production deployment at: \x1b[36m${productionUrl}\x1b[0m`); + console.log( + chalk.bgBlack.hex('#FFF')(`ā–² You can access your production deployment at: \x1b[36m${productionUrl}\x1b[0m`), + ); }; diff --git a/packages/core/utils/vercel/setupAndCreate.ts b/packages/core/utils/vercel/setupAndCreate.ts index 7721b6c..b61895f 100644 --- a/packages/core/utils/vercel/setupAndCreate.ts +++ b/packages/core/utils/vercel/setupAndCreate.ts @@ -1,4 +1,5 @@ import { execSync } from 'child_process'; +import chalk from 'chalk'; const getUserName = (): string | null => { try { @@ -13,30 +14,36 @@ export const setupAndCreateVercelProject = async () => { const vercelUserName = getUserName(); if (!vercelUserName) { - console.log('šŸ–‡ļø Logging in to Vercel...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Logging in to Vercel...')); try { execSync('npx vercel login', { stdio: 'inherit' }); } catch (error) { - console.log('\nšŸ–‡ļø Oops! Something went wrong while logging in to Vercel...'); - console.log('šŸ–‡ļø You might already be logged in with this email in another project.'); console.log( - 'šŸ–‡ļø In this case, select "Continue with Email" and enter the email you\'re already logged in with.\n', + chalk.bgBlack.hex('#FFF')( + 'ā–² Oops! Something went wrong while logging in to Vercel...', + '\nā–² You might already be logged in with this email in another project.', + '\nā–² In this case, select "Continue with Email" and enter the email you\'re already logged in with.\n', + ), ); try { execSync('npx vercel login', { stdio: 'inherit' }); } catch { - console.log('\nšŸ–‡ļø Please check the error above and try again.'); - console.log('šŸ–‡ļø After successfully logging in with "vercel login", please run create-stapler-app again.\n'); + console.log( + chalk.bgBlack.hex('#FFF')( + 'ā–² Please check the error above and try again.', + '\nā–² After successfully logging in with "vercel login", please run create-stapler-app again.\n', + ), + ); process.exit(1); } } } else { - console.log(`šŸ–‡ļø You are logged to Vercel as \x1b[36m${vercelUserName}\x1b[0m`); + console.log(chalk.bgBlack.hex('#FFF')(`ā–² You are logged to Vercel as \x1b[36m${vercelUserName}\x1b[0m`)); } - console.log('šŸ–‡ļø Initializing Vercel project...'); + console.log(chalk.bgBlack.hex('#FFF')('ā–² Initializing Vercel project...')); execSync('npx vercel init'); - console.log('šŸ–‡ļø Linking Vercel project...'); + console.log(chalk.bgBlack.hex('#FFF')('\nā–² Linking Vercel project...')); execSync('npx vercel link', { stdio: 'inherit' }); }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c189353..ab05037 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -124,9 +124,15 @@ importers: packages/core: dependencies: + chalk: + specifier: ^5.3.0 + version: 5.3.0 fs-extra: specifier: ^11.2.0 version: 11.2.0 + gradient-string: + specifier: ^3.0.0 + version: 3.0.0 inquirer: specifier: ^10.2.2 version: 10.2.2