ATlast — you'll never need to find your favorites on another platform again. Find your favs in the ATmosphere.
atproto
1import * as esbuild from 'esbuild'; 2import * as fs from 'fs'; 3import * as path from 'path'; 4import { fileURLToPath } from 'url'; 5import postcss from 'postcss'; 6import tailwindcss from 'tailwindcss'; 7import autoprefixer from 'autoprefixer'; 8 9const __dirname = path.dirname(fileURLToPath(import.meta.url)); 10 11const watch = process.argv.includes('--watch'); 12const isProd = process.argv.includes('--prod') || process.env.NODE_ENV === 'production'; 13const mode = isProd ? 'production' : 'development'; 14 15// Environment-specific configuration 16const ATLAST_API_URL = mode === 'production' 17 ? 'https://atlast.byarielm.fyi' 18 : 'http://127.0.0.1:8888'; 19 20console.log(`🌍 Building for ${mode} mode`); 21console.log(`🔗 API URL: ${ATLAST_API_URL}`); 22 23// Clean dist directory 24const distDir = path.join(__dirname, 'dist', 'chrome'); 25if (fs.existsSync(distDir)) { 26 fs.rmSync(distDir, { recursive: true }); 27} 28fs.mkdirSync(distDir, { recursive: true }); 29 30// Build configuration base 31const buildConfigBase = { 32 bundle: true, 33 minify: !watch, 34 sourcemap: watch ? 'inline' : false, 35 target: 'es2020', 36 format: 'esm', 37 define: { 38 '__ATLAST_API_URL__': JSON.stringify(ATLAST_API_URL), 39 '__BUILD_MODE__': JSON.stringify(mode), 40 }, 41}; 42 43// Build scripts 44const scripts = [ 45 { 46 ...buildConfigBase, 47 entryPoints: ['src/content/index.ts'], 48 outfile: path.join(distDir, 'content', 'index.js'), 49 }, 50 { 51 ...buildConfigBase, 52 entryPoints: ['src/background/service-worker.ts'], 53 outfile: path.join(distDir, 'background', 'service-worker.js'), 54 }, 55 { 56 ...buildConfigBase, 57 entryPoints: ['src/popup/popup.ts'], 58 outfile: path.join(distDir, 'popup', 'popup.js'), 59 }, 60]; 61 62// Build function 63async function build() { 64 try { 65 console.log('🔨 Building extension...'); 66 67 // Build all scripts 68 for (const config of scripts) { 69 if (watch) { 70 const ctx = await esbuild.context(config); 71 await ctx.watch(); 72 console.log(`👀 Watching ${path.basename(config.entryPoints[0])}...`); 73 } else { 74 await esbuild.build(config); 75 console.log(`✅ Built ${path.basename(config.entryPoints[0])}`); 76 } 77 } 78 79 // Copy static files 80 copyStaticFiles(); 81 82 // Process CSS with Tailwind 83 await processCSS(); 84 85 if (!watch) { 86 console.log('✨ Build complete!'); 87 } 88 } catch (error) { 89 console.error('❌ Build failed:', error); 90 process.exit(1); 91 } 92} 93 94// Process CSS with PostCSS (Tailwind + Autoprefixer) 95async function processCSS() { 96 const cssPath = path.join(__dirname, 'src/popup/popup.css'); 97 const outputPath = path.join(distDir, 'popup/popup.css'); 98 99 const css = fs.readFileSync(cssPath, 'utf8'); 100 101 // Import cssnano dynamically for production minification 102 const plugins = [tailwindcss, autoprefixer]; 103 if (isProd) { 104 const cssnano = (await import('cssnano')).default; 105 plugins.push(cssnano); 106 } 107 108 const result = await postcss(plugins).process(css, { 109 from: cssPath, 110 to: outputPath, 111 }); 112 113 // Create directory if it doesn't exist 114 const destDir = path.dirname(outputPath); 115 if (!fs.existsSync(destDir)) { 116 fs.mkdirSync(destDir, { recursive: true }); 117 } 118 119 fs.writeFileSync(outputPath, result.css); 120 console.log('🎨 Processed CSS with Tailwind'); 121} 122 123// Copy static files 124function copyStaticFiles() { 125 const filesToCopy = [ 126 { from: 'manifest.json', to: 'manifest.json' }, 127 { from: 'src/popup/popup.html', to: 'popup/popup.html' }, 128 ]; 129 130 for (const file of filesToCopy) { 131 const srcPath = path.join(__dirname, file.from); 132 const destPath = path.join(distDir, file.to); 133 134 // Create directory if it doesn't exist 135 const destDir = path.dirname(destPath); 136 if (!fs.existsSync(destDir)) { 137 fs.mkdirSync(destDir, { recursive: true }); 138 } 139 140 fs.copyFileSync(srcPath, destPath); 141 } 142 143 // Create placeholder icons (TODO: replace with actual icons) 144 const assetsDir = path.join(distDir, 'assets'); 145 if (!fs.existsSync(assetsDir)) { 146 fs.mkdirSync(assetsDir, { recursive: true }); 147 } 148 149 // Create simple text files as placeholder icons 150 const sizes = [16, 48, 128]; 151 for (const size of sizes) { 152 const iconPath = path.join(assetsDir, `icon-${size}.png`); 153 if (!fs.existsSync(iconPath)) { 154 // TODO: Generate actual PNG icons 155 fs.writeFileSync(iconPath, `Placeholder ${size}x${size} icon`); 156 } 157 } 158 159 console.log('📋 Copied static files'); 160} 161 162// Run build 163build();