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.
Files changed (99) hide show
  1. package/lib/index.cjs +43 -43
  2. package/package.json +1 -1
  3. package/templates/19.7.0/apps/mobile/.ignorefile +1 -0
  4. package/templates/19.7.0/apps/mobile/android/app/src/main/java/com/appsmobile/MainActivity.kt +5 -1
  5. package/templates/19.7.0/apps/mobile/ios/AppsMobile/AppDelegate.mm +6 -0
  6. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x.png +0 -0
  7. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png +0 -0
  8. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@3x.png +0 -0
  9. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png +0 -0
  10. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29.png +0 -0
  11. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x.png +0 -0
  12. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png +0 -0
  13. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@3x.png +0 -0
  14. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png +0 -0
  15. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x.png +0 -0
  16. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png +0 -0
  17. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@3x.png +0 -0
  18. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png +0 -0
  19. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png +0 -0
  20. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png +0 -0
  21. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png +0 -0
  22. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png +0 -0
  23. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png +0 -0
  24. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon@3x.png +0 -0
  25. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png +0 -0
  26. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/AppIcon~ipad.png +0 -0
  27. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/AppIcon.appiconset/Contents.json +134 -0
  28. package/templates/19.7.0/apps/mobile/ios/AppsMobile/Images.xcassets/Contents.json +6 -0
  29. package/templates/19.7.0/apps/mobile/project.json +17 -19
  30. package/templates/21.2.2/apps/mobile/.ignorefile +1 -0
  31. package/templates/21.2.2/apps/mobile/android/app/src/main/java/com/mobile/MainActivity.kt +5 -1
  32. package/templates/21.2.2/apps/mobile/ios/Mobile/AppDelegate.mm +6 -0
  33. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x.png +0 -0
  34. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@2x~ipad.png +0 -0
  35. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20@3x.png +0 -0
  36. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-20~ipad.png +0 -0
  37. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29.png +0 -0
  38. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x.png +0 -0
  39. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@2x~ipad.png +0 -0
  40. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29@3x.png +0 -0
  41. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-29~ipad.png +0 -0
  42. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x.png +0 -0
  43. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@2x~ipad.png +0 -0
  44. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40@3x.png +0 -0
  45. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-40~ipad.png +0 -0
  46. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@2x~car.png +0 -0
  47. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-60@3x~car.png +0 -0
  48. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon-83.5@2x~ipad.png +0 -0
  49. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x.png +0 -0
  50. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@2x~ipad.png +0 -0
  51. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon@3x.png +0 -0
  52. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon~ios-marketing.png +0 -0
  53. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/AppIcon~ipad.png +0 -0
  54. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/AppIcon.appiconset/Contents.json +134 -0
  55. package/templates/21.2.2/apps/mobile/ios/Mobile/Images.xcassets/Contents.json +6 -0
  56. package/templates/21.2.2/apps/mobile/project.json +17 -19
  57. package/templates/shared/.ignorefile +1 -0
  58. package/templates/shared/apps/mobile/android/app/src/main/AndroidManifest.xml +28 -0
  59. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +6 -0
  60. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +0 -0
  61. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_background.png +0 -0
  62. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png +0 -0
  63. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-hdpi/ic_launcher_monochrome.png +0 -0
  64. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +0 -0
  65. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_background.png +0 -0
  66. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png +0 -0
  67. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-mdpi/ic_launcher_monochrome.png +0 -0
  68. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +0 -0
  69. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png +0 -0
  70. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
  71. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xhdpi/ic_launcher_monochrome.png +0 -0
  72. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +0 -0
  73. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png +0 -0
  74. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
  75. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_monochrome.png +0 -0
  76. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png +0 -0
  77. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png +0 -0
  78. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
  79. package/templates/shared/apps/mobile/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_monochrome.png +0 -0
  80. package/templates/shared/apps/mobile/android/app/src/main/res/styles.xml +14 -0
  81. package/templates/shared/apps/mobile/deploy.sh +107 -0
  82. package/templates/shared/apps/mobile/package.json +1 -78
  83. package/templates/shared/apps/mobile/picker.sh +151 -0
  84. package/templates/shared/apps/mobile/pod-install.sh +40 -0
  85. package/templates/shared/apps/mobile/react-native.config.js +15 -0
  86. package/templates/shared/apps/mobile/run-android.sh +131 -0
  87. package/templates/shared/apps/mobile/run-ios.sh +89 -0
  88. package/templates/shared/apps/mobile/scripts/setup-ios-dev-scheme.rb +101 -1
  89. package/templates/shared/apps/mobile/src/app/index.tsx +3 -39
  90. package/templates/shared/apps/mobile/src/app/query-client.ts +40 -0
  91. package/templates/shared/apps/mobile/src/assets/images/logo.png +0 -0
  92. package/templates/shared/apps/mobile/src/components/atoms/KeyboardAwareScrollView/keyboard-aware-scroll-view.component.tsx +1 -0
  93. package/templates/shared/apps/mobile/src/components/atoms/Modal/modal.component.tsx +19 -6
  94. package/templates/shared/apps/mobile/src/components/atoms/Typography/typography.component.tsx +1 -1
  95. package/templates/shared/apps/mobile/src/components/molecules/ScreenContainer/screen-container.component.tsx +2 -2
  96. package/templates/shared/apps/mobile/src/components/molecules/ScreenHeader/screen-header.component.tsx +1 -1
  97. package/templates/shared/apps/mobile/src/routes/index.tsx +7 -1
  98. package/templates/shared/clean-generated-outputs.sh +4 -0
  99. 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>
@@ -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>
@@ -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