UNPKG

@hcaptcha/react-native-hcaptcha

Version:

hCaptcha Library for React Native (both Android and iOS)

122 lines (103 loc) 4.69 kB
#!/usr/bin/env node const { execSync } = require('child_process'); const { platform: osPlatform } = require('os'); const fs = require('fs'); const path = require('path'); const ROOT = path.resolve(__dirname, '..'); const HOST_DIR = path.join(ROOT, '__e2e__', 'host'); const E2E_DIR = path.join(ROOT, '__e2e__'); const pm = process.argv.includes('--pm') ? process.argv[process.argv.indexOf('--pm') + 1] : 'npm'; const targetPlatform = process.argv.includes('--platform') ? process.argv[process.argv.indexOf('--platform') + 1] : null; if (fs.existsSync(HOST_DIR)) { console.log('Cleaning previous host app...'); fs.rmSync(HOST_DIR, { recursive: true, force: true }); } // 1. Scaffold the host app WITHOUT building native code console.log('Generating host app at __e2e__/host/ ...'); execSync( `node __scripts__/generate-example.js --path __e2e__/host --pm ${pm} --skip-build`, { stdio: 'inherit', cwd: ROOT }, ); const hostTestsDir = path.join(HOST_DIR, '__tests__'); if (fs.existsSync(hostTestsDir)) { fs.rmSync(hostTestsDir, { recursive: true, force: true }); } // 2. Install react-native-harness (must happen BEFORE native build so // HarnessUI TurboModule is compiled into the binary) console.log('Installing react-native-harness in host app...'); const harnessPkgs = [ 'react-native-harness', '@react-native-harness/platform-android', '@react-native-harness/platform-apple', '@react-native-harness/ui', ].join(' '); if (pm === 'yarn') { execSync(`yarn add --dev ${harnessPkgs}`, { stdio: 'inherit', cwd: HOST_DIR }); } else { execSync(`npm i --save-dev ${harnessPkgs}`, { stdio: 'inherit', cwd: HOST_DIR }); } // Patch @react-native-harness/ui codegenConfig: the published package is // missing ios.modulesProvider, so RN's codegen never registers HarnessUI in // RCTModuleProviders.mm and the TurboModule can't be found at runtime on iOS. const harnessUiPkgPath = path.join(HOST_DIR, 'node_modules', '@react-native-harness', 'ui', 'package.json'); if (fs.existsSync(harnessUiPkgPath)) { const harnessUiPkg = JSON.parse(fs.readFileSync(harnessUiPkgPath, 'utf8')); if (harnessUiPkg.codegenConfig && !harnessUiPkg.codegenConfig.ios) { harnessUiPkg.codegenConfig.ios = { modulesProvider: { HarnessUI: 'HarnessUI' }, }; fs.writeFileSync(harnessUiPkgPath, JSON.stringify(harnessUiPkg, null, 2) + '\n'); console.log('Patched @react-native-harness/ui codegenConfig with ios.modulesProvider'); } } // 3. Build native code for the target platform only const buildIos = (!targetPlatform || targetPlatform === 'ios') && osPlatform() === 'darwin'; const buildAndroid = !targetPlatform || targetPlatform === 'android'; if (buildIos) { const gemfile = path.join(HOST_DIR, 'Gemfile'); if (fs.existsSync(gemfile)) { const content = fs.readFileSync(gemfile, 'utf8'); if (!content.includes("gem 'nkf'")) { fs.appendFileSync(gemfile, "\ngem 'nkf'\n"); } } const podDir = path.join(HOST_DIR, 'ios'); console.log('Running pod install...'); execSync('bundle install', { stdio: 'inherit', cwd: podDir }); execSync('bundle exec pod install', { stdio: 'inherit', cwd: podDir }); console.log('Building iOS...'); execSync('npx react-native build-ios --buildFolder build', { stdio: 'inherit', cwd: HOST_DIR }); } if (buildAndroid) { const gradleDir = path.join(HOST_DIR, 'android'); console.log('Building Android...'); execSync('./gradlew assembleDebug', { stdio: 'inherit', cwd: gradleDir, env: { ...process.env, GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx4096m -XX:MaxMetaspaceSize=1024m"' }, }); ['assets', 'res'].forEach(dir => fs.mkdirSync(path.join(HOST_DIR, 'android/app/src/main', dir), { recursive: true }), ); } // 4. Copy harness configs and test files into host app console.log('Copying harness configs and test files into host app...'); const filesToCopy = [ ['rn-harness.config.mjs', 'rn-harness.config.mjs'], ['jest.harness.config.mjs', 'jest.harness.config.mjs'], ]; for (const [src, dest] of filesToCopy) { fs.copyFileSync(path.join(E2E_DIR, src), path.join(HOST_DIR, dest)); } const hostE2eDir = path.join(HOST_DIR, '__e2e__'); fs.mkdirSync(hostE2eDir, { recursive: true }); const testFiles = fs.readdirSync(E2E_DIR).filter(f => f.endsWith('.harness.js') || f.endsWith('.harness.ts') || f.endsWith('.harness.tsx')); for (const file of testFiles) { fs.copyFileSync(path.join(E2E_DIR, file), path.join(hostE2eDir, file)); } const snapshotsDir = path.join(E2E_DIR, '__image_snapshots__'); fs.mkdirSync(snapshotsDir, { recursive: true }); fs.symlinkSync(snapshotsDir, path.join(hostE2eDir, '__image_snapshots__')); console.log('E2E host app setup complete.');