Skip to content

Conversation

@uc-brunosouza
Copy link
Collaborator

@uc-brunosouza uc-brunosouza commented Oct 6, 2025

Summary by CodeRabbit

  • New Features

    • Added a command to publish a local SDK build for testing.
    • Improved React Native autolinking configuration.
  • Refactor

    • Switched from TurboModules to NativeModules for broader compatibility.
    • Unified Android package namespace.
  • Chores

    • Overhauled CI with dedicated Android and iOS jobs.
    • Enabled Hermes and defined supported Android ABIs.
    • Updated Android/Gradle/Kotlin versions and sample app dependencies.
    • Translated and enhanced sample scripts; added iOS sandbox fix helper.
  • Tests

    • Added comprehensive Android unit/instrumentation tests and utilities.
    • Refined assertions and removed outdated test scaffolding.

- Fabric/TurboModules configurados
- STL compartilhada funcionando
- fbjni 0.6.0 + Hermes + Flipper
- Patches aplicados para react-native-screens e react-native-safe-area-context
- CodeGen StringLiteralUnionTypeAnnotation ainda pendente
souzabrunoj and others added 21 commits September 30, 2025 17:56
…with-new-requirements

# Conflicts:
#	android/build-legacy.gradle
#	example/ios/Podfile.lock
#	package-lock.json
…it-tests

# Conflicts:
#	.github/workflows/ci.yml
#	package-lock.json
#	package.json
# Conflicts:
#	package-lock.json
#	sample/ios/Podfile.lock
…it-tests

# Conflicts:
#	package-lock.json
#	sample/package-lock.json
…l-RNUsercentricsPackage

# Conflicts:
#	package-lock.json
#	package.json
@coderabbitai
Copy link

coderabbitai bot commented Oct 6, 2025

Walkthrough

Refactors Android package namespace, updates Gradle configs and dependencies, adjusts sample app settings, and revises CI to split RN tests and add iOS/Android jobs. Introduces local publish scripts, minor iOS imports, and reworks JS binding from TurboModule to NativeModules with a runtime guard. Adds/replaces test utilities and relocates a flag class.

Changes

Cohort / File(s) Summary
CI workflows
.github/workflows/ci.yml
Replaces RN test flow with granular steps; adds separate iOS and Android jobs with platform-specific setup and tests; removes commented scaffolding.
Android Gradle config
android/build.gradle.kts, android/gradle.properties, android/settings.gradle.kts
Adds NDK abiFilters, modernizes packaging block, adds test deps including react-android, enables Hermes, sets architectures, and downgrades Kotlin plugin to 2.0.21.
Android namespace refactor (core)
android/src/main/java/com/usercentrics/reactnative/... (multiple), android/src/main/java/com/usercentrics/reactnative/api/UsercentricsProxy.kt, android/src/main/java/com/usercentrics/reactnative/extensions/*
Changes package from com.usercentrics.reactnativeusercentrics to com.usercentrics.reactnative across core, api, and extensions; adjusts imports accordingly.
UCRNFlag relocation
android/src/main/java/com/usercentrics/reactnative/UCRNFlag.kt, android/src/main/java/com/usercentrics/reactnativeusercentrics/UCRNFlag.kt
Adds UCRNFlag under new package and removes the old one under previous namespace.
Android tests utility and tests
android/src/androidTest/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt, android/src/androidTest/java/com/usercentrics/reactnative/fake/FakePromise.kt, android/src/androidTest/java/com/usercentrics/reactnativemodule/fake/FakePromise.kt, android/src/test/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt, android/src/test/java/com/usercentrics/reactnative/fake/FakePromise.kt
Adds robust FakePromise for tests; removes older incomplete FakePromise; adjusts assertions for nullability; adds unit tests for promise behavior and module basics.
JS Native binding change
src/NativeUsercentrics.ts
Replaces TurboModule access with NativeModules; removes TurboModule typing; adds runtime guard; updates export.
RN config files
react-native.config.js, sample/react-native.config.js
Points Android sourceDir to ./android; adds packageInstance; removes iOS podspecPath; updates sample package path.
Sample Android project
sample/android/app/build.gradle.kts, sample/android/app/src/main/java/.../MainApplication.kt, sample/android/gradle/libs.versions.toml, sample/android/gradle/wrapper/gradle-wrapper.properties
Tweaks NDK filters, packaging picks, buildTypes; adds deps (autolinked, tests, Flipper); updates import to new package; bumps AGP/Gradle/Kotlin versions; switches wrapper to -all distribution.
iOS minor imports
ios/Extensions/BannerSettings+Dict.swift, ios/Extensions/UIColor+Extensions.swift, ios/Extensions/UIImage+UsercentricsLogoDict.swift, ios/RNUsercentricsModule.swift
Adds/updates UIKit/React imports; no functional changes.
Local publish tooling
scripts/publish-local.js, scripts/publish-local.sh, package.json
Adds JS and Bash scripts to publish local package; adds npm script publish-local; includes version bumping, build, pack, and instructions.
Sample maintenance scripts
sample/scripts/clean-and-build.sh, sample/scripts/clean-ios-cache, sample/scripts/fix-xcode-sandbox.sh
Translates messages to English, expands CocoaPods cleanup, adjusts Xcode settings via script, and adds safety/diagnostics.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor JS as JS App
  participant RN as react-native (NativeModules)
  participant Mod as RNUsercentricsModule (Native)
  Note over JS,RN: Access module without TurboModules

  JS->>RN: const { RNUsercentricsModule } = NativeModules
  alt Module available
    RN-->>JS: RNUsercentricsModule reference
    JS->>Mod: call exported methods
    Mod-->>JS: result/Promise
  else Module missing
    RN-->>JS: undefined
    JS->>JS: throw Error("RNUsercentricsModule not linked...")
  end

  Note right of Mod: Android package namespace updated<br/>to com.usercentrics.reactnative
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A bunny refacts with hop and glide,
Packages nudged to the proper side.
CI now sprints on droid and iOS,
NativeModules answer—no Turbo stress.
Scripts pack carrots for local run,
Tests burrow deep till all is done.
Thump-thump—shipping’s fun! 🥕🚀

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.44% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary change by referencing the specific import error for the RNUsercentricsPackage symbol and uses a conventional “fix:” prefix. It directly relates to the bulk of the changes, which update package namespaces and configurations to resolve that symbol-not-found issue. The phrasing is concise and informative enough for teammates to understand the pull request’s main purpose.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/cannot-find-symbol-RNUsercentricsPackage

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🧹 Nitpick comments (3)
sample/android/app/build.gradle.kts (1)

96-96: Consider updating MockK to a more recent version.

The current version mockk-android:1.12.0 is from June 2021. Based on learnings, newer versions (1.13.x and 1.14.x) are available with improvements and bug fixes.

Consider updating to a more recent version:

-    androidTestImplementation("io.mockk:mockk-android:1.12.0")
+    androidTestImplementation("io.mockk:mockk-android:1.13.12")

Based on learnings.

android/src/androidTest/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt (1)

293-297: Test could silently fail with null consent object.

The assertions now use optional chaining (consent?.getBoolean("status") instead of consent.getBoolean("status")). While this is technically correct since result.getMap(0) on Line 291 returns a nullable type, it could mask test failures. If consent is null, the test will compare expected values against null rather than failing with a clear NPE.

Consider adding an explicit null check before the assertions to make test failures more obvious:

 val result = promise.resolveValue as WritableArray
 val consent = result.getMap(0)
+require(consent != null) { "Expected consent object to be non-null" }

-assertEquals(false, consent?.getBoolean("status"))
-assertEquals("ocv9HNX_g", consent?.getString("templateId"))
-assertEquals("Facebook SDK", consent?.getString("dataProcessor"))
-assertEquals(0, consent?.getInt("type"))
-assertEquals("1.0.1", consent?.getString("version"))
+assertEquals(false, consent.getBoolean("status"))
+assertEquals("ocv9HNX_g", consent.getString("templateId"))
+assertEquals("Facebook SDK", consent.getString("dataProcessor"))
+assertEquals(0, consent.getInt("type"))
+assertEquals("1.0.1", consent.getString("version"))
scripts/publish-local.sh (1)

1-118: Consider consolidating duplicate implementations.

Both scripts/publish-local.js and scripts/publish-local.sh implement the same local publishing workflow. Maintaining two implementations increases the risk of divergence and bugs.

Consider:

  1. Choosing one implementation (the JS version is more portable)
  2. If both are needed, document the use cases for each
  3. Extract shared logic to avoid duplication

Which approach aligns better with your team's workflow?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0f1706b and 8de1372.

⛔ Files ignored due to path filters (2)
  • package-lock.json is excluded by !**/package-lock.json
  • sample/package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (46)
  • .github/workflows/ci.yml (1 hunks)
  • android/build.gradle.kts (3 hunks)
  • android/gradle.properties (1 hunks)
  • android/settings.gradle.kts (1 hunks)
  • android/src/androidTest/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt (1 hunks)
  • android/src/androidTest/java/com/usercentrics/reactnative/fake/FakePromise.kt (1 hunks)
  • android/src/androidTest/java/com/usercentrics/reactnativemodule/fake/FakePromise.kt (0 hunks)
  • android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModule.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModuleSpec.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/ReactContextProvider.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/ReactContextProviderImpl.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/UCRNFlag.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/api/UsercentricsProxy.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/BannerFontExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/BannerSettingsExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/CCPADataExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/ConsentDisclosureSerializer.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/ReadableMapExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/TCFDataExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UserDecisionExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UserOptionsExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsConsentUserResponseExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsReadyStatusExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsServiceConsentExtensions.kt (1 hunks)
  • android/src/main/java/com/usercentrics/reactnativeusercentrics/UCRNFlag.kt (0 hunks)
  • android/src/test/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt (1 hunks)
  • android/src/test/java/com/usercentrics/reactnative/fake/FakePromise.kt (1 hunks)
  • ios/Extensions/BannerSettings+Dict.swift (1 hunks)
  • ios/Extensions/UIColor+Extensions.swift (1 hunks)
  • ios/Extensions/UIImage+UsercentricsLogoDict.swift (1 hunks)
  • ios/RNUsercentricsModule.swift (1 hunks)
  • package.json (1 hunks)
  • react-native.config.js (1 hunks)
  • sample/android/app/build.gradle.kts (5 hunks)
  • sample/android/app/src/main/java/com/usercentrics/reactnativesdk/sample/MainApplication.kt (1 hunks)
  • sample/android/gradle/libs.versions.toml (1 hunks)
  • sample/android/gradle/wrapper/gradle-wrapper.properties (1 hunks)
  • sample/react-native.config.js (1 hunks)
  • sample/scripts/clean-and-build.sh (2 hunks)
  • sample/scripts/clean-ios-cache (2 hunks)
  • sample/scripts/fix-xcode-sandbox.sh (1 hunks)
  • scripts/publish-local.js (1 hunks)
  • scripts/publish-local.sh (1 hunks)
  • src/NativeUsercentrics.ts (3 hunks)
💤 Files with no reviewable changes (2)
  • android/src/main/java/com/usercentrics/reactnativeusercentrics/UCRNFlag.kt
  • android/src/androidTest/java/com/usercentrics/reactnativemodule/fake/FakePromise.kt
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/ci.yml

48-48: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


51-51: the runner of "actions/setup-node@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


84-84: the runner of "actions/setup-node@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


89-89: the runner of "actions/setup-java@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test-android
  • GitHub Check: test-ios
🔇 Additional comments (40)
ios/Extensions/BannerSettings+Dict.swift (1)

3-3: LGTM!

The UIKit import is necessary for the UIKit types (UIColor, UIFont, UIImage, CGFloat) used throughout this file.

ios/Extensions/UIColor+Extensions.swift (1)

1-1: LGTM!

Replacing Foundation with UIKit is appropriate since this file extends UIColor and uses CGFloat, both of which are UIKit types. UIKit also imports Foundation, so no functionality is lost.

ios/Extensions/UIImage+UsercentricsLogoDict.swift (1)

2-2: LGTM!

The UIKit import is necessary for the UIImage extension defined in this file.

ios/RNUsercentricsModule.swift (1)

5-5: LGTM!

The React import is necessary for the React Native bridge types (RCTPromiseResolveBlock, RCTPromiseRejectBlock, RCTJSInvoker, RCTBridgeModule) used throughout this module.

android/gradle.properties (1)

5-7: LGTM!

The added properties are standard React Native configuration:

  • reactNativeArchitectures specifies the target ABIs (armeabi-v7a, arm64-v8a, x86, x86_64)
  • hermesEnabled=true enables the Hermes JavaScript engine
android/settings.gradle.kts (1)

8-8: Confirm Kotlin plugin downgrade
No Kotlin 2.1+ APIs detected; please ensure React Native 0.79.6 and all project dependencies are compatible with plugin version 2.0.21 and that the build succeeds.

sample/android/gradle/wrapper/gradle-wrapper.properties (1)

3-3: LGTM! Standard Gradle wrapper update.

Switching from -bin.zip to -all.zip provides sources and documentation for better IDE integration and debugging support.

android/src/main/java/com/usercentrics/reactnative/UCRNFlag.kt (1)

1-4: LGTM! Marker class relocated to new package namespace.

The empty class with @Suppress("unused") is a standard pattern for ensuring package processing during build/autolinking.

android/src/main/java/com/usercentrics/reactnative/ReactContextProviderImpl.kt (1)

1-1: LGTM! Package namespace aligned with PR refactor.

The package declaration update is part of the broader namespace refactor to resolve the "cannot find symbol" issue mentioned in the PR title.

src/NativeUsercentrics.ts (2)

16-16: Interface signature simplified.

The Spec interface no longer extends TurboModule, aligning with the migration to NativeModules-based architecture.


63-72: Good runtime guard for missing native module.

The runtime check provides clear, actionable error messages for both iOS and Android setup issues, improving developer experience during integration.

sample/android/app/build.gradle.kts (3)

26-26: LGTM! ABI filter configuration.

Using listOf for ABI filters is appropriate and maintains explicit ordering.


54-59: LGTM! Proper native library conflict resolution.

The pickFirsts configuration correctly handles duplicate native libraries across dependencies.


115-125: Verify if the commented subprojects block is intentional.

The entire subprojects configuration has been commented out rather than removed. If this is no longer needed, consider removing it entirely to keep the build file clean.

Is this block needed for any specific configuration, or can it be safely removed?

android/build.gradle.kts (3)

25-27: LGTM! ABI filter configuration added.

Restricting supported ABIs is a good practice for library modules to ensure consistent behavior across platforms.


52-56: LGTM! Modern packaging configuration.

The packaging block replaces the deprecated packagingOptions, aligning with current Gradle plugin conventions.


63-67: LGTM! Current and appropriate test dependency versions.

The test dependencies use recent stable versions:

  • JUnit 4.13.2 (latest JUnit 4 maintenance release)
  • MockK 1.13.12 (July 2024 release)
  • kotlinx-coroutines-test 1.9.0 (September 2024 release)

These are well-maintained and appropriate choices for the test suite.

Based on learnings.

android/src/androidTest/java/com/usercentrics/reactnative/fake/FakePromise.kt (1)

7-73: Test helper implementation looks solid.

The FakePromise class properly implements the React Native Promise interface with:

  • Thread-safe synchronization using CountDownLatch
  • Complete coverage of all Promise interface methods
  • Proper state capture for both resolve and reject scenarios

The implementation will work well for testing async native module methods once the package declaration is fixed.

android/src/main/java/com/usercentrics/reactnative/RNUsercentricsModuleSpec.kt (1)

1-1: LGTM! Package namespace updated consistently.

The package declaration update aligns with the broader refactor to resolve the "cannot find symbol RNUsercentricsPackage" issue mentioned in the PR title. All method signatures and functionality remain unchanged.

android/src/main/java/com/usercentrics/reactnative/api/UsercentricsProxy.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration and import path have been correctly updated from com.usercentrics.reactnativeusercentrics.* to com.usercentrics.reactnative.* to align with the namespace reorganization across the Android module.

Also applies to: 6-6

android/src/main/java/com/usercentrics/reactnative/RNUsercentricsPackage.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration and import path have been correctly updated to the new com.usercentrics.reactnative namespace, consistent with the broader refactoring effort.

Also applies to: 8-8

android/src/main/java/com/usercentrics/reactnative/extensions/ReadableMapExtensions.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration has been correctly updated to the new com.usercentrics.reactnative.extensions namespace.

react-native.config.js (3)

7-7: New packageInstance field added.

The packageInstance: 'new RNUsercentricsPackage()' field has been added, which is likely required for React Native autolinking to instantiate the package with the new namespace. This change looks appropriate for the namespace refactor.


9-9: Verify iOS configuration after podspec removal.

The iOS configuration has been changed from containing a podspecPath to an empty object. Please verify that iOS builds and linking still work correctly after this change. The podspec may now be autodiscovered or configured elsewhere.


5-5: sourceDir path is correct. The './android' directory exists relative to this config file; no update needed.

android/src/main/java/com/usercentrics/reactnative/extensions/BannerSettingsExtensions.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration has been correctly updated to the new com.usercentrics.reactnative.extensions namespace.

android/src/main/java/com/usercentrics/reactnative/extensions/UserOptionsExtensions.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration has been correctly updated to the new com.usercentrics.reactnative.extensions namespace.

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsCMPDataExtensions.kt (1)

1-1: LGTM! Package namespace refactor is correct.

The package declaration has been correctly updated to the new com.usercentrics.reactnative.extensions namespace.

android/src/main/java/com/usercentrics/reactnative/extensions/CCPADataExtensions.kt (1)

1-1: LGTM! Package namespace updated correctly.

The package declaration has been correctly updated as part of the repository-wide namespace refactor from com.usercentrics.reactnativeusercentrics.extensions to com.usercentrics.reactnative.extensions.

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsReadyStatusExtensions.kt (1)

1-1: LGTM! Package namespace updated correctly.

The package declaration has been correctly updated as part of the repository-wide namespace refactor.

android/src/main/java/com/usercentrics/reactnative/extensions/UsercentricsConsentUserResponseExtensions.kt (1)

1-1: LGTM! Package namespace updated correctly.

The package declaration has been correctly updated as part of the repository-wide namespace refactor.

android/src/main/java/com/usercentrics/reactnative/extensions/UserDecisionExtensions.kt (1)

1-1: LGTM! Package namespace updated correctly.

The package declaration has been correctly updated as part of the repository-wide namespace refactor.

android/src/test/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt (1)

10-96: LGTM! FakePromise tests are comprehensive.

The test coverage for FakePromise is thorough, validating resolve/reject behavior, overwrite semantics, interface methods, null handling, and complex data structures.

sample/scripts/clean-and-build.sh (1)

5-68: LGTM! Clean localization to English.

The translation from Portuguese to English improves consistency across the project. The script logic and error handling remain unchanged.

scripts/publish-local.js (1)

99-106: Verify npm pack output parsing.

The script extracts the package filename by taking the last line of npm pack output. This assumes npm's output format is stable, but npm could change this in future versions.

Consider using a more robust approach or adding validation:

 const packOutput = execSync('npm pack', { encoding: 'utf8' });
 const packageFile = packOutput.trim().split('\n').pop();

 if (!packageFile) {
     printError('Failed to create npm package!');
     process.exit(1);
 }
+
+// Verify the file actually exists
+if (!fs.existsSync(packageFile)) {
+    printError(`Package file not found: ${packageFile}`);
+    printError('npm pack may have changed its output format');
+    process.exit(1);
+}
sample/scripts/fix-xcode-sandbox.sh (1)

40-42: Verify perl injection logic.

The perl one-liner attempts to inject VALIDATE_MODULES = NO; into buildSettings blocks that don't already have it. The regex and unless condition may not work correctly across multiline blocks in the pbxproj format.

Test this script on a real Pods project to ensure:

  1. The perl regex correctly matches buildSettings = { patterns
  2. The unless /VALIDATE_MODULES/ condition properly checks the current line (not the block)
  3. No duplicate injections occur

Consider documenting expected pbxproj format or adding validation.

sample/scripts/clean-ios-cache (1)

18-29: Functional enhancement: added pod install.

The script now runs pod install --repo-update after cleaning the Cocoapods cache (Line 25). This is a functional change beyond localization, ensuring pods are reinstalled after cleanup.

Consider documenting that this script now performs a full pod reinstall, which may take significant time.

.github/workflows/ci.yml (2)

26-27: Clarify TypeScript installation approach.

The workflow installs TypeScript as a dev dependency via yarn add rather than relying on package.json. This could lead to version drift if the version in the command (^5.6.3) diverges from package.json (^5.8.3 at Line 64).

Consider either:

  1. Removing this step and relying on package.json's devDependency
  2. Documenting why a specific TS version is needed for CI

Which approach aligns with your project's versioning strategy?


73-77: Verify macOS runner choice for Android tests.

The test-android job runs on macos-13 (Line 75), which is unusual for Android builds. Typically, Android tests run on ubuntu-latest for cost efficiency unless macOS-specific tooling is required.

Is there a specific reason for using macOS? If not, consider switching to ubuntu-latest to reduce CI costs and runtime.

package.json (1)

42-42: LGTM! New local publish script.

The addition of the publish-local script aligns with the new tooling added in scripts/publish-local.sh and scripts/publish-local.js.

xcode-version: '15.2'

- name: Checkout
uses: actions/checkout@v2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Update GitHub Actions versions.

Static analysis detected deprecated action versions that may fail on newer GitHub runners:

  • Line 48: actions/checkout@v2 → upgrade to @v4
  • Line 51: actions/setup-node@v2 → upgrade to @v4
  • Line 84: actions/setup-node@v2 → upgrade to @v4
  • Line 89: actions/setup-java@v1 → upgrade to @v4

Based on static analysis tool (actionlint).

Apply this diff:

-      - name: Checkout
-        uses: actions/checkout@v2
+      - name: Checkout
+        uses: actions/checkout@v4

-      - name: Setup Node
-        uses: actions/setup-node@v2
+      - name: Setup Node
+        uses: actions/setup-node@v4
         with:
           node-version: ${{ env.NODE_JS_VERSION }}

Similar updates for lines 84 and 89.

Also applies to: 51-51, 84-84, 89-89

🧰 Tools
🪛 actionlint (1.7.7)

48-48: the runner of "actions/checkout@v2" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
.github/workflows/ci.yml lines 48, 51, 84 and 89: update deprecated GitHub
Action versions to their current stable major releases; replace
actions/checkout@v2 with actions/checkout@v4, replace actions/setup-node@v2 with
actions/setup-node@v4 at both line 51 and 84, and replace actions/setup-java@v1
with actions/setup-java@v4 at line 89; ensure there are no breaking
configuration changes required by the new majors (adjust inputs if needed) and
run the workflow linter or actionlint to validate the updated workflow.

@@ -0,0 +1,73 @@
package com.usercentrics.reactnativemodule.fake
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Package declaration doesn't match file path.

The package declaration com.usercentrics.reactnativemodule.fake conflicts with the file path android/src/androidTest/java/com/usercentrics/reactnative/fake/FakePromise.kt, which implies the package should be com.usercentrics.reactnative.fake.

This mismatch will cause compilation errors as the compiler expects the package to match the directory structure.

Apply this diff to fix the package declaration:

-package com.usercentrics.reactnativemodule.fake
+package com.usercentrics.reactnative.fake
🤖 Prompt for AI Agents
In android/src/androidTest/java/com/usercentrics/reactnative/fake/FakePromise.kt
around line 1 the package declaration is incorrect: it currently reads
com.usercentrics.reactnativemodule.fake but must match the directory path
com.usercentrics.reactnative.fake; update the package declaration to
com.usercentrics.reactnative.fake so the package name matches the file path to
resolve the compilation error.

@@ -0,0 +1,73 @@
package com.usercentrics.reactnativemodule.fake
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Package naming inconsistency with the namespace refactor.

This file uses com.usercentrics.reactnativemodule.fake, while the other files in this PR have been refactored to use com.usercentrics.reactnative.*. This inconsistency could lead to confusion and maintainability issues.

Consider updating the package to align with the refactored namespace:

-package com.usercentrics.reactnativemodule.fake
+package com.usercentrics.reactnative.fake
🤖 Prompt for AI Agents
In android/src/test/java/com/usercentrics/reactnative/fake/FakePromise.kt around
line 1, the package declaration uses com.usercentrics.reactnativemodule.fake
which is inconsistent with the refactored namespace; change the package
declaration to follow the new namespace (e.g.,
com.usercentrics.reactnative.fake) and update any import or test references in
this file to match the new package name so it aligns with the rest of the PR.

Comment on lines +14 to +16
fun await() {
lock.await()
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

Add timeout to prevent indefinitely hanging tests.

The await() method blocks indefinitely if the promise is never resolved or rejected. This could cause tests to hang without a clear failure signal, making debugging difficult.

Apply this diff to add a timeout:

-fun await() {
-    lock.await()
-}
+fun await(timeoutSeconds: Long = 5) {
+    if (!lock.await(timeoutSeconds, java.util.concurrent.TimeUnit.SECONDS)) {
+        throw AssertionError("Promise was not resolved or rejected within $timeoutSeconds seconds")
+    }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fun await() {
lock.await()
}
fun await(timeoutSeconds: Long = 5) {
if (!lock.await(timeoutSeconds, java.util.concurrent.TimeUnit.SECONDS)) {
throw AssertionError("Promise was not resolved or rejected within $timeoutSeconds seconds")
}
}
🤖 Prompt for AI Agents
In android/src/test/java/com/usercentrics/reactnative/fake/FakePromise.kt around
lines 14 to 16, the await() method calls lock.await() which can block forever;
change it to wait with a bounded timeout and fail the test if the wait times
out. Replace the indefinite wait with lock.await(timeout, TimeUnit.MILLISECONDS)
(or a suitable TimeUnit) and throw/AssertionError/IllegalStateException (or use
test framework fail()) when await returns false to ensure the test fails rather
than hanging; pick a sensible timeout (e.g., a few seconds) and document the
choice in a brief comment.

@@ -0,0 +1,159 @@
package com.usercentrics.reactnativemodule
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Package naming inconsistency with the namespace refactor.

This file uses com.usercentrics.reactnativemodule, while the main source files have been refactored to com.usercentrics.reactnative.*. This inconsistency should be corrected to align with the repository-wide namespace refactor.

Apply this diff:

-package com.usercentrics.reactnativemodule
+package com.usercentrics.reactnative

Also update the import on line 3:

-import com.usercentrics.reactnativemodule.fake.FakePromise
+import com.usercentrics.reactnative.fake.FakePromise
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
package com.usercentrics.reactnativemodule
package com.usercentrics.reactnative
import com.usercentrics.reactnative.fake.FakePromise
🤖 Prompt for AI Agents
In
android/src/test/java/com/usercentrics/reactnative/RNUsercentricsModuleTest.kt
around line 1, the package declaration uses com.usercentrics.reactnativemodule
which is inconsistent with the repo-wide refactor to
com.usercentrics.reactnative; change the package line to
com.usercentrics.reactnative and update any import on line 3 to reference the
new package path (e.g., replace imports from
com.usercentrics.reactnativemodule.* to com.usercentrics.reactnative.*) so the
test file matches the main source namespace.

Comment on lines +10 to +14
androidGradlePlugin = "8.7.2"
gradle = "8.13"

# Kotlin
kotlin = "2.1.20"
kotlin = "2.0.21"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify dependency version compatibility.

Multiple dependency versions were updated:

  • Android Gradle Plugin: 8.5.2 → 8.7.2 (upgrade)
  • Gradle: 8.8.2 → 8.13 (upgrade)
  • Kotlin: 2.1.20 → 2.0.21 (downgrade)

The Kotlin downgrade is unusual and should be verified for compatibility with:

  • AGP 8.7.2 (which typically supports newer Kotlin versions)
  • React Native 0.79.6
  • Other project dependencies

Additionally, run this script to check for compatibility issues:


🏁 Script executed:

#!/bin/bash
# Description: Check for version compatibility warnings in build logs

# Search for any version compatibility issues in gradle files
echo "=== Checking Gradle version requirements ==="
rg -n "gradle.*version|kotlinVersion" --type gradle sample/android/

# Check for any deprecated API usage that might be affected by AGP upgrade
echo -e "\n=== Checking for deprecated Gradle APIs ==="
rg -n "deprecated|Deprecated" sample/android/build.gradle.kts sample/android/app/build.gradle.kts 2>/dev/null || echo "No build.gradle.kts files found or no deprecated API warnings"

Length of output: 151


🌐 Web query:

What is the recommended Kotlin version for Android Gradle Plugin 8.7.2?

💡 Result:

Recommended Kotlin: Kotlin 2.1 (use a 2.1.x KGP, e.g. 2.1.20–2.1.21). (kotlinlang.org)

Citations:


Align Kotlin version with AGP 8.7.2 compatibility.
Kotlin was downgraded to 2.0.21, but AGP 8.7.2 recommends Kotlin 2.1.x; bump the version in sample/android/gradle/libs.versions.toml (line 14) to at least 2.1.20.

🤖 Prompt for AI Agents
In sample/android/gradle/libs.versions.toml around lines 10 to 14, the Kotlin
version is set to 2.0.21 which is incompatible with AGP 8.7.2; update the kotlin
entry on line 14 to at least 2.1.20 (e.g., set kotlin = "2.1.20" or a matching
2.1.x release) so the Kotlin version aligns with AGP 8.7.2 compatibility.

android: {
sourceDir: require('path').resolve(__dirname, '../android'),
packageImportPath: 'import com.usercentrics.reactnativeusercentrics.RNUsercentricsPackage;',
packageImportPath: 'import com.usercentrics.reactnative.RNUsercentricsPackage;',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify the package namespace refactor is complete.

The package import path has been updated from com.usercentrics.reactnativeusercentrics.RNUsercentricsPackage to com.usercentrics.reactnative.RNUsercentricsPackage. Ensure that:

  1. The RNUsercentricsPackage class exists at the new package location
  2. All references to the old package name have been updated throughout the codebase
  3. The Android module's package declaration matches this new path

Run the following script to verify the package refactor:


🏁 Script executed:

#!/bin/bash
# Description: Verify the package namespace refactor is complete

# Find the RNUsercentricsPackage class at the new location
echo "=== Searching for RNUsercentricsPackage in new location ==="
fd -e kt -e java RNUsercentricsPackage | head -10
rg -n "^package com\.usercentrics\.reactnative" android/src --type kotlin --type java | head -20

# Check for any remaining references to old package name
echo -e "\n=== Checking for old package references ==="
rg -n "com\.usercentrics\.reactnativeusercentrics" --type kotlin --type java --type js --type gradle | head -20

Length of output: 4055


Update remaining old package references

  • In legacy-sample/react-native.config.js and example/react-native.config.js, change
    import com.usercentrics.reactnativeusercentrics.RNUsercentricsPackage
    import com.usercentrics.reactnative.RNUsercentricsPackage
  • In android/src/androidTest/java/com/usercentrics/reactnative/… (e.g. RNUsercentricsModuleTest.kt, SaveDecisionsForTCFMock.kt, ReactContextProviderMock.kt, FakeUsercentricsProxy.kt), update all imports from
    com.usercentrics.reactnativeusercentrics.*
    com.usercentrics.reactnative.*
🤖 Prompt for AI Agents
In sample/react-native.config.js around line 13 and in
legacy-sample/react-native.config.js and example/react-native.config.js (same
location), replace the old package import reference by changing any occurrence
of "import com.usercentrics.reactnativeusercentrics.RNUsercentricsPackage" to
"import com.usercentrics.reactnative.RNUsercentricsPackage"; additionally, in
all android test sources under
android/src/androidTest/java/com/usercentrics/reactnative (e.g.
RNUsercentricsModuleTest.kt, SaveDecisionsForTCFMock.kt,
ReactContextProviderMock.kt, FakeUsercentricsProxy.kt) update imports that
reference "com.usercentrics.reactnativeusercentrics.*" to
"com.usercentrics.reactnative.*" so all package paths consistently use
com.usercentrics.reactnative.

Comment on lines +27 to +33
# 1. Disable ENABLE_USER_SCRIPT_SANDBOXING
echo "🔧 Disabling user script sandboxing..."
sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES;/ENABLE_USER_SCRIPT_SANDBOXING = NO;/g' "$PODS_PROJECT"
sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES/ENABLE_USER_SCRIPT_SANDBOXING = NO/g' "$PODS_PROJECT"

SANDBOX_CHANGES=$(grep -c "ENABLE_USER_SCRIPT_SANDBOXING = NO" "$PODS_PROJECT" || true)
echo "✅ Disabled sandbox in $SANDBOX_CHANGES locations"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Portability concern: BSD sed syntax.

The -i '' syntax is BSD sed (macOS) specific and will fail on Linux (GNU sed). Since the comment at Line 4 indicates this is a backup solution, consider either:

  • Documenting the macOS-only limitation
  • Using portable sed syntax: sed -i.bak (works on both)

Apply this diff for portability:

-sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES;/ENABLE_USER_SCRIPT_SANDBOXING = NO;/g' "$PODS_PROJECT"
-sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES/ENABLE_USER_SCRIPT_SANDBOXING = NO/g' "$PODS_PROJECT"
+sed -i.bak 's/ENABLE_USER_SCRIPT_SANDBOXING = YES;/ENABLE_USER_SCRIPT_SANDBOXING = NO;/g' "$PODS_PROJECT"
+sed -i.bak 's/ENABLE_USER_SCRIPT_SANDBOXING = YES/ENABLE_USER_SCRIPT_SANDBOXING = NO/g' "$PODS_PROJECT"
+rm -f "$PODS_PROJECT.bak"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# 1. Disable ENABLE_USER_SCRIPT_SANDBOXING
echo "🔧 Disabling user script sandboxing..."
sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES;/ENABLE_USER_SCRIPT_SANDBOXING = NO;/g' "$PODS_PROJECT"
sed -i '' 's/ENABLE_USER_SCRIPT_SANDBOXING = YES/ENABLE_USER_SCRIPT_SANDBOXING = NO/g' "$PODS_PROJECT"
SANDBOX_CHANGES=$(grep -c "ENABLE_USER_SCRIPT_SANDBOXING = NO" "$PODS_PROJECT" || true)
echo "✅ Disabled sandbox in $SANDBOX_CHANGES locations"
# 1. Disable ENABLE_USER_SCRIPT_SANDBOXING
echo "🔧 Disabling user script sandboxing..."
sed -i.bak 's/ENABLE_USER_SCRIPT_SANDBOXING = YES;/ENABLE_USER_SCRIPT_SANDBOXING = NO;/g' "$PODS_PROJECT"
sed -i.bak 's/ENABLE_USER_SCRIPT_SANDBOXING = YES/ENABLE_USER_SCRIPT_SANDBOXING = NO/g' "$PODS_PROJECT"
rm -f "$PODS_PROJECT.bak"
SANDBOX_CHANGES=$(grep -c "ENABLE_USER_SCRIPT_SANDBOXING = NO" "$PODS_PROJECT" || true)
echo "✅ Disabled sandbox in $SANDBOX_CHANGES locations"
🤖 Prompt for AI Agents
In sample/scripts/fix-xcode-sandbox.sh around lines 27 to 33 the script uses
BSD-only sed with the -i '' inline-edit flag which will fail on GNU sed (Linux);
make it portable by either detecting platform (use uname to choose BSD vs GNU
behavior) or replace the inline edit with a cross-platform form such as sed
-i.bak 's/.../.../g' and then remove the .bak files afterwards (or document that
the script is macOS-only). Ensure both sed invocations are updated consistently
and any created .bak files are cleaned up.

Comment on lines +101 to +103
# Get absolute path of the package
PACKAGE_PATH=$(realpath "$PACKAGE_FILE")
print_info "Package path: $PACKAGE_PATH"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Portability concern: realpath command.

The realpath command (Line 102) is not available by default on macOS without installing coreutils. This could cause the script to fail on macOS systems.

Consider using a portable alternative:

-PACKAGE_PATH=$(realpath "$PACKAGE_FILE")
+PACKAGE_PATH=$(cd "$(dirname "$PACKAGE_FILE")" && pwd -P)/$(basename "$PACKAGE_FILE")

Or check for realpath availability upfront with a warning.

🤖 Prompt for AI Agents
In scripts/publish-local.sh around lines 101 to 103, the script uses realpath
which is not available by default on macOS; replace this with a portable
approach: first detect if realpath exists and use it, otherwise try a fallback
such as readlink -f (if available) or a small Python/Perl POSIX-resolve
one-liner to compute the absolute path, and if none are available print a clear
warning and exit with a non-zero status; update the script so PACKAGE_PATH is
assigned using the detected working method and add a brief comment documenting
the fallback sequence.

@@ -1,5 +1,4 @@
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
import { NativeModules } from 'react-native';
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Verify the TurboModule to NativeModules migration rationale.

The import has been changed from TurboModuleRegistry to NativeModules, representing a move away from React Native's new architecture (TurboModules) to the legacy bridge architecture.

Please confirm:

  1. Is this migration intentional?
  2. Does this affect new architecture support?
  3. Are there compatibility implications for existing users?

🏁 Script executed:

#!/bin/bash
# Description: Check for any documentation or comments about the TurboModule migration

# Search for TurboModule references and migration notes
rg -i "turbomodule|new.*architecture" --type md --type ts -C 3

# Check for related config changes
rg "newArchEnabled" --type kotlin --type java -C 2

Length of output: 3163


Reinstate conditional TurboModule usage in src/NativeUsercentrics.ts
Wrap the import to call TurboModuleRegistry.getEnforcing when newArchEnabled=true, fallback to NativeModules, and update documentation to reflect new-architecture support.

🤖 Prompt for AI Agents
In src/NativeUsercentrics.ts around line 1, restore conditional TurboModule
usage for the new architecture: import TurboModuleRegistry (and NativeModules)
from 'react-native' and select the native implementation with
TurboModuleRegistry.getEnforcing('Usercentrics') when the newArch is enabled
(i.e. the turbo registry is available) and fall back to
NativeModules.Usercentrics when it is not; then export that selected module as
the default/native bridge. Also update the module comment/docs to note support
for the new architecture and the conditional selection logic.

@uc-brunosilva uc-brunosilva merged commit d9f830a into master Oct 6, 2025
3 of 4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 27, 2025
@uc-brunosouza uc-brunosouza deleted the fix/cannot-find-symbol-RNUsercentricsPackage branch October 31, 2025 12:26
@coderabbitai coderabbitai bot mentioned this pull request Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants