UNPKG

react-native-test-app

Version:

react-native-test-app provides a test app for all supported platforms as a package

186 lines (166 loc) 5.09 kB
// @ts-check "use strict"; /** * This script (and its dependencies) currently cannot be converted to ESM * because it is consumed in `react-native.config.js`. */ const nodefs = require("node:fs"); const path = require("node:path"); const { generateAndroidManifest } = require("../android/android-manifest"); const { configureGradleWrapper } = require("../android/gradle-wrapper"); const { findFile, findNearest, getPackageVersion, readJSONFile, readTextFile, toVersionNumber, v, } = require("./helpers"); /** * @typedef {import("./types.js").ProjectConfig} ProjectConfig * @typedef {import("./types.js").ProjectParams} ProjectParams */ /** * Returns the version number of a React Native dependency. * @param {string} packageName * @returns {number} */ const getRNPackageVersion = (() => { const isTesting = "NODE_TEST_CONTEXT" in process.env; /** @type {Record<string, number>} */ let versions = {}; /** @type {(packageName: string) => number} */ return (packageName, fs = nodefs) => { if (isTesting || !versions[packageName]) { const rnDir = path.dirname(require.resolve("react-native/package.json")); const versionString = getPackageVersion(packageName, rnDir, fs); versions[packageName] = toVersionNumber(versionString); } return versions[packageName]; }; })(); /** * Returns the version number of `@react-native-community/cli-platform-ios`. * @returns {number} */ function cliPlatformIOSVersion() { return getRNPackageVersion("@react-native-community/cli-platform-ios"); } /** * @param {string | undefined} manifestPath * @returns {string | undefined} */ function getAndroidPackageName(manifestPath, fs = nodefs) { if (!manifestPath) { return undefined; } const rncliAndroidVersion = getRNPackageVersion( "@react-native-community/cli-platform-android", fs ); if (rncliAndroidVersion < v(12, 3, 7)) { // TODO: This block can be removed when we drop support for 0.72 return undefined; } if (rncliAndroidVersion >= v(13, 0, 0) && rncliAndroidVersion < v(13, 6, 9)) { // TODO: This block can be removed when we drop support for 0.73 return undefined; } /** @type {{ android?: { package?: string }}} */ const manifest = readJSONFile(manifestPath, fs); return manifest.android?.package; } /** * @returns {string | undefined} */ function iosProjectPath() { const needsProjectPath = cliPlatformIOSVersion() < v(8, 0, 0); if (needsProjectPath) { // `sourceDir` and `podfile` detection was fixed in // @react-native-community/cli-platform-ios v5.0.2 (see // https://github.com/react-native-community/cli/pull/1444). return "node_modules/.generated/ios/ReactTestApp.xcodeproj"; } return undefined; } /** * @param {string} solutionFile * @returns {ProjectParams["windows"]["project"]} */ function windowsProjectPath(solutionFile, fs = nodefs) { const sln = readTextFile(solutionFile, fs); const m = sln.match( /([^"]*?node_modules[/\\].generated[/\\]windows[/\\].*?\.vcxproj)/ ); return { projectFile: m ? m[1] : `(Failed to parse '${solutionFile}')` }; } /** * @param {ProjectConfig} configuration * @returns {Partial<ProjectParams>} */ function configureProjects({ android, ios, windows }, fs = nodefs) { const reactNativeConfig = findNearest( "react-native.config.js", undefined, fs ); if (!reactNativeConfig) { throw new Error("Failed to find `react-native.config.js`"); } /** @type {Partial<ProjectParams>} */ const config = {}; if (android) { const { packageName, sourceDir } = android; const manifestPath = path.join( "app", "build", "generated", "rnta", "src", "main", "AndroidManifest.xml" ); const projectRoot = path.dirname(reactNativeConfig); const appManifestPath = findFile("app.json", projectRoot, fs); if (appManifestPath) { generateAndroidManifest( appManifestPath, path.resolve(projectRoot, sourceDir, manifestPath), fs ); } config.android = { sourceDir, manifestPath, packageName: packageName || getAndroidPackageName(appManifestPath, fs), }; configureGradleWrapper(sourceDir, fs); } if (ios) { // `ios.sourceDir` was added in 8.0.0 // https://github.com/react-native-community/cli/commit/25eec7c695f09aea0ace7c0b591844fe8828ccc5 if (cliPlatformIOSVersion() >= v(8, 0, 0)) { config.ios = ios; } const project = iosProjectPath(); if (project) { config.ios = config.ios ?? {}; config.ios.project = project; } } if (windows && fs.existsSync(windows.solutionFile)) { const { sourceDir, solutionFile } = windows; config.windows = { sourceDir, solutionFile: path.relative(sourceDir, solutionFile), project: windowsProjectPath(solutionFile, fs), }; } return config; } exports.cliPlatformIOSVersion = cliPlatformIOSVersion; exports.configureProjects = configureProjects; exports.internalForTestingPurposesOnly = { getAndroidPackageName, };