UNPKG

@monitoro/herd

Version:

Automate your browser, build AI web tools and MCP servers with Monitoro Herd

134 lines (133 loc) 5.11 kB
import { fileURLToPath } from 'url'; import { dirname, join, relative } from 'path'; import * as fs from 'fs'; import * as esbuild from 'esbuild'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); export async function buildTrail(trailPath, options = {}) { const { outDir = join(trailPath, '.build'), format = 'esm', platform = 'node', target = 'node18', silent = false, minify = true, treeShaking = true } = options; // Ensure trailPath is absolute trailPath = fs.realpathSync(trailPath); // Create build directory if it doesn't exist if (!fs.existsSync(outDir)) { fs.mkdirSync(outDir, { recursive: true }); } // Common build options const commonOptions = { format, platform, target, bundle: true, sourcemap: true, outdir: outDir, external: ['@monitoro/herd'], define: { 'process.env.NODE_ENV': '"production"' }, logLevel: silent ? 'silent' : 'info', color: true, minify, minifyWhitespace: minify, minifyIdentifiers: minify, minifySyntax: minify, treeShaking, legalComments: 'none', ignoreAnnotations: false, }; // Build each file const files = ['actions.ts', 'urls.ts', 'selectors.ts']; const buildPromises = files.map(async (file) => { const entryPoint = join(trailPath, file); if (!fs.existsSync(entryPoint)) { if (!silent) { console.warn(`⚠️ Warning: ${file} not found in trail directory`); } return; } try { // Get source file size for comparison const sourceStats = fs.statSync(entryPoint); const sourceSize = sourceStats.size; await esbuild.build({ ...commonOptions, entryPoints: [entryPoint], outdir: outDir }); // Get built file size const outputFile = join(outDir, file.replace('.ts', '.js')); if (fs.existsSync(outputFile)) { const outputStats = fs.statSync(outputFile); const outputSize = outputStats.size; const reductionPercent = sourceSize > 0 ? Math.round((1 - (outputSize / sourceSize)) * 100) : 0; if (!silent) { console.log(`✨ Built ${relative(trailPath, entryPoint)} (${formatFileSize(sourceSize)}${formatFileSize(outputSize)}, ${reductionPercent > 0 ? '-' : '+'}${Math.abs(reductionPercent)}%)`); } } else { if (!silent) { console.log(`✨ Built ${relative(trailPath, entryPoint)}`); } } } catch (error) { if (!silent) { console.error(`❌ Failed to build ${relative(trailPath, entryPoint)}:`, error); } throw error; } }); await Promise.all(buildPromises); // Process package.json if it exists const packageJsonPath = join(trailPath, 'package.json'); if (fs.existsSync(packageJsonPath)) { try { // Read and parse the existing package.json const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf8'); const packageJson = JSON.parse(packageJsonContent); // Ensure type module is set packageJson.type = "module"; // Write the modified package.json to the output directory fs.writeFileSync(join(outDir, 'package.json'), JSON.stringify(packageJson, null, 2)); if (!silent) { console.log(`✨ Processed package.json (ensured type: module is set)`); } } catch (error) { if (!silent) { console.error(`⚠️ Warning: Failed to process package.json:`, error); // Fall back to direct copy if parsing fails fs.copyFileSync(packageJsonPath, join(outDir, 'package.json')); console.log(`✨ Copied package.json (fallback)`); } } } return outDir; } export function getBuiltTrailPath(trailPath) { // Ensure trailPath is absolute trailPath = fs.realpathSync(trailPath); return join(trailPath, '.build'); } export function isTrailBuilt(trailPath) { // Ensure trailPath is absolute trailPath = fs.realpathSync(trailPath); const builtPath = getBuiltTrailPath(trailPath); return fs.existsSync(builtPath) && fs.existsSync(join(builtPath, 'actions.js')) && fs.existsSync(join(builtPath, 'urls.js')) && fs.existsSync(join(builtPath, 'selectors.js')); } // Helper function to format file size in a human-readable format function formatFileSize(bytes) { if (bytes < 1024) { return `${bytes} B`; } else if (bytes < 1024 * 1024) { return `${(bytes / 1024).toFixed(1)} KB`; } else { return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } }