mirror of
				https://gitcode.com/gh_mirrors/re/react-native-pushy.git
				synced 2025-10-31 21:33:12 +08:00 
			
		
		
		
	feat: project init
This commit is contained in:
		
							
								
								
									
										232
									
								
								.github/workflows/e2e_android.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										232
									
								
								.github/workflows/e2e_android.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,232 @@ | |||||||
|  | name: Testing E2E Android | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   workflow_dispatch: | ||||||
|  |     inputs: | ||||||
|  |       clearCaches: | ||||||
|  |         description: "Clear workflow caches where possible" | ||||||
|  |         required: false | ||||||
|  |         type: string | ||||||
|  |  | ||||||
|  |   pull_request: | ||||||
|  |     branches: | ||||||
|  |       - '**' | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - '.spellcheck.dict.txt' | ||||||
|  |       # - '**/*.md' | ||||||
|  |  | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - main | ||||||
|  |       - v14-release | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - '.spellcheck.dict.txt' | ||||||
|  |  | ||||||
|  | concurrency: | ||||||
|  |   group: ${{ github.workflow }}-${{ github.ref }} | ||||||
|  |   cancel-in-progress: true | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   android: | ||||||
|  |     name: Android | ||||||
|  |     runs-on: macos-12 | ||||||
|  |     timeout-minutes: 90 | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         # Refactor to make these dynamic with a low/high bracket only on schedule, not push | ||||||
|  |         # For now this is just the fastest combo (api/arch/target/snapshot-warm-time) based on testing | ||||||
|  |         api-level: [30] | ||||||
|  |         arch: [x86_64] | ||||||
|  |         target: [google_apis] | ||||||
|  |         first-boot-delay: [600] | ||||||
|  |         # This is useful for benchmarking, do 0, 1, 2, etc (up to 256 max job-per-matrix limit) for averages | ||||||
|  |         iteration: [0] | ||||||
|  |     env: | ||||||
|  |       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||||||
|  |       EMULATOR_COMMAND: "-avd TestingAVD -noaudio -gpu swiftshader_indirect -camera-back none -no-snapshot -no-window -no-boot-anim -nojni -memory 2048 -timezone 'Europe/London' -cores 2" | ||||||
|  |       EMULATOR_EXECUTABLE: qemu-system-x86_64-headless | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 50 | ||||||
|  |  | ||||||
|  |       # Set up tool versions | ||||||
|  |       - uses: actions/setup-node@v3 | ||||||
|  |         with: | ||||||
|  |           node-version: 16 | ||||||
|  |  | ||||||
|  |       - name: Configure JDK 1.11 | ||||||
|  |         uses: actions/setup-java@v3 | ||||||
|  |         with: | ||||||
|  |           distribution: 'temurin' | ||||||
|  |           java-version: '11' | ||||||
|  |  | ||||||
|  |       # Set path variables needed for caches | ||||||
|  |       - name: Set workflow variables | ||||||
|  |         id: workflow-variables | ||||||
|  |         run: | | ||||||
|  |           echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT | ||||||
|  |           echo "yarn-cache-dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | ||||||
|  |           echo "tempdir=$TMPDIR" >> $GITHUB_OUTPUT | ||||||
|  |  | ||||||
|  |       - uses: actions/cache@v3 | ||||||
|  |         name: Yarn Cache | ||||||
|  |         id: yarn-cache | ||||||
|  |         with: | ||||||
|  |           path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }} | ||||||
|  |           key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock') }} | ||||||
|  |           restore-keys: ${{ runner.os }}-yarn-v1 | ||||||
|  |  | ||||||
|  |       - name: Yarn Install | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 10 | ||||||
|  |           retry_wait_seconds: 60 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: DETOX_DISABLE_POSTINSTALL=1 yarn --no-audit --prefer-offline | ||||||
|  |  | ||||||
|  |       - name: Cache pushy Emulator | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         with: | ||||||
|  |           path: ~/.cache/pushy/emulators | ||||||
|  |           key: pushy-emulators-v1-${{ github.run_id }} | ||||||
|  |           restore-keys: pushy-emulators-v1 | ||||||
|  |  | ||||||
|  |       - name: Start pushy Emulator | ||||||
|  |         run: yarn tests:emulator:start-ci | ||||||
|  |  | ||||||
|  |       - uses: actions/cache@v3 | ||||||
|  |         name: Gradle Cache | ||||||
|  |         with: | ||||||
|  |           path: ~/.gradle/caches | ||||||
|  |           key: ${{ runner.os }}-gradle-v1-${{ hashFiles('**/*.gradle*') }} | ||||||
|  |           restore-keys: ${{ runner.os }}-gradle-v1 | ||||||
|  |  | ||||||
|  |         # This appears to be 'Cache Size: ~1230 MB (1290026823 B)' based on watching action logs | ||||||
|  |         # Repo limit is 10GB; branch caches are independent; branches may read default branch cache. | ||||||
|  |         # We don't want branches to evict main branch snapshot, so save on main, read-only all else | ||||||
|  |       - name: AVD cache | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         id: avd-cache | ||||||
|  |         with: | ||||||
|  |           path: | | ||||||
|  |             ~/.android/avd/* | ||||||
|  |             ~/.android/adb* | ||||||
|  |           key: avd-${{ matrix.api-level }}-${{ matrix.arch }}-${{matrix.target}}-v1-${{ github.event.inputs.clearCaches }} | ||||||
|  |           restore-keys: | | ||||||
|  |             avd-${{ matrix.api-level }}-${{ matrix.arch }}-${{matrix.target}}-v1 | ||||||
|  |  | ||||||
|  |       - name: Clear Caches Optionally | ||||||
|  |         if: "${{ github.event.inputs.clearCaches != '' }}" | ||||||
|  |         shell: bash | ||||||
|  |         run: | | ||||||
|  |           du -sk ~/.gradle | ||||||
|  |           du -sk ~/.android | ||||||
|  |           rm -fr ~/.gradle | ||||||
|  |           rm -fr ~/.android | ||||||
|  |           du -sk ~/.gradle || echo ~/.gradle is gone | ||||||
|  |           du -sk ~/.android || echo ~/.android is gone | ||||||
|  |  | ||||||
|  |       - name: Build Android App | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 25 | ||||||
|  |           retry_wait_seconds: 60 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: yarn build:android-release | ||||||
|  |  | ||||||
|  |       - name: Metro Bundler Cache | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         with: | ||||||
|  |           path: ${{ steps.workflow-variables.outputs.metro-cache }} | ||||||
|  |           key: ${{ runner.os }}-metro-v1-${{ github.run_id }} | ||||||
|  |           restore-keys: ${{ runner.os }}-metro-v1 | ||||||
|  |  | ||||||
|  |       - name: Pre-fetch Javascript bundle | ||||||
|  |         # Prebuild the bundle so that's fast when the app starts. | ||||||
|  |         run: | | ||||||
|  |           nohup yarn tests:packager:jet-ci & | ||||||
|  |           printf 'Waiting for packager to come online' | ||||||
|  |           until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do | ||||||
|  |             printf '.' | ||||||
|  |             sleep 2 | ||||||
|  |           done | ||||||
|  |           echo "Packager is online! Preparing javascript bundle..." | ||||||
|  |           curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&inlineSourceMap=true" | ||||||
|  |           echo "...javascript bundle ready." | ||||||
|  |  | ||||||
|  |       - name: AVD Boot and Snapshot Creation | ||||||
|  |         # Only generate a snapshot with a cache miss | ||||||
|  |         # Comment the if out to generate snapshots on branch for performance testing | ||||||
|  |         if: "${{ github.event.inputs.clearCaches != '' || (steps.avd-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main') }}" | ||||||
|  |         uses: reactivecircus/android-emulator-runner@v2 | ||||||
|  |         with: | ||||||
|  |           api-level: ${{ matrix.api-level }} | ||||||
|  |           avd-name: TestingAVD | ||||||
|  |           force-avd-creation: false | ||||||
|  |           target: ${{ matrix.target }} | ||||||
|  |           arch: ${{ matrix.arch }} | ||||||
|  |           emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||||
|  |           sdcard-path-or-size: 100M | ||||||
|  |           disable-animations: true | ||||||
|  |           # Give the emulator a little time to run and do first boot stuff before taking snapshot | ||||||
|  |           script: | | ||||||
|  |             $ANDROID_HOME/platform-tools/adb logcat '*:D' -d > adb-snapshot-log.txt | ||||||
|  |             $ANDROID_HOME/platform-tools/adb logcat --clear | ||||||
|  |             echo "Generated AVD snapshot for caching." | ||||||
|  |  | ||||||
|  |         # This step is separate so pure install time may be calculated as a step | ||||||
|  |       - name: Emulator Snapshot After Firstboot Warmup | ||||||
|  |         # Only generate a snapshot for saving with a cache miss | ||||||
|  |         # Switch the if statements via comment if generating snapshots for performance testing | ||||||
|  |         # if: matrix.first-boot-delay != '0' | ||||||
|  |         if: "${{ github.event.inputs.clearCaches != '' || (steps.avd-cache.outputs.cache-hit != 'true' && github.ref == 'refs/heads/main') }}" | ||||||
|  |         env: | ||||||
|  |           FIRST_BOOT_DELAY: ${{ matrix.first-boot-delay }} | ||||||
|  |         uses: reactivecircus/android-emulator-runner@v2 | ||||||
|  |         with: | ||||||
|  |           api-level: ${{ matrix.api-level }} | ||||||
|  |           avd-name: TestingAVD | ||||||
|  |           force-avd-creation: false | ||||||
|  |           target: ${{ matrix.target }} | ||||||
|  |           arch: ${{ matrix.arch }} | ||||||
|  |           emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||||
|  |           sdcard-path-or-size: 100M | ||||||
|  |           disable-animations: true | ||||||
|  |           # Give the emulator a little time to run and do first boot stuff before taking snapshot | ||||||
|  |           # The zygote restart makes sure zygote has correct heap size as a workaround for android emulator init bug | ||||||
|  |           script: | | ||||||
|  |             $ANDROID_HOME/platform-tools/adb shell su root "setprop ctl.restart zygote" | ||||||
|  |             sleep $FIRST_BOOT_DELAY | ||||||
|  |             $ANDROID_HOME/platform-tools/adb logcat '*:D' -d > adb-warmup-log.txt | ||||||
|  |             $ANDROID_HOME/platform-tools/adb logcat --clear | ||||||
|  |             echo "First boot warmup completed." | ||||||
|  |  | ||||||
|  |       - name: Test Tapper | ||||||
|  |         # Run this outside the emulator runner so the emulator runner does not wait on it for cleanup | ||||||
|  |         run: | | ||||||
|  |           nohup sh -c "until false; do $ANDROID_HOME/platform-tools/adb shell input tap 100 800; sleep 0.2; done" & | ||||||
|  |         shell: bash | ||||||
|  |  | ||||||
|  |       - name: Detox Tests | ||||||
|  |         uses: reactivecircus/android-emulator-runner@v2 | ||||||
|  |         timeout-minutes: 40 | ||||||
|  |         with: | ||||||
|  |           api-level: ${{ matrix.api-level }} | ||||||
|  |           avd-name: TestingAVD | ||||||
|  |           force-avd-creation: false | ||||||
|  |           target: ${{ matrix.target }} | ||||||
|  |           arch: ${{ matrix.arch }} | ||||||
|  |           emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | ||||||
|  |           sdcard-path-or-size: 100M | ||||||
|  |           disable-animations: true | ||||||
|  |           # Detox uses Espresso to choreograph steps in reaction to UI events, so we need to send a stream of taps. | ||||||
|  |           script: | | ||||||
|  |             $ANDROID_HOME/platform-tools/adb devices | ||||||
|  |             nohup sh -c "$ANDROID_HOME/platform-tools/adb logcat '*:D' > adb-log.txt" & | ||||||
|  |             yarn test:android-release | ||||||
							
								
								
									
										183
									
								
								.github/workflows/e2e_ios.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										183
									
								
								.github/workflows/e2e_ios.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,183 @@ | |||||||
|  | name: Testing E2E iOS | ||||||
|  |  | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |     branches: | ||||||
|  |       - '**' | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - '.spellcheck.dict.txt' | ||||||
|  |       - '**/*.md' | ||||||
|  |  | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - main | ||||||
|  |       - v14-release | ||||||
|  |     paths-ignore: | ||||||
|  |       - 'docs/**' | ||||||
|  |       - 'website/**' | ||||||
|  |       - '.spellcheck.dict.txt' | ||||||
|  |         # - '**/*.md' | ||||||
|  |  | ||||||
|  | concurrency: | ||||||
|  |   group: ${{ github.workflow }}-${{ github.ref }} | ||||||
|  |   cancel-in-progress: true | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   ios: | ||||||
|  |     name: iOS | ||||||
|  |     runs-on: macos-12 | ||||||
|  |     # TODO matrix across APIs, at least 11 and 15 (lowest to highest) | ||||||
|  |     timeout-minutes: 60 | ||||||
|  |     env: | ||||||
|  |       CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | ||||||
|  |     steps: | ||||||
|  |       # Set up tool versions | ||||||
|  |       - uses: actions/setup-node@v3 | ||||||
|  |         with: | ||||||
|  |           node-version: 16 | ||||||
|  |  | ||||||
|  |       - name: Configure JDK 1.11 | ||||||
|  |         uses: actions/setup-java@v3 | ||||||
|  |         with: | ||||||
|  |           distribution: 'temurin' | ||||||
|  |           java-version: '11' | ||||||
|  |  | ||||||
|  |       - uses: maxim-lobanov/setup-xcode@v1 | ||||||
|  |         with: | ||||||
|  |           xcode-version: 'latest-stable' | ||||||
|  |  | ||||||
|  |       - uses: actions/checkout@v3 | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 50 | ||||||
|  |  | ||||||
|  |       # Set path variables needed for caches | ||||||
|  |       - name: Set workflow variables | ||||||
|  |         id: workflow-variables | ||||||
|  |         run: | | ||||||
|  |           echo "metro-cache=$HOME/.metro" >> $GITHUB_OUTPUT | ||||||
|  |           echo "xcode-version=$(xcodebuild -version|tail -1|cut -f3 -d' ')" >> $GITHUB_OUTPUT | ||||||
|  |           echo "yarn-cache-dir=$(yarn cache dir)" >> $GITHUB_OUTPUT | ||||||
|  |  | ||||||
|  |       - uses: actions/cache@v3 | ||||||
|  |         name: Yarn Cache | ||||||
|  |         id: yarn-cache | ||||||
|  |         with: | ||||||
|  |           path: ${{ steps.workflow-variables.outputs.yarn-cache-dir }} | ||||||
|  |           key: ${{ runner.os }}-yarn-v1-${{ hashFiles('yarn.lock') }} | ||||||
|  |           restore-keys: ${{ runner.os }}-yarn-v1 | ||||||
|  |  | ||||||
|  |       - uses: actions/cache@v3 | ||||||
|  |         name: Detox Framework Cache | ||||||
|  |         id: detox-cache | ||||||
|  |         with: | ||||||
|  |           path: ~/Library/Detox/ios | ||||||
|  |           key: ${{ runner.os }}-detox-framework-cache-${{ steps.workflow-variables.outputs.xcode-version }} | ||||||
|  |  | ||||||
|  |       # Detox is compiled during yarn install, using Xcode, set up cache first | ||||||
|  |       - uses: hendrikmuhs/ccache-action@v1.2 | ||||||
|  |         name: Xcode Compile Cache | ||||||
|  |         with: | ||||||
|  |           key: ${{ runner.os }}-v2 # makes a unique key w/related restore key internally | ||||||
|  |           max-size: 1500M | ||||||
|  |  | ||||||
|  |       - name: Yarn Install | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 10 | ||||||
|  |           retry_wait_seconds: 60 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: yarn --no-audit --prefer-offline | ||||||
|  |  | ||||||
|  |       - name: Setup Ruby | ||||||
|  |         uses: ruby/setup-ruby@v1 | ||||||
|  |         with: | ||||||
|  |           ruby-version: 3 | ||||||
|  |  | ||||||
|  |       - name: Update Ruby build tools | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 2 | ||||||
|  |           retry_wait_seconds: 60 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: gem update cocoapods xcodeproj | ||||||
|  |  | ||||||
|  |       - uses: actions/cache@v3 | ||||||
|  |         name: Cache Pods | ||||||
|  |         id: pods-cache | ||||||
|  |         with: | ||||||
|  |           path: tests/ios/Pods | ||||||
|  |           key: ${{ runner.os }}-pods-v2-${{ hashFiles('tests/ios/Podfile.lock') }} | ||||||
|  |           restore-keys: ${{ runner.os }}-pods-v2 | ||||||
|  |  | ||||||
|  |       - name: Pod Install | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 10 | ||||||
|  |           retry_wait_seconds: 30 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: yarn tests:ios:pod:install | ||||||
|  |  | ||||||
|  |       - name: Cache Firestore Emulator | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         with: | ||||||
|  |           path: ~/.cache/pushy/emulators | ||||||
|  |           key: pushy-emulators-v1-${{ github.run_id }} | ||||||
|  |           restore-keys: pushy-emulators-v1 | ||||||
|  |  | ||||||
|  |       - name: Start Firestore Emulator | ||||||
|  |         run: yarn tests:emulator:start-ci | ||||||
|  |  | ||||||
|  |       - name: Install brew utilities | ||||||
|  |         uses: nick-invision/retry@v2 | ||||||
|  |         with: | ||||||
|  |           timeout_minutes: 5 | ||||||
|  |           retry_wait_seconds: 60 | ||||||
|  |           max_attempts: 3 | ||||||
|  |           command: HOMEBREW_NO_AUTO_UPDATE=1 brew tap wix/brew && HOMEBREW_NO_AUTO_UPDATE=1 brew install applesimutils xcbeautify && applesimutils --list | ||||||
|  |  | ||||||
|  |       - name: Build iOS App | ||||||
|  |         run: | | ||||||
|  |           export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH" | ||||||
|  |           export CCACHE_SLOPPINESS=clang_index_store,file_stat_matches,include_file_ctime,include_file_mtime,ivfsoverlay,pch_defines,modules,system_headers,time_macros | ||||||
|  |           export CCACHE_FILECLONE=true | ||||||
|  |           export CCACHE_DEPEND=true | ||||||
|  |           export CCACHE_INODECACHE=true | ||||||
|  |           export CCACHE_LIMIT_MULTIPLE=0.95 | ||||||
|  |           ccache -s | ||||||
|  |           export SKIP_BUNDLING=1 | ||||||
|  |           export RCT_NO_LAUNCH_PACKAGER=1 | ||||||
|  |           set -o pipefail | ||||||
|  |           yarn build:ios-release | ||||||
|  |           ccache -s | ||||||
|  |         shell: bash | ||||||
|  |  | ||||||
|  |       - name: Metro Bundler Cache | ||||||
|  |         uses: actions/cache@v3 | ||||||
|  |         with: | ||||||
|  |           path: ${{ steps.workflow-variables.outputs.metro-cache }} | ||||||
|  |           key: ${{ runner.os }}-metro-v1-${{ github.run_id }} | ||||||
|  |           restore-keys: ${{ runner.os }}-metro-v1 | ||||||
|  |  | ||||||
|  |       - name: Pre-fetch Javascript bundle | ||||||
|  |         run: | | ||||||
|  |           nohup yarn tests:packager:jet-ci & | ||||||
|  |           printf 'Waiting for packager to come online' | ||||||
|  |           until curl --output /dev/null --silent --head --fail http://localhost:8081/status; do | ||||||
|  |             printf '.' | ||||||
|  |             sleep 2 | ||||||
|  |           done | ||||||
|  |           echo "Packager is online! Preparing bundle..." | ||||||
|  |           curl --output /dev/null --silent --head --fail "http://localhost:8081/index.bundle?platform=ios&dev=true&minify=false&inlineSourceMap=true" | ||||||
|  |           echo "...javascript bundle ready" | ||||||
|  |  | ||||||
|  |       - name: Create Simulator Log | ||||||
|  |         # With a little delay so the detox test below has time to spawn it, missing the first part of boot is fine | ||||||
|  |         # If you boot the simulator separately from detox, some other race fails and detox testee never sends ready to proxy | ||||||
|  |         continue-on-error: true | ||||||
|  |         run: nohup sh -c "sleep 30 && xcrun simctl spawn booted log stream --level debug --style compact > simulator.log 2>&1 &" | ||||||
|  |  | ||||||
|  |       - name: Detox Test | ||||||
|  |         timeout-minutes: 30 | ||||||
|  |         run: yarn test:ios-release | ||||||
							
								
								
									
										10
									
								
								.github/workflows/scripts/adb_all_emulators.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/scripts/adb_all_emulators.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | echo "Running $1 on all running emulators..." | ||||||
|  | devices=`adb devices` | ||||||
|  |  | ||||||
|  | for device in $devices; do | ||||||
|  |     if [[ "$device" =~ "emulator-" ]]; then | ||||||
|  |       adb -s $device $1 | ||||||
|  |     fi     | ||||||
|  | done     | ||||||
|  | echo "All Done." | ||||||
							
								
								
									
										13
									
								
								.github/workflows/scripts/database.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/scripts/database.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | { | ||||||
|  |   "rules": { | ||||||
|  |     // Database in general is closed. Read/Write to anything but "tests/" will fail. | ||||||
|  |     ".read": false, | ||||||
|  |     ".write": false, | ||||||
|  |  | ||||||
|  |     // ..."tests" node will succeed | ||||||
|  |      "tests": { | ||||||
|  |         ".read": true, | ||||||
|  |         ".write": true, | ||||||
|  |      } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								.github/workflows/scripts/firebase.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								.github/workflows/scripts/firebase.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | { | ||||||
|  |   "firestore": { | ||||||
|  |     "rules": "firestore.rules", | ||||||
|  |     "indexes": "firestore.indexes.json" | ||||||
|  |   }, | ||||||
|  |   "functions": { | ||||||
|  |     "predeploy": [ | ||||||
|  |       "yarn", | ||||||
|  |       "yarn --prefix \"$RESOURCE_DIR\" build" | ||||||
|  |     ], | ||||||
|  |     "source": "functions" | ||||||
|  |   }, | ||||||
|  |   "database": { | ||||||
|  |     "rules": "database.rules" | ||||||
|  |   }, | ||||||
|  |   "storage": { | ||||||
|  |     "rules": "storage.rules" | ||||||
|  |   }, | ||||||
|  |   "emulators": { | ||||||
|  |     "auth": { | ||||||
|  |       "port": 9099 | ||||||
|  |     }, | ||||||
|  |     "database": { | ||||||
|  |       "port": 9000 | ||||||
|  |     }, | ||||||
|  |     "firestore": { | ||||||
|  |       "port": 8080 | ||||||
|  |     }, | ||||||
|  |     "functions": { | ||||||
|  |       "port": 5001 | ||||||
|  |     }, | ||||||
|  |     "storage": { | ||||||
|  |       "port": 9199 | ||||||
|  |     }, | ||||||
|  |     "ui": { | ||||||
|  |       "enabled": true | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										72
									
								
								.github/workflows/scripts/firestore.indexes.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								.github/workflows/scripts/firestore.indexes.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | { | ||||||
|  |   "indexes": [ | ||||||
|  |     { | ||||||
|  |       "collectionGroup": "firestore", | ||||||
|  |       "queryScope": "COLLECTION", | ||||||
|  |       "fields": [ | ||||||
|  |         { | ||||||
|  |           "fieldPath": "a", | ||||||
|  |           "order": "ASCENDING" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "fieldPath": "b", | ||||||
|  |           "order": "ASCENDING" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ], | ||||||
|  |   "fieldOverrides": [ | ||||||
|  |     { | ||||||
|  |       "collectionGroup": "collectionGroup", | ||||||
|  |       "fieldPath": "value", | ||||||
|  |       "indexes": [ | ||||||
|  |         { | ||||||
|  |           "order": "ASCENDING", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "DESCENDING", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "arrayConfig": "CONTAINS", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "ASCENDING", | ||||||
|  |           "queryScope": "COLLECTION_GROUP" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "DESCENDING", | ||||||
|  |           "queryScope": "COLLECTION_GROUP" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     }, | ||||||
|  |     { | ||||||
|  |       "collectionGroup": "collectionGroup", | ||||||
|  |       "fieldPath": "number", | ||||||
|  |       "indexes": [ | ||||||
|  |         { | ||||||
|  |           "order": "ASCENDING", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "DESCENDING", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "arrayConfig": "CONTAINS", | ||||||
|  |           "queryScope": "COLLECTION" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "ASCENDING", | ||||||
|  |           "queryScope": "COLLECTION_GROUP" | ||||||
|  |         }, | ||||||
|  |         { | ||||||
|  |           "order": "DESCENDING", | ||||||
|  |           "queryScope": "COLLECTION_GROUP" | ||||||
|  |         } | ||||||
|  |       ] | ||||||
|  |     } | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										17
									
								
								.github/workflows/scripts/firestore.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/workflows/scripts/firestore.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | rules_version = '2'; | ||||||
|  | service cloud.firestore { | ||||||
|  |   match /databases/{database}/documents { | ||||||
|  |   match /{document=**} { | ||||||
|  |       allow read, write: if false; | ||||||
|  |     } | ||||||
|  |   match /firestore-bundle-tests/{document=**} { | ||||||
|  |       allow read, write: if true; | ||||||
|  |     } | ||||||
|  |   match /firestore/{document=**} { | ||||||
|  |       allow read, write: if true; | ||||||
|  |     }  | ||||||
|  |   match /{path=**}/collectionGroup/{documentId} { | ||||||
|  |       allow read, write: if true; | ||||||
|  |     }   | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								.github/workflows/scripts/functions/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/scripts/functions/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | |||||||
|  | # Compiled JavaScript files | ||||||
|  | lib/**/*.js | ||||||
|  | lib/**/*.js.map | ||||||
|  |  | ||||||
|  | # TypeScript v1 declaration files | ||||||
|  | typings/ | ||||||
|  |  | ||||||
|  | # Node.js dependency directory | ||||||
|  | node_modules/ | ||||||
|  | yarn.lock | ||||||
							
								
								
									
										24
									
								
								.github/workflows/scripts/functions/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/scripts/functions/package.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | |||||||
|  | { | ||||||
|  |   "name": "functions", | ||||||
|  |   "scripts": { | ||||||
|  |     "build": "tsc", | ||||||
|  |     "serve": "npm run build && firebase emulators:start --only functions", | ||||||
|  |     "shell": "npm run build && firebase functions:shell", | ||||||
|  |     "start": "npm run shell", | ||||||
|  |     "deploy": "firebase deploy --only functions", | ||||||
|  |     "logs": "firebase functions:log" | ||||||
|  |   }, | ||||||
|  |   "engines": { | ||||||
|  |     "node": "16" | ||||||
|  |   }, | ||||||
|  |   "main": "lib/index.js", | ||||||
|  |   "dependencies": { | ||||||
|  |     "firebase-admin": "^11.3.0", | ||||||
|  |     "firebase-functions": "^4.2.1" | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "firebase-functions-test": "^3.0.0", | ||||||
|  |     "typescript": "^4.9.5" | ||||||
|  |   }, | ||||||
|  |   "private": true | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								.github/workflows/scripts/functions/src/exports.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								.github/workflows/scripts/functions/src/exports.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | /* | ||||||
|  |  * | ||||||
|  |  *  Testing tools for invertase/react-native-firebase use only. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||||
|  |  * | ||||||
|  |  *  See License file for more information. | ||||||
|  | */ | ||||||
|  |  | ||||||
|  | /* eslint-disable global-require */ | ||||||
|  | module.exports = { | ||||||
|  |   SAMPLE_DATA: require('./functions/sample-data'), | ||||||
|  | }; | ||||||
							
								
								
									
										12
									
								
								.github/workflows/scripts/functions/src/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								.github/workflows/scripts/functions/src/index.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | |||||||
|  | import * as functions from 'firebase-functions'; | ||||||
|  |  | ||||||
|  | // // Start writing Firebase Functions | ||||||
|  | // // https://firebase.google.com/docs/functions/typescript | ||||||
|  | // | ||||||
|  | export const helloWorld = functions.https.onRequest((request, response) => { | ||||||
|  |   functions.logger.info('Hello logs!', { structuredData: true }); | ||||||
|  |   response.send('{ "data": "Hello from Firebase!" }'); | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | export { testFunctionCustomRegion } from './testFunctionCustomRegion'; | ||||||
|  | export { testFunctionDefaultRegion } from './testFunctionDefaultRegion'; | ||||||
							
								
								
									
										80
									
								
								.github/workflows/scripts/functions/src/sample-data.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								.github/workflows/scripts/functions/src/sample-data.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,80 @@ | |||||||
|  | /* | ||||||
|  |  *  Testing tools for invertase/react-native-firebase use only. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||||
|  |  * | ||||||
|  |  *  See License file for more information. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | const SAMPLE_DATA: { [key: string]: any } = { | ||||||
|  |   number: 1234, | ||||||
|  |   string: 'acde', | ||||||
|  |   boolean: true, | ||||||
|  |   null: null, | ||||||
|  |   object: { | ||||||
|  |     number: 1234, | ||||||
|  |     string: 'acde', | ||||||
|  |     boolean: true, | ||||||
|  |     null: null, | ||||||
|  |   }, | ||||||
|  |   array: [1234, 'acde', true, null], | ||||||
|  |   deepObject: { | ||||||
|  |     array: [1234, 'acde', false, null], | ||||||
|  |     object: { | ||||||
|  |       number: 1234, | ||||||
|  |       string: 'acde', | ||||||
|  |       boolean: true, | ||||||
|  |       null: null, | ||||||
|  |       array: [1234, 'acde', true, null], | ||||||
|  |     }, | ||||||
|  |     number: 1234, | ||||||
|  |     string: 'acde', | ||||||
|  |     boolean: true, | ||||||
|  |     null: null, | ||||||
|  |   }, | ||||||
|  |   deepArray: [ | ||||||
|  |     1234, | ||||||
|  |     'acde', | ||||||
|  |     true, | ||||||
|  |     null, | ||||||
|  |     [1234, 'acde', true, null], | ||||||
|  |     { | ||||||
|  |       number: 1234, | ||||||
|  |       string: 'acde', | ||||||
|  |       boolean: true, | ||||||
|  |       null: null, | ||||||
|  |       array: [1234, 'acde', true, null], | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  |   deepMap: { | ||||||
|  |     number: 123, | ||||||
|  |     string: 'foo', | ||||||
|  |     booleanTrue: true, | ||||||
|  |     booleanFalse: false, | ||||||
|  |     null: null, | ||||||
|  |     list: ['1', 2, true, false], | ||||||
|  |     map: { | ||||||
|  |       number: 123, | ||||||
|  |       string: 'foo', | ||||||
|  |       booleanTrue: true, | ||||||
|  |       booleanFalse: false, | ||||||
|  |       null: null, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   deepList: [ | ||||||
|  |     '1', | ||||||
|  |     2, | ||||||
|  |     true, | ||||||
|  |     false, | ||||||
|  |     ['1', 2, true, false], | ||||||
|  |     { | ||||||
|  |       number: 123, | ||||||
|  |       string: 'foo', | ||||||
|  |       booleanTrue: true, | ||||||
|  |       booleanFalse: false, | ||||||
|  |       null: null, | ||||||
|  |     }, | ||||||
|  |   ], | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default SAMPLE_DATA; | ||||||
							
								
								
									
										14
									
								
								.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								.github/workflows/scripts/functions/src/testFunctionCustomRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | /* | ||||||
|  |  * | ||||||
|  |  *  Testing tools for invertase/react-native-firebase use only. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||||
|  |  * | ||||||
|  |  *  See License file for more information. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import * as functions from 'firebase-functions'; | ||||||
|  |  | ||||||
|  | export const testFunctionCustomRegion = functions | ||||||
|  |   .region('europe-west1') | ||||||
|  |   .https.onCall(() => 'europe-west1'); | ||||||
							
								
								
									
										70
									
								
								.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								.github/workflows/scripts/functions/src/testFunctionDefaultRegion.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | |||||||
|  | /* | ||||||
|  |  * | ||||||
|  |  *  Testing tools for invertase/react-native-firebase use only. | ||||||
|  |  * | ||||||
|  |  *  Copyright (C) 2018-present Invertase Limited <oss@invertase.io> | ||||||
|  |  * | ||||||
|  |  *  See License file for more information. | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | import * as assert from 'assert'; | ||||||
|  | import { FirebaseError } from 'firebase-admin'; | ||||||
|  | import * as functions from 'firebase-functions'; | ||||||
|  | import SAMPLE_DATA from './sample-data'; | ||||||
|  |  | ||||||
|  | export const testFunctionDefaultRegion = functions.https.onCall(data => { | ||||||
|  |   console.log(Date.now(), data); | ||||||
|  |  | ||||||
|  |   if (typeof data === 'undefined') { | ||||||
|  |     return 'undefined'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (typeof data === 'string') { | ||||||
|  |     return 'string'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (typeof data === 'number') { | ||||||
|  |     return 'number'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (typeof data === 'boolean') { | ||||||
|  |     return 'boolean'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (data === null) { | ||||||
|  |     return 'null'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   if (Array.isArray(data)) { | ||||||
|  |     return 'array'; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const { type, asError, inputData } = data; | ||||||
|  |   if (!Object.hasOwnProperty.call(SAMPLE_DATA, type)) { | ||||||
|  |     throw new functions.https.HttpsError('invalid-argument', 'Invalid test requested.'); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const outputData = SAMPLE_DATA[type]; | ||||||
|  |  | ||||||
|  |   try { | ||||||
|  |     assert.deepEqual(outputData, inputData); | ||||||
|  |   } catch (e) { | ||||||
|  |     console.error(e); | ||||||
|  |     throw new functions.https.HttpsError( | ||||||
|  |       'invalid-argument', | ||||||
|  |       'Input and Output types did not match.', | ||||||
|  |       (e as FirebaseError).message, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // all good | ||||||
|  |   if (asError) { | ||||||
|  |     throw new functions.https.HttpsError( | ||||||
|  |       'cancelled', | ||||||
|  |       'Response data was requested to be sent as part of an Error payload, so here we are!', | ||||||
|  |       outputData, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   return outputData; | ||||||
|  | }); | ||||||
							
								
								
									
										16
									
								
								.github/workflows/scripts/functions/tsconfig.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/scripts/functions/tsconfig.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | { | ||||||
|  |   "compilerOptions": { | ||||||
|  |     "module": "commonjs", | ||||||
|  |     "noImplicitReturns": true, | ||||||
|  |     "noUnusedLocals": true, | ||||||
|  |     "outDir": "lib", | ||||||
|  |     "sourceMap": true, | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |     "strict": true, | ||||||
|  |     "target": "es2017" | ||||||
|  |   }, | ||||||
|  |   "compileOnSave": true, | ||||||
|  |   "include": [ | ||||||
|  |     "src" | ||||||
|  |   ] | ||||||
|  | } | ||||||
							
								
								
									
										6
									
								
								.github/workflows/scripts/start-firebase-emulator.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/scripts/start-firebase-emulator.bat
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | @REM this pushd is likely not needed, but just in case | ||||||
|  | pushd "%~dp0" | ||||||
|  | @REM this is just to see what our current directory is. Should be .github/workflow/scripts | ||||||
|  | echo %cd% | ||||||
|  | @REM strangely, unless you specify the config file as being right in the current directory, it won't find it, and everything fails | ||||||
|  | yarn firebase emulators:start --config %cd%\firebase.json --only auth,database,firestore,functions,storage --project react-native-firebase-testing | ||||||
							
								
								
									
										44
									
								
								.github/workflows/scripts/start-firebase-emulator.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										44
									
								
								.github/workflows/scripts/start-firebase-emulator.sh
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | if ! [ -x "$(command -v firebase)" ]; then | ||||||
|  |   echo "❌ Firebase-tools CLI is missing. Run 'npm i -g firebase-tools' or the equivalent" | ||||||
|  |   exit 1 | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | EMU_START_COMMAND="firebase emulators:start --only auth,database,firestore,functions,storage --project react-native-firebase-testing" | ||||||
|  | #EMU_START_COMMAND="sleep 120" | ||||||
|  | MAX_RETRIES=3 | ||||||
|  | MAX_CHECKATTEMPTS=60 | ||||||
|  | CHECKATTEMPTS_WAIT=1 | ||||||
|  |  | ||||||
|  | # Make sure functions are ready to go | ||||||
|  | pushd "$(dirname "$0")/functions" && yarn && yarn build && popd | ||||||
|  |  | ||||||
|  |  | ||||||
|  | RETRIES=1 | ||||||
|  | while [ $RETRIES -le $MAX_RETRIES ]; do | ||||||
|  |  | ||||||
|  |   if [ "$1" == "--no-daemon" ]; then | ||||||
|  |     echo "Starting Firebase Emulator Suite in foreground." | ||||||
|  |     $EMU_START_COMMAND | ||||||
|  |     exit 0 | ||||||
|  |   else | ||||||
|  |     echo "Starting Firebase Emulator Suite in background." | ||||||
|  |     $EMU_START_COMMAND & | ||||||
|  |     CHECKATTEMPTS=1 | ||||||
|  |     while [ $CHECKATTEMPTS -le $MAX_CHECKATTEMPTS ]; do | ||||||
|  |       sleep $CHECKATTEMPTS_WAIT | ||||||
|  |       if curl --output /dev/null --silent --fail http://localhost:8080; then | ||||||
|  |         echo "Firebase Emulator Suite is online!" | ||||||
|  |         exit 0; | ||||||
|  |       fi | ||||||
|  |       echo "Waiting for Firebase Emulator Suite to come online, check $CHECKATTEMPTS of $MAX_CHECKATTEMPTS..." | ||||||
|  |       ((CHECKATTEMPTS = CHECKATTEMPTS + 1)) | ||||||
|  |     done | ||||||
|  |   fi | ||||||
|  |  | ||||||
|  |   echo "Firebase Emulator Suite did not come online in $MAX_CHECKATTEMPTS checks. Try $RETRIES of $MAX_RETRIES." | ||||||
|  |   ((RETRIES = RETRIES + 1)) | ||||||
|  |  | ||||||
|  | done | ||||||
|  | echo "Firebase Emulator Suite did not come online after $MAX_RETRIES attempts." | ||||||
|  | exit 1 | ||||||
							
								
								
									
										21
									
								
								.github/workflows/scripts/storage.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								.github/workflows/scripts/storage.rules
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | |||||||
|  | rules_version = '2'; | ||||||
|  | service firebase.storage { | ||||||
|  |   match /b/{bucket}/o { | ||||||
|  |     match /{document=**} { | ||||||
|  |       allow read, write: if false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     match /writeOnly.jpeg { | ||||||
|  |       allow read: if false; | ||||||
|  |       allow write: if true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     match /playground/{document=**} { | ||||||
|  |       allow read, write: if true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     match /react-native-firebase-testing/{document=**} { | ||||||
|  |       allow read, write: if true; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										
											BIN
										
									
								
								Example/testHotUpdate/cache/test-butler-app.apk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Example/testHotUpdate/cache/test-butler-app.apk
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										111
									
								
								Example/testHotUpdate/detox.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								Example/testHotUpdate/detox.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | /** @type {Detox.DetoxConfig} */ | ||||||
|  | module.exports = { | ||||||
|  |   logger: { | ||||||
|  |     level: process.env.CI ? 'debug' : undefined, | ||||||
|  |   }, | ||||||
|  |   testRunner: { | ||||||
|  |     args: { | ||||||
|  |       config: 'e2e/jest.config.js', | ||||||
|  |       maxWorkers: process.env.CI ? 2 : undefined, | ||||||
|  |       _: ['e2e'], | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   artifacts: { | ||||||
|  |     plugins: { | ||||||
|  |       log: process.env.CI ? 'failing' : undefined, | ||||||
|  |       screenshot: process.env.CI ? 'failing' : undefined, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   apps: { | ||||||
|  |     'ios.release': { | ||||||
|  |       type: 'ios.app', | ||||||
|  |       binaryPath: | ||||||
|  |         'ios/build/Build/Products/Release-iphonesimulator/testHotUpdate.app', | ||||||
|  |       build: | ||||||
|  |         'export RCT_NO_LAUNCH_PACKAGER=true && xcodebuild -workspace ios/testHotUpdate.xcworkspace -UseNewBuildSystem=NO -scheme testHotUpdate -configuration Release -sdk iphonesimulator -derivedDataPath ios/build -quiet', | ||||||
|  |     }, | ||||||
|  |     'ios.debug': { | ||||||
|  |       type: 'ios.app', | ||||||
|  |       binaryPath: | ||||||
|  |         'ios/build/Build/Products/Debug-iphonesimulator/testHotUpdate.app', | ||||||
|  |       build: | ||||||
|  |         'xcodebuild -workspace ios/testHotUpdate.xcworkspace -UseNewBuildSystem=NO -scheme testHotUpdate -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', | ||||||
|  |       start: 'scripts/start-rn.sh ios', | ||||||
|  |     }, | ||||||
|  |     'android.debug': { | ||||||
|  |       type: 'android.apk', | ||||||
|  |       binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk', | ||||||
|  |       build: | ||||||
|  |         'cd android ; ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -', | ||||||
|  |       start: 'scripts/start-rn.sh android', | ||||||
|  |     }, | ||||||
|  |     'android.release': { | ||||||
|  |       type: 'android.apk', | ||||||
|  |       binaryPath: 'android/app/build/outputs/apk/release/app-release.apk', | ||||||
|  |       build: | ||||||
|  |         'cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -', | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   devices: { | ||||||
|  |     simulator: { | ||||||
|  |       type: 'ios.simulator', | ||||||
|  |       headless: Boolean(process.env.CI), | ||||||
|  |       device: { | ||||||
|  |         type: 'iPhone 14', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     emulator: { | ||||||
|  |       type: 'android.emulator', | ||||||
|  |       headless: Boolean(process.env.CI), | ||||||
|  |       gpuMode: process.env.CI ? 'off' : undefined, | ||||||
|  |       device: { | ||||||
|  |         avdName: 'Pixel_3a_API_33_arm64-v8a', | ||||||
|  |       }, | ||||||
|  |       utilBinaryPaths: ['./cache/test-butler-app.apk'], | ||||||
|  |     }, | ||||||
|  |     'genymotion.emulator.uuid': { | ||||||
|  |       type: 'android.genycloud', | ||||||
|  |       device: { | ||||||
|  |         recipeUUID: 'a50a71d6-da90-4c67-bdfa-5b602b0bbd15', | ||||||
|  |       }, | ||||||
|  |       utilBinaryPaths: ['./cache/test-butler-app.apk'], | ||||||
|  |     }, | ||||||
|  |     'genymotion.emulator.name': { | ||||||
|  |       type: 'android.genycloud', | ||||||
|  |       device: { | ||||||
|  |         recipeName: 'Pixel_3a_API_33_arm64-v8a', | ||||||
|  |       }, | ||||||
|  |       utilBinaryPaths: ['./cache/test-butler-app.apk'], | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  |   configurations: { | ||||||
|  |     'ios.sim.release': { | ||||||
|  |       device: 'simulator', | ||||||
|  |       app: 'ios.release', | ||||||
|  |     }, | ||||||
|  |     'ios.sim.debug': { | ||||||
|  |       device: 'simulator', | ||||||
|  |       app: 'ios.debug', | ||||||
|  |     }, | ||||||
|  |     'ios.manual': { | ||||||
|  |       type: 'ios.manual', | ||||||
|  |       behavior: { | ||||||
|  |         launchApp: 'manual', | ||||||
|  |       }, | ||||||
|  |       artifacts: false, | ||||||
|  |       session: { | ||||||
|  |         autoStart: true, | ||||||
|  |         server: 'ws://localhost:8099', | ||||||
|  |         sessionId: 'com.wix.demo.react.native', | ||||||
|  |       }, | ||||||
|  |     }, | ||||||
|  |     'android.emu.debug': { | ||||||
|  |       device: 'emulator', | ||||||
|  |       app: 'android.debug', | ||||||
|  |     }, | ||||||
|  |     'android.emu.release': { | ||||||
|  |       device: 'emulator', | ||||||
|  |       app: 'android.release', | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | }; | ||||||
							
								
								
									
										89
									
								
								Example/testHotUpdate/e2e/NativeModule.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								Example/testHotUpdate/e2e/NativeModule.test.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,89 @@ | |||||||
|  | import {by, device, element, expect} from 'detox'; | ||||||
|  |  | ||||||
|  | describe('测试Native模块的方法', () => { | ||||||
|  |   beforeAll(async () => { | ||||||
|  |     await device.launchApp(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setLocalHashInfo', async () => { | ||||||
|  |     await element(by.id('testcase')).longPress(); | ||||||
|  |     await element(by.id('setLocalHashInfo')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('getLocalHashInfo', async () => { | ||||||
|  |     await element(by.id('getLocalHashInfo')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setUuid', async () => { | ||||||
|  |     await element(by.id('setUuid')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setBlockUpdate', async () => { | ||||||
|  |     await element(by.id('setBlockUpdate')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('reloadUpdate', async () => { | ||||||
|  |     await element(by.id('reloadUpdate')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('刚刚更新失败了,版本被回滚.'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('setNeedUpdate', async () => { | ||||||
|  |     await element(by.id('testcase')).longPress(); | ||||||
|  |     await element(by.id('setNeedUpdate')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('markSuccess', async () => { | ||||||
|  |     await element(by.id('markSuccess')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('done'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('downloadPatchFromPpk', async () => { | ||||||
|  |     await element(by.id('downloadPatchFromPpk')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('failed to open zip file'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('downloadPatchFromPackage', async () => { | ||||||
|  |     await element(by.id('downloadPatchFromPackage')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('failed to open zip file'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   it('downloadFullUpdate', async () => { | ||||||
|  |     await element(by.id('downloadFullUpdate')).tap(); | ||||||
|  |     await element(by.id('submit')).tap(); | ||||||
|  |     await expect(element(by.text('failed to open zip file'))).toBeVisible(); | ||||||
|  |     await element(by.text('OK')).tap(); | ||||||
|  |   }); | ||||||
|  |  | ||||||
|  |   if (device.getPlatform() === 'android') { | ||||||
|  |     it('downloadAndInstallApk', async () => { | ||||||
|  |       await element(by.id('testcase')).longPress(); | ||||||
|  |       await element(by.id('downloadAndInstallApk')).tap(); | ||||||
|  |       await element(by.id('submit')).tap(); | ||||||
|  |       await expect(element(by.text('failed to open zip file'))).toBeVisible(); | ||||||
|  |       await element(by.text('OK')).tap(); | ||||||
|  |     }); | ||||||
|  |   } | ||||||
|  | }); | ||||||
							
								
								
									
										29
									
								
								Example/testHotUpdate/e2e/globalSetup.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								Example/testHotUpdate/e2e/globalSetup.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | |||||||
|  | import { execSync } from 'child_process'; | ||||||
|  |  | ||||||
|  | import { pathExists, ensureDir } from 'fs-extra'; | ||||||
|  |  | ||||||
|  | import { resolveConfig } from 'detox/internals'; | ||||||
|  | import { globalSetup } from 'detox/runners/jest'; | ||||||
|  |  | ||||||
|  | export default async function customGlobalSetup() { | ||||||
|  |   const config = await resolveConfig(); | ||||||
|  |   if (config.device.type === 'android.emulator') { | ||||||
|  |     await downloadTestButlerAPK(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   await globalSetup(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | async function downloadTestButlerAPK() { | ||||||
|  |   const version = '2.2.1'; | ||||||
|  |   const artifactUrl = `https://repo1.maven.org/maven2/com/linkedin/testbutler/test-butler-app/${version}/test-butler-app-${version}.apk`; | ||||||
|  |   const filePath = `cache/test-butler-app.apk`; | ||||||
|  |  | ||||||
|  |   await ensureDir('cache'); | ||||||
|  |   if (!(await pathExists(filePath))) { | ||||||
|  |     console.log(`\nDownloading Test-Butler APK v${version}...`); | ||||||
|  |     execSync(`curl -f -o ${filePath} ${artifactUrl}`); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | module.exports = customGlobalSetup; | ||||||
							
								
								
									
										16
									
								
								Example/testHotUpdate/e2e/jest.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								Example/testHotUpdate/e2e/jest.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | |||||||
|  | /** @type {import('jest').Config} */ | ||||||
|  | module.exports = { | ||||||
|  |   maxWorkers: 1, | ||||||
|  |   globalSetup: './globalSetup.ts', | ||||||
|  |   globalTeardown: 'detox/runners/jest/globalTeardown', | ||||||
|  |   testEnvironment: 'detox/runners/jest/testEnvironment', | ||||||
|  |   setupFilesAfterEnv: ['./setup.ts'], | ||||||
|  |   testRunner: 'jest-circus/runner', | ||||||
|  |   testTimeout: 120000, | ||||||
|  |   testMatch: ['**/*.test.ts'], | ||||||
|  |   transform: { | ||||||
|  |     '\\.tsx?$': 'ts-jest', | ||||||
|  |   }, | ||||||
|  |   reporters: ['detox/runners/jest/reporter'], | ||||||
|  |   verbose: true, | ||||||
|  | }; | ||||||
							
								
								
									
										5
									
								
								Example/testHotUpdate/e2e/setup.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								Example/testHotUpdate/e2e/setup.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | |||||||
|  | import { device } from 'detox'; | ||||||
|  |  | ||||||
|  | beforeAll(async () => { | ||||||
|  |   await device.launchApp(); | ||||||
|  | }); | ||||||
| @@ -89,11 +89,6 @@ PODS: | |||||||
|     - DoubleConversion |     - DoubleConversion | ||||||
|     - fmt (~> 6.2.1) |     - fmt (~> 6.2.1) | ||||||
|     - glog |     - glog | ||||||
|   - RCT-Folly/Fabric (2021.07.22.00): |  | ||||||
|     - boost |  | ||||||
|     - DoubleConversion |  | ||||||
|     - fmt (~> 6.2.1) |  | ||||||
|     - glog |  | ||||||
|   - RCT-Folly/Futures (2021.07.22.00): |   - RCT-Folly/Futures (2021.07.22.00): | ||||||
|     - boost |     - boost | ||||||
|     - DoubleConversion |     - DoubleConversion | ||||||
| @@ -126,10 +121,8 @@ PODS: | |||||||
|     - RCTRequired |     - RCTRequired | ||||||
|     - RCTTypeSafety |     - RCTTypeSafety | ||||||
|     - React-Core |     - React-Core | ||||||
|     - React-graphics |  | ||||||
|     - React-jsi |     - React-jsi | ||||||
|     - React-jsiexecutor |     - React-jsiexecutor | ||||||
|     - React-rncore |  | ||||||
|     - ReactCommon/turbomodule/bridging |     - ReactCommon/turbomodule/bridging | ||||||
|     - ReactCommon/turbomodule/core |     - ReactCommon/turbomodule/core | ||||||
|   - React-Core (0.71.1): |   - React-Core (0.71.1): | ||||||
| @@ -278,326 +271,6 @@ PODS: | |||||||
|     - React-logger (= 0.71.1) |     - React-logger (= 0.71.1) | ||||||
|     - React-perflogger (= 0.71.1) |     - React-perflogger (= 0.71.1) | ||||||
|     - React-runtimeexecutor (= 0.71.1) |     - React-runtimeexecutor (= 0.71.1) | ||||||
|   - React-Fabric (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-Fabric/animations (= 0.71.1) |  | ||||||
|     - React-Fabric/attributedstring (= 0.71.1) |  | ||||||
|     - React-Fabric/butter (= 0.71.1) |  | ||||||
|     - React-Fabric/componentregistry (= 0.71.1) |  | ||||||
|     - React-Fabric/componentregistrynative (= 0.71.1) |  | ||||||
|     - React-Fabric/components (= 0.71.1) |  | ||||||
|     - React-Fabric/config (= 0.71.1) |  | ||||||
|     - React-Fabric/core (= 0.71.1) |  | ||||||
|     - React-Fabric/debug_core (= 0.71.1) |  | ||||||
|     - React-Fabric/debug_renderer (= 0.71.1) |  | ||||||
|     - React-Fabric/imagemanager (= 0.71.1) |  | ||||||
|     - React-Fabric/leakchecker (= 0.71.1) |  | ||||||
|     - React-Fabric/mapbuffer (= 0.71.1) |  | ||||||
|     - React-Fabric/mounting (= 0.71.1) |  | ||||||
|     - React-Fabric/runtimescheduler (= 0.71.1) |  | ||||||
|     - React-Fabric/scheduler (= 0.71.1) |  | ||||||
|     - React-Fabric/telemetry (= 0.71.1) |  | ||||||
|     - React-Fabric/templateprocessor (= 0.71.1) |  | ||||||
|     - React-Fabric/textlayoutmanager (= 0.71.1) |  | ||||||
|     - React-Fabric/uimanager (= 0.71.1) |  | ||||||
|     - React-Fabric/utils (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/animations (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/attributedstring (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/butter (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/componentregistry (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/componentregistrynative (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-Fabric/components/activityindicator (= 0.71.1) |  | ||||||
|     - React-Fabric/components/image (= 0.71.1) |  | ||||||
|     - React-Fabric/components/inputaccessory (= 0.71.1) |  | ||||||
|     - React-Fabric/components/legacyviewmanagerinterop (= 0.71.1) |  | ||||||
|     - React-Fabric/components/modal (= 0.71.1) |  | ||||||
|     - React-Fabric/components/root (= 0.71.1) |  | ||||||
|     - React-Fabric/components/safeareaview (= 0.71.1) |  | ||||||
|     - React-Fabric/components/scrollview (= 0.71.1) |  | ||||||
|     - React-Fabric/components/slider (= 0.71.1) |  | ||||||
|     - React-Fabric/components/text (= 0.71.1) |  | ||||||
|     - React-Fabric/components/textinput (= 0.71.1) |  | ||||||
|     - React-Fabric/components/unimplementedview (= 0.71.1) |  | ||||||
|     - React-Fabric/components/view (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/activityindicator (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/image (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/inputaccessory (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/legacyviewmanagerinterop (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/modal (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/root (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/safeareaview (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/scrollview (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/slider (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/text (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/textinput (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/unimplementedview (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/components/view (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|     - Yoga |  | ||||||
|   - React-Fabric/config (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/core (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/debug_core (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/debug_renderer (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/imagemanager (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - React-RCTImage (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/leakchecker (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/mapbuffer (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/mounting (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/runtimescheduler (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/scheduler (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/telemetry (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/templateprocessor (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/textlayoutmanager (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-Fabric/uimanager |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/uimanager (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-Fabric/utils (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - RCTRequired (= 0.71.1) |  | ||||||
|     - RCTTypeSafety (= 0.71.1) |  | ||||||
|     - React-graphics (= 0.71.1) |  | ||||||
|     - React-jsi (= 0.71.1) |  | ||||||
|     - React-jsiexecutor (= 0.71.1) |  | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |  | ||||||
|   - React-graphics (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - React-Core/Default (= 0.71.1) |  | ||||||
|   - React-hermes (0.71.1): |   - React-hermes (0.71.1): | ||||||
|     - DoubleConversion |     - DoubleConversion | ||||||
|     - glog |     - glog | ||||||
| @@ -624,34 +297,19 @@ PODS: | |||||||
|   - React-jsinspector (0.71.1) |   - React-jsinspector (0.71.1) | ||||||
|   - React-logger (0.71.1): |   - React-logger (0.71.1): | ||||||
|     - glog |     - glog | ||||||
|   - react-native-update (9.1.0): |   - react-native-update (9.0.0): | ||||||
|     - RCT-Folly (= 2021.07.22.00) |  | ||||||
|     - RCTRequired |  | ||||||
|     - RCTTypeSafety |  | ||||||
|     - React |     - React | ||||||
|     - React-Codegen |  | ||||||
|     - React-Core |     - React-Core | ||||||
|     - react-native-update/HDiffPatch (= 9.1.0) |     - react-native-update/HDiffPatch (= 9.0.0) | ||||||
|     - react-native-update/RCTPushy (= 9.1.0) |     - react-native-update/RCTPushy (= 9.0.0) | ||||||
|     - ReactCommon/turbomodule/core |  | ||||||
|     - SSZipArchive |     - SSZipArchive | ||||||
|   - react-native-update/HDiffPatch (9.1.0): |   - react-native-update/HDiffPatch (9.0.0): | ||||||
|     - RCT-Folly (= 2021.07.22.00) |  | ||||||
|     - RCTRequired |  | ||||||
|     - RCTTypeSafety |  | ||||||
|     - React |     - React | ||||||
|     - React-Codegen |  | ||||||
|     - React-Core |     - React-Core | ||||||
|     - ReactCommon/turbomodule/core |  | ||||||
|     - SSZipArchive |     - SSZipArchive | ||||||
|   - react-native-update/RCTPushy (9.1.0): |   - react-native-update/RCTPushy (9.0.0): | ||||||
|     - RCT-Folly (= 2021.07.22.00) |  | ||||||
|     - RCTRequired |  | ||||||
|     - RCTTypeSafety |  | ||||||
|     - React |     - React | ||||||
|     - React-Codegen |  | ||||||
|     - React-Core |     - React-Core | ||||||
|     - ReactCommon/turbomodule/core |  | ||||||
|     - SSZipArchive |     - SSZipArchive | ||||||
|   - React-perflogger (0.71.1) |   - React-perflogger (0.71.1) | ||||||
|   - React-RCTActionSheet (0.71.1): |   - React-RCTActionSheet (0.71.1): | ||||||
| @@ -668,8 +326,6 @@ PODS: | |||||||
|     - RCTRequired |     - RCTRequired | ||||||
|     - RCTTypeSafety |     - RCTTypeSafety | ||||||
|     - React-Core |     - React-Core | ||||||
|     - React-graphics |  | ||||||
|     - React-RCTFabric |  | ||||||
|     - ReactCommon/turbomodule/core |     - ReactCommon/turbomodule/core | ||||||
|   - React-RCTBlob (0.71.1): |   - React-RCTBlob (0.71.1): | ||||||
|     - RCT-Folly (= 2021.07.22.00) |     - RCT-Folly (= 2021.07.22.00) | ||||||
| @@ -679,11 +335,6 @@ PODS: | |||||||
|     - React-jsi (= 0.71.1) |     - React-jsi (= 0.71.1) | ||||||
|     - React-RCTNetwork (= 0.71.1) |     - React-RCTNetwork (= 0.71.1) | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |     - ReactCommon/turbomodule/core (= 0.71.1) | ||||||
|   - React-RCTFabric (0.71.1): |  | ||||||
|     - RCT-Folly/Fabric (= 2021.07.22.00) |  | ||||||
|     - React-Core (= 0.71.1) |  | ||||||
|     - React-Fabric (= 0.71.1) |  | ||||||
|     - React-RCTImage (= 0.71.1) |  | ||||||
|   - React-RCTImage (0.71.1): |   - React-RCTImage (0.71.1): | ||||||
|     - RCT-Folly (= 2021.07.22.00) |     - RCT-Folly (= 2021.07.22.00) | ||||||
|     - RCTTypeSafety (= 0.71.1) |     - RCTTypeSafety (= 0.71.1) | ||||||
| @@ -719,7 +370,6 @@ PODS: | |||||||
|     - React-Core/RCTVibrationHeaders (= 0.71.1) |     - React-Core/RCTVibrationHeaders (= 0.71.1) | ||||||
|     - React-jsi (= 0.71.1) |     - React-jsi (= 0.71.1) | ||||||
|     - ReactCommon/turbomodule/core (= 0.71.1) |     - ReactCommon/turbomodule/core (= 0.71.1) | ||||||
|   - React-rncore (0.71.1) |  | ||||||
|   - React-runtimeexecutor (0.71.1): |   - React-runtimeexecutor (0.71.1): | ||||||
|     - React-jsi (= 0.71.1) |     - React-jsi (= 0.71.1) | ||||||
|   - ReactCommon/turbomodule/bridging (0.71.1): |   - ReactCommon/turbomodule/bridging (0.71.1): | ||||||
| @@ -779,7 +429,6 @@ DEPENDENCIES: | |||||||
|   - libevent (~> 2.1.12) |   - libevent (~> 2.1.12) | ||||||
|   - OpenSSL-Universal (= 1.1.1100) |   - OpenSSL-Universal (= 1.1.1100) | ||||||
|   - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) |   - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) | ||||||
|   - RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) |  | ||||||
|   - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) |   - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) | ||||||
|   - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) |   - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) | ||||||
|   - React (from `../node_modules/react-native/`) |   - React (from `../node_modules/react-native/`) | ||||||
| @@ -790,8 +439,6 @@ DEPENDENCIES: | |||||||
|   - React-Core/RCTWebSocket (from `../node_modules/react-native/`) |   - React-Core/RCTWebSocket (from `../node_modules/react-native/`) | ||||||
|   - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) |   - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) | ||||||
|   - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) |   - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) | ||||||
|   - React-Fabric (from `../node_modules/react-native/ReactCommon`) |  | ||||||
|   - React-graphics (from `../node_modules/react-native/ReactCommon/react/renderer/graphics`) |  | ||||||
|   - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) |   - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) | ||||||
|   - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) |   - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) | ||||||
|   - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) |   - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) | ||||||
| @@ -803,14 +450,12 @@ DEPENDENCIES: | |||||||
|   - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) |   - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) | ||||||
|   - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) |   - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) | ||||||
|   - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) |   - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) | ||||||
|   - React-RCTFabric (from `../node_modules/react-native/React`) |  | ||||||
|   - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) |   - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) | ||||||
|   - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) |   - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) | ||||||
|   - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) |   - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) | ||||||
|   - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) |   - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) | ||||||
|   - React-RCTText (from `../node_modules/react-native/Libraries/Text`) |   - React-RCTText (from `../node_modules/react-native/Libraries/Text`) | ||||||
|   - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) |   - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) | ||||||
|   - React-rncore (from `../node_modules/react-native/ReactCommon`) |  | ||||||
|   - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) |   - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) | ||||||
|   - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) |   - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) | ||||||
|   - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) |   - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) | ||||||
| @@ -865,10 +510,6 @@ EXTERNAL SOURCES: | |||||||
|     :path: "../node_modules/react-native/React/CoreModules" |     :path: "../node_modules/react-native/React/CoreModules" | ||||||
|   React-cxxreact: |   React-cxxreact: | ||||||
|     :path: "../node_modules/react-native/ReactCommon/cxxreact" |     :path: "../node_modules/react-native/ReactCommon/cxxreact" | ||||||
|   React-Fabric: |  | ||||||
|     :path: "../node_modules/react-native/ReactCommon" |  | ||||||
|   React-graphics: |  | ||||||
|     :path: "../node_modules/react-native/ReactCommon/react/renderer/graphics" |  | ||||||
|   React-hermes: |   React-hermes: | ||||||
|     :path: "../node_modules/react-native/ReactCommon/hermes" |     :path: "../node_modules/react-native/ReactCommon/hermes" | ||||||
|   React-jsi: |   React-jsi: | ||||||
| @@ -891,8 +532,6 @@ EXTERNAL SOURCES: | |||||||
|     :path: "../node_modules/react-native/Libraries/AppDelegate" |     :path: "../node_modules/react-native/Libraries/AppDelegate" | ||||||
|   React-RCTBlob: |   React-RCTBlob: | ||||||
|     :path: "../node_modules/react-native/Libraries/Blob" |     :path: "../node_modules/react-native/Libraries/Blob" | ||||||
|   React-RCTFabric: |  | ||||||
|     :path: "../node_modules/react-native/React" |  | ||||||
|   React-RCTImage: |   React-RCTImage: | ||||||
|     :path: "../node_modules/react-native/Libraries/Image" |     :path: "../node_modules/react-native/Libraries/Image" | ||||||
|   React-RCTLinking: |   React-RCTLinking: | ||||||
| @@ -905,8 +544,6 @@ EXTERNAL SOURCES: | |||||||
|     :path: "../node_modules/react-native/Libraries/Text" |     :path: "../node_modules/react-native/Libraries/Text" | ||||||
|   React-RCTVibration: |   React-RCTVibration: | ||||||
|     :path: "../node_modules/react-native/Libraries/Vibration" |     :path: "../node_modules/react-native/Libraries/Vibration" | ||||||
|   React-rncore: |  | ||||||
|     :path: "../node_modules/react-native/ReactCommon" |  | ||||||
|   React-runtimeexecutor: |   React-runtimeexecutor: | ||||||
|     :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" |     :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" | ||||||
|   ReactCommon: |   ReactCommon: | ||||||
| @@ -919,7 +556,7 @@ SPEC CHECKSUMS: | |||||||
|   CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 |   CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 | ||||||
|   DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 |   DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 | ||||||
|   FBLazyVector: ad72713385db5289b19f1ead07e8e4aa26dcb01d |   FBLazyVector: ad72713385db5289b19f1ead07e8e4aa26dcb01d | ||||||
|   FBReactNativeSpec: 06fc2a521838dc240b499699d43467b071c66908 |   FBReactNativeSpec: df2602c11e33d310433496e28a48b4b2be652a61 | ||||||
|   Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 |   Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0 | ||||||
|   Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c |   Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c | ||||||
|   Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 |   Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 | ||||||
| @@ -939,31 +576,27 @@ SPEC CHECKSUMS: | |||||||
|   RCTTypeSafety: c276d85975bde3d8448907235c70bf0da257adfd |   RCTTypeSafety: c276d85975bde3d8448907235c70bf0da257adfd | ||||||
|   React: e481a67971af1ce9639c9f746b753dd0e84ca108 |   React: e481a67971af1ce9639c9f746b753dd0e84ca108 | ||||||
|   React-callinvoker: 1051c04a94fa9d243786b86380606bad701a3b31 |   React-callinvoker: 1051c04a94fa9d243786b86380606bad701a3b31 | ||||||
|   React-Codegen: d4bc58865453b6a797405aa99f9fa1da3c9e58c6 |   React-Codegen: 14b1e716d361d5ad95e0ce1a338f3fa0733a98b5 | ||||||
|   React-Core: 698fc3baecb80d511d987475a16d036cec6d287f |   React-Core: 698fc3baecb80d511d987475a16d036cec6d287f | ||||||
|   React-CoreModules: 59245305f41ff0adfeac334acc0594dea4585a7c |   React-CoreModules: 59245305f41ff0adfeac334acc0594dea4585a7c | ||||||
|   React-cxxreact: 49accd2954b0f532805dbcd1918fa6962f32f247 |   React-cxxreact: 49accd2954b0f532805dbcd1918fa6962f32f247 | ||||||
|   React-Fabric: 30982dc19c7511bedf1751b0a0c21a5b816e2a3e |  | ||||||
|   React-graphics: beabc29b026e7472ced1482557effedd15a09cf1 |  | ||||||
|   React-hermes: d068733294581a085e95b6024e8d951b005e26d3 |   React-hermes: d068733294581a085e95b6024e8d951b005e26d3 | ||||||
|   React-jsi: 122b9bce14f4c6c7cb58f28f87912cfe091885fa |   React-jsi: 122b9bce14f4c6c7cb58f28f87912cfe091885fa | ||||||
|   React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa |   React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa | ||||||
|   React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07 |   React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07 | ||||||
|   React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75 |   React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75 | ||||||
|   react-native-update: b9d44d250953e61f1b42c22fa4d585a6bb5dd4d6 |   react-native-update: 2b5ef06bfeaa668614c8deb7ec4d20dcf56f9278 | ||||||
|   React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85 |   React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85 | ||||||
|   React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de |   React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de | ||||||
|   React-RCTAnimation: 168d53718c74153947c0109f55900faa64d79439 |   React-RCTAnimation: 168d53718c74153947c0109f55900faa64d79439 | ||||||
|   React-RCTAppDelegate: 5f34addd2f9d8c542c129b562b7f3db0cc599a3d |   React-RCTAppDelegate: a8efbab128b34aa07a9491c85a41401210b1bec5 | ||||||
|   React-RCTBlob: 9bcbfc893bfda9f6b2eb016329d38c0f6366d31a |   React-RCTBlob: 9bcbfc893bfda9f6b2eb016329d38c0f6366d31a | ||||||
|   React-RCTFabric: cec4e89720e8778aa132e5515be1af251d2e9b6a |  | ||||||
|   React-RCTImage: 3fcd4570b4b0f1ac2f4b4b6308dba33ce66c5b50 |   React-RCTImage: 3fcd4570b4b0f1ac2f4b4b6308dba33ce66c5b50 | ||||||
|   React-RCTLinking: 1edb8e1bb3fc39bf9e13c63d6aaaa3f0c3d18683 |   React-RCTLinking: 1edb8e1bb3fc39bf9e13c63d6aaaa3f0c3d18683 | ||||||
|   React-RCTNetwork: 500a79e0e0f67678077df727fabba87a55c043e1 |   React-RCTNetwork: 500a79e0e0f67678077df727fabba87a55c043e1 | ||||||
|   React-RCTSettings: cc4414eb84ad756d619076c3999fecbf12896d6f |   React-RCTSettings: cc4414eb84ad756d619076c3999fecbf12896d6f | ||||||
|   React-RCTText: 2a34261f3da6e34f47a62154def657546ebfa5e1 |   React-RCTText: 2a34261f3da6e34f47a62154def657546ebfa5e1 | ||||||
|   React-RCTVibration: 49d531ec8498e0afa2c9b22c2205784372e3d4f3 |   React-RCTVibration: 49d531ec8498e0afa2c9b22c2205784372e3d4f3 | ||||||
|   React-rncore: b802bc9f6985c482127b066c869999a09d25edeb |  | ||||||
|   React-runtimeexecutor: 311feb67600774723fe10eb8801d3138cae9ad67 |   React-runtimeexecutor: 311feb67600774723fe10eb8801d3138cae9ad67 | ||||||
|   ReactCommon: 03be76588338a27a88d103b35c3c44a3fd43d136 |   ReactCommon: 03be76588338a27a88d103b35c3c44a3fd43d136 | ||||||
|   SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 |   SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608 | ||||||
|   | |||||||
| @@ -211,7 +211,7 @@ | |||||||
| 					}; | 					}; | ||||||
| 				}; | 				}; | ||||||
| 			}; | 			}; | ||||||
| 			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */; | 			buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotUpdate" */; | ||||||
| 			compatibilityVersion = "Xcode 12.0"; | 			compatibilityVersion = "Xcode 12.0"; | ||||||
| 			developmentRegion = en; | 			developmentRegion = en; | ||||||
| 			hasScannedForEncodings = 0; | 			hasScannedForEncodings = 0; | ||||||
| @@ -689,7 +689,7 @@ | |||||||
| 			defaultConfigurationIsVisible = 0; | 			defaultConfigurationIsVisible = 0; | ||||||
| 			defaultConfigurationName = Release; | 			defaultConfigurationName = Release; | ||||||
| 		}; | 		}; | ||||||
| 		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotupdate" */ = { | 		83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "testHotUpdate" */ = { | ||||||
| 			isa = XCConfigurationList; | 			isa = XCConfigurationList; | ||||||
| 			buildConfigurations = ( | 			buildConfigurations = ( | ||||||
| 				83CBBA201A601CBA00E9B192 /* Debug */, | 				83CBBA201A601CBA00E9B192 /* Debug */, | ||||||
|   | |||||||
| @@ -7,4 +7,7 @@ | |||||||
|    <FileRef |    <FileRef | ||||||
|       location = "group:Pods/Pods.xcodeproj"> |       location = "group:Pods/Pods.xcodeproj"> | ||||||
|    </FileRef> |    </FileRef> | ||||||
|  |    <FileRef | ||||||
|  |       location = "group:testHotUpdate.xcodeproj"> | ||||||
|  |    </FileRef> | ||||||
| </Workspace> | </Workspace> | ||||||
|   | |||||||
| @@ -24,17 +24,6 @@ | |||||||
| 	<string>$(CURRENT_PROJECT_VERSION)</string> | 	<string>$(CURRENT_PROJECT_VERSION)</string> | ||||||
| 	<key>LSRequiresIPhoneOS</key> | 	<key>LSRequiresIPhoneOS</key> | ||||||
| 	<true/> | 	<true/> | ||||||
| 	<key>NSAppTransportSecurity</key> |  | ||||||
| 	<dict> |  | ||||||
| 		<key>NSExceptionDomains</key> |  | ||||||
| 		<dict> |  | ||||||
| 			<key>localhost</key> |  | ||||||
| 			<dict> |  | ||||||
| 				<key>NSExceptionAllowsInsecureHTTPLoads</key> |  | ||||||
| 				<true/> |  | ||||||
| 			</dict> |  | ||||||
| 		</dict> |  | ||||||
| 	</dict> |  | ||||||
| 	<key>NSLocationWhenInUseUsageDescription</key> | 	<key>NSLocationWhenInUseUsageDescription</key> | ||||||
| 	<string></string> | 	<string></string> | ||||||
| 	<key>UILaunchStoryboardName</key> | 	<key>UILaunchStoryboardName</key> | ||||||
| @@ -51,5 +40,18 @@ | |||||||
| 	</array> | 	</array> | ||||||
| 	<key>UIViewControllerBasedStatusBarAppearance</key> | 	<key>UIViewControllerBasedStatusBarAppearance</key> | ||||||
| 	<false/> | 	<false/> | ||||||
|  | 	<key>NSAppTransportSecurity</key> | ||||||
|  | 	<dict> | ||||||
|  | 		<key>NSAllowsArbitraryLoads</key> | ||||||
|  | 		<true/> | ||||||
|  | 		<key>NSExceptionDomains</key> | ||||||
|  | 		<dict> | ||||||
|  | 			<key>localhost</key> | ||||||
|  | 			<dict> | ||||||
|  | 				<key>NSExceptionAllowsInsecureHTTPLoads</key> | ||||||
|  | 				<true/> | ||||||
|  | 			</dict> | ||||||
|  | 		</dict> | ||||||
|  | 	</dict> | ||||||
| </dict> | </dict> | ||||||
| </plist> | </plist> | ||||||
|   | |||||||
| @@ -25,11 +25,15 @@ | |||||||
|     "@types/react": "^18.0.24", |     "@types/react": "^18.0.24", | ||||||
|     "@types/react-test-renderer": "^18.0.0", |     "@types/react-test-renderer": "^18.0.0", | ||||||
|     "babel-jest": "^29.2.1", |     "babel-jest": "^29.2.1", | ||||||
|  |     "detox": "^20.5.0", | ||||||
|     "eslint": "^8.19.0", |     "eslint": "^8.19.0", | ||||||
|  |     "fs-extra": "^11.1.0", | ||||||
|     "jest": "^29.2.1", |     "jest": "^29.2.1", | ||||||
|     "metro-react-native-babel-preset": "0.73.7", |     "metro-react-native-babel-preset": "0.73.7", | ||||||
|     "prettier": "^2.4.1", |     "prettier": "^2.4.1", | ||||||
|     "react-test-renderer": "18.2.0" |     "react-test-renderer": "18.2.0", | ||||||
|  |     "ts-jest": "^29.0.5", | ||||||
|  |     "typescript": "^4.9.5" | ||||||
|   }, |   }, | ||||||
|   "jest": { |   "jest": { | ||||||
|     "preset": "react-native" |     "preset": "react-native" | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* eslint-disable react-native/no-inline-styles */ | /* eslint-disable react-native/no-inline-styles */ | ||||||
| /* eslint-disable react/react-in-jsx-scope */ | /* eslint-disable react/react-in-jsx-scope */ | ||||||
| import {useState} from 'react'; | import {useCallback, useMemo, useState} from 'react'; | ||||||
| import { | import { | ||||||
|   ActivityIndicator, |   ActivityIndicator, | ||||||
|   Alert, |   Alert, | ||||||
| @@ -10,14 +10,117 @@ import { | |||||||
|   StyleSheet, |   StyleSheet, | ||||||
|   SafeAreaView, |   SafeAreaView, | ||||||
|   Text, |   Text, | ||||||
|  |   ScrollView, | ||||||
|   View, |   View, | ||||||
|  |   TouchableOpacity, | ||||||
| } from 'react-native'; | } from 'react-native'; | ||||||
|  |  | ||||||
| import {PushyModule} from 'react-native-update'; | import {PushyModule} from 'react-native-update'; | ||||||
|  | const Hash = '9D5CE6EBA420717BE7E7D308B11F8207681B066C951D68F3994D19828F342474'; | ||||||
|  | const UUID = '00000000-0000-0000-0000-000000000000'; | ||||||
|  | const DownloadUrl = | ||||||
|  |   'http://cos.pgyer.com/697913e94d7441f20c686e2b0996a1aa.apk?sign=363b035b7ef52c199c268abfacee3712&t=1678603669&response-content-disposition=attachment%3Bfilename%3DtestHotupdate_1.0.apk'; | ||||||
| export default function TestConsole({visible}) { | export default function TestConsole({visible}) { | ||||||
|   const [text, setText] = useState(''); |   const [text, setText] = useState(''); | ||||||
|   const [running, setRunning] = useState(false); |   const [running, setRunning] = useState(false); | ||||||
|  |   const [options, setOptions] = useState(); | ||||||
|  |   const NativeTestMethod = useMemo(() => { | ||||||
|  |     return [ | ||||||
|  |       { | ||||||
|  |         name: 'setLocalHashInfo', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText( | ||||||
|  |             `setLocalHashInfo\n${Hash}\n{\"version\":\"1.0.0\",\"size\":\"19M\"}`, | ||||||
|  |           ); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'getLocalHashInfo', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText(`getLocalHashInfo\n${Hash}`); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'setUuid', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText(`setUuid\n${UUID}`); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'setBlockUpdate', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('setBlockUpdate'); | ||||||
|  |           setOptions({reason: 'application has been block', until: 1673082950}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'reloadUpdate', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('reloadUpdate'); | ||||||
|  |           setOptions({hash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'setNeedUpdate', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('setNeedUpdate'); | ||||||
|  |           setOptions({hash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'markSuccess', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('markSuccess'); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'downloadPatchFromPpk', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('downloadPatchFromPpk'); | ||||||
|  |           setOptions({updateUrl: DownloadUrl, hash: Hash, originHash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'downloadPatchFromPackage', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('downloadPatchFromPackage'); | ||||||
|  |           setOptions({updateUrl: DownloadUrl, hash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'downloadFullUpdate', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('downloadFullUpdate'); | ||||||
|  |           setOptions({updateUrl: DownloadUrl, hash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |       { | ||||||
|  |         name: 'downloadAndInstallApk', | ||||||
|  |         invoke: () => { | ||||||
|  |           setText('downloadAndInstallApk'); | ||||||
|  |           setOptions({url: DownloadUrl, target: Hash, hash: Hash}); | ||||||
|  |         }, | ||||||
|  |       }, | ||||||
|  |     ]; | ||||||
|  |   }, []); | ||||||
|  |  | ||||||
|  |   const renderTestView = useCallback(() => { | ||||||
|  |     const views = []; | ||||||
|  |     for (let i = 0; i < NativeTestMethod.length; i++) { | ||||||
|  |       views.push( | ||||||
|  |         <TouchableOpacity | ||||||
|  |           key={i} | ||||||
|  |           testID={NativeTestMethod[i].name} | ||||||
|  |           onPress={() => { | ||||||
|  |             NativeTestMethod[i].invoke(); | ||||||
|  |           }} | ||||||
|  |           style={{width: 10, height: 10, backgroundColor: 'red'}} | ||||||
|  |         />, | ||||||
|  |       ); | ||||||
|  |     } | ||||||
|  |     return <View>{views}</View>; | ||||||
|  |   }, [NativeTestMethod]); | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <Modal visible={visible}> |     <Modal visible={visible}> | ||||||
|       <SafeAreaView style={{flex: 1, padding: 10}}> |       <SafeAreaView style={{flex: 1, padding: 10}}> | ||||||
| @@ -42,25 +145,27 @@ export default function TestConsole({visible}) { | |||||||
|         {running && <ActivityIndicator />} |         {running && <ActivityIndicator />} | ||||||
|         <Button |         <Button | ||||||
|           title="执行" |           title="执行" | ||||||
|  |           testID="submit" | ||||||
|           onPress={async () => { |           onPress={async () => { | ||||||
|             setRunning(true); |             setRunning(true); | ||||||
|             try { |             try { | ||||||
|               const inputs = text.split('\n'); |               const inputs = text.split('\n'); | ||||||
|               const methodName = inputs[0]; |               const methodName = inputs[0]; | ||||||
|               let params; |               let params = []; | ||||||
|               if (inputs.length === 1) { |               if (inputs.length === 1) { | ||||||
|  |                 if (options) { | ||||||
|  |                   await PushyModule[methodName](options); | ||||||
|  |                 } else { | ||||||
|                   await PushyModule[methodName](); |                   await PushyModule[methodName](); | ||||||
|  |                 } | ||||||
|               } else { |               } else { | ||||||
|                 if (inputs.length === 2) { |                 if (inputs.length === 2) { | ||||||
|                   params = inputs[1]; |                   params = [inputs[1]]; | ||||||
|                 } else { |                 } else { | ||||||
|                   params = {}; |                   params = [inputs[1], inputs[2]]; | ||||||
|                   for (let i = 1; i < inputs.length; i += 2) { |  | ||||||
|                     params[inputs[i]] = inputs[i + 1]; |  | ||||||
|                   } |  | ||||||
|                   console.log({inputs, params}); |                   console.log({inputs, params}); | ||||||
|                 } |                 } | ||||||
|                 await PushyModule[methodName](params); |                 await PushyModule[methodName](...params); | ||||||
|               } |               } | ||||||
|               Alert.alert('done'); |               Alert.alert('done'); | ||||||
|             } catch (e) { |             } catch (e) { | ||||||
| @@ -69,9 +174,11 @@ export default function TestConsole({visible}) { | |||||||
|             setRunning(false); |             setRunning(false); | ||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|         <View style={{marginTop: 15}}> |         <ScrollView style={{marginTop: 15}}> | ||||||
|           <Button title="重置" onPress={() => setText('')} /> |           <Button title="重置" onPress={() => setText('')} /> | ||||||
|         </View> |  | ||||||
|  |           {renderTestView()} | ||||||
|  |         </ScrollView> | ||||||
|       </SafeAreaView> |       </SafeAreaView> | ||||||
|     </Modal> |     </Modal> | ||||||
|   ); |   ); | ||||||
|   | |||||||
| @@ -170,6 +170,7 @@ export default class App extends Component { | |||||||
|         </TouchableOpacity> |         </TouchableOpacity> | ||||||
|  |  | ||||||
|         <TouchableOpacity |         <TouchableOpacity | ||||||
|  |           testID="testcase" | ||||||
|           style={{marginTop: 15}} |           style={{marginTop: 15}} | ||||||
|           onLongPress={() => { |           onLongPress={() => { | ||||||
|             this.setState({showTestConsole: true}); |             this.setState({showTestConsole: true}); | ||||||
|   | |||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -58,6 +58,7 @@ repositories { | |||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     implementation 'com.facebook.react:react-native:+' |     implementation 'com.facebook.react:react-native:+' | ||||||
|  |     implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.0' | ||||||
| } | } | ||||||
| if (isNewArchitectureEnabled()) { | if (isNewArchitectureEnabled()) { | ||||||
|     react { |     react { | ||||||
|   | |||||||
| @@ -10,8 +10,19 @@ import com.facebook.react.bridge.Promise; | |||||||
| import com.facebook.react.bridge.ReactApplicationContext; | import com.facebook.react.bridge.ReactApplicationContext; | ||||||
| import com.facebook.react.bridge.ReadableMap; | import com.facebook.react.bridge.ReadableMap; | ||||||
| import com.facebook.react.bridge.UiThreadUtil; | import com.facebook.react.bridge.UiThreadUtil; | ||||||
|  | import com.fasterxml.jackson.databind.ObjectMapper; | ||||||
|  |  | ||||||
|  | import org.json.JSONObject; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
|  | import java.io.IOException; | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | import java.util.Optional; | ||||||
|  | import java.util.regex.Matcher; | ||||||
|  | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
| public class UpdateModuleImpl { | public class UpdateModuleImpl { | ||||||
|  |  | ||||||
|     public static final String NAME = "Pushy"; |     public static final String NAME = "Pushy"; | ||||||
| @@ -72,6 +83,7 @@ public class UpdateModuleImpl { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void downloadPatchFromPpk(UpdateContext updateContext, ReadableMap options, Promise promise) { |     public static void downloadPatchFromPpk(UpdateContext updateContext, ReadableMap options, Promise promise) { | ||||||
|  |         try { | ||||||
|             String url = options.getString("updateUrl"); |             String url = options.getString("updateUrl"); | ||||||
|             String hash = options.getString("hash"); |             String hash = options.getString("hash"); | ||||||
|  |  | ||||||
| @@ -88,11 +100,18 @@ public class UpdateModuleImpl { | |||||||
|                     promise.reject(error); |                     promise.reject(error); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |         }catch (Exception e){ | ||||||
|  |             promise.reject("执行报错:"+e.getMessage()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void reloadUpdate(UpdateContext updateContext, ReactApplicationContext mContext, ReadableMap options) { |     public static void reloadUpdate(UpdateContext updateContext, ReactApplicationContext mContext, ReadableMap options,Promise promise) { | ||||||
|         final String hash = options.getString("hash"); |         final String hash = options.getString("hash"); | ||||||
|  |  | ||||||
|  |         if(hash==null || hash.isEmpty()){ | ||||||
|  |             promise.reject("hash不能为空"); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         UiThreadUtil.runOnUiThread(new Runnable() { |         UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
|             @Override |             @Override | ||||||
|             public void run() { |             public void run() { | ||||||
| @@ -112,6 +131,7 @@ public class UpdateModuleImpl { | |||||||
|                         loadField.setAccessible(true); |                         loadField.setAccessible(true); | ||||||
|                         loadField.set(instanceManager, loader); |                         loadField.set(instanceManager, loader); | ||||||
|                     } catch (Throwable err) { |                     } catch (Throwable err) { | ||||||
|  |                         promise.reject("pushy:"+err.getMessage()); | ||||||
|                         Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile"); |                         Field jsBundleField = instanceManager.getClass().getDeclaredField("mJSBundleFile"); | ||||||
|                         jsBundleField.setAccessible(true); |                         jsBundleField.setAccessible(true); | ||||||
|                         jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application)); |                         jsBundleField.set(instanceManager, UpdateContext.getBundleUrl(application)); | ||||||
| @@ -119,11 +139,14 @@ public class UpdateModuleImpl { | |||||||
|  |  | ||||||
|                     try { |                     try { | ||||||
|                         instanceManager.recreateReactContextInBackground(); |                         instanceManager.recreateReactContextInBackground(); | ||||||
|  |                         promise.resolve(true); | ||||||
|                     } catch (Throwable err) { |                     } catch (Throwable err) { | ||||||
|  |                         promise.reject("pushy:"+err.getMessage()); | ||||||
|                         activity.recreate(); |                         activity.recreate(); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                 } catch (Throwable err) { |                 } catch (Throwable err) { | ||||||
|  |                     promise.reject("pushy:switchVersion failed"+err.getMessage()); | ||||||
|                     Log.e("pushy", "switchVersion failed", err); |                     Log.e("pushy", "switchVersion failed", err); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -131,31 +154,46 @@ public class UpdateModuleImpl { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     public static void setNeedUpdate(UpdateContext updateContext, ReadableMap options) { |     public static void setNeedUpdate(UpdateContext updateContext, ReadableMap options,Promise promise) { | ||||||
|  |         try { | ||||||
|             final String hash = options.getString("hash"); |             final String hash = options.getString("hash"); | ||||||
|  |             if(hash==null || hash.isEmpty()){ | ||||||
|  |                 promise.reject("hash不能为空"); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|             UiThreadUtil.runOnUiThread(new Runnable() { |             UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void run() { |                 public void run() { | ||||||
|                     try { |                     try { | ||||||
|                         updateContext.switchVersion(hash); |                         updateContext.switchVersion(hash); | ||||||
|  |                         promise.resolve(true); | ||||||
|                     } catch (Throwable err) { |                     } catch (Throwable err) { | ||||||
|  |                         promise.reject("switchVersionLater failed:"+err.getMessage()); | ||||||
|                         Log.e("pushy", "switchVersionLater failed", err); |                         Log.e("pushy", "switchVersionLater failed", err); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |         }catch (Exception e){ | ||||||
|  |             promise.reject("执行报错:"+e.getMessage()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void markSuccess(UpdateContext updateContext) { |     public static void markSuccess(UpdateContext updateContext,Promise promise) { | ||||||
|  |         try { | ||||||
|             UiThreadUtil.runOnUiThread(new Runnable() { |             UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void run() { |                 public void run() { | ||||||
|                     updateContext.markSuccess(); |                     updateContext.markSuccess(); | ||||||
|  |                     promise.resolve(true); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |         }catch (Exception e){ | ||||||
|  |             promise.reject("执行报错:"+e.getMessage()); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void setBlockUpdate(UpdateContext updateContext, ReadableMap options) { |     public static void setBlockUpdate(UpdateContext updateContext, ReadableMap options,Promise promise) { | ||||||
|  |         try { | ||||||
|             final int until = options.getInt("until"); |             final int until = options.getInt("until"); | ||||||
|             final String reason = options.getString("reason"); |             final String reason = options.getString("reason"); | ||||||
|             UiThreadUtil.runOnUiThread(new Runnable() { |             UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
| @@ -164,28 +202,64 @@ public class UpdateModuleImpl { | |||||||
|                     updateContext.setBlockUpdate(until, reason); |                     updateContext.setBlockUpdate(until, reason); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |             promise.resolve(true); | ||||||
|  |         }catch (Exception e){ | ||||||
|  |             promise.reject("执行报错:"+e.getMessage()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     public static void setUuid(UpdateContext updateContext, String uuid) { |     } | ||||||
|  |  | ||||||
|  |     public static void setUuid(UpdateContext updateContext, String uuid, Promise promise) { | ||||||
|  |         try { | ||||||
|             UiThreadUtil.runOnUiThread(new Runnable() { |             UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
|                 @Override |                 @Override | ||||||
|                 public void run() { |                 public void run() { | ||||||
|                     updateContext.setKv("uuid", uuid); |                     updateContext.setKv("uuid", uuid); | ||||||
|  |                     promise.resolve(true); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|  |         }catch (Exception e){ | ||||||
|  |             promise.reject("执行报错:"+e.getMessage()); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     public static void setLocalHashInfo(UpdateContext updateContext, final String hash, final String info) { |     } | ||||||
|  |  | ||||||
|  |     public static boolean check(String json) { | ||||||
|  |         ObjectMapper mapper = new ObjectMapper(); | ||||||
|  |         try { | ||||||
|  |             mapper.readValue(json, Map.class); | ||||||
|  |             System.out.println("String can be converted to Map"); | ||||||
|  |             return  true; | ||||||
|  |         } catch (IOException e) { | ||||||
|  |             System.out.println("String cannot be converted to Map"); | ||||||
|  |             return  false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     public static void setLocalHashInfo(UpdateContext updateContext, final String hash, final String info, Promise promise) { | ||||||
|         UiThreadUtil.runOnUiThread(new Runnable() { |         UiThreadUtil.runOnUiThread(new Runnable() { | ||||||
|             @Override |             @Override | ||||||
|             public void run() { |             public void run() { | ||||||
|  |                 if(!check(info)){ | ||||||
|                     updateContext.setKv("hash_" + hash, info); |                     updateContext.setKv("hash_" + hash, info); | ||||||
|  |                     promise.reject("校验报错:json字符串格式错误"); | ||||||
|  |                 }else { | ||||||
|  |                     updateContext.setKv("hash_" + hash, info); | ||||||
|  |                     promise.resolve(true); | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static void getLocalHashInfo(UpdateContext updateContext, final String hash, Promise promise) { |     public static void getLocalHashInfo(UpdateContext updateContext, final String hash, Promise promise) { | ||||||
|         promise.resolve(updateContext.getKv("hash_" + hash)); |         String value = updateContext.getKv("hash_" + hash); | ||||||
|  |         if(check(value)){ | ||||||
|  |             promise.resolve(value); | ||||||
|  |         }else { | ||||||
|  |             promise.reject("校验报错:json字符串格式错误"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -94,33 +94,33 @@ public class UpdateModule extends NativeUpdateSpec { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void reloadUpdate(ReadableMap options) { |     public void reloadUpdate(ReadableMap options,Promise promise) { | ||||||
|         UpdateModuleImpl.reloadUpdate(updateContext, mContext, options); |         UpdateModuleImpl.reloadUpdate(updateContext, mContext, options,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void setNeedUpdate(ReadableMap options) { |     public void setNeedUpdate(ReadableMap options,Promise promise) { | ||||||
|         UpdateModuleImpl.setNeedUpdate(updateContext, options); |         UpdateModuleImpl.setNeedUpdate(updateContext, options,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void markSuccess() { |     public void markSuccess(Promise promise) { | ||||||
|         UpdateModuleImpl.markSuccess(updateContext); |         UpdateModuleImpl.markSuccess(updateContext,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void setBlockUpdate(ReadableMap options) { |     public void setBlockUpdate(ReadableMap options,Promise promise) { | ||||||
|         UpdateModuleImpl.setBlockUpdate(updateContext,options); |         UpdateModuleImpl.setBlockUpdate(updateContext,options,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void setUuid(final String uuid) { |     public void setUuid(final String uuid, Promise promise) { | ||||||
|         UpdateModuleImpl.setUuid(updateContext,uuid); |         UpdateModuleImpl.setUuid(updateContext,uuid,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void setLocalHashInfo(final String hash, final String info) { |     public void setLocalHashInfo(final String hash, final String info, final Promise promise) { | ||||||
|         UpdateModuleImpl.setLocalHashInfo(updateContext,hash,info); |         UpdateModuleImpl.setLocalHashInfo(updateContext,hash,info,promise); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -192,29 +192,53 @@ RCT_EXPORT_MODULE(RCTPushy); | |||||||
|     return self; |     return self; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(setBlockUpdate:(NSDictionary *)options) | RCT_EXPORT_METHOD(setBlockUpdate:(NSDictionary *)options | ||||||
|  |                   resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                                     rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|     // NSMutableDictionary *blockUpdateInfo = [NSMutableDictionary new]; |     // NSMutableDictionary *blockUpdateInfo = [NSMutableDictionary new]; | ||||||
|     // blockUpdateInfo[@"reason"] = options[@"reason"]; |     // blockUpdateInfo[@"reason"] = options[@"reason"]; | ||||||
|     // blockUpdateInfo[@"until"] = options[@"until"]; |     // blockUpdateInfo[@"until"] = options[@"until"]; | ||||||
|  |     @try { | ||||||
|         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; | ||||||
|         [defaults setObject:options forKey:keyBlockUpdate]; |         [defaults setObject:options forKey:keyBlockUpdate]; | ||||||
|         [defaults synchronize]; |         [defaults synchronize]; | ||||||
|  |         resolve(@true); | ||||||
|  |     } | ||||||
|  |     @catch (NSException *exception) { | ||||||
|  |         reject(@"执行报错", nil, nil); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(setUuid:(NSString *)uuid) | RCT_EXPORT_METHOD(setUuid:(NSString *)uuid  resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                   rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|  |     @try { | ||||||
|         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; | ||||||
|         [defaults setObject:uuid forKey:keyUuid]; |         [defaults setObject:uuid forKey:keyUuid]; | ||||||
|         [defaults synchronize]; |         [defaults synchronize]; | ||||||
|  |         resolve(@true); | ||||||
|  |     } | ||||||
|  |     @catch (NSException *exception) { | ||||||
|  |         reject(@"json格式校验报错", nil, nil); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(setLocalHashInfo:(NSString *)hash | RCT_EXPORT_METHOD(setLocalHashInfo:(NSString *)hash | ||||||
|                   value:(NSString *)value) |                   value:(NSString *)value resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                   rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|  |     NSData *data = [value dataUsingEncoding:NSUTF8StringEncoding]; | ||||||
|  |     NSError *error = nil; | ||||||
|  |     id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; | ||||||
|  |     if (object && [object isKindOfClass:[NSDictionary class]]) { | ||||||
|         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; | ||||||
|         [defaults setObject:value forKey:[keyHashInfo stringByAppendingString:hash]]; |         [defaults setObject:value forKey:[keyHashInfo stringByAppendingString:hash]]; | ||||||
|         [defaults synchronize]; |         [defaults synchronize]; | ||||||
|  |         resolve(@true); | ||||||
|  |     } else { | ||||||
|  |         reject(@"json格式校验报错", nil, nil); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -269,7 +293,9 @@ RCT_EXPORT_METHOD(downloadPatchFromPpk:(NSDictionary *)options | |||||||
|     }]; |     }]; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options) | RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options | ||||||
|  |                   resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                   rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|     NSString *hash = options[@"hash"]; |     NSString *hash = options[@"hash"]; | ||||||
|      |      | ||||||
| @@ -290,15 +316,20 @@ RCT_EXPORT_METHOD(setNeedUpdate:(NSDictionary *)options) | |||||||
|         [defaults setObject:newInfo forKey:keyPushyInfo]; |         [defaults setObject:newInfo forKey:keyPushyInfo]; | ||||||
|          |          | ||||||
|         [defaults synchronize]; |         [defaults synchronize]; | ||||||
|  |         resolve(@true); | ||||||
|  |     }else{ | ||||||
|  |         reject(@"执行报错", nil, nil); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options) | RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options | ||||||
|  |                   resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                                     rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|  |     @try { | ||||||
|         NSString *hash = options[@"hash"]; |         NSString *hash = options[@"hash"]; | ||||||
| 
 |  | ||||||
|         if (hash.length) { |         if (hash.length) { | ||||||
|         [self setNeedUpdate:options]; |             [self setNeedUpdate:options resolver:resolve rejecter:reject]; | ||||||
|              |              | ||||||
|             // reload 0.62+ |             // reload 0.62+ | ||||||
|             // RCTReloadCommandSetBundleURL([[self class] bundleURL]); |             // RCTReloadCommandSetBundleURL([[self class] bundleURL]); | ||||||
| @@ -308,11 +339,22 @@ RCT_EXPORT_METHOD(reloadUpdate:(NSDictionary *)options) | |||||||
|                [self.bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"]; |                [self.bridge setValue:[[self class] bundleURL] forKey:@"bundleURL"]; | ||||||
|                [self.bridge reload]; |                [self.bridge reload]; | ||||||
|            }); |            }); | ||||||
|  |             resolve(@true); | ||||||
|  |         }else{ | ||||||
|  |             reject(@"执行报错", nil, nil); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     @catch (NSException *exception) { | ||||||
|  |         reject(@"执行报错", nil, nil); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| RCT_EXPORT_METHOD(markSuccess) | RCT_EXPORT_METHOD(markSuccess: | ||||||
|  |                   resolver:(RCTPromiseResolveBlock)resolve | ||||||
|  |                                     rejecter:(RCTPromiseRejectBlock)reject) | ||||||
| { | { | ||||||
|  |      | ||||||
|  |     @try { | ||||||
|         // up package info |         // up package info | ||||||
|         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; |         NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; | ||||||
|         NSMutableDictionary *pushyInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]]; |         NSMutableDictionary *pushyInfo = [[NSMutableDictionary alloc] initWithDictionary:[defaults objectForKey:keyPushyInfo]]; | ||||||
| @@ -329,6 +371,11 @@ RCT_EXPORT_METHOD(markSuccess) | |||||||
|          |          | ||||||
|         // clear other package dir |         // clear other package dir | ||||||
|         [self clearInvalidFiles]; |         [self clearInvalidFiles]; | ||||||
|  |         resolve(@true); | ||||||
|  |     } | ||||||
|  |     @catch (NSException *exception) { | ||||||
|  |         reject(@"执行报错", nil, nil); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @@ -354,6 +401,19 @@ RCT_EXPORT_METHOD(markSuccess) | |||||||
|     // Remove upstream listeners, stop unnecessary background tasks |     // Remove upstream listeners, stop unnecessary background tasks | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | - (BOOL) isBlankString:(NSString *)string { | ||||||
|  |     if (string == nil || string == NULL) { | ||||||
|  |         return YES; | ||||||
|  |     } | ||||||
|  |     if ([string isKindOfClass:[NSNull class]]) { | ||||||
|  |         return YES; | ||||||
|  |     } | ||||||
|  |     if ([[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] length]==0) { | ||||||
|  |         return YES; | ||||||
|  |     } | ||||||
|  |     return NO; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| - (void)doPushy:(PushyType)type options:(NSDictionary *)options callback:(void (^)(NSError *error))callback | - (void)doPushy:(PushyType)type options:(NSDictionary *)options callback:(void (^)(NSError *error))callback | ||||||
| { | { | ||||||
| @@ -365,7 +425,7 @@ RCT_EXPORT_METHOD(markSuccess) | |||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|     NSString *originHash = [RCTConvert NSString:options[@"originHash"]]; |     NSString *originHash = [RCTConvert NSString:options[@"originHash"]]; | ||||||
|     if (type == PushyTypePatchFromPpk && originHash <= 0) { |     if (type == PushyTypePatchFromPpk && [self isBlankString:originHash]) { | ||||||
|         callback([self errorWithMessage:ERROR_OPTIONS]); |         callback([self errorWithMessage:ERROR_OPTIONS]); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| @@ -570,7 +630,7 @@ RCT_EXPORT_METHOD(markSuccess) | |||||||
| - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule: | - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule: | ||||||
|     (const facebook::react::ObjCTurboModule::InitParams &)params |     (const facebook::react::ObjCTurboModule::InitParams &)params | ||||||
| { | { | ||||||
|     return std::make_shared<facebook::react::NativeCalculatorSpecJSI>(params); |     return std::make_shared<facebook::react::NativeUpdateSpecJSI>(params); | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| @@ -1 +1 @@ | |||||||
| 1676798137 | 1678849794 | ||||||
|   | |||||||
| @@ -19,10 +19,13 @@ export interface Spec extends TurboModule { | |||||||
|     uuid: string, |     uuid: string, | ||||||
|     isUsingBundleUrl: boolean, |     isUsingBundleUrl: boolean, | ||||||
|   }; |   }; | ||||||
|   setLocalHashInfo(hash: string, info: string): void; |   setLocalHashInfo(hash: string, info: string): Promise<void>; | ||||||
|   getLocalHashInfo(hash: string): Promise<string>; |   getLocalHashInfo(hash: string): Promise<string>; | ||||||
|   setUuid(uuid: string): void; |   setUuid(uuid: string): Promise<void>; | ||||||
|   setBlockUpdate(options: { reason: string, until: number }): void; |   setBlockUpdate(options: { reason: string, until: number }): Promise<void>; | ||||||
|  |   reloadUpdate(options: { hash: string }): Promise<void>; | ||||||
|  |   setNeedUpdate(options: { hash: string }): Promise<void>; | ||||||
|  |   markSuccess(): Promise<void>; | ||||||
|   downloadPatchFromPpk(options: { |   downloadPatchFromPpk(options: { | ||||||
|     updateUrl: string, |     updateUrl: string, | ||||||
|     hash: string, |     hash: string, | ||||||
| @@ -36,9 +39,6 @@ export interface Spec extends TurboModule { | |||||||
|     updateUrl: string, |     updateUrl: string, | ||||||
|     hash: string, |     hash: string, | ||||||
|   }): Promise<void>; |   }): Promise<void>; | ||||||
|   reloadUpdate(options: { hash: string }): void; |  | ||||||
|   setNeedUpdate(options: { hash: string }): void; |  | ||||||
|   markSuccess(): void; |  | ||||||
|   downloadAndInstallApk(options: { |   downloadAndInstallApk(options: { | ||||||
|     url: string, |     url: string, | ||||||
|     target: string, |     target: string, | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										21
									
								
								package.json
									
									
									
									
									
								
							| @@ -7,7 +7,23 @@ | |||||||
|     "prepublish": "yarn submodule", |     "prepublish": "yarn submodule", | ||||||
|     "submodule": "git submodule update --init --recursive", |     "submodule": "git submodule update --init --recursive", | ||||||
|     "test": "echo \"Error: no test specified\" && exit 1", |     "test": "echo \"Error: no test specified\" && exit 1", | ||||||
|     "build-lib": "yarn submodule && $ANDROID_HOME/ndk/20.1.5948944/ndk-build NDK_PROJECT_PATH=android APP_BUILD_SCRIPT=android/jni/Android.mk NDK_APPLICATION_MK=android/jni/Application.mk NDK_LIBS_OUT=android/lib" |     "build-lib": "yarn submodule && $ANDROID_HOME/ndk/20.1.5948944/ndk-build NDK_PROJECT_PATH=android APP_BUILD_SCRIPT=android/jni/Android.mk NDK_APPLICATION_MK=android/jni/Application.mk NDK_LIBS_OUT=android/lib", | ||||||
|  |     "build:ios": "cd Example/testHotUpdate && detox build --configuration ios.sim.debug", | ||||||
|  |     "build:ios-debug": "cd Example/testHotUpdate && detox build --configuration ios.sim.debug", | ||||||
|  |     "build:ios-release": "cd Example/testHotUpdate && detox build --configuration ios.sim.release", | ||||||
|  |     "build:android-debug": "cd Example/testHotUpdate && detox build --configuration android.emu.debug", | ||||||
|  |     "build:android-release": "cd Example/testHotUpdate && detox build --configuration android.emu.release", | ||||||
|  |     "test:ios": "cd Example/testHotUpdate && detox test --configuration ios.sim.debug", | ||||||
|  |     "test:ios-debug": "cd Example/testHotUpdate && detox test --configuration ios.sim.debug", | ||||||
|  |     "test:ios-release": "cd Example/testHotUpdate && detox test --configuration ios.sim.release", | ||||||
|  |     "test:android-debug": "cd Example/testHotUpdate && detox test --configuration android.emu.debug", | ||||||
|  |     "test:android-release": "cd Example/testHotUpdate && ./node_modules/.bin/nyc yarn detox test --configuration android.emu.debug", | ||||||
|  |     "e2e:ios": "npm run build:ios-release && npm run test:ios-release", | ||||||
|  |     "e2e:android": "npm run build:android-release && npm run test:android-release", | ||||||
|  |     "tests:emulator:prepare": "cd .github/workflows/scripts/functions && yarn && yarn build", | ||||||
|  |     "tests:emulator:start-ci": "yarn tests:emulator:prepare && cd ./.github/workflows/scripts && ./start-firebase-emulator.sh", | ||||||
|  |     "tests:packager:jet-ci": "cd Example/testHotUpdate && cross-env TMPDIR=$HOME/.metro REACT_DEBUGGER=\"echo nope\" node_modules/.bin/react-native start --no-interactive", | ||||||
|  |     "tests:ios:pod:install": "rm -rf ios/RCTPushy.xcworkspace && yarn pod-install" | ||||||
|   }, |   }, | ||||||
|   "repository": { |   "repository": { | ||||||
|     "type": "git", |     "type": "git", | ||||||
| @@ -39,5 +55,8 @@ | |||||||
|         "jsSrcsDir": "lib" |         "jsSrcsDir": "lib" | ||||||
|       } |       } | ||||||
|     ] |     ] | ||||||
|  |   }, | ||||||
|  |   "devDependencies": { | ||||||
|  |     "firebase-tools": "^11.24.1" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 steven
					steven