122 lines
3.4 KiB
JavaScript
122 lines
3.4 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow strict-local
|
|
* @format
|
|
*/
|
|
|
|
'use strict';
|
|
const {TEMPLATES_FOLDER_PATH} = require('./constants');
|
|
const {
|
|
codegenLog,
|
|
isReactNativeCoreLibrary,
|
|
parseiOSAnnotations,
|
|
} = require('./utils');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const MODULE_PROVIDERS_H_TEMPLATE_PATH = path.join(
|
|
TEMPLATES_FOLDER_PATH,
|
|
'RCTModuleProvidersH.template',
|
|
);
|
|
|
|
const MODULE_PROVIDERS_MM_TEMPLATE_PATH = path.join(
|
|
TEMPLATES_FOLDER_PATH,
|
|
'RCTModuleProvidersMM.template',
|
|
);
|
|
|
|
function generateRCTModuleProviders(
|
|
projectRoot /*: string */,
|
|
pkgJson /*: $FlowFixMe */,
|
|
libraries /*: $ReadOnlyArray<$FlowFixMe> */,
|
|
outputDir /*: string */,
|
|
) {
|
|
fs.mkdirSync(outputDir, {recursive: true});
|
|
// Generate Header File
|
|
codegenLog('Generating RCTModulesProvider.h');
|
|
const templateH = fs.readFileSync(MODULE_PROVIDERS_H_TEMPLATE_PATH, 'utf8');
|
|
const finalPathH = path.join(outputDir, 'RCTModuleProviders.h');
|
|
fs.writeFileSync(finalPathH, templateH);
|
|
codegenLog(`Generated artifact: ${finalPathH}`);
|
|
|
|
codegenLog('Generating RCTModuleProviders.mm');
|
|
let modulesInLibraries = {} /*:: as {[string]: Array<$FlowFixMe>} */;
|
|
|
|
let app = pkgJson.codegenConfig
|
|
? {config: pkgJson.codegenConfig, libraryPath: projectRoot}
|
|
: null;
|
|
|
|
const moduleLibraries = libraries
|
|
.concat(app)
|
|
.filter(Boolean)
|
|
.filter(({config, libraryPath}) => {
|
|
if (
|
|
isReactNativeCoreLibrary(config.name) ||
|
|
config.type === 'components'
|
|
) {
|
|
return false;
|
|
}
|
|
return true;
|
|
});
|
|
|
|
// Old API
|
|
moduleLibraries.forEach(({config, libraryPath}) => {
|
|
const libraryName = JSON.parse(
|
|
fs.readFileSync(path.join(libraryPath, 'package.json'), 'utf8'),
|
|
).name;
|
|
|
|
if (config.ios?.modulesProvider) {
|
|
modulesInLibraries[libraryName] = Object.keys(
|
|
config.ios?.modulesProvider,
|
|
).map(moduleName => {
|
|
return {
|
|
moduleName,
|
|
className: config.ios?.modulesProvider[moduleName],
|
|
};
|
|
});
|
|
}
|
|
});
|
|
|
|
// New API
|
|
const iosAnnotations = parseiOSAnnotations(moduleLibraries);
|
|
for (const [libraryName, {modules: moduleAnnotationMap}] of Object.entries(
|
|
iosAnnotations,
|
|
)) {
|
|
for (const [moduleName, annotation] of Object.entries(
|
|
moduleAnnotationMap,
|
|
)) {
|
|
if (annotation.className) {
|
|
modulesInLibraries[libraryName] = modulesInLibraries[libraryName] || [];
|
|
modulesInLibraries[libraryName].push({
|
|
moduleName,
|
|
className: annotation.className,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const modulesMapping = Object.keys(modulesInLibraries)
|
|
.flatMap(library => {
|
|
const modules = modulesInLibraries[library];
|
|
return modules.map(({moduleName, className}) => {
|
|
return `\t\t@"${moduleName}": @"${className}", // ${library}`;
|
|
});
|
|
})
|
|
.join('\n');
|
|
|
|
// Generate implementation file
|
|
const templateMM = fs
|
|
.readFileSync(MODULE_PROVIDERS_MM_TEMPLATE_PATH, 'utf8')
|
|
.replace(/{moduleMapping}/, modulesMapping);
|
|
const finalPathMM = path.join(outputDir, 'RCTModuleProviders.mm');
|
|
fs.writeFileSync(finalPathMM, templateMM);
|
|
codegenLog(`Generated artifact: ${finalPathMM}`);
|
|
}
|
|
|
|
module.exports = {
|
|
generateRCTModuleProviders,
|
|
};
|