151 lines
7.1 KiB
JavaScript
151 lines
7.1 KiB
JavaScript
"use strict";
|
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
};
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.resolveReactNativeModule = resolveReactNativeModule;
|
|
exports.createReactNativeConfigAsync = createReactNativeConfigAsync;
|
|
exports.resolveAppProjectConfigAsync = resolveAppProjectConfigAsync;
|
|
const fs_1 = __importDefault(require("fs"));
|
|
const path_1 = __importDefault(require("path"));
|
|
const androidResolver_1 = require("./androidResolver");
|
|
const config_1 = require("./config");
|
|
const iosResolver_1 = require("./iosResolver");
|
|
const ExpoModuleConfig_1 = require("../ExpoModuleConfig");
|
|
const dependencies_1 = require("../dependencies");
|
|
const webResolver_1 = require("./webResolver");
|
|
const isMissingFBReactNativeSpecCodegenOutput = async (reactNativePath) => {
|
|
const generatedDir = path_1.default.resolve(reactNativePath, 'React/FBReactNativeSpec');
|
|
try {
|
|
const stat = await fs_1.default.promises.lstat(generatedDir);
|
|
return !stat.isDirectory();
|
|
}
|
|
catch {
|
|
return true;
|
|
}
|
|
};
|
|
async function resolveReactNativeModule(resolution, projectConfig, platform, excludeNames) {
|
|
if (excludeNames.has(resolution.name)) {
|
|
return null;
|
|
}
|
|
else if (resolution.name === 'react-native' || resolution.name === 'react-native-macos') {
|
|
// Starting from version 0.76, the `react-native` package only defines platforms
|
|
// when @react-native-community/cli-platform-android/ios is installed.
|
|
// Therefore, we need to manually filter it out.
|
|
// NOTE(@kitten): `loadConfigAsync` is skipped too, because react-native's config is too slow
|
|
return null;
|
|
}
|
|
const libraryConfig = (await (0, config_1.loadConfigAsync)(resolution.path));
|
|
const reactNativeConfig = {
|
|
...libraryConfig?.dependency,
|
|
...projectConfig?.dependencies?.[resolution.name],
|
|
};
|
|
if (Object.keys(libraryConfig?.platforms ?? {}).length > 0) {
|
|
// Package defines platforms would be a platform host package.
|
|
// The rnc-cli will skip this package.
|
|
return null;
|
|
}
|
|
let maybeExpoModuleConfig;
|
|
if (!libraryConfig) {
|
|
// NOTE(@kitten): If we don't have an explicit react-native.config.{js,ts} file,
|
|
// we should pass the Expo Module config (if it exists) to the resolvers below,
|
|
// which can then decide if the React Native inferred config and Expo Module
|
|
// configs conflict
|
|
try {
|
|
maybeExpoModuleConfig = await (0, ExpoModuleConfig_1.discoverExpoModuleConfigAsync)(resolution.path);
|
|
}
|
|
catch {
|
|
// We ignore invalid Expo Modules for the purpose of auto-linking and
|
|
// pretend the config doesn't exist, if it isn't valid JSON
|
|
}
|
|
}
|
|
let platformData = null;
|
|
if (platform === 'android') {
|
|
platformData = await (0, androidResolver_1.resolveDependencyConfigImplAndroidAsync)(resolution.path, reactNativeConfig.platforms?.android, maybeExpoModuleConfig);
|
|
}
|
|
else if (platform === 'ios') {
|
|
platformData = await (0, iosResolver_1.resolveDependencyConfigImplIosAsync)(resolution, reactNativeConfig.platforms?.ios, maybeExpoModuleConfig);
|
|
}
|
|
else if (platform === 'web') {
|
|
platformData = await (0, webResolver_1.checkDependencyWebAsync)(resolution, reactNativeConfig, maybeExpoModuleConfig);
|
|
}
|
|
return (platformData && {
|
|
root: resolution.path,
|
|
name: resolution.name,
|
|
platforms: {
|
|
[platform]: platformData,
|
|
},
|
|
});
|
|
}
|
|
/**
|
|
* Create config for react-native core autolinking.
|
|
*/
|
|
async function createReactNativeConfigAsync({ appRoot, sourceDir, autolinkingOptions, }) {
|
|
const excludeNames = new Set(autolinkingOptions.exclude);
|
|
const projectConfig = (await (0, config_1.loadConfigAsync)(appRoot));
|
|
// custom native modules should be resolved first so that they can override other modules
|
|
const searchPaths = autolinkingOptions.nativeModulesDir
|
|
? [autolinkingOptions.nativeModulesDir, ...autolinkingOptions.searchPaths]
|
|
: autolinkingOptions.searchPaths;
|
|
const limitDepth = autolinkingOptions.legacy_shallowReactNativeLinking ? 1 : undefined;
|
|
const resolutions = (0, dependencies_1.mergeResolutionResults)(await Promise.all([
|
|
(0, dependencies_1.scanDependenciesFromRNProjectConfig)(appRoot, projectConfig),
|
|
...searchPaths.map((searchPath) => (0, dependencies_1.scanDependenciesInSearchPath)(searchPath)),
|
|
(0, dependencies_1.scanDependenciesRecursively)(appRoot, { limitDepth }),
|
|
]));
|
|
const dependencies = await (0, dependencies_1.filterMapResolutionResult)(resolutions, (resolution) => resolveReactNativeModule(resolution, projectConfig, autolinkingOptions.platform, excludeNames));
|
|
// See: https://github.com/facebook/react-native/pull/53690
|
|
// When we're building react-native from source without these generated files, we need to force them to be generated
|
|
// Every published react-native version (or out-of-tree version) should have these files, but building from the raw repo won't (e.g. Expo Go)
|
|
const reactNativeResolution = resolutions['react-native'];
|
|
if (reactNativeResolution &&
|
|
autolinkingOptions.platform === 'ios' &&
|
|
(await isMissingFBReactNativeSpecCodegenOutput(reactNativeResolution.path))) {
|
|
dependencies['react-native'] = {
|
|
root: reactNativeResolution.path,
|
|
name: 'react-native',
|
|
platforms: {
|
|
ios: {
|
|
// This will trigger a warning in list_native_modules but will trigger the artifacts
|
|
// codegen codepath as expected
|
|
podspecPath: '',
|
|
version: reactNativeResolution.version,
|
|
configurations: [],
|
|
scriptPhases: [],
|
|
},
|
|
},
|
|
};
|
|
}
|
|
return {
|
|
root: appRoot,
|
|
reactNativePath: resolutions['react-native']?.path,
|
|
dependencies,
|
|
project: await resolveAppProjectConfigAsync(appRoot, autolinkingOptions.platform, sourceDir),
|
|
};
|
|
}
|
|
async function resolveAppProjectConfigAsync(projectRoot, platform, sourceDir) {
|
|
// TODO(@kitten): use the commandRoot here to find these files in non <projectRoot>/<platform> folders
|
|
if (platform === 'android') {
|
|
const androidDir = sourceDir ?? path_1.default.join(projectRoot, 'android');
|
|
const { gradle, manifest } = await (0, androidResolver_1.findGradleAndManifestAsync)({ androidDir, isLibrary: false });
|
|
if (gradle == null || manifest == null) {
|
|
return {};
|
|
}
|
|
const packageName = await (0, androidResolver_1.parsePackageNameAsync)(manifest, gradle);
|
|
return {
|
|
android: {
|
|
packageName: packageName ?? '',
|
|
sourceDir: sourceDir ?? path_1.default.join(projectRoot, 'android'),
|
|
},
|
|
};
|
|
}
|
|
if (platform === 'ios') {
|
|
return {
|
|
ios: {
|
|
sourceDir: sourceDir ?? path_1.default.join(projectRoot, 'ios'),
|
|
},
|
|
};
|
|
}
|
|
return {};
|
|
}
|
|
//# sourceMappingURL=reactNativeConfig.js.map
|