nx-react-native-cli 2.6.12 → 2.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +43 -43
- package/package.json +1 -1
- package/templates/19.7.0/apps/mobile/.ignorefile +1 -0
- package/templates/19.7.0/apps/mobile/android/app/src/main/java/com/appsmobile/MainActivity.kt +5 -1
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/AppDelegate.mm +6 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@3x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@3x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@3x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@3x.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon~ipad.png +0 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/Contents.json +134 -0
- package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/Contents.json +6 -0
- package/templates/19.7.0/apps/mobile/project.json +17 -19
- package/templates/21.2.2/apps/mobile/.ignorefile +1 -0
- package/templates/21.2.2/apps/mobile/android/app/src/main/java/com/mobile/MainActivity.kt +5 -1
- package/templates/21.2.2/apps/mobile/ios/Mobile/AppDelegate.mm +6 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@3x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@3x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@3x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@3x.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon~ipad.png +0 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/Contents.json +134 -0
- package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/Contents.json +6 -0
- package/templates/21.2.2/apps/mobile/project.json +17 -19
- package/templates/shared/.ignorefile +1 -0
- package/templates/shared/apps/mobile/android/app/src/main/AndroidManifest.xml +28 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png +0 -0
- package/templates/shared/apps/mobile/android/app/src/main/res/styles.xml +14 -0
- package/templates/shared/apps/mobile/deploy.sh +107 -0
- package/templates/shared/apps/mobile/package.json +1 -78
- package/templates/shared/apps/mobile/picker.sh +151 -0
- package/templates/shared/apps/mobile/pod-install.sh +40 -0
- package/templates/shared/apps/mobile/react-native.config.js +15 -0
- package/templates/shared/apps/mobile/run-android.sh +131 -0
- package/templates/shared/apps/mobile/run-ios.sh +89 -0
- package/templates/shared/apps/mobile/scripts/setup-ios-dev-scheme.rb +101 -1
- package/templates/shared/apps/mobile/src/app/index.tsx +3 -39
- package/templates/shared/apps/mobile/src/app/query-client.ts +40 -0
- package/templates/shared/apps/mobile/src/assets/images/logo.png +0 -0
- package/templates/shared/apps/mobile/src/components/atoms/KeyboardAwareScrollView/keyboard-aware-scroll-view.component.tsx +1 -0
- package/templates/shared/apps/mobile/src/components/atoms/Modal/modal.component.tsx +19 -6
- package/templates/shared/apps/mobile/src/components/atoms/Typography/typography.component.tsx +1 -1
- package/templates/shared/apps/mobile/src/components/molecules/ScreenContainer/screen-container.component.tsx +2 -2
- package/templates/shared/apps/mobile/src/components/molecules/ScreenHeader/screen-header.component.tsx +1 -1
- package/templates/shared/apps/mobile/src/routes/index.tsx +7 -1
- package/templates/shared/clean-generated-outputs.sh +4 -0
- package/templates/shared/apps/mobile/src/assets/images/.gitkeep +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
|
|
2
|
+
|
|
3
|
+
<uses-permission android:name="android.permission.INTERNET" />
|
|
4
|
+
|
|
5
|
+
<application
|
|
6
|
+
android:name=".MainApplication"
|
|
7
|
+
android:label="@string/app_name"
|
|
8
|
+
android:icon="@mipmap/ic_launcher"
|
|
9
|
+
android:roundIcon="@mipmap/ic_launcher"
|
|
10
|
+
android:allowBackup="false"
|
|
11
|
+
tools:replace="android:allowBackup"
|
|
12
|
+
android:theme="@style/AppTheme"
|
|
13
|
+
android:supportsRtl="true"
|
|
14
|
+
android:networkSecurityConfig="@xml/network_security_config">
|
|
15
|
+
<activity
|
|
16
|
+
android:name=".MainActivity"
|
|
17
|
+
android:label="@string/app_name"
|
|
18
|
+
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
|
|
19
|
+
android:launchMode="singleTask"
|
|
20
|
+
android:windowSoftInputMode="adjustResize"
|
|
21
|
+
android:exported="true">
|
|
22
|
+
<intent-filter>
|
|
23
|
+
<action android:name="android.intent.action.MAIN" />
|
|
24
|
+
<category android:name="android.intent.category.LAUNCHER" />
|
|
25
|
+
</intent-filter>
|
|
26
|
+
</activity>
|
|
27
|
+
</application>
|
|
28
|
+
</manifest>
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
+
<background android:drawable="@mipmap/ic_launcher_background"/>
|
|
4
|
+
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
|
|
5
|
+
<monochrome android:drawable="@mipmap/ic_launcher_monochrome"/>
|
|
6
|
+
</adaptive-icon>
|
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png
ADDED
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png
ADDED
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png
ADDED
|
Binary file
|
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png
ADDED
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png
ADDED
|
Binary file
|
package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png
ADDED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<resources>
|
|
2
|
+
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
|
|
3
|
+
<!-- Customize your theme here. -->
|
|
4
|
+
<item name="android:editTextBackground">@drawable/rn_edit_text_material</item>
|
|
5
|
+
<item name="colorAccent">#1185e6</item>
|
|
6
|
+
<item name="colorPrimary">#1185e6</item>
|
|
7
|
+
</style>
|
|
8
|
+
|
|
9
|
+
<style name="BootTheme" parent="Theme.BootSplash">
|
|
10
|
+
<item name="bootSplashBackground">@color/bootsplash_background</item>
|
|
11
|
+
<item name="bootSplashLogo">@drawable/bootsplash_logo</item>
|
|
12
|
+
<item name="postBootSplashTheme">@style/AppTheme</item>
|
|
13
|
+
</style>
|
|
14
|
+
</resources>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Interactive deployment - picks platform, lane, and environment
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
FASTLANE_DIR="$SCRIPT_DIR/fastlane"
|
|
6
|
+
|
|
7
|
+
source "$SCRIPT_DIR/picker.sh"
|
|
8
|
+
|
|
9
|
+
# --- Platform selection ---
|
|
10
|
+
PLATFORMS=("ios" "android")
|
|
11
|
+
pick "Select a platform:" "${PLATFORMS[@]}" --key "deploy-platform"
|
|
12
|
+
SELECTED_PLATFORM="${PLATFORMS[$PICKED_INDEX]}"
|
|
13
|
+
|
|
14
|
+
# --- Lane selection (dynamically parsed from Fastfile) ---
|
|
15
|
+
LANES=$(python3 -c "
|
|
16
|
+
import re
|
|
17
|
+
with open('$FASTLANE_DIR/Fastfile') as f:
|
|
18
|
+
content = f.read()
|
|
19
|
+
|
|
20
|
+
# Find the platform block for the selected platform
|
|
21
|
+
pattern = r'platform\s+:$SELECTED_PLATFORM\s+do(.*?)^end'
|
|
22
|
+
match = re.search(pattern, content, re.DOTALL | re.MULTILINE)
|
|
23
|
+
if match:
|
|
24
|
+
block = match.group(1)
|
|
25
|
+
# Find all lane declarations
|
|
26
|
+
lanes = re.findall(r'lane\s+:(\w+)\s+do', block)
|
|
27
|
+
for lane in lanes:
|
|
28
|
+
print(lane)
|
|
29
|
+
")
|
|
30
|
+
|
|
31
|
+
if [ -z "$LANES" ]; then
|
|
32
|
+
echo "No lanes found for platform: $SELECTED_PLATFORM"
|
|
33
|
+
exit 1
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
LANE_ARRAY=()
|
|
37
|
+
while IFS= read -r line; do
|
|
38
|
+
[ -z "$line" ] && continue
|
|
39
|
+
LANE_ARRAY+=("$line")
|
|
40
|
+
done <<< "$LANES"
|
|
41
|
+
|
|
42
|
+
pick "Select a lane:" "${LANE_ARRAY[@]}" --key "deploy-lane-$SELECTED_PLATFORM"
|
|
43
|
+
SELECTED_LANE="${LANE_ARRAY[$PICKED_INDEX]}"
|
|
44
|
+
|
|
45
|
+
# --- Environment selection (dynamically from .env.* files) ---
|
|
46
|
+
ENV_ARRAY=()
|
|
47
|
+
for env_file in "$FASTLANE_DIR"/.env.*; do
|
|
48
|
+
[ -f "$env_file" ] || continue
|
|
49
|
+
env_name=$(basename "$env_file" | sed 's/^\.env\.//')
|
|
50
|
+
# Skip template
|
|
51
|
+
if [ "$env_name" = "template" ]; then
|
|
52
|
+
continue
|
|
53
|
+
fi
|
|
54
|
+
ENV_ARRAY+=("$env_name")
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
if [ ${#ENV_ARRAY[@]} -eq 0 ]; then
|
|
58
|
+
echo ""
|
|
59
|
+
echo "No environment files found. Create at least one of:"
|
|
60
|
+
echo " fastlane/.env.development"
|
|
61
|
+
echo " fastlane/.env.staging"
|
|
62
|
+
echo " fastlane/.env.production"
|
|
63
|
+
exit 1
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
pick "Select an environment:" "${ENV_ARRAY[@]}" --key "deploy-env"
|
|
67
|
+
SELECTED_ENV="${ENV_ARRAY[$PICKED_INDEX]}"
|
|
68
|
+
|
|
69
|
+
# --- Safeguard: check for local URLs in .env ---
|
|
70
|
+
APP_ENV="$SCRIPT_DIR/.env"
|
|
71
|
+
if [ -f "$APP_ENV" ]; then
|
|
72
|
+
if grep -qiE 'localhost|192\.168\.' "$APP_ENV"; then
|
|
73
|
+
echo ""
|
|
74
|
+
echo "Deployment aborted: apps/mobile/.env contains a local URL (localhost or 192.168.*)."
|
|
75
|
+
echo "Update your .env to point to the correct remote server before deploying."
|
|
76
|
+
exit 1
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --- Confirmation ---
|
|
81
|
+
echo ""
|
|
82
|
+
echo "Deploy summary:"
|
|
83
|
+
echo " Platform: $SELECTED_PLATFORM"
|
|
84
|
+
echo " Lane: $SELECTED_LANE"
|
|
85
|
+
if [ -n "$SELECTED_ENV" ]; then
|
|
86
|
+
echo " Environment: $SELECTED_ENV"
|
|
87
|
+
fi
|
|
88
|
+
echo ""
|
|
89
|
+
|
|
90
|
+
CONFIRM_ARRAY=("Yes" "No")
|
|
91
|
+
pick "Proceed with deployment?" "${CONFIRM_ARRAY[@]}"
|
|
92
|
+
if [ "$PICKED_INDEX" -ne 0 ]; then
|
|
93
|
+
echo "Deployment cancelled."
|
|
94
|
+
exit 0
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# --- Run fastlane ---
|
|
98
|
+
echo ""
|
|
99
|
+
FASTLANE_CMD="bundle exec fastlane $SELECTED_PLATFORM $SELECTED_LANE"
|
|
100
|
+
if [ -n "$SELECTED_ENV" ]; then
|
|
101
|
+
FASTLANE_CMD="$FASTLANE_CMD --env $SELECTED_ENV"
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
echo "Running: $FASTLANE_CMD"
|
|
105
|
+
echo ""
|
|
106
|
+
|
|
107
|
+
cd "$SCRIPT_DIR" && $FASTLANE_CMD
|
|
@@ -1,82 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mobile",
|
|
3
3
|
"version": "0.0.1",
|
|
4
|
-
"private": true
|
|
5
|
-
"scripts": {
|
|
6
|
-
"android:connect": "adb reverse tcp:8081 tcp:8081",
|
|
7
|
-
"start": "npx nx start mobile --skip-nx-cache",
|
|
8
|
-
"run-ios": "./ios-only.sh npx nx run-ios mobile --skip-nx-cache --scheme=Dev --simulator='iPhone 16'",
|
|
9
|
-
"run-android": "npx nx run-android mobile --skip-nx-cache",
|
|
10
|
-
"ensure-symlink": "npx nx ensure-symlink mobile",
|
|
11
|
-
"sync-deps": "npx nx sync-deps mobile",
|
|
12
|
-
"pod-install": "./ios-only.sh npx nx pod-install mobile",
|
|
13
|
-
"export-node-binary": "./export-node-binary.sh",
|
|
14
|
-
"bundle:pod-install": "./ios-only.sh 'cd ios && bundle install && bundle exec pod install --repo-update && npm run export-node-binary'",
|
|
15
|
-
"pre-build": "npm run ensure-symlink && npm run sync-deps && npm run pod-install",
|
|
16
|
-
"list:ios-configurations": "./ios-only.sh 'cd ios && xcodebuild -list'",
|
|
17
|
-
"list:ios-devices": "./ios-only.sh xcrun xctrace list devices",
|
|
18
|
-
"xcode": "./ios-only.sh xed -b ios",
|
|
19
|
-
"touch-xcode": "./ios-only.sh 'cd ios && touch .xcode.env'",
|
|
20
|
-
"check-env:mobile": "cd ../.. && npm run check-env:mobile",
|
|
21
|
-
"setup-fastlane": "rbenv local && bundle install && bundle update",
|
|
22
|
-
"deploy-android:dev": "bundle exec fastlane android dev --env development",
|
|
23
|
-
"deploy-ios:dev": "./ios-only.sh 'bundle exec fastlane ios dev --env development'",
|
|
24
|
-
"ios-certificates": "./ios-only.sh 'npm run setup-fastlane && bundle exec fastlane ios certificates --env development'"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"@gorhom/bottom-sheet": "*",
|
|
28
|
-
"@hookform/resolvers": "*",
|
|
29
|
-
"@react-native-community/datetimepicker": "*",
|
|
30
|
-
"@react-native-community/hooks": "*",
|
|
31
|
-
"@react-native/metro-config": "*",
|
|
32
|
-
"@react-navigation/core": "*",
|
|
33
|
-
"@react-navigation/material-top-tabs": "*",
|
|
34
|
-
"@react-navigation/native-stack": "*",
|
|
35
|
-
"@react-navigation/native": "*",
|
|
36
|
-
"@react-navigation/routers": "*",
|
|
37
|
-
"@react-navigation/stack": "*",
|
|
38
|
-
"@shopify/react-native-skia": "*",
|
|
39
|
-
"@tanstack/query-async-storage-persister": "*",
|
|
40
|
-
"@tanstack/query-core": "*",
|
|
41
|
-
"@tanstack/query-sync-storage-persister": "*",
|
|
42
|
-
"@tanstack/react-query-persist-client": "*",
|
|
43
|
-
"@tanstack/react-query": "*",
|
|
44
|
-
"@testing-library/jest-native": "*",
|
|
45
|
-
"@testing-library/react-native": "*",
|
|
46
|
-
"axios": "*",
|
|
47
|
-
"babel-plugin-module-resolver": "*",
|
|
48
|
-
"dayjs": "*",
|
|
49
|
-
"jotai-optics": "*",
|
|
50
|
-
"jotai": "*",
|
|
51
|
-
"lodash": "*",
|
|
52
|
-
"metro-config": "*",
|
|
53
|
-
"react-hook-form": "*",
|
|
54
|
-
"react-native-dotenv": "*",
|
|
55
|
-
"react-native-gesture-handler": "*",
|
|
56
|
-
"react-native-get-random-values": "*",
|
|
57
|
-
"react-native-haptic-feedback": "*",
|
|
58
|
-
"react-native-keyboard-controller": "*",
|
|
59
|
-
"react-native-mmkv": "*",
|
|
60
|
-
"react-native-modal-datetime-picker": "*",
|
|
61
|
-
"react-native-modal": "*",
|
|
62
|
-
"react-native-nitro-modules": "*",
|
|
63
|
-
"react-native-pager-view": "*",
|
|
64
|
-
"react-native-reanimated": "*",
|
|
65
|
-
"react-native-safe-area-context": "*",
|
|
66
|
-
"react-native-screens": "*",
|
|
67
|
-
"react-native-simple-toast": "*",
|
|
68
|
-
"react-native-svg-transformer": "*",
|
|
69
|
-
"react-native-svg": "*",
|
|
70
|
-
"react-native-turbo-image": "*",
|
|
71
|
-
"react-native-url-polyfill": "*",
|
|
72
|
-
"react-native-worklets": "*",
|
|
73
|
-
"react-native": "*",
|
|
74
|
-
"react": "*",
|
|
75
|
-
"tailwindcss": "*",
|
|
76
|
-
"twrnc": "*",
|
|
77
|
-
"uuid": "*",
|
|
78
|
-
"zod-validation-error": "*",
|
|
79
|
-
"zod": "*",
|
|
80
|
-
"zustand": "*"
|
|
81
|
-
}
|
|
4
|
+
"private": true
|
|
82
5
|
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Arrow key menu picker with scrolling and recent selection memory
|
|
3
|
+
# Usage: source picker.sh
|
|
4
|
+
# pick "Title" options_array # no memory
|
|
5
|
+
# pick "Title" options_array --key "cache-key" # remembers last pick
|
|
6
|
+
|
|
7
|
+
PICKER_CACHE_DIR="${HOME}/.cache/nxrn-picker"
|
|
8
|
+
|
|
9
|
+
pick() {
|
|
10
|
+
local title="$1"
|
|
11
|
+
shift
|
|
12
|
+
|
|
13
|
+
# Parse options and --key flag
|
|
14
|
+
local raw_options=()
|
|
15
|
+
local cache_key=""
|
|
16
|
+
while [ $# -gt 0 ]; do
|
|
17
|
+
if [ "$1" = "--key" ]; then
|
|
18
|
+
cache_key="$2"
|
|
19
|
+
shift 2
|
|
20
|
+
else
|
|
21
|
+
raw_options+=("$1")
|
|
22
|
+
shift
|
|
23
|
+
fi
|
|
24
|
+
done
|
|
25
|
+
|
|
26
|
+
local options=("${raw_options[@]}")
|
|
27
|
+
local count=${#options[@]}
|
|
28
|
+
local selected=0
|
|
29
|
+
|
|
30
|
+
# If cache key provided, sort last-used to top
|
|
31
|
+
local reordered_indices=()
|
|
32
|
+
if [ -n "$cache_key" ] && [ -f "$PICKER_CACHE_DIR/$cache_key" ]; then
|
|
33
|
+
local last_pick
|
|
34
|
+
last_pick=$(cat "$PICKER_CACHE_DIR/$cache_key")
|
|
35
|
+
|
|
36
|
+
# Find the last-used item and move it to front
|
|
37
|
+
local found_idx=-1
|
|
38
|
+
for i in "${!options[@]}"; do
|
|
39
|
+
if [ "${options[$i]}" = "$last_pick" ]; then
|
|
40
|
+
found_idx=$i
|
|
41
|
+
break
|
|
42
|
+
fi
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
if [ $found_idx -ge 0 ]; then
|
|
46
|
+
local new_options=("${options[$found_idx]}")
|
|
47
|
+
reordered_indices=($found_idx)
|
|
48
|
+
for i in "${!options[@]}"; do
|
|
49
|
+
if [ "$i" -ne $found_idx ]; then
|
|
50
|
+
new_options+=("${options[$i]}")
|
|
51
|
+
reordered_indices+=($i)
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
options=("${new_options[@]}")
|
|
55
|
+
fi
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# If no reorder happened, build identity mapping
|
|
59
|
+
if [ ${#reordered_indices[@]} -eq 0 ]; then
|
|
60
|
+
for i in "${!options[@]}"; do
|
|
61
|
+
reordered_indices+=($i)
|
|
62
|
+
done
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# Max visible rows
|
|
66
|
+
local term_height=$(tput lines)
|
|
67
|
+
local max_visible=$((term_height - 4))
|
|
68
|
+
if [ $max_visible -gt $count ]; then
|
|
69
|
+
max_visible=$count
|
|
70
|
+
fi
|
|
71
|
+
if [ $max_visible -lt 3 ]; then
|
|
72
|
+
max_visible=3
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
local scroll_offset=0
|
|
76
|
+
|
|
77
|
+
tput civis
|
|
78
|
+
trap 'tput cnorm' RETURN
|
|
79
|
+
|
|
80
|
+
draw_menu() {
|
|
81
|
+
for ((i = 0; i < max_visible; i++)); do
|
|
82
|
+
local idx=$((scroll_offset + i))
|
|
83
|
+
tput el
|
|
84
|
+
if [ "$idx" -eq $selected ]; then
|
|
85
|
+
echo -e " \033[7m> ${options[$idx]}\033[0m"
|
|
86
|
+
else
|
|
87
|
+
echo " ${options[$idx]}"
|
|
88
|
+
fi
|
|
89
|
+
done
|
|
90
|
+
tput el
|
|
91
|
+
if [ $count -gt $max_visible ]; then
|
|
92
|
+
echo -e " \033[2m[$((selected + 1))/$count]\033[0m"
|
|
93
|
+
else
|
|
94
|
+
echo ""
|
|
95
|
+
fi
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
echo ""
|
|
99
|
+
echo "$title"
|
|
100
|
+
draw_menu
|
|
101
|
+
|
|
102
|
+
local visible_lines=$((max_visible + 1))
|
|
103
|
+
|
|
104
|
+
while true; do
|
|
105
|
+
IFS= read -rsn1 key
|
|
106
|
+
|
|
107
|
+
if [[ "$key" == $'\x1b' ]]; then
|
|
108
|
+
read -rsn2 rest
|
|
109
|
+
key+="$rest"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
case "$key" in
|
|
113
|
+
$'\x1b[A' | k)
|
|
114
|
+
((selected--))
|
|
115
|
+
if [ $selected -lt 0 ]; then
|
|
116
|
+
selected=$((count - 1))
|
|
117
|
+
scroll_offset=$((count - max_visible))
|
|
118
|
+
if [ $scroll_offset -lt 0 ]; then scroll_offset=0; fi
|
|
119
|
+
elif [ $selected -lt $scroll_offset ]; then
|
|
120
|
+
scroll_offset=$selected
|
|
121
|
+
fi
|
|
122
|
+
;;
|
|
123
|
+
$'\x1b[B' | j)
|
|
124
|
+
((selected++))
|
|
125
|
+
if [ $selected -ge $count ]; then
|
|
126
|
+
selected=0
|
|
127
|
+
scroll_offset=0
|
|
128
|
+
elif [ $selected -ge $((scroll_offset + max_visible)) ]; then
|
|
129
|
+
scroll_offset=$((selected - max_visible + 1))
|
|
130
|
+
fi
|
|
131
|
+
;;
|
|
132
|
+
'')
|
|
133
|
+
break
|
|
134
|
+
;;
|
|
135
|
+
esac
|
|
136
|
+
|
|
137
|
+
tput cuu $visible_lines
|
|
138
|
+
draw_menu
|
|
139
|
+
done
|
|
140
|
+
|
|
141
|
+
tput cnorm
|
|
142
|
+
|
|
143
|
+
# Save selection to cache
|
|
144
|
+
if [ -n "$cache_key" ]; then
|
|
145
|
+
mkdir -p "$PICKER_CACHE_DIR"
|
|
146
|
+
echo "${options[$selected]}" > "$PICKER_CACHE_DIR/$cache_key"
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
# Map back to original index
|
|
150
|
+
PICKED_INDEX=${reordered_indices[$selected]}
|
|
151
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Smart pod install - only runs when dependencies have changed
|
|
3
|
+
# Compares checksum of Podfile + root package.json deps against cached value
|
|
4
|
+
|
|
5
|
+
if [[ "$OSTYPE" != "darwin"* ]]; then
|
|
6
|
+
echo "Skipping pod install on non-macOS platform"
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
11
|
+
IOS_DIR="$SCRIPT_DIR/ios"
|
|
12
|
+
ROOT_DIR="$SCRIPT_DIR/../.."
|
|
13
|
+
CHECKSUM_FILE="$IOS_DIR/.pods-checksum"
|
|
14
|
+
|
|
15
|
+
# Generate checksum from files that affect pods
|
|
16
|
+
CURRENT_CHECKSUM=$(cat \
|
|
17
|
+
"$IOS_DIR/Podfile" \
|
|
18
|
+
"$ROOT_DIR/package.json" \
|
|
19
|
+
"$ROOT_DIR/yarn.lock" \
|
|
20
|
+
2>/dev/null | shasum -a 256 | awk '{print $1}')
|
|
21
|
+
|
|
22
|
+
# Compare with cached checksum
|
|
23
|
+
if [ -f "$CHECKSUM_FILE" ]; then
|
|
24
|
+
CACHED_CHECKSUM=$(cat "$CHECKSUM_FILE")
|
|
25
|
+
if [ "$CURRENT_CHECKSUM" = "$CACHED_CHECKSUM" ]; then
|
|
26
|
+
echo "Pods up to date, skipping install."
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
echo "Dependencies changed, running pod install..."
|
|
32
|
+
cd "$IOS_DIR" && bundle install && bundle exec pod install
|
|
33
|
+
|
|
34
|
+
if [ $? -eq 0 ]; then
|
|
35
|
+
echo "$CURRENT_CHECKSUM" > "$CHECKSUM_FILE"
|
|
36
|
+
cd "$SCRIPT_DIR" && ./export-node-binary.sh
|
|
37
|
+
else
|
|
38
|
+
echo "Pod install failed"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
@@ -1,4 +1,19 @@
|
|
|
1
|
+
const rootPkg = require('../../package.json');
|
|
2
|
+
|
|
3
|
+
// Dynamically read all dependencies from the root package.json
|
|
4
|
+
// so autolinking discovers native modules without duplicating deps here.
|
|
5
|
+
const allDeps = Object.keys({
|
|
6
|
+
...rootPkg.dependencies,
|
|
7
|
+
...rootPkg.devDependencies,
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const dependencies = {};
|
|
11
|
+
for (const dep of allDeps) {
|
|
12
|
+
dependencies[dep] = {};
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
module.exports = {
|
|
16
|
+
dependencies,
|
|
2
17
|
project: {
|
|
3
18
|
ios: {},
|
|
4
19
|
android: {},
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Interactive Android launcher - picks variant and device
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
ANDROID_DIR="$SCRIPT_DIR/android"
|
|
6
|
+
|
|
7
|
+
source "$SCRIPT_DIR/picker.sh"
|
|
8
|
+
|
|
9
|
+
# --- Variant selection via gradle install tasks ---
|
|
10
|
+
echo ""
|
|
11
|
+
echo "Fetching build variants..."
|
|
12
|
+
|
|
13
|
+
INSTALL_TASKS=$(cd "$ANDROID_DIR" && ./gradlew app:tasks --group=install --quiet 2>/dev/null | grep "^install" | grep -vi "AndroidTest\|Optimized" | awk '{print $1}')
|
|
14
|
+
|
|
15
|
+
if [ -z "$INSTALL_TASKS" ]; then
|
|
16
|
+
echo "Could not read build variants from Gradle"
|
|
17
|
+
exit 1
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
TASK_ARRAY=()
|
|
21
|
+
DISPLAY_ARRAY=()
|
|
22
|
+
while IFS= read -r line; do
|
|
23
|
+
[ -z "$line" ] && continue
|
|
24
|
+
TASK_ARRAY+=("$line")
|
|
25
|
+
DISPLAY_ARRAY+=("${line#install}")
|
|
26
|
+
done <<< "$INSTALL_TASKS"
|
|
27
|
+
|
|
28
|
+
pick "Select a build variant:" "${DISPLAY_ARRAY[@]}" --key "android-variant"
|
|
29
|
+
SELECTED_TASK="${TASK_ARRAY[$PICKED_INDEX]}"
|
|
30
|
+
SELECTED_VARIANT="${SELECTED_TASK#install}"
|
|
31
|
+
|
|
32
|
+
# Mode is the full variant name with first letter lowercased (e.g. devDebug, productionRelease)
|
|
33
|
+
MODE="$(tr '[:upper:]' '[:lower:]' <<< "${SELECTED_VARIANT:0:1}")${SELECTED_VARIANT:1}"
|
|
34
|
+
|
|
35
|
+
# Infer appIdSuffix from flavor (lowercase first char of variant minus build type)
|
|
36
|
+
FLAVOR=$(echo "$SELECTED_VARIANT" | sed -E 's/(Debug|Release)$//' | tr '[:upper:]' '[:lower:]')
|
|
37
|
+
APP_ID_SUFFIX=""
|
|
38
|
+
if [ "$FLAVOR" != "production" ] && [ -n "$FLAVOR" ]; then
|
|
39
|
+
APP_ID_SUFFIX="$FLAVOR"
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
# --- Device selection (booted devices + shutdown AVDs) ---
|
|
43
|
+
DEVICE_ARRAY=()
|
|
44
|
+
DEVICE_IDS=()
|
|
45
|
+
DEVICE_TYPES=() # "booted" or "avd"
|
|
46
|
+
|
|
47
|
+
# Collect running devices/emulators
|
|
48
|
+
RUNNING_AVDS=()
|
|
49
|
+
DEVICES=$(adb devices -l 2>/dev/null | tail -n +2 | grep -v '^$')
|
|
50
|
+
if [ -n "$DEVICES" ]; then
|
|
51
|
+
while IFS= read -r line; do
|
|
52
|
+
[ -z "$line" ] && continue
|
|
53
|
+
SERIAL=$(echo "$line" | awk '{print $1}')
|
|
54
|
+
MODEL=$(echo "$line" | grep -o 'model:[^ ]*' | cut -d: -f2)
|
|
55
|
+
|
|
56
|
+
if echo "$SERIAL" | grep -q "emulator"; then
|
|
57
|
+
# Get AVD name for this running emulator
|
|
58
|
+
AVD_NAME=$(adb -s "$SERIAL" emu avd name 2>/dev/null | head -1 | tr -d '\r')
|
|
59
|
+
RUNNING_AVDS+=("$AVD_NAME")
|
|
60
|
+
LABEL="[Booted] $SERIAL${AVD_NAME:+ ($AVD_NAME)}"
|
|
61
|
+
else
|
|
62
|
+
LABEL="[Device] $SERIAL${MODEL:+ ($MODEL)}"
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
DEVICE_ARRAY+=("$LABEL")
|
|
66
|
+
DEVICE_IDS+=("$SERIAL")
|
|
67
|
+
DEVICE_TYPES+=("booted")
|
|
68
|
+
done <<< "$DEVICES"
|
|
69
|
+
fi
|
|
70
|
+
|
|
71
|
+
# Collect shutdown AVDs
|
|
72
|
+
ALL_AVDS=$(emulator -list-avds 2>/dev/null)
|
|
73
|
+
if [ -n "$ALL_AVDS" ]; then
|
|
74
|
+
while IFS= read -r avd; do
|
|
75
|
+
[ -z "$avd" ] && continue
|
|
76
|
+
# Skip if already running
|
|
77
|
+
ALREADY_RUNNING=false
|
|
78
|
+
for running in "${RUNNING_AVDS[@]}"; do
|
|
79
|
+
if [ "$avd" = "$running" ]; then
|
|
80
|
+
ALREADY_RUNNING=true
|
|
81
|
+
break
|
|
82
|
+
fi
|
|
83
|
+
done
|
|
84
|
+
if [ "$ALREADY_RUNNING" = false ]; then
|
|
85
|
+
DEVICE_ARRAY+=("[Shutdown] $avd")
|
|
86
|
+
DEVICE_IDS+=("$avd")
|
|
87
|
+
DEVICE_TYPES+=("avd")
|
|
88
|
+
fi
|
|
89
|
+
done <<< "$ALL_AVDS"
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
if [ ${#DEVICE_ARRAY[@]} -eq 0 ]; then
|
|
93
|
+
echo ""
|
|
94
|
+
echo "No Android devices or AVDs found."
|
|
95
|
+
exit 1
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
pick "Select a device:" "${DEVICE_ARRAY[@]}" --key "android-device"
|
|
99
|
+
SELECTED_INDEX=$PICKED_INDEX
|
|
100
|
+
SELECTED_DEVICE="${DEVICE_IDS[$SELECTED_INDEX]}"
|
|
101
|
+
|
|
102
|
+
# Boot AVD if shutdown
|
|
103
|
+
if [ "${DEVICE_TYPES[$SELECTED_INDEX]}" = "avd" ]; then
|
|
104
|
+
echo ""
|
|
105
|
+
echo "Booting AVD: $SELECTED_DEVICE..."
|
|
106
|
+
# Launch in a new session so it's fully detached from this script
|
|
107
|
+
perl -e 'use POSIX "setsid"; setsid(); exec("emulator", "-avd", $ARGV[0], "-no-snapshot-load")' "$SELECTED_DEVICE" </dev/null &>/dev/null &
|
|
108
|
+
|
|
109
|
+
# Wait for device to come online
|
|
110
|
+
echo "Waiting for device to boot..."
|
|
111
|
+
adb wait-for-device
|
|
112
|
+
# Wait for boot animation to finish
|
|
113
|
+
while [ "$(adb shell getprop sys.boot_completed 2>/dev/null | tr -d '\r')" != "1" ]; do
|
|
114
|
+
sleep 1
|
|
115
|
+
done
|
|
116
|
+
echo "Device booted."
|
|
117
|
+
|
|
118
|
+
# Get the serial of the newly booted emulator
|
|
119
|
+
SELECTED_DEVICE=$(adb devices | grep "emulator" | tail -1 | awk '{print $1}')
|
|
120
|
+
fi
|
|
121
|
+
|
|
122
|
+
echo ""
|
|
123
|
+
echo "Running: task=$SELECTED_TASK mode=$MODE device=$SELECTED_DEVICE"
|
|
124
|
+
echo ""
|
|
125
|
+
|
|
126
|
+
RN_ARGS="--tasks=$SELECTED_TASK --mode=$MODE --device=$SELECTED_DEVICE"
|
|
127
|
+
if [ -n "$APP_ID_SUFFIX" ]; then
|
|
128
|
+
RN_ARGS="$RN_ARGS --appIdSuffix=$APP_ID_SUFFIX"
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
cd "$SCRIPT_DIR" && npx react-native run-android $RN_ARGS
|