// ... imports import { copyFileSync, mkdirSync, existsSync, rmSync, writeFileSync, readFileSync, readdirSync, statSync } from 'fs'; import { execSync } from 'child_process'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const rootDir = join(__dirname, '..'); const serverDir = join(rootDir, 'server'); const androidAssetsDir = join(rootDir, 'android', 'app', 'src', 'main', 'assets', 'nodejs-v3'); const distNodejsDir = join(rootDir, 'dist', 'nodejs-v3'); function copyServerToAndroid() { console.log('Starting Bundle & Copy Process...'); try { // 1. Ensure dist directory exists if (!existsSync(distNodejsDir)) { mkdirSync(distNodejsDir, { recursive: true }); } // 2. Run the bundle script console.log('Bundling server with esbuild...'); execSync('node bundle.js', { cwd: serverDir, stdio: 'inherit' }); // 3. Prepare Android assets directory console.log(`Preparing Android assets: ${androidAssetsDir}`); if (existsSync(androidAssetsDir)) { // Clean up previous install to ensure no stale files rmSync(androidAssetsDir, { recursive: true, force: true }); } mkdirSync(androidAssetsDir, { recursive: true }); // 4. Copy the bundled index.js const bundledFile = join(distNodejsDir, 'index.js'); if (existsSync(bundledFile)) { console.log('Copying bundled index.js to Android assets...'); copyFileSync(bundledFile, join(androidAssetsDir, 'index.js')); } else { throw new Error('Bundled file not found! Bundling must have failed.'); } // 5. Copy package.json (still good to have for versioning/metadata) // We modify it to point to index.js as main if it doesn't already const serverPackageJson = join(serverDir, 'package.json'); if (existsSync(serverPackageJson)) { console.log('Copying package.json to Android assets...'); // We don't really need to parse/edit it if the bundle is index.js and the plugin defaults to it, // but it's cleaner to ensure 'main' is 'index.js'. const pkg = JSON.parse(readFileSync(serverPackageJson, 'utf8')); pkg.main = 'index.js'; writeFileSync(join(androidAssetsDir, 'package.json'), JSON.stringify(pkg, null, 2)); // Also copy to dist for reference writeFileSync(join(distNodejsDir, 'package.json'), JSON.stringify(pkg, null, 2)); } // 6. Handle builtin_modules (Capacitor requirement) const pluginBuiltinModules = join(rootDir, 'node_modules', 'capacitor-nodejs', 'android', 'src', 'main', 'assets', 'builtin_modules'); const androidBuiltinModules = join(rootDir, 'android', 'app', 'src', 'main', 'assets', 'builtin_modules'); if (!existsSync(dirname(androidBuiltinModules))) { mkdirSync(dirname(androidBuiltinModules), { recursive: true }); } if (existsSync(androidBuiltinModules)) { rmSync(androidBuiltinModules, { recursive: true, force: true }); } if (existsSync(pluginBuiltinModules)) { console.log('Copying builtin_modules...'); // Simple recursive copy for builtin_modules const copyRecursive = (src, dest) => { const stats = statSync(src); if (stats.isDirectory()) { mkdirSync(dest, { recursive: true }); readdirSync(src).forEach(child => { copyRecursive(join(src, child), join(dest, child)); }); } else { copyFileSync(src, dest); } }; copyRecursive(pluginBuiltinModules, androidBuiltinModules); } else { mkdirSync(androidBuiltinModules, { recursive: true }); writeFileSync(join(androidBuiltinModules, 'README.txt'), 'Placeholder for builtin_modules'); } console.log('✓ Server bundled and copied successfully to android/assets/nodejs-v3'); console.log(' NOTE: node_modules were explicitely SKIPPED because we are using a bundle.'); } catch (error) { console.error('✗ Error:', error); process.exit(1); } } copyServerToAndroid();