2025-06-18 18:50:46 +02:00
"use strict" ;
Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
exports . doctorAndroid = void 0 ;
const tslib _1 = require ( "tslib" ) ;
2025-07-06 20:20:48 +02:00
const fs _extra _1 = require ( "fs-extra" ) ;
2025-06-18 18:50:46 +02:00
const path _1 = require ( "path" ) ;
const colors _1 = tslib _1 . _ _importDefault ( require ( "../colors" ) ) ;
const common _1 = require ( "../common" ) ;
const errors _1 = require ( "../errors" ) ;
const log _1 = require ( "../log" ) ;
2025-07-06 20:20:48 +02:00
const fs _1 = require ( "../util/fs" ) ;
2025-06-18 18:50:46 +02:00
const xml _1 = require ( "../util/xml" ) ;
async function doctorAndroid ( config ) {
var _a ;
try {
2025-07-06 20:20:48 +02:00
await ( 0 , common _1 . check ) ( [ checkAndroidInstalled , ( ) => checkGradlew ( config ) , ( ) => checkAppSrcDirs ( config ) ] ) ;
2025-06-18 18:50:46 +02:00
( 0 , log _1 . logSuccess ) ( 'Android looking great! 👌' ) ;
}
catch ( e ) {
if ( ! ( 0 , errors _1 . isFatal ) ( e ) ) {
( 0 , errors _1 . fatal ) ( ( _a = e . stack ) !== null && _a !== void 0 ? _a : e ) ;
}
throw e ;
}
}
exports . doctorAndroid = doctorAndroid ;
async function checkAppSrcDirs ( config ) {
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( config . android . appDirAbs ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( config . android . appDir ) } directory is missing in ${ colors _1 . default . strong ( config . android . platformDir ) } ` ;
}
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( config . android . srcMainDirAbs ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( config . android . srcMainDir ) } directory is missing in ${ colors _1 . default . strong ( config . android . platformDir ) } ` ;
}
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( config . android . assetsDirAbs ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( config . android . assetsDir ) } directory is missing in ${ colors _1 . default . strong ( config . android . platformDir ) } ` ;
}
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( config . android . webDirAbs ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( config . android . webDir ) } directory is missing in ${ colors _1 . default . strong ( config . android . platformDir ) } ` ;
}
const appSrcMainAssetsWwwIndexHtmlDir = ( 0 , path _1 . join ) ( config . android . webDirAbs , 'index.html' ) ;
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( appSrcMainAssetsWwwIndexHtmlDir ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( 'index.html' ) } file is missing in ${ colors _1 . default . strong ( config . android . webDirAbs ) } ` ;
}
return checkAndroidManifestFile ( config ) ;
}
async function checkAndroidManifestFile ( config ) {
const manifestFileName = 'AndroidManifest.xml' ;
const manifestFilePath = ( 0 , path _1 . join ) ( config . android . srcMainDirAbs , manifestFileName ) ;
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( manifestFilePath ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( manifestFileName ) } is missing in ${ colors _1 . default . strong ( config . android . srcMainDir ) } ` ;
}
try {
const xmlData = await ( 0 , xml _1 . readXML ) ( manifestFilePath ) ;
return checkAndroidManifestData ( config , xmlData ) ;
}
catch ( e ) {
return e ;
}
}
async function checkAndroidManifestData ( config , xmlData ) {
const manifestNode = xmlData . manifest ;
if ( ! manifestNode ) {
return ` Missing ${ colors _1 . default . input ( '<manifest>' ) } XML node in ${ colors _1 . default . strong ( config . android . srcMainDir ) } ` ;
}
const applicationChildNodes = manifestNode . application ;
if ( ! Array . isArray ( manifestNode . application ) ) {
return ` Missing ${ colors _1 . default . input ( '<application>' ) } XML node as a child node of ${ colors _1 . default . input ( '<manifest>' ) } in ${ colors _1 . default . strong ( config . android . srcMainDir ) } ` ;
}
let mainActivityClassPath = '' ;
2025-07-06 20:20:48 +02:00
const mainApplicationNode = applicationChildNodes . find ( ( applicationChildNode ) => {
2025-06-18 18:50:46 +02:00
const activityChildNodes = applicationChildNode . activity ;
if ( ! Array . isArray ( activityChildNodes ) ) {
return false ;
}
2025-07-06 20:20:48 +02:00
const mainActivityNode = activityChildNodes . find ( ( activityChildNode ) => {
2025-06-18 18:50:46 +02:00
const intentFilterChildNodes = activityChildNode [ 'intent-filter' ] ;
if ( ! Array . isArray ( intentFilterChildNodes ) ) {
return false ;
}
2025-07-06 20:20:48 +02:00
return intentFilterChildNodes . find ( ( intentFilterChildNode ) => {
2025-06-18 18:50:46 +02:00
const actionChildNodes = intentFilterChildNode . action ;
if ( ! Array . isArray ( actionChildNodes ) ) {
return false ;
}
2025-07-06 20:20:48 +02:00
const mainActionChildNode = actionChildNodes . find ( ( actionChildNode ) => {
2025-06-18 18:50:46 +02:00
const androidName = actionChildNode . $ [ 'android:name' ] ;
return androidName === 'android.intent.action.MAIN' ;
} ) ;
if ( ! mainActionChildNode ) {
return false ;
}
const categoryChildNodes = intentFilterChildNode . category ;
if ( ! Array . isArray ( categoryChildNodes ) ) {
return false ;
}
2025-07-06 20:20:48 +02:00
return categoryChildNodes . find ( ( categoryChildNode ) => {
2025-06-18 18:50:46 +02:00
const androidName = categoryChildNode . $ [ 'android:name' ] ;
return androidName === 'android.intent.category.LAUNCHER' ;
} ) ;
} ) ;
} ) ;
if ( mainActivityNode ) {
mainActivityClassPath = mainActivityNode . $ [ 'android:name' ] ;
}
return mainActivityNode ;
} ) ;
if ( ! mainApplicationNode ) {
return ` Missing main ${ colors _1 . default . input ( '<activity>' ) } XML node in ${ colors _1 . default . strong ( config . android . srcMainDir ) } ` ;
}
if ( ! mainActivityClassPath ) {
return ` Missing ${ colors _1 . default . input ( '<activity android:name="">' ) } attribute for MainActivity class in ${ colors _1 . default . strong ( config . android . srcMainDir ) } ` ;
}
return checkPackage ( config , mainActivityClassPath ) ;
}
async function checkPackage ( config , mainActivityClassPath ) {
const appSrcMainJavaDir = ( 0 , path _1 . join ) ( config . android . srcMainDirAbs , 'java' ) ;
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( appSrcMainJavaDir ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( 'java' ) } directory is missing in ${ colors _1 . default . strong ( appSrcMainJavaDir ) } ` ;
}
const mainActivityClassName = mainActivityClassPath . split ( '.' ) . pop ( ) ;
2025-07-06 20:20:48 +02:00
const srcFiles = await ( 0 , fs _1 . readdirp ) ( appSrcMainJavaDir , {
filter : ( entry ) => ! entry . stats . isDirectory ( ) &&
2025-06-18 18:50:46 +02:00
[ '.java' , '.kt' ] . includes ( ( 0 , path _1 . extname ) ( entry . path ) ) &&
mainActivityClassName === ( 0 , path _1 . parse ) ( entry . path ) . name ,
} ) ;
if ( srcFiles . length == 0 ) {
return ` Main activity file ( ${ mainActivityClassName } ) is missing ` ;
}
return checkBuildGradle ( config ) ;
}
async function checkBuildGradle ( config ) {
const fileName = 'build.gradle' ;
const filePath = ( 0 , path _1 . join ) ( config . android . appDirAbs , fileName ) ;
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( filePath ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( fileName ) } file is missing in ${ colors _1 . default . strong ( config . android . appDir ) } ` ;
}
2025-07-06 20:20:48 +02:00
let fileContent = await ( 0 , fs _extra _1 . readFile ) ( filePath , { encoding : 'utf-8' } ) ;
2025-06-18 18:50:46 +02:00
fileContent = fileContent . replace ( /'|"/g , '' ) . replace ( /\s+/g , ' ' ) ;
const searchFor = ` applicationId ` ;
if ( fileContent . indexOf ( searchFor ) === - 1 ) {
return ` ${ colors _1 . default . strong ( 'build.gradle' ) } file missing ${ colors _1 . default . input ( ` applicationId ` ) } config in ${ filePath } ` ;
}
return null ;
}
async function checkGradlew ( config ) {
const fileName = 'gradlew' ;
const filePath = ( 0 , path _1 . join ) ( config . android . platformDirAbs , fileName ) ;
2025-07-06 20:20:48 +02:00
if ( ! ( await ( 0 , fs _extra _1 . pathExists ) ( filePath ) ) ) {
2025-06-18 18:50:46 +02:00
return ` ${ colors _1 . default . strong ( fileName ) } file is missing in ${ colors _1 . default . strong ( config . android . platformDir ) } ` ;
}
return null ;
}
async function checkAndroidInstalled ( ) {
/ *
if ( ! await isInstalled ( 'android' ) ) {
return 'Android is not installed. For information: https://developer.android.com/studio/index.html' ;
}
* /
return null ;
}