From 08fd9ccffb1dd6cec4426e0ebadd5828f1e7355f Mon Sep 17 00:00:00 2001 From: RealBhupesh Date: Sun, 2 Aug 2026 12:34:51 +0530 Subject: [PATCH] Fix iOS codegen fallback for libraries without config --- .../generate-artifacts-executor-test.js | 51 +++++++++++++++++++ .../generate-artifacts-executor/utils.js | 10 ++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js b/packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js index fa51aebd2816..085f79b5cbcf 100644 --- a/packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js +++ b/packages/react-native/scripts/codegen/__tests__/generate-artifacts-executor-test.js @@ -12,6 +12,9 @@ const fixtures = require('../__fixtures__/fixtures'); const {execute} = require('../generate-artifacts-executor'); +const { + generateRCTThirdPartyComponents, +} = require('../generate-artifacts-executor/generateRCTThirdPartyComponents'); const { extractSupportedApplePlatforms, } = require('../generate-artifacts-executor/generateSchemaInfos'); @@ -20,6 +23,7 @@ const { extractLibrariesFromJSON, } = require('../generate-artifacts-executor/utils'); const fs = require('node:fs'); +const os = require('node:os'); const path = require('node:path'); const rootPath = path.join(__dirname, '../../..'); @@ -176,6 +180,53 @@ describe('extractSupportedApplePlatforms', () => { }); }); +describe('generateRCTThirdPartyComponents', () => { + it('crawls component libraries without an iOS config', () => { + const libraryPath = fs.mkdtempSync( + path.join(os.tmpdir(), 'react-native-codegen-'), + ); + const outputDir = path.join(libraryPath, 'output'); + + fs.writeFileSync( + path.join(libraryPath, 'package.json'), + JSON.stringify({name: 'component-library'}), + ); + fs.writeFileSync( + path.join(libraryPath, 'ExampleComponent.mm'), + `Class ExampleComponentCls(void) { + return RCTExampleComponent.class; +} +`, + ); + + try { + generateRCTThirdPartyComponents( + [ + { + config: { + name: 'ComponentLibraryConfig', + type: 'components', + jsSrcsDir: 'src', + }, + libraryPath, + }, + ], + outputDir, + ); + + const generatedFile = fs.readFileSync( + path.join(outputDir, 'RCTThirdPartyComponentsProvider.mm'), + 'utf8', + ); + expect(generatedFile).toContain( + '@"ExampleComponent": NSClassFromString(@"RCTExampleComponent"), // component-library', + ); + } finally { + fs.rmSync(libraryPath, {recursive: true, force: true}); + } + }); +}); + describe('delete empty files and folders', () => { beforeEach(() => { jest.resetModules(); diff --git a/packages/react-native/scripts/codegen/generate-artifacts-executor/utils.js b/packages/react-native/scripts/codegen/generate-artifacts-executor/utils.js index eb979f878558..ce8dfabb816c 100644 --- a/packages/react-native/scripts/codegen/generate-artifacts-executor/utils.js +++ b/packages/react-native/scripts/codegen/generate-artifacts-executor/utils.js @@ -396,11 +396,6 @@ function parseiOSAnnotations( const map = {}; for (const library of libraries) { - const iosConfig = library?.config?.ios; - if (!iosConfig) { - continue; - } - const libraryName = getLibraryName(library); map[libraryName] = map[libraryName] || { library, @@ -408,6 +403,11 @@ function parseiOSAnnotations( components: {}, }; + const iosConfig = library?.config?.ios; + if (!iosConfig) { + continue; + } + const {modules, components} = iosConfig; if (modules) { for (const [moduleName, annotation] of Object.entries(modules)) {