Repository: onejs/one
File: packages/vxrn/src/exports/prebuild.ts (TypeScript)

Code before:
      mode: srcPermissions,
    })
  })
}
/*
End of meta owned code
End of copyright Facebook
*/

const transformPath = (filePath: string) => {
  return filePath
    .replace('_BUCK', 'BUCK')
    .replace('_gitignore', '.gitignore')
    .replace('_gitattributes', '.gitattributes')
    .replace('_babelrc', '.babelrc')
    .replace('_editorconfig', '.editorconfig')
    .replace('_eslintrc.js', '.eslintrc.js')
    .replace('_flowconfig', '.flowconfig')
    .replace('_buckconfig', '.buckconfig')
    .replace('_prettierrc.js', '.prettierrc.js')
    .replace('_bundle', '.bundle')
    .replace('_ruby-version', '.ruby-version')
    .replace('_node-version', '.node-version')
    .replace('_watchmanconfig', '.watchmanconfig')
    .replace('_xcode.env', '.xcode.env')
}

export const prebuild = async ({
  root,
  platform,
  expo = true,
}: { root: string; platform?: 'ios' | 'android' | string; expo: boolean }) => {
  const options = await fillOptions({ root })

  applyBuiltInPatches(options).catch((err) => {
    console.error(`\n 🥺 error applying built-in patches`, err)
  })
  const doesIOSExist = FSExtra.existsSync(path.resolve('ios'))
  const doesAndroidExist = FSExtra.existsSync(path.resolve('android'))

  if (expo) {
    try {
      // Import Expo from the user's project instead of from where vxrn is installed, since vxrn may be installed globally or at the root workspace.
      const importPath = require.resolve('@expo/cli/build/src/prebuild/index.js', {
        paths: [root],
      })
      const expoPrebuild = (await import(importPath)).default.expoPrebuild
      await expoPrebuild([
        ...(platform ? ['--platform', platform] : []),
        '--skip-dependency-update',
        'react,react-native,expo',

Review comment (suggestion):
We can move these functions to a separate file for readability (so one can see the main `prebuild` function at the top when looking at this `prebuild.ts` file).

Code after:
      let packageJsonContents = await FSExtra.readFile(packageJsonPath, 'utf8')
      let { devDependencies } = JSON.parse(packageJsonContents)
      if (!devDependencies['@react-native-community/template']) {
        const installCommand: `${PackageManagerName} ${'add' | 'install'} ${'-D'} ${'@react-native-community/template'}` =
          await (async () => {
            const found = await detectPackageManager()
            switch (true) {
              case found.bun:
                return `bun add -D @react-native-community/template`
              case found.pnpm:
                return `pnpm install -D @react-native-community/template`
              case found.yarn:
                return `yarn add -D @react-native-community/template`
              default:
                return `npm install -D @react-native-community/template`
            }
          })()
        throw new Error(
          '"@react-native-community/template" is not found in package.json, please install "@react-native-community/template" as dev dependency:\n' +
            `\`${installCommand}\``
        )
      }
    } catch (error) {
      throw new Error('package.json checks are failing:\n' + error)
    }

    // any because we don't have access react-native config
    let appConfig: any
    try {
      const appConfigPath = path.resolve('app.json')
      const appConfigContents = await FSExtra.readFile(appConfigPath, 'utf8')
      appConfig = JSON.parse(appConfigContents)
    } catch (error) {
      throw new Error('app.json checks are failing:\n' + error)
    }
    if (platform == 'ios' || !platform) {
      if (!doesIOSExist) {
        await generateForPlatform(root, 'ios', appConfig)
      } else {
        console.error('ios/ folder already exists')
      }
    }
    if (platform == 'android' || !platform) {
      if (!doesAndroidExist) {
        await generateForPlatform(root, 'android', appConfig)
      } else {
        console.error('android/ folder already exists')
      }
    }
    if (!platform || platform === 'ios') {
      console.info(`Run cd ios && pod install`)