Conversation
|
Caution Review failedThe pull request is closed. WalkthroughThis update introduces an Expo config plugin version 0.9.4-alpha.4 adding support for Expo Android integration. It includes new TypeScript source files for Android manifest and Gradle modifications, configuration files, build scripts, and example project setup. It updates package metadata, TypeScript settings, and documentation. The GitHub Actions CI workflow and setup action were removed. Changes
Sequence Diagram(s)sequenceDiagram
participant AppConfig
participant withReclaimInAppSdk
participant withReclaimAndroidManifest
participant withReclaimProjectBuildGradle
AppConfig->>withReclaimInAppSdk: Apply plugin
withReclaimInAppSdk->>withReclaimAndroidManifest: Modify AndroidManifest.xml
withReclaimInAppSdk->>withReclaimProjectBuildGradle: Modify project build.gradle
withReclaimAndroidManifest-->>withReclaimInAppSdk: Return updated config
withReclaimProjectBuildGradle-->>withReclaimInAppSdk: Return updated config
withReclaimInAppSdk-->>AppConfig: Return fully updated config
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
expo-plugin/src/index.ts (1)
1-14: Fix formatting issues flagged by Prettier.The plugin logic is correct and follows Expo plugin patterns well. However, there are several formatting issues that need to be addressed.
Apply this diff to fix the formatting issues:
-import { type ConfigPlugin, withPlugins } from '@expo/config-plugins'; -import { - installReclaimAndroidManifest, - installReclaimProjectBuildGradle, -} from './android'; +import { type ConfigPlugin, withPlugins } from '@expo/config-plugins'; +import { + installReclaimAndroidManifest, + installReclaimProjectBuildGradle, +} from './android'; const withReclaimInAppSdk: ConfigPlugin = (config) => { - return withPlugins(config, [ - installReclaimAndroidManifest, - installReclaimProjectBuildGradle, - ]); + return withPlugins(config, [ + installReclaimAndroidManifest, + installReclaimProjectBuildGradle, + ]); };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
CHANGELOG.md(1 hunks)app.plugin.js(1 hunks)expo-plugin/src/android/index.ts(1 hunks)expo-plugin/src/android/install_reclaim_android_manifest.ts(1 hunks)expo-plugin/src/android/install_reclaim_project_build_gradle.ts(1 hunks)expo-plugin/src/index.ts(1 hunks)expo-plugin/tsconfig.json(1 hunks)package.json(4 hunks)
🧰 Additional context used
🪛 ESLint
expo-plugin/src/index.ts
[error] 3-3: Delete ··
(prettier/prettier)
[error] 4-4: Delete ··
(prettier/prettier)
[error] 8-8: Delete ··
(prettier/prettier)
[error] 9-9: Replace ········ with ····
(prettier/prettier)
[error] 10-10: Replace ········ with ····
(prettier/prettier)
[error] 11-11: Delete ··
(prettier/prettier)
expo-plugin/src/android/install_reclaim_project_build_gradle.ts
[error] 2-2: Delete ··
(prettier/prettier)
[error] 3-3: Delete ··
(prettier/prettier)
[error] 7-7: Delete ··
(prettier/prettier)
[error] 8-8: Replace ····const·flutterStorageUrl·=·process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||·config.android['FLUTTER_STORAGE_BASE_URL']·||·"https://storage.googleapis.com" with const·flutterStorageUrl·=⏎······process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||⏎······config.android['FLUTTER_STORAGE_BASE_URL']·||⏎······'https://storage.googleapis.com';
(prettier/prettier)
[error] 9-9: Replace ····const·reclaimStorageUrl·=·process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||·config.android['RECLAIM_STORAGE_BASE_URL']·||·"https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" with const·reclaimStorageUrl·=⏎······process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||⏎······config.android['RECLAIM_STORAGE_BASE_URL']·||⏎······'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo';
(prettier/prettier)
[error] 11-11: Delete ····
(prettier/prettier)
[error] 12-12: Replace ············ with ······
(prettier/prettier)
[error] 13-13: Delete ········
(prettier/prettier)
[error] 14-14: Delete ········
(prettier/prettier)
[error] 18-18: Delete ······
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 21-21: Delete ··
(prettier/prettier)
[error] 22-22: Insert ⏎
(prettier/prettier)
expo-plugin/src/android/install_reclaim_android_manifest.ts
[error] 4-4: Delete ··
(prettier/prettier)
[error] 5-5: Delete ····
(prettier/prettier)
[error] 6-6: Delete ····
(prettier/prettier)
[error] 8-8: Replace ········ with ····
(prettier/prettier)
[error] 9-9: Delete ······
(prettier/prettier)
[error] 10-10: Replace ········ with ····
(prettier/prettier)
[error] 12-13: Delete ⏎····
(prettier/prettier)
[error] 15-15: Delete ····
(prettier/prettier)
[error] 16-16: Replace ········ with ····
(prettier/prettier)
[error] 17-17: Delete ····
(prettier/prettier)
[error] 18-18: Replace ········ with ····
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 22-22: Delete ····
(prettier/prettier)
[error] 23-23: Replace ············ with ······
(prettier/prettier)
[error] 24-24: Delete ····
(prettier/prettier)
[error] 26-26: Replace ········ with ····
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 28-29: Replace ················act.$['android:name']·!=⏎··············· with ········act.$['android:name']·!=
(prettier/prettier)
[error] 30-30: Replace ········ with ····
(prettier/prettier)
[error] 32-32: Delete ····
(prettier/prettier)
[error] 33-33: Replace ············ with ······
(prettier/prettier)
[error] 34-34: Delete ········
(prettier/prettier)
[error] 35-35: Replace ················ with ········
(prettier/prettier)
[error] 36-36: Replace ················'android:configChanges': with ········'android:configChanges':⏎·········
(prettier/prettier)
[error] 37-37: Delete ········
(prettier/prettier)
[error] 38-38: Replace ················ with ········
(prettier/prettier)
[error] 39-39: Delete ······
(prettier/prettier)
[error] 40-40: Delete ····
(prettier/prettier)
[error] 42-42: Delete ····
(prettier/prettier)
[error] 43-43: Delete ··
(prettier/prettier)
[error] 44-44: Insert ⏎
(prettier/prettier)
🔇 Additional comments (8)
expo-plugin/tsconfig.json (1)
1-11: LGTM! Standard TypeScript configuration for Expo plugin.The configuration is well-structured with appropriate compiler options for building a plugin that generates declaration files and outputs to a build directory.
CHANGELOG.md (1)
1-4: LGTM! Clear changelog entry for the new Expo Android support.The entry properly documents the new feature addition with appropriate version numbering.
app.plugin.js (1)
1-1: LGTM! Standard Expo plugin entry point pattern.This follows the common practice of re-exporting the built plugin for easy consumption by Expo projects.
expo-plugin/src/android/index.ts (1)
1-2: LGTM! Clean export pattern for Android plugins.The named exports provide a clear interface for the Android-specific plugin functionality.
package.json (4)
3-3: LGTM: Version bump is appropriate.The version increment from 0.9.2 to 0.9.3 correctly reflects the addition of new Expo plugin functionality.
23-23: LGTM: Expo plugin directory properly included.Adding the "expo-plugin" directory to the files array ensures the plugin code will be included in the published package.
51-53: LGTM: Build scripts properly configured.The build scripts correctly ensure that both the main SDK and the Expo plugin are compiled during prepare and prepack phases. The TypeScript compilation for the expo-plugin directory is properly configured.
77-77: LGTM: Appropriate dependency for Expo plugin development.The @expo/config-plugins dependency is correctly added as a devDependency, which is the standard approach for Expo plugin development.
| import { | ||
| type ConfigPlugin, | ||
| withProjectBuildGradle, | ||
| } from '@expo/config-plugins'; | ||
|
|
||
| export const installReclaimProjectBuildGradle: ConfigPlugin = (config) => { | ||
| return withProjectBuildGradle(config, async (config) => { | ||
| const flutterStorageUrl = process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || config.android['FLUTTER_STORAGE_BASE_URL'] || "https://storage.googleapis.com" | ||
| const reclaimStorageUrl = process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || config.android['RECLAIM_STORAGE_BASE_URL'] || "https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" | ||
|
|
||
| if (!config.modResults.contents.match('reclaim-inapp-sdk')) { | ||
| config.modResults.contents = config.modResults.contents.replace( | ||
| /mavenCentral\(\)/g, | ||
| ` | ||
| mavenCentral() | ||
| maven { url "${reclaimStorageUrl}" } | ||
| maven { url "${flutterStorageUrl}/download.flutter.io" }` | ||
| ); | ||
| } | ||
| return config; | ||
| }); | ||
| }; No newline at end of file |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix formatting issues and improve error handling.
The plugin logic is sound, but there are several formatting and potential robustness issues to address.
Apply this diff to fix formatting and improve error handling:
import {
- type ConfigPlugin,
- withProjectBuildGradle,
+ type ConfigPlugin,
+ withProjectBuildGradle,
} from '@expo/config-plugins';
export const installReclaimProjectBuildGradle: ConfigPlugin = (config) => {
- return withProjectBuildGradle(config, async (config) => {
- const flutterStorageUrl = process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || config.android['FLUTTER_STORAGE_BASE_URL'] || "https://storage.googleapis.com"
- const reclaimStorageUrl = process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || config.android['RECLAIM_STORAGE_BASE_URL'] || "https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo"
+ return withProjectBuildGradle(config, async (config) => {
+ const flutterStorageUrl =
+ process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL ||
+ config.android?.['FLUTTER_STORAGE_BASE_URL'] ||
+ 'https://storage.googleapis.com';
+ const reclaimStorageUrl =
+ process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL ||
+ config.android?.['RECLAIM_STORAGE_BASE_URL'] ||
+ 'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo';
- if (!config.modResults.contents.match('reclaim-inapp-sdk')) {
- config.modResults.contents = config.modResults.contents.replace(
- /mavenCentral\(\)/g,
- `
- mavenCentral()
- maven { url "${reclaimStorageUrl}" }
- maven { url "${flutterStorageUrl}/download.flutter.io" }`
- );
- }
- return config;
- });
+ if (!config.modResults.contents.match('reclaim-inapp-sdk')) {
+ config.modResults.contents = config.modResults.contents.replace(
+ /mavenCentral\(\)/g,
+ `mavenCentral()
+ maven { url "${reclaimStorageUrl}" }
+ maven { url "${flutterStorageUrl}/download.flutter.io" }`
+ );
+ }
+ return config;
+ });
};Key improvements:
- Fixed all formatting issues identified by Prettier
- Added optional chaining (
?.) for safer property access - Used consistent single quotes
- Improved template string formatting
📝 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.
| import { | |
| type ConfigPlugin, | |
| withProjectBuildGradle, | |
| } from '@expo/config-plugins'; | |
| export const installReclaimProjectBuildGradle: ConfigPlugin = (config) => { | |
| return withProjectBuildGradle(config, async (config) => { | |
| const flutterStorageUrl = process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || config.android['FLUTTER_STORAGE_BASE_URL'] || "https://storage.googleapis.com" | |
| const reclaimStorageUrl = process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || config.android['RECLAIM_STORAGE_BASE_URL'] || "https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" | |
| if (!config.modResults.contents.match('reclaim-inapp-sdk')) { | |
| config.modResults.contents = config.modResults.contents.replace( | |
| /mavenCentral\(\)/g, | |
| ` | |
| mavenCentral() | |
| maven { url "${reclaimStorageUrl}" } | |
| maven { url "${flutterStorageUrl}/download.flutter.io" }` | |
| ); | |
| } | |
| return config; | |
| }); | |
| }; | |
| import { | |
| type ConfigPlugin, | |
| withProjectBuildGradle, | |
| } from '@expo/config-plugins'; | |
| export const installReclaimProjectBuildGradle: ConfigPlugin = (config) => { | |
| return withProjectBuildGradle(config, async (config) => { | |
| const flutterStorageUrl = | |
| process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || | |
| config.android?.['FLUTTER_STORAGE_BASE_URL'] || | |
| 'https://storage.googleapis.com'; | |
| const reclaimStorageUrl = | |
| process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || | |
| config.android?.['RECLAIM_STORAGE_BASE_URL'] || | |
| 'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo'; | |
| if (!config.modResults.contents.match('reclaim-inapp-sdk')) { | |
| config.modResults.contents = config.modResults.contents.replace( | |
| /mavenCentral\(\)/g, | |
| `mavenCentral() | |
| maven { url "${reclaimStorageUrl}" } | |
| maven { url "${flutterStorageUrl}/download.flutter.io" }` | |
| ); | |
| } | |
| return config; | |
| }); | |
| }; |
🧰 Tools
🪛 ESLint
[error] 2-2: Delete ··
(prettier/prettier)
[error] 3-3: Delete ··
(prettier/prettier)
[error] 7-7: Delete ··
(prettier/prettier)
[error] 8-8: Replace ····const·flutterStorageUrl·=·process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||·config.android['FLUTTER_STORAGE_BASE_URL']·||·"https://storage.googleapis.com" with const·flutterStorageUrl·=⏎······process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||⏎······config.android['FLUTTER_STORAGE_BASE_URL']·||⏎······'https://storage.googleapis.com';
(prettier/prettier)
[error] 9-9: Replace ····const·reclaimStorageUrl·=·process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||·config.android['RECLAIM_STORAGE_BASE_URL']·||·"https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" with const·reclaimStorageUrl·=⏎······process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||⏎······config.android['RECLAIM_STORAGE_BASE_URL']·||⏎······'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo';
(prettier/prettier)
[error] 11-11: Delete ····
(prettier/prettier)
[error] 12-12: Replace ············ with ······
(prettier/prettier)
[error] 13-13: Delete ········
(prettier/prettier)
[error] 14-14: Delete ········
(prettier/prettier)
[error] 18-18: Delete ······
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 21-21: Delete ··
(prettier/prettier)
[error] 22-22: Insert ⏎
(prettier/prettier)
🤖 Prompt for AI Agents
In expo-plugin/src/android/install_reclaim_project_build_gradle.ts lines 1 to
22, fix formatting issues by aligning indentation and spacing consistently,
replace double quotes with single quotes for string literals, and improve
template string formatting for readability. Add optional chaining when accessing
config.android properties to avoid runtime errors if those properties are
undefined. These changes will enhance code robustness and maintain consistent
style.
| import { type ConfigPlugin, withAndroidManifest } from '@expo/config-plugins'; | ||
|
|
||
| export const installReclaimAndroidManifest: ConfigPlugin = (config) => { | ||
| return withAndroidManifest(config, (config) => { | ||
| let androidManifest = config.modResults.manifest; | ||
| const cannotInstallMessage = 'cannot install reclaim inapp android sdk'; | ||
|
|
||
| if (!androidManifest) { | ||
| throw new Error(`No AndroidManifest found, ${cannotInstallMessage}`); | ||
| } | ||
|
|
||
|
|
||
| let application = androidManifest.application![0]; | ||
|
|
||
| // Add the tools to apply permission remove | ||
| // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK. | ||
| // androidManifest.$ = { | ||
| // ...androidManifest.$, | ||
| // 'xmlns:tools': 'http://schemas.android.com/tools', | ||
| // }; | ||
|
|
||
| if (!application) { | ||
| throw new Error(`No base application found, ${cannotInstallMessage}`); | ||
| } | ||
|
|
||
| application.activity = application.activity!.filter( | ||
| (act) => | ||
| act.$['android:name'] != | ||
| 'org.reclaimprotocol.inapp_sdk.ReclaimActivity' | ||
| ); | ||
|
|
||
| application.activity.push({ | ||
| $: { | ||
| 'android:name': 'org.reclaimprotocol.inapp_sdk.ReclaimActivity', | ||
| 'android:theme': '@style/Theme.ReclaimInAppSdk.LaunchTheme', | ||
| 'android:configChanges': 'orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode', | ||
| 'android:hardwareAccelerated': 'true', | ||
| 'android:windowSoftInputMode': 'adjustResize', | ||
| }, | ||
| }); | ||
|
|
||
| return config; | ||
| }); | ||
| }; No newline at end of file |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Fix extensive formatting issues while preserving solid logic.
The plugin logic is well-structured with proper error handling and duplicate prevention, but requires significant formatting fixes.
Apply this diff to fix all formatting issues:
import { type ConfigPlugin, withAndroidManifest } from '@expo/config-plugins';
export const installReclaimAndroidManifest: ConfigPlugin = (config) => {
- return withAndroidManifest(config, (config) => {
- let androidManifest = config.modResults.manifest;
- const cannotInstallMessage = 'cannot install reclaim inapp android sdk';
+ return withAndroidManifest(config, (config) => {
+ let androidManifest = config.modResults.manifest;
+ const cannotInstallMessage = 'cannot install reclaim inapp android sdk';
- if (!androidManifest) {
- throw new Error(`No AndroidManifest found, ${cannotInstallMessage}`);
- }
-
-
- let application = androidManifest.application![0];
+ if (!androidManifest) {
+ throw new Error(`No AndroidManifest found, ${cannotInstallMessage}`);
+ }
- // Add the tools to apply permission remove
- // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK.
- // androidManifest.$ = {
- // ...androidManifest.$,
- // 'xmlns:tools': 'http://schemas.android.com/tools',
- // };
+ let application = androidManifest.application![0];
- if (!application) {
- throw new Error(`No base application found, ${cannotInstallMessage}`);
- }
+ // Add the tools to apply permission remove
+ // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK.
+ // androidManifest.$ = {
+ // ...androidManifest.$,
+ // 'xmlns:tools': 'http://schemas.android.com/tools',
+ // };
- application.activity = application.activity!.filter(
- (act) =>
- act.$['android:name'] !=
- 'org.reclaimprotocol.inapp_sdk.ReclaimActivity'
- );
+ if (!application) {
+ throw new Error(`No base application found, ${cannotInstallMessage}`);
+ }
- application.activity.push({
- $: {
- 'android:name': 'org.reclaimprotocol.inapp_sdk.ReclaimActivity',
- 'android:theme': '@style/Theme.ReclaimInAppSdk.LaunchTheme',
- 'android:configChanges': 'orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode',
- 'android:hardwareAccelerated': 'true',
- 'android:windowSoftInputMode': 'adjustResize',
- },
- });
+ application.activity = application.activity!.filter(
+ (act) =>
+ act.$['android:name'] != 'org.reclaimprotocol.inapp_sdk.ReclaimActivity'
+ );
- return config;
- });
+ application.activity.push({
+ $: {
+ 'android:name': 'org.reclaimprotocol.inapp_sdk.ReclaimActivity',
+ 'android:theme': '@style/Theme.ReclaimInAppSdk.LaunchTheme',
+ 'android:configChanges':
+ 'orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode',
+ 'android:hardwareAccelerated': 'true',
+ 'android:windowSoftInputMode': 'adjustResize',
+ },
+ });
+
+ return config;
+ });
};The core logic is excellent with proper error handling and duplicate prevention. The activity configuration appears appropriate for Android SDK integration.
📝 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.
| import { type ConfigPlugin, withAndroidManifest } from '@expo/config-plugins'; | |
| export const installReclaimAndroidManifest: ConfigPlugin = (config) => { | |
| return withAndroidManifest(config, (config) => { | |
| let androidManifest = config.modResults.manifest; | |
| const cannotInstallMessage = 'cannot install reclaim inapp android sdk'; | |
| if (!androidManifest) { | |
| throw new Error(`No AndroidManifest found, ${cannotInstallMessage}`); | |
| } | |
| let application = androidManifest.application![0]; | |
| // Add the tools to apply permission remove | |
| // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK. | |
| // androidManifest.$ = { | |
| // ...androidManifest.$, | |
| // 'xmlns:tools': 'http://schemas.android.com/tools', | |
| // }; | |
| if (!application) { | |
| throw new Error(`No base application found, ${cannotInstallMessage}`); | |
| } | |
| application.activity = application.activity!.filter( | |
| (act) => | |
| act.$['android:name'] != | |
| 'org.reclaimprotocol.inapp_sdk.ReclaimActivity' | |
| ); | |
| application.activity.push({ | |
| $: { | |
| 'android:name': 'org.reclaimprotocol.inapp_sdk.ReclaimActivity', | |
| 'android:theme': '@style/Theme.ReclaimInAppSdk.LaunchTheme', | |
| 'android:configChanges': 'orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode', | |
| 'android:hardwareAccelerated': 'true', | |
| 'android:windowSoftInputMode': 'adjustResize', | |
| }, | |
| }); | |
| return config; | |
| }); | |
| }; | |
| import { type ConfigPlugin, withAndroidManifest } from '@expo/config-plugins'; | |
| export const installReclaimAndroidManifest: ConfigPlugin = (config) => { | |
| return withAndroidManifest(config, (config) => { | |
| let androidManifest = config.modResults.manifest; | |
| const cannotInstallMessage = 'cannot install reclaim inapp android sdk'; | |
| if (!androidManifest) { | |
| throw new Error(`No AndroidManifest found, ${cannotInstallMessage}`); | |
| } | |
| let application = androidManifest.application![0]; | |
| // Add the tools to apply permission remove | |
| // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK. | |
| // androidManifest.$ = { | |
| // ...androidManifest.$, | |
| // 'xmlns:tools': 'http://schemas.android.com/tools', | |
| // }; | |
| if (!application) { | |
| throw new Error(`No base application found, ${cannotInstallMessage}`); | |
| } | |
| application.activity = application.activity!.filter( | |
| (act) => | |
| act.$['android:name'] != 'org.reclaimprotocol.inapp_sdk.ReclaimActivity' | |
| ); | |
| application.activity.push({ | |
| $: { | |
| 'android:name': 'org.reclaimprotocol.inapp_sdk.ReclaimActivity', | |
| 'android:theme': '@style/Theme.ReclaimInAppSdk.LaunchTheme', | |
| 'android:configChanges': | |
| 'orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode', | |
| 'android:hardwareAccelerated': 'true', | |
| 'android:windowSoftInputMode': 'adjustResize', | |
| }, | |
| }); | |
| return config; | |
| }); | |
| }; |
🧰 Tools
🪛 ESLint
[error] 4-4: Delete ··
(prettier/prettier)
[error] 5-5: Delete ····
(prettier/prettier)
[error] 6-6: Delete ····
(prettier/prettier)
[error] 8-8: Replace ········ with ····
(prettier/prettier)
[error] 9-9: Delete ······
(prettier/prettier)
[error] 10-10: Replace ········ with ····
(prettier/prettier)
[error] 12-13: Delete ⏎····
(prettier/prettier)
[error] 15-15: Delete ····
(prettier/prettier)
[error] 16-16: Replace ········ with ····
(prettier/prettier)
[error] 17-17: Delete ····
(prettier/prettier)
[error] 18-18: Replace ········ with ····
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 22-22: Delete ····
(prettier/prettier)
[error] 23-23: Replace ············ with ······
(prettier/prettier)
[error] 24-24: Delete ····
(prettier/prettier)
[error] 26-26: Replace ········ with ····
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 28-29: Replace ················act.$['android:name']·!=⏎··············· with ········act.$['android:name']·!=
(prettier/prettier)
[error] 30-30: Replace ········ with ····
(prettier/prettier)
[error] 32-32: Delete ····
(prettier/prettier)
[error] 33-33: Replace ············ with ······
(prettier/prettier)
[error] 34-34: Delete ········
(prettier/prettier)
[error] 35-35: Replace ················ with ········
(prettier/prettier)
[error] 36-36: Replace ················'android:configChanges': with ········'android:configChanges':⏎·········
(prettier/prettier)
[error] 37-37: Delete ········
(prettier/prettier)
[error] 38-38: Replace ················ with ········
(prettier/prettier)
[error] 39-39: Delete ······
(prettier/prettier)
[error] 40-40: Delete ····
(prettier/prettier)
[error] 42-42: Delete ····
(prettier/prettier)
[error] 43-43: Delete ··
(prettier/prettier)
[error] 44-44: Insert ⏎
(prettier/prettier)
🤖 Prompt for AI Agents
In expo-plugin/src/android/install_reclaim_android_manifest.ts lines 1 to 44,
the code logic is solid but the formatting is inconsistent and needs cleanup.
Fix indentation to be uniform, remove unnecessary blank lines, and ensure
consistent spacing around operators and braces. Also, uncomment and properly
format the androidManifest.$ assignment to add the 'xmlns:tools' attribute as
intended. Preserve all existing logic and error handling while improving
readability and style.
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (4)
expo-plugin/src/index.ts (1)
7-12: Fix formatting in the plugin implementation.The plugin logic is correct, but the formatting needs to be consistent.
Apply this diff to fix the formatting:
const withReclaimInAppSdk: ConfigPlugin = (config) => { - return withPlugins(config, [ - withReclaimAndroidManifest, - withReclaimProjectBuildGradle, - ]); + return withPlugins(config, [ + withReclaimAndroidManifest, + withReclaimProjectBuildGradle, + ]); };expo-plugin/src/android/withReclaimProjectBuildGradle.ts (2)
8-9: Add missing semicolons and improve variable declarations.The variable declarations are missing semicolons, which is inconsistent with TypeScript best practices.
Apply this diff to add semicolons:
- const flutterStorageUrl = process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || "https://storage.googleapis.com" - const reclaimStorageUrl = process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || "https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" + const flutterStorageUrl = + process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL || + 'https://storage.googleapis.com'; + const reclaimStorageUrl = + process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL || + 'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo';
11-19: Consider more targeted repository injection approach.The current implementation replaces ALL occurrences of
mavenCentral()which could potentially affect unrelated repository configurations. Also, the hardcoded indentation might not match the original file's formatting.Consider a more targeted approach that adds repositories to a specific repositories block:
- if (!config.modResults.contents.match('reclaim-inapp-sdk')) { - config.modResults.contents = config.modResults.contents.replace( - /mavenCentral\(\)/g, - ` - mavenCentral() - maven { url "${reclaimStorageUrl}" } - maven { url "${flutterStorageUrl}/download.flutter.io" }` - ); - } + if (!config.modResults.contents.includes('reclaim-inapp-sdk')) { + // Find the allprojects repositories block and add our repositories + const repositoriesRegex = /(allprojects\s*\{[\s\S]*?repositories\s*\{[^}]*)(mavenCentral\(\))/; + if (repositoriesRegex.test(config.modResults.contents)) { + config.modResults.contents = config.modResults.contents.replace( + repositoriesRegex, + `$1$2 + maven { url "${reclaimStorageUrl}" } + maven { url "${flutterStorageUrl}/download.flutter.io" }` + ); + } + }This approach is more targeted and preserves the original indentation style.
expo-plugin/src/android/withReclaimAndroidManifest.ts (1)
15-21: Consider removing or documenting the commented code.The commented code block for adding tools namespace should either be removed if not needed, or properly documented if it might be used in the future.
If this code is not needed, remove it:
- // Add the tools to apply permission remove - // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK. - // androidManifest.$ = { - // ...androidManifest.$, - // 'xmlns:tools': 'http://schemas.android.com/tools', - // };Or if it's for future use, improve the documentation:
- // Add the tools to apply permission remove - // Let the consumer app apply the permission on their app. All permissions are optional for this Reclaim InApp SDK. - // androidManifest.$ = { - // ...androidManifest.$, - // 'xmlns:tools': 'http://schemas.android.com/tools', - // }; + // TODO: Uncomment this if we need to remove permissions in the future + // Currently, we let the consumer app handle all permissions since they are optional + // androidManifest.$ = { + // ...androidManifest.$, + // 'xmlns:tools': 'http://schemas.android.com/tools', + // };
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
.github/actions/setup/action.yml(0 hunks).github/workflows/ci.yml(0 hunks)expo-plugin/src/android/index.ts(1 hunks)expo-plugin/src/android/withReclaimAndroidManifest.ts(1 hunks)expo-plugin/src/android/withReclaimProjectBuildGradle.ts(1 hunks)expo-plugin/src/index.ts(1 hunks)expo-plugin/tsconfig.json(1 hunks)package.json(4 hunks)tsconfig.build.json(1 hunks)tsconfig.json(1 hunks)
💤 Files with no reviewable changes (2)
- .github/actions/setup/action.yml
- .github/workflows/ci.yml
✅ Files skipped from review due to trivial changes (2)
- tsconfig.build.json
- tsconfig.json
🚧 Files skipped from review as they are similar to previous changes (3)
- expo-plugin/tsconfig.json
- expo-plugin/src/android/index.ts
- package.json
🧰 Additional context used
🧬 Code Graph Analysis (1)
expo-plugin/src/android/withReclaimProjectBuildGradle.ts (2)
expo-plugin/src/android/index.ts (1)
withReclaimProjectBuildGradle(2-2)ios/inapp_rn_sdk/Api.swift (1)
process(541-566)
🪛 ESLint
expo-plugin/src/android/withReclaimProjectBuildGradle.ts
[error] 2-2: Delete ··
(prettier/prettier)
[error] 3-3: Delete ··
(prettier/prettier)
[error] 7-7: Delete ··
(prettier/prettier)
[error] 8-8: Replace ····const·flutterStorageUrl·=·process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||·"https://storage.googleapis.com" with const·flutterStorageUrl·=⏎······process.env.EXPO_PUBLIC_FLUTTER_STORAGE_BASE_URL·||⏎······'https://storage.googleapis.com';
(prettier/prettier)
[error] 9-9: Replace ········const·reclaimStorageUrl·=·process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||·"https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo" with ····const·reclaimStorageUrl·=⏎······process.env.EXPO_PUBLIC_RECLAIM_STORAGE_BASE_URL·||⏎······'https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo';
(prettier/prettier)
[error] 11-11: Replace ········ with ····
(prettier/prettier)
[error] 12-12: Replace ············ with ······
(prettier/prettier)
[error] 13-13: Replace ················ with ········
(prettier/prettier)
[error] 14-14: Insert ····
(prettier/prettier)
[error] 18-18: Delete ······
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 21-21: Delete ··
(prettier/prettier)
expo-plugin/src/android/withReclaimAndroidManifest.ts
[error] 4-4: Delete ··
(prettier/prettier)
[error] 5-5: Delete ····
(prettier/prettier)
[error] 6-6: Delete ····
(prettier/prettier)
[error] 8-8: Replace ········ with ····
(prettier/prettier)
[error] 9-9: Delete ······
(prettier/prettier)
[error] 10-10: Replace ········ with ····
(prettier/prettier)
[error] 12-13: Delete ⏎····
(prettier/prettier)
[error] 15-15: Delete ····
(prettier/prettier)
[error] 16-16: Replace ········ with ····
(prettier/prettier)
[error] 17-17: Delete ····
(prettier/prettier)
[error] 18-18: Replace ········ with ····
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ····
(prettier/prettier)
[error] 22-22: Delete ····
(prettier/prettier)
[error] 23-23: Replace ············ with ······
(prettier/prettier)
[error] 24-24: Delete ····
(prettier/prettier)
[error] 26-26: Replace ········ with ····
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 28-29: Replace ················act.$['android:name']·!=⏎··············· with ········act.$['android:name']·!=
(prettier/prettier)
[error] 30-30: Replace ········ with ····
(prettier/prettier)
[error] 32-32: Delete ····
(prettier/prettier)
[error] 33-33: Replace ············ with ······
(prettier/prettier)
[error] 34-34: Delete ········
(prettier/prettier)
[error] 35-35: Replace ················ with ········
(prettier/prettier)
[error] 36-36: Replace ················'android:configChanges': with ········'android:configChanges':⏎·········
(prettier/prettier)
[error] 37-37: Delete ········
(prettier/prettier)
[error] 38-38: Replace ················ with ········
(prettier/prettier)
[error] 39-39: Delete ······
(prettier/prettier)
[error] 40-40: Delete ····
(prettier/prettier)
[error] 42-42: Delete ····
(prettier/prettier)
[error] 43-43: Delete ··
(prettier/prettier)
[error] 44-44: Insert ⏎
(prettier/prettier)
expo-plugin/src/index.ts
[error] 1-1: Replace ·type·ConfigPlugin,·createRunOncePlugin,·withPlugins· with ⏎··type·ConfigPlugin,⏎··createRunOncePlugin,⏎··withPlugins,⏎
(prettier/prettier)
[error] 1-1: 'createRunOncePlugin' is defined but never used.
(@typescript-eslint/no-unused-vars)
[error] 3-3: Delete ··
(prettier/prettier)
[error] 4-4: Delete ··
(prettier/prettier)
[error] 8-8: Delete ··
(prettier/prettier)
[error] 9-9: Delete ····
(prettier/prettier)
[error] 10-10: Delete ····
(prettier/prettier)
[error] 11-11: Delete ··
(prettier/prettier)
🔇 Additional comments (1)
expo-plugin/src/android/withReclaimAndroidManifest.ts (1)
32-40: LGTM! Activity configuration looks comprehensive.The ReclaimActivity configuration includes all necessary attributes for proper Android integration, including theme, configuration changes, hardware acceleration, and window soft input mode.
| @@ -0,0 +1,14 @@ | |||
| import { type ConfigPlugin, createRunOncePlugin, withPlugins } from '@expo/config-plugins'; | |||
There was a problem hiding this comment.
Remove unused import and fix formatting.
The createRunOncePlugin import is not used in this file and should be removed. Additionally, there are several formatting issues that need to be addressed.
Apply this diff to fix the unused import and formatting:
-import { type ConfigPlugin, createRunOncePlugin, withPlugins } from '@expo/config-plugins';
+import {
+ type ConfigPlugin,
+ withPlugins,
+} from '@expo/config-plugins';
import {
- withReclaimAndroidManifest,
- withReclaimProjectBuildGradle,
+ withReclaimAndroidManifest,
+ withReclaimProjectBuildGradle,
} from './android';📝 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.
| import { type ConfigPlugin, createRunOncePlugin, withPlugins } from '@expo/config-plugins'; | |
| import { | |
| type ConfigPlugin, | |
| withPlugins, | |
| } from '@expo/config-plugins'; | |
| import { | |
| withReclaimAndroidManifest, | |
| withReclaimProjectBuildGradle, | |
| } from './android'; | |
| // …rest of the file… |
🧰 Tools
🪛 ESLint
[error] 1-1: Replace ·type·ConfigPlugin,·createRunOncePlugin,·withPlugins· with ⏎··type·ConfigPlugin,⏎··createRunOncePlugin,⏎··withPlugins,⏎
(prettier/prettier)
[error] 1-1: 'createRunOncePlugin' is defined but never used.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
In expo-plugin/src/index.ts at line 1, remove the unused import
'createRunOncePlugin' from the import statement. After removing it, reformat the
import line and the rest of the file to ensure consistent and clean code
formatting according to the project's style guidelines.
| application.activity = application.activity!.filter( | ||
| (act) => | ||
| act.$['android:name'] != | ||
| 'org.reclaimprotocol.inapp_sdk.ReclaimActivity' | ||
| ); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add safety check for activity array before filtering.
The code assumes application.activity exists before filtering, but it should be initialized if undefined to prevent runtime errors.
Apply this diff to add proper safety checks:
- application.activity = application.activity!.filter(
- (act) =>
- act.$['android:name'] !=
- 'org.reclaimprotocol.inapp_sdk.ReclaimActivity'
- );
+ // Initialize activity array if it doesn't exist
+ if (!application.activity) {
+ application.activity = [];
+ }
+
+ // Remove any existing ReclaimActivity entries
+ application.activity = application.activity.filter(
+ (act) =>
+ act.$['android:name'] !==
+ 'org.reclaimprotocol.inapp_sdk.ReclaimActivity'
+ );Also note the change from != to !== for strict equality comparison, which is preferred in TypeScript.
🧰 Tools
🪛 ESLint
[error] 26-26: Replace ········ with ····
(prettier/prettier)
[error] 27-27: Delete ······
(prettier/prettier)
[error] 28-29: Replace ················act.$['android:name']·!=⏎··············· with ········act.$['android:name']·!=
(prettier/prettier)
[error] 30-30: Replace ········ with ····
(prettier/prettier)
🤖 Prompt for AI Agents
In expo-plugin/src/android/withReclaimAndroidManifest.ts around lines 26 to 30,
the code filters application.activity without checking if it is defined, which
can cause runtime errors. Add a safety check to initialize application.activity
as an empty array if it is undefined before filtering. Also, replace the !=
operator with !== for strict equality comparison in the filter condition.
…native-sdk into mushaheed.expo_setup
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (16)
samples/example_expo/components/ui/TabBarBackground.ios.tsx (1)
17-19: Consider renaming the hook for clarity.The function name
useBottomTabOverflowis misleading since it returns the tab bar height, not overflow values. Consider renaming to better reflect its purpose.-export function useBottomTabOverflow() { +export function useBottomTabOverflow() { return useBottomTabBarHeight(); }Alternative names:
useBottomTabHeight,useTabBarHeight, oruseBottomTabBarOverflowif it's specifically meant to represent overflow handling.README.md (1)
50-103: Excellent comprehensive Expo setup documentation.The "Expo Only Setup" section is well-structured and covers all necessary scenarios. The warnings about Expo Go compatibility and the clear distinction between EAS and non-EAS workflows are particularly valuable.
Apply these fixes for the static analysis issues:
-Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so merge the following code to the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file: +Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so, merge the following code to the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file:Also add language specifiers to the code blocks:
-``` +```bash # For iOS npx expo prebuild npx expo run:ios-``` +```bash # For online builds npx eas-cli build --profile developmentsamples/example_expo/components/HelloWave.tsx (1)
13-32: LGTM! Well-implemented animated component.The HelloWave component uses react-native-reanimated effectively with:
- Proper shared value usage
- Correct animation sequencing and repetition
- Appropriate cleanup with dependency array
- Good integration with ThemedText for consistency
Apply this formatting fix for prettier:
- rotationAnimation.value = withRepeat( - withSequence(withTiming(25, { duration: 150 }), withTiming(0, { duration: 150 })), - 4 // Run the animation 4 times - ); + rotationAnimation.value = withRepeat( + withSequence( + withTiming(25, { duration: 150 }), + withTiming(0, { duration: 150 }) + ), + 4 // Run the animation 4 times + );samples/example_expo/app/_layout.tsx (1)
9-29: LGTM! Well-structured root layout with proper theme and navigation setup.The implementation correctly handles:
- Asynchronous font loading with appropriate loading state
- Theme provider integration with color scheme detection
- Navigation stack configuration
- Status bar styling
Apply these formatting fixes for prettier:
-import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'; +import { + DarkTheme, + DefaultTheme, + ThemeProvider, +} from '@react-navigation/native';- <Stack > + <Stack>samples/example_expo/components/ThemedView.tsx (1)
1-14: LGTM! Well-structured themed component with minor formatting issues.The
ThemedViewcomponent is cleanly implemented and correctly integrates with the theming system. The type definitions and logic are sound.However, please address the Prettier formatting issues flagged by ESLint to maintain code consistency:
-export function ThemedView({ style, lightColor, darkColor, ...otherProps }: ThemedViewProps) { - const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background'); +export function ThemedView({ + style, + lightColor, + darkColor, + ...otherProps +}: ThemedViewProps) { + const backgroundColor = useThemeColor( + { light: lightColor, dark: darkColor }, + 'background' + );samples/example_expo/android/build.gradle (1)
18-24: Consider adding error handling for dynamic React Native path resolution.The dynamic resolution of the React Native Android directory is clever but could be fragile if Node.js is unavailable or if the command fails. Consider adding error handling or a fallback mechanism.
You could wrap this in a try-catch or provide a fallback path:
def reactNativeAndroidDir try { reactNativeAndroidDir = new File( providers.exec { workingDir(rootDir) commandLine("node", "--print", "require.resolve('react-native/package.json')") }.standardOutput.asText.get().trim(), "../android" ) } catch (Exception e) { // Fallback to a default path or throw a more descriptive error throw new GradleException("Failed to resolve React Native Android directory: ${e.message}") }samples/example_expo/components/ExternalLink.tsx (1)
1-24: Excellent cross-platform external link handling!The
ExternalLinkcomponent elegantly handles the differences between web and native platforms. The type definition using intersection types is well-crafted, and the platform-specific logic correctly prevents default navigation on native while opening in-app browser.Minor formatting issue to address:
-type Props = Omit<ComponentProps<typeof Link>, 'href'> & { href: Href & string }; +type Props = Omit<ComponentProps<typeof Link>, 'href'> & { + href: Href & string; +};samples/example_expo/components/ui/IconSymbol.tsx (2)
28-41: Good cross-platform icon abstraction with a few considerations.The mapping approach is solid for ensuring consistent iconography across platforms. However, there are a couple of points to address:
- The
weightparameter is declared but not used in the implementation- The icon mapping is quite limited - consider how new icons will be added
Consider either removing the unused
weightparameter or documenting why it's kept for future use:export function IconSymbol({ name, size = 24, color, style, }: { name: IconSymbolName; size?: number; color: string | OpaqueColorValue; style?: StyleProp<TextStyle>; - weight?: SymbolWeight; }) {Alternatively, add a comment explaining its purpose for iOS platform compatibility.
16-21: Consider expanding the icon mapping or documenting the addition process.The current mapping only includes 4 icons. Consider:
- Adding more commonly used icons
- Documenting the process for adding new icons
- Creating a utility or script to help with mapping
samples/example_expo/components/Collapsible.tsx (1)
10-33: Well-implemented collapsible component!The
Collapsiblecomponent is cleanly designed with:
- Proper state management for open/closed state
- Good use of themed components
- Nice visual feedback with the rotating chevron
- Appropriate accessibility with TouchableOpacity
The logic and theming integration are solid.
Please address the minor formatting issues:
-export function Collapsible({ children, title }: PropsWithChildren & { title: string }) { +export function Collapsible({ + children, + title, +}: PropsWithChildren & { title: string }) {onPress={() => setIsOpen((value) => !value)} - activeOpacity={0.8}> + activeOpacity={0.8} + >samples/example_expo/components/ThemedText.tsx (2)
22-30: Simplify conditional style applicationThe multiple ternary operators for style selection can be simplified using array indexing or a style mapping approach for better readability and performance.
Consider this refactor:
+const typeStyles = { + default: styles.default, + title: styles.title, + defaultSemiBold: styles.defaultSemiBold, + subtitle: styles.subtitle, + link: styles.link, +}; return ( <Text style={[ { color }, - type === 'default' ? styles.default : undefined, - type === 'title' ? styles.title : undefined, - type === 'defaultSemiBold' ? styles.defaultSemiBold : undefined, - type === 'subtitle' ? styles.subtitle : undefined, - type === 'link' ? styles.link : undefined, + typeStyles[type], style, ]} {...rest} /> );
55-60: Consider making link color theme-awareThe link style has a hardcoded color that won't adapt to theme changes. Consider using the theme color system for consistency.
link: { lineHeight: 30, fontSize: 16, - color: '#0a7ea4', + // Remove hardcoded color, let the component's color prop handle theming },Then ensure the component receives appropriate link colors via the
lightColoranddarkColorprops whentype="link".samples/example_expo/scripts/reset-project.js (1)
104-111: Consider improving input validationThe current validation only checks for 'y' or 'n', but could be more user-friendly by accepting variations like 'yes', 'no', 'Y', 'N'.
- if (userInput === "y" || userInput === "n") { + if (['y', 'yes', 'n', 'no'].includes(userInput)) { moveDirectories(userInput).finally(() => rl.close()); } else { - console.log("❌ Invalid input. Please enter 'Y' or 'N'."); + console.log("❌ Invalid input. Please enter 'Y', 'yes', 'N', or 'no'."); rl.close(); }samples/example_expo/components/ParallaxScrollView.tsx (1)
30-45: Fix code formatting as indicated by ESLintThe static analysis tools have identified formatting issues that should be addressed for consistency.
Apply these formatting fixes:
{ scale: interpolate( - scrollOffset.value, [-HEADER_HEIGHT, 0, HEADER_HEIGHT], [2, 1, 1] + scrollOffset.value, + [-HEADER_HEIGHT, 0, HEADER_HEIGHT], + [2, 1, 1] ), },samples/example_expo/app/(home)/_layout.tsx (1)
1-2: Remove commented import statement.The commented import on line 1 appears to be dead code and should be removed.
-// import { ReclaimVerification } from '@reclaimprotocol/inapp-rn-sdk'; import { ReclaimVerification } from '@reclaimprotocol/inapp-rn-sdk';samples/example_expo/android/app/build.gradle (1)
90-97: Consider using a more specific application ID for production.The application ID
org.example.expois clearly for example purposes. Ensure this is updated to a proper package name before production use.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (20)
samples/example_expo/android/app/src/main/res/drawable-hdpi/splashscreen_logo.pngis excluded by!**/*.pngsamples/example_expo/android/app/src/main/res/drawable-mdpi/splashscreen_logo.pngis excluded by!**/*.pngsamples/example_expo/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.pngis excluded by!**/*.pngsamples/example_expo/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.pngis excluded by!**/*.pngsamples/example_expo/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.pngis excluded by!**/*.pngsamples/example_expo/android/gradle/wrapper/gradle-wrapper.jaris excluded by!**/*.jarsamples/example_expo/assets/fonts/SpaceMono-Regular.ttfis excluded by!**/*.ttfsamples/example_expo/assets/images/adaptive-icon.pngis excluded by!**/*.pngsamples/example_expo/assets/images/favicon.pngis excluded by!**/*.pngsamples/example_expo/assets/images/icon.pngis excluded by!**/*.pngsamples/example_expo/assets/images/partial-react-logo.pngis excluded by!**/*.pngsamples/example_expo/assets/images/react-logo.pngis excluded by!**/*.pngsamples/example_expo/assets/images/react-logo@2x.pngis excluded by!**/*.pngsamples/example_expo/assets/images/react-logo@3x.pngis excluded by!**/*.pngsamples/example_expo/assets/images/splash-icon.pngis excluded by!**/*.pngsamples/example_expo/ios/Podfile.lockis excluded by!**/*.locksamples/example_expo/ios/exampleexpo/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.pngis excluded by!**/*.pngsamples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenLogo.imageset/image.pngis excluded by!**/*.pngsamples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenLogo.imageset/image@2x.pngis excluded by!**/*.pngsamples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenLogo.imageset/image@3x.pngis excluded by!**/*.png
📒 Files selected for processing (68)
README.md(2 hunks)package.json(4 hunks)samples/example_expo/.env.example(1 hunks)samples/example_expo/.gitignore(1 hunks)samples/example_expo/README.md(1 hunks)samples/example_expo/android/.gitignore(1 hunks)samples/example_expo/android/app/build.gradle(1 hunks)samples/example_expo/android/app/proguard-rules.pro(1 hunks)samples/example_expo/android/app/src/debug/AndroidManifest.xml(1 hunks)samples/example_expo/android/app/src/main/AndroidManifest.xml(1 hunks)samples/example_expo/android/app/src/main/java/org/example/expo/MainActivity.kt(1 hunks)samples/example_expo/android/app/src/main/java/org/example/expo/MainApplication.kt(1 hunks)samples/example_expo/android/app/src/main/res/drawable/ic_launcher_background.xml(1 hunks)samples/example_expo/android/app/src/main/res/drawable/rn_edit_text_material.xml(1 hunks)samples/example_expo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml(1 hunks)samples/example_expo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml(1 hunks)samples/example_expo/android/app/src/main/res/values-night/colors.xml(1 hunks)samples/example_expo/android/app/src/main/res/values/colors.xml(1 hunks)samples/example_expo/android/app/src/main/res/values/strings.xml(1 hunks)samples/example_expo/android/app/src/main/res/values/styles.xml(1 hunks)samples/example_expo/android/build.gradle(1 hunks)samples/example_expo/android/gradle.properties(1 hunks)samples/example_expo/android/gradle/wrapper/gradle-wrapper.properties(1 hunks)samples/example_expo/android/gradlew(1 hunks)samples/example_expo/android/gradlew.bat(1 hunks)samples/example_expo/android/settings.gradle(1 hunks)samples/example_expo/app.json(1 hunks)samples/example_expo/app/(home)/_layout.tsx(1 hunks)samples/example_expo/app/+not-found.tsx(1 hunks)samples/example_expo/app/_layout.tsx(1 hunks)samples/example_expo/components/Collapsible.tsx(1 hunks)samples/example_expo/components/ExternalLink.tsx(1 hunks)samples/example_expo/components/HapticTab.tsx(1 hunks)samples/example_expo/components/HelloWave.tsx(1 hunks)samples/example_expo/components/ParallaxScrollView.tsx(1 hunks)samples/example_expo/components/ThemedText.tsx(1 hunks)samples/example_expo/components/ThemedView.tsx(1 hunks)samples/example_expo/components/ui/IconSymbol.ios.tsx(1 hunks)samples/example_expo/components/ui/IconSymbol.tsx(1 hunks)samples/example_expo/components/ui/TabBarBackground.ios.tsx(1 hunks)samples/example_expo/components/ui/TabBarBackground.tsx(1 hunks)samples/example_expo/constants/Colors.ts(1 hunks)samples/example_expo/eslint.config.js(1 hunks)samples/example_expo/hooks/useColorScheme.ts(1 hunks)samples/example_expo/hooks/useColorScheme.web.ts(1 hunks)samples/example_expo/hooks/useThemeColor.ts(1 hunks)samples/example_expo/ios/.gitignore(1 hunks)samples/example_expo/ios/.xcode.env(1 hunks)samples/example_expo/ios/Podfile(1 hunks)samples/example_expo/ios/Podfile.properties.json(1 hunks)samples/example_expo/ios/exampleexpo.xcodeproj/project.pbxproj(1 hunks)samples/example_expo/ios/exampleexpo.xcodeproj/xcshareddata/xcschemes/exampleexpo.xcscheme(1 hunks)samples/example_expo/ios/exampleexpo.xcworkspace/contents.xcworkspacedata(1 hunks)samples/example_expo/ios/exampleexpo/AppDelegate.swift(1 hunks)samples/example_expo/ios/exampleexpo/Images.xcassets/AppIcon.appiconset/Contents.json(1 hunks)samples/example_expo/ios/exampleexpo/Images.xcassets/Contents.json(1 hunks)samples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenBackground.colorset/Contents.json(1 hunks)samples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenLogo.imageset/Contents.json(1 hunks)samples/example_expo/ios/exampleexpo/Info.plist(1 hunks)samples/example_expo/ios/exampleexpo/PrivacyInfo.xcprivacy(1 hunks)samples/example_expo/ios/exampleexpo/SplashScreen.storyboard(1 hunks)samples/example_expo/ios/exampleexpo/Supporting/Expo.plist(1 hunks)samples/example_expo/ios/exampleexpo/exampleexpo-Bridging-Header.h(1 hunks)samples/example_expo/ios/exampleexpo/exampleexpo.entitlements(1 hunks)samples/example_expo/package.json(1 hunks)samples/example_expo/scripts/reset-project.js(1 hunks)samples/example_expo/tsconfig.json(1 hunks)user-workspace/src/App.tsx(1 hunks)
✅ Files skipped from review due to trivial changes (44)
- samples/example_expo/android/app/src/main/res/values-night/colors.xml
- samples/example_expo/ios/exampleexpo/exampleexpo-Bridging-Header.h
- user-workspace/src/App.tsx
- samples/example_expo/.env.example
- samples/example_expo/ios/exampleexpo.xcworkspace/contents.xcworkspacedata
- samples/example_expo/hooks/useColorScheme.ts
- samples/example_expo/ios/exampleexpo/Images.xcassets/Contents.json
- samples/example_expo/ios/exampleexpo/exampleexpo.entitlements
- samples/example_expo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
- samples/example_expo/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
- samples/example_expo/ios/Podfile.properties.json
- samples/example_expo/android/app/src/main/res/values/colors.xml
- samples/example_expo/constants/Colors.ts
- samples/example_expo/android/app/src/main/res/drawable/ic_launcher_background.xml
- samples/example_expo/android/gradle/wrapper/gradle-wrapper.properties
- samples/example_expo/components/ui/TabBarBackground.tsx
- samples/example_expo/android/app/proguard-rules.pro
- samples/example_expo/tsconfig.json
- samples/example_expo/android/.gitignore
- samples/example_expo/components/ui/IconSymbol.ios.tsx
- samples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenBackground.colorset/Contents.json
- samples/example_expo/ios/.xcode.env
- samples/example_expo/ios/exampleexpo/Images.xcassets/AppIcon.appiconset/Contents.json
- samples/example_expo/eslint.config.js
- samples/example_expo/ios/exampleexpo/Images.xcassets/SplashScreenLogo.imageset/Contents.json
- samples/example_expo/ios/exampleexpo/PrivacyInfo.xcprivacy
- samples/example_expo/android/app/src/debug/AndroidManifest.xml
- samples/example_expo/components/HapticTab.tsx
- samples/example_expo/ios/.gitignore
- samples/example_expo/ios/exampleexpo/Supporting/Expo.plist
- samples/example_expo/android/app/src/main/res/values/styles.xml
- samples/example_expo/.gitignore
- samples/example_expo/hooks/useColorScheme.web.ts
- samples/example_expo/app.json
- samples/example_expo/android/gradlew.bat
- samples/example_expo/app/+not-found.tsx
- samples/example_expo/package.json
- samples/example_expo/android/app/src/main/res/drawable/rn_edit_text_material.xml
- samples/example_expo/android/app/src/main/res/values/strings.xml
- samples/example_expo/ios/exampleexpo/SplashScreen.storyboard
- samples/example_expo/android/gradle.properties
- samples/example_expo/ios/exampleexpo.xcodeproj/xcshareddata/xcschemes/exampleexpo.xcscheme
- samples/example_expo/hooks/useThemeColor.ts
- samples/example_expo/ios/exampleexpo/Info.plist
🚧 Files skipped from review as they are similar to previous changes (1)
- package.json
🧰 Additional context used
🧬 Code Graph Analysis (5)
samples/example_expo/components/ThemedView.tsx (1)
samples/example_expo/hooks/useThemeColor.ts (1)
useThemeColor(9-21)
samples/example_expo/components/HelloWave.tsx (1)
samples/example_expo/components/ThemedText.tsx (1)
ThemedText(11-34)
samples/example_expo/components/Collapsible.tsx (3)
samples/example_expo/components/ThemedView.tsx (1)
ThemedView(10-14)samples/example_expo/constants/Colors.ts (1)
Colors(9-26)samples/example_expo/components/ThemedText.tsx (1)
ThemedText(11-34)
samples/example_expo/components/ThemedText.tsx (1)
samples/example_expo/hooks/useThemeColor.ts (1)
useThemeColor(9-21)
samples/example_expo/components/ParallaxScrollView.tsx (1)
samples/example_expo/components/ThemedView.tsx (1)
ThemedView(10-14)
🪛 ESLint
samples/example_expo/components/ThemedView.tsx
[error] 10-10: Replace ·style,·lightColor,·darkColor,·...otherProps· with ⏎··style,⏎··lightColor,⏎··darkColor,⏎··...otherProps⏎
(prettier/prettier)
[error] 11-11: Replace {·light:·lightColor,·dark:·darkColor·},·'background' with ⏎····{·light:·lightColor,·dark:·darkColor·},⏎····'background'⏎··
(prettier/prettier)
samples/example_expo/components/HelloWave.tsx
[error] 18-18: Replace withTiming(25,·{·duration:·150·}),·withTiming(0,·{·duration:·150·}) with ⏎········withTiming(25,·{·duration:·150·}),⏎········withTiming(0,·{·duration:·150·})⏎······
(prettier/prettier)
samples/example_expo/app/_layout.tsx
[error] 1-1: Replace ·DarkTheme,·DefaultTheme,·ThemeProvider· with ⏎··DarkTheme,⏎··DefaultTheme,⏎··ThemeProvider,⏎
(prettier/prettier)
[error] 22-22: Delete ·
(prettier/prettier)
samples/example_expo/components/ExternalLink.tsx
[error] 6-6: Replace ·href:·Href·&·string· with ⏎··href:·Href·&·string;⏎
(prettier/prettier)
samples/example_expo/components/Collapsible.tsx
[error] 10-10: Replace ·children,·title· with ⏎··children,⏎··title,⏎
(prettier/prettier)
[error] 19-19: Insert ⏎······
(prettier/prettier)
samples/example_expo/components/ui/IconSymbol.tsx
[error] 8-8: Replace SymbolViewProps['name'],·ComponentProps<typeof·MaterialIcons>['name'] with ⏎··SymbolViewProps['name'],⏎··ComponentProps<typeof·MaterialIcons>['name']⏎
(prettier/prettier)
[error] 40-40: Replace <MaterialIcons·color={color}·size={size}·name={MAPPING[name]}·style={style}·/> with (⏎····<MaterialIcons⏎······color={color}⏎······size={size}⏎······name={MAPPING[name]}⏎······style={style}⏎····/>⏎··)
(prettier/prettier)
samples/example_expo/app/(home)/_layout.tsx
[error] 4-4: Replace ·Button,·Clipboard,·ScrollView,·Text,·TextInput,·View· with ⏎··Button,⏎··Clipboard,⏎··ScrollView,⏎··Text,⏎··TextInput,⏎··View,⏎
(prettier/prettier)
[error] 9-9: Delete ··
(prettier/prettier)
[error] 10-10: Delete ··
(prettier/prettier)
[error] 11-11: Insert ;
(prettier/prettier)
[error] 14-14: Delete ··
(prettier/prettier)
[error] 15-15: Delete ··
(prettier/prettier)
[error] 16-16: Replace ··const·[result,·setResult]·=·useState<ReclaimVerification.Response·|·null>(null with const·[result,·setResult]·=·useState<ReclaimVerification.Response·|·null>(⏎····null⏎··
(prettier/prettier)
[error] 18-18: Delete ··
(prettier/prettier)
[error] 19-19: Replace ········ with ····
(prettier/prettier)
[error] 20-20: Delete ······
(prettier/prettier)
[error] 21-21: Delete ········
(prettier/prettier)
[error] 22-22: Replace ················ with ········
(prettier/prettier)
[error] 23-23: Delete ······
(prettier/prettier)
[error] 24-24: Replace ············ with ······
(prettier/prettier)
[error] 25-25: Delete ····
(prettier/prettier)
[error] 26-26: Replace ····console.assert(config.REACT_APP_RECLAIM_APP_ID,·'RECLAIM_APP_ID·is·not·set'); with console.assert(⏎······config.REACT_APP_RECLAIM_APP_ID,⏎······'RECLAIM_APP_ID·is·not·set'
(prettier/prettier)
[error] 27-27: Replace ····console.assert(config.REACT_APP_RECLAIM_APP_SECRET,·'RECLAIM_APP_SECRET·is·not·set'); with );⏎····console.assert(⏎······config.REACT_APP_RECLAIM_APP_SECRET,⏎······'RECLAIM_APP_SECRET·is·not·set'
(prettier/prettier)
[error] 28-28: Insert );⏎
(prettier/prettier)
[error] 29-29: Delete ······
(prettier/prettier)
[error] 30-30: Replace ············ with ······
(prettier/prettier)
[error] 31-31: Delete ········
(prettier/prettier)
[error] 32-32: Delete ········
(prettier/prettier)
[error] 33-33: Delete ········
(prettier/prettier)
[error] 34-34: Delete ······
(prettier/prettier)
[error] 35-35: Replace ············ with ······
(prettier/prettier)
[error] 36-36: Delete ····
(prettier/prettier)
[error] 37-37: Replace ············ with ······
(prettier/prettier)
[error] 38-38: Replace ················ with ········
(prettier/prettier)
[error] 39-39: Delete ······
(prettier/prettier)
[error] 40-40: Delete ······
(prettier/prettier)
[error] 41-41: Replace ················ with ········
(prettier/prettier)
[error] 42-42: Delete ··········
(prettier/prettier)
[error] 43-43: Replace ························ with ············
(prettier/prettier)
[error] 44-44: Replace ···························· with ··············
(prettier/prettier)
[error] 45-45: Replace ···························· with ··············
(prettier/prettier)
[error] 46-46: Replace ························ with ············
(prettier/prettier)
[error] 47-47: Replace ························ with ············
(prettier/prettier)
[error] 48-48: Delete ··········
(prettier/prettier)
[error] 49-49: Replace ························ with ············
(prettier/prettier)
[error] 50-50: Replace ···························· with ··············
(prettier/prettier)
[error] 51-51: Delete ··············
(prettier/prettier)
[error] 52-52: Delete ············
(prettier/prettier)
[error] 53-53: Replace ························ with ············
(prettier/prettier)
[error] 54-54: Delete ··········
(prettier/prettier)
[error] 55-55: Replace ························ with ············
(prettier/prettier)
[error] 56-56: Delete ··············
(prettier/prettier)
[error] 57-57: Replace ···························· with ··············
(prettier/prettier)
[error] 58-58: Delete ············
(prettier/prettier)
[error] 59-59: Replace ························ with ············
(prettier/prettier)
[error] 60-60: Delete ··········
(prettier/prettier)
[error] 61-61: Delete ··········
(prettier/prettier)
[error] 62-62: Replace ························ with ············
(prettier/prettier)
[error] 63-63: Delete ··············
(prettier/prettier)
[error] 64-64: Replace ···························· with ··············
(prettier/prettier)
[error] 65-65: Replace ························ with ············
(prettier/prettier)
[error] 66-66: Replace ················ with ········
(prettier/prettier)
[error] 67-67: Replace ············ with ······
(prettier/prettier)
[error] 68-68: Delete ········
(prettier/prettier)
[error] 69-69: Replace ··········text:·error·instanceof·Error·?·error.message with text:⏎············error·instanceof·Error⏎··············?·error.message⏎·············
(prettier/prettier)
[error] 70-70: Replace ···················· with ··········
(prettier/prettier)
[error] 71-71: Delete ········
(prettier/prettier)
[error] 72-72: Replace ············ with ······
(prettier/prettier)
[error] 73-73: Replace ········ with ····
(prettier/prettier)
[error] 74-74: Delete ··
(prettier/prettier)
[error] 76-76: Delete ··
(prettier/prettier)
[error] 77-77: Delete ····
(prettier/prettier)
[error] 78-78: Replace ············ with ······
(prettier/prettier)
[error] 79-79: Delete ········
(prettier/prettier)
[error] 80-80: Delete ········
(prettier/prettier)
[error] 81-81: Delete ······
(prettier/prettier)
[error] 82-82: Replace ············ with ······
(prettier/prettier)
[error] 83-83: Delete ····
(prettier/prettier)
[error] 85-85: Replace ········ with ····
(prettier/prettier)
[error] 86-86: Delete ······
(prettier/prettier)
[error] 87-87: Replace ······const·verificationResult·= with const·verificationResult·=⏎·······
(prettier/prettier)
[error] 88-88: Delete ······
(prettier/prettier)
[error] 89-89: Delete ····
(prettier/prettier)
[error] 90-90: Replace ············ with ······
(prettier/prettier)
[error] 91-91: Delete ········
(prettier/prettier)
[error] 92-92: Delete ······
(prettier/prettier)
[error] 93-93: Replace ············ with ······
(prettier/prettier)
[error] 94-94: Delete ········
(prettier/prettier)
[error] 95-95: Replace ···················· with ··········
(prettier/prettier)
[error] 96-96: Delete ············
(prettier/prettier)
[error] 97-97: Replace ···························· with ··············
(prettier/prettier)
[error] 98-98: Replace ···························· with ··············
(prettier/prettier)
[error] 99-99: Delete ············
(prettier/prettier)
[error] 100-100: Delete ············
(prettier/prettier)
[error] 101-101: Delete ··········
(prettier/prettier)
[error] 102-102: Delete ············
(prettier/prettier)
[error] 103-103: Replace ···························· with ··············
(prettier/prettier)
[error] 104-104: Replace ···························· with ··············
(prettier/prettier)
[error] 105-105: Replace ························ with ············
(prettier/prettier)
[error] 106-106: Replace ························ with ············
(prettier/prettier)
[error] 107-107: Delete ··········
(prettier/prettier)
[error] 108-108: Delete ············
(prettier/prettier)
[error] 109-109: Delete ··············
(prettier/prettier)
[error] 110-110: Replace ···························· with ··············
(prettier/prettier)
[error] 111-111: Replace ························ with ············
(prettier/prettier)
[error] 112-112: Replace ························ with ············
(prettier/prettier)
[error] 113-113: Replace ···················· with ··········
(prettier/prettier)
[error] 114-114: Delete ··········
(prettier/prettier)
[error] 115-115: Replace ························ with ············
(prettier/prettier)
[error] 116-116: Replace ···························· with ··············
(prettier/prettier)
[error] 117-117: Replace ···························· with ··············
(prettier/prettier)
[error] 118-118: Delete ············
(prettier/prettier)
[error] 119-119: Replace ················ with ········
(prettier/prettier)
[error] 120-120: Replace ············ with ······
(prettier/prettier)
[error] 121-121: Replace ················ with ········
(prettier/prettier)
[error] 122-122: Replace ··········text:·error·instanceof·Error·?·error.message with text:⏎············error·instanceof·Error⏎··············?·error.message⏎·············
(prettier/prettier)
[error] 123-123: Delete ··········
(prettier/prettier)
[error] 124-124: Replace ················ with ········
(prettier/prettier)
[error] 125-125: Replace ············ with ······
(prettier/prettier)
[error] 126-126: Delete ····
(prettier/prettier)
[error] 127-127: Replace ··} with };
(prettier/prettier)
[error] 129-129: Replace ···· with ··
(prettier/prettier)
[error] 130-130: Delete ····
(prettier/prettier)
[error] 131-131: Replace ············ with ······
(prettier/prettier)
[error] 132-132: Replace ················ with ········
(prettier/prettier)
[error] 133-133: Delete ········
(prettier/prettier)
[error] 134-134: Delete ······
(prettier/prettier)
[error] 135-135: Replace ············ with ······
(prettier/prettier)
[error] 136-136: Delete ····
(prettier/prettier)
[error] 137-137: Replace ········ with ····
(prettier/prettier)
[error] 138-138: Delete ······
(prettier/prettier)
[error] 139-139: Replace ············ with ······
(prettier/prettier)
[error] 140-140: Delete ········
(prettier/prettier)
[error] 141-141: Replace ················ with ········
(prettier/prettier)
[error] 142-142: Delete ······
(prettier/prettier)
[error] 143-143: Replace ········ with ····
(prettier/prettier)
[error] 144-144: Delete ······
(prettier/prettier)
[error] 145-145: Delete ········
(prettier/prettier)
[error] 146-146: Delete ········
(prettier/prettier)
[error] 147-147: Replace ············ with ······
(prettier/prettier)
[error] 148-148: Replace ········ with ····
(prettier/prettier)
[error] 149-149: Replace ····} with ··};
(prettier/prettier)
[error] 151-151: Delete ··
(prettier/prettier)
[error] 152-152: Delete ····
(prettier/prettier)
[error] 153-153: Replace ············ with ······
(prettier/prettier)
[error] 154-154: Replace ············ with ······
(prettier/prettier)
[error] 155-155: Delete ······
(prettier/prettier)
[error] 156-156: Replace ················ with ········
(prettier/prettier)
[error] 157-157: Replace ···················· with ··········
(prettier/prettier)
[error] 158-158: Replace ···················· with ··········
(prettier/prettier)
[error] 159-159: Delete ········
(prettier/prettier)
[error] 160-160: Replace ············ with ······
(prettier/prettier)
[error] 161-161: Delete ····
(prettier/prettier)
[error] 162-162: Replace ············ with ······
(prettier/prettier)
[error] 163-163: Replace ············ with ······
(prettier/prettier)
[error] 164-164: Delete ········
(prettier/prettier)
[error] 165-165: Delete ········
(prettier/prettier)
[error] 166-166: Delete ······
(prettier/prettier)
[error] 167-167: Replace ········ with ····
(prettier/prettier)
[error] 168-168: Delete ··
(prettier/prettier)
[error] 170-170: Delete ··
(prettier/prettier)
[error] 171-171: Delete ····
(prettier/prettier)
[error] 172-172: Replace ······<Text·style={{·fontSize:·24,·fontWeight:·'bold',·textAlign:·'center',·marginBottom:·20,·color:·'#000000'·}}> with <Text⏎········style={{⏎··········fontSize:·24,⏎··········fontWeight:·'bold',⏎··········textAlign:·'center',⏎··········marginBottom:·20,⏎··········color:·'#000000',⏎········}}
(prettier/prettier)
[error] 173-173: Replace ········ with ······>⏎
(prettier/prettier)
[error] 174-174: Delete ······
(prettier/prettier)
[error] 176-176: Delete ······
(prettier/prettier)
[error] 177-177: Replace ········<Text·style={{·fontSize:·16,·fontWeight:·'600',·marginBottom:·8,·color:·'#000000'·}}> with <Text⏎··········style={{⏎············fontSize:·16,⏎············fontWeight:·'600',⏎············marginBottom:·8,⏎············color:·'#000000',⏎··········}}
(prettier/prettier)
[error] 178-178: Replace ·· with >⏎
(prettier/prettier)
[error] 179-179: Delete ········
(prettier/prettier)
[error] 180-180: Replace ················ with ········
(prettier/prettier)
[error] 181-181: Replace ···················· with ··········
(prettier/prettier)
[error] 182-182: Replace ························ with ············
(prettier/prettier)
[error] 183-183: Delete ············
(prettier/prettier)
[error] 184-184: Replace ························ with ············
(prettier/prettier)
[error] 185-185: Replace ························ with ············
(prettier/prettier)
[error] 186-186: Replace ························ with ············
(prettier/prettier)
[error] 187-187: Replace ························ with ············
(prettier/prettier)
[error] 188-188: Delete ··········
(prettier/prettier)
[error] 189-189: Delete ··········
(prettier/prettier)
[error] 190-190: Replace ···················· with ··········
(prettier/prettier)
[error] 191-191: Replace ···················· with ··········
(prettier/prettier)
[error] 192-192: Replace ···················· with ··········
(prettier/prettier)
[error] 193-193: Delete ········
(prettier/prettier)
[error] 194-194: Delete ······
(prettier/prettier)
[error] 196-199: Replace ············<Button⏎················title="Start·Verification"⏎················onPress={handleStartVerification}⏎··········· with ······<Button·title="Start·Verification"·onPress={handleStartVerification}
(prettier/prettier)
[error] 201-201: Replace ······<Text·style={{·flex:·0,·padding:·16,·textAlign:·'center',·color:·'#000000',·fontWeight:·'bold'·}}>OR with <Text⏎········style={{⏎··········flex:·0,⏎··········padding:·16,⏎··········textAlign:·'center',⏎··········color:·'#000000',⏎··········fontWeight:·'bold',⏎········}}⏎······>⏎········OR⏎······
(prettier/prettier)
[error] 203-203: Delete ······
(prettier/prettier)
[error] 204-204: Replace ········<Text·style={{·fontSize:·16,·fontWeight:·'600',·marginBottom:·8,·color:·'#000000'·}}> with <Text⏎··········style={{⏎············fontSize:·16,⏎············fontWeight:·'600',⏎············marginBottom:·8,⏎············color:·'#000000',⏎··········}}
(prettier/prettier)
[error] 205-205: Replace ·· with >⏎
(prettier/prettier)
[error] 206-206: Delete ········
(prettier/prettier)
[error] 207-207: Replace ················ with ········
(prettier/prettier)
[error] 208-208: Replace ···················· with ··········
(prettier/prettier)
[error] 209-209: Replace ························ with ············
(prettier/prettier)
[error] 210-210: Replace ························ with ············
(prettier/prettier)
[error] 211-211: Delete ············
(prettier/prettier)
[error] 212-212: Replace ························ with ············
(prettier/prettier)
[error] 213-213: Replace ························ with ············
(prettier/prettier)
[error] 214-214: Delete ············
(prettier/prettier)
[error] 215-215: Replace ···················· with ··········
(prettier/prettier)
[error] 216-216: Delete ··········
(prettier/prettier)
[error] 217-217: Replace ···················· with ··········
(prettier/prettier)
[error] 218-218: Delete ··········
(prettier/prettier)
[error] 219-219: Delete ··········
(prettier/prettier)
[error] 220-220: Delete ········
(prettier/prettier)
[error] 221-221: Delete ······
(prettier/prettier)
[error] 223-223: Replace ············ with ······
(prettier/prettier)
[error] 224-224: Replace ················ with ········
(prettier/prettier)
[error] 225-225: Delete ········
(prettier/prettier)
[error] 226-226: Delete ······
(prettier/prettier)
[error] 228-228: Replace ············ with ······
(prettier/prettier)
[error] 229-229: Replace ············<ScrollView with ······<ScrollView⏎·······
(prettier/prettier)
[error] 230-230: Replace ················ with ··········
(prettier/prettier)
[error] 231-231: Replace ················ with ··········
(prettier/prettier)
[error] 232-232: Delete ······
(prettier/prettier)
[error] 233-233: Replace ················ with ··········
(prettier/prettier)
[error] 234-234: Replace ················ with ··········
(prettier/prettier)
[error] 235-235: Delete ······
(prettier/prettier)
[error] 236-236: Replace ············}}> with ········}}
(prettier/prettier)
[error] 237-237: Replace ··········<Text with >⏎········<Text⏎·········
(prettier/prettier)
[error] 238-238: Delete ········
(prettier/prettier)
[error] 239-239: Replace ······}}··> with }}
(prettier/prettier)
[error] 240-240: Replace ·········· with ········>⏎
(prettier/prettier)
[error] 241-241: Delete ········
(prettier/prettier)
[error] 242-242: Replace ················ with ········
(prettier/prettier)
[error] 243-243: Replace ··········<Text with <Text⏎···········
(prettier/prettier)
[error] 244-244: Replace ························ with ··············
(prettier/prettier)
[error] 245-245: Replace ········}}·onPress={copyProof}·> with }}⏎············onPress={copyProof}
(prettier/prettier)
[error] 246-246: Replace ·· with >⏎
(prettier/prettier)
[error] 247-247: Delete ··········
(prettier/prettier)
[error] 248-248: Delete ········
(prettier/prettier)
[error] 249-249: Delete ······
(prettier/prettier)
[error] 251-251: Delete ······
(prettier/prettier)
[error] 252-255: Replace ················<Button⏎····················title="Ping"⏎····················onPress={onPing}⏎··············· with ········<Button·title="Ping"·onPress={onPing}
(prettier/prettier)
[error] 256-256: Replace ············ with ······
(prettier/prettier)
[error] 257-259: Delete ⏎⏎····
(prettier/prettier)
[error] 260-260: Delete ··
(prettier/prettier)
samples/example_expo/components/ParallaxScrollView.tsx
[error] 41-41: Replace scrollOffset.value,·[-HEADER_HEIGHT,·0,·HEADER_HEIGHT],·[2,·1,·1] with ⏎············scrollOffset.value,⏎············[-HEADER_HEIGHT,·0,·HEADER_HEIGHT],⏎············[2,·1,·1]⏎··········
(prettier/prettier)
[error] 53-53: Insert ⏎······
(prettier/prettier)
[error] 59-59: Insert ⏎········
(prettier/prettier)
🪛 LanguageTool
README.md
[uncategorized] ~52-~52: Possible missing comma found.
Context: ... the Reclaim InApp Config Plugin. To do so merge the following code to the plugins...
(AI_HYDRA_LEO_MISSING_COMMA)
samples/example_expo/README.md
[style] ~27-~27: Consider using “incompatible” to avoid wordiness.
Context: ...ent with Expo Note: This plugin is not compatible with Expo Go. Please use a development ...
(NOT_ABLE_PREMIUM)
[uncategorized] ~52-~52: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...https://github.com/expo/expo): View our open source platform and contribute. - [Discord com...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🪛 markdownlint-cli2 (0.17.2)
README.md
80-80: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
92-92: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🪛 Biome (1.9.4)
samples/example_expo/app/(home)/_layout.tsx
[error] 60-60: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
[error] 113-113: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
🪛 RuboCop (1.75.5)
samples/example_expo/ios/Podfile
[convention] 5-5: Avoid using rescue in its modifier form.
(Style/RescueModifier)
[convention] 28-28: Put a comma after the last item of a multiline array.
(Style/TrailingCommaInArrayLiteral)
[convention] 42-42: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
[convention] 50-50: Avoid comma after the last parameter of a method call.
(Style/TrailingCommaInArguments)
🔇 Additional comments (29)
samples/example_expo/components/ui/TabBarBackground.ios.tsx (2)
1-3: LGTM! Clean and appropriate imports.The imports are well-organized and appropriate for an iOS-specific tab bar background component using Expo's blur functionality.
5-15: Well-implemented blur background component.The BlurTabBarBackground component correctly uses
systemChromeMaterialtint for iOS system integration and appropriate absolute positioning. The comments clearly explain the system adaptation behavior.README.md (1)
28-32: LGTM! Clear Expo installation instructions.The addition of Expo-specific installation instructions is helpful and follows best practices.
samples/example_expo/ios/exampleexpo/AppDelegate.swift (2)
1-53: LGTM! Well-structured Expo AppDelegate implementation.The implementation correctly follows Expo and React Native patterns:
- Proper inheritance from ExpoAppDelegate
- Correct React Native factory initialization
- Appropriate deep linking support for both URL schemes and Universal Links
- Good separation of concerns with ReactNativeDelegate
The conditional compilation for iOS/tvOS and the delegate pattern are implemented properly.
55-70: LGTM! Proper bundle URL configuration for different environments.The ReactNativeDelegate correctly handles bundle URL resolution for development vs production environments, which is essential for Expo development workflow.
samples/example_expo/README.md (1)
1-54: LGTM! Clear and comprehensive Expo example README.The README provides excellent guidance for users with:
- Clear step-by-step setup instructions
- Important compatibility notes about Expo Go limitations
- Proper explanation of file-based routing
- Helpful reset functionality for development
- Standard community resources
The note about plugin incompatibility with Expo Go is particularly valuable for preventing user confusion.
samples/example_expo/android/build.gradle (1)
8-9: Verify the security and availability of custom Maven repositories.The custom Reclaim SDK repository endpoints should be verified for:
- HTTPS usage for security
- Repository availability and reliability
- Authentication requirements if any
Please verify these repository endpoints are accessible and secure:
#!/bin/bash # Description: Verify Maven repository endpoints are accessible echo "Checking Reclaim SDK repository..." curl -I https://reclaim-inapp-sdk.s3.ap-south-1.amazonaws.com/android/repo echo "Checking Flutter storage repository..." curl -I https://storage.googleapis.com/download.flutter.ioAlso applies to: 36-37
samples/example_expo/android/settings.gradle (1)
1-40: LGTM: Standard Expo Android Gradle configurationThe Gradle settings file follows Expo and React Native best practices with proper plugin management, autolinking configuration, and conditional environment-based setup. The dynamic path resolution using Node.js commands is the recommended approach for these frameworks.
samples/example_expo/scripts/reset-project.js (1)
48-99: LGTM: Well-structured reset script with good error handlingThe script properly handles user interaction, file system operations, and error cases. The async/await pattern is correctly implemented, and the file operations use safe methods with proper error handling.
samples/example_expo/android/app/src/main/AndroidManifest.xml (2)
2-6: Review permission usageThe manifest requests several sensitive permissions. Ensure these are actually needed:
WRITE_EXTERNAL_STORAGEis often unnecessary in modern Android apps (API 29+)SYSTEM_ALERT_WINDOWis a sensitive permission that requires user approvalConsider removing unused permissions or documenting their necessity.
30-30: Verify ReclaimActivity configurationThe ReclaimActivity configuration looks appropriate for the Reclaim protocol integration, with proper theme and configuration change handling.
samples/example_expo/components/ParallaxScrollView.tsx (2)
49-66: LGTM: Well-implemented parallax scroll componentThe component properly implements a parallax scrolling effect with good animation performance using React Native Reanimated. The animation interpolation values create a smooth parallax effect, and the component integrates well with the theming system.
52-53: Fix formatting for scroll view propsApply the formatting fix suggested by ESLint:
scrollEventThrottle={16} - scrollIndicatorInsets={{ bottom }} - contentContainerStyle={{ paddingBottom: bottom }}> + scrollIndicatorInsets={{ bottom }} + contentContainerStyle={{ paddingBottom: bottom }} + >samples/example_expo/ios/exampleexpo.xcodeproj/project.pbxproj (1)
1-579: LGTM!The Xcode project configuration is properly set up with correct build phases, framework references, and ReclaimInAppSdk integration.
samples/example_expo/android/gradlew (1)
1-251: LGTM!Standard Gradle wrapper script with no modifications.
samples/example_expo/android/app/src/main/java/org/example/expo/MainActivity.kt (1)
23-23: Pass savedInstanceState to super.onCreate().Passing
nullinstead ofsavedInstanceStatebreaks Android's state restoration mechanism, which could cause issues when the app is restored from background or after configuration changes.- super.onCreate(null) + super.onCreate(savedInstanceState)Likely an incorrect or invalid review comment.
samples/example_expo/android/app/src/main/java/org/example/expo/MainApplication.kt (5)
1-17: LGTM! Proper imports and package structure.The package structure and imports are correctly configured for an Expo React Native Android application. All necessary React Native, Expo, and Android imports are included.
19-38: LGTM! Correct ReactNativeHost configuration for Expo.The ReactNativeHost setup follows Expo best practices:
- Uses ReactNativeHostWrapper for Expo integration
- Properly configures packages with PackageList
- Sets correct JS main module path for Expo (
.expo/.virtual-metro-entry)- Correctly uses BuildConfig flags for architecture and debugging support
40-41: LGTM! Proper ReactHost implementation.The ReactHost property correctly delegates to ReactNativeHostWrapper's createReactHost method with proper context and host parameters.
43-51: LGTM! Proper application initialization.The onCreate method correctly:
- Calls super.onCreate()
- Initializes SoLoader with OpenSourceMergedSoMapping
- Conditionally loads new architecture entry point
- Dispatches application lifecycle events to Expo
53-56: LGTM! Proper configuration change handling.The onConfigurationChanged method correctly forwards configuration changes to both the parent class and Expo's ApplicationLifecycleDispatcher.
samples/example_expo/android/app/build.gradle (8)
1-5: LGTM! Proper plugin configuration.The plugin applications are correct for an Expo React Native Android app, including the necessary Android, Kotlin, and React Native plugins. The project root definition is properly configured.
20-21: LGTM! Correct Expo CLI configuration.The Expo CLI configuration correctly uses
@expo/cliwith theexport:embedbundle command, which is the proper way to bundle Expo apps for production.
69-82: LGTM! Proper build optimization configuration.The Proguard and JSC flavor configurations are correctly set up:
- Proguard is conditionally enabled via properties
- Uses the community JSC build with a reasonable version
133-148: LGTM! Dynamic packaging options configuration.The dynamic packaging options configuration is well-implemented with proper error handling and logging. The loop correctly processes gradle properties and applies them to packaging options.
154-171: LGTM! Conditional Fresco dependencies.The conditional inclusion of Fresco dependencies based on image format support (GIF, WebP) is correctly implemented and follows Expo best practices for optimizing bundle size.
172-176: LGTM! Proper JavaScript engine configuration.The conditional dependency on Hermes vs JSC is correctly implemented, allowing for flexible JavaScript engine selection based on project configuration.
12-15: Verify Node.js command execution security.The dynamic path resolution using Node.js commands could potentially be a security risk if the environment is compromised. However, this is standard practice for Expo/React Native builds and the commands are deterministic.
#!/bin/bash # Description: Check if there are any security best practices documentation for Node.js command execution in Gradle builds # Search for any existing security documentation or patterns rg -A 5 -B 5 "execute.*node" --type gradle
98-105: Security concern: Debug keystore configuration.The debug keystore configuration uses default credentials which is acceptable for development but should never be used in production.
#!/bin/bash # Description: Check if there are any production keystore configurations or warnings # Look for any keystore-related configurations or documentation rg -A 10 -B 5 "keystore|signing" --type gradle
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| break; | ||
| case ReclaimVerification.ExceptionType.Failed: |
There was a problem hiding this comment.
Remove redundant case clause.
The Failed case is redundant since it falls through to the default case which handles the same logic.
- case ReclaimVerification.ExceptionType.Failed:
default:
Snackbar.show({
text: 'Verification failed',
duration: Snackbar.LENGTH_LONG,
});Also applies to: 113-113
🧰 Tools
🪛 Biome (1.9.4)
[error] 60-60: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
🪛 ESLint
[error] 60-60: Delete ··········
(prettier/prettier)
🤖 Prompt for AI Agents
In samples/example_expo/app/(home)/_layout.tsx at lines 60 and 113, remove the
redundant case clause for ReclaimVerification.ExceptionType.Failed since it
falls through to the default case which already handles the same logic. Simply
delete these case lines to avoid duplication and keep the switch statement
clean.
| if (error instanceof ReclaimVerification.ReclaimVerificationException) { | ||
| switch (error.type) { | ||
| case ReclaimVerification.ExceptionType.Cancelled: | ||
| Snackbar.show({ | ||
| text: 'Verification cancelled', | ||
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| break; | ||
| case ReclaimVerification.ExceptionType.Dismissed: | ||
| Snackbar.show({ | ||
| text: 'Verification dismissed', | ||
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| break; | ||
| case ReclaimVerification.ExceptionType.SessionExpired: | ||
| Snackbar.show({ | ||
| text: 'Verification session expired', | ||
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| break; | ||
| case ReclaimVerification.ExceptionType.Failed: | ||
| default: | ||
| Snackbar.show({ | ||
| text: 'Verification failed', | ||
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| } | ||
| } else { | ||
| Snackbar.show({ | ||
| text: error instanceof Error ? error.message : 'An unknown verification error occurred', | ||
| duration: Snackbar.LENGTH_LONG, | ||
| }); | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Extract duplicate error handling logic.
The error handling code is duplicated between handleStartVerification and handleStartVerificationFromUrl. This violates the DRY principle and makes maintenance harder.
Consider extracting the error handling into a reusable function:
+ const handleVerificationError = (error: unknown) => {
+ console.info({
+ verificationError: error,
+ });
+ if (error instanceof ReclaimVerification.ReclaimVerificationException) {
+ switch (error.type) {
+ case ReclaimVerification.ExceptionType.Cancelled:
+ Snackbar.show({
+ text: 'Verification cancelled',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ break;
+ case ReclaimVerification.ExceptionType.Dismissed:
+ Snackbar.show({
+ text: 'Verification dismissed',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ break;
+ case ReclaimVerification.ExceptionType.SessionExpired:
+ Snackbar.show({
+ text: 'Verification session expired',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ break;
+ case ReclaimVerification.ExceptionType.Failed:
+ default:
+ Snackbar.show({
+ text: 'Verification failed',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ }
+ } else {
+ Snackbar.show({
+ text: error instanceof Error ? error.message : 'An unknown verification error occurred',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ }
+ };
} catch (error) {
- console.info({
- verificationError: error,
- });
- if (error instanceof ReclaimVerification.ReclaimVerificationException) {
- // ... duplicate error handling code ...
- } else {
- // ... duplicate error handling code ...
- }
+ handleVerificationError(error);
}Also applies to: 93-125
🧰 Tools
🪛 Biome (1.9.4)
[error] 60-60: Useless case clause.
because the default clause is present:
Unsafe fix: Remove the useless case.
(lint/complexity/noUselessSwitchCase)
🪛 ESLint
[error] 40-40: Delete ······
(prettier/prettier)
[error] 41-41: Replace ················ with ········
(prettier/prettier)
[error] 42-42: Delete ··········
(prettier/prettier)
[error] 43-43: Replace ························ with ············
(prettier/prettier)
[error] 44-44: Replace ···························· with ··············
(prettier/prettier)
[error] 45-45: Replace ···························· with ··············
(prettier/prettier)
[error] 46-46: Replace ························ with ············
(prettier/prettier)
[error] 47-47: Replace ························ with ············
(prettier/prettier)
[error] 48-48: Delete ··········
(prettier/prettier)
[error] 49-49: Replace ························ with ············
(prettier/prettier)
[error] 50-50: Replace ···························· with ··············
(prettier/prettier)
[error] 51-51: Delete ··············
(prettier/prettier)
[error] 52-52: Delete ············
(prettier/prettier)
[error] 53-53: Replace ························ with ············
(prettier/prettier)
[error] 54-54: Delete ··········
(prettier/prettier)
[error] 55-55: Replace ························ with ············
(prettier/prettier)
[error] 56-56: Delete ··············
(prettier/prettier)
[error] 57-57: Replace ···························· with ··············
(prettier/prettier)
[error] 58-58: Delete ············
(prettier/prettier)
[error] 59-59: Replace ························ with ············
(prettier/prettier)
[error] 60-60: Delete ··········
(prettier/prettier)
[error] 61-61: Delete ··········
(prettier/prettier)
[error] 62-62: Replace ························ with ············
(prettier/prettier)
[error] 63-63: Delete ··············
(prettier/prettier)
[error] 64-64: Replace ···························· with ··············
(prettier/prettier)
[error] 65-65: Replace ························ with ············
(prettier/prettier)
[error] 66-66: Replace ················ with ········
(prettier/prettier)
[error] 67-67: Replace ············ with ······
(prettier/prettier)
[error] 68-68: Delete ········
(prettier/prettier)
[error] 69-69: Replace ··········text:·error·instanceof·Error·?·error.message with text:⏎············error·instanceof·Error⏎··············?·error.message⏎·············
(prettier/prettier)
[error] 70-70: Replace ···················· with ··········
(prettier/prettier)
[error] 71-71: Delete ········
(prettier/prettier)
[error] 72-72: Replace ············ with ······
(prettier/prettier)
🤖 Prompt for AI Agents
In samples/example_expo/app/(home)/_layout.tsx between lines 40-72 and 93-125,
the error handling logic for ReclaimVerification exceptions is duplicated.
Extract this repeated error handling code into a separate reusable function that
accepts the error object and shows the appropriate Snackbar message. Replace the
duplicated blocks in both handleStartVerification and
handleStartVerificationFromUrl with calls to this new function to adhere to the
DRY principle and improve maintainability.
| console.assert(config.REACT_APP_RECLAIM_APP_ID, 'RECLAIM_APP_ID is not set'); | ||
| console.assert(config.REACT_APP_RECLAIM_APP_SECRET, 'RECLAIM_APP_SECRET is not set'); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Replace console.assert with proper error handling.
console.assert doesn't throw errors in production builds and won't prevent execution if environment variables are missing. This could lead to runtime errors when the SDK is initialized with empty strings.
- console.assert(config.REACT_APP_RECLAIM_APP_ID, 'RECLAIM_APP_ID is not set');
- console.assert(config.REACT_APP_RECLAIM_APP_SECRET, 'RECLAIM_APP_SECRET is not set');
+ if (!config.REACT_APP_RECLAIM_APP_ID || !config.REACT_APP_RECLAIM_APP_SECRET) {
+ Snackbar.show({
+ text: 'Reclaim app credentials are not configured',
+ duration: Snackbar.LENGTH_LONG,
+ });
+ return;
+ }📝 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.
| console.assert(config.REACT_APP_RECLAIM_APP_ID, 'RECLAIM_APP_ID is not set'); | |
| console.assert(config.REACT_APP_RECLAIM_APP_SECRET, 'RECLAIM_APP_SECRET is not set'); | |
| if (!config.REACT_APP_RECLAIM_APP_ID || !config.REACT_APP_RECLAIM_APP_SECRET) { | |
| Snackbar.show({ | |
| text: 'Reclaim app credentials are not configured', | |
| duration: Snackbar.LENGTH_LONG, | |
| }); | |
| return; | |
| } |
🧰 Tools
🪛 ESLint
[error] 26-26: Replace ····console.assert(config.REACT_APP_RECLAIM_APP_ID,·'RECLAIM_APP_ID·is·not·set'); with console.assert(⏎······config.REACT_APP_RECLAIM_APP_ID,⏎······'RECLAIM_APP_ID·is·not·set'
(prettier/prettier)
[error] 27-27: Replace ····console.assert(config.REACT_APP_RECLAIM_APP_SECRET,·'RECLAIM_APP_SECRET·is·not·set'); with );⏎····console.assert(⏎······config.REACT_APP_RECLAIM_APP_SECRET,⏎······'RECLAIM_APP_SECRET·is·not·set'
(prettier/prettier)
🤖 Prompt for AI Agents
In samples/example_expo/app/(home)/_layout.tsx around lines 26 to 27, replace
the console.assert statements checking for REACT_APP_RECLAIM_APP_ID and
REACT_APP_RECLAIM_APP_SECRET with proper error handling that throws an error if
these environment variables are missing. This ensures the application halts
execution and clearly notifies the developer of the missing configuration
instead of silently failing in production.
| require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") | ||
|
|
||
| require 'json' | ||
| podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Improve error handling for JSON parsing.
Using rescue {} silently ignores all errors when reading the configuration file, which could hide important issues like missing files or syntax errors.
-podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {}
+begin
+ podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json')))
+rescue Errno::ENOENT
+ puts "Warning: Podfile.properties.json not found, using defaults"
+ podfile_properties = {}
+rescue JSON::ParserError => e
+ raise "Error parsing Podfile.properties.json: #{e.message}"
+end📝 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.
| podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} | |
| begin | |
| podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) | |
| rescue Errno::ENOENT | |
| puts "Warning: Podfile.properties.json not found, using defaults" | |
| podfile_properties = {} | |
| rescue JSON::ParserError => e | |
| raise "Error parsing Podfile.properties.json: #{e.message}" | |
| end |
🧰 Tools
🪛 RuboCop (1.75.5)
[convention] 5-5: Avoid using rescue in its modifier form.
(Style/RescueModifier)
🤖 Prompt for AI Agents
In samples/example_expo/ios/Podfile at line 5, the current use of `rescue {}`
silently ignores all errors during JSON parsing, which can hide critical issues.
Replace the generic rescue with explicit error handling that catches specific
exceptions like file not found or JSON parse errors, and log or raise a
meaningful error message to inform about the problem instead of silently
ignoring it.
| release { | ||
| // Caution! In production, you need to generate your own keystore file. | ||
| // see https://reactnative.dev/docs/signed-apk-android. | ||
| signingConfig signingConfigs.debug | ||
| shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) | ||
| minifyEnabled enableProguardInReleaseBuilds | ||
| proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" | ||
| crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Security warning: Production uses debug signing config.
The release build type is configured to use the debug signing config, which is not suitable for production. The comment acknowledges this, but it's important to ensure proper keystore generation before production deployment.
For production, you should:
- Generate a proper release keystore
- Configure signing with production credentials
- Store sensitive signing information securely (e.g., environment variables)
release {
- // Caution! In production, you need to generate your own keystore file.
- // see https://reactnative.dev/docs/signed-apk-android.
- signingConfig signingConfigs.debug
+ signingConfig signingConfigs.release // Configure proper release signing
shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false)
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true)
}📝 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.
| release { | |
| // Caution! In production, you need to generate your own keystore file. | |
| // see https://reactnative.dev/docs/signed-apk-android. | |
| signingConfig signingConfigs.debug | |
| shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) | |
| minifyEnabled enableProguardInReleaseBuilds | |
| proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" | |
| crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true) | |
| } | |
| release { | |
| signingConfig signingConfigs.release // Configure proper release signing | |
| shrinkResources (findProperty('android.enableShrinkResourcesInReleaseBuilds')?.toBoolean() ?: false) | |
| minifyEnabled enableProguardInReleaseBuilds | |
| proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" | |
| crunchPngs (findProperty('android.enablePngCrunchInReleaseBuilds')?.toBoolean() ?: true) | |
| } |
🤖 Prompt for AI Agents
In samples/example_expo/android/app/build.gradle around lines 110 to 118, the
release build is incorrectly using the debug signing configuration, which is
insecure for production. To fix this, generate a proper release keystore,
configure the signingConfigs block with the release keystore credentials, and
update the release build type to use this release signingConfig instead of
debug. Ensure sensitive keystore passwords and aliases are stored securely, such
as in environment variables or gradle.properties, and referenced appropriately
in the build.gradle file.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (4)
README.md (4)
52-53: Comma missing after introductory phraseA comma after “To do so” improves readability and resolves the LanguageTool warning.
-Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so merge the following code to the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file: +Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so, merge the following code into the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file:
80-88: Add language identifier to fenced code block
markdownlintflags this block (MD040). Prefix it withsh(orbash) for proper syntax highlighting.-``` +# For iOS / Android build commands +```sh # For iOS npx expo prebuild npx expo run:ios # For Android npx expo prebuild npx expo run:android
92-98: Second fenced block also lacks a language specSame
markdownlintissue as above. Addsh.-``` +# For EAS build commands +```sh # For online builds npx eas-cli build --profile development # For local builds npx eas-cli build --profile development --local
100-100: Fix typo “physicial” → “physical”-Follow [the fixing ios performance issues guide](#fixing-performance-issues-on-ios-physical-devices) to fix slow proof generation on iOS physicial devices. +Follow [the fixing iOS performance issues guide](#fixing-performance-issues-on-ios-physical-devices) to fix slow proof generation on iOS physical devices.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
README.md(2 hunks)
🧰 Additional context used
🪛 LanguageTool
README.md
[uncategorized] ~52-~52: Possible missing comma found.
Context: ... the Reclaim InApp Config Plugin. To do so merge the following code to the plugins...
(AI_HYDRA_LEO_MISSING_COMMA)
🪛 markdownlint-cli2 (0.17.2)
README.md
80-80: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
92-92: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (7)
README.md (1)
25-31: Streamline the “Installation” sub-section formattingThe two alternative guides are currently rendered as bold paragraphs. Using a short unordered list improves scannability and keeps the visual rhythm consistent with the surrounding documentation sections.
-**For React Native projects without Expo:** -📖 [Installation Guide for React Native (No Framework)](documentation/install-no-framework.md) - -**For React Native Expo projects:** -📖 [Installation Guide for React Native Expo](documentation/install-expo.md) +• **React-Native (no Expo):** + 📖 [Installation Guide](documentation/install-no-framework.md) + +• **React-Native + Expo:** + 📖 [Installation Guide](documentation/install-expo.md)documentation/install-expo.md (3)
22-24: Add missing comma and use “into” for clarityCurrent sentence reads a little abruptly and may trip non-native readers.
-Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so merge the following code to the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file: +Expo users can skip the native configuration changes by adding the Reclaim InApp Config Plugin. To do so, merge the following code into the plugins section of your `app.json`, `app.config.js`, or `app.config.ts` file:
46-58: Specify a shell language marker for fenced blocks
markdownlint(MD040) warns when the language is omitted. Addingsh(orbash) silences the warning and enables proper syntax highlighting.-``` +# For iOS / Android +```sh # For iOS npx expo prebuild npx expo run:ios ... npx expo run:androidApply the same change to the EAS-build command block below (lines 63-68). --- `70-92`: **Tighten wording and add missing article** Minor grammar fixes and reduction of repetitive “Click on …” phrasing. ```diff -Your app performance will be severely impacted when you run debug executable on a physical device. Fixing this requires a simple change in your Xcode project xcscheme. +Your app’s performance drops noticeably when you run the debug executable on a physical device. You can resolve this with a small change in your Xcode scheme. ... -4. Click on the **Edit Scheme** button. -5. Click on the **Run** tab. -6. Click on the **Arguments** tab and check the **Environment Variables** section. +4. Select **Edit Scheme**. +5. Open the **Run** tab. +6. Switch to **Arguments** and locate **Environment Variables**.documentation/install-no-framework.md (3)
105-107: Insert the definite article for smoother reading-Your app performance will be severely impacted when you run debug executable on a physical device. +Your app’s performance will be severely impacted when you run the debug executable on a physical device.
90-94: Provide language identifier for the Podfile snippet
markdownlintflags this fenced block. Addingrubykeeps lint happy and renders syntax highlighting.-``` +```ruby platform :ios, '13.0' # or platform :ios, min_ios_version_supportedRepeat for other Ruby/Groovy snippets that currently lack a language tag. --- `130-130`: **Remove trailing colon in heading** The colon violates MD026 and is unnecessary. ```diff -#### Overriding SDK dependency in `Podfile` (Optional): +#### Overriding SDK dependency in `Podfile` (Optional)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
README.md(1 hunks)documentation/install-expo.md(1 hunks)documentation/install-no-framework.md(1 hunks)
🧰 Additional context used
🪛 LanguageTool
documentation/install-expo.md
[uncategorized] ~22-~22: A comma might be missing here.
Context: ... the Reclaim InApp Config Plugin. To do so merge the following code to the plugins...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~72-~72: Possible missing article found.
Context: ... will be severely impacted when you run debug executable on a physical device. Fixing...
(AI_HYDRA_LEO_MISSING_THE)
[style] ~81-~81: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ent xcscheme in Xcode" width="500"> 4. Click on the Edit Scheme button. 5. Click...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~82-~82: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...Click on the Edit Scheme button. 5. Click on the Run tab. 6. Click on the **A...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~83-~83: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...button. 5. Click on the Run tab. 6. Click on the Arguments tab and check the ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[uncategorized] ~92-~92: Possible missing comma found.
Context: .... 9. Run the app on a physical device. Now your React Native Expo project is ready...
(AI_HYDRA_LEO_MISSING_COMMA)
documentation/install-no-framework.md
[uncategorized] ~105-~105: Possible missing article found.
Context: ... will be severely impacted when you run debug executable on a physical device. Fixing...
(AI_HYDRA_LEO_MISSING_THE)
[style] ~114-~114: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ent xcscheme in Xcode" width="500"> 4. Click on the Edit Scheme button. 5. Click...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~115-~115: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...Click on the Edit Scheme button. 5. Click on the Run tab. 6. Click on the **A...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~116-~116: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...button. 5. Click on the Run tab. 6. Click on the Arguments tab and check the ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[uncategorized] ~125-~125: Possible missing comma found.
Context: .... 9. Run the app on a physical device. Now your React Native project is ready to u...
(AI_HYDRA_LEO_MISSING_COMMA)
🪛 markdownlint-cli2 (0.17.2)
documentation/install-no-framework.md
90-90: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
130-130: Trailing punctuation in heading
Punctuation: ':'
(MD026, no-trailing-punctuation)
🔇 Additional comments (1)
documentation/install-expo.md (1)
28-33: Double-check plugin resolution pathThe example lists the plugin as:
"plugins": [ "@reclaimprotocol/inapp-rn-sdk", … ]This assumes the package’s
package.jsonexposes the config plugin via the"expo"or"main"entry field. If the plugin lives underexpo-plugin/dist(as the directory structure suggests) make surepackage.jsoncontains"expo": "./expo-plugin/dist/index.js"so that Expo can resolve it without an explicit sub-path.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (10)
samples/example_expo/README.md (4)
5-5: Use “incompatible” for conciseness
not compatible→incompatiblekeeps the sentence tight and avoids the double-negative style.-**Note:** This plugin is not compatible with Expo Go. +**Note:** This plugin is incompatible with Expo Go.
23-24: Fix article before “Android emulator”Grammatically, it should be “an Android emulator.”
-...open the app in a Android emulator... +...open the app in an Android emulator...
11-15: Offer Yarn parity for dependency installYou later provide Yarn commands (
yarn android / yarn ios) but step 2 only showsnpm install. Add the Yarn equivalent for consistency.npm install + # OR + yarn install
39-45: Clarify CocoaPods step wording“This only needs to be run on first clone” → “the first clone” and capitalise SDK name.
-For iOS, remember to install CocoaPods dependencies (this only needs to be run on first clone or after updating inapp sdk). +For iOS, remember to install CocoaPods dependencies (this only needs to be run on the first clone or after updating the InApp SDK).documentation/install-expo.md (3)
22-22: Insert comma after introductory clauseMissing comma after “To do so”.
-To do so merge the following code +To do so, merge the following code
46-46: Minor wording & casing“Expo Go” is fine; drop all-caps NOT and fix punctuation.
-Note: This module contains custom native code which is NOT supported by Expo Go +Note: This module contains custom native code that is not supported by Expo Go.
70-72: iOS spelling & missing article
IOS→iOS; insert a before “debug executable”.-#### Fixing performance issues on IOS physical devices -Your app performance will be severely impacted when you run debug executable on a physical device. +#### Fixing performance issues on iOS physical devices +Your app performance will be severely impacted when you run a debug executable on a physical device.documentation/install-no-framework.md (3)
70-72: Capitalise “Alternatively” and tighten wording-or alternatively add the following repositories to the relevant repositories block: +Alternatively, add the following repositories to the relevant repositories block:
103-106: iOS casing and missing article-#### Fixing performance issues on IOS physical devices -Your app performance will be severely impacted when you run debug executable on a physical device. +#### Fixing performance issues on iOS physical devices +Your app performance will be severely impacted when you run a debug executable on a physical device.
38-49: Manifest snippet indentationMany React Native projects indent XML with two spaces; your snippet is indented six, which may confuse copy-paste users. Consider normalising to two.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
documentation/install-expo.md(1 hunks)documentation/install-no-framework.md(1 hunks)samples/example_expo/README.md(1 hunks)samples/example_expo/package.json(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- samples/example_expo/package.json
🧰 Additional context used
🪛 LanguageTool
documentation/install-expo.md
[uncategorized] ~22-~22: Possible missing comma found.
Context: ... the Reclaim InApp Config Plugin. To do so merge the following code to the plugins...
(AI_HYDRA_LEO_MISSING_COMMA)
[uncategorized] ~72-~72: Possible missing article found.
Context: ... will be severely impacted when you run debug executable on a physical device. Fixing...
(AI_HYDRA_LEO_MISSING_THE)
[style] ~81-~81: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ent xcscheme in Xcode" width="500"> 4. Click on the Edit Scheme button. 5. Click...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~82-~82: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...Click on the Edit Scheme button. 5. Click on the Run tab. 6. Click on the **A...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~83-~83: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...button. 5. Click on the Run tab. 6. Click on the Arguments tab and check the ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[uncategorized] ~92-~92: Possible missing comma found.
Context: .... 9. Run the app on a physical device. Now your React Native Expo project is ready...
(AI_HYDRA_LEO_MISSING_COMMA)
documentation/install-no-framework.md
[uncategorized] ~105-~105: Possible missing article found.
Context: ... will be severely impacted when you run debug executable on a physical device. Fixing...
(AI_HYDRA_LEO_MISSING_THE)
[style] ~114-~114: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...ent xcscheme in Xcode" width="500"> 4. Click on the Edit Scheme button. 5. Click...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~115-~115: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...Click on the Edit Scheme button. 5. Click on the Run tab. 6. Click on the **A...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[style] ~116-~116: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...button. 5. Click on the Run tab. 6. Click on the Arguments tab and check the ...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
[uncategorized] ~125-~125: Possible missing comma found.
Context: .... 9. Run the app on a physical device. Now your React Native project is ready to u...
(AI_HYDRA_LEO_MISSING_COMMA)
samples/example_expo/README.md
[style] ~5-~5: Consider using “incompatible” to avoid wordiness.
Context: ...te-expo-app). Note: This plugin is not compatible with Expo Go. Please use a development ...
(NOT_ABLE_PREMIUM)
[uncategorized] ~74-~74: If this is a compound adjective that modifies the following noun, use a hyphen.
Context: ...https://github.com/expo/expo): View our open source platform and contribute. - [Discord com...
(EN_COMPOUND_ADJECTIVE_INTERNAL)
🔇 Additional comments (1)
documentation/install-expo.md (1)
28-33: ```shell
#!/bin/bashCheck the package name in package.json
echo "Package name in package.json:"
grep -E '^\s*"name":' -m1 -n package.jsonVerify that the built plugin entrypoint exists
echo ""
echo "Looking for expo-plugin/build/index.js:"
fd --max-depth 3 "expo-plugin/build/index.js"</details> </blockquote></details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
Summary by CodeRabbit
New Features
Chores
Documentation