diff --git a/.circleci/README.md b/.circleci/README.md index 0ae32f93c4d13c..a69111990927a8 100644 --- a/.circleci/README.md +++ b/.circleci/README.md @@ -1,172 +1,4 @@ # Circle CI -This directory is home to the Circle CI configuration files. Circle is our continuous integration service provider. You can see the overall status of React Native's builds at https://circleci.com/gh/facebook/react-native - -You may also see an individual PR's build status by scrolling down to the Checks section in the PR. - -## Purposes - -We use CircleCI for mainly 3 purposes: - -1. Testing changes -2. Release Nightlies -3. Release Stable Versions of React Native - -When testing changes, we run all the tests on commits that lands on `main`. For commits in PR, we try to understand which kind of changes the PR is about and we try to selectively run only the relevant tests. so, for example, if a PR only touches iOS files, we are going to run only iOS tests. - -A Nighly job runs every day at around 9:00 PM, GMT. They run from `main` and they publish a version of React Native using the current state of the codebase, creating a version number that follows the format: `0..0-nightly--`. -The nightly job also publish all the monorepo packages, taking care of updating the transitive dependencies of those packages. - -Stable versions are released manually by the Release Crew and they run from a stable branch. Stable branches have the shape of `0.-stable`. - -## How It Works? - -CircleCI execution is now split in two steps: -- Setup -- Testing - -The setup step takes care of analyzing the changes in the PR and of deciding which jobs needs to run. - -The testing flow is a set of workflows that executes the required tests. - -### Setup - -The code of the setup workflow lives in the root [`config.yml`](https://github.com/facebook/react-native/blob/main/.circleci/config.yml) file. -It uses the `Continuation orb` from CircleCI to start a CI flow that depends on the changes present in the PR. - -If the changes are not coming from a PR (either a simple commit or if the CI is running on main) **we always run all the tests** as a cautionary measure. - -The setup job has also to expose all the pipeline parameters that we would need to pass to the actual workflow. Those parameters are **automatically forwarded** to the workflows that are started as a result of the setup. - -The setup job uses a JS script to carry on its logic. The [`pipeline_selection.js`](https://github.com/facebook/react-native/blob/main/scripts/circleci/pipeline_selection.js) script can be invoked with two commands: -- `filter-jobs` -- `create-configs` - -The **`filter-jobs`** command takes care of creating a JSON representation of the tests we need to run based on the changes in the PR. - -The **`create-configs`** command consumes the JSON representation to create a CircleCI configuration that can then executes all the required tests. - -#### Creating a Configuration - -To create a configuration, the `pipeline-selection` scripts collates together various pieces of `YML` files that lives in the [`Configurations` folder](https://github.com/facebook/react-native/tree/main/.circleci/configurations). - -The order in which these files are appended is **important** and it always contains the following.: - -1. `top_level.yml`: this file contains some high level directives for CircleCI, like the version, the list of orbs, the cache-keys, and the pipeline parameters that can be used by the workflows. -2. `executors.yml`: this file contains the list of the executors used in our jobs and their configurations. -3. `commands.yml`: this file contains all the commands that can be used by jobs to executes. Commands are reusable functions that are shared by multiple jobs. -4. `jobs.yml`: this file contains the jobs that are used by workflows to carry on some specific tasks. They are composed of sequential commands. -5. `workflows.yml`: this file contains the shared workflows that needs to (or can) be always executed, no matter which kind of changes are pushed to CI. An example of these workflows is `analysis` (which is always executed) or `nightly` (which can be executed if a specific pipeline parameter is passed to the CI). - -Then, the `pipeline_selection create-configs` attach some specific test workflows, depending on the changes that are present in the PR. These change-dependent workflows live in the [`test_workflows`](https://github.com/facebook/react-native/tree/main/.circleci/configurations/test_workflows) folder. -These workflows are: -* `testAll.yml` => runs all the possible tests. This workflow is executed on main and on PRs which change set touches both iOS and Android -* `testAndroid.yml` => runs all the build steps and Android tests. This is used on changes that happens on the Android codebase and infra (`ReactAndroid` folder) -* `testIOS.yml` => runs all the build steps and iOS tests. This is used on changes that happens on the iOS codebase and infra (`React` folder) -* `testE2E.yml` => runs the E2E tests. As of today, E2E tests can be triggered if the commit message contains the `#run-e2e-tests` tag. -* `testJS.yml` => For all the changes that do not touch native/platform code, we only run JS tests. - -Notice that if there are changes on files that do not represents code (for example `.md` files like this one or the `Changelog`) we don't run any CI. - -## Test workflows - -The test workflows for native code are composed of 2 parts: -- building React Native -- testing - -Building React Native requires us to build several parts of it: -1. We need to build the Hermes JS engine -2. We need to build Android to create prebuilds -3. We need to package everything in an npm package that will mimic a React native release -4. We need to create a local maven repository - -### Building Hermes Engine - -#### Android -The `build_android` workflows takes care of building the Android version of Hermes and to put it properly in a local maven repository. -See the [Build Android](#build_android) section below. - -#### iOS -Hermes is a very complicated item to build for iOS. -It is composed of the Hermes compiler (HermesC) and of the actual engine. - -Hermes is shipped as a universal XCFramework. This means that we need to build all the architecture slices and then put them together in the XCFramework archive. -We also need to build 2 configurations: Debug and Release. - -In order to be efficient and to save costs, we parallelize the process as much as possible: - -1. We prepare the environment for building Hermes. -2. We build HermesC which is required by all the slices. -3. We start 8 jobs to build all the required slices in parallel: - 1. `iphone` slice, Debug mode - 1. `iphonesimulator` slice, Debug mode - 1. `macos` slice, Debug mode - 1. `catalyst` slice, Debug mode - 1. `iphone` slice, Release mode - 1. `iphonesimulator` slice, Release mode - 1. `macos` slice, Release mode - 1. `catalyst` slice, Release mode -4. We then have 2 jobs to create the Debug and Release tarballs in parallel. - 1. The Debug job receives the 4 Debug slices - 1. The Release job receives the 4 Release slices - -The `Debug` and `Release` tarball are then uploaded as artifacts. Notice that these we use these artifacts to **test the release** of React Native. - -While building Hermes, we take also care of building the dSYMs. A dSYM (Debug Symbols) is an archive that contains the Debug Symbols that users can load to de-symbolicate the Hermes Stack traces. These symbols are published when we create a React Native release. - -A lot of these build steps are automated by some shell scripts that lives in the [`react-native/packages/react-native/sdks/hermes-engine/utils` folder](https://github.com/facebook/react-native/tree/main/packages/react-native/sdks/hermes-engine/utils). - -### Build Android - -The android build is all managed by Gradle, so building android should be as easy as calling a [`gradle` command](https://github.com/facebook/react-native/blob/main/.circleci/configurations/jobs.yml#L268-L274). - -The relevant part here is that the build android generates a `maven-local` repository that is passed to the [`build_npm_package`](https://github.com/facebook/react-native/blob/main/.circleci/configurations/jobs.yml#L1182) and that we use to test the releases. - -### Build NPM package - -This job is the responsible to create an NPM package that is suitable to be released or tested in CI. -If we are in a release flow (for example the Nightly workflow), it also proceed with the publication. - -The job can be invoked with different parameters: -- `dry-run` => it does not publish anything, but prepare the artifacts to be used for testing -- `nightly` => it creates the artifacts and publish a nightly version of React Native. -- `release` => it creates the artifacts and publish a stable version of React Native. - -The build NPM package takes all the artifacts produced in the previous steps (iOS' Hermes, iOS' Hermes dSYMs, Android's `maven-local`) and creates an npm package packing all the code. - -If in a release mode, it also proceed publishing the NPM package to NPM, and the artifacts to Maven central, which we use to distribute all the artifacts. - -This job also uploads the `maven-local` repository and a zipped version of the npm package to CircleCI's artifacts. We use these artifacts to **test the release** of React Native. - -## Testing React Native -React Native tests runs in two different scenarios: -- RNTester -- A New App - -### RNTester -RNTester is our internal testing app. It is a fully working React Native app that lives in the [`react-native/packages/rn-tester` folder](https://github.com/facebook/react-native/tree/main/packages/rn-tester) of the repository. -RNTester is an app which contains code that exercise most part of the React Native frameworks. -It also has the feature of building React Native **from source**. For that reason, it does not have to wait for the NPM package to be ready, but RNTester's tests can start as soon as the `build_android` step and the step that builds Hermes for iOS are done. - -Notice the Tests on RNTester for iOS consumes the Hermes engine that is built in the previous steps. - -For Android, these tests creates an APK that is uploaded as an artifact in CircleCI. We use these artifacts to **test the releases** of React Native.. - -### A New App -The React Native repo contains a template app in the [`react-native/packages/react-native/template` folder]() that is used to spin up a new application that is preconfigured with React Native. - -We have several tests that we run starting from the template, testing various configurations: -- Debug/Release -- JSC/Hermes (two different JS engine we support) -- New/Old Architecture (two different Architectures for React Native) - -We want to test all the React Native changes against the template, but we can't publish a React native version on each change that is merged. Therefore, to run tests on the template we use a NPM registry proxy called [Verdaccio](https://verdaccio.org/). - -When running a Template test our CI follows roughly these steps: -1. Prepare the executor -2. Start a Verdaccio server -3. Publish on Verdaccio all the monorepo [packages](https://github.com/facebook/react-native/tree/main/packages) on which React Native depends on. -4. Publish on Verdaccio the react-native NPM package that has been created in the NPM step -5. Spin up a new React native apps from the template, downloading react-native from Verdaccio. - -In this way, we are sure that we can test all the changes that happen in React Native on a new React Native app. +This directory was home to the Circle CI configuration files. +In July 2024 we moved to GitHub Actions, and week this folder for backward compatibility, as we want to keep on using Circle CI for the release of React Native <= 0.74. diff --git a/.circleci/config.yml b/.circleci/config.yml index a642711e33d1af..88db963b290c47 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,114 +1,13 @@ version: 2.1 - -# this allows you to use CircleCI's dynamic configuration feature -setup: true - -orbs: - continuation: circleci/continuation@1.0.0 - -parameters: - # Real pipelines parameters - run_release_workflow: - default: false - type: boolean - - run_nightly_workflow: - default: false - type: boolean - - release_version: - default: "" - type: string - - release_monorepo_packages_version: - default: "" - type: string - - release_tag: - default: "" - type: string - - release_dry_run: - default: false - type: boolean +workflows: + version: 2 + stub: + jobs: + - circleci-stub jobs: - choose_ci_jobs: + circleci-stub: docker: - image: debian:bullseye - resource_class: small steps: - - run: - name: Install Yarn - command: | - apt update - apt install -y wget git curl jq - - apt-get update - apt-get install -y ca-certificates curl gnupg - mkdir -p /etc/apt/keyrings - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg - - NODE_MAJOR=18 - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list - apt-get update - - apt install -y nodejs - npm install --global yarn - - checkout - - run: - name: Yarn Install - command: yarn install - - when: - condition: - or: - - equal: [ main, << pipeline.git.branch >> ] - - matches: - pattern: /0\.[0-9]+[\.[0-9]+]?-stable/ - value: << pipeline.git.branch >> - steps: - - run: - name: "[Main or Stable] Create input for config to test everything" - command: | - mkdir -p /tmp/circleci/ - echo '{ "run_all": true }' > /tmp/circleci/pipeline_config.json - - when: - condition: - not: - or: - - equal: [ main, << pipeline.git.branch >> ] - - matches: - pattern: /0\.[0-9]+[\.[0-9]+]?-stable/ - value: << pipeline.git.branch >> - steps: - - run: - name: "[PR Branch] Filter jobs" - command: | - if [[ -z "$CIRCLE_PULL_REQUEST" ]]; then - echo "Not in a PR. Can't filter properly outside a PR. Please open a PR so that we can run the proper CI tests." - echo "For safety, we run all the tests!" - mkdir -p /tmp/circleci/ - echo '{ "run_all": true }' > /tmp/circleci/pipeline_config.json - else - PR_NUMBER="${CIRCLE_PULL_REQUEST##*/}" - node ./scripts/circleci/pipeline_selection.js filter-jobs - fi - - run: - name: Create config - description: Generates a configuration on the fly, depending on the files that have been modified - command: | - node ./scripts/circleci/pipeline_selection.js create-configs - - store_artifacts: - path: .circleci/generated_config.yml - destination: generated_config.yml - - continuation/continue: - configuration_path: .circleci/generated_config.yml - -# our single workflow, that triggers the setup job defined above -workflows: - always-run: - jobs: - - choose_ci_jobs: - filters: - tags: - only: /.*/ + - run: echo "There is nothing here, just an empty job. Everything has been moved to GitHub Action" diff --git a/.circleci/configurations/commands.yml b/.circleci/configurations/commands.yml deleted file mode 100644 index faef8484725969..00000000000000 --- a/.circleci/configurations/commands.yml +++ /dev/null @@ -1,580 +0,0 @@ -# ------------------------- -# COMMANDS -# ------------------------- -commands: - # Checkout with cache, on machines that are using Docker the cache is ignored - checkout_code_with_cache: - parameters: - checkout_base_cache_key: - default: *checkout_cache_key - type: string - steps: - - restore_cache: - key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }} - - checkout - - save_cache: - key: << parameters.checkout_base_cache_key >>-{{ arch }}-{{ .Branch }}-{{ .Revision }} - paths: - - ".git" - - setup_ruby: - parameters: - ruby_version: - default: "2.6.10" - type: string - steps: - - restore_cache: - key: *gems_cache_key - - run: - name: Set Required Ruby - command: echo << parameters.ruby_version >> > /tmp/required_ruby - - restore_cache: - key: *rbenv_cache_key - - run: - name: Install the proper Ruby and run Bundle install - command: | - # Check if rbenv is installed. CircleCI is migrating to rbenv so we may not need to always install it. - - if [[ -z "$(command -v rbenv)" ]]; then - brew install rbenv ruby-build - # Load and init rbenv - (rbenv init 2> /dev/null) || true - echo '' >> ~/.bash_profile - echo 'eval "$(rbenv init - bash)"' >> ~/.bash_profile - source ~/.bash_profile - else - echo "rbenv found; Skipping installation" - fi - - # Install the right version of ruby - if [[ -z "$(rbenv versions | grep << parameters.ruby_version >>)" ]]; then - # ensure that `ruby-build` can see all the available versions of Ruby - # some PRs received machines in a weird state, this should make the pipelines - # more robust. - brew update && brew upgrade ruby-build - rbenv install << parameters.ruby_version >> - fi - - # Set ruby dependencies - rbenv global << parameters.ruby_version >> - if [[ << parameters.ruby_version >> == "2.6.10" ]]; then - # RubyGems 3.0.3.1 breaks Bundler - gem update --system 3.2.3 - rbenv rehash - gem install bundler -v 2.4.22 - else - rbenv rehash - gem install bundler - fi - bundle check || bundle install --path vendor/bundle --clean - - save_cache: - key: *rbenv_cache_key - paths: - - ~/.rbenv - - save_cache: - key: *gems_cache_key - paths: - - vendor/bundle - - run_yarn: - parameters: - yarn_base_cache_key: - default: *yarn_cache_key - type: string - - steps: - - restore_cache: - keys: - - << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }} - - << parameters.yarn_base_cache_key >>-{{ arch }} - - << parameters.yarn_base_cache_key >> - - run: - name: "Yarn: Install Dependencies" - command: | - # Skip yarn install on metro bump commits as the package is not yet - # available on npm - if [[ $(echo "$GIT_COMMIT_DESC" | grep -c "Bump metro@") -eq 0 ]]; then - yarn install --non-interactive --cache-folder ~/.cache/yarn - fi - - save_cache: - paths: - - ~/.cache/yarn - key: << parameters.yarn_base_cache_key >>-{{ arch }}-{{ checksum "yarn.lock" }} - - build_packages: - steps: - - run: - name: Build packages - command: yarn build - - brew_install: - parameters: - package: - description: Homebrew package to install - type: string - steps: - - run: - name: "Brew: Install << parameters.package >>" - command: brew install << parameters.package >> - - with_rntester_pods_cache_span: - parameters: - steps: - type: steps - steps: - - run: - name: Setup CocoaPods cache - # Copy packages/rn-tester/Podfile.lock since it can be changed by pod install - command: cp packages/rn-tester/Podfile.lock packages/rn-tester/Podfile.lock.bak - - restore_cache: - keys: - # The committed lockfile is generated using static libraries and USE_HERMES=1 so it could load an outdated cache if a change - # only affects the frameworks or hermes config. To help prevent this also cache based on the content of Podfile. - - *pods_cache_key - - steps: << parameters.steps >> - - save_cache: - paths: - - packages/rn-tester/Pods - key: *pods_cache_key - - with_gradle_cache: - parameters: - steps: - type: steps - steps: - - restore_cache: - keys: - - *gradle_cache_key - - v3-gradle-{{ .Environment.CIRCLE_JOB }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}- - - v3-gradle-{{ .Environment.CIRCLE_JOB }}- - - v3-gradle- - - steps: << parameters.steps >> - - save_cache: - paths: - - ~/.gradle/caches - - ~/.gradle/wrapper - - packages/react-native/ReactAndroid/build/downloads - - packages/react-native/ReactAndroid/build/third-party-ndk - key: *gradle_cache_key - - run_e2e: - parameters: - platform: - description: Target platform - type: enum - enum: ["android", "ios", "js"] - default: "js" - retries: - description: How many times the job should try to run these tests - type: integer - default: 3 - steps: - - run: - name: "Run Tests: << parameters.platform >> End-to-End Tests" - command: node ./scripts/e2e/run-ci-e2e-tests.js --<< parameters.platform >> --retries << parameters.retries >> - - report_bundle_size: - parameters: - platform: - description: Target platform - type: enum - enum: ["android", "ios"] - steps: - - run: - name: Report size of RNTester.app (analysis-bot) - command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" scripts/circleci/report-bundle-size.sh << parameters.platform >> || true - - setup_hermes_version: - steps: - - run: - name: Set up Hermes workspace and caching - command: | - mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes" - - if [ -f "$HERMES_VERSION_FILE" ]; then - echo "Hermes Version file found! Using this version for the build:" - cat $HERMES_VERSION_FILE > /tmp/hermes/hermesversion - else - echo "Hermes Version file not found!!!" - echo "Using the last commit from main for the build:" - HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]') - echo $HERMES_TAG_SHA > /tmp/hermes/hermesversion - fi - cat /tmp/hermes/hermesversion - - get_react_native_version: - steps: - - run: - name: Get React Native version - command: | - VERSION=$(cat packages/react-native/package.json | jq -r '.version') - # Save the react native version we are building in a file so we can use that file as part of the cache key. - echo "$VERSION" > /tmp/react-native-version - echo "React Native Version is $(cat /tmp/react-native-version)" - HERMES_VERSION="$(cat /tmp/hermes/hermesversion)" - echo "Hermes commit is $HERMES_VERSION" - - get_react_native_version_windows: - steps: - - run: - name: Get React Native version on Windows - command: | - $VERSION=cat packages/react-native/package.json | jq -r '.version' - # Save the react native version we are building in a file so we can use that file as part of the cache key. - echo "$VERSION" > /tmp/react-native-version - echo "React Native Version is $(cat /tmp/react-native-version)" - $HERMES_VERSION=cat C:\Users\circleci\project\tmp\hermes\hermesversion - echo "Hermes commit is $HERMES_VERSION" - - with_hermes_tarball_cache_span: - parameters: - steps: - type: steps - set_tarball_path: - type: boolean - default: False - flavor: - default: "Debug" - description: The Hermes build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - hermes_tarball_artifacts_dir: - type: string - default: *hermes_tarball_artifacts_dir - steps: - - get_react_native_version - - when: - condition: - equal: [ << parameters.flavor >>, "Debug"] - steps: - - restore_cache: - keys: - - *hermes_tarball_debug_cache_key - - when: - condition: - equal: [ << parameters.flavor >>, "Release"] - steps: - - restore_cache: - keys: - - *hermes_tarball_release_cache_key - - when: - condition: << parameters.set_tarball_path >> - steps: - - run: - name: Set HERMES_ENGINE_TARBALL_PATH envvar if Hermes tarball is present - command: | - HERMES_TARBALL_ARTIFACTS_DIR=<< parameters.hermes_tarball_artifacts_dir >> - if [ ! -d $HERMES_TARBALL_ARTIFACTS_DIR ]; then - echo "Hermes tarball artifacts dir not present ($HERMES_TARBALL_ARTIFACTS_DIR). Build Hermes from source." - exit 0 - fi - - if [ ! -d ~/react-native ]; then - echo "No React Native checkout found. Run `checkout` first." - exit 0 - fi - - TARBALL_FILENAME=$(node ~/react-native/packages/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>") - TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME - - echo "Looking for $TARBALL_FILENAME in $HERMES_TARBALL_ARTIFACTS_DIR" - echo "$TARBALL_PATH" - - if [ ! -f $TARBALL_PATH ]; then - echo "Hermes tarball not present ($TARBALL_PATH). Build Hermes from source." - exit 0 - fi - - echo "Found Hermes tarball at $TARBALL_PATH" - echo "export HERMES_ENGINE_TARBALL_PATH=$TARBALL_PATH" >> $BASH_ENV - - run: - name: Print Hermes version - command: | - HERMES_TARBALL_ARTIFACTS_DIR=<< parameters.hermes_tarball_artifacts_dir >> - TARBALL_FILENAME=$(node ~/react-native/packages/react-native/scripts/hermes/get-tarball-name.js --buildType "<< parameters.flavor >>") - TARBALL_PATH=$HERMES_TARBALL_ARTIFACTS_DIR/$TARBALL_FILENAME - if [[ -e $TARBALL_PATH ]]; then - tar -xf $TARBALL_PATH - echo 'print(HermesInternal?.getRuntimeProperties?.()["OSS Release Version"])' > test.js - ./destroot/bin/hermes test.js - rm test.js - rm -rf destroot - else - echo 'No Hermes tarball found.' - fi - - steps: << parameters.steps >> - - when: - condition: - equal: [ << parameters.flavor >>, "Debug"] - steps: - - save_cache: - key: *hermes_tarball_debug_cache_key - paths: *hermes_tarball_cache_paths - - when: - condition: - equal: [ << parameters.flavor >>, "Release"] - steps: - - save_cache: - key: *hermes_tarball_release_cache_key - paths: *hermes_tarball_cache_paths - - store_hermes_apple_artifacts: - description: Stores the tarball and the osx binaries - parameters: - flavor: - default: "Debug" - description: The Hermes build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - steps: - - when: - condition: - equal: [ << parameters.flavor >>, "Debug"] - steps: - - store_artifacts: - path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-debug.tar.gz - - when: - condition: - equal: [ << parameters.flavor >>, "Release"] - steps: - - store_artifacts: - path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-release.tar.gz - - store_artifacts: - path: /tmp/hermes/osx-bin/<< parameters.flavor >>/hermesc - - store_artifacts: - path: /tmp/hermes/dSYM/<< parameters.flavor >>/hermes.framework.dSYM - - stop_job_if_apple_artifacts_are_there: - description: Stops the current job if there are already the required artifacts - parameters: - flavor: - default: "All" - description: The flavor of artifacts to check. Must be one of "Debug", "Release" or "All" - type: enum - enum: ["Debug", "Release", "All"] - steps: - - when: - condition: - equal: [ << parameters.flavor >>, "All"] - steps: - - run: - name: "Export files to be checked" - command: | - echo "/tmp/hermes/Release_tarball_present" > /tmp/hermes_files - echo "/tmp/hermes/Debug_tarball_present" >> /tmp/hermes_files - echo "/tmp/hermes/Release_osx_bin" >> /tmp/hermes_files - echo "/tmp/hermes/Debug_osx_bin" >> /tmp/hermes_files - echo "/tmp/hermes/Release_dSYM" >> /tmp/hermes_files - echo "/tmp/hermes/Debug_dSYM" >> /tmp/hermes_files - - when: - condition: - not: - equal: [ << parameters.flavor >>, "All"] - steps: - - run: - name: "Export files to be checked" - command: | - echo "/tmp/hermes/<< parameters.flavor >>_tarball_present" > /tmp/hermes_files - echo "/tmp/hermes/<< parameters.flavor >>_osx_bin" >> /tmp/hermes_files - echo "/tmp/hermes/<< parameters.flavor >>_dSYM" >> /tmp/hermes_files - - run: - name: Stop if files are present - command: | - files=($(cat /tmp/hermes_files)) - # Initialize a flag indicating all files exist - - all_files_exist=true - - for file in "${files[@]}"; do - if [[ ! -f "$file" ]]; then - all_files_exist=false - echo "$file does not exist." - else - echo "$file exist." - fi - done - - if [[ "$all_files_exist" == true ]]; then - echo "Tarball, osx-bin and dSYM are present. Halting this job" - circleci-agent step halt - fi - - check_if_tarball_is_present: - description: "Checks if the tarball of a specific Flavor is present and adds a marker file" - parameters: - flavor: - default: "Debug" - description: The flavor of artifacts to check. Must be one of "Debug" or "Release" - type: enum - enum: ["Debug", "Release"] - steps: - - run: - name: Check if << parameters.flavor >> tarball is there - command: | - FLAVOR=debug - if [[ << parameters.flavor >> == "Release" ]]; then - FLAVOR=release - fi - - if [[ -f "/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" ]]; then - echo "[HERMES TARBALL] Found the << parameters.flavor >> tarball" - touch /tmp/hermes/<< parameters.flavor >>_tarball_present - fi - - check_if_osx_bin_is_present: - description: "Checks if the osx bin of a specific Flavor is present and adds a marker file" - parameters: - flavor: - default: "Debug" - description: The flavor of artifacts to check. Must be one of "Debug" or "Release" - type: enum - enum: ["Debug", "Release"] - steps: - - run: - name: Check if macosx binary is there - command: | - if [[ -d /tmp/hermes/osx-bin/<< parameters.flavor >> ]]; then - echo "[HERMES MACOSX BIN] Found the osx bin << parameters.flavor >>" - touch /tmp/hermes/<< parameters.flavor >>_osx_bin - fi - - check_if_dsym_are_present: - description: "Checks if the dSYM a specific Flavor are present and adds a marker file" - parameters: - flavor: - default: "Debug" - description: The flavor of artifacts to check. Must be one of "Debug" or "Release" - type: enum - enum: ["Debug", "Release"] - steps: - - run: - name: Check if dSYM are there - command: | - if [[ -d /tmp/hermes/dSYM/<< parameters.flavor >> ]]; then - echo "[HERMES dSYM] Found the dSYM << parameters.flavor >>" - touch /tmp/hermes/<< parameters.flavor >>_dSYM - fi - - setup_hermes_workspace: - description: "Setup Hermes Workspace" - steps: - - run: - name: Set up workspace - command: | - mkdir -p $HERMES_OSXBIN_ARTIFACTS_DIR ./packages/react-native/sdks/hermes - cp -r $HERMES_WS_DIR/hermes/* ./packages/react-native/sdks/hermes/. - cp -r ./packages/react-native/sdks/hermes-engine/utils ./packages/react-native/sdks/hermes/. - - with_xcodebuild_cache: - description: "Add caching to iOS jobs to speed up builds" - parameters: - steps: - type: steps - podfile_lock_path: - type: string - default: packages/rn-tester/Podfile.lock - pods_build_folder: - type: string - default: packages/rn-tester/Pods - podfile_lock_cache_key: - type: string - default: *rntester_podfile_lock_cache_key - cocoapods_cache_key: - type: string - default: *cocoapods_cache_key - steps: - - run: - name: Prepare Xcodebuild cache - command: | - WEEK=$(date +"%U") - YEAR=$(date +"%Y") - echo "$WEEK-$YEAR" > /tmp/week_year - - restore_cache: - key: << parameters.podfile_lock_cache_key >> - - restore_cache: - key: << parameters.cocoapods_cache_key >> - - steps: << parameters.steps >> - - save_cache: - key: << parameters.podfile_lock_cache_key >> - paths: - - << parameters.podfile_lock_path >> - - save_cache: - key: << parameters.cocoapods_cache_key >> - paths: - - << parameters.pods_build_folder >> - - store_artifacts_if_needed: - description: "This step stores the artifacts only if we are on main or on a stable branch" - parameters: - path: - type: string - destination: - type: string - default: << parameters.path >> - when: - type: enum - enum: ['always', 'on_fail', 'on_success'] - default: 'always' - steps: - - when: - condition: - or: - - equal: [ main, << pipeline.git.branch >> ] - - matches: - pattern: /0\.[0-9]+[\.[0-9]+]?-stable/ - value: << pipeline.git.branch >> - steps: - - store_artifacts: - when: << parameters.when >> - path: << parameters.path >> - destination: << parameters.destination >> - - prepare_ios_tests: - description: This command runs a set of commands to prepare iOS for running unit tests - steps: - - brew_install: - package: xcbeautify - - run: - name: Run Ruby Tests - command: | - cd packages/react-native/scripts - sh run_ruby_tests.sh - - run: - name: Boot iPhone Simulator - command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - - - run: - name: Configure Environment Variables - command: | - echo 'export PATH=/usr/local/opt/node@18/bin:$PATH' >> $BASH_ENV - source $BASH_ENV - - - run: - name: "Brew: Tap wix/brew" - command: brew tap wix/brew - - brew_install: - package: applesimutils watchman - - run: - name: Configure Watchman - command: echo "{}" > .watchmanconfig - - run_ios_tests: - description: This command run iOS tests and collects results - steps: - - run: - name: "Run Tests: iOS Unit and Integration Tests" - command: yarn test-ios - - run: - name: Zip Derived data folder - when: always - command: | - echo "zipping tests results" - cd /Users/distiller/Library/Developer/Xcode - XCRESULT_PATH=$(find . -name '*.xcresult') - tar -zcvf xcresults.tar.gz $XCRESULT_PATH - - store_artifacts_if_needed: - path: /Users/distiller/Library/Developer/Xcode/xcresults.tar.gz - - report_bundle_size: - platform: ios - - store_test_results: - path: ./reports/junit diff --git a/.circleci/configurations/executors.yml b/.circleci/configurations/executors.yml deleted file mode 100644 index eb1fecfaaefd2f..00000000000000 --- a/.circleci/configurations/executors.yml +++ /dev/null @@ -1,38 +0,0 @@ -# ------------------------- -# EXECUTORS -# ------------------------- -executors: - nodelts: - <<: *defaults - docker: - - image: *nodelts_image - resource_class: "large" - nodeprevlts: - <<: *defaults - docker: - - image: *nodeprevlts_image - resource_class: "large" - # Executor with Node & Java used to inspect and lint - node-browsers-small: - <<: *defaults - docker: - - image: *nodelts_browser_image - resource_class: "small" - node-browsers-medium: - <<: *defaults - docker: - - image: *nodelts_browser_image - resource_class: "medium" - reactnativeandroid-xlarge: - <<: *android-defaults - resource_class: "xlarge" - reactnativeandroid-large: - <<: *android-defaults - resource_class: "large" - reactnativeios: - <<: *defaults - macos: - xcode: *xcode_version - resource_class: macos.m1.medium.gen1 - environment: - - RCT_BUILD_HERMES_FROM_SOURCE: true diff --git a/.circleci/configurations/jobs.yml b/.circleci/configurations/jobs.yml deleted file mode 100644 index fbd50935d5663c..00000000000000 --- a/.circleci/configurations/jobs.yml +++ /dev/null @@ -1,1284 +0,0 @@ -# ------------------------- -# JOBS -# ------------------------- -jobs: - # ------------------------- - # JOBS: Analyze PR - # ------------------------- - # Analyze pull request and raise any lint/flow issues. - # Issues will be posted to the PR itself via GitHub bots. - # This workflow should only fail if the bots fail to run. - analyze_pr: - executor: node-browsers-medium - steps: - - checkout - - run_yarn - - run: - name: Run linters against modified files (analysis-bot) - command: GITHUB_TOKEN="$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A""$PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B" yarn lint-ci - - # ------------------------- - # JOBS: Analyze Code - # ------------------------- - analyze_code: - executor: node-browsers-small - steps: - - checkout - - run_yarn - - - run: - name: Lint code - command: scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml - when: always - - - run: - name: Lint Java - command: scripts/circleci/exec_swallow_error.sh yarn lint-java --check - when: always - - - run: - name: Set server.max_workers=1 in .flowconfig - command: | - sed -i '/\[options\]/a server.max_workers=1' .flowconfig - when: always - - - run: - name: Check for errors in code using Flow (iOS) - command: yarn flow-check - when: always - - - run: - name: Check for errors in code using Flow (Android) - command: yarn flow-check - when: always - - - run: - name: Run TypeScript tests - command: yarn test-typescript - when: always - - - run: - name: Sanity checks - command: | - ./scripts/circleci/check_license.sh - ./scripts/circleci/validate_yarn_lockfile.sh - when: always - - - run: - name: Check formatting - command: yarn run format-check - when: always - - - store_test_results: - path: ./reports/junit - - # ------------------------- - # JOBS: Test JavaScript - # ------------------------- - test_js: - parameters: - executor: - type: executor - default: nodelts - run_disabled_tests: - type: boolean - default: false - executor: << parameters.executor >> - steps: - - checkout - - run_yarn - - run: - name: Install rsync - command: sudo apt update && sudo apt install rsync - - # ------------------------- - # Run JavaScript tests - - run: - name: "Run Tests: JavaScript Tests" - command: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2 - - run_e2e: - platform: js - - # Optionally, run disabled tests - - when: - condition: << parameters.run_disabled_tests >> - steps: - - run: echo "Failing tests may be moved here temporarily." - # ------------------------- - - - store_test_results: - path: ./reports/junit - - # ------------------------- - # JOBS: iOS E2E Tests - # ------------------------- - test_e2e_ios: - executor: reactnativeios - parameters: - ruby_version: - default: "2.7.8" - description: The version of ruby that must be used - type: string - steps: - - checkout_code_with_cache - - run_yarn - - setup_hermes_version - - run: - name: Install appium - command: npm install appium@2.0.0 -g - - run: - name: Install appium drivers - command: | - appium driver install uiautomator2 - appium driver install xcuitest - - run: - name: Start Appium server - command: appium --base-path /wd/hub - background: true - - run: - name: Start Metro - command: | - cd packages/rn-tester - yarn start - background: true - - brew_install: - package: cmake - - setup_ruby: - ruby_version: << parameters.ruby_version >> - - run: - name: Boot iOS Simulator - command: source scripts/.tests.env && xcrun simctl boot "$IOS_DEVICE" || true - - with_xcodebuild_cache: - steps: - - run: - name: Install Bundler - command: | - cd packages/rn-tester - bundle check || bundle install - bundle exec pod setup - RCT_NEW_ARCH_ENABLED=1 bundle exec pod install --verbose - - run: - name: Build app - command: | - xcodebuild build \ - -workspace packages/rn-tester/RNTesterPods.xcworkspace \ - -configuration Debug \ - -scheme RNTester \ - -sdk iphonesimulator \ - -derivedDataPath /tmp/e2e/ - - run: - name: Move app to correct directory - command: mv /tmp/e2e/Build/Products/Debug-iphonesimulator/RNTester.app packages/rn-tester-e2e/apps/rn-tester.app - - run: - name: Check Appium server status - command: scripts/circleci/check_appium_server_status.sh - - run: - name: Run E2E tests - no_output_timeout: 30m - command: | - cd packages/rn-tester-e2e - (yarn test-e2e ios 2>&1 | tee /tmp/test_log) || true - - store_artifacts: - path: /tmp/test_log - - # ------------------------- - # JOBS: Android E2E Tests - # ------------------------- - test_e2e_android: - executor: - name: android/android-machine - tag: 2023.07.1 - steps: - - checkout_code_with_cache - - run_yarn - - android/create-avd: - avd-name: e2e_emulator - system-image: system-images;android-34;google_apis;x86_64 - install: true - - android/start-emulator: - avd-name: e2e_emulator - no-window: true - restore-gradle-cache-prefix: v1a - post-emulator-launch-assemble-command: "" - - run: - name: Install appium - command: npm install appium@2.0.0 -g - - run: - name: Install appium drivers - command: | - appium driver install uiautomator2@2.29.1 - appium driver install xcuitest@4.32.10 - - run: - name: Start Appium server - command: appium --base-path /wd/hub - background: true - - run: - name: Start Metro - command: | - cd packages/rn-tester - yarn start - background: true - - with_gradle_cache: - steps: - - run: - name: Build app - command: | - ./gradlew :packages:rn-tester:android:app:assembleHermesDebug -PreactNativeArchitectures=x86_64 - - run: - name: Move app to correct directory - command: mv packages/rn-tester/android/app/build/outputs/apk/hermes/debug/app-hermes-x86_64-debug.apk packages/rn-tester-e2e/apps/rn-tester.apk - - run: - name: Check Appium server status - command: | - if ! nc -z 127.0.0.1 4723; then - echo Could not find Appium server - exit 1 - fi - - run: - name: Run E2E tests - no_output_timeout: 30m - command: | - cd packages/rn-tester-e2e - (yarn test-e2e android 2>&1 | tee /tmp/test_log) || true - - store_artifacts: - path: /tmp/test_log - - # ------------------------- - # JOBS: Build Android - # ------------------------- - build_android: - executor: reactnativeandroid-xlarge - parameters: - release_type: - description: The type of release to build. Must be one of "nightly", "release", "dry-run", "prealpha". - type: enum - enum: ["nightly", "release", "dry-run", "prealpha"] - default: "dry-run" - steps: - - checkout - - run_yarn - - run: - name: Set React Native Version - command: node ./scripts/releases/set-rn-version.js --build-type << parameters.release_type >> - - - with_gradle_cache: - steps: - - run: - name: Build and publish all the Android Artifacts to /tmp/maven-local - command: | - if [[ << parameters.release_type >> == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - ./gradlew publishAllToMavenTempLocal - - - persist_to_workspace: - root: /root/react-native/ - paths: - - build/ - - .gradle/ - - packages/rn-tester/android/app/.cxx/ - - packages/rn-tester/android/app/build/ - - packages/react-native/sdks/download/ - - packages/react-native/sdks/hermes/ - - packages/react-native/ReactAndroid/.cxx/ - - packages/react-native/ReactAndroid/build/ - - packages/react-native/ReactAndroid/hermes-engine/.cxx/ - - packages/react-native/ReactAndroid/hermes-engine/build/ - - packages/react-native/ReactAndroid/src/main/jni/prebuilt/ - - packages/react-native-gradle-plugin/.gradle/ - - packages/react-native-gradle-plugin/build/ - - packages/react-native-codegen/lib/ - - # ------------------------- - # JOBS: Test Android - # ------------------------- - test_android: - executor: reactnativeandroid-xlarge - steps: - - checkout - - run_yarn - - run: - name: Set React Native Version to "dry-run" - # test_android executes only for dry-run builds. We need to bump the version for caching - # reasons otherwise we won't reuse the artifacts from the build_android job. - command: node ./scripts/releases/set-rn-version.js --build-type "dry-run" - - attach_workspace: - at: . - - - with_gradle_cache: - steps: - - run: - name: Build & Test React Native using Gradle - command: ./gradlew build -PenableWarningsAsErrors=true - - - report_bundle_size: - platform: android - - - store_test_results: - path: ~/react-native/packages/react-native-gradle-plugin/build/test-results - - - store_test_results: - path: ~/react-native/packages/react-native/ReactAndroid/build/test-results - - - store_artifacts: - path: ~/react-native/packages/rn-tester/android/app/build/outputs/apk/ - destination: rntester-apk - - # ------------------------- - # JOBS: Test Android Template - # ------------------------- - test_android_template: - executor: reactnativeandroid-large - parameters: - flavor: - default: "Debug" - description: The Android build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - architecture: - default: "OldArch" - description: Which React Native architecture to use. Must be one of "NewArch", "OldArch". - type: enum - enum: [ "NewArch", "OldArch" ] - jsengine: - default: "Hermes" - description: Which JavaScript engine to use. Must be one of "Hermes", "JSC". - type: enum - enum: ["Hermes", "JSC"] - environment: - - PROJECT_NAME: "AndroidTemplateProject" - - YARN_ENABLE_IMMUTABLE_INSTALLS: false - steps: - - checkout_code_with_cache - - run_yarn - - attach_workspace: - at: . - - run: - name: Create Android template project - command: | - REPO_ROOT=$(pwd) - node ./scripts/releases/update-template-package.js "{\"react-native\":\"file:$REPO_ROOT/build/$(cat build/react-native-package-version)\"}" - node ./scripts/e2e/init-template-e2e.js --projectName $PROJECT_NAME --templatePath "$REPO_ROOT/packages/react-native" --directory "/tmp/$PROJECT_NAME" --verbose - - with_gradle_cache: - steps: - - run: - name: Build the template application for << parameters.flavor >> with Architecture set to << parameters.architecture >>, and using the << parameters.jsengine>> JS engine. - command: | - cd /tmp/$PROJECT_NAME/android/ - if [[ << parameters.architecture >> == "NewArch" ]]; then - export ORG_GRADLE_PROJECT_newArchEnabled=true - else - export ORG_GRADLE_PROJECT_newArchEnabled=false - fi - if [[ << parameters.jsengine >> == "Hermes" ]]; then - export ORG_GRADLE_PROJECT_hermesEnabled=true - else - export ORG_GRADLE_PROJECT_hermesEnabled=false - fi - ./gradlew assemble<< parameters.flavor >> -Preact.internal.mavenLocalRepo=/root/react-native/maven-local - - - store_artifacts: - path: /tmp/AndroidTemplateProject/android/app/build/outputs/apk/ - destination: template-apk - - # ------------------------- - # JOBS: Test iOS HelloWorld - # ------------------------- - test_ios_helloworld: - parameters: - flavor: - default: "Debug" - description: The Xcode build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - architecture: - default: "OldArch" - description: Which React Native architecture to use. Must be one of "NewArch", "OldArch". - type: enum - enum: ["NewArch", "OldArch"] - jsengine: - default: "Hermes" - description: Which JavaScript engine to use. Must be one of "Hermes", "JSC". - type: enum - enum: ["Hermes", "JSC"] - use_frameworks: - default: "StaticLibraries" - description: Which kind of option we want to use for `use_frameworks!` - type: enum - enum: ["StaticLibraries", "DynamicFrameworks"] - ruby_version: - default: "2.6.10" - description: The version of ruby that must be used - type: string - podfile_lock_cache_key: - type: string - default: *helloworld_podfile_lock_cache_key - cocoapods_cache_key: - type: string - default: *helloworld_cocoapods_cache_key - executor: - description: The executor to use - default: reactnativeios - type: string - executor: << parameters.executor >> - environment: - - HERMES_WS_DIR: *hermes_workspace_root - - YARN_ENABLE_IMMUTABLE_INSTALLS: false - steps: - - checkout_code_with_cache - - run_yarn - - attach_workspace: - at: . - - *attach_hermes_workspace - - setup_ruby: - ruby_version: << parameters.ruby_version >> - - when: - condition: - equal: ["Hermes", << parameters.jsengine >>] - steps: - - run: - name: Set HERMES_ENGINE_TARBALL_PATH - command: | - BUILD_TYPE="<< parameters.flavor >>" - TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") - echo "export HERMES_ENGINE_TARBALL_PATH=$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME" >> $BASH_ENV - - with_xcodebuild_cache: - podfile_lock_path: packages/helloworld/ios/Podfile.lock - pods_build_folder: packages/helloworld/ios/Pods - cocoapods_cache_key: << parameters.cocoapods_cache_key >> - podfile_lock_cache_key: << parameters.podfile_lock_cache_key >> - steps: - - run: - name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>> - command: | - cd packages/helloworld - args=() - if [[ << parameters.architecture >> == "OldArch" ]]; then - args+=(--arch old) - fi - if [[ << parameters.jsengine >> == "JSC" ]]; then - args+=(--jsvm jsc) - fi - if [[ << parameters.use_frameworks >> == "DynamicFrameworks" ]]; then - args+=(--frameworks dynamic) - fi - yarn bootstrap ios "${args[@]}" | cat - - run: - name: Build helloworld project - command: | - cd packages/helloworld - args=() - if [[ << parameters.flavor >> == "Release" ]]; then - args+=(--prod) - fi - yarn build ios "${args[@]}" | cat - yarn bundle ios "${args[@]}" | cat - - # ------------------------- - # JOBS: Test iOS RNTester - # ------------------------- - test_ios_rntester: - - parameters: - jsengine: - default: "Hermes" - description: Which JavaScript engine to use. Must be one of "Hermes", "JSC". - type: enum - enum: ["Hermes", "JSC"] - use_frameworks: - default: "StaticLibraries" - description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks" - type: enum - enum: ["StaticLibraries", "DynamicFrameworks"] - architecture: - default: "NewArch" - description: "The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup" - type: enum - enum: ["OldArch", "NewArch"] - ruby_version: - default: "2.6.10" - description: The version of ruby that must be used - type: string - run_unit_tests: - description: whether unit tests should run or not. - default: false - type: boolean - executor: - description: The executor to use - default: reactnativeios - type: string - executor: << parameters.executor >> - steps: - - checkout_code_with_cache - - run_yarn - - *attach_hermes_workspace - - # The macOS machine can run out of storage if Hermes is enabled and built from source. - # Since this job does not use the iOS Simulator, deleting it provides a quick way to - # free up space. - - run: - name: Delete iOS Simulators - background: true - command: sudo rm -rf /Library/Developer/CoreSimulator/Profiles/Runtimes/ - - setup_ruby: - ruby_version: << parameters.ruby_version >> - - when: - condition: << parameters.run_unit_tests >> - steps: - - prepare_ios_tests - - with_hermes_tarball_cache_span: - set_tarball_path: True - steps: - - with_xcodebuild_cache: - steps: - - run: - name: Install CocoaPods dependencies - command: | - - if [[ << parameters.jsengine >> == "JSC" ]]; then - export USE_HERMES=0 - fi - - if [[ << parameters.use_frameworks >> == "DynamicFrameworks" ]]; then - export USE_FRAMEWORKS=dynamic - fi - - if [[ << parameters.architecture >> == "NewArch" ]]; then - export RCT_NEW_ARCH_ENABLED=1 - fi - - cd packages/rn-tester - - bundle install - bundle exec pod install - - when: - condition: - # The run_ios_test will also build RNTester so we don't nee to build it - # here if we run tests - equal: [ false, << parameters.run_unit_tests >> ] - - steps: - - run: - name: Build RNTester - command: | - xcodebuild build \ - -workspace packages/rn-tester/RNTesterPods.xcworkspace \ - -scheme RNTester \ - -sdk iphonesimulator - - when: - condition: << parameters.run_unit_tests >> - steps: - - run_ios_tests - - # ------------------------- - # JOBS: Build Hermes - # ------------------------- - prepare_hermes_workspace: - docker: - - image: debian:bullseye - environment: - - HERMES_WS_DIR: *hermes_workspace_root - - HERMES_VERSION_FILE: "packages/react-native/sdks/.hermesversion" - - RCT_BUILD_HERMES_FROM_SOURCE: true - steps: - - run: - name: Install dependencies - command: | - apt update - - apt install -y wget git curl jq - - apt-get update - apt-get install -y ca-certificates curl gnupg - mkdir -p /etc/apt/keyrings - curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg - - NODE_MAJOR=18 - echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list - apt-get update - - apt install -y nodejs - npm install --global yarn - - checkout - - setup_hermes_version - - get_react_native_version - - restore_cache: - key: *hermes_workspace_cache_key - - run_yarn - - run: - name: Download Hermes tarball - command: | - node packages/react-native/scripts/hermes/prepare-hermes-for-build $CIRCLE_PULL_REQUEST - cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/. - cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/. - - cat /tmp/hermes/hermesversion - - save_cache: - key: *hermes_workspace_cache_key - paths: - - /tmp/hermes/download/ - - /tmp/hermes/hermes/ - # Check if we already built the tarball - # if yes, we can skip the building and we can skip some jobs building - - restore_cache: - keys: - - *hermes_tarball_release_cache_key - - check_if_tarball_is_present: - flavor: Release - - restore_cache: - keys: - - *hermes_tarball_debug_cache_key - - check_if_tarball_is_present: - flavor: Debug - - restore_cache: - keys: - - *hermes_macosx_bin_release_cache_key - - check_if_osx_bin_is_present: - flavor: Release - - restore_cache: - keys: - - *hermes_macosx_bin_debug_cache_key - - check_if_osx_bin_is_present: - flavor: Debug - - restore_cache: - keys: - - *hermes_dsym_debug_cache_key - - check_if_dsym_are_present: - flavor: Debug - - restore_cache: - keys: - - *hermes_dsym_release_cache_key - - check_if_dsym_are_present: - flavor: Release - - persist_to_workspace: - root: *hermes_workspace_root - paths: - - download - - hermes - - hermes-runtime-darwin - - osx-bin - - dSYM - - hermesversion - - Release_tarball_present - - Debug_tarball_present - - Release_osx_bin - - Debug_osx_bin - - Release_dSYM - - Debug_dSYM - - persist_to_workspace: - root: /tmp - paths: - - react-native-version - - build_hermesc_linux: - docker: - - image: debian:bullseye - resource_class: "large" - steps: - - checkout_code_with_cache - - run: - name: Install dependencies - command: | - apt update - apt install -y git openssh-client cmake build-essential \ - libreadline-dev libicu-dev jq zip python3 - - *attach_hermes_workspace - - get_react_native_version - - restore_cache: - key: *hermes_linux_cache_key - - run: - name: Set up workspace - command: | - mkdir -p /tmp/hermes/linux64-bin - - run: - name: Build HermesC for Linux - command: | - if [ -f /tmp/hermes/linux64-bin/hermesc ]; then - echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.' - else - cd /tmp/hermes - cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \ - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive" - cmake --build build --target hermesc -j 4 - cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. - fi - - save_cache: - key: *hermes_linux_cache_key - paths: - - /tmp/hermes/linux64-bin/ - - /tmp/hermes/hermes/destroot/ - - store_artifacts_if_needed: - path: /tmp/hermes/linux64-bin/ - - persist_to_workspace: - root: /tmp/hermes/ - paths: - - linux64-bin - - build_hermesc_apple: - executor: reactnativeios - environment: - - HERMES_WS_DIR: *hermes_workspace_root - - HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir - steps: - - *attach_hermes_workspace - - stop_job_if_apple_artifacts_are_there: - flavor: "All" - - checkout_code_with_cache - - get_react_native_version - - setup_hermes_workspace - - restore_cache: - key: *hermesc_apple_cache_key - - brew_install: - package: cmake - - run: - name: "Build HermesC Apple" - command: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - build_host_hermesc_if_needed - - save_cache: - key: *hermesc_apple_cache_key - paths: - - ./packages/react-native/sdks/hermes/build_host_hermesc - - persist_to_workspace: - root: ./packages/react-native/sdks/hermes/ - paths: - - build_host_hermesc - - build_apple_slices_hermes: - parameters: - slice_base_cache_key: - default: *hermes_apple_slices_cache_key - type: string - flavor: - default: "Debug" - description: The Hermes build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - slice: - default: "iphoneos" - description: The Hermes Slice that this job has to build - type: enum - enum: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"] - executor: reactnativeios - environment: - - HERMES_WS_DIR: *hermes_workspace_root - - HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir - - HERMES_OSXBIN_ARTIFACTS_DIR: *hermes_osxbin_artifacts_dir - steps: - - *attach_hermes_workspace - - stop_job_if_apple_artifacts_are_there: - flavor: << parameters.flavor >> - - checkout_code_with_cache - - get_react_native_version - - setup_hermes_workspace - - restore_cache: - key: *hermesc_apple_cache_key - - brew_install: - package: cmake - - restore_cache: - key: << parameters.slice_base_cache_key >>-<< parameters.slice >>-<< parameters.flavor >> - - run: - name: Build the Hermes << parameters.slice >> frameworks - command: | - cd ./packages/react-native/sdks/hermes || exit 1 - SLICE=<< parameters.slice >> - FLAVOR=<< parameters.flavor >> - FINAL_PATH=build_"$SLICE"_"$FLAVOR" - echo "Final path for this slice is: $FINAL_PATH" - - if [[ -d "$FINAL_PATH" ]]; then - echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH". - exit 0 - fi - - export RELEASE_VERSION=$(cat /tmp/react-native-version) - if [[ "$SLICE" == "macosx" ]]; then - echo "[HERMES] Building Hermes for MacOS" - export MAC_DEPLOYMENT_TARGET=10.13 - BUILD_TYPE="<< parameters.flavor >>" ./utils/build-mac-framework.sh - unset MAC_DEPLOYMENT_TARGET - else - echo "[HERMES] Building Hermes for iOS: $SLICE" - export IOS_DEPLOYMENT_TARGET=13.4 - BUILD_TYPE="<< parameters.flavor >>" ./utils/build-ios-framework.sh "$SLICE" - unset IOS_DEPLOYMENT_TARGET - fi - unset RELEASE_VERSION - - echo "Moving from build_$SLICE to $FINAL_PATH" - mv build_"$SLICE" "$FINAL_PATH" - - # check whether everything is there - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then - echo "Successfully built hermes.framework for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework for $SLICE in $FLAVOR" - exit 1 - fi - - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then - echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR" - echo "Please try again" - exit 1 - fi - - save_cache: - key: << parameters.slice_base_cache_key >>-<< parameters.slice >>-<< parameters.flavor >> - paths: - - ./packages/react-native/sdks/hermes/build_<< parameters.slice >>_<< parameters.flavor >> - - build_hermes_macos: - parameters: - slice_base_cache_key: - default: *hermes_apple_slices_cache_key - type: string - flavor: - default: "Debug" - description: The Hermes build type. Must be one of "Debug", "Release". - type: enum - enum: ["Debug", "Release"] - executor: reactnativeios - environment: - - HERMES_WS_DIR: *hermes_workspace_root - - HERMES_TARBALL_ARTIFACTS_DIR: *hermes_tarball_artifacts_dir - steps: - - *attach_hermes_workspace - # Try to store the artifacts if they are already in the workspace - - store_hermes_apple_artifacts: - flavor: << parameters.flavor >> - - stop_job_if_apple_artifacts_are_there: - flavor: << parameters.flavor >> - - checkout_code_with_cache - - run_yarn - - get_react_native_version - - brew_install: - package: cmake - - setup_hermes_workspace - - restore_cache: - key: << parameters.slice_base_cache_key >>-macosx-<< parameters.flavor >> - - restore_cache: - key: << parameters.slice_base_cache_key >>-iphoneos-<< parameters.flavor >> - - restore_cache: - key: << parameters.slice_base_cache_key >>-iphonesimulator-<< parameters.flavor >> - - restore_cache: - key: << parameters.slice_base_cache_key >>-catalyst-<< parameters.flavor >> - - restore_cache: - key: << parameters.slice_base_cache_key >>-xros-<< parameters.flavor >> - - restore_cache: - key: << parameters.slice_base_cache_key >>-xrsimulator-<< parameters.flavor >> - - run: - name: "Move back build folders" - command: | - cd ./packages/react-native/sdks/hermes || exit 1 - mv build_macosx_<< parameters.flavor >> build_macosx - mv build_iphoneos_<< parameters.flavor >> build_iphoneos - mv build_iphonesimulator_<< parameters.flavor >> build_iphonesimulator - mv build_catalyst_<< parameters.flavor >> build_catalyst - mv build_xros_<< parameters.flavor >> build_xros - mv build_xrsimulator_<< parameters.flavor >> build_xrsimulator - - run: - name: "Prepare destroot folder" - command: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - prepare_dest_root_for_ci - - run: - name: "Create fat framework for iOS" - command: | - cd ./packages/react-native/sdks/hermes || exit 1 - echo "[HERMES] Creating the universal framework" - export IOS_DEPLOYMENT_TARGET=13.4 - export RELEASE_VERSION=$(cat /tmp/react-native-version) - ./utils/build-ios-framework.sh build_framework - unset RELEASE_VERSION - unset IOS_DEPLOYMENT_TARGET - - run: - name: Package the Hermes Apple frameworks - command: | - BUILD_TYPE="<< parameters.flavor >>" - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX) - - TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") - - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \ - --inputDir ./packages/react-native/sdks/hermes \ - --buildType "$BUILD_TYPE" \ - --outputDir $TARBALL_OUTPUT_DIR) - - echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH" - - mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR - cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/. - - mkdir -p /tmp/hermes/osx-bin/<< parameters.flavor >> - cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/<< parameters.flavor >> - - run: - name: Create dSYM archive - command: | - FLAVOR=<< parameters.flavor >> - WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR" - - mkdir -p "$WORKING_DIR/macosx" - mkdir -p "$WORKING_DIR/catalyst" - mkdir -p "$WORKING_DIR/iphoneos" - mkdir -p "$WORKING_DIR/iphonesimulator" - mkdir -p "$WORKING_DIR/xros" - mkdir -p "$WORKING_DIR/xrsimulator" - - cd ./packages/react-native/sdks/hermes || exit 1 - - DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM - cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/" - cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" - cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" - cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" - cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" - cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" - - DEST_DIR="/tmp/hermes/dSYM/$FLAVOR" - tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" . - - mkdir -p "$DEST_DIR" - mv "hermes.framework.dSYM" "$DEST_DIR" - - - when: - condition: - equal: [ << parameters.flavor >>, "Debug"] - steps: - - save_cache: - key: *hermes_tarball_debug_cache_key - paths: *hermes_tarball_cache_paths - - save_cache: - key: *hermes_macosx_bin_debug_cache_key - paths: /tmp/hermes/osx-bin/Debug - - save_cache: - key: *hermes_dsym_debug_cache_key - paths: /tmp/hermes/dSYM/Debug - - when: - condition: - equal: [ << parameters.flavor >>, "Release"] - steps: - - save_cache: - key: *hermes_tarball_release_cache_key - paths: *hermes_tarball_cache_paths - - save_cache: - key: *hermes_macosx_bin_release_cache_key - paths: /tmp/hermes/osx-bin/Release - - save_cache: - key: *hermes_dsym_release_cache_key - paths: /tmp/hermes/dSYM/Release - - store_hermes_apple_artifacts: - flavor: << parameters.flavor >> - - when: - condition: - equal: [ << parameters.flavor >>, "Release" ] - steps: - - persist_to_workspace: - root: /tmp/hermes/ - paths: - - hermes-runtime-darwin/hermes-ios-release.tar.gz - - when: - condition: - equal: [ << parameters.flavor >>, "Debug" ] - steps: - - persist_to_workspace: - root: /tmp/hermes/ - paths: - - hermes-runtime-darwin/hermes-ios-debug.tar.gz - - persist_to_workspace: - root: /tmp/hermes/ - paths: - - osx-bin/<< parameters.flavor >> - - dSYM/<< parameters.flavor >> - - build_hermesc_windows: - executor: - name: win/default - shell: powershell.exe - environment: - - HERMES_WS_DIR: 'C:\tmp\hermes' - - ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip" - - MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin' - - CMAKE_DIR: 'C:\Program Files\CMake\bin' - steps: - - checkout_code_with_cache - - *attach_hermes_workspace - - get_react_native_version_windows - - restore_cache: - key: *hermes_windows_cache_key - - run: - name: Set up workspace - command: | - New-Item -ItemType Directory $Env:HERMES_WS_DIR - New-Item -ItemType Directory $Env:HERMES_WS_DIR\icu - New-Item -ItemType Directory $Env:HERMES_WS_DIR\deps - New-Item -ItemType Directory $Env:HERMES_WS_DIR\win64-bin - New-Item -ItemType SymbolicLink -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes - - run: - name: Build HermesC for Windows - command: | - if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) { - choco install --no-progress cmake -y - if (-not $?) { throw "Failed to install CMake" } - - cd $Env:HERMES_WS_DIR\icu - # If Invoke-WebRequest shows a progress bar, it will fail with - # Win32 internal error "Access is denied" 0x5 occurred [...] - $progressPreference = 'silentlyContinue' - Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip" - Expand-Archive -Path "icu.zip" -DestinationPath "." - - cd $Env:HERMES_WS_DIR - Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps" - # Include MSVC++ 2015 redistributables - Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps" - - $Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR" - $Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu" - - cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF - if (-not $?) { throw "Failed to configure Hermes" } - cd build_release - cmake --build . --target hermesc --config Release - if (-not $?) { throw "Failed to build Hermes" } - - cd $Env:HERMES_WS_DIR - Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin" - # Include Windows runtime dependencies - Copy-Item -Path "deps\*" -Destination "win64-bin" - } - else { - Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild." - } - - save_cache: - key: *hermes_windows_cache_key - paths: - - C:\tmp\hermes\win64-bin\ - - C:\tmp\hermes\hermes\icu\ - - C:\tmp\hermes\hermes\deps\ - - C:\tmp\hermes\hermes\build_release\ - - store_artifacts_if_needed: - path: C:\tmp\hermes\win64-bin\ - - persist_to_workspace: - root: C:\tmp\hermes\ - paths: - - win64-bin - - # ------------------------- - # JOBS: Releases - # ------------------------- - - # Writes a new commit and tag(s), which will trigger the `publish_release` - # and `publish_bumped_packages` workflows. - prepare_release: - parameters: - version: - type: string - # TODO(T182538198): Required for 0.74.x, where workspace packages are out - # of sync with react-native. This will be removed for 0.75+. - monorepo_packages_version: - type: string - tag: - type: string - dry_run: - type: boolean - default: false - executor: nodelts - steps: - - checkout_code_with_cache - - run_yarn - - add_ssh_keys: - fingerprints: - - "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c" - - run: - name: Versioning workspace packages - command: | - node scripts/releases/set-version "<< parameters.monorepo_packages_version >>" --skip-react-native-version - - run: - name: Versioning react-native package - command: | - node scripts/releases/set-rn-version.js -v "<< parameters.version >>" --build-type "release" - - run: - name: Creating release commit - command: | - # I'm seeing failures in automatically detect the email for the - # agent that should push the commit. - git config --global user.name "Distiller" - git config --global user.email "distiller@circleci.com" - - git commit -a -m "Release << parameters.version >>" -m "#publish-packages-to-npm&<< parameters.tag >>" - git tag -a "v<< parameters.version >>" -m "v<< parameters.version >>" - GIT_PAGER=cat git show HEAD - - when: - condition: - equal: ["latest", << parameters.tag >>] - steps: - - run: - name: Updating "latest" tag - command: | - git tag -d "latest" - git push origin :latest - git tag -a "latest" -m "latest" - - unless: - condition: << parameters.dry_run >> - steps: - run: - name: Pushing release commit - command: | - git push origin $CIRCLE_BRANCH --follow-tags - - build_npm_package: - parameters: - release_type: - description: The type of release to build. Must be one of "nightly", "release", "dry-run", or "prealpha". - type: enum - enum: ["nightly", "release", "dry-run", "prealpha"] - default: "dry-run" - executor: reactnativeandroid-xlarge - environment: - - HERMES_WS_DIR: *hermes_workspace_root - steps: - - run: - name: Add github.com to SSH known hosts - command: | - mkdir -p ~/.ssh - echo '|1|If6MU203eXTaaWL678YEfWkVMrw=|kqLeIAyTy8pzpj8x8Ae4Fr8Mtlc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts - - checkout - - *attach_hermes_workspace - - run: - name: Copy Hermes binaries - command: | - mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin - - # When build_hermes_macos runs as a matrix, it outputs - if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/. - elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/. - else - ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing." - echo "Could not locate macOS hermesc binary."; exit 1; - fi - - cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/. - cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/. - mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/ - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz - cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz - cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz - - run_yarn - - build_packages - - attach_workspace: - at: . - - # START: Stables, nightlies and prealphas - # This conditional step sets up the necessary credentials for publishing react-native to npm. - - when: - condition: - or: - - equal: [ "release", << parameters.release_type >> ] - - equal: [ "nightly", << parameters.release_type >> ] - steps: - - run: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc - # END: Stables, prealpha and nightlies - - - with_gradle_cache: - steps: - - run: - name: Publish NPM - command: | - # We can't have a separate step because each command is executed in a separate shell - # so variables exported in a command are not visible in another. - if [[ << parameters.release_type >> == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - node ./scripts/releases-ci/publish-npm.js -t << parameters.release_type >> - - - run: - name: Zip Maven Artifacts from /tmp/maven-local - command: zip -r /tmp/maven-local.zip /tmp/maven-local - - store_artifacts: - path: /tmp/maven-local.zip - - store_artifacts: - path: /root/.npm/_logs - - persist_to_workspace: - root: /tmp - paths: - - maven-local - - # START: Dry-run - # Provide a react-native package for this commit as a Circle CI release artifact. - - when: - condition: - equal: [ "dry-run", << parameters.release_type >> ] - steps: - - run: - name: Build release package as a job artifact - command: | - mkdir -p build - - FILENAME=$(cd packages/react-native; npm pack | tail -1) - mv packages/react-native/$FILENAME build/ - - echo $FILENAME > build/react-native-package-version - - store_artifacts: - path: ~/react-native/build/ - destination: build - - persist_to_workspace: - root: . - paths: - - build/* - # END: Dry-run - - # START: Stable releases - - when: - condition: - equal: [ "release", << parameters.release_type >> ] - steps: - - run: - name: Update rn-diff-purge to generate upgrade-support diff - command: | - curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ - -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${CIRCLE_TAG:1}\" }}" - # END: Stable releases - - poll_maven: - docker: - - image: cimg/node:current - resource_class: small - steps: - - checkout_code_with_cache - - run_yarn - - run: - name: Poll Maven for Artifacts - command: | - node scripts/circleci/poll-maven.js - - find_and_publish_bumped_packages: - executor: nodelts - steps: - - checkout - - run_yarn - - build_packages - - run: - name: Set NPM auth token - command: echo "//registry.npmjs.org/:_authToken=${CIRCLE_NPM_TOKEN}" > ~/.npmrc - - run: - name: Find and publish all bumped packages - command: node ./scripts/releases-ci/publish-updated-packages.js diff --git a/.circleci/configurations/test_workflows/testAll.yml b/.circleci/configurations/test_workflows/testAll.yml deleted file mode 100644 index 8286628e69dab6..00000000000000 --- a/.circleci/configurations/test_workflows/testAll.yml +++ /dev/null @@ -1,97 +0,0 @@ - tests: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - - prepare_release: - name: "prepare_release (dry run test)" - version: "0.0.0" - monorepo_packages_version: "0.0.0" - tag: test - dry_run: true - - prepare_hermes_workspace - - build_android: - release_type: "dry-run" - - build_hermesc_linux: - requires: - - prepare_hermes_workspace - - build_hermesc_apple: - requires: - - prepare_hermes_workspace - - build_apple_slices_hermes: - requires: - - build_hermesc_apple - matrix: - parameters: - flavor: ["Debug", "Release"] - slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"] - - build_hermes_macos: - requires: - - build_apple_slices_hermes - matrix: - parameters: - flavor: ["Debug", "Release"] - - build_hermesc_windows: - requires: - - prepare_hermes_workspace - - build_npm_package: - # Build a release package on every untagged commit, but do not publish to npm. - release_type: "dry-run" - requires: - - build_android - - build_hermesc_linux - - build_hermes_macos - - build_hermesc_windows - - test_android: - requires: - - build_android - - test_android_template: - requires: - - build_npm_package - matrix: - parameters: - architecture: ["NewArch", "OldArch"] - jsengine: ["Hermes", "JSC"] - flavor: ["Debug", "Release"] - - test_ios_helloworld: - requires: - - build_hermes_macos - name: "Test Template with Ruby 3.2.2" - ruby_version: "3.2.2" - architecture: "NewArch" - flavor: "Debug" - jsengine: "Hermes" - use_frameworks: "StaticLibraries" - - test_ios_helloworld: - requires: - - build_hermes_macos - matrix: - parameters: - flavor: ["Debug", "Release"] - jsengine: ["Hermes", "JSC"] - use_frameworks: ["StaticLibraries", "DynamicFrameworks"] - exclude: - # This config is tested with Ruby 3.2.2. Let's not double test it. - - flavor: "Debug" - jsengine: "Hermes" - use_frameworks: "StaticLibraries" - - test_ios_rntester: - requires: - - build_hermes_macos - use_frameworks: "DynamicFrameworks" - architecture: "NewArch" - ruby_version: "3.2.2" - matrix: - parameters: - jsengine: ["Hermes", "JSC"] - - test_ios_rntester: - run_unit_tests: true - use_frameworks: "StaticLibraries" - ruby_version: "2.6.10" - requires: - - build_hermes_macos - matrix: - parameters: - jsengine: ["Hermes", "JSC"] - architecture: ["NewArch", "OldArch"] diff --git a/.circleci/configurations/test_workflows/testAndroid.yml b/.circleci/configurations/test_workflows/testAndroid.yml deleted file mode 100644 index 9a29ead21ad835..00000000000000 --- a/.circleci/configurations/test_workflows/testAndroid.yml +++ /dev/null @@ -1,57 +0,0 @@ - tests_android: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - - prepare_release: - name: "prepare_release (dry run test)" - version: "0.0.0" - monorepo_packages_version: "0.0.0" - tag: test - dry_run: true - - prepare_hermes_workspace - - build_android: - release_type: "dry-run" - - build_hermesc_linux: - requires: - - prepare_hermes_workspace - - build_hermesc_apple: - requires: - - prepare_hermes_workspace - - build_apple_slices_hermes: - requires: - - build_hermesc_apple - matrix: - parameters: - flavor: ["Debug", "Release"] - slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"] - - build_hermes_macos: - requires: - - build_apple_slices_hermes - matrix: - parameters: - flavor: ["Debug", "Release"] - - build_hermesc_windows: - requires: - - prepare_hermes_workspace - - build_npm_package: - # Build a release package on every untagged commit, but do not publish to npm. - release_type: "dry-run" - requires: - - build_android - - build_hermesc_linux - - build_hermes_macos - - build_hermesc_windows - - test_android: - requires: - - build_android - # - test_e2e_android - - test_android_template: - requires: - - build_npm_package - matrix: - parameters: - architecture: ["NewArch", "OldArch"] - jsengine: ["Hermes", "JSC"] - flavor: ["Debug", "Release"] diff --git a/.circleci/configurations/test_workflows/testE2E.yml b/.circleci/configurations/test_workflows/testE2E.yml deleted file mode 100644 index a926a395775c0e..00000000000000 --- a/.circleci/configurations/test_workflows/testE2E.yml +++ /dev/null @@ -1,9 +0,0 @@ - tests_e2e: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - - test_e2e_ios: - ruby_version: "2.7.8" - - test_e2e_android diff --git a/.circleci/configurations/test_workflows/testIOS.yml b/.circleci/configurations/test_workflows/testIOS.yml deleted file mode 100644 index e1838f8ba4eb12..00000000000000 --- a/.circleci/configurations/test_workflows/testIOS.yml +++ /dev/null @@ -1,86 +0,0 @@ - test_ios: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - - prepare_release: - name: "prepare_release (dry run test)" - version: "0.0.0" - monorepo_packages_version: "0.0.0" - tag: test - dry_run: true - - prepare_hermes_workspace - - build_android: - release_type: "dry-run" - - build_hermesc_linux: - requires: - - prepare_hermes_workspace - - build_hermesc_apple: - requires: - - prepare_hermes_workspace - - build_apple_slices_hermes: - requires: - - build_hermesc_apple - matrix: - parameters: - flavor: ["Debug", "Release"] - slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst", "xros", "xrsimulator"] - - build_hermes_macos: - requires: - - build_apple_slices_hermes - matrix: - parameters: - flavor: ["Debug", "Release"] - - build_hermesc_windows: - requires: - - prepare_hermes_workspace - - build_npm_package: - # Build a release package on every untagged commit, but do not publish to npm. - release_type: "dry-run" - requires: - - build_android - - build_hermesc_linux - - build_hermes_macos - - build_hermesc_windows - - test_ios_helloworld: - requires: - - build_hermes_macos - name: "Test Template with Ruby 3.2.2" - ruby_version: "3.2.2" - architecture: "NewArch" - flavor: "Debug" - jsengine: "Hermes" - use_frameworks: "StaticLibraries" - - test_ios_helloworld: - requires: - - build_hermes_macos - matrix: - parameters: - flavor: ["Debug", "Release"] - jsengine: ["Hermes", "JSC"] - use_frameworks: ["StaticLibraries", "DynamicFrameworks"] - exclude: - # This config is tested with Ruby 3.2.2. Let's not double test it. - - flavor: "Debug" - jsengine: "Hermes" - use_frameworks: "StaticLibraries" - - test_ios_rntester: - requires: - - build_hermes_macos - use_frameworks: "DynamicFrameworks" - ruby_version: "3.2.2" - architecture: "NewArch" - matrix: - parameters: - jsengine: ["Hermes", "JSC"] - - test_ios_rntester: - run_unit_tests: true - use_frameworks: "StaticLibraries" - ruby_version: "2.6.10" - requires: - - build_hermes_macos - matrix: - parameters: - jsengine: ["Hermes", "JSC"] - architecture: ["NewArch", "OldArch"] diff --git a/.circleci/configurations/test_workflows/testJS.yml b/.circleci/configurations/test_workflows/testJS.yml deleted file mode 100644 index 6c5ea93e1c7fb9..00000000000000 --- a/.circleci/configurations/test_workflows/testJS.yml +++ /dev/null @@ -1,11 +0,0 @@ - tests_js: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - - test_js: - run_disabled_tests: false - - test_js: - name: test_js_prev_lts - executor: nodeprevlts diff --git a/.circleci/configurations/top_level.yml b/.circleci/configurations/top_level.yml deleted file mode 100644 index 3ede1cc3d9dc59..00000000000000 --- a/.circleci/configurations/top_level.yml +++ /dev/null @@ -1,149 +0,0 @@ -version: 2.1 - -# ------------------------- -# ORBS -# ------------------------- - -orbs: - win: circleci/windows@2.4.0 - android: circleci/android@2.3.0 - -# ------------------------- -# REFERENCES -# ------------------------- -references: - defaults: &defaults - working_directory: ~/react-native - environment: - - GIT_COMMIT_DESC: git log --format=oneline -n 1 $CIRCLE_SHA1 - # The public github tokens are publicly visible by design - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: &github_analysisbot_token_a "312d354b5c36f082cfe9" - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: &github_analysisbot_token_b "07973d757026bdd9f196" - # Homebrew currently breaks while updating: - # https://discuss.circleci.com/t/brew-install-fails-while-updating/32992 - - HOMEBREW_NO_AUTO_UPDATE: 1 - android-defaults: &android-defaults - working_directory: ~/react-native - docker: - - image: reactnativecommunity/react-native-android:v13.0 - environment: - - TERM: "dumb" - - GRADLE_OPTS: '-Dorg.gradle.daemon=false' - # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. - - ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - # Repeated here, as the environment key in this executor will overwrite the one in defaults - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: *github_analysisbot_token_a - - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: *github_analysisbot_token_b - - hermes_workspace_root: &hermes_workspace_root - /tmp/hermes - hermes_tarball_artifacts_dir: &hermes_tarball_artifacts_dir - /tmp/hermes/hermes-runtime-darwin - hermes_osxbin_artifacts_dir: &hermes_osxbin_artifacts_dir - /tmp/hermes/osx-bin - attach_hermes_workspace: &attach_hermes_workspace - attach_workspace: - at: *hermes_workspace_root - xcodebuild_derived_data_path: &xcodebuild_derived_data_path - ~/Library/Developer/Xcode/DerivedData/ - - main_or_stable_only: &main_or_stable_only - filters: - branches: - only: - - main - - /0\.[0-9]+[\.[0-9]+]?-stable/ - - - # ------------------------- - # Dependency Anchors - # ------------------------- - dependency_versions: - xcode_version: &xcode_version "15.2" - nodelts_image: &nodelts_image "cimg/node:20.2.0" - nodeprevlts_image: &nodeprevlts_image "cimg/node:18.12.1" - nodelts_browser_image: &nodelts_browser_image "cimg/node:20.2.0-browsers" - - # ------------------------- - # Cache Key Anchors - # ------------------------- - # Anchors for the cache keys - - cache_keys: - checkout_cache_key: &checkout_cache_key v1-checkout - gems_cache_key: &gems_cache_key v2-gems-{{ arch }}-{{ checksum "Gemfile.lock" }} - gradle_cache_key: &gradle_cache_key v3-gradle-{{ .Environment.CIRCLE_JOB }}-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "packages/react-native/ReactAndroid/gradle.properties" }} - yarn_cache_key: &yarn_cache_key v6-yarn-cache-{{ .Environment.CIRCLE_JOB }} - rbenv_cache_key: &rbenv_cache_key v1-rbenv-{{ arch }}-{{ checksum "/tmp/required_ruby" }} - hermes_workspace_cache_key: &hermes_workspace_cache_key v5-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }} - hermes_workspace_debug_cache_key: &hermes_workspace_debug_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }} - hermes_workspace_release_cache_key: &hermes_workspace_release_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }} - hermes_linux_cache_key: &hermes_linux_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-linux-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - hermes_windows_cache_key: &hermes_windows_cache_key v2-hermes-{{ .Environment.CIRCLE_JOB }}-windows-{{ checksum "/Users/circleci/project/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - # Hermes iOS - hermesc_apple_cache_key: &hermesc_apple_cache_key v4-hermesc-apple-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - hermes_apple_slices_cache_key: &hermes_apple_slices_cache_key v8-hermes-apple-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }} - hermes_tarball_debug_cache_key: &hermes_tarball_debug_cache_key v6-hermes-tarball-debug-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }} - hermes_tarball_release_cache_key: &hermes_tarball_release_cache_key v5-hermes-tarball-release-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }}-{{ checksum "packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh" }} - hermes_macosx_bin_release_cache_key: &hermes_macosx_bin_release_cache_key v5-hermes-release-macosx-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - hermes_macosx_bin_debug_cache_key: &hermes_macosx_bin_debug_cache_key v3-hermes-debug-macosx-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - hermes_dsym_debug_cache_key: &hermes_dsym_debug_cache_key v3-hermes-debug-dsym-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - hermes_dsym_release_cache_key: &hermes_dsym_release_cache_key v3-hermes-release-dsym-{{ checksum "/tmp/hermes/hermesversion" }}-{{ checksum "/tmp/react-native-version" }} - # Cocoapods - RNTester - pods_cache_key: &pods_cache_key v12-pods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock.bak" }}-{{ checksum "packages/rn-tester/Podfile" }} - cocoapods_cache_key: &cocoapods_cache_key v12-cocoapods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile.lock" }}-{{ checksum "packages/rn-tester/Podfile" }}-{{ checksum "/tmp/hermes/hermesversion" }} - rntester_podfile_lock_cache_key: &rntester_podfile_lock_cache_key v11-podfilelock-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/rn-tester/Podfile" }}-{{ checksum "/tmp/week_year" }}-{{ checksum "/tmp/hermes/hermesversion" }} - # Cocoapods - HelloWorld - helloworld_cocoapods_cache_key: &helloworld_cocoapods_cache_key v2-cocoapods-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/helloworld/ios/Podfile.lock" }}-{{ checksum "packages/helloworld/ios/Podfile" }}-{{ checksum "/tmp/hermes/hermesversion" }} - helloworld_podfile_lock_cache_key: &helloworld_podfile_lock_cache_key v2-podfilelock-{{ arch }}-{{ .Environment.CIRCLE_JOB }}-{{ checksum "packages/helloworld/ios/Podfile" }}-{{ checksum "/tmp/week_year" }}-{{ checksum "/tmp/hermes/hermesversion" }} - - cache_paths: - hermes_workspace_macos_cache_paths: &hermes_workspace_macos_cache_paths - - ~/react-native/packages/react-native/sdks/hermes/build_macosx - - ~/react-native/packages/react-native/sdks/hermes/destroot - hermes_tarball_cache_paths: &hermes_tarball_cache_paths - - *hermes_tarball_artifacts_dir - - # ------------------------- - # Filters - # ------------------------- - # CircleCI filters are OR-ed, with all branches triggering by default and tags excluded by default - # CircleCI env-vars are only set with the branch OR tag that triggered the job, not both. - - # In this case, CIRCLE_BRANCH is unset, but CIRCLE_TAG is set. - only_release_tags: &only_release_tags - # Both of the following conditions must be included! - # Ignore any commit on any branch by default. - branches: - ignore: /.*/ - # Only act on version tags. - tags: - only: /v[0-9]+(\.[0-9]+)*(\-rc(\.[0-9]+)?)?/ - -# ------------------------- -# PIPELINE PARAMETERS -# ------------------------- -parameters: - run_release_workflow: - default: false - type: boolean - - run_nightly_workflow: - default: false - type: boolean - - release_version: - default: "" - type: string - - release_monorepo_packages_version: - default: "" - type: string - - release_tag: - default: "" - type: string - - release_dry_run: - default: false - type: boolean diff --git a/.circleci/configurations/workflows.yml b/.circleci/configurations/workflows.yml deleted file mode 100644 index ff50d9ac6dc873..00000000000000 --- a/.circleci/configurations/workflows.yml +++ /dev/null @@ -1,89 +0,0 @@ -# ------------------------- -# WORKFLOWS -# -# When creating a new workflow, make sure to include condition: -# -# when: -# and: -# - equal: [ false, << pipeline.parameters.run_release_workflow >> ] -# - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] -# -# It's setup this way so we can trigger a release via a POST -# See limitations: https://support.circleci.com/hc/en-us/articles/360050351292-How-to-trigger-a-workflow-via-CircleCI-API-v2 -# ------------------------- - -workflows: - version: 2 - - # Release workflow, triggered by `yarn trigger-react-native-release` - create_release: - when: << pipeline.parameters.run_release_workflow >> - jobs: - - prepare_release: - name: prepare_release - version: << pipeline.parameters.release_version >> - monorepo_packages_version: << pipeline.parameters.release_monorepo_packages_version >> - tag: << pipeline.parameters.release_tag >> - dry_run: << pipeline.parameters.release_dry_run >> - - # This job will run only when a tag is published due to all the jobs being filtered. - publish_release: - jobs: - - prepare_hermes_workspace: - filters: *only_release_tags - - build_android: - filters: *only_release_tags - name: build_android_for_release - release_type: "release" - - build_hermesc_linux: - filters: *only_release_tags - requires: - - prepare_hermes_workspace - - build_hermesc_apple: - filters: *only_release_tags - requires: - - prepare_hermes_workspace - - build_apple_slices_hermes: - filters: *only_release_tags - requires: - - build_hermesc_apple - matrix: - parameters: - flavor: ["Debug", "Release"] - slice: ["macosx", "iphoneos", "iphonesimulator", "catalyst"] - - build_hermesc_windows: - filters: *only_release_tags - requires: - - prepare_hermes_workspace - - build_hermes_macos: - filters: *only_release_tags - requires: - - build_apple_slices_hermes - matrix: - parameters: - flavor: ["Debug", "Release"] - # This job will trigger when a version tag is pushed (by package_release) - - build_npm_package: - name: build_and_publish_npm_package - release_type: "release" - filters: *only_release_tags - requires: - - build_android_for_release - - build_hermesc_linux - - build_hermes_macos - - build_hermesc_windows - - poll_maven: - requires: - - build_and_publish_npm_package - - analysis: - when: - and: - - equal: [ false, << pipeline.parameters.run_release_workflow >> ] - - equal: [ false, << pipeline.parameters.run_nightly_workflow >> ] - jobs: - # Run lints on every commit - - analyze_code - - # Run code checks on PRs - - analyze_pr diff --git a/.eslintrc.js b/.eslintrc.js index d1335831550f5b..4c434aab38a98b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -34,13 +34,6 @@ module.exports = { 'no-undef': 0, }, }, - { - files: ['*.js', '*.js.flow'], - excludedFiles: ['packages/react-native/template/**/*'], - rules: { - 'lint/sort-imports': 1, - }, - }, { files: ['package.json'], parser: 'jsonc-eslint-parser', diff --git a/.flowconfig b/.flowconfig index 55643d39e942e9..931b2077d03820 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,6 +1,5 @@ [ignore] -; Ignore templates for 'react-native init' -/packages/react-native/template/.* +; Ignore build cache folder /packages/react-native/sdks/.* ; Ignore the codegen e2e tests @@ -62,7 +61,7 @@ munge_underscores=true module.name_mapper='^react-native$' -> '/packages/react-native/index.js' module.name_mapper='^react-native/\(.*\)$' -> '/packages/react-native/\1' module.name_mapper='^@react-native/dev-middleware$' -> '/packages/dev-middleware' -module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '/packages/react-native/Libraries/Image/RelativeImageStub' +module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\|xml\)$' -> '/packages/react-native/Libraries/Image/RelativeImageStub' suppress_type=$FlowIssue suppress_type=$FlowFixMe @@ -91,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.238.0 +^0.245.2 diff --git a/.github/actions/build-android/action.yml b/.github/actions/build-android/action.yml new file mode 100644 index 00000000000000..cf2367f647e32c --- /dev/null +++ b/.github/actions/build-android/action.yml @@ -0,0 +1,109 @@ +name: build-android +description: This action builds android +inputs: + release-type: + required: true + description: The type of release we are building. It could be nightly, release or dry-run + run-e2e-tests: + default: 'false' + description: If we need to build to run E2E tests. If yes, we need to build also x86. +runs: + using: composite + steps: + - name: Setup git safe folders + shell: bash + run: git config --global --add safe.directory '*' + - name: Setup node.js + uses: ./.github/actions/setup-node + - name: Install node dependencies + uses: ./.github/actions/yarn-install-with-cache + - name: Set React Native Version + shell: bash + run: node ./scripts/releases/set-rn-artifacts-version.js --build-type ${{ inputs.release-type }} + - name: Setup gradle + uses: ./.github/actions/setup-gradle + with: + cache-read-only: "false" + - name: Restore Android ccache + uses: actions/cache/restore@v4 + with: + path: /github/home/.cache/ccache + key: v1-ccache-android-${{ github.job }}-${{ github.ref }} + restore-keys: | + v1-ccache-android-${{ github.job }}- + v1-ccache-android- + - name: Show ccache stats + shell: bash + run: ccache -s -v + - name: Build and publish all the Android Artifacts to /tmp/maven-local + shell: bash + run: | + if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then + # dry-run: we only build ARM64 to save time/resources. For release/nightlies the default is to build all archs. + if [[ "${{ inputs.run-e2e-tests }}" == 'true' ]]; then + export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a,x86" # x86 is required for E2E testing + else + export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" + fi + TASKS="publishAllToMavenTempLocal build" + elif [[ "${{ inputs.release-type }}" == "nightly" ]]; then + # nightly: we set isSnapshot to true so artifacts are sent to the right repository on Maven Central. + export ORG_GRADLE_PROJECT_isSnapshot="true" + TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build" + else + # release: we want to build all archs (default) + TASKS="publishAllToMavenTempLocal publishAndroidToSonatype build" + fi + ./gradlew $TASKS -PenableWarningsAsErrors=true + - name: Save Android ccache + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} + uses: actions/cache/save@v4 + with: + path: /github/home/.cache/ccache + key: v1-ccache-android-${{ github.job }}-${{ github.ref }} + - name: Show ccache stats + shell: bash + run: ccache -s -v + - name: Upload Maven Artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: maven-local + path: /tmp/maven-local + - name: Upload test results + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: build-android-results + compression-level: 1 + path: | + packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports + packages/react-native-gradle-plugin/settings-plugin/build/reports + packages/react-native/ReactAndroid/build/reports + - name: Upload RNTester APK - hermes-debug + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: rntester-hermes-debug + path: packages/rn-tester/android/app/build/outputs/apk/hermes/debug/ + compression-level: 0 + - name: Upload RNTester APK - hermes-release + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: rntester-hermes-release + path: packages/rn-tester/android/app/build/outputs/apk/hermes/release/ + compression-level: 0 + - name: Upload RNTester APK - jsc-debug + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: rntester-jsc-debug + path: packages/rn-tester/android/app/build/outputs/apk/jsc/debug/ + compression-level: 0 + - name: Upload RNTester APK - jsc-release + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: rntester-jsc-release + path: packages/rn-tester/android/app/build/outputs/apk/jsc/release/ + compression-level: 0 diff --git a/.github/actions/build-apple-slices-hermes/action.yml b/.github/actions/build-apple-slices-hermes/action.yml new file mode 100644 index 00000000000000..4f6b30679e2dea --- /dev/null +++ b/.github/actions/build-apple-slices-hermes/action.yml @@ -0,0 +1,103 @@ +name: build-apple-slices-hermes +description: This action builds hermesc for Apple platforms +inputs: + hermes-version: + required: true + description: The version of Hermes + react-native-version: + required: true + description: The version of Hermes + slice: + required: true + description: The slice of hermes you want to build. It could be iphone, iphonesimulator, macos, catalyst, xros, or xrossimulator + flavor: + required: true + description: The flavor we want to build. It can be Debug or Release +runs: + using: composite + steps: + - name: Setup xcode + uses: ./.github/actions/setup-xcode + - name: Restore Hermes workspace + uses: ./.github/actions/restore-hermes-workspace + - name: Restore HermesC Artifact + uses: actions/download-artifact@v4 + with: + name: hermesc-apple + path: ./packages/react-native/sdks/hermes/build_host_hermesc + - name: Restore Slice From Cache + id: restore-slice-cache + uses: actions/cache/restore@v4 + with: + path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }} + key: v6-hermes-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ inputs.slice }}-${{ inputs.flavor }} + - name: Build the Hermes ${{ inputs.slice }} frameworks + shell: bash + run: | + cd ./packages/react-native/sdks/hermes || exit 1 + SLICE=${{ inputs.slice }} + FLAVOR=${{ inputs.flavor }} + FINAL_PATH=build_"$SLICE"_"$FLAVOR" + echo "Final path for this slice is: $FINAL_PATH" + + if [[ -d "$FINAL_PATH" ]]; then + echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH". + exit 0 + fi + + if [[ "$ARTIFACTS_EXIST" ]]; then + echo "[HERMES] Skipping! Artifacts exists already." + exit 0 + fi + + export RELEASE_VERSION=${{ inputs.react-native-version }} + + # HermesC is used to build hermes, so it has to be executable + chmod +x ./build_host_hermesc/bin/hermesc + + if [[ "$SLICE" == "macosx" ]]; then + echo "[HERMES] Building Hermes for MacOS" + + chmod +x ./utils/build-mac-framework.sh + BUILD_TYPE="${{ inputs.flavor }}" ./utils/build-mac-framework.sh + else + echo "[HERMES] Building Hermes for iOS: $SLICE" + + chmod +x ./utils/build-ios-framework.sh + BUILD_TYPE="${{ inputs.flavor }}" ./utils/build-ios-framework.sh "$SLICE" + fi + + echo "Moving from build_$SLICE to $FINAL_PATH" + mv build_"$SLICE" "$FINAL_PATH" + + # check whether everything is there + if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then + echo "Successfully built hermes.framework for $SLICE in $FLAVOR" + else + echo "Failed to built hermes.framework for $SLICE in $FLAVOR" + exit 1 + fi + + if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then + echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR" + else + echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR" + echo "Please try again" + exit 1 + fi + - name: Compress slices to preserve Symlinks + shell: bash + run: | + cd ./packages/react-native/sdks/hermes + tar -czv -f build_${{ matrix.slice }}_${{ matrix.flavor }}.tar.gz build_${{ matrix.slice }}_${{ matrix.flavor }} + - name: Upload Artifact for Slice (${{ inputs.slice }}, ${{ inputs.flavor }}} + uses: actions/upload-artifact@v4.3.4 + with: + name: slice-${{ inputs.slice }}-${{ inputs.flavor }} + path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }}.tar.gz + - name: Save slice cache + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode. + uses: actions/cache/save@v4 + with: + path: ./packages/react-native/sdks/hermes/build_${{ inputs.slice }}_${{ inputs.flavor }} + key: v6-hermes-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ inputs.SLICE }}-${{ inputs.FLAVOR }} diff --git a/.github/actions/build-hermes-macos/action.yml b/.github/actions/build-hermes-macos/action.yml new file mode 100644 index 00000000000000..daa6b3391450ed --- /dev/null +++ b/.github/actions/build-hermes-macos/action.yml @@ -0,0 +1,207 @@ +name: build-hermes-macos +description: This action builds hermesc for Apple platforms +inputs: + hermes-version: + required: true + description: The version of Hermes + react-native-version: + required: true + description: The version of React Native + flavor: + required: true + description: The flavor we want to build. It can be Debug or Release +runs: + using: composite + steps: + - name: Setup xcode + uses: ./.github/actions/setup-xcode + - name: Setup node.js + uses: ./.github/actions/setup-node + - name: Restore Hermes workspace + uses: ./.github/actions/restore-hermes-workspace + - name: Restore Cached Artifacts + uses: actions/cache/restore@v4 + with: + key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + path: | + /tmp/hermes/osx-bin/${{ inputs.flavor }} + /tmp/hermes/dSYM/${{ inputs.flavor }} + /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz + - name: Check if the required artifacts already exist + id: check_if_apple_artifacts_are_there + shell: bash + run: | + FLAVOR="${{ inputs.flavor }}" + echo "Flavor is $FLAVOR" + OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" + DSYM="/tmp/hermes/dSYM/$FLAVOR" + HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" + + if [[ -d "$OSX_BIN" ]] && \ + [[ -d "$DSYM" ]] && \ + [[ -f "$HERMES" ]]; then + + echo "Artifacts are there!" + echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV + echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT + fi + - name: Yarn- Install Dependencies + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: ./.github/actions/yarn-install-with-cache + - name: Slice cache macosx + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-macosx-${{ inputs.flavor }} + - name: Slice cache iphoneos + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-iphoneos-${{ inputs.flavor }} + - name: Slice cache iphonesimulator + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-iphonesimulator-${{ inputs.flavor }} + - name: Slice cache catalyst + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-catalyst-${{ inputs.flavor }} + - name: Slice cache xros + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-xros-${{ inputs.flavor }} + - name: Slice cache xrsimulator + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + uses: actions/download-artifact@v4 + with: + path: ./packages/react-native/sdks/hermes/ + name: slice-xrsimulator-${{ inputs.flavor }} + - name: Unzip slices + shell: bash + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + run: | + cd ./packages/react-native/sdks/hermes + ls -l . + tar -xzv -f build_catalyst_${{ matrix.flavor }}.tar.gz + tar -xzv -f build_iphoneos_${{ matrix.flavor }}.tar.gz + tar -xzv -f build_iphonesimulator_${{ matrix.flavor }}.tar.gz + tar -xzv -f build_macosx_${{ matrix.flavor }}.tar.gz + tar -xzv -f build_xros_${{ matrix.flavor }}.tar.gz + tar -xzv -f build_xrsimulator_${{ matrix.flavor }}.tar.gz + - name: Move back build folders + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + shell: bash + run: | + ls -l ./packages/react-native/sdks/hermes + cd ./packages/react-native/sdks/hermes || exit 1 + mv build_macosx_${{ inputs.flavor }} build_macosx + mv build_iphoneos_${{ inputs.flavor }} build_iphoneos + mv build_iphonesimulator_${{ inputs.flavor }} build_iphonesimulator + mv build_catalyst_${{ inputs.flavor }} build_catalyst + mv build_xros_${{ inputs.flavor }} build_xros + mv build_xrsimulator_${{ inputs.flavor }} build_xrsimulator + - name: Prepare destroot folder + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + shell: bash + run: | + cd ./packages/react-native/sdks/hermes || exit 1 + chmod +x ./utils/build-apple-framework.sh + . ./utils/build-apple-framework.sh + prepare_dest_root_for_ci + - name: Create fat framework for iOS + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + shell: bash + run: | + cd ./packages/react-native/sdks/hermes || exit 1 + echo "[HERMES] Creating the universal framework" + chmod +x ./utils/build-ios-framework.sh + ./utils/build-ios-framework.sh build_framework + + chmod +x ./destroot/bin/hermesc + - name: Package the Hermes Apple frameworks + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + shell: bash + run: | + BUILD_TYPE="${{ inputs.flavor }}" + echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" + + TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX) + + TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") + + echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" + + TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \ + --inputDir ./packages/react-native/sdks/hermes \ + --buildType "$BUILD_TYPE" \ + --outputDir $TARBALL_OUTPUT_DIR) + + echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH" + + mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR + cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/. + + mkdir -p /tmp/hermes/osx-bin/${{ inputs.flavor }} + cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ inputs.flavor }} + ls -lR /tmp/hermes/osx-bin/ + - name: Create dSYM archive + if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != 'true' }} + shell: bash + run: | + FLAVOR=${{ inputs.flavor }} + WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR" + + mkdir -p "$WORKING_DIR/macosx" + mkdir -p "$WORKING_DIR/catalyst" + mkdir -p "$WORKING_DIR/iphoneos" + mkdir -p "$WORKING_DIR/iphonesimulator" + mkdir -p "$WORKING_DIR/xros" + mkdir -p "$WORKING_DIR/xrsimulator" + + cd ./packages/react-native/sdks/hermes || exit 1 + + DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM + cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/" + cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" + cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" + cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" + cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" + cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" + + DEST_DIR="/tmp/hermes/dSYM/$FLAVOR" + tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" . + + mkdir -p "$DEST_DIR" + mv "hermes.framework.dSYM" "$DEST_DIR" + - name: Upload hermes dSYM artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-dSYM-${{ inputs.flavor }} + path: /tmp/hermes/dSYM/${{ inputs.flavor }} + - name: Upload hermes Runtime artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-darwin-bin-${{ inputs.flavor }} + path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz + - name: Upload hermes osx artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-osx-bin-${{ inputs.flavor }} + path: /tmp/hermes/osx-bin/${{ inputs.flavor }} + - name: Upload Hermes Artifacts + uses: actions/cache/save@v4 + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode. + with: + key: v4-hermes-artifacts-${{ inputs.flavor }}-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + path: | + /tmp/hermes/osx-bin/${{ inputs.flavor }} + /tmp/hermes/dSYM/${{ inputs.flavor }} + /tmp/hermes/hermes-runtime-darwin/hermes-ios-${{ inputs.flavor }}.tar.gz diff --git a/.github/actions/build-hermesc-apple/action.yml b/.github/actions/build-hermesc-apple/action.yml new file mode 100644 index 00000000000000..dba2cb37c1b3c1 --- /dev/null +++ b/.github/actions/build-hermesc-apple/action.yml @@ -0,0 +1,37 @@ +name: build-hermesc-apple +description: This action builds hermesc for Apple platforms +inputs: + hermes-version: + required: true + description: The version of Hermes + react-native-version: + required: true + description: The version of React Native +runs: + using: composite + steps: + - name: Restore Hermes workspace + uses: ./.github/actions/restore-hermes-workspace + - name: Hermes apple cache + uses: actions/cache/restore@v4 + with: + path: ./packages/react-native/sdks/hermes/build_host_hermesc + key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + - name: Build HermesC Apple + shell: bash + run: | + cd ./packages/react-native/sdks/hermes || exit 1 + . ./utils/build-apple-framework.sh + build_host_hermesc_if_needed + - name: Upload HermesC Artifact + uses: actions/upload-artifact@v4.3.4 + with: + name: hermesc-apple + path: ./packages/react-native/sdks/hermes/build_host_hermesc + - name: Cache hermesc apple + uses: actions/cache/save@v4 + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, '-stable') }} # To avoid that the cache explode. + with: + path: ./packages/react-native/sdks/hermes/build_host_hermesc + key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + enableCrossOsArchive: true diff --git a/.github/actions/build-hermesc-linux/action.yml b/.github/actions/build-hermesc-linux/action.yml new file mode 100644 index 00000000000000..5c2298ea83bc50 --- /dev/null +++ b/.github/actions/build-hermesc-linux/action.yml @@ -0,0 +1,49 @@ +name: build-hermesc-linux +description: This action builds hermesc for linux platforms +inputs: + hermes-version: + required: True + description: The version of Hermes + react-native-version: + required: True + description: The version of React Native +runs: + using: composite + steps: + - name: Install dependencies + shell: bash + run: | + sudo apt update + sudo apt install -y git openssh-client cmake build-essential \ + libreadline-dev libicu-dev jq zip python3 + - name: Restore Hermes workspace + uses: ./.github/actions/restore-hermes-workspace + - name: Linux cache + uses: actions/cache@v4 + with: + key: v1-hermes-${{ github.job }}-linux-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + path: | + /tmp/hermes/linux64-bin/ + /tmp/hermes/hermes/destroot/ + - name: Set up workspace + shell: bash + run: | + mkdir -p /tmp/hermes/linux64-bin + - name: Build HermesC for Linux + shell: bash + run: | + if [ -f /tmp/hermes/linux64-bin/hermesc ]; then + echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.' + else + cd /tmp/hermes + cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \ + -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \ + -DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive" + cmake --build build --target hermesc -j 4 + cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. + fi + - name: Upload linux artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-linux-bin + path: /tmp/hermes/linux64-bin diff --git a/.github/actions/build-hermesc-windows/action.yml b/.github/actions/build-hermesc-windows/action.yml new file mode 100644 index 00000000000000..743e820942fca0 --- /dev/null +++ b/.github/actions/build-hermesc-windows/action.yml @@ -0,0 +1,86 @@ +name: build-hermesc-windows +description: This action builds hermesc for Windows platforms +inputs: + hermes-version: + required: True + description: The version of Hermes + react-native-version: + required: True + description: The version of React Native +runs: + using: composite + steps: + - name: Download Previous Artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-workspace + path: 'D:\tmp\hermes' + - name: Set up workspace + shell: powershell + run: | + mkdir -p D:\tmp\hermes\osx-bin + mkdir -p .\packages\react-native\sdks\hermes + cp -r -Force D:\tmp\hermes\hermes\* .\packages\react-native\sdks\hermes\. + cp -r -Force .\packages\react-native\sdks\hermes-engine\utils\* .\packages\react-native\sdks\hermes\. + - name: Windows cache + uses: actions/cache@v4 + with: + key: v2-hermes-${{ github.job }}-windows-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} + path: | + D:\tmp\hermes\win64-bin\ + D:\tmp\hermes\hermes\icu\ + D:\tmp\hermes\hermes\deps\ + D:\tmp\hermes\hermes\build_release\ + - name: setup-msbuild + uses: microsoft/setup-msbuild@v1.3.2 + - name: Set up workspace + shell: powershell + run: | + New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu + New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps + New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin + - name: Build HermesC for Windows + shell: powershell + run: | + if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) { + choco install --no-progress cmake --version 3.14.7 + if (-not $?) { throw "Failed to install CMake" } + + cd $Env:HERMES_WS_DIR\icu + # If Invoke-WebRequest shows a progress bar, it will fail with + # Win32 internal error "Access is denied" 0x5 occurred [...] + $progressPreference = 'silentlyContinue' + Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip" + Expand-Archive -Path "icu.zip" -DestinationPath "." + + cd $Env:HERMES_WS_DIR + Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps" + # Include MSVC++ 2015 redistributables + Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps" + Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps" + Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps" + + $Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR" + $Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu" + + cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF + if (-not $?) { throw "Failed to configure Hermes" } + echo "Running windows build..." + cd build_release + cmake --build . --target hermesc --config Release + if (-not $?) { throw "Failed to build Hermes" } + + echo "Copying hermesc.exe to win64-bin" + cd $Env:HERMES_WS_DIR + Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin" + # Include Windows runtime dependencies + Copy-Item -Path "deps\*" -Destination "win64-bin" + } + else { + Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild." + } + - name: Upload windows artifacts + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-win64-bin + path: D:\tmp\hermes\win64-bin\ diff --git a/.github/actions/build-npm-package/action.yml b/.github/actions/build-npm-package/action.yml new file mode 100644 index 00000000000000..295868a376bbe3 --- /dev/null +++ b/.github/actions/build-npm-package/action.yml @@ -0,0 +1,148 @@ +name: build-npm-package +description: This action builds the NPM package and uploads it to Maven +inputs: + release-type: + required: true + description: The type of release we are building. It could be nightly, release or dry-run + hermes-ws-dir: + required: 'true' + description: The workspace for hermes + gha-npm-token: + required: false + description: The GHA npm token, required only to publish to npm + default: '' +runs: + using: composite + steps: + - name: Setup git safe folders + shell: bash + run: git config --global --add safe.directory '*' + - name: Create /tmp/hermes/osx-bin directory + shell: bash + run: mkdir -p /tmp/hermes/osx-bin + - name: Download osx-bin release artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-osx-bin-Release + path: /tmp/hermes/osx-bin/Release + - name: Download osx-bin debug artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-osx-bin-Debug + path: /tmp/hermes/osx-bin/Debug + - name: Download darwin-bin release artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-darwin-bin-Release + path: /tmp/hermes/hermes-runtime-darwin + - name: Download darwin-bin debug artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-darwin-bin-Debug + path: /tmp/hermes/hermes-runtime-darwin + - name: Download hermes dSYM debug artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-dSYM-Debug + path: /tmp/hermes/dSYM/Debug + - name: Download hermes dSYM release vartifacts + uses: actions/download-artifact@v4 + with: + name: hermes-dSYM-Release + path: /tmp/hermes/dSYM/Release + - name: Download windows-bin artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-win64-bin + path: /tmp/hermes/win64-bin + - name: Download linux-bin artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-linux-bin + path: /tmp/hermes/linux64-bin + - name: Show /tmp/hermes directory + shell: bash + run: ls -lR /tmp/hermes + - name: Copy Hermes binaries + shell: bash + run: | + mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin + + # When build_hermes_macos runs as a matrix, it outputs + if [[ -d ${{ inputs.hermes-ws-dir }}/osx-bin/Release ]]; then + cp -r ${{ inputs.hermes-ws-dir }}/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/. + elif [[ -d ${{ inputs.hermes-ws-dir }}/osx-bin/Debug ]]; then + cp -r ${{ inputs.hermes-ws-dir }}/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/. + else + ls ${{ inputs.hermes-ws-dir }}/osx-bin || echo "hermesc macOS artifacts directory missing." + echo "Could not locate macOS hermesc binary."; exit 1; + fi + + # Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them. + if [[ -f "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then + mv "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" + fi + + if [[ -f "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then + mv "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-release.tar.gz" "${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Release.tar.gz" + fi + + cp -r ${{ inputs.hermes-ws-dir }}/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/. + cp -r ${{ inputs.hermes-ws-dir }}/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/. + + # Make sure the hermesc files are actually executable. + chmod -R +x packages/react-native/sdks/hermesc/* + + mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/ + cp ${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz + cp ${{ inputs.hermes-ws-dir }}/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz + cp ${{ inputs.hermes-ws-dir }}/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz + cp ${{ inputs.hermes-ws-dir }}/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz + - name: Setup node.js + uses: ./.github/actions/setup-node + - name: Setup gradle + uses: ./.github/actions/setup-gradle + - name: Install dependencies + uses: ./.github/actions/yarn-install-with-cache + - name: Build packages + shell: bash + run: yarn build + # Continue with publish steps + - name: Set npm credentials + if: ${{ inputs.release-type == 'release' || + inputs.release-type == 'nightly' }} + shell: bash + run: echo "//registry.npmjs.org/:_authToken=${{ inputs.gha-npm-token }}" > ~/.npmrc + - name: Publish NPM + shell: bash + run: | + echo "GRADLE_OPTS = $GRADLE_OPTS" + # We can't have a separate step because each command is executed in a separate shell + # so variables exported in a command are not visible in another. + if [[ "${{ inputs.release-type }}" == "dry-run" ]]; then + export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" + else + export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" + fi + node ./scripts/releases-ci/publish-npm.js -t ${{ inputs.release-type }} + - name: Upload npm logs + uses: actions/upload-artifact@v4.3.4 + with: + name: npm-logs + path: ~/.npm/_logs + - name: Build release package as a job artifact + if: ${{ inputs.release-type == 'dry-run' }} + shell: bash + run: | + mkdir -p build + + FILENAME=$(cd packages/react-native; npm pack | tail -1) + mv "packages/react-native/$FILENAME" build/ + + echo "$FILENAME" > build/react-native-package-version + - name: Upload release package + uses: actions/upload-artifact@v4.3.4 + if: ${{ inputs.release-type == 'dry-run' }} + with: + name: react-native-package + path: build diff --git a/.github/actions/cache_setup/action.yml b/.github/actions/cache_setup/action.yml deleted file mode 100644 index 7258313b8ca2b9..00000000000000 --- a/.github/actions/cache_setup/action.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: cache_setup -description: "Cache setup" -inputs: - hermes-version: - description: "Hermes version" - required: true - react-native-version: - description: "React Native version" - required: true -outputs: - cache-hit-hermes-tarball-release: - description: "Whether the hermes tarball release cache was hit" - value: ${{ steps.cache_hermes_tarball_release.outputs.cache-hit }} - cache-hit-hermes-tarball-debug: - description: "Whether the hermes tarball debug cache was hit" - value: ${{ steps.cache_hermes_tarball_debug.outputs.cache-hit }} - cache-hit-macos-bin-release: - description: "Whether the macos bin release cache was hit" - value: ${{ steps.cache_macos_bin_release.outputs.cache-hit }} - cache-hit-macos-bin-debug: - description: "Whether the macos bin debug cache was hit" - value: ${{ steps.cache_macos_bin_debug.outputs.cache-hit }} - cache-hit-dsym-release: - description: "Whether the dsym release cache was hit" - value: ${{ steps.cache_dsym_release.outputs.cache-hit }} - cache-hit-dsym-debug: - description: "Whether the dsym debug cache was hit" - value: ${{ steps.cache_dsym_debug.outputs.cache-hit }} -runs: - using: composite - steps: - - name: Cache hermes tarball release - id: cache_hermes_tarball_release - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-Release.tar.gz - key: v4-hermes-tarball-release-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }} - enableCrossOsArchive: true - - name: Cache hermes tarball debug - id: cache_hermes_tarball_debug - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/hermes-runtime-darwin/hermes-ios-Debug.tar.gz - key: v4-hermes-tarball-debug-${{ inputs.hermes-version }}-${{ inputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }} - enableCrossOsArchive: true - - name: Cache macos bin release - id: cache_macos_bin_release - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/osx-bin/Release - key: v2-hermes-release-macosx-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} - enableCrossOsArchive: true - - name: Cache macos bin debug - id: cache_macos_bin_debug - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/osx-bin/Debug - key: v2-hermes-debug-macosx-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} - enableCrossOsArchive: true - - name: Cache dsym release - id: cache_dsym_release - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/dSYM/Release - key: v2-hermes-release-dsym-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} - enableCrossOsArchive: true - - name: Cache dsym debug - id: cache_dsym_debug - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/dSYM/Debug - key: v2-hermes-debug-dsym-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} - enableCrossOsArchive: true - - name: HermesC Apple - id: hermesc_apple - uses: actions/cache@v4.0.0 - with: - path: /tmp/hermes/hermesc-apple - key: v2-hermesc-apple-${{ inputs.hermes-version }}-${{ inputs.react-native-version }} - enableCrossOsArchive: true - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 - with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ inputs.hermes-version }}-${{ github.run_number }} - enableCrossOsArchive: true diff --git a/.github/actions/create-release/action.yml b/.github/actions/create-release/action.yml index cce43d9348ba82..0d0f2055f0359e 100644 --- a/.github/actions/create-release/action.yml +++ b/.github/actions/create-release/action.yml @@ -1,29 +1,44 @@ name: create_release description: Creates a new React Native release +inputs: + version: + description: "The version of React Native we want to release. For example 0.75.0-rc.0" + required: true + is-latest-on-npm: + description: "Whether we want to tag this release as latest on NPM" + required: true + default: "false" + dry-run: + description: "Whether the job should be executed in dry-run mode or not" + default: "true" runs: using: composite steps: - name: Yarn install + uses: ./.github/actions/yarn-install-with-cache + - name: Configure Git shell: bash - run: yarn install --non-interactive + run: | + git config --local user.email "bot@reactnative.dev" + git config --local user.name "React Native Bot" - name: Creating release commit shell: bash run: | node scripts/releases/create-release-commit.js \ --reactNativeVersion "${{ inputs.version }}" \ - --tagAsLatestRelease "${{ inputs.is_latest_on_npm }}" \ - --dryRun "${{ inputs.dry_run }}" + --tagAsLatestRelease "${{ inputs.is-latest-on-npm }}" \ + --dryRun "${{ inputs.dry-run }}" GIT_PAGER=cat git show HEAD - name: Update "latest" tag if needed shell: bash - if: ${{ inputs.tag == 'latest' }} + if: ${{ inputs.is-latest-on-npm == 'true' }} run: | git tag -d "latest" git push origin :latest git tag -a "latest" -m "latest" - name: Pushing release commit shell: bash - if: ${{ inputs.dry_run == false }} + if: ${{ inputs.dry-run == 'false' }} run: | CURR_BRANCH="$(git branch --show-current)" git push origin "$CURR_BRANCH" --follow-tags diff --git a/.github/actions/lint/action.yml b/.github/actions/lint/action.yml new file mode 100644 index 00000000000000..667b990029b8ed --- /dev/null +++ b/.github/actions/lint/action.yml @@ -0,0 +1,43 @@ +name: lint +description: Runs all the linters in the codebase +inputs: + node-version: + description: "The node.js version to use" + required: false + default: "18" + github-token: + description: "The GitHub token used by pull-bot" + required: true +runs: + using: composite + steps: + - name: Setup node.js + uses: ./.github/actions/setup-node + with: + node-version: ${{ inputs.node-version }} + - name: Yarn install + shell: bash + run: yarn install --non-interactive --frozen-lockfile + - name: Run linters against modified files (analysis-bot) + shell: bash + run: yarn lint-ci + env: + GITHUB_TOKEN: ${{ inputs.github-token }} + - name: Lint code + shell: bash + run: ./scripts/circleci/exec_swallow_error.sh yarn lint --format junit -o ./reports/junit/eslint/results.xml + - name: Lint java + shell: bash + run: ./scripts/circleci/exec_swallow_error.sh yarn lint-java --check + - name: Run flowcheck + shell: bash + run: yarn flow-check + - name: Run typescript check + shell: bash + run: yarn test-typescript + - name: Check license + shell: bash + run: ./scripts/circleci/check_license.sh + - name: Check formatting + shell: bash + run: yarn run format-check diff --git a/.github/actions/maestro-android/action.yml b/.github/actions/maestro-android/action.yml new file mode 100644 index 00000000000000..1b34e6efe0e117 --- /dev/null +++ b/.github/actions/maestro-android/action.yml @@ -0,0 +1,70 @@ +name: Maestro E2E Android +description: Runs E2E Tests on iOS using Maestro +inputs: + app-path: + required: true + description: The path to the .apk file + app-id: + required: true + description: The id of the app to test + jsengine: + required: true + description: The js engine we are using + maestro-flow: + required: true + description: the folder that contains the maestro tests + install-java: + required: false + default: 'true' + description: whether this action has to install java 17 or not +runs: + using: composite + steps: + - name: Installing Maestro + shell: bash + run: export MAESTRO_VERSION=1.36.0; curl -Ls "https://get.maestro.mobile.dev" | bash + - name: Set up JDK 17 + if: ${{ inputs.install-java == 'true' }} + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'zulu' + - name: Enable KVM group perms + shell: bash + run: | + # ubuntu machines have hardware acceleration available and when we try to create an emulator, the script pauses asking for user input + # These lines set the rules to reply automatically to that question and unblock the creation of the emulator. + # source: https://github.com/ReactiveCircus/android-emulator-runner?tab=readme-ov-file#running-hardware-accelerated-emulators-on-linux-runners + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + - name: Run e2e tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 24 + arch: x86 + script: | + echo "Install APK from ${{ inputs.app-path }}" + adb install "${{ inputs.app-path }}" + + echo "Start recording to /sdcard/screen.mp4" + adb shell screenrecord /sdcard/screen.mp4 + + echo "Start testing ${{ inputs.maestro-flow }}" + $HOME/.maestro/bin/maestro test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }} --debug-output /tmp/MaestroLogs + + echo "Stop recording. Saving to screen.mp4" + adb pull /sdcard/screen.mp4 + - name: Store tests result + uses: actions/upload-artifact@v3 + with: + name: e2e_android_${{ inputs.app-id }}_report_${{ inputs.jsengine }} + path: | + report.xml + screen.mp4 + - name: Store Logs + if: failure() && steps.run-tests.outcome == 'failure' + uses: actions/upload-artifact@v4.3.4 + with: + name: maestro-logs-android-${{ inputs.app-id }}-${{ inputs.jsengine }} + path: /tmp/MaestroLogs diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml new file mode 100644 index 00000000000000..8379a6d458f6ab --- /dev/null +++ b/.github/actions/maestro-ios/action.yml @@ -0,0 +1,96 @@ +name: Maestro E2E iOS +description: Runs E2E Tests on iOS using Maestro +inputs: + app-path: + required: true + description: The path to the .app file + app-id: + required: true + description: The id of the app to test + jsengine: + required: true + description: The js engine we are using + maestro-flow: + required: true + description: the folder that contains the maestro tests +runs: + using: composite + steps: + - name: Installing Maestro + shell: bash + run: export MAESTRO_VERSION=1.36.0; curl -Ls "https://get.maestro.mobile.dev" | bash + - name: Installing Maestro dependencies + shell: bash + run: | + brew tap facebook/fb + brew install facebook/fb/idb-companion jq + - name: Set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'zulu' + - name: Run tests + id: run-tests + shell: bash + run: | + # Avoid exit from the job if one of the command returns an error. + # Maestro can fail in case of flakyness, we have some retry logic. + set +e + + echo "Launching iOS Simulator: iPhone 15 Pro" + xcrun simctl boot "iPhone 15 Pro" + + echo "Installing app on Simulator" + xcrun simctl install booted "${{ inputs.app-path }}" + + echo "Retrieving device UDID" + UDID=$(xcrun simctl list devices booted -j | jq -r '[.devices[]] | add | first | .udid') + echo "UDID is $UDID" + + echo "Bring simulator in foreground" + open -a simulator + + echo "Launch the app" + xcrun simctl launch $UDID ${{ inputs.app-id }} + + echo "Running tests with Maestro" + export MAESTRO_DRIVER_STARTUP_TIMEOUT=1500000 # 25 min. CI is extremely slow + + # Add retries for flakyness + MAX_ATTEMPTS=3 + CURR_ATTEMPT=0 + RESULT=1 + + while [[ $CURR_ATTEMPT -lt $MAX_ATTEMPTS ]] && [[ $RESULT -ne 0 ]]; do + CURR_ATTEMPT=$((CURR_ATTEMPT+1)) + echo "Attempt number $CURR_ATTEMPT" + + echo "Start video record using pid: video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid" + xcrun simctl io booted recordVideo video_record_$CURR_ATTEMPT.mov & echo $! > video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid + + echo '$HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }}' + $HOME/.maestro/bin/maestro --udid=$UDID test ${{ inputs.maestro-flow }} --format junit -e APP_ID=${{ inputs.app-id }} --debug-output /tmp/MaestroLogs + + RESULT=$? + + # Stop video + kill -SIGINT $(cat video_record_${{ inputs.jsengine }}_$CURR_ATTEMPT.pid) + done + + exit $RESULT + - name: Store video record + if: always() + uses: actions/upload-artifact@v4.3.4 + with: + name: e2e_ios_${{ inputs.app-id }}_report_${{ inputs.jsengine }} + path: | + video_record_1.mov + video_record_2.mov + video_record_3.mov + report.xml + - name: Store Logs + if: failure() && steps.run-tests.outcome == 'failure' + uses: actions/upload-artifact@v4.3.4 + with: + name: maestro-logs-${{ inputs.app-id }}-${{ inputs.jsengine }} + path: /tmp/MaestroLogs diff --git a/.github/actions/prepare-hermes-workspace/action.yml b/.github/actions/prepare-hermes-workspace/action.yml new file mode 100644 index 00000000000000..4a5e638790e017 --- /dev/null +++ b/.github/actions/prepare-hermes-workspace/action.yml @@ -0,0 +1,100 @@ +name: prepare-hermes-workspace +description: This action prepares the hermes workspace with the right hermes and react-native versions. +inputs: + hermes-ws-dir: + required: true + description: The hermes dir we need to use to setup the workspace + hermes-version-file: + required: true + description: the path to the file that will contain the hermes version +outputs: + hermes-version: + description: the version of Hermes tied to this run + value: ${{ steps.hermes-version.outputs.VERSION }} + react-native-version: + description: the version of React Native tied to this run + value: ${{ steps.react-native-version.outputs.VERSION }} +runs: + using: composite + steps: + - name: Setup node.js + uses: ./.github/actions/setup-node + + - name: Setup hermes version + shell: bash + id: hermes-version + run: | + mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes" + + if [ -f "${{ inputs.hermes-version-file }}" ]; then + echo "Hermes Version file found! Using this version for the build:" + echo "VERSION=$(cat ${{ inputs.hermes-version-file }})" >> "$GITHUB_OUTPUT" + else + echo "Hermes Version file not found!!!" + echo "Using the last commit from main for the build:" + HERMES_TAG_SHA=$(git ls-remote https://github.com/facebook/hermes main | cut -f 1 | tr -d '[:space:]') + echo "VERSION=$HERMES_TAG_SHA" >> "$GITHUB_OUTPUT" + fi + echo "Hermes commit is $HERMES_TAG_SHA" + + - name: Get react-native version + shell: bash + id: react-native-version + run: | + VERSION=$(cat packages/react-native/package.json | jq -r '.version') + # Save the react native version we are building in an output variable so we can use that file as part of the cache key. + echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" + echo "React Native Version is $VERSION" + + - name: Cache hermes workspace + id: restore-hermes + uses: actions/cache/restore@v4 + with: + path: | + /tmp/hermes/download/ + /tmp/hermes/hermes/ + key: v1-hermes-${{ steps.hermes-version.outputs.version }} + enableCrossOsArchive: true + + # It happened while testing that a cache was created from the right folders + # but those folders where empty. Thus, the next check ensures that we can work with those caches. + - name: Check if cache was meaningful + id: meaningful-cache + shell: bash + run: | + if [[ -d /tmp/hermes/hermes ]] && [[ -n "$(ls -A /tmp/hermes/hermes)" ]]; then + echo "Found a good hermes cache" + echo "HERMES_CACHED=true" >> "$GITHUB_OUTPUT" + fi + + - name: Yarn- Install Dependencies + if: ${{ steps.meaningful-cache.outputs.HERMES_CACHED != 'true' }} + uses: ./.github/actions/yarn-install-with-cache + + - name: Download Hermes tarball + if: ${{ steps.meaningful-cache.outputs.HERMES_CACHED != 'true' }} + shell: bash + run: | + node packages/react-native/scripts/hermes/prepare-hermes-for-build ${{ github.event.pull_request.html_url }} + cp packages/react-native/sdks/download/* ${{ inputs.hermes-ws-dir }}/download/. + cp -r packages/react-native/sdks/hermes/* ${{ inputs.hermes-ws-dir }}/hermes/. + + echo ${{ steps.hermes-version.outputs.version }} + + - name: Upload Hermes artifact + uses: actions/upload-artifact@v4.3.4 + with: + name: hermes-workspace + path: | + /tmp/hermes/download/ + /tmp/hermes/hermes/ + + - name: Cache hermes workspace + uses: actions/cache/save@v4 + if: ${{ github.ref == 'refs/heads/main' }} # To avoid that the cache explode. + with: + path: | + /tmp/hermes/download/ + /tmp/hermes/hermes/ + key: v1-hermes-${{ steps.hermes-version.outputs.version }} + enableCrossOsArchive: true diff --git a/.github/actions/prepare_ios_tests/action.yml b/.github/actions/prepare-ios-tests/action.yml similarity index 96% rename from .github/actions/prepare_ios_tests/action.yml rename to .github/actions/prepare-ios-tests/action.yml index 629ef73263b9f7..daa43b3b64e1b2 100644 --- a/.github/actions/prepare_ios_tests/action.yml +++ b/.github/actions/prepare-ios-tests/action.yml @@ -1,4 +1,4 @@ -name: prepare_ios_tests +name: prepare-ios-tests description: Prepare iOS Tests runs: using: composite diff --git a/.github/actions/report_bundle_size/action.yml b/.github/actions/report_bundle_size/action.yml deleted file mode 100644 index 22ca863f54db98..00000000000000 --- a/.github/actions/report_bundle_size/action.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: report_bundle_size -description: Report bundle size -inputs: - platform: - description: Platform. Either ios or android - default: ios -runs: - using: composite - steps: - - name: Report size of RNTester.app (analysis-bot) - shell: bash - run: GITHUB_TOKEN=${{ secrets.PUBLIC_ANALYSISBOT_GITHUB_TOKEN }} scripts/circleci/report-bundle-size.sh ${{ inputs.platform }} || true diff --git a/.github/actions/setup_hermes_workspace/action.yml b/.github/actions/restore-hermes-workspace/action.yml similarity index 56% rename from .github/actions/setup_hermes_workspace/action.yml rename to .github/actions/restore-hermes-workspace/action.yml index a6fc425be672c9..0b1cb259435785 100644 --- a/.github/actions/setup_hermes_workspace/action.yml +++ b/.github/actions/restore-hermes-workspace/action.yml @@ -1,8 +1,13 @@ -name: setup_hermes_workspace -description: "Setup hermes workspace" +name: restore-hermes-workspace +description: "Restore hermes workspace that has been created in Prepare Hermes Workspace" runs: using: composite steps: + - name: Download Previous Artifacts + uses: actions/download-artifact@v4 + with: + name: hermes-workspace + path: /tmp/hermes - name: Set up workspace shell: bash run: | diff --git a/.github/actions/run_e2e/action.yml b/.github/actions/run_e2e/action.yml deleted file mode 100644 index 5e479ce668d9a6..00000000000000 --- a/.github/actions/run_e2e/action.yml +++ /dev/null @@ -1,17 +0,0 @@ -name: run_e2e -description: "Run End-to-End Tests" -inputs: - platform: - description: "Platform to run tests on" - required: true - default: "js" - retries: - description: "Number of times to retry failed tests" - required: true - default: "3" -runs: - using: composite - steps: - - name: "Run Tests: ${{ inputs.platform }} End-to-End Tests" - run: node ./scripts/e2e/run-ci-e2e-tests.js --${{ inputs.platform }} --retries ${{ inputs.retries }} - shell: bash diff --git a/.github/actions/setup-gradle/action.yml b/.github/actions/setup-gradle/action.yml index 1c8b2e5f3f7fe7..c146592c1911ec 100644 --- a/.github/actions/setup-gradle/action.yml +++ b/.github/actions/setup-gradle/action.yml @@ -1,5 +1,9 @@ name: Setup gradle description: "Set up your GitHub Actions workflow with a specific version of gradle" +inputs: + cache-read-only: + description: "Whether the Gradle Cache should be in read-only mode so this job won't be allowed to write to it" + default: "true" runs: using: "composite" steps: @@ -7,3 +11,10 @@ runs: uses: gradle/actions/setup-gradle@v3 with: gradle-version: wrapper + # We want the Gradle cache to be written only on main/-stable branches run, and only for jobs with `cache-read-only` == false (i.e. `build_android`). + cache-read-only: ${{ (github.ref != 'refs/heads/main' && !contains(github.ref, '-stable')) || inputs.cache-read-only == 'true' }} + # Similarly, for those jobs we want to start with a clean cache so it doesn't grow without limits (this is the negation of the previous condition). + cache-write-only: ${{ (github.ref == 'refs/heads/main' || contains(github.ref, '-stable')) && inputs.cache-read-only != 'true' }} + # Temporarily disabling to try resolve a cache cleanup failure + # gradle-home-cache-cleanup: true + add-job-summary-as-pr-comment: on-failure diff --git a/.github/actions/setup-node/action.yml b/.github/actions/setup-node/action.yml index d69b17c7d21e17..fe041bca1c62a0 100644 --- a/.github/actions/setup-node/action.yml +++ b/.github/actions/setup-node/action.yml @@ -5,15 +5,10 @@ inputs: description: 'The node.js version to use' required: false default: '18' - cache: - description: 'The package manager to use for caching dependencies' - required: false - default: 'yarn' runs: using: "composite" steps: - name: Setup node.js - uses: actions/setup-node@v4.0.0 + uses: actions/setup-node@v4 with: node-version: ${{ inputs.node-version }} - cache: ${{ inputs.cache }} diff --git a/.github/actions/setup_xcode_build_cache/action.yml b/.github/actions/setup-xcode-build-cache/action.yml similarity index 60% rename from .github/actions/setup_xcode_build_cache/action.yml rename to .github/actions/setup-xcode-build-cache/action.yml index 9752487e8ee3c0..cb1018c9a1b471 100644 --- a/.github/actions/setup_xcode_build_cache/action.yml +++ b/.github/actions/setup-xcode-build-cache/action.yml @@ -1,4 +1,4 @@ -name: setup_xcode_build_cache +name: setup-xcode-build-cache description: Add caching to iOS jobs to speed up builds inputs: hermes-version: @@ -17,12 +17,12 @@ runs: YEAR=$(date +"%Y") echo "$WEEK-$YEAR" > /tmp/week_year - name: Cache podfile lock - uses: actions/cache@v4.0.0 + uses: actions/cache@v4 with: path: packages/rn-tester/Podfile.lock - key: v9-podfilelock-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile') }}-{{ hashfiles('/tmp/week_year') }}-${{ inputs.hermes-version}} + key: v11-podfilelock-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ hashfiles('/tmp/week_year') }}-${{ inputs.hermes-version }} - name: Cache cocoapods - uses: actions/cache@v4.0.0 + uses: actions/cache@v4 with: path: packages/rn-tester/Pods - key: v11-cocoapods-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-{{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}} + key: v13-cocoapods-${{ github.job }}-${{ hashfiles('packages/rn-tester/Podfile.lock') }}-${{ hashfiles('packages/rn-tester/Podfile') }}-${{ inputs.hermes-version}} diff --git a/.github/actions/test_ios_helloworld/action.yml b/.github/actions/test-ios-helloworld/action.yml similarity index 63% rename from .github/actions/test_ios_helloworld/action.yml rename to .github/actions/test-ios-helloworld/action.yml index b0e225cf39d80d..c3819ae95270c5 100644 --- a/.github/actions/test_ios_helloworld/action.yml +++ b/.github/actions/test-ios-helloworld/action.yml @@ -1,37 +1,21 @@ -name: test_ios_helloworld +name: test-ios-helloworld description: Test iOS Hello World inputs: jsengine: description: Which JavaScript engine to use. Must be one of "Hermes", "JSC". - type: choice default: Hermes - options: - - JSC - - Hermes use-frameworks: - description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks" - type: choice - default: StaticLibraries - options: - - StaticLibraries - - DynamicFrameworks + description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks" + default: StaticLibraries architecture: - description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup - type: choice + description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup. Must be one of "OldArch" or "NewArch" default: OldArch - options: - - OldArch - - NewArch ruby-version: description: The version of ruby that must be used default: 2.6.10 flavor: description: The flavor of the build. Must be one of "Debug", "Release". - type: choice default: Debug - options: - - Debug - - Release hermes-version: description: The version of hermes required: true @@ -45,17 +29,19 @@ runs: uses: ./.github/actions/setup-xcode - name: Setup node.js uses: ./.github/actions/setup-node - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + - name: Create Hermes folder + shell: bash + run: mkdir -p "$HERMES_WS_DIR" + - name: Download Hermes + uses: actions/download-artifact@v4 with: - hermes-version: ${{ inputs.hermes-version }} - react-native-version: ${{ inputs.react-native-version }} - - name: Run yarn + name: hermes-darwin-bin-${{ inputs.flavor }} + path: /tmp/hermes/hermes-runtime-darwin/ + - name: Print Downloaded hermes shell: bash - run: yarn install --non-interactive - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace + run: ls -lR "$HERMES_WS_DIR" + - name: Run yarn + uses: ./.github/actions/yarn-install-with-cache - name: Setup ruby uses: ruby/setup-ruby@v1.170.0 with: @@ -78,6 +64,17 @@ runs: args+=(--jsvm jsc) yarn bootstrap ios "${args[@]}" | cat else + # Tarball is restored with capital flavors suffix, but somehow the tarball name from JS at line 96 returns as lowercased. + # Let's ensure that the tarballs have the right names + + if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" ]]; then + mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" + fi + + if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz" ]]; then + mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" + fi + BUILD_TYPE="${{ inputs.flavor }}" TARBALL_FILENAME=$(node ../react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") HERMES_PATH="$HERMES_WS_DIR/hermes-runtime-darwin/$TARBALL_FILENAME" @@ -87,6 +84,7 @@ runs: shell: bash run: | cd packages/helloworld + args=() if [[ ${{ inputs.flavor }} == "Release" ]]; then args+=(--prod) diff --git a/.github/actions/test_ios_rntester/action.yml b/.github/actions/test-ios-rntester/action.yml similarity index 72% rename from .github/actions/test_ios_rntester/action.yml rename to .github/actions/test-ios-rntester/action.yml index 3f339734c9dbba..1ab333089d0901 100644 --- a/.github/actions/test_ios_rntester/action.yml +++ b/.github/actions/test-ios-rntester/action.yml @@ -1,12 +1,12 @@ -name: test_ios_rntester +name: test-ios-rntester description: Test iOS RNTester inputs: jsengine: description: Which JavaScript engine to use. Must be one of "Hermes", "JSC". default: Hermes use-frameworks: - description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks" - default: StaticLibraries + description: The dependency building and linking strategy to use. Must be one of "StaticLibraries", "DynamicFrameworks" + default: StaticLibraries architecture: description: The React Native architecture to Test. RNTester has always Fabric enabled, but we want to run integration test with the old arch setup default: NewArch @@ -15,7 +15,7 @@ inputs: default: 2.6.10 run-unit-tests: description: whether unit tests should run or not. - default: false + default: "false" hermes-tarball-artifacts-dir: description: The directory where the hermes tarball artifacts are stored default: /tmp/hermes/hermes-runtime-darwin @@ -28,6 +28,11 @@ inputs: react-native-version: description: The version of react-native required: true + run-e2e-tests: + description: Whether we want to run E2E tests or not + required: false + default: false + runs: using: composite steps: @@ -36,21 +41,19 @@ runs: - name: Setup node.js uses: ./.github/actions/setup-node - name: Run yarn - shell: bash - run: yarn install --non-interactive - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: ./.github/actions/yarn-install-with-cache + - name: Download Hermes + uses: actions/download-artifact@v4 with: - hermes-version: ${{ inputs.hermes-version }} - react-native-version: ${{ inputs.react-native-version }} + name: hermes-darwin-bin-${{ inputs.flavor }} + path: ${{ inputs.hermes-tarball-artifacts-dir }} - name: Setup ruby uses: ruby/setup-ruby@v1.170.0 with: ruby-version: ${{ inputs.ruby-version }} - name: Prepare IOS Tests - if: ${{ inputs.run-unit-tests == true }} - uses: ./.github/actions/prepare_ios_tests + if: ${{ inputs.run-unit-tests == 'true' }} + uses: ./.github/actions/prepare-ios-tests - name: Set HERMES_ENGINE_TARBALL_PATH envvar if Hermes tarball is present shell: bash run: | @@ -82,6 +85,7 @@ runs: if [[ -e $TARBALL_PATH ]]; then tar -xf $TARBALL_PATH echo 'print(HermesInternal?.getRuntimeProperties?.()["OSS Release Version"])' > test.js + chmod +x ./destroot/bin/hermes ./destroot/bin/hermes test.js rm test.js rm -rf destroot @@ -89,7 +93,7 @@ runs: echo 'No Hermes tarball found.' fi - name: Setup xcode build cache - uses: ./.github/actions/setup_xcode_build_cache + uses: ./.github/actions/setup-xcode-build-cache with: hermes-version: ${{ inputs.hermes-version }} - name: Install CocoaPods dependencies @@ -114,19 +118,34 @@ runs: bundle install bundle exec pod install - name: Build RNTester - if: ${{ inputs.run-unit-tests != true }} + if: ${{ inputs.run-unit-tests != 'true' && inputs.run-e2e-tests == 'false' }} shell: bash run: | - xcodebuild build \ + set -o pipefail && xcodebuild build \ -workspace packages/rn-tester/RNTesterPods.xcworkspace \ -scheme RNTester \ - -sdk iphonesimulator + -sdk iphonesimulator | xcbeautify + - name: Build RNTester (E2E Tests) + shell: bash + if: ${{ inputs.run-e2e-tests == 'true' }} + run: | + set -o pipefail && xcodebuild \ + -scheme "RNTester" \ + -workspace packages/rn-tester/RNTesterPods.xcworkspace \ + -configuration "Release" \ + -sdk "iphonesimulator" \ + -destination "generic/platform=iOS Simulator" \ + -derivedDataPath "/tmp/RNTesterBuild" | xcbeautify + + echo "Print path to *.app file" + find "/tmp/RNTesterBuild" -type d -name "*.app" - name: "Run Tests: iOS Unit and Integration Tests" - if: ${{ inputs.run-unit-tests == true }} + if: ${{ inputs.run-unit-tests == 'true' }} shell: bash run: yarn test-ios + - name: Zip Derived data folder - if: ${{ inputs.run-unit-tests == true }} + if: ${{ inputs.run-unit-tests == 'true' }} shell: bash run: | echo "zipping tests results" @@ -134,19 +153,14 @@ runs: XCRESULT_PATH=$(find . -name '*.xcresult') tar -zcvf xcresults.tar.gz $XCRESULT_PATH - name: Upload artifact - uses: actions/upload-artifact@v2.2.4 - if: ${{ inputs.run-unit-tests == true }} + uses: actions/upload-artifact@v4.3.4 + if: ${{ inputs.run-unit-tests == 'true' }} with: name: xcresults path: /Users/distiller/Library/Developer/Xcode/xcresults.tar.gz - - name: Report bundle size - if: ${{ inputs.run-unit-tests == true }} - uses: ./.github/actions/report_bundle_size - with: - platform: ios - name: Store test results - if: ${{ inputs.run-unit-tests == true }} - uses: actions/upload-artifact@v2.2.4 + if: ${{ inputs.run-unit-tests == 'true' }} + uses: actions/upload-artifact@v4.3.4 with: name: test-results path: ./reports/junit diff --git a/.github/actions/test-js/action.yml b/.github/actions/test-js/action.yml new file mode 100644 index 00000000000000..4cb531c46097b7 --- /dev/null +++ b/.github/actions/test-js/action.yml @@ -0,0 +1,26 @@ +name: test-js +description: Runs all the JS tests in the codebase +inputs: + node-version: + description: "The node.js version to use" + required: false + default: "18" +runs: + using: composite + steps: + - name: Setup node.js + uses: ./.github/actions/setup-node + with: + node-version: ${{ inputs.node-version }} + - name: Yarn install + uses: ./.github/actions/yarn-install-with-cache + - name: Run Tests - JavaScript Tests + shell: bash + run: node ./scripts/run-ci-javascript-tests.js --maxWorkers 2 + - name: Upload test results + if: ${{ always() }} + uses: actions/upload-artifact@v4.3.4 + with: + name: test-js-results + compression-level: 1 + path: ./reports/junit diff --git a/.github/actions/yarn-install-with-cache/action.yml b/.github/actions/yarn-install-with-cache/action.yml new file mode 100644 index 00000000000000..8273398acbbea7 --- /dev/null +++ b/.github/actions/yarn-install-with-cache/action.yml @@ -0,0 +1,28 @@ +name: yarn-install-with-cache +inputs: + update-cache: + description: Update the cache, only do this if you are update-node-modules-cache.yml + default: "false" +description: Only update node_modules if on main +runs: + using: composite + steps: + - name: Load node_modules from cache + # Restore for all branches, but save for 'main'. + uses: actions/cache/restore@v4 + with: + path: node_modules/ + key: node-modules-${{ hashFiles('package.json') }} + - name: Install dependencies + shell: bash + run: yarn install --non-interactive + - name: Save node_modules to the cache + if: github.ref == 'refs/heads/main' && inputs.update-cache == 'true' + uses: actions/cache/save@v4 + with: + path: node_modules/ + # We're assuming that variations on branches will slightly vary from main, + # so it's always important to run yarn install --non-interactive after this + # cache is restored. + key: node-modules-v1-${{ hashFiles('package.json') }} + enableCrossOsArchive: true diff --git a/.github/workflows/autorebase.yml b/.github/workflows/autorebase.yml index c7a0fa721dacbc..1a3af07c31a01d 100644 --- a/.github/workflows/autorebase.yml +++ b/.github/workflows/autorebase.yml @@ -24,5 +24,5 @@ jobs: - name: Automatic Rebase uses: cirrus-actions/rebase@1.8 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} continue-on-error: true # [macOS] diff --git a/.github/workflows/cache-reaper.yml b/.github/workflows/cache-reaper.yml new file mode 100644 index 00000000000000..472e50cfca4898 --- /dev/null +++ b/.github/workflows/cache-reaper.yml @@ -0,0 +1,20 @@ +name: Keep Github Actions Cache < 10GB + +on: + workflow_dispatch: + schedule: + # Run every 2hrs during weekdays + - cron: "0 0/2 * * 1-5" + +jobs: + cache-cleaner: + if: github.repository == 'facebook/react-native' + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v4 + - name: Use Node.js 18 + uses: actions/setup-node@v4 + - name: Trim the cache + run: node scripts/clean-gha-cache.js diff --git a/.github/workflows/check-for-reproducer.yml b/.github/workflows/check-for-reproducer.yml index 839416620f687c..5d124c32787a25 100644 --- a/.github/workflows/check-for-reproducer.yml +++ b/.github/workflows/check-for-reproducer.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/github-script@v6 with: - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} script: | const checkForReproducer = require('./.github/workflow-scripts/checkForReproducer.js') await checkForReproducer(github, context) diff --git a/.github/workflows/check-nightly.yml b/.github/workflows/check-nightly.yml new file mode 100644 index 00000000000000..2fb26d10811096 --- /dev/null +++ b/.github/workflows/check-nightly.yml @@ -0,0 +1,26 @@ +# This jobs runs every day 2 hours after the nightly job and its purpose is to report +# a failure in case the nightly failed to be published. We are going to hook this to an internal automation. +name: Check Nigthlies + +on: + workflow_dispatch: + # nightly build @ 4:15 AM UTC + schedule: + - cron: '15 4 * * *' + +jobs: + check-nightly: + runs-on: ubuntu-latest + if: github.repository == 'facebook/react-native' + steps: + - name: Check nightly + run: | + TODAY=$(date "+%Y%m%d") + echo "Checking nightly for $TODAY" + NIGHTLY="$(npm view react-native | grep $TODAY)" + if [[ -z $NIGHTLY ]]; then + echo 'Nightly job failed.' + exit 1 + else + echo 'Nightly Worked, All Good!' + fi diff --git a/.github/workflows/close-pr.yml b/.github/workflows/close-pr.yml index e6558042e6c023..2b3d773fa993c2 100644 --- a/.github/workflows/close-pr.yml +++ b/.github/workflows/close-pr.yml @@ -13,7 +13,7 @@ jobs: steps: - uses: actions/github-script@v6 with: - github-token: ${{ secrets.GITHUB_TOKEN }} + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} script: | if(!context.payload.commits || !context.payload.commits.length) return; const sha = context.payload.commits[0].id; @@ -48,7 +48,7 @@ jobs: issue_number: closedPrNumber, owner: context.repo.owner, repo: context.repo.repo, - body: `This pull request was successfully merged by ${authorName} in **${sha}**.\n\n[When will my fix make it into a release?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#when-will-my-fix-make-it-into-a-release) | [How to file a pick request?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#how-to-open-a-pick-request)` + body: `This pull request was successfully merged by ${authorName} in **${sha}**\n\n[When will my fix make it into a release?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#when-will-my-fix-make-it-into-a-release) | [How to file a pick request?](https://github.com/reactwg/react-native-releases/blob/main/docs/faq.md#how-to-open-a-pick-request)` }); // If the PR has already been processed (labeled as Merged), skip it diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 85e14987843cae..ae5800f81ee22c 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -4,25 +4,29 @@ on: workflow_dispatch: inputs: version: - description: 'The version of React Native we want to release. For example 0.75.0-rc.0' + description: "The version of React Native we want to release. For example 0.75.0-rc.0" required: true type: string - is_latest_on_npm: - description: 'Whether we want to tag this release as latest on NPM' + is-latest-on-npm: + description: "Whether we want to tag this release as latest on NPM" required: true type: boolean default: false - dry_run: - description: 'Whether the job should be executed in dry-run mode or not' + dry-run: + description: "Whether the job should be executed in dry-run mode or not" type: boolean - default: false + default: true jobs: - prepare_release: + create_release: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 + with: + token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} + fetch-depth: 0 + fetch-tags: 'true' - name: Check if on stable branch id: check_stable_branch run: | @@ -46,3 +50,7 @@ jobs: - name: Execute Prepare Release if: ${{ steps.check_stable_branch.outputs.ON_STABLE_BRANCH && !steps.check_if_tag_exists.outputs.TAG_EXISTS }} uses: ./.github/actions/create-release + with: + version: ${{ inputs.version }} + is-latest-on-npm: ${{ inputs.is-latest-on-npm }} + dry-run: ${{ inputs.dry-run }} diff --git a/.github/workflows/danger-pr.yml b/.github/workflows/danger-pr.yml index cfde17435243b8..6d0bd1622705b4 100644 --- a/.github/workflows/danger-pr.yml +++ b/.github/workflows/danger-pr.yml @@ -25,4 +25,4 @@ jobs: run: yarn danger ci --use-github-checks --failOnErrors working-directory: packages/react-native-bots env: - DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} + DANGER_GITHUB_API_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 76de850c9a4bb8..b7121c935740f1 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,11 +1,10 @@ name: Nightly on: - workflow_dispatch: - # nightly build @ 2:15 AM UTC - schedule: - - cron: '15 2 * * *' - + workflow_dispatch: + # nightly build @ 2:15 AM UTC + schedule: + - cron: "15 2 * * *" jobs: set_release_type: @@ -27,85 +26,32 @@ jobs: env: HERMES_WS_DIR: /tmp/hermes HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion - BUILD_FROM_SOURCE: true - GRADLE_OPTS: '-Dorg.gradle.daemon=false' outputs: - react-native-version: ${{ steps.react-native-version.outputs.version }} - hermes-version: ${{ steps.hermes-version.outputs.version }} + react-native-version: ${{ steps.prepare-hermes-workspace.outputs.react-native-version }} + hermes-version: ${{ steps.prepare-hermes-workspace.outputs.hermes-version }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Setup hermes version - id: hermes-version - run: | - mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes" - - if [ -f "$HERMES_VERSION_FILE" ]; then - echo "Hermes Version file found! Using this version for the build:" - echo "VERSION=$(cat $HERMES_VERSION_FILE)" >> "$GITHUB_OUTPUT" - else - echo "Hermes Version file not found!!!" - echo "Using the last commit from main for the build:" - HERMES_TAG_SHA=$(git ls-remote https://github.com/$GITHUB_REPOSITORY main | cut -f 1 | tr -d '[:space:]') - echo "VERSION=$HERMES_TAG_SHA" >> "$GITHUB_OUTPUT" - fi - echo "Hermes commit is $HERMES_TAG_SHA" - - name: Get react-native version - id: react-native-version - run: | - VERSION=$(cat packages/react-native/package.json | jq -r '.version') - # Save the react native version we are building in an output variable so we can use that file as part of the cache key. - echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" - echo "React Native Version is $VERSION" - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 + uses: actions/checkout@v4 + - name: Prepare Hermes Workspace + id: prepare-hermes-workspace + uses: ./.github/actions/prepare-hermes-workspace with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ steps.hermes-version.outputs.version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Yarn- Install Dependencies - run: yarn install --non-interactive - - name: Download Hermes tarball - run: | - node packages/react-native/scripts/hermes/prepare-hermes-for-build ${{ github.event.pull_request.html_url }} - cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/. - cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/. - - echo ${{ steps.hermes-version.outputs.version }} + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + hermes-version-file: ${{ env.HERMES_VERSION_FILE }} build_hermesc_apple: runs-on: macos-13 needs: prepare_hermes_workspace env: HERMES_WS_DIR: /tmp/hermes - HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 - with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Hermes apple cache - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_host_hermesc - key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} + uses: actions/checkout@v4 - name: Build HermesC Apple - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - build_host_hermesc_if_needed + uses: ./.github/actions/build-hermesc-apple + with: + hermes-version: ${{ needs.prepare_hermes_workspace.output.hermes-version }} + react-native-version: ${{ needs.prepare_hermes_workspace.output.react-native-version }} build_apple_slices_hermes: runs-on: macos-14 @@ -114,7 +60,9 @@ jobs: HERMES_WS_DIR: /tmp/hermes HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin HERMES_OSXBIN_ARTIFACTS_DIR: /tmp/hermes/osx-bin - continue-on-error: true + IOS_DEPLOYMENT_TARGET: "15.1" + XROS_DEPLOYMENT_TARGET: "1.0" + MAC_DEPLOYMENT_TARGET: "10.15" strategy: fail-fast: false matrix: @@ -122,85 +70,14 @@ jobs: slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Slice + uses: ./.github/actions/build-apple-slices-hermes with: + flavor: ${{ matrix.flavor }} + slice: ${{ matrix.slice}} hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT - fi - - name: Build the Hermes ${{ matrix.slice }} frameworks - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - SLICE=${{ matrix.slice }} - FLAVOR=${{ matrix.flavor }} - FINAL_PATH=build_"$SLICE"_"$FLAVOR" - echo "Final path for this slice is: $FINAL_PATH" - - if [[ -d "$FINAL_PATH" ]]; then - echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH". - exit 0 - fi - - if [[ "$ARTIFACTS_EXIST" ]]; then - echo "[HERMES] Skipping! Artifacts exists already." - exit 0 - fi - - if [[ "$SLICE" == "macosx" ]]; then - echo "[HERMES] Building Hermes for MacOS" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-mac-framework.sh - else - echo "[HERMES] Building Hermes for iOS: $SLICE" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-ios-framework.sh "$SLICE" - fi - - echo "Moving from build_$SLICE to $FINAL_PATH" - mv build_"$SLICE" "$FINAL_PATH" - - # check whether everything is there - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then - echo "Successfully built hermes.framework for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework for $SLICE in $FLAVOR" - exit 1 - fi - - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then - echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR" - echo "Please try again" - exit 1 - fi - - name: Save slice cache - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }} build_hermes_macos: runs-on: macos-13 @@ -215,292 +92,47 @@ jobs: flavor: [Debug, Release] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Hermes MacOS + uses: ./.github/actions/build-hermes-macos with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT - fi - - name: Yarn- Install Dependencies - if: ${{ ! contains(github.event.head_commit.message, 'Bump metro@') && steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: yarn install --non-interactive - - name: Slice cache macosx - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_macosx_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-macosx-${{ matrix.flavor }} - - name: Slice cache iphoneos - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphoneos_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphoneos-${{ matrix.flavor }} - - name: Slice cache iphonesimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphonesimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphonesimulator-${{ matrix.flavor }} - - name: Slice cache catalyst - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_catalyst_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-catalyst-${{ matrix.flavor }} - - name: Slice cache xros - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xros_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xros-${{ matrix.flavor }} - - name: Slice cache xrsimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xrsimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xrsimulator-${{ matrix.flavor }} - - name: Move back build folders - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - ls -l ./packages/react-native/sdks/hermes - cd ./packages/react-native/sdks/hermes || exit 1 - mv build_macosx_${{ matrix.flavor }} build_macosx - mv build_iphoneos_${{ matrix.flavor }} build_iphoneos - mv build_iphonesimulator_${{ matrix.flavor }} build_iphonesimulator - mv build_catalyst_${{ matrix.flavor }} build_catalyst - mv build_xros_${{ matrix.flavor }} build_xros - mv build_xrsimulator_${{ matrix.flavor }} build_xrsimulator - - name: Prepare destroot folder - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - prepare_dest_root_for_ci - - name: Create fat framework for iOS - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - echo "[HERMES] Creating the universal framework" - ./utils/build-ios-framework.sh build_framework - - name: Package the Hermes Apple frameworks - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - BUILD_TYPE="${{ matrix.flavor }}" - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX) - - TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") - - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \ - --inputDir ./packages/react-native/sdks/hermes \ - --buildType "$BUILD_TYPE" \ - --outputDir $TARBALL_OUTPUT_DIR) - - echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH" - - mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR - cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/. - - mkdir -p /tmp/hermes/osx-bin/${{ matrix.flavor }} - cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ matrix.flavor }} - ls -lR /tmp/hermes/osx-bin/ - - name: Upload darwin artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-darwin-bin-${{ matrix.flavor }} - path: /tmp/hermes/hermes-runtime-darwin - - name: Upload osx-bin - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-osx-bin-${{ matrix.flavor }} - path: /tmp/hermes/osx-bin - - name: Create dSYM archive - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - FLAVOR=${{ matrix.flavor }} - WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR" - - mkdir -p "$WORKING_DIR/macosx" - mkdir -p "$WORKING_DIR/catalyst" - mkdir -p "$WORKING_DIR/iphoneos" - mkdir -p "$WORKING_DIR/iphonesimulator" - mkdir -p "$WORKING_DIR/xros" - mkdir -p "$WORKING_DIR/xrsimulator" - - cd ./packages/react-native/sdks/hermes || exit 1 - - DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM - cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/" - cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" - cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" - cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" - cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" - cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" - - DEST_DIR="/tmp/hermes/dSYM/$FLAVOR" - tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" . - - mkdir -p "$DEST_DIR" - mv "hermes.framework.dSYM" "$DEST_DIR" - - name: Upload hermes dSYM artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-dSYM-${{ matrix.flavor }} - path: /tmp/hermes/dSYM/${{ matrix.flavor }} + flavor: ${{ matrix.flavor }} build_hermesc_linux: runs-on: ubuntu-latest needs: prepare_hermes_workspace + env: + HERMES_WS_DIR: /tmp/hermes + HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y git openssh-client cmake build-essential \ - libreadline-dev libicu-dev jq zip python3 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build HermesC Linux + uses: ./.github/actions/build-hermesc-linux with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Linux cache - uses: actions/cache@v4.0.0 - with: - key: v1-hermes-${{ github.job }}-linux-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - /tmp/hermes/linux64-bin/ - /tmp/hermes/hermes/destroot/ - - name: Set up workspace - run: | - mkdir -p /tmp/hermes/linux64-bin - - name: Build HermesC for Linux - run: | - if [ -f /tmp/hermes/linux64-bin/hermesc ]; then - echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.' - else - cd /tmp/hermes - cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \ - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive" - cmake --build build --target hermesc -j 4 - cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. - fi - - name: Upload linux artifacts - uses: actions/upload-artifact@v4.3.0 - with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin build_hermesc_windows: runs-on: windows-2019 needs: prepare_hermes_workspace env: HERMES_WS_DIR: 'D:\tmp\hermes' + HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin' + HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin' ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip" MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin' CMAKE_DIR: 'C:\Program Files\CMake\bin' steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build HermesC Windows + uses: ./.github/actions/build-hermesc-windows with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Windows cache - uses: actions/cache@v4.0.0 - with: - key: v2-hermes-${{ github.job }}-windows-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - D:\tmp\hermes\win64-bin\ - D:\tmp\hermes\hermes\icu\ - D:\tmp\hermes\hermes\deps\ - D:\tmp\hermes\hermes\build_release\ - - name: setup-msbuild - uses: microsoft/setup-msbuild@v1.3.2 - - name: Set up workspace - run: | - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\hermes - #New-Item -ItemType SymbolicLink -ErrorAction SilentlyContinue -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes - - name: Build HermesC for Windows - run: | - if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) { - choco install --no-progress cmake --version 3.14.7 - if (-not $?) { throw "Failed to install CMake" } - - cd $Env:HERMES_WS_DIR\icu - # If Invoke-WebRequest shows a progress bar, it will fail with - # Win32 internal error "Access is denied" 0x5 occurred [...] - $progressPreference = 'silentlyContinue' - Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip" - Expand-Archive -Path "icu.zip" -DestinationPath "." - - cd $Env:HERMES_WS_DIR - Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps" - # Include MSVC++ 2015 redistributables - Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps" - - $Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR" - $Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu" - - cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF - if (-not $?) { throw "Failed to configure Hermes" } - echo "Running windows build..." - cd build_release - cmake --build . --target hermesc --config Release - if (-not $?) { throw "Failed to build Hermes" } - - echo "Copying hermesc.exe to win64-bin" - cd $Env:HERMES_WS_DIR - Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin" - # Include Windows runtime dependencies - Copy-Item -Path "deps\*" -Destination "win64-bin" - } - else { - Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild." - } - - name: Upload windows artifacts - uses: actions/upload-artifact@v4.3.0 - with: - name: hermes-win64-bin - path: D:\tmp\hermes\win64-bin\ build_android: runs-on: 8-core-ubuntu @@ -510,200 +142,49 @@ jobs: env: TERM: "dumb" GRADLE_OPTS: "-Dorg.gradle.daemon=false" + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Install dependencies - run: yarn install --non-interactive - - name: Set React Native Version - run: node ./scripts/releases/set-rn-version.js --build-type ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - - name: Setup gradle - uses: ./.github/actions/setup-gradle - - name: Build and publish all the Android Artifacts to /tmp/maven-local - run: | - # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. - if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - ./gradlew publishAllToMavenTempLocal build -PenableWarningsAsErrors=true - shell: bash - - name: Upload test results - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 - with: - name: build-android-results - compression-level: 1 - path: | - packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports - packages/react-native-gradle-plugin/settings-plugin/build/reports - packages/react-native/ReactAndroid/build/reports - - name: Upload RNTester APK - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 + uses: actions/checkout@v4 + - name: Build Android + uses: ./.github/actions/build-android with: - name: rntester-apk - path: packages/rn-tester/android/app/build/outputs/apk/ - compression-level: 0 + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} + build_npm_package: runs-on: 8-core-ubuntu - needs: [set_release_type, prepare_hermes_workspace, build_hermes_macos, build_hermesc_linux, build_hermesc_windows,build_android] + needs: + [ + set_release_type, + prepare_hermes_workspace, + build_hermes_macos, + build_hermesc_linux, + build_hermesc_windows, + build_android, + ] container: image: reactnativecommunity/react-native-android:latest env: TERM: "dumb" - GRADLE_OPTS: '-Dorg.gradle.daemon=false' + GRADLE_OPTS: "-Dorg.gradle.daemon=false" # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - # Repeated here, as the environment key in this executor will overwrite the one in defaults - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }} - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }} - HERMES_WS_DIR: /tmp/hermes env: + HERMES_WS_DIR: /tmp/hermes GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} - REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Create /tmp/hermes/osx-bin directory - run: mkdir -p /tmp/hermes/osx-bin - - name: Download osx-bin release artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-osx-bin-Release - path: /tmp/hermes/osx-bin - - name: Download osx-bin debug artifacts - uses: actions/download-artifact@v4.1.3 + uses: actions/checkout@v4 + - name: Build and Publish NPM PAckage + uses: ./.github/actions/build-npm-package with: - name: hermes-osx-bin-Debug - path: /tmp/hermes/osx-bin - - name: Download darwin-bin release artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-darwin-bin-Release - path: /tmp/hermes/hermes-runtime-darwin - - name: Download darwin-bin debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-darwin-bin-Debug - path: /tmp/hermes/hermes-runtime-darwin - - name: Download hermes dSYM debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Debug - path: /tmp/hermes/dSYM/Debug - - name: Download hermes dSYM release vartifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Release - path: /tmp/hermes/dSYM/Release - - name: Download windows-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-win64-bin - path: /tmp/hermes/win64-bin - - name: Download linux-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup - with: - hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} - react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Show /tmp/hermes directory - run: ls -lR /tmp/hermes - - name: Copy Hermes binaries - shell: bash - run: | - mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin - - # When build_hermes_macos runs as a matrix, it outputs - if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/. - elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/. - else - ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing." - echo "Could not locate macOS hermesc binary."; exit 1; - fi - - # Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them. - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" - fi - - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz" - fi - - cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/. - cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/. - - # Make sure the hermesc files are actually executable. - chmod -R +x packages/react-native/sdks/hermesc/* - - mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/ - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz - cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz - cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Install dependencies - run: yarn install --non-interactive - - name: Build packages - run: yarn build - # Continue with publish steps - - name: Set npm credentials - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.GHA_NPM_TOKEN }}" > ~/.npmrc - - name: Publish NPM - run: | - git config --global --add safe.directory /__w/react-native/react-native - echo "GRADLE_OPTS = $GRADLE_OPTS" - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - node ./scripts/releases-ci/publish-npm.js -t nightly - - name: Zip Maven Artifacts from /tmp/maven-local - working-directory: /tmp - run: zip -r maven-local.zip maven-local - - name: Upload Maven Artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: maven-local - path: /tmp/maven-local.zip - - name: Upload npm logs - uses: actions/upload-artifact@v4.3.1 - with: - name: npm-logs - path: ~/.npm/_logs - - name: Build release package as a job artifact - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' - run: | - mkdir -p build - - FILENAME=$(cd packages/react-native; npm pack | tail -1) - mv packages/react-native/$FILENAME build/ - - echo $FILENAME > build/react-native-package-version - - name: Upload release package - uses: actions/upload-artifact@v4.3.1 - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' - with: - name: react-native-package - path: build - - name: Update rn-diff-purge to generate upgrade-support diff - if: needs.set_release_type.outputs.RELEASE_TYPE == 'release' - run: | - curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ - -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} + gha-npm-token: ${{ env.GHA_NPM_TOKEN }} diff --git a/.github/workflows/on-issue-labeled.yml b/.github/workflows/on-issue-labeled.yml index d348e571eb260e..a5800987331263 100644 --- a/.github/workflows/on-issue-labeled.yml +++ b/.github/workflows/on-issue-labeled.yml @@ -21,6 +21,7 @@ jobs: - name: Verify RN version uses: actions/github-script@v6 with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} script: | const verifyVersion = require('./.github/workflow-scripts/verifyVersion.js') const labelWithContext = await verifyVersion(github, context); @@ -40,6 +41,7 @@ jobs: - name: Add descriptive label uses: actions/github-script@v6 with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} script: | const addDescriptiveLabel = require('./.github/workflow-scripts/addDescriptiveLabels.js') await addDescriptiveLabel(github, context); @@ -52,6 +54,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/github-script@v6 with: + github-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} script: | const actOnLabel = require('./.github/workflow-scripts/actOnLabel.js') await actOnLabel(github, context, {label: context.payload.label.name}) diff --git a/.github/workflows/publish-bumped-packages.yml b/.github/workflows/publish-bumped-packages.yml index 9744cb0043d34a..6d5c27fbdd69be 100644 --- a/.github/workflows/publish-bumped-packages.yml +++ b/.github/workflows/publish-bumped-packages.yml @@ -13,11 +13,11 @@ jobs: GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Setup node.js uses: ./.github/actions/setup-node - name: Run Yarn Install - run: yarn install + uses: ./.github/actions/yarn-install-with-cache - name: Build packages run: yarn build - name: Set NPM auth token diff --git a/.github/workflows/publish-release.yml b/.github/workflows/publish-release.yml index 051aef4038eda6..296a246f93edeb 100644 --- a/.github/workflows/publish-release.yml +++ b/.github/workflows/publish-release.yml @@ -1,9 +1,9 @@ -name: Publish release - +name: Publish Release on: push: tags: - - "v0.[0-9]+.[0-9]+(-*)?" # This should match v0.X.Y and v0.X.Y-RC.0 + - "v0.*.*" # This should match v0.X.Y + - "v0.*.*-rc.*" # This should match v0.X.Y-RC.0 jobs: set_release_type: runs-on: ubuntu-latest @@ -24,86 +24,32 @@ jobs: env: HERMES_WS_DIR: /tmp/hermes HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion - BUILD_FROM_SOURCE: true - GRADLE_OPTS: '-Dorg.gradle.daemon=false' outputs: - react-native-version: ${{ steps.react-native-version.outputs.version }} - hermes-version: ${{ steps.hermes-version.outputs.version }} + react-native-version: ${{ steps.prepare-hermes-workspace.outputs.react-native-version }} + hermes-version: ${{ steps.prepare-hermes-workspace.outputs.hermes-version }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Setup hermes version - id: hermes-version - run: | - mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes" - - if [ -f "$HERMES_VERSION_FILE" ]; then - echo "Hermes Version file found! Using this version for the build:" - echo "VERSION=$(cat $HERMES_VERSION_FILE)" >> "$GITHUB_OUTPUT" - else - echo "Hermes Version file not found!!!" - echo "Using the last commit from main for the build:" - HERMES_TAG_SHA=$(git ls-remote https://github.com/$GITHUB_REPOSITORY main | cut -f 1 | tr -d '[:space:]') - echo "VERSION=$HERMES_TAG_SHA" >> "$GITHUB_OUTPUT" - fi - echo "Hermes commit is $HERMES_TAG_SHA" - - name: Get react-native version - id: react-native-version - run: | - VERSION=$(cat packages/react-native/package.json | jq -r '.version') - # Save the react native version we are building in an output variable so we can use that file as part of the cache key. - echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" - echo "React Native Version is $VERSION" - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 + uses: actions/checkout@v4 + - name: Prepare Hermes Workspace + id: prepare-hermes-workspace + uses: ./.github/actions/prepare-hermes-workspace with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ steps.hermes-version.outputs.version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Yarn- Install Dependencies - run: yarn install --non-interactive - - name: Download Hermes tarball - run: | - node packages/react-native/scripts/hermes/prepare-hermes-for-build ${{ github.event.pull_request.html_url }} - cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/. - cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/. - - echo ${{ steps.hermes-version.outputs.version }} + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + hermes-version-file: ${{ env.HERMES_VERSION_FILE }} build_hermesc_apple: runs-on: macos-13 needs: prepare_hermes_workspace env: HERMES_WS_DIR: /tmp/hermes - HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 - with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Hermes apple cache - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_host_hermesc - key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} + uses: actions/checkout@v4 - name: Build HermesC Apple - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - build_host_hermesc_if_needed - + uses: ./.github/actions/build-hermesc-apple + with: + hermes-version: ${{ needs.prepare_hermes_workspace.output.hermes-version }} + react-native-version: ${{ needs.prepare_hermes_workspace.output.react-native-version }} build_apple_slices_hermes: runs-on: macos-14 needs: [build_hermesc_apple, prepare_hermes_workspace] @@ -111,7 +57,9 @@ jobs: HERMES_WS_DIR: /tmp/hermes HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin HERMES_OSXBIN_ARTIFACTS_DIR: /tmp/hermes/osx-bin - continue-on-error: true + IOS_DEPLOYMENT_TARGET: "15.1" + XROS_DEPLOYMENT_TARGET: "1.0" + MAC_DEPLOYMENT_TARGET: "10.15" strategy: fail-fast: false matrix: @@ -119,85 +67,14 @@ jobs: slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Slice + uses: ./.github/actions/build-apple-slices-hermes with: + flavor: ${{ matrix.flavor }} + slice: ${{ matrix.slice}} hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT - fi - - name: Build the Hermes ${{ matrix.slice }} frameworks - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - SLICE=${{ matrix.slice }} - FLAVOR=${{ matrix.flavor }} - FINAL_PATH=build_"$SLICE"_"$FLAVOR" - echo "Final path for this slice is: $FINAL_PATH" - - if [[ -d "$FINAL_PATH" ]]; then - echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH". - exit 0 - fi - - if [[ "$ARTIFACTS_EXIST" ]]; then - echo "[HERMES] Skipping! Artifacts exists already." - exit 0 - fi - - if [[ "$SLICE" == "macosx" ]]; then - echo "[HERMES] Building Hermes for MacOS" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-mac-framework.sh - else - echo "[HERMES] Building Hermes for iOS: $SLICE" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-ios-framework.sh "$SLICE" - fi - - echo "Moving from build_$SLICE to $FINAL_PATH" - mv build_"$SLICE" "$FINAL_PATH" - - # check whether everything is there - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then - echo "Successfully built hermes.framework for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework for $SLICE in $FLAVOR" - exit 1 - fi - - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then - echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR" - echo "Please try again" - exit 1 - fi - - name: Save slice cache - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }} build_hermes_macos: runs-on: macos-13 @@ -212,292 +89,47 @@ jobs: flavor: [Debug, Release] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Hermes MacOS + uses: ./.github/actions/build-hermes-macos with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT - fi - - name: Yarn- Install Dependencies - if: ${{ ! contains(github.event.head_commit.message, 'Bump metro@') && steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: yarn install --non-interactive - - name: Slice cache macosx - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_macosx_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-macosx-${{ matrix.flavor }} - - name: Slice cache iphoneos - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphoneos_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphoneos-${{ matrix.flavor }} - - name: Slice cache iphonesimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphonesimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphonesimulator-${{ matrix.flavor }} - - name: Slice cache catalyst - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_catalyst_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-catalyst-${{ matrix.flavor }} - - name: Slice cache xros - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xros_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xros-${{ matrix.flavor }} - - name: Slice cache xrsimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xrsimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xrsimulator-${{ matrix.flavor }} - - name: Move back build folders - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - ls -l ./packages/react-native/sdks/hermes - cd ./packages/react-native/sdks/hermes || exit 1 - mv build_macosx_${{ matrix.flavor }} build_macosx - mv build_iphoneos_${{ matrix.flavor }} build_iphoneos - mv build_iphonesimulator_${{ matrix.flavor }} build_iphonesimulator - mv build_catalyst_${{ matrix.flavor }} build_catalyst - mv build_xros_${{ matrix.flavor }} build_xros - mv build_xrsimulator_${{ matrix.flavor }} build_xrsimulator - - name: Prepare destroot folder - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - prepare_dest_root_for_ci - - name: Create fat framework for iOS - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - echo "[HERMES] Creating the universal framework" - ./utils/build-ios-framework.sh build_framework - - name: Package the Hermes Apple frameworks - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - BUILD_TYPE="${{ matrix.flavor }}" - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX) - - TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") - - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \ - --inputDir ./packages/react-native/sdks/hermes \ - --buildType "$BUILD_TYPE" \ - --outputDir $TARBALL_OUTPUT_DIR) - - echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH" - - mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR - cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/. - - mkdir -p /tmp/hermes/osx-bin/${{ matrix.flavor }} - cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ matrix.flavor }} - ls -lR /tmp/hermes/osx-bin/ - - name: Upload darwin artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-darwin-bin-${{ matrix.flavor }} - path: /tmp/hermes/hermes-runtime-darwin - - name: Upload osx-bin - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-osx-bin-${{ matrix.flavor }} - path: /tmp/hermes/osx-bin - - name: Create dSYM archive - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - FLAVOR=${{ matrix.flavor }} - WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR" - - mkdir -p "$WORKING_DIR/macosx" - mkdir -p "$WORKING_DIR/catalyst" - mkdir -p "$WORKING_DIR/iphoneos" - mkdir -p "$WORKING_DIR/iphonesimulator" - mkdir -p "$WORKING_DIR/xros" - mkdir -p "$WORKING_DIR/xrsimulator" - - cd ./packages/react-native/sdks/hermes || exit 1 - - DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM - cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/" - cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" - cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" - cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" - cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" - cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" - - DEST_DIR="/tmp/hermes/dSYM/$FLAVOR" - tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" . - - mkdir -p "$DEST_DIR" - mv "hermes.framework.dSYM" "$DEST_DIR" - - name: Upload hermes dSYM artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-dSYM-${{ matrix.flavor }} - path: /tmp/hermes/dSYM/${{ matrix.flavor }} + flavor: ${{ matrix.flavor }} build_hermesc_linux: runs-on: ubuntu-latest needs: prepare_hermes_workspace + env: + HERMES_WS_DIR: /tmp/hermes + HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y git openssh-client cmake build-essential \ - libreadline-dev libicu-dev jq zip python3 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build HermesC Linux + uses: ./.github/actions/build-hermesc-linux with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Linux cache - uses: actions/cache@v4.0.0 - with: - key: v1-hermes-${{ github.job }}-linux-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - /tmp/hermes/linux64-bin/ - /tmp/hermes/hermes/destroot/ - - name: Set up workspace - run: | - mkdir -p /tmp/hermes/linux64-bin - - name: Build HermesC for Linux - run: | - if [ -f /tmp/hermes/linux64-bin/hermesc ]; then - echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.' - else - cd /tmp/hermes - cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \ - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive" - cmake --build build --target hermesc -j 4 - cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. - fi - - name: Upload linux artifacts - uses: actions/upload-artifact@v4.3.0 - with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin build_hermesc_windows: runs-on: windows-2019 needs: prepare_hermes_workspace env: HERMES_WS_DIR: 'D:\tmp\hermes' + HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin' + HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin' ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip" MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin' CMAKE_DIR: 'C:\Program Files\CMake\bin' steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build HermesC Windows + uses: ./.github/actions/build-hermesc-windows with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Windows cache - uses: actions/cache@v4.0.0 - with: - key: v2-hermes-${{ github.job }}-windows-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - D:\tmp\hermes\win64-bin\ - D:\tmp\hermes\hermes\icu\ - D:\tmp\hermes\hermes\deps\ - D:\tmp\hermes\hermes\build_release\ - - name: setup-msbuild - uses: microsoft/setup-msbuild@v1.3.2 - - name: Set up workspace - run: | - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\hermes - #New-Item -ItemType SymbolicLink -ErrorAction SilentlyContinue -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes - - name: Build HermesC for Windows - run: | - if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) { - choco install --no-progress cmake --version 3.14.7 - if (-not $?) { throw "Failed to install CMake" } - - cd $Env:HERMES_WS_DIR\icu - # If Invoke-WebRequest shows a progress bar, it will fail with - # Win32 internal error "Access is denied" 0x5 occurred [...] - $progressPreference = 'silentlyContinue' - Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip" - Expand-Archive -Path "icu.zip" -DestinationPath "." - - cd $Env:HERMES_WS_DIR - Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps" - # Include MSVC++ 2015 redistributables - Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps" - - $Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR" - $Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu" - - cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF - if (-not $?) { throw "Failed to configure Hermes" } - echo "Running windows build..." - cd build_release - cmake --build . --target hermesc --config Release - if (-not $?) { throw "Failed to build Hermes" } - - echo "Copying hermesc.exe to win64-bin" - cd $Env:HERMES_WS_DIR - Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin" - # Include Windows runtime dependencies - Copy-Item -Path "deps\*" -Destination "win64-bin" - } - else { - Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild." - } - - name: Upload windows artifacts - uses: actions/upload-artifact@v4.3.0 - with: - name: hermes-win64-bin - path: D:\tmp\hermes\win64-bin\ build_android: runs-on: 8-core-ubuntu @@ -507,199 +139,99 @@ jobs: env: TERM: "dumb" GRADLE_OPTS: "-Dorg.gradle.daemon=false" + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} + ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Install dependencies - run: yarn install --non-interactive - - name: Set React Native Version - run: node ./scripts/releases/set-rn-version.js --build-type ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - - name: Setup gradle - uses: ./.github/actions/setup-gradle - - name: Build and publish all the Android Artifacts to /tmp/maven-local - run: | - # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. - if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - ./gradlew publishAllToMavenTempLocal build -PenableWarningsAsErrors=true - shell: bash - - name: Upload test results - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 - with: - name: build-android-results - compression-level: 1 - path: | - packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports - packages/react-native-gradle-plugin/settings-plugin/build/reports - packages/react-native/ReactAndroid/build/reports - - name: Upload RNTester APK - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 + uses: actions/checkout@v4 + - name: Build Android + uses: ./.github/actions/build-android with: - name: rntester-apk - path: packages/rn-tester/android/app/build/outputs/apk/ - compression-level: 0 + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} build_npm_package: runs-on: 8-core-ubuntu - needs: [set_release_type, prepare_hermes_workspace, build_hermes_macos, build_hermesc_linux, build_hermesc_windows,build_android] + needs: + [ + set_release_type, + prepare_hermes_workspace, + build_hermes_macos, + build_hermesc_linux, + build_hermesc_windows, + build_android, + ] container: image: reactnativecommunity/react-native-android:latest env: TERM: "dumb" - GRADLE_OPTS: '-Dorg.gradle.daemon=false' + GRADLE_OPTS: "-Dorg.gradle.daemon=false" # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - # Repeated here, as the environment key in this executor will overwrite the one in defaults - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }} - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }} - HERMES_WS_DIR: /tmp/hermes env: + HERMES_WS_DIR: /tmp/hermes GHA_NPM_TOKEN: ${{ secrets.GHA_NPM_TOKEN }} ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} - ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY_ENCODED }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_SONATYPE_PASSWORD }} REACT_NATIVE_BOT_GITHUB_TOKEN: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Create /tmp/hermes/osx-bin directory - run: mkdir -p /tmp/hermes/osx-bin - - name: Download osx-bin release artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-osx-bin-Release - path: /tmp/hermes/osx-bin - - name: Download osx-bin debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-osx-bin-Debug - path: /tmp/hermes/osx-bin - - name: Download darwin-bin release artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-darwin-bin-Release - path: /tmp/hermes/hermes-runtime-darwin - - name: Download darwin-bin debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-darwin-bin-Debug - path: /tmp/hermes/hermes-runtime-darwin - - name: Download hermes dSYM debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Debug - path: /tmp/hermes/dSYM/Debug - - name: Download hermes dSYM release vartifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Release - path: /tmp/hermes/dSYM/Release - - name: Download windows-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-win64-bin - path: /tmp/hermes/win64-bin - - name: Download linux-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup - with: - hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} - react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Show /tmp/hermes directory - run: ls -lR /tmp/hermes - - name: Copy Hermes binaries + uses: actions/checkout@v4 + with: + fetch-depth: 0 + fetch-tags: true + - name: Build and Publish NPM PAckage + uses: ./.github/actions/build-npm-package + with: + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} + gha-npm-token: ${{ env.GHA_NPM_TOKEN }} + - name: Publish @react-native-community/template + id: publish-template-to-npm shell: bash run: | - mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin - - # When build_hermes_macos runs as a matrix, it outputs - if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/. - elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/. + COMMIT_MSG=$(git log -n1 --pretty=%B); + if grep -q '#publish-packages-to-npm&latest' <<< "$COMMIT_MSG"; then + echo "TAG=latest" >> $GITHUB_OUTPUT + IS_LATEST=true else - ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing." - echo "Could not locate macOS hermesc binary."; exit 1; + IS_LATEST=false fi + # Go from v0.75.0-rc.4 -> 0.75-stable, which is the template's branching scheme + VERSION=$(grep -oE '\d+\.\d+' <<< "${{ github.ref_name }}" | { read version; echo "$version-stable"; }) + echo "VERSION=$VERSION" >> $GITHUB_OUTPUT - # Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them. - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" - fi - - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz" - fi - - cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/. - cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/. - - # Make sure the hermesc files are actually executable. - chmod -R +x packages/react-native/sdks/hermesc/* - - mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/ - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz - cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz - cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Install dependencies - run: yarn install --non-interactive - - name: Build packages - run: yarn build - # Continue with publish steps - - name: Set npm credentials - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.GHA_NPM_TOKEN }}" > ~/.npmrc - - name: Publish NPM - run: | - git config --global --add safe.directory /__w/react-native/react-native - echo "GRADLE_OPTS = $GRADLE_OPTS" - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - node ./scripts/releases-ci/publish-npm.js -t release - - name: Zip Maven Artifacts from /tmp/maven-local - working-directory: /tmp - run: zip -r maven-local.zip maven-local - - name: Upload Maven Artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: maven-local - path: /tmp/maven-local.zip - - name: Upload npm logs - uses: actions/upload-artifact@v4.3.1 - with: - name: npm-logs - path: ~/.npm/_logs - - name: Build release package as a job artifact - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' + curl -L https://api.github.com/repos/react-native-community/template/actions/workflows/release.yaml/dispatches + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ + -d "{\"ref\":\"$VERSION\",\"inputs\":{\"version\":\"${{ github.ref_name }}\",\"is_latest_on_npm\":\"$IS_LATEST\"}}" + - name: Wait for template to be published + timeout-minutes: 3 + env: + VERSION: ${{ steps.publish-template-to-npm.outputs.VERSION }} + TAG: ${{ steps.publish-template-to-npm.outputs.TAG }} + shell: bash run: | - mkdir -p build - - FILENAME=$(cd packages/react-native; npm pack | tail -1) - mv packages/react-native/$FILENAME build/ - - echo $FILENAME > build/react-native-package-version - - name: Upload release package - uses: actions/upload-artifact@v4.3.1 - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' - with: - name: react-native-package - path: build + echo "Waiting until @react-native-community/template is published to npm" + while true; do + if curl -o /dev/null -s -f "https://registry.npmjs.org/@react-native-community/template/$VERSION"; then + echo "Confirm that @react-native-community/template@$VERSION is published on npm" + break + fi + sleep 10 + done + while [ "$TAG" == "latest" ]; do + CURRENT=$(curl -s "https://registry.npmjs.org/react-native/latest" | jq -r '.version'); + if [ "$CURRENT" == "$VERSION" ]; then + echo "Confirm that @react-native-community/template@latest == $VERSION on npm" + break + fi + sleep 10 + done - name: Update rn-diff-purge to generate upgrade-support diff - if: needs.set_release_type.outputs.RELEASE_TYPE == 'release' run: | curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ -H "Accept: application/vnd.github.v3+json" \ diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml deleted file mode 100644 index cf8478572270e9..00000000000000 --- a/.github/workflows/run-e2e-tests.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: Run E2E Tests -# This workflow is used to trigger E2E tests on a PR when a comment is made -# containing the text "#run-e2e-tests". -on: - issue_comment: - types: [created] -permissions: - contents: read -jobs: - rebase: - name: Trigger E2E Tests - permissions: - contents: write # for cirrus-actions/rebase to push code to rebase - pull-requests: read # for cirrus-actions/rebase to get info about PR - runs-on: ubuntu-latest - if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '#run-e2e-tests') - steps: - - name: Checkout the latest code - uses: actions/checkout@v4 - with: - token: ${{ secrets.GITHUB_TOKEN }} - fetch-depth: 0 # otherwise, you will fail to push refs to dest repo - - name: Push empty commit - run: | - git commit -m "#run-e2e-tests" --allow-empty - git push origin $(git branch --show-current) diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml index c418b505e674fc..d67b24620a940c 100644 --- a/.github/workflows/stale-bot.yml +++ b/.github/workflows/stale-bot.yml @@ -12,7 +12,7 @@ jobs: steps: - uses: actions/stale@v9 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} days-before-stale: 180 stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.' stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.' @@ -30,7 +30,7 @@ jobs: - uses: actions/stale@v9 with: ascending: true - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} days-before-stale: 180 stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.' stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.' @@ -47,7 +47,7 @@ jobs: steps: - uses: actions/stale@v9 with: - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} any-of-labels: 'Needs: Author Feedback' days-before-stale: 24 stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days." @@ -66,7 +66,7 @@ jobs: - uses: actions/stale@v9 with: ascending: true - repo-token: ${{ secrets.GITHUB_TOKEN }} + repo-token: ${{ secrets.REACT_NATIVE_BOT_GITHUB_TOKEN }} any-of-labels: 'Needs: Author Feedback' days-before-stale: 24 stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days." diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index d35e807cabfc9a..a4e1c92f3a602e 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -2,11 +2,16 @@ name: Test All on: workflow_dispatch: + pull_request: push: branches: - main - "*-stable" +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/main' && !contains(github.ref, 'stable')}} + jobs: set_release_type: runs-on: ubuntu-latest @@ -34,84 +39,32 @@ jobs: env: HERMES_WS_DIR: /tmp/hermes HERMES_VERSION_FILE: packages/react-native/sdks/.hermesversion - BUILD_FROM_SOURCE: true outputs: - react-native-version: ${{ steps.react-native-version.outputs.version }} - hermes-version: ${{ steps.hermes-version.outputs.version }} + react-native-version: ${{ steps.prepare-hermes-workspace.outputs.react-native-version }} + hermes-version: ${{ steps.prepare-hermes-workspace.outputs.hermes-version }} steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Setup hermes version - id: hermes-version - run: | - mkdir -p "/tmp/hermes" "/tmp/hermes/download" "/tmp/hermes/hermes" - - if [ -f "$HERMES_VERSION_FILE" ]; then - echo "Hermes Version file found! Using this version for the build:" - echo "VERSION=$(cat $HERMES_VERSION_FILE)" >> "$GITHUB_OUTPUT" - else - echo "Hermes Version file not found!!!" - echo "Using the last commit from main for the build:" - HERMES_TAG_SHA=$(git ls-remote https://github.com/$GITHUB_REPOSITORY main | cut -f 1 | tr -d '[:space:]') - echo "VERSION=$HERMES_TAG_SHA" >> "$GITHUB_OUTPUT" - fi - echo "Hermes commit is $HERMES_TAG_SHA" - - name: Get react-native version - id: react-native-version - run: | - VERSION=$(cat packages/react-native/package.json | jq -r '.version') - # Save the react native version we are building in an output variable so we can use that file as part of the cache key. - echo "VERSION=$VERSION" >> "$GITHUB_OUTPUT" - echo "React Native Version is $VERSION" - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 + uses: actions/checkout@v4 + - name: Prepare Hermes Workspace + id: prepare-hermes-workspace + uses: ./.github/actions/prepare-hermes-workspace with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ steps.hermes-version.outputs.version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Yarn- Install Dependencies - run: yarn install --non-interactive - - name: Download Hermes tarball - run: | - node packages/react-native/scripts/hermes/prepare-hermes-for-build ${{ github.event.pull_request.html_url }} - cp packages/react-native/sdks/download/* $HERMES_WS_DIR/download/. - cp -r packages/react-native/sdks/hermes/* $HERMES_WS_DIR/hermes/. - - echo ${{ steps.hermes-version.outputs.version }} + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + hermes-version-file: ${{ env.HERMES_VERSION_FILE }} build_hermesc_apple: runs-on: macos-13 needs: prepare_hermes_workspace env: HERMES_WS_DIR: /tmp/hermes - HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache hermes workspace - uses: actions/cache@v4.0.0 - with: - path: | - /tmp/hermes/download/ - /tmp/hermes/hermes/ - key: v1-hermes-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ github.run_number }} - enableCrossOsArchive: true - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Hermes apple cache - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_host_hermesc - key: v2-hermesc-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} + uses: actions/checkout@v4 - name: Build HermesC Apple - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - build_host_hermesc_if_needed + uses: ./.github/actions/build-hermesc-apple + with: + hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} + react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} build_apple_slices_hermes: runs-on: macos-14 @@ -120,7 +73,9 @@ jobs: HERMES_WS_DIR: /tmp/hermes HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin HERMES_OSXBIN_ARTIFACTS_DIR: /tmp/hermes/osx-bin - continue-on-error: true + IOS_DEPLOYMENT_TARGET: "15.1" + XROS_DEPLOYMENT_TARGET: "1.0" + MAC_DEPLOYMENT_TARGET: "10.15" strategy: fail-fast: false matrix: @@ -128,82 +83,14 @@ jobs: slice: [macosx, iphoneos, iphonesimulator, catalyst, xros, xrsimulator] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Slice + uses: ./.github/actions/build-apple-slices-hermes with: + flavor: ${{ matrix.flavor }} + slice: ${{ matrix.slice}} hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - fi - - name: Build the Hermes ${{ matrix.slice }} frameworks - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - SLICE=${{ matrix.slice }} - FLAVOR=${{ matrix.flavor }} - FINAL_PATH=build_"$SLICE"_"$FLAVOR" - echo "Final path for this slice is: $FINAL_PATH" - - if [[ -d "$FINAL_PATH" ]]; then - echo "[HERMES] Skipping! Found the requested slice at $FINAL_PATH". - exit 0 - fi - - if [[ "$ARTIFACTS_EXIST" ]]; then - echo "[HERMES] Skipping! Artifacts exists already." - exit 0 - fi - - if [[ "$SLICE" == "macosx" ]]; then - echo "[HERMES] Building Hermes for MacOS" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-mac-framework.sh - else - echo "[HERMES] Building Hermes for iOS: $SLICE" - BUILD_TYPE="${{ matrix.flavor }}" ./utils/build-ios-framework.sh "$SLICE" - fi - - echo "Moving from build_$SLICE to $FINAL_PATH" - mv build_"$SLICE" "$FINAL_PATH" - - # check whether everything is there - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework" ]]; then - echo "Successfully built hermes.framework for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework for $SLICE in $FLAVOR" - exit 1 - fi - - if [[ -d "$FINAL_PATH/API/hermes/hermes.framework.dSYM" ]]; then - echo "Successfully built hermes.framework.dSYM for $SLICE in $FLAVOR" - else - echo "Failed to built hermes.framework.dSYM for $SLICE in $FLAVOR" - echo "Please try again" - exit 1 - fi - - name: Save slice cache - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_${{ matrix.slice }}_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-${{ matrix.slice }}-${{ matrix.flavor }} build_hermes_macos: runs-on: macos-13 @@ -218,165 +105,13 @@ jobs: flavor: [Debug, Release] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - - name: Setup node.js - uses: ./.github/actions/setup-node - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build Hermes MacOS + uses: ./.github/actions/build-hermes-macos with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Setup Hermes workspace - uses: ./.github/actions/setup_hermes_workspace - - name: Check if the required artifacts already exist - id: check_if_apple_artifacts_are_there - run: | - FLAVOR="${{ matrix.flavor }}" - echo "Flavor is $FLAVOR" - OSX_BIN="/tmp/hermes/osx-bin/$FLAVOR" - DSYM="/tmp/hermes/dSYM/$FLAVOR" - HERMES="/tmp/hermes/hermes-runtime-darwin/hermes-ios-$FLAVOR.tar.gz" - - if [[ -d "$OSX_BIN" ]] && \ - [[ -d "$DSYM" ]] && \ - [[ -f "$HERMES" ]]; then - - echo "Artifacts are there!" - echo "ARTIFACTS_EXIST=true" >> $GITHUB_ENV - echo "ARTIFACTS_EXIST=true" >> $GITHUB_OUTPUT - fi - - name: Yarn- Install Dependencies - run: yarn install --non-interactive - - name: Slice cache macosx - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_macosx_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-macosx-${{ matrix.flavor }} - - name: Slice cache iphoneos - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphoneos_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphoneos-${{ matrix.flavor }} - - name: Slice cache iphonesimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_iphonesimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-iphonesimulator-${{ matrix.flavor }} - - name: Slice cache catalyst - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_catalyst_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-catalyst-${{ matrix.flavor }} - - name: Slice cache xros - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xros_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xros-${{ matrix.flavor }} - - name: Slice cache xrsimulator - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - uses: actions/cache@v4.0.0 - with: - path: ./packages/react-native/sdks/hermes/build_xrsimulator_${{ matrix.flavor }} - key: v4-hermes-apple-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }}-${{ hashfiles('packages/react-native/sdks/hermes-engine/utils/build-apple-framework.sh') }}-xrsimulator-${{ matrix.flavor }} - - name: Move back build folders - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - ls -l ./packages/react-native/sdks/hermes - cd ./packages/react-native/sdks/hermes || exit 1 - mv build_macosx_${{ matrix.flavor }} build_macosx - mv build_iphoneos_${{ matrix.flavor }} build_iphoneos - mv build_iphonesimulator_${{ matrix.flavor }} build_iphonesimulator - mv build_catalyst_${{ matrix.flavor }} build_catalyst - mv build_xros_${{ matrix.flavor }} build_xros - mv build_xrsimulator_${{ matrix.flavor }} build_xrsimulator - - name: Prepare destroot folder - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - . ./utils/build-apple-framework.sh - prepare_dest_root_for_ci - - name: Create fat framework for iOS - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - cd ./packages/react-native/sdks/hermes || exit 1 - echo "[HERMES] Creating the universal framework" - ./utils/build-ios-framework.sh build_framework - - name: Package the Hermes Apple frameworks - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - BUILD_TYPE="${{ matrix.flavor }}" - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_DIR=$(mktemp -d /tmp/hermes-tarball-output-XXXXXXXX) - - TARBALL_FILENAME=$(node ./packages/react-native/scripts/hermes/get-tarball-name.js --buildType "$BUILD_TYPE") - - echo "Packaging Hermes Apple frameworks for $BUILD_TYPE build type" - - TARBALL_OUTPUT_PATH=$(node ./packages/react-native/scripts/hermes/create-tarball.js \ - --inputDir ./packages/react-native/sdks/hermes \ - --buildType "$BUILD_TYPE" \ - --outputDir $TARBALL_OUTPUT_DIR) - - echo "Hermes tarball saved to $TARBALL_OUTPUT_PATH" - - mkdir -p $HERMES_TARBALL_ARTIFACTS_DIR - cp $TARBALL_OUTPUT_PATH $HERMES_TARBALL_ARTIFACTS_DIR/. - - mkdir -p /tmp/hermes/osx-bin/${{ matrix.flavor }} - cp ./packages/react-native/sdks/hermes/build_macosx/bin/* /tmp/hermes/osx-bin/${{ matrix.flavor }} - ls -lR /tmp/hermes/osx-bin/ - - name: Upload darwin artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-darwin-bin-${{ matrix.flavor }} - path: /tmp/hermes/hermes-runtime-darwin - - name: Upload osx-bin - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-osx-bin-${{ matrix.flavor }} - path: /tmp/hermes/osx-bin - - name: Create dSYM archive - if: ${{ steps.check_if_apple_artifacts_are_there.outputs.ARTIFACTS_EXIST != true }} - run: | - FLAVOR=${{ matrix.flavor }} - WORKING_DIR="/tmp/hermes_tmp/dSYM/$FLAVOR" - - mkdir -p "$WORKING_DIR/macosx" - mkdir -p "$WORKING_DIR/catalyst" - mkdir -p "$WORKING_DIR/iphoneos" - mkdir -p "$WORKING_DIR/iphonesimulator" - mkdir -p "$WORKING_DIR/xros" - mkdir -p "$WORKING_DIR/xrsimulator" - - cd ./packages/react-native/sdks/hermes || exit 1 - - DSYM_FILE_PATH=API/hermes/hermes.framework.dSYM - cp -r build_macosx/$DSYM_FILE_PATH "$WORKING_DIR/macosx/" - cp -r build_catalyst/$DSYM_FILE_PATH "$WORKING_DIR/catalyst/" - cp -r build_iphoneos/$DSYM_FILE_PATH "$WORKING_DIR/iphoneos/" - cp -r build_iphonesimulator/$DSYM_FILE_PATH "$WORKING_DIR/iphonesimulator/" - cp -r build_xros/$DSYM_FILE_PATH "$WORKING_DIR/xros/" - cp -r build_xrsimulator/$DSYM_FILE_PATH "$WORKING_DIR/xrsimulator/" - - DEST_DIR="/tmp/hermes/dSYM/$FLAVOR" - tar -C "$WORKING_DIR" -czvf "hermes.framework.dSYM" . - - mkdir -p "$DEST_DIR" - mv "hermes.framework.dSYM" "$DEST_DIR" - - name: Upload hermes dSYM artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: hermes-dSYM-${{ matrix.flavor }} - path: /tmp/hermes/dSYM/${{ matrix.flavor }} + flavor: ${{ matrix.flavor }} test_ios_rntester_ruby_3_2_0: runs-on: macos-13 @@ -387,13 +122,14 @@ jobs: HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Run it - uses: ./.github/actions/test_ios_rntester + uses: ./.github/actions/test-ios-rntester with: ruby-version: "3.2.0" hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} + test_ios_rntester_dynamic_frameworks: runs-on: macos-13 needs: @@ -408,9 +144,9 @@ jobs: jsengine: [Hermes, JSC] steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Run it - uses: ./.github/actions/test_ios_rntester + uses: ./.github/actions/test-ios-rntester with: jsengine: ${{ matrix.jsengine }} use-frameworks: DynamicFrameworks @@ -432,142 +168,210 @@ jobs: architecture: [NewArch, OldArch] steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Run it - uses: ./.github/actions/test_ios_rntester + uses: ./.github/actions/test-ios-rntester with: jsengine: ${{ matrix.jsengine }} architecture: ${{ matrix.architecture }} - run-unit-tests: true + run-unit-tests: "false" use-frameworks: StaticLibraries hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - build_hermesc_linux: - runs-on: ubuntu-latest - needs: prepare_hermes_workspace + test_e2e_ios_rntester: + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') }} + runs-on: macos-13 + needs: + [build_apple_slices_hermes, prepare_hermes_workspace, build_hermes_macos] + env: + HERMES_WS_DIR: /tmp/hermes + HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin + continue-on-error: true + strategy: + fail-fast: false + matrix: + jsengine: [Hermes, JSC] + architecture: [NewArch] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Install dependencies - run: | - sudo apt update - sudo apt install -y git openssh-client cmake build-essential \ - libreadline-dev libicu-dev jq zip python3 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Run it + uses: ./.github/actions/test-ios-rntester with: + jsengine: ${{ matrix.jsengine }} + architecture: ${{ matrix.architecture }} + run-unit-tests: "false" + use-frameworks: StaticLibraries hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Linux cache - uses: actions/cache@v4.0.0 + run-e2e-tests: "true" + - name: Run E2E Tests + uses: ./.github/actions/maestro-ios + with: + app-path: "/tmp/RNTesterBuild/Build/Products/Release-iphonesimulator/RNTester.app" + app-id: com.meta.RNTester.localDevelopment + jsengine: ${{ matrix.jsengine }} + maestro-flow: ./packages/rn-tester/.maestro/ + + test_e2e_ios_templateapp: + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') }} + runs-on: macos-13 + needs: build_npm_package + env: + HERMES_WS_DIR: /tmp/hermes + HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin + continue-on-error: true + strategy: + fail-fast: false + matrix: + jsengine: [Hermes, JSC] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup xcode + uses: ./.github/actions/setup-xcode + - name: Setup node.js + uses: ./.github/actions/setup-node + - name: Run yarn + uses: ./.github/actions/yarn-install-with-cache + - name: Setup ruby + uses: ruby/setup-ruby@v1.170.0 + with: + ruby-version: 2.6.10 + - name: Download Hermes + uses: actions/download-artifact@v4 with: - key: v1-hermes-${{ github.job }}-linux-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - /tmp/hermes/linux64-bin/ - /tmp/hermes/hermes/destroot/ - - name: Set up workspace + name: hermes-darwin-bin-Release + path: /tmp/react-native-tmp + - name: Download React Native Package + uses: actions/download-artifact@v4 + with: + name: react-native-package + path: /tmp/react-native-tmp + - name: Print /tmp folder + run: ls -lR /tmp/react-native-tmp + - name: Prepare artifacts run: | - mkdir -p /tmp/hermes/linux64-bin - - name: Build HermesC for Linux + REACT_NATIVE_PKG=$(find /tmp/react-native-tmp -type f -name "*.tgz") + echo "React Native tgs is $REACT_NATIVE_PKG" + + HERMES_PATH=$(find /tmp/react-native-tmp -type f -name "*.tar.gz") + echo "Hermes path is $HERMES_PATH" + + node ./scripts/e2e/init-project-e2e.js --projectName RNTestProject --currentBranch ${{ github.ref_name }} --directory /tmp/RNTestProject --pathToLocalReactNative $REACT_NATIVE_PKG + + cd /tmp/RNTestProject/ios + bundle install + HERMES_ENGINE_TARBALL_PATH=$HERMES_PATH bundle exec pod install + + set -o pipefail && xcodebuild \ + -scheme "RNTestProject" \ + -workspace RNTestProject.xcworkspace \ + -configuration "Release" \ + -sdk "iphonesimulator" \ + -destination "generic/platform=iOS Simulator" \ + -derivedDataPath "/tmp/RNTestProject" | xcbeautify + - name: Run E2E Tests + uses: ./.github/actions/maestro-ios + with: + app-path: "/tmp/RNTestProject/Build/Products/Release-iphonesimulator/RNTestProject.app" + app-id: org.reactjs.native.example.RNTestProject + jsengine: ${{ matrix.jsengine }} + maestro-flow: ./scripts/e2e/.maestro/ + + test_e2e_android_templateapp: + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') }} + runs-on: 4-core-ubuntu + needs: build_npm_package + continue-on-error: true + strategy: + fail-fast: false + matrix: + jsengine: [Hermes, JSC] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup node.js + uses: ./.github/actions/setup-node + - name: Run yarn + uses: ./.github/actions/yarn-install-with-cache + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: '17' + distribution: 'zulu' + - name: Download Maven Local + uses: actions/download-artifact@v4 + with: + name: maven-local + path: /tmp/react-native-tmp/maven-local + - name: Download React Native Package + uses: actions/download-artifact@v4 + with: + name: react-native-package + path: /tmp/react-native-tmp + - name: Print /tmp folder + run: ls -lR /tmp/react-native-tmp + - name: Prepare artifacts run: | - if [ -f /tmp/hermes/linux64-bin/hermesc ]; then - echo 'Skipping; Clean "/tmp/hermes/linux64-bin" to rebuild.' - else - cd /tmp/hermes - cmake -S hermes -B build -DHERMES_STATIC_LINK=ON -DCMAKE_BUILD_TYPE=Release -DHERMES_ENABLE_TEST_SUITE=OFF \ - -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DCMAKE_CXX_FLAGS=-s -DCMAKE_C_FLAGS=-s \ - -DCMAKE_EXE_LINKER_FLAGS="-Wl,--whole-archive -lpthread -Wl,--no-whole-archive" - cmake --build build --target hermesc -j 4 - cp /tmp/hermes/build/bin/hermesc /tmp/hermes/linux64-bin/. - fi - - name: Upload linux artifacts - uses: actions/upload-artifact@v4.3.0 + REACT_NATIVE_PKG=$(find /tmp/react-native-tmp -type f -name "*.tgz") + echo "React Native tgs is $REACT_NATIVE_PKG" + + MAVEN_LOCAL=/tmp/react-native-tmp/maven-local + echo "Maven local path is $MAVEN_LOCAL" + + node ./scripts/e2e/init-project-e2e.js --projectName RNTestProject --currentBranch ${{ github.ref_name }} --directory /tmp/RNTestProject --pathToLocalReactNative $REACT_NATIVE_PKG + + echo "Feed maven local to gradle.properties" + cd /tmp/RNTestProject + echo "react.internal.mavenLocalRepo=$MAVEN_LOCAL" >> android/gradle.properties + + # Build + cd android + ./gradlew assembleRelease --no-daemon -PreactNativeArchitectures=x86 + - name: Run E2E Tests + uses: ./.github/actions/maestro-android with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin + app-path: /tmp/RNTestProject/android/app/build/outputs/apk/release/app-release.apk + app-id: com.rntestproject + jsengine: ${{ matrix.jsengine }} + maestro-flow: ./scripts/e2e/.maestro/ + install-java: 'false' + + build_hermesc_linux: + runs-on: ubuntu-latest + needs: prepare_hermes_workspace + env: + HERMES_WS_DIR: /tmp/hermes + HERMES_TARBALL_ARTIFACTS_DIR: /tmp/hermes/hermes-runtime-darwin + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build HermesC Linux + uses: ./.github/actions/build-hermesc-linux + with: + hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} + react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} build_hermesc_windows: runs-on: windows-2019 needs: prepare_hermes_workspace env: HERMES_WS_DIR: 'D:\tmp\hermes' + HERMES_TARBALL_ARTIFACTS_DIR: 'D:\tmp\hermes\hermes-runtime-darwin' + HERMES_OSXBIN_ARTIFACTS_DIR: 'D:\tmp\hermes\osx-bin' ICU_URL: "https://github.com/unicode-org/icu/releases/download/release-64-2/icu4c-64_2-Win64-MSVC2017.zip" MSBUILD_DIR: 'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\MSBuild\Current\Bin' CMAKE_DIR: 'C:\Program Files\CMake\bin' steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Build HermesC Windows + uses: ./.github/actions/build-hermesc-windows with: hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Windows cache - uses: actions/cache@v4.0.0 - with: - key: v2-hermes-${{ github.job }}-windows-${{ needs.prepare_hermes_workspace.outputs.hermes-version }}-${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - path: | - D:\tmp\hermes\win64-bin\ - D:\tmp\hermes\hermes\icu\ - D:\tmp\hermes\hermes\deps\ - D:\tmp\hermes\hermes\build_release\ - - name: setup-msbuild - uses: microsoft/setup-msbuild@v1.3.2 - - name: Set up workspace - run: | - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\icu - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\deps - New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\win64-bin - #New-Item -ItemType Directory -ErrorAction SilentlyContinue $Env:HERMES_WS_DIR\hermes - #New-Item -ItemType SymbolicLink -ErrorAction SilentlyContinue -Target tmp\hermes\hermes -Path $Env:HERMES_WS_DIR -Name hermes - - name: Build HermesC for Windows - run: | - if (-not(Test-Path -Path $Env:HERMES_WS_DIR\win64-bin\hermesc.exe)) { - choco install --no-progress cmake --version 3.14.7 - if (-not $?) { throw "Failed to install CMake" } - - cd $Env:HERMES_WS_DIR\icu - # If Invoke-WebRequest shows a progress bar, it will fail with - # Win32 internal error "Access is denied" 0x5 occurred [...] - $progressPreference = 'silentlyContinue' - Invoke-WebRequest -Uri "$Env:ICU_URL" -OutFile "icu.zip" - Expand-Archive -Path "icu.zip" -DestinationPath "." - - cd $Env:HERMES_WS_DIR - Copy-Item -Path "icu\bin64\icu*.dll" -Destination "deps" - # Include MSVC++ 2015 redistributables - Copy-Item -Path "c:\windows\system32\msvcp140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140.dll" -Destination "deps" - Copy-Item -Path "c:\windows\system32\vcruntime140_1.dll" -Destination "deps" - - $Env:PATH += ";$Env:CMAKE_DIR;$Env:MSBUILD_DIR" - $Env:ICU_ROOT = "$Env:HERMES_WS_DIR\icu" - - cmake -S hermes -B build_release -G 'Visual Studio 16 2019' -Ax64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INTERPROCEDURAL_OPTIMIZATION=True -DHERMES_ENABLE_WIN10_ICU_FALLBACK=OFF - if (-not $?) { throw "Failed to configure Hermes" } - echo "Running windows build..." - cd build_release - cmake --build . --target hermesc --config Release - if (-not $?) { throw "Failed to build Hermes" } - - echo "Copying hermesc.exe to win64-bin" - cd $Env:HERMES_WS_DIR - Copy-Item -Path "build_release\bin\Release\hermesc.exe" -Destination "win64-bin" - # Include Windows runtime dependencies - Copy-Item -Path "deps\*" -Destination "win64-bin" - } - else { - Write-Host "Skipping; Clean c:\tmp\hermes\win64-bin to rebuild." - } - - name: Upload windows artifacts - uses: actions/upload-artifact@v4.3.0 - with: - name: hermes-win64-bin - path: D:\tmp\hermes\win64-bin\ build_android: runs-on: 8-core-ubuntu @@ -577,44 +381,46 @@ jobs: env: TERM: "dumb" GRADLE_OPTS: "-Dorg.gradle.daemon=false" + ORG_GRADLE_PROJECT_SIGNING_PWD: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_PWD }} + ORG_GRADLE_PROJECT_SIGNING_KEY: ${{ secrets.ORG_GRADLE_PROJECT_SIGNING_KEY }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Build Android + uses: ./.github/actions/build-android + with: + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} + run-e2e-tests: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') }} + + test_e2e_android_rntester: + if: ${{ github.ref == 'refs/heads/main' || contains(github.ref, 'stable') }} + runs-on: ubuntu-latest + needs: [build_android] + strategy: + fail-fast: false + matrix: + jsengine: [hermes, jsc] steps: - name: Checkout - uses: actions/checkout@v4.1.1 + uses: actions/checkout@v4 - name: Setup node.js uses: ./.github/actions/setup-node - - name: Install dependencies - run: yarn install --non-interactive - - name: Set React Native Version - run: node ./scripts/releases/set-rn-version.js --build-type ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - - name: Setup gradle - uses: ./.github/actions/setup-gradle - - name: Build and publish all the Android Artifacts to /tmp/maven-local - run: | - # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. - if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - ./gradlew publishAllToMavenTempLocal build -PenableWarningsAsErrors=true - shell: bash - - name: Upload test results - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 - with: - name: build-android-results - compression-level: 1 - path: | - packages/react-native-gradle-plugin/react-native-gradle-plugin/build/reports - packages/react-native-gradle-plugin/settings-plugin/build/reports - packages/react-native/ReactAndroid/build/reports - - name: Upload RNTester APK - if: ${{ always() }} - uses: actions/upload-artifact@v4.3.0 - with: - name: rntester-apk - path: packages/rn-tester/android/app/build/outputs/apk/ - compression-level: 0 + - name: Install node dependencies + uses: ./.github/actions/yarn-install-with-cache + - name: Download APK + uses: actions/download-artifact@v4 + with: + name: rntester-${{ matrix.jsengine }}-release + path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/release/ + - name: Print folder structure + run: ls -lR ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/release/ + - name: Run E2E Tests + uses: ./.github/actions/maestro-android + with: + app-path: ./packages/rn-tester/android/app/build/outputs/apk/${{ matrix.jsengine }}/release/app-${{ matrix.jsengine }}-x86-release.apk + app-id: com.facebook.react.uiapp + jsengine: ${{ matrix.jsengine }} + maestro-flow: ./packages/rn-tester/.maestro/ build_npm_package: runs-on: 8-core-ubuntu @@ -632,174 +438,20 @@ jobs: env: TERM: "dumb" GRADLE_OPTS: "-Dorg.gradle.daemon=false" - # By default we only build ARM64 to save time/resources. For release/nightlies/prealpha, we override this value to build all archs. - ORG_GRADLE_PROJECT_reactNativeArchitectures: "arm64-v8a" - # Repeated here, as the environment key in this executor will overwrite the one in defaults - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_A: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_A }} - PUBLIC_ANALYSISBOT_GITHUB_TOKEN_B: ${{ secrets.GITHUB_ANALYSISBOT_TOKEN_B }} - HERMES_WS_DIR: /tmp/hermes + env: + HERMES_WS_DIR: /tmp/hermes steps: - - name: Add github.com to SSH known hosts - run: | - mkdir -p ~/.ssh - echo '|1|If6MU203eXTaaWL678YEfWkVMrw=|kqLeIAyTy8pzpj8x8Ae4Fr8Mtlc= ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==' >> ~/.ssh/known_hosts - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Create /tmp/hermes/osx-bin directory - run: mkdir -p /tmp/hermes/osx-bin - - name: Download osx-bin release artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-osx-bin-Release - path: /tmp/hermes/osx-bin - - name: Download osx-bin debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-osx-bin-Debug - path: /tmp/hermes/osx-bin - - name: Download darwin-bin release artifacts - uses: actions/download-artifact@v4.1.3 + uses: actions/checkout@v4 + - name: Build NPM Package + uses: ./.github/actions/build-npm-package with: - name: hermes-darwin-bin-Release - path: /tmp/hermes/hermes-runtime-darwin - - name: Download darwin-bin debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-darwin-bin-Debug - path: /tmp/hermes/hermes-runtime-darwin - - name: Download hermes dSYM debug artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Debug - path: /tmp/hermes/dSYM/Debug - - name: Download hermes dSYM release vartifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-dSYM-Release - path: /tmp/hermes/dSYM/Release - - name: Download windows-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-win64-bin - path: /tmp/hermes/win64-bin - - name: Download linux-bin artifacts - uses: actions/download-artifact@v4.1.3 - with: - name: hermes-linux-bin - path: /tmp/hermes/linux64-bin - - name: Show /tmp/hermes directory - run: ls -lR /tmp/hermes - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup - with: - hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} - react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Copy Hermes binaries - shell: bash - run: | - mkdir -p ./packages/react-native/sdks/hermesc ./packages/react-native/sdks/hermesc/osx-bin ./packages/react-native/sdks/hermesc/win64-bin ./packages/react-native/sdks/hermesc/linux64-bin - - # When build_hermes_macos runs as a matrix, it outputs - if [[ -d $HERMES_WS_DIR/osx-bin/Release ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Release/* ./packages/react-native/sdks/hermesc/osx-bin/. - elif [[ -d $HERMES_WS_DIR/osx-bin/Debug ]]; then - cp -r $HERMES_WS_DIR/osx-bin/Debug/* ./packages/react-native/sdks/hermesc/osx-bin/. - else - ls $HERMES_WS_DIR/osx-bin || echo "hermesc macOS artifacts directory missing." - echo "Could not locate macOS hermesc binary."; exit 1; - fi - - # Sometimes, GHA creates artifacts with lowercase Debug/Release. Make sure that if it happen, we uppercase them. - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-debug.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz" - fi - - if [[ -f "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" ]]; then - mv "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-release.tar.gz" "$HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz" - fi - - cp -r $HERMES_WS_DIR/win64-bin/* ./packages/react-native/sdks/hermesc/win64-bin/. - cp -r $HERMES_WS_DIR/linux64-bin/* ./packages/react-native/sdks/hermesc/linux64-bin/. - - # Make sure the hermesc files are actually executable. - chmod -R +x packages/react-native/sdks/hermesc/* - - mkdir -p ./packages/react-native/ReactAndroid/external-artifacts/artifacts/ - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Debug.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-debug.tar.gz - cp $HERMES_WS_DIR/hermes-runtime-darwin/hermes-ios-Release.tar.gz ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-ios-release.tar.gz - cp $HERMES_WS_DIR/dSYM/Debug/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-debug.tar.gz - cp $HERMES_WS_DIR/dSYM/Release/hermes.framework.dSYM ./packages/react-native/ReactAndroid/external-artifacts/artifacts/hermes-framework-dSYM-release.tar.gz - - name: Use Node.js 18 - uses: actions/setup-node@v4.0.0 - with: - node-version: 18 - cache: yarn - - name: Install dependencies - run: yarn install --non-interactive - - name: Build packages - run: yarn build - # Continue with publish steps - - name: Set npm credentials - if: needs.set_release_type.outputs.RELEASE_TYPE == 'release' || - needs.set_release_type.outputs.RELEASE_TYPE == 'nightly' - run: echo "//registry.npmjs.org/:_authToken=${{ secrets.CIRCLE_NPM_TOKEN }}" > ~/.npmrc - - name: Publish NPM - shell: bash - run: | - # The checkout command puts react-native in a folder that is not "safe" for git - # Every git command run in an unsafe folder fails. We need to pick the current commit to use it as part of the version - # The following line marks the folder where react-native lives as "safe" - git config --global --add safe.directory /__w/react-native/react-native - - echo "GRADLE_OPTS = $GRADLE_OPTS" - # We can't have a separate step because each command is executed in a separate shell - # so variables exported in a command are not visible in another. - if [[ "${{ needs.set_release_type.outputs.RELEASE_TYPE }}" == "dry-run" ]]; then - export ORG_GRADLE_PROJECT_reactNativeArchitectures="arm64-v8a" - else - export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" - fi - node ./scripts/releases-ci/publish-npm.js -t ${{ needs.set_release_type.outputs.RELEASE_TYPE }} - - name: Zip Maven Artifacts from /tmp/maven-local - working-directory: /tmp - run: zip -r maven-local.zip maven-local - - name: Upload Maven Artifacts - uses: actions/upload-artifact@v4.3.1 - with: - name: maven-local - path: /tmp/maven-local.zip - - name: Upload npm logs - uses: actions/upload-artifact@v4.3.1 - with: - name: npm-logs - path: ~/.npm/_logs - - name: Build release package as a job artifact - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' - run: | - mkdir -p build - - FILENAME=$(cd packages/react-native; npm pack | tail -1) - mv packages/react-native/$FILENAME build/ - - echo $FILENAME > build/react-native-package-version - - name: Upload release package - uses: actions/upload-artifact@v4.3.1 - if: needs.set_release_type.outputs.RELEASE_TYPE == 'dry-run' - with: - name: react-native-package - path: build - - name: Update rn-diff-purge to generate upgrade-support diff - if: needs.set_release_type.outputs.RELEASE_TYPE == 'release' - run: | - curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \ - -d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${{ github.ref_name }}\" }}" + hermes-ws-dir: ${{ env.HERMES_WS_DIR }} + release-type: ${{ needs.set_release_type.outputs.RELEASE_TYPE }} test_android_helloworld: - runs-on: ubuntu-latest - needs: prepare_hermes_workspace + runs-on: 4-core-ubuntu + needs: build_npm_package container: image: reactnativecommunity/react-native-android:latest env: @@ -819,33 +471,26 @@ jobs: jsengine: [Hermes, JSC] steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - name: Cache setup - id: cache_setup - uses: ./.github/actions/cache_setup + uses: actions/checkout@v4 + - name: Setup git safe folders + run: git config --global --add safe.directory '*' + - name: Download npm package artifact + uses: actions/download-artifact@v4.1.3 with: - hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} - react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} - - name: Run yarn - shell: bash - run: yarn install --non-interactive + name: react-native-package + path: build + - name: Download maven-local artifact + uses: actions/download-artifact@v4.1.3 + with: + name: maven-local + path: /tmp/maven-local - name: Setup gradle uses: ./.github/actions/setup-gradle - - name: Build CodeGen JS scripts - shell: bash - run: | - cd packages/react-native-codegen - yarn run build - - name: Monitor Disk utilization (before build) + - name: Run yarn install + uses: ./.github/actions/yarn-install-with-cache + - name: Prepare the Helloworld application shell: bash - if: always() - run: | - echo "On Runner:" - df -h - echo "Root:" - du -hs * - echo "Projects folder:" - du -hs ./packages/* + run: node ./scripts/e2e/init-project-e2e.js --useHelloWorld --pathToLocalReactNative "$GITHUB_WORKSPACE/build/$(cat build/react-native-package-version)" - name: Build the Helloworld application for ${{ matrix.flavor }} with Architecture set to ${{ matrix.architecture }}, and using the ${{ matrix.jsengine }} JS engine. shell: bash run: | @@ -860,22 +505,12 @@ jobs: if [[ ${{ matrix.flavor }} == "Release" ]]; then args+=(--prod) fi - yarn build android "${args[@]}" -P reactNativeArchitectures="$TARGET_ARCHITECTURE" - - name: Monitor Disk utilization (after build) - shell: bash - if: always() - run: | - echo "On Runner:" - df -h - echo "Root:" - du -hs * - echo "Projects folder:" - du -hs ./packages/* + yarn build android "${args[@]}" -P reactNativeArchitectures="$TARGET_ARCHITECTURE" -P react.internal.mavenLocalRepo="/tmp/maven-local" - name: Upload artifact - uses: actions/upload-artifact@v4.3.1 + uses: actions/upload-artifact@v4.3.4 with: - name: template-apk-${{ matrix.flavor }}-${{ matrix.architecture }}-${{ matrix.jsengine }} - path: ./app/build/outputs/apk/ + name: helloworld-apk-${{ matrix.flavor }}-${{ matrix.architecture }}-${{ matrix.jsengine }} + path: ./packages/helloworld/android/app/build/outputs/apk/ compression-level: 0 test_ios_helloworld_with_ruby_3_2_0: @@ -887,8 +522,8 @@ jobs: YARN_ENABLE_IMMUTABLE_INSTALLS: false steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - uses: ./.github/actions/test_ios_helloworld + uses: actions/checkout@v4 + - uses: ./.github/actions/test-ios-helloworld with: ruby-version: 3.2.0 architecture: NewArch @@ -915,11 +550,37 @@ jobs: YARN_ENABLE_IMMUTABLE_INSTALLS: false steps: - name: Checkout - uses: actions/checkout@v4.1.1 - - uses: ./.github/actions/test_ios_helloworld + uses: actions/checkout@v4 + - uses: ./.github/actions/test-ios-helloworld with: flavor: ${{ matrix.flavor }} jsengine: ${{ matrix.jsengine }} use-frameworks: ${{ matrix.use_frameworks }} hermes-version: ${{ needs.prepare_hermes_workspace.outputs.hermes-version }} react-native-version: ${{ needs.prepare_hermes_workspace.outputs.react-native-version }} + + test_js: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + node-version: ["20", "18"] + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Test JS + uses: ./.github/actions/test-js + with: + node-version: ${{ matrix.node-version }} + + lint: + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Run all the Linters + uses: ./.github/actions/lint + with: + github-token: ${{ env.GH_TOKEN }} diff --git a/.github/workflows/update-node-modules-cache.yml b/.github/workflows/update-node-modules-cache.yml new file mode 100644 index 00000000000000..9c74021341b8bd --- /dev/null +++ b/.github/workflows/update-node-modules-cache.yml @@ -0,0 +1,18 @@ +name: Update node modules cache + +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + update_node_modules_cache: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Install yarn dependencies and update cache + uses: ./.github/actions/yarn-install-with-cache + with: + update-cache: "true" diff --git a/.gitignore b/.gitignore index 7f8de311318698..1218bfb15e0f5a 100644 --- a/.gitignore +++ b/.gitignore @@ -39,8 +39,6 @@ project.xcworkspace /packages/react-native/ReactAndroid/external-artifacts/artifacts/ /packages/react-native/ReactAndroid/hermes-engine/build/ /packages/react-native/ReactAndroid/hermes-engine/.cxx/ -/packages/react-native/template/android/app/build/ -/packages/react-native/template/android/build/ /packages/helloworld/android/app/build/ /packages/helloworld/android/build/ /packages/react-native-popup-menu-android/android/build/ @@ -108,16 +106,12 @@ package-lock.json # Ruby Gems (Bundler) /packages/react-native/vendor -/packages/react-native/template/vendor /packages/helloworld/vendor .ruby-version /**/.ruby-version vendor/ # iOS / CocoaPods -/packages/react-native/template/ios/build/ -/packages/react-native/template/ios/Pods/ -/packages/react-native/template/ios/Podfile.lock /packages/helloworld/ios/build/ /packages/helloworld/ios/Pods/ /packages/helloworld/ios/Podfile.lock @@ -163,10 +157,6 @@ vendor/ # Temporary files created by Metro to check the health of the file watcher .metro-health-check* -# E2E files -/packages/rn-tester-e2e/apps/*.apk -/packages/rn-tester-e2e/apps/*.app - # CircleCI .circleci/generated_config.yml diff --git a/.yarnrc.yml b/.yarnrc.yml index fd5296c36ec72c..4ea9859784a963 100644 --- a/.yarnrc.yml +++ b/.yarnrc.yml @@ -1,3 +1,7 @@ +compressionLevel: mixed + +enableGlobalCache: false + nodeLinker: node-modules yarnPath: .yarn/releases/yarn-4.3.1.cjs diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f999f30714403..6316f3936b5a7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,433 @@ # Changelog +## v0.75.2 + +### Added + +#### Android specific + +- **runtime:** Add support for handling `com.facebook.react.bridge.Dynamic` as parameter for TurboModules ([45cd81706d](https://github.com/facebook/react-native/commit/45cd81706d2c9ef7b792a716298cefa92ca2773a) by [@cortinico](https://github.com/cortinico)) + +### Changed + +#### Android specific + +- **ReactRootView:** Replaced `mLastHeight` with `mVisibleViewArea.height()` since mLastHeight value is not getting updated. For `width` we are already using `mVisibleViewArea.width()` ([603eb94dd9](https://github.com/facebook/react-native/commit/603eb94dd934f11ff568a3bd814e310bcbf152e1) by [@shubhamguptadream11](https://github.com/shubhamguptadream11)) +- **ImageSource:** `open` for inheritance ([02d9979c32](https://github.com/facebook/react-native/commit/02d9979c3298ff9c5c4490847f94242d7ef9ea3a) by [@cortinico](https://github.com/cortinico)) + +### Removed + +#### iOS specific + +- **RCTBaseTextInputView:** UIReturnKeyDefault ([26aff664c0](https://github.com/facebook/react-native/commit/26aff664c07f129e64e60b42aa0c7eeaa79a93c3) by [@elencho](https://github.com/elencho)) + +### Fixed + +- **codegen:** scripts require `yargs` ([0979921850](https://github.com/facebook/react-native/commit/0979921850b33a8c1abdf9d256138b78a403133a) by [@tido64](https://github.com/tido64)) + +## v0.75.1 + +### Changed + +- **hermes:** Bump Hermes version ([f202e80177](https://github.com/facebook/react-native/commit/f202e801776794ec30b2dc25fe87e52ec77c18ab) by [@cortinico](https://github.com/cortinico)) + +### Removed + +#### Android specific + +- **renderer:** Gate off % border radii on Android Paper ([bbd5b5e157](https://github.com/facebook/react-native/commit/bbd5b5e1574499478ab0bf3fe9d2a21b02b7fedd) by [@NickGerleman](https://github.com/NickGerleman)) +- **renderer:** Gate off % translate on Android Paper ([0273123dde](https://github.com/facebook/react-native/commit/0273123dde04de72da4ebfeff26b0830eea00745) by [@NickGerleman](https://github.com/NickGerleman)) + +## v0.75.0 + +### Breaking + +- **codegen:** Use hasteModuleName for C++ Turbo Module enums ([b7fc5867f2](https://github.com/facebook/react-native/commit/b7fc5867f2f8248db8230ce3602077547ca971a1) by [@christophpurrer](https://github.com/christophpurrer)) +- **codegen:** Use hasteModuleName for C++ Turbo Module structs ([07261d0408](https://github.com/facebook/react-native/commit/07261d0408e0250738504914ed931e71b838450e) by [@christophpurrer](https://github.com/christophpurrer)) +- **codegen:** Don't support 'float' enums in Turbo Modules ([536edf3726](https://github.com/facebook/react-native/commit/536edf3726c7de161bca5075110eaad0bd58c08e) by @christophpurrer) +- **codegen:** Native modules using the codegen now throw an error when called with `null` for optional but not nullable arguments. ([67b9628af5](https://github.com/facebook/react-native/commit/67b9628af588e8fc778d732fc387dbd48acf705e) by [@rubennorte](https://github.com/rubennorte)) +- **typescript:** Transform TouchableHighlight from JS `class` to `ForwardRef` component ([401f2fbb14](https://github.com/facebook/react-native/commit/401f2fbb14b1cfea93220810cce79b47720ecc72) by [@retyui](https://github.com/retyui)) +- **typescript:** Transform `TouchableOpacity` from JS `class` to `ForwardRef` component ([3d00549399](https://github.com/facebook/react-native/commit/3d0054939929608d317dc1e75a21dd20b9930eda) by [@retyui](https://github.com/retyui)) +- **eslint:** RN ESLint config no longer runs Prettier during ESLint ([727f30bd0b](https://github.com/facebook/react-native/commit/727f30bd0b27ff168e6a6556a9ffbc7e42dbb8f0) by [@gaearon](https://github.com/gaearon)) +- **c++:** ScrollViewShadowNode.h - Make getContentOriginOffset to know info about if call-site want transform or not ([ce588db63f](https://github.com/facebook/react-native/commit/ce588db63fb6510b8c06b85a82008a72c778792d) by [@realsoelynn](https://github.com/realsoelynn)) +- **c++:** RuntimeExecutor.h - Remove executeAsynchronously and executeSynchronously_CAN_DEADLOCK ([8b1a01610c](https://github.com/facebook/react-native/commit/8b1a01610c256beab43b093ced4f22eafbb943d9) by [@philIip](https://github.com/philIip)) +- **c++:** JsErrorHandler.h - Rename JsErrorHandlingFunc to OnJsError ([2e3f2268dc](https://github.com/facebook/react-native/commit/2e3f2268dccff379cbf0c2767465c8d20c38fdc5) by [@RSNara](https://github.com/RSNara)) +- **c++:** JsErrorHandler.h - Rename handleJsError to handleFatalError ([c041b9f40f](https://github.com/facebook/react-native/commit/c041b9f40f092d981fdfa01cd5dc3cbe6e874b5e) by [@RSNara](https://github.com/RSNara)) +- **c++:** ReactPrimitives.h - Remove unused imports (folly/dynamic.h) ([4fd95b6e02](https://github.com/facebook/react-native/commit/4fd95b6e02c82386ad85cea51f118f8055e4eb50) by [@christophpurrer](https://github.com/christophpurrer)) +- **c++:** LongLivedObjectCollection.h - Make `LongLivedObjectCollection::get` accept a Runtime reference as parameter. ([86a52cc2dc](https://github.com/facebook/react-native/commit/86a52cc2dc294131e138b1f6ee14b3e56e8c8572) by [@fabriziocucci](https://github.com/fabriziocucci)) +- **c++:** LongLivedObject.h - Make `LongLivedObject` constructor accept a `Runtime` reference. ([3706bf077e](https://github.com/facebook/react-native/commit/3706bf077e62b82a8c15874ac1ee6f0a7497468d) by [@fabriziocucci](https://github.com/fabriziocucci)) +- **c++:** Rename utils/jsi files ([d0cac87c6e](https://github.com/facebook/react-native/commit/d0cac87c6ea6caf528f0c164d4b43e3cfbb0b0b8) by [@TatianaKapos](https://github.com/TatianaKapos)) +- **TextInput:** Remove deprecated onTextInput callback ([34a50ae8ef](https://github.com/facebook/react-native/commit/34a50ae8ef559f309117d5b6abe0b68b2b349fa4) by [@javache](https://github.com/javache)) +- **Pressability:** Removed deprecated methods from Pressability. ([e4f3338069](https://github.com/facebook/react-native/commit/e4f3338069bfe70217a46239c468e4f12fa179fc) by [@javache](https://github.com/javache)) +- **cli:** Remove the ram-bundle command. ([58b45e86a6](https://github.com/facebook/react-native/commit/58b45e86a6fd78409dc358e27ae736c95fee9f39) by [@blakef](https://github.com/blakef)) + +#### Android specific + +- **ReactViewBackgroundDrawable:** Deprecate `ReactViewBackgroundDrawable` in favor of `CSSBackgroundDrawable` ([d7766fa927](https://github.com/facebook/react-native/commit/d7766fa9273ac47dc28935973b0402345b707885) by [@NickGerleman](https://github.com/NickGerleman)) +- **ReactContext:** Make ReactApplicationContext and ReactContext abstract. Please instantiate BridgeReactContext instead (bridge mode). Or BridgelessReactContext instead (bridgeless mode). ([e69f6755c8](https://github.com/facebook/react-native/commit/e69f6755c8d73e412acc444fbb1d36cad472e1bc) by [@RSNara](https://github.com/RSNara)) +- **layout:** Enable flex gap percentage value for RN. ([41a14962fc](https://github.com/facebook/react-native/commit/41a14962fc7adaf434f1634b17f3d66261e30a9f) by [@realsoelynn](https://github.com/realsoelynn)) +- **layout:**: Set and require `android:supportsRtl="true"` for RTL layout ([82c6f8a580](https://github.com/facebook/react-native/commit/82c6f8a58056cfa163a61a4e6668a54625b15d06) by [@NickGerleman](https://github.com/NickGerleman)) +- **turbomodule:** JSIModule - Deleting this class as you should be using `TurboModule` instead ([73b4d67a78](https://github.com/facebook/react-native/commit/73b4d67a78e003d62c660cf3c710e01b29512c4a) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **runtime:** ReactHostImpl - Removing `ReactJsExceptionHandler` param from constructor and providing a default private implementation ([fe7e7a015f](https://github.com/facebook/react-native/commit/fe7e7a015f30697c4ccffb2ba6474611efb4c08a) by [@alanleedev](https://github.com/alanleedev)) +- **DevSupport:** DevSupportManagerFactory - Method `.create()` changed to take an additional parameter of type `PausedInDebuggerOverlayManager` (nullable) ([1d26907ca4](https://github.com/facebook/react-native/commit/1d26907ca4d00cfa52f6395624b3121a7e96aca1) by [@motiz88](https://github.com/motiz88)) +- **runtime:** OnLoad.cpp - Make the app responsible for returning core turbomodule if not using default app setup/template ([7facb32f30](https://github.com/facebook/react-native/commit/7facb32f30d17eb27f870dd531d3dc7ebe4532f6) by [@RSNara](https://github.com/RSNara)) +- **measurement:** Delete UIManagerModule.measureLayoutRelativeToParent() ([958f8e2bb5](https://github.com/facebook/react-native/commit/958f8e2bb55ba3a2ace9507a48a582f546dd3ec2) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **PopUpMenu** UIManager.showPopupMenu() and UIManager.dismissPopupMenu() have been removed ([c631e93341](https://github.com/facebook/react-native/commit/c631e93341a33031f44087bc20c7e35e053d7d93) by [@alanleedev](https://github.com/alanleedev)) +- **ReactContext:** Delete ReactContext.initializeWithInstance(). ReactContext now no longer contains legacy react instance methods. Please use BridgeReactInstance instead. ([fb23470483](https://github.com/facebook/react-native/commit/fb234704832513d655a2890458eec66f873a5674) by [@RSNara](https://github.com/RSNara)), ([05ef779c0b](https://github.com/facebook/react-native/commit/05ef779c0b1722ad3827f382f7d3de5d0391afb0) by [@fabriziocucci](https://github.com/fabriziocucci)), ([14fb1cc335](https://github.com/facebook/react-native/commit/14fb1cc335b900666ef4fe6cec6a23a7a95bcf76) by [@RSNara](https://github.com/RSNara)), and ([f99dc486cd](https://github.com/facebook/react-native/commit/f99dc486cdd742988320a8235c180ccecdcdd0d6) by [@RSNara](https://github.com/RSNara)) +- **ReactContext** Remove getJavaScriptContextHolder() from BridgelessReactContext since now it can be accessed through BridgelessCatalystInstance in Bridgeless mode ([4595351310](https://github.com/facebook/react-native/commit/4595351310f353aad5a5f7af0fe2989650675cdc) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **ReactContext** Remove getRuntimeExecutor() from ReactContext since now it can be accessed through BridgelessCatalystInstance in Bridgeless mode ([f7b9aafd10](https://github.com/facebook/react-native/commit/f7b9aafd10a2f76c9bbdfdd1d925b4edf7a9dac3) by [@arushikesarwani94](https://github.com/arushikesarwani94)) + +#### iOS specific + +- **runtime:** RCTHost.h - Remove `getSurfacePresenter` and `getModuleRegistry` ([f19371f28d](https://github.com/facebook/react-native/commit/f19371f28ddbb660ed08a3e38aef85f27f0876a7) by [@cipolleschi](https://github.com/cipolleschi)) +- **Image:** Remove unused RCTImageLoadingPerfInstrumentationEnabled ([f6b9a42985](https://github.com/facebook/react-native/commit/f6b9a429853aa5fcb7895a144c77b538e9017c1e) by [@realsoelynn](https://github.com/realsoelynn)) +- **Error Handling:** Remove `RCTRedBox` access through `RCTBridge` ([b5db214d2a](https://github.com/facebook/react-native/commit/b5db214d2a6cc6e2336edd423ceeaec06dd7b4fc) by [@realsoelynn](https://github.com/realsoelynn)) +- **runtime** EventPriority - Remove EventPriority class and always use the default EventPriority::AsynchronousBatched. This is potentially a breaking change if something in OSS sets a different priority. If a build fails because of this, simply remove the use of EventPriority. ([55ed1c26ab](https://github.com/facebook/react-native/commit/55ed1c26ab7eda2a6ed1a7c41f3018b63fdd6a99) by [@sammy-SC](https://github.com/sammy-SC)) +- **PushNotificationIOS:** RCTPushNotificationManager - Deleting deprecated didReceiveLocalNotification & didReceiveRemoteNotification callbacks ([7fffe692e7](https://github.com/facebook/react-native/commit/7fffe692e715004ac4fee6418dfe8a462e180b4b)) +- **PushNotificationIOS:** PushNotificationIOS - Deleting deprecated alertAction and repeatInterval ([410e3b5ebd](https://github.com/facebook/react-native/commit/410e3b5ebd70fee7243c9c1d9d217cd912c01018)) +- **PushNotificationIOS:** PushNotificationIOS - Deleting old push notification implementation ([916dde4c60](https://github.com/facebook/react-native/commit/916dde4c604b4bba0e510ee1ab5c0cf5bd19ecbe) by [@philIip](https://github.com/philIip)) +- **cocoapods:** Rename BUILD_FROM_SOURCE to RCT_BUILD_HERMES_FROM_SOURCE ([6a1509f318](https://github.com/facebook/react-native/commit/6a1509f31858fad5aa1bdae4d6b0d10c5aebfaa4) by [@cipolleschi](https://github.com/cipolleschi)) +- **cocoapods:** Rename React-Codegen to ReactCodegen ([6549216b76](https://github.com/facebook/react-native/commit/6549216b765b850a5751075ce270fcb78e76b778) by [@dmytrorykun](https://github.com/dmytrorykun)) +- **TextInput:** Remove deprecated onTextInput callback ([24aece35b4](https://github.com/facebook/react-native/commit/24aece35b4a2bf196ad48900cdb8a3ca6ea53288) by [@Saadnajmi](https://github.com/Saadnajmi)) + +### Added + +- **Image:** `Image.getSize/getSizeWithHeaders` method returns a promise if you don't pass a `success` callback ([2c1bcbac81](https://github.com/facebook/react-native/commit/2c1bcbac81dc4506196c000d72d52b7e9c1c1ec1) by [@retyui](https://github.com/retyui)) +- **SectionList:** Fixes SectionList Unmounting issue with separatorComponent on data addition and removal. ([6204ea36d3](https://github.com/facebook/react-native/commit/6204ea36d321c9e27757d5f36ff7e74fa68c54d5) by [@Biki-das](https://github.com/Biki-das)) +- **cli:** Move cli Android build into core ([62acc29896](https://github.com/facebook/react-native/commit/62acc29896b635c9e2d62d96c3d9533bb912b3a3) by [@blakef](https://github.com/blakef)) +- **cli:** Move cli iOS build into core ([98f0893f39](https://github.com/facebook/react-native/commit/98f0893f392f33af3a6b4d20d8fcb25a4aac4a92) by [@blakef](https://github.com/blakef)) +- **cli:** core-cli-utils now builds for Android ([89f16da89e](https://github.com/facebook/react-native/commit/89f16da89e5670f2c7fc21100c84607daa680336) by [@blakef](https://github.com/blakef)) +- **codegen:** Add EventEmitter code-gen support for C++ Turbo Modules ([fd618819c7](https://github.com/facebook/react-native/commit/fd618819c7fd61422019ee1899980cb5ec4b5440) by [@christophpurrer](https://github.com/christophpurrer)) +- **codegen:** Add function to only generate RNCore components ([9a27c08fb9](https://github.com/facebook/react-native/commit/9a27c08fb9c80eb4b65a8dc7bd96db09e301bf72) by [@cipolleschi](https://github.com/cipolleschi)) +- **codegen:** Skip generation of RNCore if the files have been already generated ([03ba46f7e6](https://github.com/facebook/react-native/commit/03ba46f7e69d802530d43b5516da5f77def23fbd) by [@cipolleschi](https://github.com/cipolleschi)) +- **debugger:** Add `ReactNativeApplication.[enable,metadataUpdated]` CDP messages for reading host metadata ([aced4072cf](https://github.com/facebook/react-native/commit/aced4072cfebb1c41a06a2a25179c4c0bd173fe0) by [@huntie](https://github.com/huntie)) +- **debugger:** Inspector proxy: Add ping/pong keepalive to debugger connections. ([704756352c](https://github.com/facebook/react-native/commit/704756352c3228037063991385bdac2544322225) by [@robhogan](https://github.com/robhogan)) +- **debugger:** Support opening React DevTools from both Chrome DevTools frontend (React Native DevTools) and `react-devtools` standalone app ([430dd0be26](https://github.com/facebook/react-native/commit/430dd0be26c44821b2bdc2e818a81ac8a0b4b970) by [@hoxyq](https://github.com/hoxyq)) +- **runtime:** Add ReactRootViewTagGenerator ([7dec625eca](https://github.com/facebook/react-native/commit/7dec625ecabdc23cbae37e0034d29bb7bff17755) by [@christophpurrer](https://github.com/christophpurrer)) +- **runtime:** Added missing `remove` methods for `Linking.addEventListener` and `AccessibilityInfo.addEventListener` Jest mocks ([2483c63017](https://github.com/facebook/react-native/commit/2483c63017b0d47c377bf67cb7c597e2d7e57897) by [@levibuzolic](https://github.com/levibuzolic)) +- **runtime:** Implement `requestIdleCallback` and `cancelIdleCallback` in the new architecture ([abfadc6083](https://github.com/facebook/react-native/commit/abfadc60832b791892f81ae3f25dd8ac10ff7a99) by [@robik](https://github.com/robik)) +- **style:** Added `AppRegistry.setRootViewStyleProvider` ([dbdd4da14f](https://github.com/facebook/react-native/commit/dbdd4da14f9baf5f533e1e0ae9b98fa0c644ec14) by [@acoates-ms](https://github.com/acoates-ms)) +- **turbomodule:** Add EventEmitter C++ bridging type ([2a0a11256a](https://github.com/facebook/react-native/commit/2a0a11256a9919c70989aef00631da3a0f4afb25) by [@christophpurrer](https://github.com/christophpurrer)) +- **turbomodule:** Turbo Module EventEmitters as functions ([42f136d00d](https://github.com/facebook/react-native/commit/42f136d00d0917bad8928839dea01e99bb0a1c98) by [@christophpurrer](https://github.com/christophpurrer)) +- **typescript:** Add missing `Header` methods ([028615180b](https://github.com/facebook/react-native/commit/028615180b1fee8a4ab38a77163aa1fbfd68c6db) by [@retyui](https://github.com/retyui)) +- **typescript:** Allow to pass empty string as style ([1ea269f42c](https://github.com/facebook/react-native/commit/1ea269f42c2ef10e95fcf4751e71fba8bb5fe80d) by [@retyui](https://github.com/retyui)) + +#### Android specific + +- **Image:** Adds a new `Image` prop `resizeMultiplier` to help increase quality of small images on low DPI devices ([b6c3433537](https://github.com/facebook/react-native/commit/b6c343353765d8b13344841613250214fe8783db)) +- **PopUpMenu:** Add (optional) onPopupDismiss() callback for PopupMenuAndroid ([bc3e3360d1](https://github.com/facebook/react-native/commit/bc3e3360d1bd3fde9ab4d28c49757e3db0dad7f9) by [@alanleedev](https://github.com/alanleedev)) +- **StatusBar:** Added null checks, marked null safety in StatusBarModule ([7349dabae2](https://github.com/facebook/react-native/commit/7349dabae2eae35c8c24d544d7abf0d710ca26f8)) +- **StatusBar:** Added suppression for deprecated getter/setter usage in StatusBarModule ([ac51deeaf4](https://github.com/facebook/react-native/commit/ac51deeaf43723927d5000bee30d7f0b7a16575e)) +- **c++:** Allow bridgeless apps to register cxx modules via cxxreactpackages ([b9e52f0807](https://github.com/facebook/react-native/commit/b9e52f08073150f702b12dc5e38929e9651b806e) by [@RSNara](https://github.com/RSNara)) +- **c++:** Introduce CallInvokerHolder stable API ([69bb4fca44](https://github.com/facebook/react-native/commit/69bb4fca44c4a6c094b6c4c5c03a7e9aefa7ed1f) by [@philIip](https://github.com/philIip)) +- **colors** Update ColorPropConverter to support color function values ([4fb5573796](https://github.com/facebook/react-native/commit/4fb5573796e33868aefe4ebdcb8250e171af4989) by [@ryanlntn](https://github.com/ryanlntn)) +- **colors:** Add isWideColorGamutEnabled to ReactActivityDelegate ([0a9891a2f2](https://github.com/facebook/react-native/commit/0a9891a2f2bf8c18e00d7a9c0f299a4161417466) by [@ryanlntn](https://github.com/ryanlntn)) +- **colors:** Extend Property Processor to support long props ([0a80270187](https://github.com/facebook/react-native/commit/0a80270187c05fe2da1f25fb8a8426fd4f03f8f2) by [@cipolleschi](https://github.com/cipolleschi)) +- **colors:** Update ColorPropConverter to support color function values ([fa7dbd578d](https://github.com/facebook/react-native/commit/fa7dbd578d6e0bd394591b30671aa0ff9bddf40c) by [@ryanlntn](https://github.com/ryanlntn)) +- **colors:** Update bridge to handle long values ([0dc5c5f1f4](https://github.com/facebook/react-native/commit/0dc5c5f1f43701f396d2eb49bbabd2bfd2338cf4) by [@ryanlntn](https://github.com/ryanlntn)) +- **error handling**: Option to set a custom JSExceptionHandler instance ([098454d425](https://github.com/facebook/react-native/commit/098454d4250127a8b6dea8d8b36b2754953ed118)) +- **gradle:** Expose prefabs for newly added targets ([c16761da83](https://github.com/facebook/react-native/commit/c16761da833f7081e9378349e7f29cefbfe36d4f) by [@WoLewicki](https://github.com/WoLewicki)) +- **layout** Percentage support in translate ([c13790ff1d](https://github.com/facebook/react-native/commit/c13790ff1d11ef95ad04f7d7dc87f09a9cbf7025) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **layout:** Added support for using percentages when defining border radius related properties. ([181ed33ab0](https://github.com/facebook/react-native/commit/181ed33ab0ae3a67c5bcb73de315fb6d5e697388) by [@jorge-cab](https://github.com/jorge-cab)) +- **runtime:** Add 64 bit integer (long) value support to MapBuffer ([57ed0fb309](https://github.com/facebook/react-native/commit/57ed0fb30931979742634a1faa9a4d3b5261e50d) by [@ryanlntn](https://github.com/ryanlntn)) +- **runtime:** Add the `ReactMarkerConstants.CONTENT_APPEARED` support on Android in bridgeless mode. ([5da9fdf8f1](https://github.com/facebook/react-native/commit/5da9fdf8f1780d8e491f46ce721861dd4e41992b) by [@Kudo](https://github.com/Kudo)) +- **runtime:** Added `onUserLeaveHint` support into `ReactActivityDelegate` ([3cf6c64a80](https://github.com/facebook/react-native/commit/3cf6c64a800f96e398ad928d32de21d9e0dfe915) by [@behenate](https://github.com/behenate)) +- **runtime:** Added `onUserLeaveHint` support into `ReactActivityDelegate` ([6450d08187](https://github.com/facebook/react-native/commit/6450d08187952c157b5998e7bdc08f4b17f73281) by [@behenate](https://github.com/behenate)) +- **runtime:** Added featureflag to avoid additional background threads during execution ([4324f08749](https://github.com/facebook/react-native/commit/4324f08749433cc175f85246791bf8946b6ef04a) by [@javache](https://github.com/javache)) +- **runtime:** Added getNativeModule(name) to ReactContext ([fdb2427a86](https://github.com/facebook/react-native/commit/fdb2427a863809b3637678f94105fed7eceef4f6) by [@javache](https://github.com/javache)) +- **runtime:** GetJavaScriptContextHolder() supported in BridgelessReactContext since it's supported in ReactContext[Bridge] ([dfa6519749](https://github.com/facebook/react-native/commit/dfa65197491cb3ddfaaeca68d6c47a5bfb93eb83) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **runtime:** Introduce BridgeReactContext ([6386988de1](https://github.com/facebook/react-native/commit/6386988de1a55d082ffc8162571398ca8e3bafd5) by [@RSNara](https://github.com/RSNara)) +- **runtime:** Introduced ReactContext.hasReactInstance() to replace .hasCatalystInstance() ([3a3f3e6232](https://github.com/facebook/react-native/commit/3a3f3e6232d6eec7d8863a910e1f76a1c6003ccb) by [@RSNara](https://github.com/RSNara)) +- **turbomodule:** Add BindingsInstaller for TurboModules ([d999e9bf1e](https://github.com/facebook/react-native/commit/d999e9bf1ee6cad513be38c4f2c795ab58f59aa4) by [@Kudo](https://github.com/Kudo)) + +#### iOS specific + +- **Modal:** RCTConvert to support UIModalPresentationStyle ([2d547a3252](https://github.com/facebook/react-native/commit/2d547a3252b328251e49dabfeec85f8d46c85411) by [@vonovak](https://github.com/vonovak)) +- **TextInput:** Add all supported ReturnKeyTypes ([ed9978b8de](https://github.com/facebook/react-native/commit/ed9978b8de307d11def9190a461fc18b881800e0) by [@elencho](https://github.com/elencho)) +- **bridgeless** Expose host delegate methods ([f500b47a95](https://github.com/facebook/react-native/commit/f500b47a957dea5e1ca2687965fb7a6a3fa64001) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **c++:** Introduce CallInvoker support in bridgeless native modules ([8f9ff89093](https://github.com/facebook/react-native/commit/8f9ff8909353b0e6782278c24bd0519c5506e51d) by [@philIip](https://github.com/philIip)) +- **cocoapods:** Libraries can now declare Swift Package Manager dependencies in their .podspec with `ReactNativePodsUtils.spm_dependency` ([f903f34837](https://github.com/facebook/react-native/commit/f903f3483794f0e0e0b05ac24ab761344c319d6b) by [@mfazekas](https://github.com/mfazekas)) +- **color:** Add basic DisplayP3 color support ([a40bd8e34a](https://github.com/facebook/react-native/commit/a40bd8e34a4de61e9f7690f808fe978fab1df11c) by [@ryanlntn](https://github.com/ryanlntn)) +- **fonts:** Update font to handle system condensed variant ([86dffb3f15](https://github.com/facebook/react-native/commit/86dffb3f155dc9652f3abc32383643498b3a21b2) by [@shidoro](https://github.com/shidoro)) +- **layout:** Added support for using percentages when defining border radius related properties. ([9c4ee6df08](https://github.com/facebook/react-native/commit/9c4ee6df087f9bc3024d893f1d87d54646661512) by [@jorge-cab](https://github.com/jorge-cab)) +- **layout:** Percentage support in translate in new arch. ([f997b81288](https://github.com/facebook/react-native/commit/f997b81288148b4eee30b65375059feac2a14cd8) by [@intergalacticspacehighway](https://github.com/intergalacticspacehighway)) +- **runtime:** Add Instruments signposts API for SystraceSection ([840c31c3a4](https://github.com/facebook/react-native/commit/840c31c3a42c006527561cb003670845f7c921d7) by [@lyahdav](https://github.com/lyahdav)) +- **runtime::** Optimize RCTKeyWindow() for iOS 15+ ([b2fba371df](https://github.com/facebook/react-native/commit/b2fba371df0edafbb3323188004fc1f6d9ab1e8a) by [@okwasniewski](https://github.com/okwasniewski)) +- **swift** Set SWIFT_ACTIVE_COMPILATION_CONDITIONS to DEBUG ([756f89aa59](https://github.com/facebook/react-native/commit/756f89aa59cba78cba39b22a338a3a48bcb38f1b) by [@okwasniewski](https://github.com/okwasniewski)) +- **turbomodules** Add BindingsInstaller for TurboModules ([bed487e24b](https://github.com/facebook/react-native/commit/bed487e24b90a03b282b81cee5f7d2a203963d36) by [@Kudo](https://github.com/Kudo)) +- **xros:** Prebuilt version of Hermes for visionOS ([924fb3de9b](https://github.com/facebook/react-native/commit/924fb3de9bc9328c3315316fbb796b933be5bcbe) by [@okwasniewski](https://github.com/okwasniewski)) + +### Changed + +- **Animated:** Improved performance of `Animated` components ([452373b5bf](https://github.com/facebook/react-native/commit/452373b5bf4469d42af722851035e5e9bc3acdb9) by [@yungsters](https://github.com/yungsters)) +- **BlobModule:** Add info to invalid blob response error ([489df722b3](https://github.com/facebook/react-native/commit/489df722b3b9b4106d53d853d9ff6d0a3f177254)) +- **BlobModule:** Trim invalid blob response error message ([30463fb007](https://github.com/facebook/react-native/commit/30463fb007966fbd8803508cda025bc62c490265)) +- **Pressable:** Improve performance of `Pressable` component. ([cfa784c5ce](https://github.com/facebook/react-native/commit/cfa784c5cec060506d3d76e7819b50934f2c69be) by [@Zahoq](https://github.com/Zahoq)) +- **ScrollView:** MaintainVisibleContentPosition property on ScrollView now selects the first partially visible view as the anchor, rather than the first fully visible view. ([252ef19c8d](https://github.com/facebook/react-native/commit/252ef19c8d5bc5392d900af21136b351723f3b3c)) +- **StyleSheet** Optimized performance of `StyleSheet.compose` ([34331af9ce](https://github.com/facebook/react-native/commit/34331af9cea59595c903f2f95896037ab1b22b16) by [@yungsters](https://github.com/yungsters)) +- **c++:** Allow invoking the AsyncCallback synchronously to allow for tight performance optimization. ([765e542c8d](https://github.com/facebook/react-native/commit/765e542c8d25401e1b8818ff3caec2796efb51b1) by [@nlutsenko](https://github.com/nlutsenko)) +- **debugger:** Inspector proxy: Rewrite 127.0.0.1 to localhost in source map URLs for better IPv4->IPv6 tunnelling support. ([a52bd7dd08](https://github.com/facebook/react-native/commit/a52bd7dd080e1f0ad03209eecb69bda903470205) by [@robhogan](https://github.com/robhogan)) +- **debugger:** Update Chrome launch flags for `--experimental-debugger` launch flow ([b1bb0bee41](https://github.com/facebook/react-native/commit/b1bb0bee411436587e02942d187c08938f68d114) by [@motiz88](https://github.com/motiz88)) +- **deps:** Bumped @react-native-community/cli to 14.0.0 +- **hermes**: Enable regenerator transform for hermes-canary ([a0237e96f1](https://github.com/facebook/react-native/commit/a0237e96f1f0b5908008c0435a4efea120e77ac4) by [@avp](https://github.com/avp)) +- **hermes:** Disable Babel plugin for arrow functions for Hermes ([cdc3b9cdfc](https://github.com/facebook/react-native/commit/cdc3b9cdfc02eae3e76275b87b715c7669cc493f) by [@yungsters](https://github.com/yungsters)) +- **jest**: Enables React global flag that causes Jest testing environment to require `act()` ([5a8327857b](https://github.com/facebook/react-native/commit/5a8327857bdd6c2c96e0455258cba12512ea5dc8) by [@yungsters](https://github.com/yungsters)) +- **js:** Console polyfill now copies all properties from the existing `console` object ([949296571b](https://github.com/facebook/react-native/commit/949296571b36080d4ebe0bc8fac9ef3907367475) by [@motiz88](https://github.com/motiz88)) +- **linter:** `no-string-refs` is now a lint error ([387250112e](https://github.com/facebook/react-native/commit/387250112e9ff5d98e4d4172a2f3696042aba857) by [@yungsters](https://github.com/yungsters)) +- **react-dev-tools**: Upgrade[react-devtools-core]: ^5.3.1 ([2617ec5570](https://github.com/facebook/react-native/commit/2617ec55704d6aaa057fc20dc7e82235e1b3a799) by [@hoxyq](https://github.com/hoxyq)) +- **react:** Upgrade to `react@18.3.1` ([abb7070a51](https://github.com/facebook/react-native/commit/abb7070a512133e225646be3a1392667c3f1c966) by [@yungsters](https://github.com/yungsters)) +- **share** Update `Share.share()`'s argument types to be more explicit. ([8b53d41a88](https://github.com/facebook/react-native/commit/8b53d41a88c3c7c83183baa46be307102aa90d54)) +- **template:** Moved the template from react-native into react-native-community/template ([07abfceae1](https://github.com/facebook/react-native/commit/07abfceae117edc8ed205fe1ebaef89ce3041386) by [@blakef](https://github.com/blakef)) +- **testing**: `mockComponent` now also mocks `name` ([5062c5256e](https://github.com/facebook/react-native/commit/5062c5256e64c4db53ea7c7bfeae127715fef972) by [@yungsters](https://github.com/yungsters)) +- **testing:** Allow moving SyncCallback for advanced use-cases ([43c55e98d4](https://github.com/facebook/react-native/commit/43c55e98d493d60f9a05fb4f96efd54d1ea3bce8) by [@javache](https://github.com/javache)) +- **yoga**: Reduce warning level of distributed Yoga builds ([b696a7dc5e](https://github.com/facebook/react-native/commit/b696a7dc5e78dd42eb712e7c4b7d6f389526d933) by [@NickGerleman](https://github.com/NickGerleman)) + +#### Android specific + +- **Alert:** Migrated `AlertFragment` dialog builder to use `androidx.appcompat` (1/2) ([297ded90aa](https://github.com/facebook/react-native/commit/297ded90aa1e905a37dba316e7b19b6779c8c804)) +- **Alert:** Migrated `AlertFragment` dialog builder to use `androidx.appcompat` (2/2) ([600d3f6ff1](https://github.com/facebook/react-native/commit/600d3f6ff180de87fbe950c0e7558f11915e5966)) +- **deps:** Bump Fresco to 3.2.0 to fix CVE-2018-14498 ([744024be7f](https://github.com/facebook/react-native/commit/744024be7f95970bdd786931bdf10dd50c515124) by [@cortinico](https://github.com/cortinico)) +- **deps:** AGP to 8.5.0 ([19f6aec4a1](https://github.com/facebook/react-native/commit/19f6aec4a104f9b0dcfe3033e3c5cb6799338982) by [@cortinico](https://github.com/cortinico)) +- **deps:** Kotlin to 1.9.24 ([3f3abf5b40](https://github.com/facebook/react-native/commit/3f3abf5b40e60b7b9c02ec4942fec1be3684acc6) by [@cortinico](https://github.com/cortinico)) +- **DevSupport** Expose `openDebugger()` method on `DevSupportManager` ([b309af79e8](https://github.com/facebook/react-native/commit/b309af79e8bf2eb741db83b00359a73fe1b458a5) by [@motiz88](https://github.com/motiz88)) +- **DevSupport** In bridgeless, `useDevSupport` now is configurable by ReactNativeHost. ([d195fd0c06](https://github.com/facebook/react-native/commit/d195fd0c0622e9d833dacf879c7da9f5b3c5fccd) by [@javache](https://github.com/javache)) +- **DevSupport:** Decouple `DevInternalSettings` from `DevSupportManagerBase` ([52cec1e798](https://github.com/facebook/react-native/commit/52cec1e798c98ee948c34fad24a7b61d29e6ce2d) by [@Kudo](https://github.com/Kudo)) +- **DevSupport:** Update constructor signature of `DevServerHelper` ([a1e8118541](https://github.com/facebook/react-native/commit/a1e81185416a53c7c7d0cfc67e40079fd0073e7c) by [@huntie](https://github.com/huntie)) +- **gradle:** Expose `mapbufferjni` via prefab. ([c73e22142e](https://github.com/facebook/react-native/commit/c73e22142e9958fb406d5ca7d86228f938e5c8d5) by [@tomekzaw](https://github.com/tomekzaw)) +- **runtime:** Changed the `handleRemoveView` function in `ReactViewGroup.java` to ignore calls for `Views` that are not children of this `ViewGroup` ([0d7a92b551](https://github.com/facebook/react-native/commit/0d7a92b551bb8bd91aeba73316cbaf7315362094) by [@bartlomiejbloniarz](https://github.com/bartlomiejbloniarz)) +- **runtime:** Enforce Activities using ReactDelegate implement DefaultHardwareBackBtnHandler. ([a2d277f740](https://github.com/facebook/react-native/commit/a2d277f740d8ee95137d42679a1ffd872962a108) by [@javache](https://github.com/javache)) +- **runtime:** Simplified ReactActivityDelegate to expose a single createRootView method. ([3283202248](https://github.com/facebook/react-native/commit/3283202248a36dbda553745afc46a3e3e2ab41a6) by [@javache](https://github.com/javache)) +- **runtime:** Throwing IllegalArgumentException from ReactPackage is no longer suppressed ([2584bcb6c8](https://github.com/facebook/react-native/commit/2584bcb6c842b6a4fb7148dedc66f77c0f8210bb) by [@javache](https://github.com/javache)) + +#### iOS specific + +- **Modal:** Move the snapshotting code before the dismissal. ([30d6251b78](https://github.com/facebook/react-native/commit/30d6251b7890118290c1f7f7a9df69423e15a406) by [@cipolleschi](https://github.com/cipolleschi)) +- **Networking:** Fire `onprogress` event for `XMLHttpRequest` even when the `Content-Length` header is missing in the response headers ([457d14bd1b](https://github.com/facebook/react-native/commit/457d14bd1b85b0748b0824253753c6fee7ccc8bd)) +- **RCTAppDelegate:** Improve reusability for RCTRootViewFactory ([23709f7c61](https://github.com/facebook/react-native/commit/23709f7c61caebebafa9b01264176cb95204ec42) by [@Kudo](https://github.com/Kudo)) +- **RCTAppDelegate:** Support `customizeRootView` from `RCTRootViewFactory` ([8956869792](https://github.com/facebook/react-native/commit/89568697920230015f6146ac67a8fff87736d7dd) by [@Kudo](https://github.com/Kudo)) +- **cocoapods:** Add `DEFINES_MODULE` for React-jsinspector.podspec ([4e6186555e](https://github.com/facebook/react-native/commit/4e6186555eac8e98724e5027a882c92ee195652d) by [@Kudo](https://github.com/Kudo)) +- **ruby:** Update Gemfile in template ([06eea61c19](https://github.com/facebook/react-native/commit/06eea61c19cd730cf0c14a436f042d30791c3f4a) by [@matinzd](https://github.com/matinzd)) +- **runtime:** Fallback to the first `foregroundInactive` window when there are no `foregroundActive` windows in RCTKeyWindow ([42ceacd281](https://github.com/facebook/react-native/commit/42ceacd281011ba8a6833d13a083208574bd85f2) by [@cipolleschi](https://github.com/cipolleschi)) +- **runtime:** Move `notifyObservers` straight to `RCTEventDispatcher.mm`. ([f5c888c2d7](https://github.com/facebook/react-native/commit/f5c888c2d7c6dfe009de5df2cc795aff26286c19) by [@WoLewicki](https://github.com/WoLewicki)) + +### Deprecated + +- **cli:** npx react-native init is deprecated and will log a warning until 0.76 ([47a3f52007](https://github.com/facebook/react-native/commit/47a3f5200708fc0247d8b403dbe447af636b79cb) by [@blakef](https://github.com/blakef)) +- **runtime:** Deprecate RCTRuntimeExecutorModule ([7ea84bd3eb](https://github.com/facebook/react-native/commit/7ea84bd3eb228529e341f9fab5abf6ddda961db8) by [@philIip](https://github.com/philIip)) + +### Removed + +- **Image:** Remove non-existent methods from `` component ([09c903c439](https://github.com/facebook/react-native/commit/09c903c43922d83ddae1602751804c34b5aeff86) by [@retyui](https://github.com/retyui)) +- **TextInput:** Remove viewconfigs for onTextInput callbacks ([910cde6134](https://github.com/facebook/react-native/commit/910cde6134d5c1f6886764ab27c1102584532795) by [@javache](https://github.com/javache)) +- **debugger:** `launchId` query param for `/debugger-frontend` is no longer generated automatically for each `/open-debugger` call. Caller of `/open-debugger` is now responsible for generating the `launchId`, which will be passed along to `/debugger-frontend`. ([b7de916664](https://github.com/facebook/react-native/commit/b7de91666453b832b889d9577226097aeeace1a8) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) +- **dev-middleware:** `react-native/dev-middleware`: Remove non-standard `faviconUrl` field from CDP `/json` response ([df19e597e3](https://github.com/facebook/react-native/commit/df19e597e3e8be9c76f6dba885fd978095710f49) by [@huntie](https://github.com/huntie)) +- **typescript:** Remove `tvParallaxProperties` prop from `TouchableOpacity` & add missing `focusable`, `rejectResponderTermination` props ([0a0cd6517f](https://github.com/facebook/react-native/commit/0a0cd6517fdd6fbcc751b4d9ae19106740b23703) by [@retyui](https://github.com/retyui)) +- **android - Animated:** Removed `NativeAnimationsDebugModule` (already not Public API) ([95f7a5c597](https://github.com/facebook/react-native/commit/95f7a5c597eeb8db3a19777cac1ea14e58682cf0) by [@yungsters](https://github.com/yungsters)) +- **ios - cocoapods: ** Delete deprecated Xcode version check ([2b85a236a1](https://github.com/facebook/react-native/commit/2b85a236a1121d86b3a99f0d9c6da0ae35817a8c) by [@naxey](https://github.com/naxey)) + +### Fixed + +- **Animated:** Fix broken native animation in Paper ([92540a618d](https://github.com/facebook/react-native/commit/92540a618d336c747c0ebdfffdd1a2a0a82e636d) by [@sammy-SC](https://github.com/sammy-SC)) +- **Animated:** Fix sequence restart failure ([a93a15aca3](https://github.com/facebook/react-native/commit/a93a15aca3e380f2f8158465b1b315ac3fab8307) by [@asyler](https://github.com/asyler)) +- **Animated:** Fixed memoization for components wrapped with createAnimatedComponent ([be06fd4e22](https://github.com/facebook/react-native/commit/be06fd4e22a500128d202436600381b8bc17b3f5)) +- **Button:** Adds forwardRef call to new functional component implementation of Button control. ([8e7263a415](https://github.com/facebook/react-native/commit/8e7263a415676d1fb08da027c9dc6ca9fc2b6573) by [@chiaramooney](https://github.com/chiaramooney)) +- **FlatList:** Fix clicking items on the inverted FlatList on the new architecture ([3753b7a0e7](https://github.com/facebook/react-native/commit/3753b7a0e78f8820e5f5150dd9bdf1b53145a7bd) by [@kosmydel](https://github.com/kosmydel)) +- **Networking** Fix fetch memory leak ([c647950e5e](https://github.com/facebook/react-native/commit/c647950e5e78f1bcd110111067b21daa44e4d464) by [@huzhanbo1996](https://github.com/huzhanbo1996)) +- **TextInput** Handle `fontWeight` normalization for TextInput component ([15f27bc299](https://github.com/facebook/react-native/commit/15f27bc299a0d1e6a5dec81efb594f54039120a7) by [@NickGerleman](https://github.com/NickGerleman)) +- **Touchable:** Fixed inconsistency in TouchableX component disabled / focusable behavior ([775713cef7](https://github.com/facebook/react-native/commit/775713cef7ff7b45a60c34e4f1629dc6cde1aa05) by [@rozele](https://github.com/rozele)) +- **c++:** Avoid ShadowTreeRegistry::mutex_ read lock reentrancy ([1a164fae6a](https://github.com/facebook/react-native/commit/1a164fae6a27051d0a3fd9f7aa094c384c58d4c4) by [@rozele](https://github.com/rozele)) +- **cli:** Allow proxying commands from react-native to react-native-community/cli with explicit warning ([9aed45a9d9](https://github.com/facebook/react-native/commit/9aed45a9d99218e7468ce2779dcbaa40cce50c83) by [@blakef](https://github.com/blakef)) +- **cli:** Fix version checker not considering nightlies ([489d9f6c62](https://github.com/facebook/react-native/commit/489d9f6c624aa0b3e2607cd70e46adbb2ea7162d) by [@tido64](https://github.com/tido64)) +- **codegen:** Align CodegenSchema.d.ts with CodegenSchema.js ([ea3a7143b9](https://github.com/facebook/react-native/commit/ea3a7143b9c8e886a6cf5ffd04386c3b19ef6b4a) by [@christophpurrer](https://github.com/christophpurrer)) +- **codegen:** Don't break script phase and codegen when coreutils installed on macOS ([e0799536ef](https://github.com/facebook/react-native/commit/e0799536ef1b68b98fb772e256d1d72424349008) by [@blakef](https://github.com/blakef)) +- **codegen:** Fixed `Props.h` created from codegen missing default initializers in C++ `struct` ([639d890dff](https://github.com/facebook/react-native/commit/639d890dff49af788fbe27c60b33f6025ec33cca) by [@alanleedev](https://github.com/alanleedev)) +- **codegen:** Make sure that we can't include Codegen symbols multiple times ([46b6453eb6](https://github.com/facebook/react-native/commit/46b6453eb6fe5435a792aa4a0f9183446f4fa41f) by [@cipolleschi](https://github.com/cipolleschi)) +- **codegen:** Fixed crash when passing fewer arguments than expected in native modules using codegen ([179b684e76](https://github.com/facebook/react-native/commit/179b684e7636361f7acd782cdf028c7c30b7b9fd) by [@rubennorte](https://github.com/rubennorte)) +- **codegen:** Fixed crash when passing non-numeric values where RootTag is expected to methods in native modules using codegen ([abbc6eb022](https://github.com/facebook/react-native/commit/abbc6eb02251d8c510b3fb5415796a8f05388c98) by [@rubennorte](https://github.com/rubennorte)) +- **codegen:** Fixes enum codegen value cases ([1a1795a537](https://github.com/facebook/react-native/commit/1a1795a537f3fdb8417149565c7bd4221af2b72e) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **debugger:** LogBox and Chrome DevTools stack frame collapsing patterns are now compatible with Windows file paths. ([8d0046a5e1](https://github.com/facebook/react-native/commit/8d0046a5e10ca27a073e5509ca70ffab15d2d3e9) by [@motiz88](https://github.com/motiz88)) +- **debugger:** Debugger frontend socket-termination countdown now begins after the ping message is actually sent ([20462ca984](https://github.com/facebook/react-native/commit/20462ca984ae306d6ea829c381d91d4df1cb1cde) by [@EdmondChuiHW](https://github.com/EdmondChuiHW)) +- **debugger:** Fix breakpoints opening to incorrect location or disappearing from debugger frontend UI. ([ac714b1c33](https://github.com/facebook/react-native/commit/ac714b1c3300d3a169bdcfec05d556e18a7b83ff) by [@robhogan](https://github.com/robhogan)) +- **debugger:** Inspector proxy: prevent errors proxying a device message from blocking the handler queue or spamming logs. ([e05319cc87](https://github.com/facebook/react-native/commit/e05319cc872c7d99c5ba33641a7791a3db2b3415) by [@robhogan](https://github.com/robhogan)) +- **error handling:** Fixed LogBox not showing correctly on the New Architecture ([db1043dfbf](https://github.com/facebook/react-native/commit/db1043dfbf15b8d2e39eeb50b315384aa39e4606) by [@rubennorte](https://github.com/rubennorte)) +- **error handling:** Remove accidental duplication in React warnings in Logbox ([32c3cd3e8a](https://github.com/facebook/react-native/commit/32c3cd3e8addb924f904de19c6e311a0ddb4e963) by [@gaearon](https://github.com/gaearon)) +- **error handling:** Fix logbox reporting for React errors ([64e6721b23](https://github.com/facebook/react-native/commit/64e6721b23e9f3c35d42d5b1f1b68220e46a34ed) by [@yungsters](https://github.com/yungsters)) +- **error handling:** Support component stacks without source info. ([1b53051b8c](https://github.com/facebook/react-native/commit/1b53051b8c0661095dbcb7546432eeda3a129fd4) by [@rickhanlonii](https://github.com/rickhanlonii)) +- **error handling:** Support component stacks without source info. ([e9e668f0ec](https://github.com/facebook/react-native/commit/e9e668f0eca625248a95c53a506d33a4ec389f70) by [@rickhanlonii](https://github.com/rickhanlonii)) +- **error handling:** Support hermes component stacks with missing source info. ([82db330360](https://github.com/facebook/react-native/commit/82db33036029c232cbaec7e58f2d84c873504732) by [@rickhanlonii](https://github.com/rickhanlonii)) +- **infra:** Replace deprecated babel-plugin libraries to fix deprecation warnings on installation ([6213b2a62a](https://github.com/facebook/react-native/commit/6213b2a62a2366b150e0ac60aa8693baac2bb1d1) by [@kaganece](https://github.com/kaganece)) +- **jest:** Fix jest setup for Image methods (resolveAssetSource, getSize, prefetch, queryCache) ([d53cc2b46d](https://github.com/facebook/react-native/commit/d53cc2b46dee5ed4d93ee76dea4aea9da42d0158)) +- **layout:** Fix duplicate rotation operations ([54f582f651](https://github.com/facebook/react-native/commit/54f582f651c68e9fa6bedb5d1546f4e5a4a64704) by [@NickGerleman](https://github.com/NickGerleman)) +- **layout:** Fixed padding not being applied to inline views in text ([12aef32b82](https://github.com/facebook/react-native/commit/12aef32b82325ab143b6ed421f3cbf0f8be66f60) by [@j-piasecki](https://github.com/j-piasecki)) +- **layout:** Fixup margin: auto and justification behavior for overflowed containers ([f21d9afe0b](https://github.com/facebook/react-native/commit/f21d9afe0b0ddd97d89e89886d0d8e58739174ac) by [@NickGerleman](https://github.com/NickGerleman)) +- **runtime:** Add `collapsableChildren` prop ([7b44c8d1d0](https://github.com/facebook/react-native/commit/7b44c8d1d0a089a766c7eab1b5435b2dbf61454c) by [@NickGerleman](https://github.com/NickGerleman)) +- **runtime:** Add missing `NativeState` methods to the `WithRuntimeDecorator` class. ([218ea5d44c](https://github.com/facebook/react-native/commit/218ea5d44cae5774b1445cbc9e07d1ea3ef773d1) by [@bartlomiejbloniarz](https://github.com/bartlomiejbloniarz)) +- **runtime:** Add option for multiple `mountingOverrideDelegates` ([358fe46969](https://github.com/facebook/react-native/commit/358fe46969654932e73af94127c05e6ce5ed7049) by [@WoLewicki](https://github.com/WoLewicki)) +- **runtime:** Fixed prioritization of idle priority tasks, which were incorrectly scheduled as immediate priority ([0ca3ed87f3](https://github.com/facebook/react-native/commit/0ca3ed87f3424a333c815c9d57b17f133dd19eab) by [@rubennorte](https://github.com/rubennorte)) +- **runtime:** New architecture timer methods now return integers instead of an opaque object. ([a16f7dc547](https://github.com/facebook/react-native/commit/a16f7dc547e85daed7e3732142f36cce5699faa0) by [@javache](https://github.com/javache)) + +#### Android specific + +- **Animated:** Reduce maximum log spam from FrameBasedAnimationDriver ([42299499d8](https://github.com/facebook/react-native/commit/42299499d8cac0b3e6ae7814ca375005ecfa05f0)) +- **DevMenu:** ShouldShowDevMenuOrReload() in RELEASE mode ([63043b79be](https://github.com/facebook/react-native/commit/63043b79be50b2589de96c63922b7909ca1f381f) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **DevSupport:** OnKeyLongPress() in RELEASE mode ([bdcc979bab](https://github.com/facebook/react-native/commit/bdcc979bab2cb300e540c031a7c54e05b2328410) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **Modal:** Fix a crash in Modal component ([d116837da2](https://github.com/facebook/react-native/commit/d116837da2734709f5f85dac1515d118b172bdcf) by [@sammy-SC](https://github.com/sammy-SC)) +- **PointerEvents:** PointerEvents were not dispatching after a scroll event ([766ece7b9b](https://github.com/facebook/react-native/commit/766ece7b9b1a578d5b7acd99bc8b0055e862fa86) by [@javache](https://github.com/javache)) +- **PointerEvents:** Views would still receive hover events when nested in a view with pointer-events: "none" ([38cbc082db](https://github.com/facebook/react-native/commit/38cbc082db92abdc00a73be0485999f406a05fe6) by [@javache](https://github.com/javache)) +- **ReactDelegate:** Fixing exposing ReactDelegate through ReactActivity for reload() ([e25860f07c](https://github.com/facebook/react-native/commit/e25860f07c6af8d529d618da3ded556485ca0a73) by [@arushikesarwani94](https://github.com/arushikesarwani94)) +- **ScrollView:** Add support for scrollEventThrottle for ScrollView on the New Architecture. ([4d2262b8d2](https://github.com/facebook/react-native/commit/4d2262b8d2b38eddbdfb2264a33f87c28aa7712f) by [@dmytrorykun](https://github.com/dmytrorykun)) +- **ScrollView:** Fix maintainVisibleContentPosition during momentum scroll ([a9e6759bb5](https://github.com/facebook/react-native/commit/a9e6759bb5d8f08c444b7a324c4488b9e5f2ed1b) by [@janicduplessis](https://github.com/janicduplessis)) +- **StatusBar:** Fixed StatusBar.currentHeight calculations to honor all cutout sizes ([0b8222a854](https://github.com/facebook/react-native/commit/0b8222a854a0f0e7808d596a57596f4dd98135f2)) +- **StatusBar:** Fixed StatusBar.currentHeight calculations to honor all cutout sizes ([cc485ccf7d](https://github.com/facebook/react-native/commit/cc485ccf7dddbcbdcfb03457fd2a48569fab5820)) +- **Text:** Fixed `adjustFontSizeToFit` when used without `numberOfLines` ([b236e154a1](https://github.com/facebook/react-native/commit/b236e154a1e29885258d325241fb94afb80a7f57) by [@j-piasecki](https://github.com/j-piasecki)) +- **Text:** Fixed `adjustsFontSizeToFit` not working on Android when using the new architecture ([747a96b7b3](https://github.com/facebook/react-native/commit/747a96b7b39fa53db353ef739560e27c6679d7fc) by [@j-piasecki](https://github.com/j-piasecki)) +- **autolinking:** Fix autolink plugin for libraries that are platform-specific ([20521cc908](https://github.com/facebook/react-native/commit/20521cc908a347e3a2b3ac0fd6710946f18b1510) by [@gabrieldonadel](https://github.com/gabrieldonadel)) +- **autolinking:** Fix core autolinking not working on Windows ([c8cb3d4a59](https://github.com/facebook/react-native/commit/c8cb3d4a5904a5aab7fd41bedb032a919ef0758e) by [@cortinico](https://github.com/cortinico)) +- **autolinking:** If `npx react-native-community/cli config` fails or timeouts proper error is shown and built is aborted, instead of leaving and empty autolinking.json ([3782511350](https://github.com/facebook/react-native/commit/3782511350c069425ad11cdefb8c6d3f10526fc2) by [@mfazekas](https://github.com/mfazekas)) +- **error handling:** Android exceptions without a message would lead to unexpected crashes ([48f48f8e67](https://github.com/facebook/react-native/commit/48f48f8e6726103d1537193d52144cbce2402168) by [@javache](https://github.com/javache)) +- **error handling:** Fixed android native rejections should be instanceof Error ([62cbdbbcc6](https://github.com/facebook/react-native/commit/62cbdbbcc60f9074e47416007aef81e0792d7c95) by [@huzhanbo1996](https://github.com/huzhanbo1996)) +- **error handling:** Show RedBox after reloads fail (bridgeless) ([2f8d4f0c25](https://github.com/facebook/react-native/commit/2f8d4f0c253853ec4f56cf01b41a1f73a393f804) by [@RSNara](https://github.com/RSNara)) +- **gradle:** Fixed build from source failing due to a missing file ([b2898540c9](https://github.com/facebook/react-native/commit/b2898540c9ba3616f7bb8f9d3d621be1fbba0d85) by [@j-piasecki](https://github.com/j-piasecki)) +- **gradle:** Make `rrc_textinput` on Android a shared library ([ea8ad6457c](https://github.com/facebook/react-native/commit/ea8ad6457c0bb55d2a1150e7af6d0d20f3237006) by [@j-piasecki](https://github.com/j-piasecki)) +- **kotlin:** Fix crash due to missing JvmStatic to `convertToCase` ([cef17ba14f](https://github.com/facebook/react-native/commit/cef17ba14f435b966d2ffd9b3660ccf28fe03b6c) by [@cortinico](https://github.com/cortinico)) +- **kotlin:** Use `JvmStatic` annotations for all methods from `AndroidUnicodeUtils.kt` ([54dadd7bda](https://github.com/facebook/react-native/commit/54dadd7bda0431548760aab0fade57f083d716a8) by [@WoLewicki](https://github.com/WoLewicki)) +- **layout** Propagate layout direction to Android Views and Drawables ([e16faca18c](https://github.com/facebook/react-native/commit/e16faca18c052a1c3b7ce6fb3b8236347b222e8a) by [@NickGerleman](https://github.com/NickGerleman)) +- **layout:** Better overflow support for ScrollView, Text, TextInput ([bfb3b7008d](https://github.com/facebook/react-native/commit/bfb3b7008d3e83400154b0348e7ab680ee06aa8c) by [@NickGerleman](https://github.com/NickGerleman)) +- **layout:** Fix cached spannable measurement path ([002396beae](https://github.com/facebook/react-native/commit/002396beae3c5d107b44968c1b1906040054e3da) by [@NickGerleman](https://github.com/NickGerleman)) +- **layout:** Fixed `textAlign` not being taken into account when positioning views inlined in text ([1f08799560](https://github.com/facebook/react-native/commit/1f087995608fd016a8a3dd84c0ca88a9239d96b9) by [@j-piasecki](https://github.com/j-piasecki)) +- **layout:** Resolved error "No virtual method setLeftTopRightBottom" ([08ecdee71c](https://github.com/facebook/react-native/commit/08ecdee71c9d5a4e385a585941ca93ae1002b01f) by [@mmmoussa](https://github.com/mmmoussa)) +- **renderer:** Cascading renders were not mounting correctly when `batchRenderingUpdatesInEventLoop` is enabled. ([849da2146c](https://github.com/facebook/react-native/commit/849da2146ca27b7512f2f3ea0f8af8aa001e807a) by [@javache](https://github.com/javache)) +- **runtime:** Fix ClassCastException in `ReactModalHostView` ([15ff82f811](https://github.com/facebook/react-native/commit/15ff82f811287f9a686d993af9ee80f891a7774f) by [@cortinico](https://github.com/cortinico)) +- **runtime:** Fix a case when view preallocation or props forwarding on Android lead to dropped props update ([cf926a1329](https://github.com/facebook/react-native/commit/cf926a1329a8cd6921e9799877883ac1fbc26fbb) by [@sammy-SC](https://github.com/sammy-SC)) +- **runtime:** Fix crash in `getChildAtWithSubviewClippingEnabled` ([d6a44e632a](https://github.com/facebook/react-native/commit/d6a44e632a7ffbd60b90dac410294947cd82f2d8) by [@javache](https://github.com/javache)) +- **runtime:** Fix dynamic_cast (RTTI) for ShadowNodeWrapper when accessed by third-party libraries again ([ea958c69f6](https://github.com/facebook/react-native/commit/ea958c69f624be67c770384c203f86255c1eebec) by [@tomekzaw](https://github.com/tomekzaw)) +- **runtime:** Fixed app reloading for `ReactActivity.getReactDelegate().reload()`. ([539922339b](https://github.com/facebook/react-native/commit/539922339b5ca1937ce3207038199a27566914fe) by [@Kudo](https://github.com/Kudo)) +- **runtime:** Fixed error thrown during ReactInstance teardown ([e67d5560cf](https://github.com/facebook/react-native/commit/e67d5560cfd35f07ce74cfcc12555346a6f0e865) by [@javache](https://github.com/javache)) +- **runtime:** Improved resiliency of reloads when bundle loading fails ([524e3eec3e](https://github.com/facebook/react-native/commit/524e3eec3e73f56746ace8bef569f36802a7a62e) by [@javache](https://github.com/javache)) +- **runtime:** Local scheduler for thread-safe ([7dd91d3437](https://github.com/facebook/react-native/commit/7dd91d3437952cf19569efce30c823d14bdf6c9d) by [@Sunbreak](https://github.com/Sunbreak)) +- **runtime:** Surfaces no longer leak activity once stopped ([af721084af](https://github.com/facebook/react-native/commit/af721084afd5ba530e47fb353e8e5b1c4d9f56b7)) +- **runtime:** Tentative fix for NPE `JavaTimerManager$IdleCallbackRunnable.cancel` ([e686b4330d](https://github.com/facebook/react-native/commit/e686b4330d0a69fe78008b7eac86c54c9f96ee79) by [@cortinico](https://github.com/cortinico)) +- **runtime:**: ViewManagers can pass context to their base class. ([90663081de](https://github.com/facebook/react-native/commit/90663081de872243203da99116d2cab0fbec95ff) by [@javache](https://github.com/javache)) +- **runtime:** Unmount React root when activity is destroyed on Bridgeless ([33aa83a0e6](https://github.com/facebook/react-native/commit/33aa83a0e6f63d3d50d4803074ad9e2243439100) by [@fabriziocucci](https://github.com/fabriziocucci)) +- **style:** Border-Radius percentages are now correctly resolved. ([082e29ed4e](https://github.com/facebook/react-native/commit/082e29ed4ecc40ed9dfeae6b1b94d5a33efddef0) by [@jorge-cab](https://github.com/jorge-cab)) +- **style:** Fix borderRadius incorrect overrides ([8d5bbca1eb](https://github.com/facebook/react-native/commit/8d5bbca1eb8b91d0f678b557996a78c091976a53) by [@jorge-cab](https://github.com/jorge-cab)) +- **turbomodule:** Cover SingletonMap when parsing events exported by module ([8a15e0d97a](https://github.com/facebook/react-native/commit/8a15e0d97ad7556b9f1b4068662791a32e1ae3d2) by [@WoLewicki](https://github.com/WoLewicki)) + +#### iOS specific + + +- **Animated:** Fixes animated frame timing ([690df7a556](https://github.com/facebook/react-native/commit/690df7a5561d93da27f69ff803bed453652ad51c) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **ContextMenu:** Hide AutoFill from context menu when using `contextMenuHidden` ([493dbb2190](https://github.com/facebook/react-native/commit/493dbb21907c71e2a220876eddd08a5ea075e1e8) by [@jakex7](https://github.com/jakex7)) +- **DevMenu:** Fix RCTPerfMonitor not showing up in scene based app ([16775215d5](https://github.com/facebook/react-native/commit/16775215d5a734288da7147db348824395198407) by [@ouabing](https://github.com/ouabing)) +- **InteropLayers:** Make sure to pass the RCTBridgeProxy to ViewManagers ([d6c90cf7ed](https://github.com/facebook/react-native/commit/d6c90cf7ed80caf0fc4eb2541f3dcadc3833dd37) by [@cipolleschi](https://github.com/cipolleschi)) +- **Networking:** Fixed headers content type check for iOS bundle download ([d9b0f15c84](https://github.com/facebook/react-native/commit/d9b0f15c844abce5e97edfd401656d84d0c84133) by [@jayshah123](https://github.com/jayshah123)) +- **PullToRefresh:** Properly recycle the RCTPullToRefreshViewComponentView ([18f0a90358](https://github.com/facebook/react-native/commit/18f0a90358b4e7eb59871cc11a88ef9bef575246) by [@cipolleschi](https://github.com/cipolleschi)) +- **RCTAppDelegate:** Added space to $(inherited) string to avoid creation of wrong cpp flags in RCTAppDelegate podspec ([be93092c1b](https://github.com/facebook/react-native/commit/be93092c1b8a079f74dcdc129afc3767f03b8a2e) by [@nikhiltekwani09](https://github.com/nikhiltekwani09)) +- **RCTAppDelegate:** Add missing forward blocks to RCTRootViewFactory ([9d79f05e68](https://github.com/facebook/react-native/commit/9d79f05e68cd64bf8b213ff89a25726184ef387c) by [@okwasniewski](https://github.com/okwasniewski)) +- **RCTAppDelegate:** Allow importing RCTAppDelegate in Swift ([7c953698b4](https://github.com/facebook/react-native/commit/7c953698b41af7187504fa56a9a7c943ae724cd0) by [@okwasniewski](https://github.com/okwasniewski)) +- **RCTAppDelegate:** Allow usage of `RCTRootViewFactory` from Swift ([5aea518d88](https://github.com/facebook/react-native/commit/5aea518d880ff73c91b8e462b9aa40ac0d218538) by [@okwasniewski](https://github.com/okwasniewski)) +- **RCTAppDelegate:** Fixed Method name in hint from customiseView to customizeRootView ([46d4b837a5](https://github.com/facebook/react-native/commit/46d4b837a581168507b569744cae459bd1f4a70c) by [@svengiebel](https://github.com/svengiebel)) +- **RCTAppDelegate:** Fixes customizeRootView migration comment ([fbf9c4343a](https://github.com/facebook/react-native/commit/fbf9c4343ae922013b008a7d855c5927b7113e60) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **RCTAppDelegate:** Remove loadSourceForBridge in RCTRootViewFactory ([0c02b26c1e](https://github.com/facebook/react-native/commit/0c02b26c1e00ca27d7a3ba4244a0957d4cb473aa) by [@okwasniewski](https://github.com/okwasniewski)) +- **SCrollView:** Preserve content offset in ScrollView when the component is suspended ([510d2906b2](https://github.com/facebook/react-native/commit/510d2906b21b8c4c063369d2c2cb391aad268fea) by [@sammy-SC](https://github.com/sammy-SC)) +- **ScrollCiew:** Remove usage of deprecated scrollIndicatorInsets in RCTScrollView ([ce10ce4d98](https://github.com/facebook/react-native/commit/ce10ce4d98bc22351b9694ef0bb15ad696f3ba5f)) +- **ScrollView:** Fixing scroll view breakage caused by #44789 ([f4b921c1d5](https://github.com/facebook/react-native/commit/f4b921c1d5a40c96ecce949db2fe0755c5b90f35)) +- **Text:** Fixed font size enlarging when `adjustFontSizeToFit` is set ([ed7766cee9](https://github.com/facebook/react-native/commit/ed7766cee941e36af05b19a315b442edf738ef80) by [@j-piasecki](https://github.com/j-piasecki)) +- **Text:** Fixed text highlighting in the New Architecture ([eadcebbb3e](https://github.com/facebook/react-native/commit/eadcebbb3efe1af70f3f7321617df9bc7fde0371)) +- **TextInput:** Fix Multiline TextInput with a fixed height scrolls to the bottom when changing AttributedText ([f6badca2f9](https://github.com/facebook/react-native/commit/f6badca2f9a5f1e986dd76444bebde0d6049513d) by [@fabOnReact](https://github.com/fabOnReact)) +- **Touchable:** Fixed stale state on TouchableOpacity and TouchableBounce ([00055f89a0](https://github.com/facebook/react-native/commit/00055f89a0ad636c2f15b4dc94047ce6cb4a7e0f) by [@sammy-SC](https://github.com/sammy-SC)) +- **UIActivityIndicatorViewStyles:** Removed references to deprecated UIActivityIndicatorViewStyles ([a23ae9c7f2](https://github.com/facebook/react-native/commit/a23ae9c7f2031b25c431b1b9791beab6b5527def)) +- **accessibility:** Fix the accessibility label not being applied to text components on the new architecture ([9922628032](https://github.com/facebook/react-native/commit/9922628032ace4d87257c1b3d70c2dc6c38a60a6) by [@j-piasecki](https://github.com/j-piasecki)) +- **autolinking:** Auto linking script of script phase ([e320ab47cf](https://github.com/facebook/react-native/commit/e320ab47cf855f2e5de74ea448ec292cf0bbb29a)) +- **cocoapods:** Exposes react_native_pods methods through autolinking.rb ([6b56fb0d0b](https://github.com/facebook/react-native/commit/6b56fb0d0b40728d0baef8566d754d7081363584) by [@blakef](https://github.com/blakef)) +- **dark mode:** Fix dark mode on initial load. ([b957513cc6](https://github.com/facebook/react-native/commit/b957513cc65b66ab0288db3fba5ccf9232f7c1fc)) +- **error handling:** Add missing call to `[super viewDidLoad]` in `RCTRedBox.mm`. ([d93788301c](https://github.com/facebook/react-native/commit/d93788301c1fafceba4c3e2ceb40cd4e49c6ae8d) by [@hakonk](https://github.com/hakonk)) +- **layout:** Fix `InputAccessoryView` width on device orientation change ([8597727c28](https://github.com/facebook/react-native/commit/8597727c28d9cb77012f3f4ebb032c335246d589) by [@mauriciomeirelles](https://github.com/mauriciomeirelles)) +- **objc:** Fixed missing header imports ([46f53e97f0](https://github.com/facebook/react-native/commit/46f53e97f0c193d1a92ac56d23b3bef40639dd09)) +- **privacy manifest:** Fix error on handling privacy manifest ([c24929c5f4](https://github.com/facebook/react-native/commit/c24929c5f4c6f88878691b5f778922864bbd5683) by [@cxa](https://github.com/cxa)) +- **privacy manifest:** Fix privacy aggregation ([00b366159d](https://github.com/facebook/react-native/commit/00b366159d760b705e86ea5f7fe5dbe53a1c5e72) by [@aleqsio](https://github.com/aleqsio)) +- **privacy manifest:** Privacy Manifest aggregation failing due to missing nil check ([47b42dc845](https://github.com/facebook/react-native/commit/47b42dc84560aa66af4b7dcfa5886af66d175c3c) by [@swrobel](https://github.com/swrobel)) +- **runtime:** Avoid calling abstract methods in RCTComposedViewRegistry ([9bdd777fd7](https://github.com/facebook/react-native/commit/9bdd777fd766ff9a0c59e7a2136279cd91a3916b) by [@cipolleschi](https://github.com/cipolleschi)) +- **runtime:** Extract the constants from ViewManagers in the UI Thread if needed. ([94537c7beb](https://github.com/facebook/react-native/commit/94537c7bebe23f1c9a79c7a94383ed960ebf30f7) by [@cipolleschi](https://github.com/cipolleschi)) +- **runtime:** Fixed `HermesExecutorFactory.h` build error when importing its private header ([2d46dbe6ce](https://github.com/facebook/react-native/commit/2d46dbe6ce962bbdcae5d91afe557b46b6b7cfe4) by [@Kudo](https://github.com/Kudo)) +- **runtime:** Fixes NSDataBigString length calculation ([9d637e4622](https://github.com/facebook/react-native/commit/9d637e4622781568b143b8585909b73211a0f8ba) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **runtime:** Fixes race condition of m_batchHadNativeModuleOrTurboModuleCalls ([3f74f69cf0](https://github.com/facebook/react-native/commit/3f74f69cf00858cd18774837bf5afc3fccdfca86) by [@zhongwuzw](https://github.com/zhongwuzw)) +- **runtime:** Implement shared atomic counters and replace static integers in `RCTImageLoader` and `RCTNetworkTask` that were accessed concurrently, which in some cases lead to data races. ([ffc16fc18b](https://github.com/facebook/react-native/commit/ffc16fc18bcc44d1e98d66dbbe56fb726962fb72) by [@hakonk](https://github.com/hakonk)) +- **runtime:** Let RCTHost be initialized with a function to provide the `bundleURL` so that it can connect to metro on Reload when the url changes. ([8b8b85bb1f](https://github.com/facebook/react-native/commit/8b8b85bb1f55a8090360fec84ec4f56f372ede6b) by [@cipolleschi](https://github.com/cipolleschi)) +- **runtime:** Missing `progress` in `onProgress` native event arguments ([78ab5f4b83](https://github.com/facebook/react-native/commit/78ab5f4b836d64b71760754c7cce1315630640c7) by [@netmaxt3r](https://github.com/netmaxt3r)) +- **style:** Fixed border being drawn over children when no color was set ([91c5a6d936](https://github.com/facebook/react-native/commit/91c5a6d9368b01172000763ba48e91eb1434e7d7) by [@j-piasecki](https://github.com/j-piasecki)) +- **style:** Removed Legacy iOS 10 code messing with border radius ([9204e44ef5](https://github.com/facebook/react-native/commit/9204e44ef5038ed9190a7e5362a7ea3c0793b361) by [@jorge-cab](https://github.com/jorge-cab)) +- **turbomodule:** Fixed race condition in native module invalidation. ([b7812a8b6c](https://github.com/facebook/react-native/commit/b7812a8b6c3afbeacaad94779cd010bcc5440785) by [@dmytrorykun](https://github.com/dmytrorykun)) +- **xcode:** Do not use temporary node when creating the .xcode.env.local ([8408b8bc96](https://github.com/facebook/react-native/commit/8408b8bc96db15e265ca65fce7875ee65dcfdcec) by [@cipolleschi](https://github.com/cipolleschi)) + +## v0.74.5 + +### Fixed + +#### iOS specific + +- Pass the right Apple system versions to Hermes ([10e9669ad1](https://github.com/facebook/react-native/commit/10e9669ad11141b155caa606638b4c6081fcf01c) by [@cipolleschi](https://github.com/cipolleschi)) + +#### Android specific + +- Remove deprecated onTextInput callback ([5da40cbb1c](https://github.com/facebook/react-native/commit/5da40cbb1cab9637db477156c4501ecfcf1c3315) by [@javache](https://github.com/javache)) + + +## v0.74.4 + +### Added + +#### Android specific + +- Stub com.facebook.react.settings on 0.74 ([13ea273850](https://github.com/facebook/react-native/commit/13ea2738508332785e6b0dd129a8cc6e66d7b3da) by [@cortinico](https://github.com/cortinico)) + +#### iOS specific + +- Prebuilt version of Hermes for visionOS ([924fb3de9b](https://github.com/facebook/react-native/commit/924fb3de9bc9328c3315316fbb796b933be5bcbe) by [@okwasniewski](https://github.com/okwasniewski)) + +### Fixed + +- Don't break script phase and codegen when coreutils installed on macOS ([e0799536ef](https://github.com/facebook/react-native/commit/e0799536ef1b68b98fb772e256d1d72424349008) by [@blakef](https://github.com/blakef)) +- Remove setting of process.exitCode that breaks Jest tests ([e42932cfc6](https://github.com/facebook/react-native/commit/e42932cfc6dae7fb90fa29d123be4caed89deac0) by [@@douglowder](https://github.com/douglowder)) + +#### iOS specific + +- Make sure to pass the RCTBridgeProxy to ViewManagers ([d6c90cf7ed](https://github.com/facebook/react-native/commit/d6c90cf7ed80caf0fc4eb2541f3dcadc3833dd37) by [@cipolleschi](https://github.com/cipolleschi)) +- Implement shared atomic counters and replace static integers in `RCTImageLoader` and `RCTNetworkTask` that were accessed concurrently, which in some cases lead to data races. ([ffc16fc18b](https://github.com/facebook/react-native/commit/ffc16fc18bcc44d1e98d66dbbe56fb726962fb72) by [@hakonk](https://github.com/hakonk)) +- Do not use temporary node when creating the .xcode.env.local ([8408b8bc96](https://github.com/facebook/react-native/commit/8408b8bc96db15e265ca65fce7875ee65dcfdcec) by [@cipolleschi](https://github.com/cipolleschi)) +- Building of iOS project when RCTAppDelegate is used in the project ([be93092c1b](https://github.com/facebook/react-native/commit/be93092c1b8a079f74dcdc129afc3767f03b8a2e) by [@nikhiltekwani09](https://github.com/nikhiltekwani09)) +- Fix error on handling privacy manifest ([e39e9c4a60](https://github.com/facebook/react-native/commit/e39e9c4a60a54d3280d8516d5891cec05d5ab793) by [@cxa](https://github.com/cxa)) + +## v0.74.3 + +### Added + +- Add the ReactMarkerConstants.CONTENT_APPEARED support on Android in bridgeless mode. ([3c4d7618f0](https://github.com/facebook/react-native/commit/3c4d7618f00751b08f73ffcec9ef1f69d44136da) by [@Kudo](https://github.com/Kudo)) + +### Changed + +- Feat: update CLI to 13.6.9 ([d1e2a35061](https://github.com/facebook/react-native/commit/d1e2a3506152abde9b870b1a63f16d00ec277ea6) by [@szymonrybczak](https://github.com/szymonrybczak)) + + +#### iOS specific + +- Support `customizeRootView` from `RCTRootViewFactory` ([3c4d761](https://github.com/facebook/react-native/commit/3c4d7618f00751b08f73ffcec9ef1f69d44136da) by [@Kudo](https://github.com/Kudo)) + +### Fixed + +- Codegen computes output path relative to project root instead of current working directory. ([d3e0430dea](https://github.com/facebook/react-native/commit/d3e0430deac573fd44792e6005d5de20e9ad2797) by [@dmytrorykun](https://github.com/dmytrorykun)) + + +### Android specific + +- Android native rejections should be instanceof Error ([f4b0fcb9](https://github.com/facebook/react-native/commit/f4b0fcb92263667754348f82030f85cc941846ba) by [huzhanbo1996](https://github.com/huzhanbo1996)) +- Tentative fix for NPE `JavaTimerManager$IdleCallbackRunnable.cancel` ([988bf162a0](https://github.com/facebook/react-native/commit/988bf162a0f36d9919cebbebc1fca27b58be4ae5) by [@cortinico](https://github.com/cortinico)) + +#### iOS specific + +- Fixed Multiline TextInput with a fixed height scrolls to the bottom when changing AttributedText ([e210c7c5](https://github.com/facebook/react-native/commit/e210c7c5741202a6e1b372731b50fdb59a7232bb) by [@fabOnReact](https://github.com/fabOnReact)) +- Fixed border being drawn over children when no color was set ([a2b52af3](https://github.com/facebook/react-native/commit/a2b52af3bcc273cf85f01510c24d4e8da1b45656) by [@j-piasecki](https://github.com/j-piasecki)) + ## v0.74.2 ### Changed @@ -598,6 +1026,28 @@ - Bump activesupport to minimum 6.1.7.5 CVE-2023-38037. ([07a159f279](https://github.com/facebook/react-native/commit/07a159f279cdcbed29c9c437dec1c0b8ac2d852f) by [@lunaleaps](https://github.com/lunaleaps)) +## v0.73.9 + +### Added + +#### iOS specific + +- Add privacy manifest aggregation. ([f4b9d09](https://github.com/facebook/react-native/commit/f4b9d098c863fa36f261e5961ad13dd4cd2706f8) by [@aleqsio](https://github.com/aleqsio)) + +### Changed + +- Feat: update CLI to 12.3.7 ([c7a1f2428f](https://github.com/facebook/react-native/commit/c7a1f2428fd6772e34b547ea23fa1d265c5d8a62) by [@szymonrybczak](https://github.com/szymonrybczak)) + +### Fixed + +#### iOS specific + +- Remove invalidate observer instead of re-adding observer in DeviceInfo module ([9db3eb6](https://github.com/facebook/react-native/commit/9db3eb686201f6ad4fddf5300f348f0caf69cfad) by [@zhongwuzw](https://github.com/zhongwuzw)) +- Fix privacy aggregation ([6983a8b](https://github.com/facebook/react-native/commit/6983a8b1b9c33ea4e580a4e94e1e9535b6cb5d81) by [@aleqsio](https://github.com/aleqsio)) +- Privacy Manifest aggregation failing due to missing nil check ([115331b](https://github.com/facebook/react-native/commit/115331b213152df623ad1c7988c9295802af6850) by [@swrobel](https://github.com/swrobel)) +- In privacy manifest post install script, handle the case where the file reference doesn't have a path ([86cb45e](https://github.com/facebook/react-native/commit/86cb45e57786b0a62d9c523f9d5db4f8e5dc52df) by [@robertying](https://github.com/robertying)) +- Privacy Manifest aggregation failing due to no `NSPrivacyAccessedAPITypes` key ([4bb94fe](https://github.com/facebook/react-native/commit/4bb94fe1e6c6174af5c9148bfc00f4bc7a87cf19) by [@renchap](https://github.com/renchap)) + ## v0.73.8 ### Added @@ -713,6 +1163,15 @@ - Fix race condition between A11yManager and UIManager ([f39f34ed82](https://github.com/facebook/react-native/commit/f39f34ed82997d0595522a285c3cb8693594e718) by [@cipolleschi](https://github.com/cipolleschi)) - Fix symbol not found _jump_fcontext with use_frameworks ([a2771ce58a](https://github.com/facebook/react-native/commit/a2771ce58ac221d1ac0de265c1ce571212fbcf83) by [@cipolleschi](https://github.com/cipolleschi)) +## v0.72.17 + +### Fixed + +#### iOS specific + +- Fix Privacy Manifest file path by providing targets ([da0f8ac060](https://github.com/facebook/react-native/commit/da0f8ac060d853d8229423559c9338646dd11455) by [@siddharthkul](https://github.com/siddharthkul)) +- Handle the case where the file reference doesn't have a path ([b5b3f3c43d](https://github.com/facebook/react-native/commit/b5b3f3c43d02dc552c0884f9cee416c68b6eaea2) by [@robertying](https://github.com/robertying)) + ## v0.72.15 ### Added diff --git a/Gemfile b/Gemfile index 8e468b2c4e6681..88f17b435ec0c3 100644 --- a/Gemfile +++ b/Gemfile @@ -3,5 +3,5 @@ source 'https://rubygems.org' # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version ruby ">= 2.6.10" -gem 'cocoapods', '~> 1.13' +gem 'cocoapods', '~> 1.13', '!= 1.15.0', '!= 1.15.1' gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' diff --git a/Gemfile.lock b/Gemfile.lock index fd9835f9187368..77b0436cde5cff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -96,7 +96,7 @@ PLATFORMS DEPENDENCIES activesupport (>= 6.1.7.5, < 7.1.0) - cocoapods (~> 1.13) + cocoapods (~> 1.13, != 1.15.1, != 1.15.0) RUBY VERSION ruby 3.3.0p0 diff --git a/build.gradle.kts b/build.gradle.kts index e24bf6467328f4..d848efee0ab69c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -60,7 +60,7 @@ nexusPublishing { tasks.register("clean", Delete::class.java) { description = "Remove all the build files and intermediate build outputs" - dependsOn(gradle.includedBuild("react-native-gradle-plugin").task(":clean")) + dependsOn(gradle.includedBuild("gradle-plugin").task(":clean")) subprojects.forEach { if (it.project.plugins.hasPlugin("com.android.library") || it.project.plugins.hasPlugin("com.android.application")) { @@ -86,7 +86,7 @@ tasks.register("clean", Delete::class.java) { tasks.register("build") { description = "Build and test all the React Native relevant projects." - dependsOn(gradle.includedBuild("react-native-gradle-plugin").task(":build")) + dependsOn(gradle.includedBuild("gradle-plugin").task(":build")) } tasks.register("publishAllToMavenTempLocal") { @@ -97,10 +97,9 @@ tasks.register("publishAllToMavenTempLocal") { ":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository") } -tasks.register("publishAllToSonatype") { - description = "Publish all the artifacts to Sonatype (Maven Central or Snapshot repository)" +tasks.register("publishAndroidToSonatype") { + description = "Publish the Android artifacts to Sonatype (Maven Central or Snapshot repository)" dependsOn(":packages:react-native:ReactAndroid:publishToSonatype") - dependsOn(":packages:react-native:ReactAndroid:external-artifacts:publishToSonatype") dependsOn(":packages:react-native:ReactAndroid:hermes-engine:publishToSonatype") } diff --git a/flow-typed/npm/babel-traverse_v7.x.x.js b/flow-typed/npm/babel-traverse_v7.x.x.js index b35fd7863068c5..c1fefdcc39120d 100644 --- a/flow-typed/npm/babel-traverse_v7.x.x.js +++ b/flow-typed/npm/babel-traverse_v7.x.x.js @@ -900,7 +900,9 @@ declare module '@babel/traverse' { isImportAttribute(opts?: Opts): boolean; isImportDeclaration(opts?: Opts): boolean; isImportDefaultSpecifier(opts?: Opts): boolean; + isImportExpression(opts?: Opts): boolean; isImportNamespaceSpecifier(opts?: Opts): boolean; + isImportOrExportDeclaration(opts?: Opts): boolean; isImportSpecifier(opts?: Opts): boolean; isIndexedAccessType(opts?: Opts): boolean; isInferredPredicate(opts?: Opts): boolean; @@ -1215,7 +1217,9 @@ declare module '@babel/traverse' { assertImportAttribute(opts?: Opts): void; assertImportDeclaration(opts?: Opts): void; assertImportDefaultSpecifier(opts?: Opts): void; + assertImportExpression(opts?: Opts): void; assertImportNamespaceSpecifier(opts?: Opts): void; + assertImportOrExportDeclaration(opts?: Opts): void; assertImportSpecifier(opts?: Opts): void; assertIndexedAccessType(opts?: Opts): void; assertInferredPredicate(opts?: Opts): void; @@ -1571,10 +1575,15 @@ declare module '@babel/traverse' { ImportAttribute?: VisitNode, ImportDeclaration?: VisitNode, ImportDefaultSpecifier?: VisitNode, + ImportExpression?: VisitNode, ImportNamespaceSpecifier?: VisitNode< BabelNodeImportNamespaceSpecifier, TState, >, + ImportOrExportDeclaration?: VisitNode< + BabelNodeImportOrExportDeclaration, + TState, + >, ImportSpecifier?: VisitNode, IndexedAccessType?: VisitNode, InferredPredicate?: VisitNode, diff --git a/flow-typed/npm/babel-types_v7.x.x.js b/flow-typed/npm/babel-types_v7.x.x.js index 6f344941bc71fd..7626bdec96fe7a 100644 --- a/flow-typed/npm/babel-types_v7.x.x.js +++ b/flow-typed/npm/babel-types_v7.x.x.js @@ -60,7 +60,7 @@ declare type BabelNodeAssignmentExpression = { loc: ?BabelNodeSourceLocation, type: "AssignmentExpression"; operator: string; - left: BabelNodeLVal; + left: BabelNodeLVal | BabelNodeOptionalMemberExpression; right: BabelNodeExpression; }; @@ -142,7 +142,7 @@ declare type BabelNodeCallExpression = { loc: ?BabelNodeSourceLocation, type: "CallExpression"; callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier; - arguments: Array; + arguments: Array; optional?: true | false; typeArguments?: BabelNodeTypeParameterInstantiation; typeParameters?: BabelNodeTSTypeParameterInstantiation; @@ -434,7 +434,7 @@ declare type BabelNodeNewExpression = { loc: ?BabelNodeSourceLocation, type: "NewExpression"; callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier; - arguments: Array; + arguments: Array; optional?: true | false; typeArguments?: BabelNodeTypeParameterInstantiation; typeParameters?: BabelNodeTSTypeParameterInstantiation; @@ -452,7 +452,6 @@ declare type BabelNodeProgram = { directives?: Array; sourceType?: "script" | "module"; interpreter?: BabelNodeInterpreterDirective; - sourceFile: string; }; declare type BabelNodeObjectExpression = { @@ -640,7 +639,7 @@ declare type BabelNodeVariableDeclaration = { end: ?number; loc: ?BabelNodeSourceLocation, type: "VariableDeclaration"; - kind: "var" | "let" | "const" | "using"; + kind: "var" | "let" | "const" | "using" | "await using"; declarations: Array; declare?: boolean; }; @@ -693,6 +692,7 @@ declare type BabelNodeAssignmentPattern = { left: BabelNodeIdentifier | BabelNodeObjectPattern | BabelNodeArrayPattern | BabelNodeMemberExpression | BabelNodeTSAsExpression | BabelNodeTSSatisfiesExpression | BabelNodeTSTypeAssertion | BabelNodeTSNonNullExpression; right: BabelNodeExpression; decorators?: Array; + optional?: boolean; typeAnnotation?: BabelNodeTypeAnnotation | BabelNodeTSTypeAnnotation | BabelNodeNoop; }; @@ -765,7 +765,7 @@ declare type BabelNodeClassDeclaration = { end: ?number; loc: ?BabelNodeSourceLocation, type: "ClassDeclaration"; - id: BabelNodeIdentifier; + id?: BabelNodeIdentifier; superClass?: BabelNodeExpression; body: BabelNodeClassBody; decorators?: Array; @@ -787,6 +787,7 @@ declare type BabelNodeExportAllDeclaration = { type: "ExportAllDeclaration"; source: BabelNodeStringLiteral; assertions?: Array; + attributes?: Array; exportKind?: "type" | "value"; }; @@ -814,6 +815,7 @@ declare type BabelNodeExportNamedDeclaration = { specifiers?: Array; source?: BabelNodeStringLiteral; assertions?: Array; + attributes?: Array; exportKind?: "type" | "value"; }; @@ -855,8 +857,10 @@ declare type BabelNodeImportDeclaration = { specifiers: Array; source: BabelNodeStringLiteral; assertions?: Array; + attributes?: Array; importKind?: "type" | "typeof" | "value"; module?: boolean; + phase?: "source" | "defer"; }; declare type BabelNodeImportDefaultSpecifier = { @@ -894,6 +898,19 @@ declare type BabelNodeImportSpecifier = { importKind?: "type" | "typeof" | "value"; }; +declare type BabelNodeImportExpression = { + leadingComments?: Array; + innerComments?: Array; + trailingComments?: Array; + start: ?number; + end: ?number; + loc: ?BabelNodeSourceLocation, + type: "ImportExpression"; + source: BabelNodeExpression; + options?: BabelNodeExpression; + phase?: "source" | "defer"; +}; + declare type BabelNodeMetaProperty = { leadingComments?: Array; innerComments?: Array; @@ -942,6 +959,7 @@ declare type BabelNodeObjectPattern = { type: "ObjectPattern"; properties: Array; decorators?: Array; + optional?: boolean; typeAnnotation?: BabelNodeTypeAnnotation | BabelNodeTSTypeAnnotation | BabelNodeNoop; }; @@ -1081,7 +1099,7 @@ declare type BabelNodeOptionalCallExpression = { loc: ?BabelNodeSourceLocation, type: "OptionalCallExpression"; callee: BabelNodeExpression; - arguments: Array; + arguments: Array; optional: boolean; typeArguments?: BabelNodeTypeParameterInstantiation; typeParameters?: BabelNodeTSTypeParameterInstantiation; @@ -1305,8 +1323,6 @@ declare type BabelNodeDeclareInterface = { typeParameters?: BabelNodeTypeParameterDeclaration; extends?: Array; body: BabelNodeObjectTypeAnnotation; - implements?: Array; - mixins?: Array; }; declare type BabelNodeDeclareModule = { @@ -1492,8 +1508,6 @@ declare type BabelNodeInterfaceDeclaration = { typeParameters?: BabelNodeTypeParameterDeclaration; extends?: Array; body: BabelNodeObjectTypeAnnotation; - implements?: Array; - mixins?: Array; }; declare type BabelNodeInterfaceTypeAnnotation = { @@ -2424,7 +2438,7 @@ declare type BabelNodeTSCallSignatureDeclaration = { loc: ?BabelNodeSourceLocation, type: "TSCallSignatureDeclaration"; typeParameters?: BabelNodeTSTypeParameterDeclaration; - parameters: Array; + parameters: Array; typeAnnotation?: BabelNodeTSTypeAnnotation; }; @@ -2437,7 +2451,7 @@ declare type BabelNodeTSConstructSignatureDeclaration = { loc: ?BabelNodeSourceLocation, type: "TSConstructSignatureDeclaration"; typeParameters?: BabelNodeTSTypeParameterDeclaration; - parameters: Array; + parameters: Array; typeAnnotation?: BabelNodeTSTypeAnnotation; }; @@ -2451,7 +2465,6 @@ declare type BabelNodeTSPropertySignature = { type: "TSPropertySignature"; key: BabelNodeExpression; typeAnnotation?: BabelNodeTSTypeAnnotation; - initializer?: BabelNodeExpression; computed?: boolean; kind: "get" | "set"; optional?: boolean; @@ -2468,7 +2481,7 @@ declare type BabelNodeTSMethodSignature = { type: "TSMethodSignature"; key: BabelNodeExpression; typeParameters?: BabelNodeTSTypeParameterDeclaration; - parameters: Array; + parameters: Array; typeAnnotation?: BabelNodeTSTypeAnnotation; computed?: boolean; kind: "method" | "get" | "set"; @@ -2638,7 +2651,7 @@ declare type BabelNodeTSFunctionType = { loc: ?BabelNodeSourceLocation, type: "TSFunctionType"; typeParameters?: BabelNodeTSTypeParameterDeclaration; - parameters: Array; + parameters: Array; typeAnnotation?: BabelNodeTSTypeAnnotation; }; @@ -2651,7 +2664,7 @@ declare type BabelNodeTSConstructorType = { loc: ?BabelNodeSourceLocation, type: "TSConstructorType"; typeParameters?: BabelNodeTSTypeParameterDeclaration; - parameters: Array; + parameters: Array; typeAnnotation?: BabelNodeTSTypeAnnotation; abstract?: boolean; }; @@ -3032,6 +3045,7 @@ declare type BabelNodeTSImportType = { argument: BabelNodeStringLiteral; qualifier?: BabelNodeTSEntityName; typeParameters?: BabelNodeTSTypeParameterInstantiation; + options?: BabelNodeExpression; }; declare type BabelNodeTSImportEqualsDeclaration = { @@ -3136,13 +3150,14 @@ declare type BabelNodeTSTypeParameter = { constraint?: BabelNodeTSType; default?: BabelNodeTSType; name: string; + const?: boolean; in?: boolean; out?: boolean; }; -declare type BabelNode = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeInterpreterDirective | BabelNodeDirective | BabelNodeDirectiveLiteral | BabelNodeBlockStatement | BabelNodeBreakStatement | BabelNodeCallExpression | BabelNodeCatchClause | BabelNodeConditionalExpression | BabelNodeContinueStatement | BabelNodeDebuggerStatement | BabelNodeDoWhileStatement | BabelNodeEmptyStatement | BabelNodeExpressionStatement | BabelNodeFile | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeIfStatement | BabelNodeLabeledStatement | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeProgram | BabelNodeObjectExpression | BabelNodeObjectMethod | BabelNodeObjectProperty | BabelNodeRestElement | BabelNodeReturnStatement | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeSwitchCase | BabelNodeSwitchStatement | BabelNodeThisExpression | BabelNodeThrowStatement | BabelNodeTryStatement | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeVariableDeclaration | BabelNodeVariableDeclarator | BabelNodeWhileStatement | BabelNodeWithStatement | BabelNodeAssignmentPattern | BabelNodeArrayPattern | BabelNodeArrowFunctionExpression | BabelNodeClassBody | BabelNodeClassExpression | BabelNodeClassDeclaration | BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeExportSpecifier | BabelNodeForOfStatement | BabelNodeImportDeclaration | BabelNodeImportDefaultSpecifier | BabelNodeImportNamespaceSpecifier | BabelNodeImportSpecifier | BabelNodeMetaProperty | BabelNodeClassMethod | BabelNodeObjectPattern | BabelNodeSpreadElement | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateElement | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeExportNamespaceSpecifier | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeClassProperty | BabelNodeClassAccessorProperty | BabelNodeClassPrivateProperty | BabelNodeClassPrivateMethod | BabelNodePrivateName | BabelNodeStaticBlock | BabelNodeAnyTypeAnnotation | BabelNodeArrayTypeAnnotation | BabelNodeBooleanTypeAnnotation | BabelNodeBooleanLiteralTypeAnnotation | BabelNodeNullLiteralTypeAnnotation | BabelNodeClassImplements | BabelNodeDeclareClass | BabelNodeDeclareFunction | BabelNodeDeclareInterface | BabelNodeDeclareModule | BabelNodeDeclareModuleExports | BabelNodeDeclareTypeAlias | BabelNodeDeclareOpaqueType | BabelNodeDeclareVariable | BabelNodeDeclareExportDeclaration | BabelNodeDeclareExportAllDeclaration | BabelNodeDeclaredPredicate | BabelNodeExistsTypeAnnotation | BabelNodeFunctionTypeAnnotation | BabelNodeFunctionTypeParam | BabelNodeGenericTypeAnnotation | BabelNodeInferredPredicate | BabelNodeInterfaceExtends | BabelNodeInterfaceDeclaration | BabelNodeInterfaceTypeAnnotation | BabelNodeIntersectionTypeAnnotation | BabelNodeMixedTypeAnnotation | BabelNodeEmptyTypeAnnotation | BabelNodeNullableTypeAnnotation | BabelNodeNumberLiteralTypeAnnotation | BabelNodeNumberTypeAnnotation | BabelNodeObjectTypeAnnotation | BabelNodeObjectTypeInternalSlot | BabelNodeObjectTypeCallProperty | BabelNodeObjectTypeIndexer | BabelNodeObjectTypeProperty | BabelNodeObjectTypeSpreadProperty | BabelNodeOpaqueType | BabelNodeQualifiedTypeIdentifier | BabelNodeStringLiteralTypeAnnotation | BabelNodeStringTypeAnnotation | BabelNodeSymbolTypeAnnotation | BabelNodeThisTypeAnnotation | BabelNodeTupleTypeAnnotation | BabelNodeTypeofTypeAnnotation | BabelNodeTypeAlias | BabelNodeTypeAnnotation | BabelNodeTypeCastExpression | BabelNodeTypeParameter | BabelNodeTypeParameterDeclaration | BabelNodeTypeParameterInstantiation | BabelNodeUnionTypeAnnotation | BabelNodeVariance | BabelNodeVoidTypeAnnotation | BabelNodeEnumDeclaration | BabelNodeEnumBooleanBody | BabelNodeEnumNumberBody | BabelNodeEnumStringBody | BabelNodeEnumSymbolBody | BabelNodeEnumBooleanMember | BabelNodeEnumNumberMember | BabelNodeEnumStringMember | BabelNodeEnumDefaultedMember | BabelNodeIndexedAccessType | BabelNodeOptionalIndexedAccessType | BabelNodeJSXAttribute | BabelNodeJSXClosingElement | BabelNodeJSXElement | BabelNodeJSXEmptyExpression | BabelNodeJSXExpressionContainer | BabelNodeJSXSpreadChild | BabelNodeJSXIdentifier | BabelNodeJSXMemberExpression | BabelNodeJSXNamespacedName | BabelNodeJSXOpeningElement | BabelNodeJSXSpreadAttribute | BabelNodeJSXText | BabelNodeJSXFragment | BabelNodeJSXOpeningFragment | BabelNodeJSXClosingFragment | BabelNodeNoop | BabelNodePlaceholder | BabelNodeV8IntrinsicIdentifier | BabelNodeArgumentPlaceholder | BabelNodeBindExpression | BabelNodeImportAttribute | BabelNodeDecorator | BabelNodeDoExpression | BabelNodeExportDefaultSpecifier | BabelNodeRecordExpression | BabelNodeTupleExpression | BabelNodeDecimalLiteral | BabelNodeModuleExpression | BabelNodeTopicReference | BabelNodePipelineTopicExpression | BabelNodePipelineBareFunction | BabelNodePipelinePrimaryTopicReference | BabelNodeTSParameterProperty | BabelNodeTSDeclareFunction | BabelNodeTSDeclareMethod | BabelNodeTSQualifiedName | BabelNodeTSCallSignatureDeclaration | BabelNodeTSConstructSignatureDeclaration | BabelNodeTSPropertySignature | BabelNodeTSMethodSignature | BabelNodeTSIndexSignature | BabelNodeTSAnyKeyword | BabelNodeTSBooleanKeyword | BabelNodeTSBigIntKeyword | BabelNodeTSIntrinsicKeyword | BabelNodeTSNeverKeyword | BabelNodeTSNullKeyword | BabelNodeTSNumberKeyword | BabelNodeTSObjectKeyword | BabelNodeTSStringKeyword | BabelNodeTSSymbolKeyword | BabelNodeTSUndefinedKeyword | BabelNodeTSUnknownKeyword | BabelNodeTSVoidKeyword | BabelNodeTSThisType | BabelNodeTSFunctionType | BabelNodeTSConstructorType | BabelNodeTSTypeReference | BabelNodeTSTypePredicate | BabelNodeTSTypeQuery | BabelNodeTSTypeLiteral | BabelNodeTSArrayType | BabelNodeTSTupleType | BabelNodeTSOptionalType | BabelNodeTSRestType | BabelNodeTSNamedTupleMember | BabelNodeTSUnionType | BabelNodeTSIntersectionType | BabelNodeTSConditionalType | BabelNodeTSInferType | BabelNodeTSParenthesizedType | BabelNodeTSTypeOperator | BabelNodeTSIndexedAccessType | BabelNodeTSMappedType | BabelNodeTSLiteralType | BabelNodeTSExpressionWithTypeArguments | BabelNodeTSInterfaceDeclaration | BabelNodeTSInterfaceBody | BabelNodeTSTypeAliasDeclaration | BabelNodeTSInstantiationExpression | BabelNodeTSAsExpression | BabelNodeTSSatisfiesExpression | BabelNodeTSTypeAssertion | BabelNodeTSEnumDeclaration | BabelNodeTSEnumMember | BabelNodeTSModuleDeclaration | BabelNodeTSModuleBlock | BabelNodeTSImportType | BabelNodeTSImportEqualsDeclaration | BabelNodeTSExternalModuleReference | BabelNodeTSNonNullExpression | BabelNodeTSExportAssignment | BabelNodeTSNamespaceExportDeclaration | BabelNodeTSTypeAnnotation | BabelNodeTSTypeParameterInstantiation | BabelNodeTSTypeParameterDeclaration | BabelNodeTSTypeParameter; -declare type BabelNodeStandardized = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeInterpreterDirective | BabelNodeDirective | BabelNodeDirectiveLiteral | BabelNodeBlockStatement | BabelNodeBreakStatement | BabelNodeCallExpression | BabelNodeCatchClause | BabelNodeConditionalExpression | BabelNodeContinueStatement | BabelNodeDebuggerStatement | BabelNodeDoWhileStatement | BabelNodeEmptyStatement | BabelNodeExpressionStatement | BabelNodeFile | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeIfStatement | BabelNodeLabeledStatement | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeProgram | BabelNodeObjectExpression | BabelNodeObjectMethod | BabelNodeObjectProperty | BabelNodeRestElement | BabelNodeReturnStatement | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeSwitchCase | BabelNodeSwitchStatement | BabelNodeThisExpression | BabelNodeThrowStatement | BabelNodeTryStatement | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeVariableDeclaration | BabelNodeVariableDeclarator | BabelNodeWhileStatement | BabelNodeWithStatement | BabelNodeAssignmentPattern | BabelNodeArrayPattern | BabelNodeArrowFunctionExpression | BabelNodeClassBody | BabelNodeClassExpression | BabelNodeClassDeclaration | BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeExportSpecifier | BabelNodeForOfStatement | BabelNodeImportDeclaration | BabelNodeImportDefaultSpecifier | BabelNodeImportNamespaceSpecifier | BabelNodeImportSpecifier | BabelNodeMetaProperty | BabelNodeClassMethod | BabelNodeObjectPattern | BabelNodeSpreadElement | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateElement | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeExportNamespaceSpecifier | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeClassProperty | BabelNodeClassAccessorProperty | BabelNodeClassPrivateProperty | BabelNodeClassPrivateMethod | BabelNodePrivateName | BabelNodeStaticBlock; -declare type BabelNodeExpression = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeCallExpression | BabelNodeConditionalExpression | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeObjectExpression | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeThisExpression | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeArrowFunctionExpression | BabelNodeClassExpression | BabelNodeMetaProperty | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeTypeCastExpression | BabelNodeJSXElement | BabelNodeJSXFragment | BabelNodeBindExpression | BabelNodeDoExpression | BabelNodeRecordExpression | BabelNodeTupleExpression | BabelNodeDecimalLiteral | BabelNodeModuleExpression | BabelNodeTopicReference | BabelNodePipelineTopicExpression | BabelNodePipelineBareFunction | BabelNodePipelinePrimaryTopicReference | BabelNodeTSInstantiationExpression | BabelNodeTSAsExpression | BabelNodeTSSatisfiesExpression | BabelNodeTSTypeAssertion | BabelNodeTSNonNullExpression; +declare type BabelNode = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeInterpreterDirective | BabelNodeDirective | BabelNodeDirectiveLiteral | BabelNodeBlockStatement | BabelNodeBreakStatement | BabelNodeCallExpression | BabelNodeCatchClause | BabelNodeConditionalExpression | BabelNodeContinueStatement | BabelNodeDebuggerStatement | BabelNodeDoWhileStatement | BabelNodeEmptyStatement | BabelNodeExpressionStatement | BabelNodeFile | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeIfStatement | BabelNodeLabeledStatement | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeProgram | BabelNodeObjectExpression | BabelNodeObjectMethod | BabelNodeObjectProperty | BabelNodeRestElement | BabelNodeReturnStatement | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeSwitchCase | BabelNodeSwitchStatement | BabelNodeThisExpression | BabelNodeThrowStatement | BabelNodeTryStatement | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeVariableDeclaration | BabelNodeVariableDeclarator | BabelNodeWhileStatement | BabelNodeWithStatement | BabelNodeAssignmentPattern | BabelNodeArrayPattern | BabelNodeArrowFunctionExpression | BabelNodeClassBody | BabelNodeClassExpression | BabelNodeClassDeclaration | BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeExportSpecifier | BabelNodeForOfStatement | BabelNodeImportDeclaration | BabelNodeImportDefaultSpecifier | BabelNodeImportNamespaceSpecifier | BabelNodeImportSpecifier | BabelNodeImportExpression | BabelNodeMetaProperty | BabelNodeClassMethod | BabelNodeObjectPattern | BabelNodeSpreadElement | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateElement | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeExportNamespaceSpecifier | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeClassProperty | BabelNodeClassAccessorProperty | BabelNodeClassPrivateProperty | BabelNodeClassPrivateMethod | BabelNodePrivateName | BabelNodeStaticBlock | BabelNodeAnyTypeAnnotation | BabelNodeArrayTypeAnnotation | BabelNodeBooleanTypeAnnotation | BabelNodeBooleanLiteralTypeAnnotation | BabelNodeNullLiteralTypeAnnotation | BabelNodeClassImplements | BabelNodeDeclareClass | BabelNodeDeclareFunction | BabelNodeDeclareInterface | BabelNodeDeclareModule | BabelNodeDeclareModuleExports | BabelNodeDeclareTypeAlias | BabelNodeDeclareOpaqueType | BabelNodeDeclareVariable | BabelNodeDeclareExportDeclaration | BabelNodeDeclareExportAllDeclaration | BabelNodeDeclaredPredicate | BabelNodeExistsTypeAnnotation | BabelNodeFunctionTypeAnnotation | BabelNodeFunctionTypeParam | BabelNodeGenericTypeAnnotation | BabelNodeInferredPredicate | BabelNodeInterfaceExtends | BabelNodeInterfaceDeclaration | BabelNodeInterfaceTypeAnnotation | BabelNodeIntersectionTypeAnnotation | BabelNodeMixedTypeAnnotation | BabelNodeEmptyTypeAnnotation | BabelNodeNullableTypeAnnotation | BabelNodeNumberLiteralTypeAnnotation | BabelNodeNumberTypeAnnotation | BabelNodeObjectTypeAnnotation | BabelNodeObjectTypeInternalSlot | BabelNodeObjectTypeCallProperty | BabelNodeObjectTypeIndexer | BabelNodeObjectTypeProperty | BabelNodeObjectTypeSpreadProperty | BabelNodeOpaqueType | BabelNodeQualifiedTypeIdentifier | BabelNodeStringLiteralTypeAnnotation | BabelNodeStringTypeAnnotation | BabelNodeSymbolTypeAnnotation | BabelNodeThisTypeAnnotation | BabelNodeTupleTypeAnnotation | BabelNodeTypeofTypeAnnotation | BabelNodeTypeAlias | BabelNodeTypeAnnotation | BabelNodeTypeCastExpression | BabelNodeTypeParameter | BabelNodeTypeParameterDeclaration | BabelNodeTypeParameterInstantiation | BabelNodeUnionTypeAnnotation | BabelNodeVariance | BabelNodeVoidTypeAnnotation | BabelNodeEnumDeclaration | BabelNodeEnumBooleanBody | BabelNodeEnumNumberBody | BabelNodeEnumStringBody | BabelNodeEnumSymbolBody | BabelNodeEnumBooleanMember | BabelNodeEnumNumberMember | BabelNodeEnumStringMember | BabelNodeEnumDefaultedMember | BabelNodeIndexedAccessType | BabelNodeOptionalIndexedAccessType | BabelNodeJSXAttribute | BabelNodeJSXClosingElement | BabelNodeJSXElement | BabelNodeJSXEmptyExpression | BabelNodeJSXExpressionContainer | BabelNodeJSXSpreadChild | BabelNodeJSXIdentifier | BabelNodeJSXMemberExpression | BabelNodeJSXNamespacedName | BabelNodeJSXOpeningElement | BabelNodeJSXSpreadAttribute | BabelNodeJSXText | BabelNodeJSXFragment | BabelNodeJSXOpeningFragment | BabelNodeJSXClosingFragment | BabelNodeNoop | BabelNodePlaceholder | BabelNodeV8IntrinsicIdentifier | BabelNodeArgumentPlaceholder | BabelNodeBindExpression | BabelNodeImportAttribute | BabelNodeDecorator | BabelNodeDoExpression | BabelNodeExportDefaultSpecifier | BabelNodeRecordExpression | BabelNodeTupleExpression | BabelNodeDecimalLiteral | BabelNodeModuleExpression | BabelNodeTopicReference | BabelNodePipelineTopicExpression | BabelNodePipelineBareFunction | BabelNodePipelinePrimaryTopicReference | BabelNodeTSParameterProperty | BabelNodeTSDeclareFunction | BabelNodeTSDeclareMethod | BabelNodeTSQualifiedName | BabelNodeTSCallSignatureDeclaration | BabelNodeTSConstructSignatureDeclaration | BabelNodeTSPropertySignature | BabelNodeTSMethodSignature | BabelNodeTSIndexSignature | BabelNodeTSAnyKeyword | BabelNodeTSBooleanKeyword | BabelNodeTSBigIntKeyword | BabelNodeTSIntrinsicKeyword | BabelNodeTSNeverKeyword | BabelNodeTSNullKeyword | BabelNodeTSNumberKeyword | BabelNodeTSObjectKeyword | BabelNodeTSStringKeyword | BabelNodeTSSymbolKeyword | BabelNodeTSUndefinedKeyword | BabelNodeTSUnknownKeyword | BabelNodeTSVoidKeyword | BabelNodeTSThisType | BabelNodeTSFunctionType | BabelNodeTSConstructorType | BabelNodeTSTypeReference | BabelNodeTSTypePredicate | BabelNodeTSTypeQuery | BabelNodeTSTypeLiteral | BabelNodeTSArrayType | BabelNodeTSTupleType | BabelNodeTSOptionalType | BabelNodeTSRestType | BabelNodeTSNamedTupleMember | BabelNodeTSUnionType | BabelNodeTSIntersectionType | BabelNodeTSConditionalType | BabelNodeTSInferType | BabelNodeTSParenthesizedType | BabelNodeTSTypeOperator | BabelNodeTSIndexedAccessType | BabelNodeTSMappedType | BabelNodeTSLiteralType | BabelNodeTSExpressionWithTypeArguments | BabelNodeTSInterfaceDeclaration | BabelNodeTSInterfaceBody | BabelNodeTSTypeAliasDeclaration | BabelNodeTSInstantiationExpression | BabelNodeTSAsExpression | BabelNodeTSSatisfiesExpression | BabelNodeTSTypeAssertion | BabelNodeTSEnumDeclaration | BabelNodeTSEnumMember | BabelNodeTSModuleDeclaration | BabelNodeTSModuleBlock | BabelNodeTSImportType | BabelNodeTSImportEqualsDeclaration | BabelNodeTSExternalModuleReference | BabelNodeTSNonNullExpression | BabelNodeTSExportAssignment | BabelNodeTSNamespaceExportDeclaration | BabelNodeTSTypeAnnotation | BabelNodeTSTypeParameterInstantiation | BabelNodeTSTypeParameterDeclaration | BabelNodeTSTypeParameter; +declare type BabelNodeStandardized = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeInterpreterDirective | BabelNodeDirective | BabelNodeDirectiveLiteral | BabelNodeBlockStatement | BabelNodeBreakStatement | BabelNodeCallExpression | BabelNodeCatchClause | BabelNodeConditionalExpression | BabelNodeContinueStatement | BabelNodeDebuggerStatement | BabelNodeDoWhileStatement | BabelNodeEmptyStatement | BabelNodeExpressionStatement | BabelNodeFile | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeIfStatement | BabelNodeLabeledStatement | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeProgram | BabelNodeObjectExpression | BabelNodeObjectMethod | BabelNodeObjectProperty | BabelNodeRestElement | BabelNodeReturnStatement | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeSwitchCase | BabelNodeSwitchStatement | BabelNodeThisExpression | BabelNodeThrowStatement | BabelNodeTryStatement | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeVariableDeclaration | BabelNodeVariableDeclarator | BabelNodeWhileStatement | BabelNodeWithStatement | BabelNodeAssignmentPattern | BabelNodeArrayPattern | BabelNodeArrowFunctionExpression | BabelNodeClassBody | BabelNodeClassExpression | BabelNodeClassDeclaration | BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeExportSpecifier | BabelNodeForOfStatement | BabelNodeImportDeclaration | BabelNodeImportDefaultSpecifier | BabelNodeImportNamespaceSpecifier | BabelNodeImportSpecifier | BabelNodeImportExpression | BabelNodeMetaProperty | BabelNodeClassMethod | BabelNodeObjectPattern | BabelNodeSpreadElement | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateElement | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeExportNamespaceSpecifier | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeClassProperty | BabelNodeClassAccessorProperty | BabelNodeClassPrivateProperty | BabelNodeClassPrivateMethod | BabelNodePrivateName | BabelNodeStaticBlock; +declare type BabelNodeExpression = BabelNodeArrayExpression | BabelNodeAssignmentExpression | BabelNodeBinaryExpression | BabelNodeCallExpression | BabelNodeConditionalExpression | BabelNodeFunctionExpression | BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeNullLiteral | BabelNodeBooleanLiteral | BabelNodeRegExpLiteral | BabelNodeLogicalExpression | BabelNodeMemberExpression | BabelNodeNewExpression | BabelNodeObjectExpression | BabelNodeSequenceExpression | BabelNodeParenthesizedExpression | BabelNodeThisExpression | BabelNodeUnaryExpression | BabelNodeUpdateExpression | BabelNodeArrowFunctionExpression | BabelNodeClassExpression | BabelNodeImportExpression | BabelNodeMetaProperty | BabelNodeSuper | BabelNodeTaggedTemplateExpression | BabelNodeTemplateLiteral | BabelNodeYieldExpression | BabelNodeAwaitExpression | BabelNodeImport | BabelNodeBigIntLiteral | BabelNodeOptionalMemberExpression | BabelNodeOptionalCallExpression | BabelNodeTypeCastExpression | BabelNodeJSXElement | BabelNodeJSXFragment | BabelNodeBindExpression | BabelNodeDoExpression | BabelNodeRecordExpression | BabelNodeTupleExpression | BabelNodeDecimalLiteral | BabelNodeModuleExpression | BabelNodeTopicReference | BabelNodePipelineTopicExpression | BabelNodePipelineBareFunction | BabelNodePipelinePrimaryTopicReference | BabelNodeTSInstantiationExpression | BabelNodeTSAsExpression | BabelNodeTSSatisfiesExpression | BabelNodeTSTypeAssertion | BabelNodeTSNonNullExpression; declare type BabelNodeBinary = BabelNodeBinaryExpression | BabelNodeLogicalExpression; declare type BabelNodeScopable = BabelNodeBlockStatement | BabelNodeCatchClause | BabelNodeDoWhileStatement | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeProgram | BabelNodeObjectMethod | BabelNodeSwitchStatement | BabelNodeWhileStatement | BabelNodeArrowFunctionExpression | BabelNodeClassExpression | BabelNodeClassDeclaration | BabelNodeForOfStatement | BabelNodeClassMethod | BabelNodeClassPrivateMethod | BabelNodeStaticBlock | BabelNodeTSModuleBlock; declare type BabelNodeBlockParent = BabelNodeBlockStatement | BabelNodeCatchClause | BabelNodeDoWhileStatement | BabelNodeForInStatement | BabelNodeForStatement | BabelNodeFunctionDeclaration | BabelNodeFunctionExpression | BabelNodeProgram | BabelNodeObjectMethod | BabelNodeSwitchStatement | BabelNodeWhileStatement | BabelNodeArrowFunctionExpression | BabelNodeForOfStatement | BabelNodeClassMethod | BabelNodeClassPrivateMethod | BabelNodeStaticBlock | BabelNodeTSModuleBlock; @@ -3172,7 +3187,7 @@ declare type BabelNodeProperty = BabelNodeObjectProperty | BabelNodeClassPropert declare type BabelNodeUnaryLike = BabelNodeUnaryExpression | BabelNodeSpreadElement; declare type BabelNodePattern = BabelNodeAssignmentPattern | BabelNodeArrayPattern | BabelNodeObjectPattern; declare type BabelNodeClass = BabelNodeClassExpression | BabelNodeClassDeclaration; -declare type BabelNodeModuleDeclaration = BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeImportDeclaration; +declare type BabelNodeImportOrExportDeclaration = BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeImportDeclaration; declare type BabelNodeExportDeclaration = BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration; declare type BabelNodeModuleSpecifier = BabelNodeExportSpecifier | BabelNodeImportDefaultSpecifier | BabelNodeImportNamespaceSpecifier | BabelNodeImportSpecifier | BabelNodeExportNamespaceSpecifier | BabelNodeExportDefaultSpecifier; declare type BabelNodeAccessor = BabelNodeClassAccessorProperty; @@ -3190,17 +3205,18 @@ declare type BabelNodeTypeScript = BabelNodeTSParameterProperty | BabelNodeTSDec declare type BabelNodeTSTypeElement = BabelNodeTSCallSignatureDeclaration | BabelNodeTSConstructSignatureDeclaration | BabelNodeTSPropertySignature | BabelNodeTSMethodSignature | BabelNodeTSIndexSignature; declare type BabelNodeTSType = BabelNodeTSAnyKeyword | BabelNodeTSBooleanKeyword | BabelNodeTSBigIntKeyword | BabelNodeTSIntrinsicKeyword | BabelNodeTSNeverKeyword | BabelNodeTSNullKeyword | BabelNodeTSNumberKeyword | BabelNodeTSObjectKeyword | BabelNodeTSStringKeyword | BabelNodeTSSymbolKeyword | BabelNodeTSUndefinedKeyword | BabelNodeTSUnknownKeyword | BabelNodeTSVoidKeyword | BabelNodeTSThisType | BabelNodeTSFunctionType | BabelNodeTSConstructorType | BabelNodeTSTypeReference | BabelNodeTSTypePredicate | BabelNodeTSTypeQuery | BabelNodeTSTypeLiteral | BabelNodeTSArrayType | BabelNodeTSTupleType | BabelNodeTSOptionalType | BabelNodeTSRestType | BabelNodeTSUnionType | BabelNodeTSIntersectionType | BabelNodeTSConditionalType | BabelNodeTSInferType | BabelNodeTSParenthesizedType | BabelNodeTSTypeOperator | BabelNodeTSIndexedAccessType | BabelNodeTSMappedType | BabelNodeTSLiteralType | BabelNodeTSExpressionWithTypeArguments | BabelNodeTSImportType; declare type BabelNodeTSBaseType = BabelNodeTSAnyKeyword | BabelNodeTSBooleanKeyword | BabelNodeTSBigIntKeyword | BabelNodeTSIntrinsicKeyword | BabelNodeTSNeverKeyword | BabelNodeTSNullKeyword | BabelNodeTSNumberKeyword | BabelNodeTSObjectKeyword | BabelNodeTSStringKeyword | BabelNodeTSSymbolKeyword | BabelNodeTSUndefinedKeyword | BabelNodeTSUnknownKeyword | BabelNodeTSVoidKeyword | BabelNodeTSThisType | BabelNodeTSLiteralType; +declare type BabelNodeModuleDeclaration = BabelNodeExportAllDeclaration | BabelNodeExportDefaultDeclaration | BabelNodeExportNamedDeclaration | BabelNodeImportDeclaration; declare module "@babel/types" { declare export function arrayExpression(elements?: Array): BabelNodeArrayExpression; - declare export function assignmentExpression(operator: string, left: BabelNodeLVal, right: BabelNodeExpression): BabelNodeAssignmentExpression; + declare export function assignmentExpression(operator: string, left: BabelNodeLVal | BabelNodeOptionalMemberExpression, right: BabelNodeExpression): BabelNodeAssignmentExpression; declare export function binaryExpression(operator: "+" | "-" | "/" | "%" | "*" | "**" | "&" | "|" | ">>" | ">>>" | "<<" | "^" | "==" | "===" | "!=" | "!==" | "in" | "instanceof" | ">" | "<" | ">=" | "<=" | "|>", left: BabelNodeExpression | BabelNodePrivateName, right: BabelNodeExpression): BabelNodeBinaryExpression; declare export function interpreterDirective(value: string): BabelNodeInterpreterDirective; declare export function directive(value: BabelNodeDirectiveLiteral): BabelNodeDirective; declare export function directiveLiteral(value: string): BabelNodeDirectiveLiteral; declare export function blockStatement(body: Array, directives?: Array): BabelNodeBlockStatement; declare export function breakStatement(label?: BabelNodeIdentifier): BabelNodeBreakStatement; - declare export function callExpression(callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier, _arguments: Array): BabelNodeCallExpression; + declare export function callExpression(callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier, _arguments: Array): BabelNodeCallExpression; declare export function catchClause(param?: BabelNodeIdentifier | BabelNodeArrayPattern | BabelNodeObjectPattern, body: BabelNodeBlockStatement): BabelNodeCatchClause; declare export function conditionalExpression(test: BabelNodeExpression, consequent: BabelNodeExpression, alternate: BabelNodeExpression): BabelNodeConditionalExpression; declare export function continueStatement(label?: BabelNodeIdentifier): BabelNodeContinueStatement; @@ -3223,7 +3239,7 @@ declare module "@babel/types" { declare export function regExpLiteral(pattern: string, flags?: string): BabelNodeRegExpLiteral; declare export function logicalExpression(operator: "||" | "&&" | "??", left: BabelNodeExpression, right: BabelNodeExpression): BabelNodeLogicalExpression; declare export function memberExpression(object: BabelNodeExpression | BabelNodeSuper, property: BabelNodeExpression | BabelNodeIdentifier | BabelNodePrivateName, computed?: boolean, optional?: true | false): BabelNodeMemberExpression; - declare export function newExpression(callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier, _arguments: Array): BabelNodeNewExpression; + declare export function newExpression(callee: BabelNodeExpression | BabelNodeSuper | BabelNodeV8IntrinsicIdentifier, _arguments: Array): BabelNodeNewExpression; declare export function program(body: Array, directives?: Array, sourceType?: "script" | "module", interpreter?: BabelNodeInterpreterDirective): BabelNodeProgram; declare export function objectExpression(properties: Array): BabelNodeObjectExpression; declare export function objectMethod(kind?: "method" | "get" | "set", key: BabelNodeExpression | BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeBigIntLiteral, params: Array, body: BabelNodeBlockStatement, computed?: boolean, generator?: boolean, async?: boolean): BabelNodeObjectMethod; @@ -3239,7 +3255,7 @@ declare module "@babel/types" { declare export function tryStatement(block: BabelNodeBlockStatement, handler?: BabelNodeCatchClause, finalizer?: BabelNodeBlockStatement): BabelNodeTryStatement; declare export function unaryExpression(operator: "void" | "throw" | "delete" | "!" | "+" | "-" | "~" | "typeof", argument: BabelNodeExpression, prefix?: boolean): BabelNodeUnaryExpression; declare export function updateExpression(operator: "++" | "--", argument: BabelNodeExpression, prefix?: boolean): BabelNodeUpdateExpression; - declare export function variableDeclaration(kind: "var" | "let" | "const" | "using", declarations: Array): BabelNodeVariableDeclaration; + declare export function variableDeclaration(kind: "var" | "let" | "const" | "using" | "await using", declarations: Array): BabelNodeVariableDeclaration; declare export function variableDeclarator(id: BabelNodeLVal, init?: BabelNodeExpression): BabelNodeVariableDeclarator; declare export function whileStatement(test: BabelNodeExpression, body: BabelNodeStatement): BabelNodeWhileStatement; declare export function withStatement(object: BabelNodeExpression, body: BabelNodeStatement): BabelNodeWithStatement; @@ -3248,7 +3264,7 @@ declare module "@babel/types" { declare export function arrowFunctionExpression(params: Array, body: BabelNodeBlockStatement | BabelNodeExpression, async?: boolean): BabelNodeArrowFunctionExpression; declare export function classBody(body: Array): BabelNodeClassBody; declare export function classExpression(id?: BabelNodeIdentifier, superClass?: BabelNodeExpression, body: BabelNodeClassBody, decorators?: Array): BabelNodeClassExpression; - declare export function classDeclaration(id: BabelNodeIdentifier, superClass?: BabelNodeExpression, body: BabelNodeClassBody, decorators?: Array): BabelNodeClassDeclaration; + declare export function classDeclaration(id?: BabelNodeIdentifier, superClass?: BabelNodeExpression, body: BabelNodeClassBody, decorators?: Array): BabelNodeClassDeclaration; declare export function exportAllDeclaration(source: BabelNodeStringLiteral): BabelNodeExportAllDeclaration; declare export function exportDefaultDeclaration(declaration: BabelNodeTSDeclareFunction | BabelNodeFunctionDeclaration | BabelNodeClassDeclaration | BabelNodeExpression): BabelNodeExportDefaultDeclaration; declare export function exportNamedDeclaration(declaration?: BabelNodeDeclaration, specifiers?: Array, source?: BabelNodeStringLiteral): BabelNodeExportNamedDeclaration; @@ -3258,6 +3274,7 @@ declare module "@babel/types" { declare export function importDefaultSpecifier(local: BabelNodeIdentifier): BabelNodeImportDefaultSpecifier; declare export function importNamespaceSpecifier(local: BabelNodeIdentifier): BabelNodeImportNamespaceSpecifier; declare export function importSpecifier(local: BabelNodeIdentifier, imported: BabelNodeIdentifier | BabelNodeStringLiteral): BabelNodeImportSpecifier; + declare export function importExpression(source: BabelNodeExpression, options?: BabelNodeExpression): BabelNodeImportExpression; declare export function metaProperty(meta: BabelNodeIdentifier, property: BabelNodeIdentifier): BabelNodeMetaProperty; declare export function classMethod(kind?: "get" | "set" | "method" | "constructor", key: BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeBigIntLiteral | BabelNodeExpression, params: Array, body: BabelNodeBlockStatement, computed?: boolean, _static?: boolean, generator?: boolean, async?: boolean): BabelNodeClassMethod; declare export function objectPattern(properties: Array): BabelNodeObjectPattern; @@ -3274,7 +3291,7 @@ declare module "@babel/types" { declare export function bigIntLiteral(value: string): BabelNodeBigIntLiteral; declare export function exportNamespaceSpecifier(exported: BabelNodeIdentifier): BabelNodeExportNamespaceSpecifier; declare export function optionalMemberExpression(object: BabelNodeExpression, property: BabelNodeExpression | BabelNodeIdentifier, computed?: boolean, optional: boolean): BabelNodeOptionalMemberExpression; - declare export function optionalCallExpression(callee: BabelNodeExpression, _arguments: Array, optional: boolean): BabelNodeOptionalCallExpression; + declare export function optionalCallExpression(callee: BabelNodeExpression, _arguments: Array, optional: boolean): BabelNodeOptionalCallExpression; declare export function classProperty(key: BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeBigIntLiteral | BabelNodeExpression, value?: BabelNodeExpression, typeAnnotation?: BabelNodeTypeAnnotation | BabelNodeTSTypeAnnotation | BabelNodeNoop, decorators?: Array, computed?: boolean, _static?: boolean): BabelNodeClassProperty; declare export function classAccessorProperty(key: BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeBigIntLiteral | BabelNodeExpression | BabelNodePrivateName, value?: BabelNodeExpression, typeAnnotation?: BabelNodeTypeAnnotation | BabelNodeTSTypeAnnotation | BabelNodeNoop, decorators?: Array, computed?: boolean, _static?: boolean): BabelNodeClassAccessorProperty; declare export function classPrivateProperty(key: BabelNodePrivateName, value?: BabelNodeExpression, decorators?: Array, _static?: boolean): BabelNodeClassPrivateProperty; @@ -3382,10 +3399,10 @@ declare module "@babel/types" { declare export function tsDeclareFunction(id?: BabelNodeIdentifier, typeParameters?: BabelNodeTSTypeParameterDeclaration | BabelNodeNoop, params: Array, returnType?: BabelNodeTSTypeAnnotation | BabelNodeNoop): BabelNodeTSDeclareFunction; declare export function tsDeclareMethod(decorators?: Array, key: BabelNodeIdentifier | BabelNodeStringLiteral | BabelNodeNumericLiteral | BabelNodeBigIntLiteral | BabelNodeExpression, typeParameters?: BabelNodeTSTypeParameterDeclaration | BabelNodeNoop, params: Array, returnType?: BabelNodeTSTypeAnnotation | BabelNodeNoop): BabelNodeTSDeclareMethod; declare export function tsQualifiedName(left: BabelNodeTSEntityName, right: BabelNodeIdentifier): BabelNodeTSQualifiedName; - declare export function tsCallSignatureDeclaration(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSCallSignatureDeclaration; - declare export function tsConstructSignatureDeclaration(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSConstructSignatureDeclaration; - declare export function tsPropertySignature(key: BabelNodeExpression, typeAnnotation?: BabelNodeTSTypeAnnotation, initializer?: BabelNodeExpression): BabelNodeTSPropertySignature; - declare export function tsMethodSignature(key: BabelNodeExpression, typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSMethodSignature; + declare export function tsCallSignatureDeclaration(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSCallSignatureDeclaration; + declare export function tsConstructSignatureDeclaration(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSConstructSignatureDeclaration; + declare export function tsPropertySignature(key: BabelNodeExpression, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSPropertySignature; + declare export function tsMethodSignature(key: BabelNodeExpression, typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSMethodSignature; declare export function tsIndexSignature(parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSIndexSignature; declare export function tsAnyKeyword(): BabelNodeTSAnyKeyword; declare export function tsBooleanKeyword(): BabelNodeTSBooleanKeyword; @@ -3401,8 +3418,8 @@ declare module "@babel/types" { declare export function tsUnknownKeyword(): BabelNodeTSUnknownKeyword; declare export function tsVoidKeyword(): BabelNodeTSVoidKeyword; declare export function tsThisType(): BabelNodeTSThisType; - declare export function tsFunctionType(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSFunctionType; - declare export function tsConstructorType(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSConstructorType; + declare export function tsFunctionType(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSFunctionType; + declare export function tsConstructorType(typeParameters?: BabelNodeTSTypeParameterDeclaration, parameters: Array, typeAnnotation?: BabelNodeTSTypeAnnotation): BabelNodeTSConstructorType; declare export function tsTypeReference(typeName: BabelNodeTSEntityName, typeParameters?: BabelNodeTSTypeParameterInstantiation): BabelNodeTSTypeReference; declare export function tsTypePredicate(parameterName: BabelNodeIdentifier | BabelNodeTSThisType, typeAnnotation?: BabelNodeTSTypeAnnotation, asserts?: boolean): BabelNodeTSTypePredicate; declare export function tsTypeQuery(exprName: BabelNodeTSEntityName | BabelNodeTSImportType, typeParameters?: BabelNodeTSTypeParameterInstantiation): BabelNodeTSTypeQuery; @@ -3509,6 +3526,7 @@ declare module "@babel/types" { declare export function isImportDefaultSpecifier(node: ?Object, opts?: ?Object): node is ImportDefaultSpecifier; declare export function isImportNamespaceSpecifier(node: ?Object, opts?: ?Object): node is ImportNamespaceSpecifier; declare export function isImportSpecifier(node: ?Object, opts?: ?Object): node is ImportSpecifier; + declare export function isImportExpression(node: ?Object, opts?: ?Object): node is ImportExpression; declare export function isMetaProperty(node: ?Object, opts?: ?Object): node is MetaProperty; declare export function isClassMethod(node: ?Object, opts?: ?Object): node is ClassMethod; declare export function isObjectPattern(node: ?Object, opts?: ?Object): node is ObjectPattern; @@ -3692,8 +3710,8 @@ declare module "@babel/types" { declare export function isTSTypeParameterInstantiation(node: ?Object, opts?: ?Object): node is TSTypeParameterInstantiation; declare export function isTSTypeParameterDeclaration(node: ?Object, opts?: ?Object): node is TSTypeParameterDeclaration; declare export function isTSTypeParameter(node: ?Object, opts?: ?Object): node is TSTypeParameter; - declare export function isStandardized(node: ?Object, opts?: ?Object): node is (ArrayExpression | AssignmentExpression | BinaryExpression | InterpreterDirective | Directive | DirectiveLiteral | BlockStatement | BreakStatement | CallExpression | CatchClause | ConditionalExpression | ContinueStatement | DebuggerStatement | DoWhileStatement | EmptyStatement | ExpressionStatement | File | ForInStatement | ForStatement | FunctionDeclaration | FunctionExpression | Identifier | IfStatement | LabeledStatement | StringLiteral | NumericLiteral | NullLiteral | BooleanLiteral | RegExpLiteral | LogicalExpression | MemberExpression | NewExpression | Program | ObjectExpression | ObjectMethod | ObjectProperty | RestElement | ReturnStatement | SequenceExpression | ParenthesizedExpression | SwitchCase | SwitchStatement | ThisExpression | ThrowStatement | TryStatement | UnaryExpression | UpdateExpression | VariableDeclaration | VariableDeclarator | WhileStatement | WithStatement | AssignmentPattern | ArrayPattern | ArrowFunctionExpression | ClassBody | ClassExpression | ClassDeclaration | ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | ExportSpecifier | ForOfStatement | ImportDeclaration | ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier | MetaProperty | ClassMethod | ObjectPattern | SpreadElement | Super | TaggedTemplateExpression | TemplateElement | TemplateLiteral | YieldExpression | AwaitExpression | Import | BigIntLiteral | ExportNamespaceSpecifier | OptionalMemberExpression | OptionalCallExpression | ClassProperty | ClassAccessorProperty | ClassPrivateProperty | ClassPrivateMethod | PrivateName | StaticBlock); - declare export function isExpression(node: ?Object, opts?: ?Object): node is (ArrayExpression | AssignmentExpression | BinaryExpression | CallExpression | ConditionalExpression | FunctionExpression | Identifier | StringLiteral | NumericLiteral | NullLiteral | BooleanLiteral | RegExpLiteral | LogicalExpression | MemberExpression | NewExpression | ObjectExpression | SequenceExpression | ParenthesizedExpression | ThisExpression | UnaryExpression | UpdateExpression | ArrowFunctionExpression | ClassExpression | MetaProperty | Super | TaggedTemplateExpression | TemplateLiteral | YieldExpression | AwaitExpression | Import | BigIntLiteral | OptionalMemberExpression | OptionalCallExpression | TypeCastExpression | JSXElement | JSXFragment | BindExpression | DoExpression | RecordExpression | TupleExpression | DecimalLiteral | ModuleExpression | TopicReference | PipelineTopicExpression | PipelineBareFunction | PipelinePrimaryTopicReference | TSInstantiationExpression | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression); + declare export function isStandardized(node: ?Object, opts?: ?Object): node is (ArrayExpression | AssignmentExpression | BinaryExpression | InterpreterDirective | Directive | DirectiveLiteral | BlockStatement | BreakStatement | CallExpression | CatchClause | ConditionalExpression | ContinueStatement | DebuggerStatement | DoWhileStatement | EmptyStatement | ExpressionStatement | File | ForInStatement | ForStatement | FunctionDeclaration | FunctionExpression | Identifier | IfStatement | LabeledStatement | StringLiteral | NumericLiteral | NullLiteral | BooleanLiteral | RegExpLiteral | LogicalExpression | MemberExpression | NewExpression | Program | ObjectExpression | ObjectMethod | ObjectProperty | RestElement | ReturnStatement | SequenceExpression | ParenthesizedExpression | SwitchCase | SwitchStatement | ThisExpression | ThrowStatement | TryStatement | UnaryExpression | UpdateExpression | VariableDeclaration | VariableDeclarator | WhileStatement | WithStatement | AssignmentPattern | ArrayPattern | ArrowFunctionExpression | ClassBody | ClassExpression | ClassDeclaration | ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | ExportSpecifier | ForOfStatement | ImportDeclaration | ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier | ImportExpression | MetaProperty | ClassMethod | ObjectPattern | SpreadElement | Super | TaggedTemplateExpression | TemplateElement | TemplateLiteral | YieldExpression | AwaitExpression | Import | BigIntLiteral | ExportNamespaceSpecifier | OptionalMemberExpression | OptionalCallExpression | ClassProperty | ClassAccessorProperty | ClassPrivateProperty | ClassPrivateMethod | PrivateName | StaticBlock); + declare export function isExpression(node: ?Object, opts?: ?Object): node is (ArrayExpression | AssignmentExpression | BinaryExpression | CallExpression | ConditionalExpression | FunctionExpression | Identifier | StringLiteral | NumericLiteral | NullLiteral | BooleanLiteral | RegExpLiteral | LogicalExpression | MemberExpression | NewExpression | ObjectExpression | SequenceExpression | ParenthesizedExpression | ThisExpression | UnaryExpression | UpdateExpression | ArrowFunctionExpression | ClassExpression | ImportExpression | MetaProperty | Super | TaggedTemplateExpression | TemplateLiteral | YieldExpression | AwaitExpression | Import | BigIntLiteral | OptionalMemberExpression | OptionalCallExpression | TypeCastExpression | JSXElement | JSXFragment | BindExpression | DoExpression | RecordExpression | TupleExpression | DecimalLiteral | ModuleExpression | TopicReference | PipelineTopicExpression | PipelineBareFunction | PipelinePrimaryTopicReference | TSInstantiationExpression | TSAsExpression | TSSatisfiesExpression | TSTypeAssertion | TSNonNullExpression); declare export function isBinary(node: ?Object, opts?: ?Object): node is (BinaryExpression | LogicalExpression); declare export function isScopable(node: ?Object, opts?: ?Object): node is (BlockStatement | CatchClause | DoWhileStatement | ForInStatement | ForStatement | FunctionDeclaration | FunctionExpression | Program | ObjectMethod | SwitchStatement | WhileStatement | ArrowFunctionExpression | ClassExpression | ClassDeclaration | ForOfStatement | ClassMethod | ClassPrivateMethod | StaticBlock | TSModuleBlock); declare export function isBlockParent(node: ?Object, opts?: ?Object): node is (BlockStatement | CatchClause | DoWhileStatement | ForInStatement | ForStatement | FunctionDeclaration | FunctionExpression | Program | ObjectMethod | SwitchStatement | WhileStatement | ArrowFunctionExpression | ForOfStatement | ClassMethod | ClassPrivateMethod | StaticBlock | TSModuleBlock); @@ -3723,7 +3741,7 @@ declare module "@babel/types" { declare export function isUnaryLike(node: ?Object, opts?: ?Object): node is (UnaryExpression | SpreadElement); declare export function isPattern(node: ?Object, opts?: ?Object): node is (AssignmentPattern | ArrayPattern | ObjectPattern); declare export function isClass(node: ?Object, opts?: ?Object): node is (ClassExpression | ClassDeclaration); - declare export function isModuleDeclaration(node: ?Object, opts?: ?Object): node is (ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | ImportDeclaration); + declare export function isImportOrExportDeclaration(node: ?Object, opts?: ?Object): node is (ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | ImportDeclaration); declare export function isExportDeclaration(node: ?Object, opts?: ?Object): node is (ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration); declare export function isModuleSpecifier(node: ?Object, opts?: ?Object): node is (ExportSpecifier | ImportDefaultSpecifier | ImportNamespaceSpecifier | ImportSpecifier | ExportNamespaceSpecifier | ExportDefaultSpecifier); declare export function isAccessor(node: ?Object, opts?: ?Object): node is (ClassAccessorProperty); @@ -3741,6 +3759,7 @@ declare module "@babel/types" { declare export function isTSTypeElement(node: ?Object, opts?: ?Object): node is (TSCallSignatureDeclaration | TSConstructSignatureDeclaration | TSPropertySignature | TSMethodSignature | TSIndexSignature); declare export function isTSType(node: ?Object, opts?: ?Object): node is (TSAnyKeyword | TSBooleanKeyword | TSBigIntKeyword | TSIntrinsicKeyword | TSNeverKeyword | TSNullKeyword | TSNumberKeyword | TSObjectKeyword | TSStringKeyword | TSSymbolKeyword | TSUndefinedKeyword | TSUnknownKeyword | TSVoidKeyword | TSThisType | TSFunctionType | TSConstructorType | TSTypeReference | TSTypePredicate | TSTypeQuery | TSTypeLiteral | TSArrayType | TSTupleType | TSOptionalType | TSRestType | TSUnionType | TSIntersectionType | TSConditionalType | TSInferType | TSParenthesizedType | TSTypeOperator | TSIndexedAccessType | TSMappedType | TSLiteralType | TSExpressionWithTypeArguments | TSImportType); declare export function isTSBaseType(node: ?Object, opts?: ?Object): node is (TSAnyKeyword | TSBooleanKeyword | TSBigIntKeyword | TSIntrinsicKeyword | TSNeverKeyword | TSNullKeyword | TSNumberKeyword | TSObjectKeyword | TSStringKeyword | TSSymbolKeyword | TSUndefinedKeyword | TSUnknownKeyword | TSVoidKeyword | TSThisType | TSLiteralType); + declare export function isModuleDeclaration(node: ?Object, opts?: ?Object): node is (ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration | ImportDeclaration); declare export function isNumberLiteral(node: ?Object, opts?: ?Object): node is NumericLiteral; declare export function isRegexLiteral(node: ?Object, opts?: ?Object): node is RegExpLiteral; declare export function isRestProperty(node: ?Object, opts?: ?Object): node is RestElement; @@ -3881,6 +3900,7 @@ declare module "@babel/types" { declare export type ImportDefaultSpecifier = BabelNodeImportDefaultSpecifier; declare export type ImportNamespaceSpecifier = BabelNodeImportNamespaceSpecifier; declare export type ImportSpecifier = BabelNodeImportSpecifier; + declare export type ImportExpression = BabelNodeImportExpression; declare export type MetaProperty = BabelNodeMetaProperty; declare export type ClassMethod = BabelNodeClassMethod; declare export type ObjectPattern = BabelNodeObjectPattern; @@ -4095,7 +4115,7 @@ declare module "@babel/types" { declare export type UnaryLike = BabelNodeUnaryLike; declare export type Pattern = BabelNodePattern; declare export type Class = BabelNodeClass; - declare export type ModuleDeclaration = BabelNodeModuleDeclaration; + declare export type ImportOrExportDeclaration = BabelNodeImportOrExportDeclaration; declare export type ExportDeclaration = BabelNodeExportDeclaration; declare export type ModuleSpecifier = BabelNodeModuleSpecifier; declare export type Accessor = BabelNodeAccessor; @@ -4113,4 +4133,5 @@ declare module "@babel/types" { declare export type TSTypeElement = BabelNodeTSTypeElement; declare export type TSType = BabelNodeTSType; declare export type TSBaseType = BabelNodeTSBaseType; + declare export type ModuleDeclaration = BabelNodeModuleDeclaration; } diff --git a/flow-typed/npm/pretty-format_v26.x.x.js b/flow-typed/npm/pretty-format_v26.x.x.js deleted file mode 100644 index bd2c68334cffb3..00000000000000 --- a/flow-typed/npm/pretty-format_v26.x.x.js +++ /dev/null @@ -1,49 +0,0 @@ -/** - * @flow strict - * @format - */ - -type PrettyFormatPlugin = - | { - test: (value: mixed) => boolean, - print: (value: mixed) => string, - } - | { - test: (value: mixed) => boolean, - serialize: (value: mixed) => string, - }; - -declare module 'pretty-format' { - declare module.exports: { - ( - value: mixed, - options?: ?{ - callToJSON?: ?boolean, - escapeRegex?: ?boolean, - escapeString?: ?boolean, - highlight?: ?boolean, - indent?: ?number, - maxDepth?: ?number, - min?: ?boolean, - plugins?: ?Array, - printFunctionName?: ?boolean, - theme?: ?{ - comment?: ?string, - prop?: ?string, - tag?: ?string, - value: ?string, - }, - }, - ): string, - - plugins: { - AsymmetricMatcher: PrettyFormatPlugin, - ConvertAnsi: PrettyFormatPlugin, - DOMCollection: PrettyFormatPlugin, - DOMElement: PrettyFormatPlugin, - Immutable: PrettyFormatPlugin, - ReactElement: PrettyFormatPlugin, - ReactTestComponent: PrettyFormatPlugin, - }, - }; -} diff --git a/flow-typed/npm/pretty-format_v29.x.x.js b/flow-typed/npm/pretty-format_v29.x.x.js new file mode 100644 index 00000000000000..e1654971a219e9 --- /dev/null +++ b/flow-typed/npm/pretty-format_v29.x.x.js @@ -0,0 +1,73 @@ +/** + * (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + * + * @flow strict + * @format + * @oncall react_native + */ +declare type Print = (value: mixed) => string; +declare type Indent = (value: string) => string; +declare type PluginOptions = { + edgeSpacing: string, + min: boolean, + spacing: string, +}; +declare type Colors = { + comment: {close: string, open: string}, + content: {close: string, open: string}, + prop: {close: string, open: string}, + tag: {close: string, open: string}, + value: {close: string, open: string}, +}; +declare type CompareKeys = ((a: string, b: string) => number) | null | void; + +declare type PrettyFormatPlugin = + | { + print: ( + value: mixed, + print?: ?Print, + indent?: ?Indent, + options?: ?PluginOptions, + colors?: ?Colors, + ) => string, + test: (value: mixed) => boolean, + } + | { + serialize: (value: mixed) => string, + test: (value: mixed) => boolean, + }; + +declare module 'pretty-format' { + declare export function format( + value: mixed, + options?: ?{ + callToJSON?: ?boolean, + compareKeys?: CompareKeys, + escapeRegex?: ?boolean, + escapeString?: ?boolean, + highlight?: ?boolean, + indent?: ?number, + maxDepth?: ?number, + maxWidth?: ?number, + min?: ?boolean, + plugins?: ?Array, + printBasicPrototype?: ?boolean, + printFunctionName?: ?boolean, + theme?: ?{ + comment?: ?string, + content?: ?string, + prop?: ?string, + tag?: ?string, + value: ?string, + }, + }, + ): string; + declare export const plugins: { + AsymmetricMatcher: PrettyFormatPlugin, + DOMCollection: PrettyFormatPlugin, + DOMElement: PrettyFormatPlugin, + Immutable: PrettyFormatPlugin, + ReactElement: PrettyFormatPlugin, + ReactTestComponent: PrettyFormatPlugin, + }; +} diff --git a/flow-typed/npm/react-test-renderer_v16.x.x.js b/flow-typed/npm/react-test-renderer_v16.x.x.js index 44dc3e2c71f2de..406dbafc0bf476 100644 --- a/flow-typed/npm/react-test-renderer_v16.x.x.js +++ b/flow-typed/npm/react-test-renderer_v16.x.x.js @@ -1,6 +1,3 @@ -// flow-typed signature: 7bac6c05f7415881918d3d510109e739 -// flow-typed version: fce74493f0/react-test-renderer_v16.x.x/flow_>=v0.104.x - // Type definitions for react-test-renderer 16.x.x // Ported from: https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/react-test-renderer @@ -44,14 +41,14 @@ type ReactTestInstance = { ... }; -type TestRendererOptions = { createNodeMock(element: React$Element): any, ... }; +type TestRendererOptions = { createNodeMock(element: React.MixedElement): any, ... }; declare module "react-test-renderer" { declare export type ReactTestRenderer = { toJSON(): null | ReactTestRendererJSON, toTree(): null | ReactTestRendererTree, - unmount(nextElement?: React$Element): void, - update(nextElement: React$Element): void, + unmount(nextElement?: React.MixedElement): void, + update(nextElement: React.MixedElement): void, getInstance(): ?ReactComponentInstance, root: ReactTestInstance, ... @@ -60,7 +57,7 @@ declare module "react-test-renderer" { declare type Thenable = { then(resolve: () => mixed, reject?: () => mixed): mixed, ... }; declare function create( - nextElement: React$Element, + nextElement: React.MixedElement, options?: TestRendererOptions ): ReactTestRenderer; @@ -71,9 +68,9 @@ declare module "react-test-renderer/shallow" { declare export default class ShallowRenderer { static createRenderer(): ShallowRenderer; getMountedInstance(): ReactTestInstance; - getRenderOutput>(): E; - getRenderOutput(): React$Element; - render(element: React$Element, context?: any): void; + getRenderOutput(): E; + getRenderOutput(): React.MixedElement; + render(element: React.MixedElement, context?: any): void; unmount(): void; } } diff --git a/flow-typed/npm/semver_v7.x.x.js b/flow-typed/npm/semver_v7.x.x.js new file mode 100644 index 00000000000000..9760b61198f01c --- /dev/null +++ b/flow-typed/npm/semver_v7.x.x.js @@ -0,0 +1,229 @@ +declare module 'semver' { + declare type Release = + | "major" + | "premajor" + | "minor" + | "preminor" + | "patch" + | "prepatch" + | "prerelease"; + + // The supported comparators are taken from the source here: + // https://github.com/npm/node-semver/blob/8bd070b550db2646362c9883c8d008d32f66a234/semver.js#L623 + declare type Operator = + | "===" + | "!==" + | "==" + | "=" + | "" // Not sure why you would want this, but whatever. + | "!=" + | ">" + | ">=" + | "<" + | "<="; + + declare class SemVer { + build: Array; + loose: ?boolean; + major: number; + minor: number; + patch: number; + prerelease: Array; + raw: string; + version: string; + + constructor(version: string | SemVer, options?: Options): SemVer; + compare(other: string | SemVer): -1 | 0 | 1; + compareMain(other: string | SemVer): -1 | 0 | 1; + comparePre(other: string | SemVer): -1 | 0 | 1; + compareBuild(other: string | SemVer): -1 | 0 | 1; + format(): string; + inc(release: Release, identifier: string): this; + } + + declare class Comparator { + options?: Options; + operator: Operator; + semver: SemVer; + value: string; + + constructor(comp: string | Comparator, options?: Options): Comparator; + parse(comp: string): void; + test(version: string): boolean; + } + + declare class Range { + loose: ?boolean; + raw: string; + set: Array>; + + constructor(range: string | Range, options?: Options): Range; + format(): string; + parseRange(range: string): Array; + test(version: string): boolean; + toString(): string; + } + + declare var SEMVER_SPEC_VERSION: string; + declare var re: Array; + declare var src: Array; + + declare type Options = { + options?: Options, + includePrerelease?: boolean, + ... + } | boolean; + + // Functions + declare function valid(v: string | SemVer, options?: Options): string | null; + declare function clean(v: string | SemVer, options?: Options): string | null; + declare function inc( + v: string | SemVer, + release: Release, + options?: Options, + identifier?: string + ): string | null; + declare function inc( + v: string | SemVer, + release: Release, + identifier: string + ): string | null; + declare function major(v: string | SemVer, options?: Options): number; + declare function minor(v: string | SemVer, options?: Options): number; + declare function patch(v: string | SemVer, options?: Options): number; + declare function intersects(r1: string | SemVer, r2: string | SemVer, loose?: boolean): boolean; + declare function minVersion(r: string | Range): Range | null; + + // Comparison + declare function gt( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function gte( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function lt( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function lte( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function eq( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function neq( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): boolean; + declare function cmp( + v1: string | SemVer, + comparator: Operator, + v2: string | SemVer, + options?: Options + ): boolean; + declare function compare( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): -1 | 0 | 1; + declare function rcompare( + v1: string | SemVer, + v2: string | SemVer, + options?: Options + ): -1 | 0 | 1; + declare function diff(v1: string | SemVer, v2: string | SemVer): ?Release; + declare function intersects(comparator: Comparator): boolean; + declare function sort( + list: Array, + options?: Options + ): Array; + declare function rsort( + list: Array, + options?: Options + ): Array; + declare function compareIdentifiers( + v1: string | SemVer, + v2: string | SemVer + ): -1 | 0 | 1; + declare function rcompareIdentifiers( + v1: string | SemVer, + v2: string | SemVer + ): -1 | 0 | 1; + + // Ranges + declare function validRange( + range: string | Range, + options?: Options + ): string | null; + declare function satisfies( + version: string | SemVer, + range: string | Range, + options?: Options + ): boolean; + declare function maxSatisfying( + versions: Array, + range: string | Range, + options?: Options + ): string | SemVer | null; + declare function minSatisfying( + versions: Array, + range: string | Range, + options?: Options + ): string | SemVer | null; + declare function gtr( + version: string | SemVer, + range: string | Range, + options?: Options + ): boolean; + declare function ltr( + version: string | SemVer, + range: string | Range, + options?: Options + ): boolean; + declare function outside( + version: string | SemVer, + range: string | Range, + hilo: ">" | "<", + options?: Options + ): boolean; + declare function intersects( + range: Range + ): boolean; + declare function simplifyRange( + ranges: Array, + range: string | Range, + options?: Options, + ): string | Range; + declare function subset( + sub: string | Range, + dom: string | Range, + options?: Options, + ): boolean; + + // Coercion + declare function coerce( + version: string | SemVer, + options?: Options + ): ?SemVer + + // Not explicitly documented, or deprecated + declare function parse(version: string, options?: Options): ?SemVer; + declare function toComparators( + range: string | Range, + options?: Options + ): Array>; +} + +declare module 'semver/preload' { + declare module.exports: $Exports<"semver">; +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba..a4b76b9530d66f 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 6f7a6eb33e8098..66cd5a0e49b557 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index b740cf13397ab1..f5feea6d6b116b 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 7101f8e4676fca..16302dedeb5262 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,3 +1,8 @@ +@REM Copyright (c) Meta Platforms, Inc. and affiliates. +@REM +@REM This source code is licensed under the MIT license found in the +@REM LICENSE file in the root directory of this source tree. + @rem @rem Copyright 2015 the original author or authors. @rem @@ -13,6 +18,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/jest.config.js b/jest.config.js index 2744eb6f6e31d5..e063d90a190714 100644 --- a/jest.config.js +++ b/jest.config.js @@ -30,10 +30,8 @@ module.exports = { testRegex: '/__tests__/.*-test(\\.fb)?\\.js$', testPathIgnorePatterns: [ '/node_modules/', - '/packages/react-native/template', '/packages/react-native/sdks', '/packages/react-native/Libraries/Renderer', - '/packages/rn-tester/e2e', '/packages/react-native-test-renderer/src', ], transformIgnorePatterns: ['node_modules/(?!@react-native/)'], diff --git a/package.json b/package.json index 453dac5a84503e..698d6a52972b71 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "print-packages": "node ./scripts/monorepo/print", "shellcheck": "./scripts/circleci/analyze_scripts.sh", "start": "cd packages/rn-tester && npm run start", - "set-version": "node ./scripts/releases/set-version", + "set-version": "node ./scripts/releases/set-version.js", "test-android": "./gradlew :packages:react-native:ReactAndroid:test", "test-ci": "jest --maxWorkers=2 --ci --reporters=\"default\" --reporters=\"jest-junit\"", "test-e2e-local-clean": "node ./scripts/release-testing/test-e2e-local-clean.js", @@ -36,26 +36,28 @@ }, "workspaces": [ "packages/*", - "tools/*" + "tools/*", + "!packages/helloworld" ], "devDependencies": { - "@babel/core": "^7.20.0", - "@babel/eslint-parser": "^7.20.0", - "@babel/generator": "^7.20.0", - "@babel/plugin-transform-regenerator": "^7.20.0", - "@babel/preset-env": "^7.20.0", - "@babel/preset-flow": "^7.20.0", + "@babel/core": "^7.25.2", + "@babel/eslint-parser": "^7.25.1", + "@babel/generator": "^7.25.0", + "@babel/plugin-transform-regenerator": "^7.24.7", + "@babel/preset-env": "^7.25.3", + "@babel/preset-flow": "^7.24.7", "@definitelytyped/dtslint": "^0.0.127", "@jest/create-cache-key-function": "^29.6.3", "@pkgjs/parseargs": "^0.11.0", - "@react-native/metro-babel-transformer": "0.75.0-main", - "@react-native/metro-config": "0.75.0-main", + "@react-native/metro-babel-transformer": "0.76.0-main", + "@react-native/metro-config": "0.76.0-main", "@tsconfig/node18": "1.0.1", "@types/react": "^18.2.6", "@typescript-eslint/parser": "^7.1.1", "ansi-styles": "^4.2.1", "babel-plugin-minify-dead-code-elimination": "^0.5.2", - "babel-plugin-transform-define": "^2.1.2", + "babel-plugin-syntax-hermes-parser": "0.23.1", + "babel-plugin-transform-define": "^2.1.4", "babel-plugin-transform-flow-enums": "^0.0.2", "babel-preset-fbjs": "^3.4.0", "chalk": "^4.0.0", @@ -75,23 +77,23 @@ "eslint-plugin-react-native": "^4.0.0", "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", - "flow-api-translator": "0.22.0", - "flow-bin": "^0.238.0", + "flow-api-translator": "0.23.1", + "flow-bin": "^0.245.2", "glob": "^7.1.1", - "hermes-eslint": "0.22.0", - "hermes-transform": "0.22.0", + "hermes-eslint": "0.23.1", + "hermes-transform": "0.23.1", "inquirer": "^7.1.0", "jest": "^29.6.3", "jest-junit": "^10.0.0", "jscodeshift": "^0.14.0", - "metro-babel-register": "^0.80.0", - "metro-memory-fs": "^0.80.0", + "metro-babel-register": "^0.80.10", + "metro-memory-fs": "^0.80.10", "micromatch": "^4.0.4", "mkdirp": "^0.5.1", "node-fetch": "^2.2.0", "nullthrows": "^1.1.1", "prettier": "2.8.8", - "prettier-plugin-hermes-parser": "0.22.0", + "prettier-plugin-hermes-parser": "0.23.1", "react": "19.0.0-rc-fb9a90fa48-20240614", "react-test-renderer": "19.0.0-rc-fb9a90fa48-20240614", "rimraf": "^3.0.2", diff --git a/packages/assets/package.json b/packages/assets/package.json index 8c19ed7ebe9585..3f5350a2410f9f 100644 --- a/packages/assets/package.json +++ b/packages/assets/package.json @@ -1,6 +1,6 @@ { "name": "@react-native/assets-registry", - "version": "0.75.0-main", + "version": "0.76.0-main", "description": "Asset support code for React Native.", "license": "MIT", "repository": { diff --git a/packages/assets/registry.js b/packages/assets/registry.js index 02470da3c4962a..64b2735d3bb528 100644 --- a/packages/assets/registry.js +++ b/packages/assets/registry.js @@ -10,6 +10,8 @@ 'use strict'; +export type AssetDestPathResolver = 'android' | 'generic'; + export type PackagerAsset = { +__packager_asset: boolean, +fileSystemLocation: string, @@ -20,6 +22,7 @@ export type PackagerAsset = { +hash: string, +name: string, +type: string, + +resolver?: AssetDestPathResolver, ... }; diff --git a/packages/babel-plugin-codegen/package.json b/packages/babel-plugin-codegen/package.json index 2ab077718db9f3..863beeefe3905f 100644 --- a/packages/babel-plugin-codegen/package.json +++ b/packages/babel-plugin-codegen/package.json @@ -1,6 +1,6 @@ { "name": "@react-native/babel-plugin-codegen", - "version": "0.75.0-main", + "version": "0.76.0-main", "description": "Babel plugin to generate native module and view manager code for React Native.", "license": "MIT", "repository": { @@ -25,10 +25,10 @@ "index.js" ], "dependencies": { - "@react-native/codegen": "0.75.0-main" + "@react-native/codegen": "0.76.0-main" }, "devDependencies": { - "@babel/core": "^7.20.0" + "@babel/core": "^7.25.2" }, "beachball": { "shouldPublish": false diff --git a/packages/community-cli-plugin/package.json b/packages/community-cli-plugin/package.json index 6a71df052b4a94..3cc08f87199533 100644 --- a/packages/community-cli-plugin/package.json +++ b/packages/community-cli-plugin/package.json @@ -1,6 +1,6 @@ { "name": "@react-native/community-cli-plugin", - "version": "0.75.0-main", + "version": "0.76.0-main", "description": "Core CLI commands for React Native", "keywords": [ "react-native", @@ -22,21 +22,26 @@ "dist" ], "dependencies": { - "@react-native-community/cli-server-api": "14.0.0-alpha.2", - "@react-native-community/cli-tools": "14.0.0-alpha.2", - "@react-native/dev-middleware": "0.75.0-main", - "@react-native/metro-babel-transformer": "0.75.0-main", + "@react-native/dev-middleware": "0.76.0-main", + "@react-native/metro-babel-transformer": "0.76.0-main", "chalk": "^4.0.0", "execa": "^5.1.1", - "metro": "^0.80.3", - "metro-config": "^0.80.3", - "metro-core": "^0.80.3", + "metro": "^0.80.10", + "metro-config": "^0.80.10", + "metro-core": "^0.80.10", "node-fetch": "^2.2.0", - "querystring": "^0.2.1", "readline": "^1.3.0" }, "devDependencies": { - "metro-resolver": "^0.80.3" + "metro-resolver": "^0.80.10" + }, + "peerDependencies": { + "@react-native-community/cli-server-api": "*" + }, + "peerDependenciesMeta": { + "@react-native-community/cli-server-api": { + "optional": true + } }, "engines": { "node": ">=18" diff --git a/packages/community-cli-plugin/src/commands/bundle/buildBundle.js b/packages/community-cli-plugin/src/commands/bundle/buildBundle.js index 98aac3b8fa5c46..8cfce1f1699c5c 100644 --- a/packages/community-cli-plugin/src/commands/bundle/buildBundle.js +++ b/packages/community-cli-plugin/src/commands/bundle/buildBundle.js @@ -14,10 +14,11 @@ import type {ConfigT} from 'metro-config'; import type {RequestOptions} from 'metro/src/shared/types.flow'; import loadMetroConfig from '../../utils/loadMetroConfig'; +import {logger} from '../../utils/logger'; import parseKeyValueParamArray from '../../utils/parseKeyValueParamArray'; import saveAssets from './saveAssets'; -import {logger} from '@react-native-community/cli-tools'; import chalk from 'chalk'; +import {promises as fs} from 'fs'; import Server from 'metro/src/Server'; import metroBundle from 'metro/src/shared/output/bundle'; import metroRamBundle from 'metro/src/shared/output/RamBundle'; @@ -112,6 +113,12 @@ async function buildBundleWithConfig( try { const bundle = await bundleImpl.build(server, requestOpts); + // Ensure destination directory exists before saving the bundle + await fs.mkdir(path.dirname(args.bundleOutput), { + recursive: true, + mode: 0o755, + }); + // $FlowIgnore[class-object-subtyping] // $FlowIgnore[incompatible-call] // $FlowIgnore[prop-missing] diff --git a/packages/community-cli-plugin/src/commands/bundle/saveAssets.js b/packages/community-cli-plugin/src/commands/bundle/saveAssets.js index 1aae31542fdc5d..a92e718182ad89 100644 --- a/packages/community-cli-plugin/src/commands/bundle/saveAssets.js +++ b/packages/community-cli-plugin/src/commands/bundle/saveAssets.js @@ -11,6 +11,7 @@ import type {AssetData} from 'metro/src/Assets'; +import {logger} from '../../utils/logger'; import { cleanAssetCatalog, getImageSet, @@ -20,7 +21,6 @@ import { import filterPlatformAssetScales from './filterPlatformAssetScales'; import getAssetDestPathAndroid from './getAssetDestPathAndroid'; import getAssetDestPathIOS from './getAssetDestPathIOS'; -import {logger} from '@react-native-community/cli-tools'; import fs from 'fs'; import path from 'path'; @@ -111,7 +111,9 @@ function copyAll(filesToCopy: CopiedFiles) { } else { // queue.length === 0 is checked in previous branch, so this is string const src = queue.shift(); + // $FlowFixMe[incompatible-type] const dest = filesToCopy[src]; + // $FlowFixMe[incompatible-call] copy(src, dest, copyNext); } }; diff --git a/packages/community-cli-plugin/src/commands/start/attachKeyHandlers.js b/packages/community-cli-plugin/src/commands/start/attachKeyHandlers.js index 1278832bc0f603..fcb387691e40dc 100644 --- a/packages/community-cli-plugin/src/commands/start/attachKeyHandlers.js +++ b/packages/community-cli-plugin/src/commands/start/attachKeyHandlers.js @@ -12,7 +12,7 @@ import type {Config} from '@react-native-community/cli-types'; import {KeyPressHandler} from '../../utils/KeyPressHandler'; -import {logger} from '@react-native-community/cli-tools'; +import {logger} from '../../utils/logger'; import chalk from 'chalk'; import execa from 'execa'; import fetch from 'node-fetch'; @@ -24,7 +24,6 @@ export default function attachKeyHandlers({ cliConfig, devServerUrl, messageSocket, - experimentalDebuggerFrontend, }: { cliConfig: Config, devServerUrl: string, @@ -32,7 +31,6 @@ export default function attachKeyHandlers({ broadcast: (type: string, params?: Record | null) => void, ... }>, - experimentalDebuggerFrontend: boolean, }) { if (process.stdin.isTTY !== true) { logger.debug('Interactive mode is not supported in this environment'); @@ -44,7 +42,7 @@ export default function attachKeyHandlers({ }; const onPress = async (key: string) => { - switch (key) { + switch (key.toLowerCase()) { case 'r': logger.info('Reloading connected app(s)...'); messageSocket.broadcast('reload', null); @@ -78,9 +76,7 @@ export default function attachKeyHandlers({ ).stdout?.pipe(process.stdout); break; case 'j': - if (!experimentalDebuggerFrontend) { - return; - } + // TODO(T192878199): Add multi-target selection await fetch(devServerUrl + '/open-debugger', {method: 'POST'}); break; case CTRL_C: @@ -101,11 +97,9 @@ export default function attachKeyHandlers({ '', `${chalk.bold('i')} - run on iOS`, `${chalk.bold('a')} - run on Android`, - `${chalk.bold('d')} - open Dev Menu`, - ...(experimentalDebuggerFrontend - ? [`${chalk.bold('j')} - open debugger (experimental, Hermes only)`] - : []), `${chalk.bold('r')} - reload app`, + `${chalk.bold('d')} - open Dev Menu`, + `${chalk.bold('j')} - open DevTools`, '', ].join('\n'), ); diff --git a/packages/community-cli-plugin/src/commands/start/index.js b/packages/community-cli-plugin/src/commands/start/index.js index 7cc22efb661861..cd438b2115fe67 100644 --- a/packages/community-cli-plugin/src/commands/start/index.js +++ b/packages/community-cli-plugin/src/commands/start/index.js @@ -95,13 +95,6 @@ const startCommand: Command = { name: '--no-interactive', description: 'Disables interactive mode', }, - { - name: '--experimental-debugger', - description: - "[Experimental] Enable the new debugger experience and 'j' to " + - 'debug. This enables the new frontend experience only: connection ' + - 'reliability and some basic features are unstable in this release.', - }, ], }; diff --git a/packages/community-cli-plugin/src/commands/start/middleware.js b/packages/community-cli-plugin/src/commands/start/middleware.js new file mode 100644 index 00000000000000..bd2235c3c7f585 --- /dev/null +++ b/packages/community-cli-plugin/src/commands/start/middleware.js @@ -0,0 +1,81 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import type {NextHandleFunction, Server} from 'connect'; +import type {TerminalReportableEvent} from 'metro/src/lib/TerminalReporter'; + +import {logger} from '../../utils/logger'; + +type MiddlewareReturn = { + middleware: Server, + websocketEndpoints: { + [path: string]: ws$WebSocketServer, + }, + messageSocketEndpoint: { + server: ws$WebSocketServer, + broadcast: (method: string, params?: Record | null) => void, + }, + eventsSocketEndpoint: { + server: ws$WebSocketServer, + reportEvent: (event: TerminalReportableEvent) => void, + }, + ... +}; + +const noopNextHandle: NextHandleFunction = (req, res, next) => { + next(); +}; + +// $FlowFixMe +const unusedStubWSServer: ws$WebSocketServer = {}; +// $FlowFixMe +const unusedMiddlewareStub: Server = {}; + +const communityMiddlewareFallback = { + createDevServerMiddleware: (params: { + host?: string, + port: number, + watchFolders: $ReadOnlyArray, + }): MiddlewareReturn => ({ + middleware: unusedMiddlewareStub, + websocketEndpoints: {}, + messageSocketEndpoint: { + server: unusedStubWSServer, + broadcast: ( + method: string, + _params?: Record | null, + ): void => {}, + }, + eventsSocketEndpoint: { + server: unusedStubWSServer, + reportEvent: (event: TerminalReportableEvent) => {}, + }, + }), + indexPageMiddleware: noopNextHandle, +}; + +// Attempt to use the community middleware if it exists, but fallback to +// the stubs if it doesn't. +try { + const community = require('@react-native-community/cli-server-api'); + communityMiddlewareFallback.indexPageMiddleware = + community.indexPageMiddleware; + communityMiddlewareFallback.createDevServerMiddleware = + community.createDevServerMiddleware; +} catch { + logger.debug(`⚠️ Unable to find @react-native-community/cli-server-api +Starting the server without the community middleware.`); +} + +export const createDevServerMiddleware = + communityMiddlewareFallback.createDevServerMiddleware; +export const indexPageMiddleware = + communityMiddlewareFallback.indexPageMiddleware; diff --git a/packages/community-cli-plugin/src/commands/start/runServer.js b/packages/community-cli-plugin/src/commands/start/runServer.js index 95cb7a92f7cdff..407800a72eadaa 100644 --- a/packages/community-cli-plugin/src/commands/start/runServer.js +++ b/packages/community-cli-plugin/src/commands/start/runServer.js @@ -16,12 +16,13 @@ import typeof TerminalReporter from 'metro/src/lib/TerminalReporter'; import isDevServerRunning from '../../utils/isDevServerRunning'; import loadMetroConfig from '../../utils/loadMetroConfig'; +import {logger} from '../../utils/logger'; +import * as version from '../../utils/version'; import attachKeyHandlers from './attachKeyHandlers'; import { createDevServerMiddleware, indexPageMiddleware, } from '@react-native-community/cli-server-api'; -import {logger, version} from '@react-native-community/cli-tools'; import {createDevMiddleware} from '@react-native/dev-middleware'; import chalk from 'chalk'; import Metro from 'metro'; @@ -33,7 +34,6 @@ export type StartCommandArgs = { assetPlugins?: string[], cert?: string, customLogReporterPath?: string, - experimentalDebugger: boolean, host?: string, https?: boolean, maxWorkers?: number, @@ -112,10 +112,6 @@ async function runServer( projectRoot, serverBaseUrl: devServerUrl, logger, - unstable_experiments: { - // NOTE: Only affects the /open-debugger endpoint - enableNewDebugger: args.experimentalDebugger, - }, }); let reportEvent: (event: TerminalReportableEvent) => void; @@ -134,7 +130,6 @@ async function runServer( cliConfig: ctx, devServerUrl, messageSocket: messageSocketEndpoint, - experimentalDebuggerFrontend: args.experimentalDebugger, }); } }, diff --git a/packages/community-cli-plugin/src/utils/KeyPressHandler.js b/packages/community-cli-plugin/src/utils/KeyPressHandler.js index 9cea7f8d92e8f2..af3609f8da4427 100644 --- a/packages/community-cli-plugin/src/utils/KeyPressHandler.js +++ b/packages/community-cli-plugin/src/utils/KeyPressHandler.js @@ -9,7 +9,8 @@ * @oncall react_native */ -import {CLIError, logger} from '@react-native-community/cli-tools'; +import {CLIError} from './errors'; +import {logger} from './logger'; const CTRL_C = '\u0003'; diff --git a/packages/community-cli-plugin/src/utils/errors.js b/packages/community-cli-plugin/src/utils/errors.js new file mode 100644 index 00000000000000..9f18ec69c793da --- /dev/null +++ b/packages/community-cli-plugin/src/utils/errors.js @@ -0,0 +1,39 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +/** + * A custom Error that creates a single-lined message to match current styling inside CLI. + * Uses original stack trace when `originalError` is passed or erase the stack if it's not defined. + */ +export class CLIError extends Error { + constructor(msg: string, originalError?: Error | string) { + super(inlineString(msg)); + if (originalError != null) { + this.stack = + typeof originalError === 'string' + ? originalError + : originalError.stack || ''.split('\n').slice(0, 2).join('\n'); + } else { + // When the "originalError" is not passed, it means that we know exactly + // what went wrong and provide means to fix it. In such cases showing the + // stack is an unnecessary clutter to the CLI output, hence removing it. + this.stack = ''; + } + } +} + +/** + * Raised when we're unable to find a package.json + */ +export class UnknownProjectError extends Error {} + +export const inlineString = (str: string = ''): string => + str.replace(/(\s{2,})/gm, ' ').trim(); diff --git a/packages/community-cli-plugin/src/utils/loadMetroConfig.js b/packages/community-cli-plugin/src/utils/loadMetroConfig.js index d3eaeb93bba8b3..3d116c4946b637 100644 --- a/packages/community-cli-plugin/src/utils/loadMetroConfig.js +++ b/packages/community-cli-plugin/src/utils/loadMetroConfig.js @@ -12,8 +12,9 @@ import type {Config} from '@react-native-community/cli-types'; import type {ConfigT, InputConfigT, YargArguments} from 'metro-config'; +import {CLIError} from './errors'; +import {logger} from './logger'; import {reactNativePlatformResolver} from './metroPlatformResolver'; -import {CLIError, logger} from '@react-native-community/cli-tools'; import {loadConfig, mergeConfig, resolveConfig} from 'metro-config'; import path from 'path'; @@ -98,7 +99,7 @@ export default async function loadMetroConfig( ================================================================================================= From React Native 0.73, your project's Metro config should extend '@react-native/metro-config' or it will fail to build. Please copy the template at: -https://github.com/facebook/react-native/blob/main/packages/react-native/template/metro.config.js +https://github.com/react-native-community/template/blob/main/template/metro.config.js This warning will be removed in future (https://github.com/facebook/metro/issues/1018). ================================================================================================= `; diff --git a/packages/community-cli-plugin/src/utils/logger.js b/packages/community-cli-plugin/src/utils/logger.js new file mode 100644 index 00000000000000..6b30a5287ebe10 --- /dev/null +++ b/packages/community-cli-plugin/src/utils/logger.js @@ -0,0 +1,112 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import chalk from 'chalk'; + +const SEPARATOR = ', '; + +let verbose: boolean = process.argv.includes('--verbose'); +let disabled: boolean = false; +let hidden: boolean = false; + +const formatMessages = (messages: Array) => + chalk.reset(messages.join(SEPARATOR)); + +const success = (...messages: Array) => { + if (!disabled) { + console.log(`${chalk.green.bold('success')} ${formatMessages(messages)}`); + } +}; + +const info = (...messages: Array) => { + if (!disabled) { + console.log(`${chalk.cyan.bold('info')} ${formatMessages(messages)}`); + } +}; + +const warn = (...messages: Array) => { + if (!disabled) { + console.warn(`${chalk.yellow.bold('warn')} ${formatMessages(messages)}`); + } +}; + +const error = (...messages: Array) => { + if (!disabled) { + console.error(`${chalk.red.bold('error')} ${formatMessages(messages)}`); + } +}; + +const debug = (...messages: Array) => { + if (verbose && !disabled) { + console.log(`${chalk.gray.bold('debug')} ${formatMessages(messages)}`); + } else { + hidden = true; + } +}; + +const log = (...messages: Array) => { + if (!disabled) { + console.log(`${formatMessages(messages)}`); + } +}; + +const setVerbose = (level: boolean) => { + verbose = level; +}; + +const isVerbose = (): boolean => verbose; + +const disable = () => { + disabled = true; +}; + +const enable = () => { + disabled = false; +}; + +const hasDebugMessages = (): boolean => hidden; + +let communityLogger; +try { + const {logger} = require('@react-native-community/cli-tools'); + logger.debug("Using @react-naive-community/cli-tools' logger"); + communityLogger = logger; +} catch { + // This is no longer a required dependency in react-native projects, but use it instead of + // our forked version if it's available. Fail silently otherwise. +} + +type Logger = $ReadOnly<{ + debug: (...message: Array) => void, + error: (...message: Array) => void, + log: (...message: Array) => void, + info: (...message: Array) => void, + warn: (...message: Array) => void, + ... +}>; + +export const logger: Logger = communityLogger ?? { + success, + info, + warn, + error, + debug, + log, + setVerbose, + isVerbose, + hasDebugMessages, + disable, + enable, +}; + +if (communityLogger == null) { + logger.debug("Using @react-native/communityu-cli-plugin's logger"); +} diff --git a/packages/community-cli-plugin/src/utils/parseKeyValueParamArray.js b/packages/community-cli-plugin/src/utils/parseKeyValueParamArray.js index 021529007aeddf..2ebdebb4fa0e43 100644 --- a/packages/community-cli-plugin/src/utils/parseKeyValueParamArray.js +++ b/packages/community-cli-plugin/src/utils/parseKeyValueParamArray.js @@ -9,8 +9,6 @@ * @oncall react_native */ -import querystring from 'querystring'; - export default function parseKeyValueParamArray( keyValueArray: $ReadOnlyArray, ): Record { @@ -23,8 +21,11 @@ export default function parseKeyValueParamArray( if (item.indexOf('&') !== -1) { throw new Error('Parameter cannot include "&" but found: ' + item); } - Object.assign(result, querystring.parse(item)); + const params = new URLSearchParams(item); + params.forEach((value, key) => { + // $FlowExpectedError[prop-missing] + result[key] = value; + }); } - return result; } diff --git a/packages/community-cli-plugin/src/utils/version.js b/packages/community-cli-plugin/src/utils/version.js new file mode 100644 index 00000000000000..bfbefc799c9ab1 --- /dev/null +++ b/packages/community-cli-plugin/src/utils/version.js @@ -0,0 +1,219 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + * @oncall react_native + */ + +import {logger} from './logger'; +import chalk from 'chalk'; +import {readFileSync} from 'fs'; +import path from 'path'; +import semver from 'semver'; + +type Release = { + // The current stable release + stable: string, + // The current candidate release. These are only populated if the latest release is a candidate release. + candidate?: string, + changelogUrl: string, + diffUrl: string, +}; + +interface DiffPurge { + name: string; + zipball_url: string; + tarball_url: string; + commit: { + sha: string, + url: string, + }; + node_id: string; +} + +type Update = { + // Only populated if an upgrade is available + upgrade?: Release, + // The project's package's current version + current: string, + // The project's package's name + name: string, +}; + +type LatestVersions = { + candidate?: string, + stable: string, +}; + +type Headers = { + 'User-Agent': string, + [header: string]: string, +}; + +function getReactNativeVersion(projectRoot: string): string | void { + try { + const resolvedPath: string = require.resolve('react-native/package.json', { + paths: [projectRoot], + }); + logger.debug( + `Found 'react-native' from '${projectRoot}' -> '${resolvedPath}'`, + ); + return JSON.parse(readFileSync(resolvedPath, 'utf8')).version; + } catch { + logger.debug("Couldn't read the version of 'react-native'"); + return; + } +} + +/** + * Logs out a message if the user's version is behind a stable version of React Native + */ +export async function logIfUpdateAvailable(projectRoot: string): Promise { + const versions = await latest(projectRoot); + if (!versions?.upgrade) { + return; + } + if (semver.gt(versions.upgrade.stable, versions.current)) { + logger.info( + `React Native v${versions.upgrade.stable} is now available (your project is running on v${versions.name}). +Changelog: ${chalk.dim.underline(versions.upgrade?.changelogUrl ?? 'none')} +Diff: ${chalk.dim.underline(versions.upgrade?.diffUrl ?? 'none')} +`, + ); + } +} + +/** + * Finds the latest stables version of React Native > current version + */ +async function latest(projectRoot: string): Promise { + try { + const currentVersion = getReactNativeVersion(projectRoot); + if (currentVersion == null) { + return; + } + const {name} = JSON.parse( + readFileSync(path.join(projectRoot, 'package.json'), 'utf8'), + ); + const upgrade = await getLatestRelease(name, currentVersion); + + if (upgrade) { + return { + name, + current: currentVersion, + upgrade, + }; + } + } catch (e) { + // We let the flow continue as this component is not vital for the rest of + // the CLI. + logger.debug( + 'Cannot detect current version of React Native, ' + + 'skipping check for a newer release', + ); + logger.debug(e); + } +} + +// $FlowFixMe +function isDiffPurgeEntry(data: Partial): data is DiffPurge { + return ( + [data.name, data.zipball_url, data.tarball_url, data.node_id].filter( + e => typeof e !== 'undefined', + ).length === 0 + ); +} + +/** + * Checks via GitHub API if there is a newer stable React Native release and, + * if it exists, returns the release data. + * + * If the latest release is not newer or if it's a prerelease, the function + * will return undefined. + */ +export default async function getLatestRelease( + name: string, + currentVersion: string, +): Promise { + logger.debug('Checking for a newer version of React Native'); + try { + logger.debug(`Current version: ${currentVersion}`); + + // if the version is a nightly/canary build, we want to bail + // since they are nightlies or unreleased versions + if (['-canary', '-nightly'].some(s => currentVersion.includes(s))) { + return; + } + + logger.debug('Checking for newer releases on GitHub'); + const latestVersion = await getLatestRnDiffPurgeVersion(name); + if (latestVersion == null) { + logger.debug('Failed to get latest release'); + return; + } + const {stable, candidate} = latestVersion; + logger.debug(`Latest release: ${stable} (${candidate ?? ''})`); + + if (semver.compare(stable, currentVersion) >= 0) { + return { + stable, + candidate, + changelogUrl: buildChangelogUrl(stable), + diffUrl: buildDiffUrl(currentVersion, stable), + }; + } + } catch (e) { + logger.debug( + 'Something went wrong with remote version checking, moving on', + ); + logger.debug(e); + } +} + +function buildChangelogUrl(version: string) { + return `https://github.com/facebook/react-native/releases/tag/v${version}`; +} + +function buildDiffUrl(oldVersion: string, newVersion: string) { + return `https://react-native-community.github.io/upgrade-helper/?from=${oldVersion}&to=${newVersion}`; +} + +/** + * Returns the most recent React Native version available to upgrade to. + */ +async function getLatestRnDiffPurgeVersion( + name: string, +): Promise { + const options = { + // https://developer.github.com/v3/#user-agent-required + headers: {'User-Agent': '@react-native/community-cli-plugin'} as Headers, + }; + + const resp = await fetch( + 'https://api.github.com/repos/react-native-community/rn-diff-purge/tags', + options, + ); + + const result: LatestVersions = {stable: '0.0.0'}; + + if (resp.status !== 200) { + return; + } + + const body: DiffPurge[] = (await resp.json()).filter(isDiffPurgeEntry); + for (const {name: version} of body) { + if (result.candidate != null && version.includes('-rc')) { + result.candidate = version.substring(8); + continue; + } + if (!version.includes('-rc')) { + result.stable = version.substring(8); + return result; + } + } + return result; +} diff --git a/packages/core-cli-utils/package.json b/packages/core-cli-utils/package.json index 739c42c1d937bd..4f37fe8a0189a4 100644 --- a/packages/core-cli-utils/package.json +++ b/packages/core-cli-utils/package.json @@ -1,6 +1,6 @@ { "name": "@react-native/core-cli-utils", - "version": "0.75.0-main", + "version": "0.76.0-main", "description": "React Native CLI library for Frameworks to build on", "license": "MIT", "main": "./src/index.flow.js", @@ -24,6 +24,6 @@ "node": ">=18" }, "files": [ - "src" + "dist" ] } diff --git a/packages/debugger-frontend/BUILD_INFO b/packages/debugger-frontend/BUILD_INFO index 789c9b30ed417e..61f0f52efcbc30 100644 --- a/packages/debugger-frontend/BUILD_INFO +++ b/packages/debugger-frontend/BUILD_INFO @@ -1,5 +1,5 @@ -@generated SignedSource<> -Git revision: f7e972ce2917749a125fc0871781d9307ca336e8 +@generated SignedSource<> +Git revision: a556d261a5e2131864f4e38ded62d8f90e81c39a Built with --nohooks: false Is local checkout: false Remote URL: https://github.com/facebookexperimental/rn-chrome-devtools-frontend diff --git a/packages/debugger-frontend/dist/third-party/front_end/Images/Images.js b/packages/debugger-frontend/dist/third-party/front_end/Images/Images.js index 937e5b3d1fa01f..33484bf152153b 100644 --- a/packages/debugger-frontend/dist/third-party/front_end/Images/Images.js +++ b/packages/debugger-frontend/dist/third-party/front_end/Images/Images.js @@ -18,6 +18,10 @@ style.setProperty('--image-file-navigationControls_2x', 'url(\"' + new URL('./na style.setProperty('--image-file-navigationControls', 'url(\"' + new URL('./navigationControls.png', import.meta.url).toString() + '\")'); style.setProperty('--image-file-nodeIcon', 'url(\"' + new URL('./nodeIcon.avif', import.meta.url).toString() + '\")'); style.setProperty('--image-file-popoverArrows', 'url(\"' + new URL('./popoverArrows.png', import.meta.url).toString() + '\")'); +style.setProperty('--image-file-react_native/learn-debugging-basics', 'url(\"' + new URL('./react_native/learn-debugging-basics.jpg', import.meta.url).toString() + '\")'); +style.setProperty('--image-file-react_native/learn-native-debugging', 'url(\"' + new URL('./react_native/learn-native-debugging.jpg', import.meta.url).toString() + '\")'); +style.setProperty('--image-file-react_native/learn-react-devtools', 'url(\"' + new URL('./react_native/learn-react-devtools.jpg', import.meta.url).toString() + '\")'); +style.setProperty('--image-file-react_native/learn-react-native-devtools', 'url(\"' + new URL('./react_native/learn-react-native-devtools.jpg', import.meta.url).toString() + '\")'); style.setProperty('--image-file-react_native/welcomeIcon', 'url(\"' + new URL('./react_native/welcomeIcon.png', import.meta.url).toString() + '\")'); style.setProperty('--image-file-toolbarResizerVertical', 'url(\"' + new URL('./toolbarResizerVertical.png', import.meta.url).toString() + '\")'); style.setProperty('--image-file-touchCursor_2x', 'url(\"' + new URL('./touchCursor_2x.png', import.meta.url).toString() + '\")'); diff --git a/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-debugging-basics.jpg b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-debugging-basics.jpg new file mode 100644 index 00000000000000..c0bc0a25784e58 Binary files /dev/null and b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-debugging-basics.jpg differ diff --git a/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-native-debugging.jpg b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-native-debugging.jpg new file mode 100644 index 00000000000000..ea73f9d8a9c94f Binary files /dev/null and b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-native-debugging.jpg differ diff --git a/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-devtools.jpg b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-devtools.jpg new file mode 100644 index 00000000000000..123481f6c61ab0 Binary files /dev/null and b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-devtools.jpg differ diff --git a/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-native-devtools.jpg b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-native-devtools.jpg new file mode 100644 index 00000000000000..e4b5d14f0f8d5b Binary files /dev/null and b/packages/debugger-frontend/dist/third-party/front_end/Images/react_native/learn-react-native-devtools.jpg differ diff --git a/packages/debugger-frontend/dist/third-party/front_end/core/host/host.js b/packages/debugger-frontend/dist/third-party/front_end/core/host/host.js index a608b7541fe6ab..44d7e9814a1c03 100644 --- a/packages/debugger-frontend/dist/third-party/front_end/core/host/host.js +++ b/packages/debugger-frontend/dist/third-party/front_end/core/host/host.js @@ -1 +1 @@ -import*as e from"../platform/platform.js";import*as r from"../root/root.js";import*as o from"../common/common.js";import*as t from"../i18n/i18n.js";var n;!function(e){e.AppendedToURL="appendedToURL",e.CanceledSaveURL="canceledSaveURL",e.ColorThemeChanged="colorThemeChanged",e.ContextMenuCleared="contextMenuCleared",e.ContextMenuItemSelected="contextMenuItemSelected",e.DeviceCountUpdated="deviceCountUpdated",e.DevicesDiscoveryConfigChanged="devicesDiscoveryConfigChanged",e.DevicesPortForwardingStatusChanged="devicesPortForwardingStatusChanged",e.DevicesUpdated="devicesUpdated",e.DispatchMessage="dispatchMessage",e.DispatchMessageChunk="dispatchMessageChunk",e.EnterInspectElementMode="enterInspectElementMode",e.EyeDropperPickedColor="eyeDropperPickedColor",e.FileSystemsLoaded="fileSystemsLoaded",e.FileSystemRemoved="fileSystemRemoved",e.FileSystemAdded="fileSystemAdded",e.FileSystemFilesChangedAddedRemoved="FileSystemFilesChangedAddedRemoved",e.IndexingTotalWorkCalculated="indexingTotalWorkCalculated",e.IndexingWorked="indexingWorked",e.IndexingDone="indexingDone",e.KeyEventUnhandled="keyEventUnhandled",e.ReattachRootTarget="reattachMainTarget",e.ReloadInspectedPage="reloadInspectedPage",e.RevealSourceLine="revealSourceLine",e.SavedURL="savedURL",e.SearchCompleted="searchCompleted",e.SetInspectedTabId="setInspectedTabId",e.SetUseSoftMenu="setUseSoftMenu",e.ShowPanel="showPanel"}(n||(n={}));const s=[[n.AppendedToURL,"appendedToURL",["url"]],[n.CanceledSaveURL,"canceledSaveURL",["url"]],[n.ColorThemeChanged,"colorThemeChanged",[]],[n.ContextMenuCleared,"contextMenuCleared",[]],[n.ContextMenuItemSelected,"contextMenuItemSelected",["id"]],[n.DeviceCountUpdated,"deviceCountUpdated",["count"]],[n.DevicesDiscoveryConfigChanged,"devicesDiscoveryConfigChanged",["config"]],[n.DevicesPortForwardingStatusChanged,"devicesPortForwardingStatusChanged",["status"]],[n.DevicesUpdated,"devicesUpdated",["devices"]],[n.DispatchMessage,"dispatchMessage",["messageObject"]],[n.DispatchMessageChunk,"dispatchMessageChunk",["messageChunk","messageSize"]],[n.EnterInspectElementMode,"enterInspectElementMode",[]],[n.EyeDropperPickedColor,"eyeDropperPickedColor",["color"]],[n.FileSystemsLoaded,"fileSystemsLoaded",["fileSystems"]],[n.FileSystemRemoved,"fileSystemRemoved",["fileSystemPath"]],[n.FileSystemAdded,"fileSystemAdded",["errorMessage","fileSystem"]],[n.FileSystemFilesChangedAddedRemoved,"fileSystemFilesChangedAddedRemoved",["changed","added","removed"]],[n.IndexingTotalWorkCalculated,"indexingTotalWorkCalculated",["requestId","fileSystemPath","totalWork"]],[n.IndexingWorked,"indexingWorked",["requestId","fileSystemPath","worked"]],[n.IndexingDone,"indexingDone",["requestId","fileSystemPath"]],[n.KeyEventUnhandled,"keyEventUnhandled",["event"]],[n.ReattachRootTarget,"reattachMainTarget",[]],[n.ReloadInspectedPage,"reloadInspectedPage",["hard"]],[n.RevealSourceLine,"revealSourceLine",["url","lineNumber","columnNumber"]],[n.SavedURL,"savedURL",["url","fileSystemPath"]],[n.SearchCompleted,"searchCompleted",["requestId","fileSystemPath","files"]],[n.SetInspectedTabId,"setInspectedTabId",["tabId"]],[n.SetUseSoftMenu,"setUseSoftMenu",["useSoftMenu"]],[n.ShowPanel,"showPanel",["panelName"]]];var i=Object.freeze({__proto__:null,get Events(){return n},EventDescriptors:s});const a={systemError:"System error",connectionError:"Connection error",certificateError:"Certificate error",httpError:"HTTP error",cacheError:"Cache error",signedExchangeError:"Signed Exchange error",ftpError:"FTP error",certificateManagerError:"Certificate manager error",dnsResolverError:"DNS resolver error",unknownError:"Unknown error",httpErrorStatusCodeSS:"HTTP error: status code {PH1}, {PH2}",invalidUrl:"Invalid URL",decodingDataUrlFailed:"Decoding Data URL failed"},d=t.i18n.registerUIStrings("core/host/ResourceLoader.ts",a),c=t.i18n.getLocalizedString.bind(void 0,d);let l=0;const u={},m=function(e){return u[++l]=e,l},g=function(e){u[e].close(),delete u[e]},p=function(e,r){u[e].write(r)};let h=function(e,r,t,n){const s=new o.StringOutputStream.StringOutputStream;w(e,r,s,(function(e,r,o){t(e,r,s.data(),o)}),n)};function v(e,r,o){if(void 0===e||void 0===o)return null;if(0!==e){if(function(e){return e<=-300&&e>-400}(e))return c(a.httpErrorStatusCodeSS,{PH1:String(r),PH2:o});const t=function(e){return c(e>-100?a.systemError:e>-200?a.connectionError:e>-300?a.certificateError:e>-400?a.httpError:e>-500?a.cacheError:e>-600?a.signedExchangeError:e>-700?a.ftpError:e>-800?a.certificateManagerError:e>-900?a.dnsResolverError:a.unknownError)}(e);return`${t}: ${o}`}return null}const w=function(e,r,t,n,s){const i=m(t);if(new o.ParsedURL.ParsedURL(e).isDataURL())return void(e=>new Promise(((r,o)=>{const t=new XMLHttpRequest;t.withCredentials=!1,t.open("GET",e,!0),t.onreadystatechange=function(){if(t.readyState===XMLHttpRequest.DONE){if(200!==t.status)return t.onreadystatechange=null,void o(new Error(String(t.status)));t.onreadystatechange=null,r(t.responseText)}},t.send(null)})))(e).then((function(e){p(i,e),l({statusCode:200})})).catch((function(e){l({statusCode:404,messageOverride:c(a.decodingDataUrlFailed)})}));if(!s&&function(e){try{const r=new URL(e);return"file:"===r.protocol&&""!==r.host}catch(e){return!1}}(e))return void(n&&n(!1,{},{statusCode:400,netError:-20,netErrorName:"net::BLOCKED_BY_CLIENT",message:"Loading from a remote file path is prohibited for security reasons."}));const d=[];if(r)for(const e in r)d.push(e+": "+r[e]);function l(e){if(n){const{success:r,description:o}=function(e){const{statusCode:r,netError:o,netErrorName:t,urlValid:n,messageOverride:s}=e;let i="";const d=r>=200&&r<300;if("string"==typeof s)i=s;else if(!d)if(void 0===o)i=c(!1===n?a.invalidUrl:a.unknownError);else{const e=v(o,r,t);e&&(i=e)}return console.assert(d===(0===i.length)),{success:d,description:{statusCode:r,netError:o,netErrorName:t,urlValid:n,message:i}}}(e);n(r,e.headers||{},o)}g(i)}I.loadNetworkResource(e,d.join("\r\n"),i,l)};var C=Object.freeze({__proto__:null,ResourceLoader:{},bindOutputStream:m,discardOutputStream:g,streamWrite:p,get load(){return h},setLoadForTest:function(e){h=e},netErrorToMessage:v,loadAsStream:w});const k={devtoolsS:"DevTools - {PH1}"},S=t.i18n.registerUIStrings("core/host/InspectorFrontendHost.ts",k),f=t.i18n.getLocalizedString.bind(void 0,S),y="/overrides";class b{#e;events;#r=null;recordedCountHistograms=[];recordedEnumeratedHistograms=[];recordedPerformanceHistograms=[];constructor(){function e(e){!("mac"===this.platform()?e.metaKey:e.ctrlKey)||"+"!==e.key&&"-"!==e.key||e.stopPropagation()}this.#e=new Map,"undefined"!=typeof document&&document.addEventListener("keydown",(r=>{e.call(this,r)}),!0)}platform(){const e=navigator.userAgent;return e.includes("Windows NT")?"windows":e.includes("Mac OS X")?"mac":"linux"}loadCompleted(){}bringToFront(){}closeWindow(){}setIsDocked(e,r){window.setTimeout(r,0)}showSurvey(e,r){window.setTimeout((()=>r({surveyShown:!1})),0)}canShowSurvey(e,r){window.setTimeout((()=>r({canShowSurvey:!1})),0)}setInspectedPageBounds(e){}inspectElementCompleted(){}setInjectedScriptForOrigin(e,r){}inspectedURLChanged(e){document.title=f(k.devtoolsS,{PH1:e.replace(/^https?:\/\//,"")})}copyText(e){null!=e&&navigator.clipboard.writeText(e)}openInNewTab(e){window.open(e,"_blank")}openSearchResultsInNewTab(e){o.Console.Console.instance().error("Search is not enabled in hosted mode. Please inspect using chrome://inspect")}showItemInFolder(e){o.Console.Console.instance().error("Show item in folder is not enabled in hosted mode. Please inspect using chrome://inspect")}save(e,r,o){let t=this.#e.get(e);t||(t=[],this.#e.set(e,t)),t.push(r),this.events.dispatchEventToListeners(n.SavedURL,{url:e,fileSystemPath:e})}append(e,r){const o=this.#e.get(e);o&&(o.push(r),this.events.dispatchEventToListeners(n.AppendedToURL,e))}close(r){const o=this.#e.get(r)||[];this.#e.delete(r);let t="";if(r)try{const o=e.StringUtilities.trimURL(r);t=e.StringUtilities.removeURLFragment(o)}catch(e){t=r}const n=document.createElement("a");n.download=t;const s=new Blob([o.join("")],{type:"text/plain"}),i=URL.createObjectURL(s);n.href=i,n.click(),URL.revokeObjectURL(i)}sendMessageToBackend(e){}recordCountHistogram(e,r,o,t,n){this.recordedCountHistograms.length>=100&&this.recordedCountHistograms.shift(),this.recordedCountHistograms.push({histogramName:e,sample:r,min:o,exclusiveMax:t,bucketSize:n})}recordEnumeratedHistogram(e,r,o){this.recordedEnumeratedHistograms.length>=100&&this.recordedEnumeratedHistograms.shift(),this.recordedEnumeratedHistograms.push({actionName:e,actionCode:r})}recordPerformanceHistogram(e,r){this.recordedPerformanceHistograms.length>=100&&this.recordedPerformanceHistograms.shift(),this.recordedPerformanceHistograms.push({histogramName:e,duration:r})}recordUserMetricsAction(e){}requestFileSystems(){this.events.dispatchEventToListeners(n.FileSystemsLoaded,[])}addFileSystem(e){window.webkitRequestFileSystem(window.TEMPORARY,1048576,(e=>{this.#r=e;const r={fileSystemName:"sandboxedRequestedFileSystem",fileSystemPath:y,rootURL:"filesystem:devtools://devtools/isolated/",type:"overrides"};this.events.dispatchEventToListeners(n.FileSystemAdded,{fileSystem:r})}))}removeFileSystem(e){const r=e=>{e.forEach((e=>{e.isDirectory?e.removeRecursively((()=>{})):e.isFile&&e.remove((()=>{}))}))};this.#r&&this.#r.root.createReader().readEntries(r),this.#r=null,this.events.dispatchEventToListeners(n.FileSystemRemoved,y)}isolatedFileSystem(e,r){return this.#r}loadNetworkResource(e,r,o,t){fetch(e).then((async e=>{const r=await e.arrayBuffer();let o=r;if(function(e){const r=new Uint8Array(e);return!(!r||r.length<3)&&31===r[0]&&139===r[1]&&8===r[2]}(r)){const e=new DecompressionStream("gzip"),t=e.writable.getWriter();t.write(r),t.close(),o=e.readable}return await new Response(o).text()})).then((function(e){p(o,e),t({statusCode:200,headers:void 0,messageOverride:void 0,netError:void 0,netErrorName:void 0,urlValid:void 0})})).catch((function(){t({statusCode:404,headers:void 0,messageOverride:void 0,netError:void 0,netErrorName:void 0,urlValid:void 0})}))}registerPreference(e,r){}getPreferences(e){const r={};for(const e in window.localStorage)r[e]=window.localStorage[e];e(r)}getPreference(e,r){r(window.localStorage[e])}setPreference(e,r){window.localStorage[e]=r}removePreference(e){delete window.localStorage[e]}clearPreferences(){window.localStorage.clear()}getSyncInformation(e){e({isSyncActive:!1,arePreferencesSynced:!1})}upgradeDraggedFileSystemPermissions(e){}indexPath(e,r,o){}stopIndexing(e){}searchInPath(e,r,o){}zoomFactor(){return 1}zoomIn(){}zoomOut(){}resetZoom(){}setWhitelistedShortcuts(e){}setEyeDropperActive(e){}showCertificateViewer(e){}reattach(e){e()}readyForTest(){}connectionReady(){}setOpenNewWindowForPopups(e){}setDevicesDiscoveryConfig(e){}setDevicesUpdatesEnabled(e){}performActionOnRemotePage(e,r){}openRemotePage(e,r){}openNodeFrontend(){}showContextMenuAtPoint(e,r,o,t){throw"Soft context menu should be used"}isHostedMode(){return!0}setAddExtensionCallback(e){}async initialTargetId(){return null}doAidaConversation(e,r,o){o({error:"Not implemened"})}registerAidaClientEvent(e){}recordImpression(e){}recordResize(e){}recordClick(e){}recordHover(e){}recordDrag(e){}recordChange(e){}recordKeyDown(e){}}let I=globalThis.InspectorFrontendHost;class x{constructor(){for(const e of s)this[e[1]]=this.dispatch.bind(this,e[0],e[2],e[3])}dispatch(e,r,o,...t){if(r.length<2){try{I.events.dispatchEventToListeners(e,t[0])}catch(e){console.error(e+" "+e.stack)}return}const n={};for(let e=0;e{let{promise:r,resolve:o,reject:t}=e.PromiseUtilities.promiseWithResolvers();return{write:async n=>{o(n),({promise:r,resolve:o,reject:t}=e.PromiseUtilities.promiseWithResolvers())},close:async()=>{o(null)},read:()=>r,fail:e=>t(e)}})(),t=m(o);let n;I.doAidaConversation(JSON.stringify(P.buildApiRequest(r)),t,(e=>{403===e.statusCode?o.fail(new Error("Server responded: permission denied")):e.error?o.fail(new Error(`Cannot send request: ${e.error} ${e.detail||""}`)):200!==e.statusCode?o.fail(new Error(`Request failed: ${JSON.stringify(e)}`)):o.close()}));const s=[];let i=!1;for(;n=await o.read();){if(!n.length)continue;let e;n.startsWith(",")&&(n=n.slice(1)),n.startsWith("[")||(n="["+n),n.endsWith("]")||(n+="]");try{e=JSON.parse(n)}catch(e){throw new Error("Cannot parse chunk: "+n,{cause:e})}const r="\n`````\n";for(const o of e)if("textChunk"in o)i&&(s.push(r),i=!1),s.push(o.textChunk.text);else{if(!("codeChunk"in o))throw"error"in o?new Error(`Server responded: ${JSON.stringify(o)}`):new Error("Unknown chunk result");i||(s.push(r),i=!0),s.push(o.codeChunk.code)}yield{explanation:s.join("")+(i?r:""),metadata:{rpcGlobalId:e[0]?.metadata?.rpcGlobalId}}}}}var T=Object.freeze({__proto__:null,AidaClient:P});let R,M,F,D,O;function _(){return R||(R=I.platform()),R}var H=Object.freeze({__proto__:null,platform:_,isMac:function(){return void 0===M&&(M="mac"===_()),M},isWin:function(){return void 0===F&&(F="windows"===_()),F},setPlatformForTests:function(e){R=e,M=void 0,F=void 0},isCustomDevtoolsFrontend:function(){return void 0===D&&(D=window.location.toString().startsWith("devtools://devtools/custom/")),D},fontFamily:function(){if(O)return O;switch(_()){case"linux":O="Roboto, Ubuntu, Arial, sans-serif";break;case"mac":O="'Lucida Grande', sans-serif";break;case"windows":O="'Segoe UI', Tahoma, sans-serif"}return O}});let A=null;function L(){return null===A&&(A=new N),A}class N{#o="error";#t=new Set;#n=null;addEventListener(e){this.#t.add(e);return()=>{this.#t.delete(e)}}removeAllEventListeners(){this.#t.clear()}sendEvent(e){if(!0!==globalThis.enableReactNativePerfMetrics)return;const r=this.#s(e),o=[];for(const e of this.#t)try{e(r)}catch(e){o.push(e)}if(o.length>0){const e=new AggregateError(o);console.error("Error occurred when calling event listeners",e)}}registerPerfMetricsGlobalPostMessageHandler(){!0===globalThis.enableReactNativePerfMetrics&&!0===globalThis.enableReactNativePerfMetricsGlobalPostMessage&&this.addEventListener((e=>{window.postMessage({event:e,tag:"react-native-chrome-devtools-perf-metrics"},window.location.origin)}))}registerGlobalErrorReporting(){window.addEventListener("error",(e=>{const[r,o]=W(`[RNPerfMetrics] uncaught error: ${e.message}`,e.error);this.sendEvent({eventName:"Browser.Error",params:{type:"error",message:r,error:o}})}),{passive:!0}),window.addEventListener("unhandledrejection",(e=>{const[r,o]=W("[RNPerfMetrics] unhandled promise rejection",e.reason);this.sendEvent({eventName:"Browser.Error",params:{type:"rejectedPromise",message:r,error:o}})}),{passive:!0});const e=globalThis.console,r=e[this.#o];e[this.#o]=(...o)=>{try{const e=o[0],[r,t]=W("[RNPerfMetrics] console.error",e);this.sendEvent({eventName:"Browser.Error",params:{message:r,error:t,type:"consoleError"}})}catch(e){const[r,o]=W("[RNPerfMetrics] Error handling console.error",e);this.sendEvent({eventName:"Browser.Error",params:{message:r,error:o,type:"consoleError"}})}finally{r.apply(e,o)}}}setLaunchId(e){this.#n=e}entryPointLoadingStarted(e){this.sendEvent({eventName:"Entrypoint.LoadingStarted",entryPoint:e})}entryPointLoadingFinished(e){this.sendEvent({eventName:"Entrypoint.LoadingFinished",entryPoint:e})}browserVisibilityChanged(e){this.sendEvent({eventName:"Browser.VisibilityChange",params:{visibilityState:e}})}remoteDebuggingTerminated(e){this.sendEvent({eventName:"Connection.DebuggingTerminated",params:{reason:e}})}developerResourceLoadingStarted(e,r){const o=U(e);this.sendEvent({eventName:"DeveloperResource.LoadingStarted",params:{url:o,loadingMethod:r}})}developerResourceLoadingFinished(e,r,o){const t=U(e);this.sendEvent({eventName:"DeveloperResource.LoadingFinished",params:{url:t,loadingMethod:r,success:o.success,errorMessage:o.errorDescription?.message}})}#s(e){return{...e,...{timestamp:performance.timeOrigin+performance.now(),launchId:this.#n}}}}function U(e){const{url:r}=e;return e.isHttpOrHttps()?r:`${r.slice(0,100)} …(omitted ${r.length-100} characters)`}function W(e,r){if(r instanceof Error){return[`${e}: ${r.message}`,r]}const o=`${e}: ${String(r)}`;return[o,new Error(o,{cause:r})]}var V,B,j,q,G,z,$,X,K,Q,J,Y,Z,ee,re,oe,te=Object.freeze({__proto__:null,getInstance:L});class ne{#i;#a;#d;constructor(){this.#i=!1,this.#a=!1,this.#d=""}breakpointWithConditionAdded(e){e>=2||I.recordEnumeratedHistogram("DevTools.BreakpointWithConditionAdded",e,2)}breakpointEditDialogRevealedFrom(e){e>=7||I.recordEnumeratedHistogram("DevTools.BreakpointEditDialogRevealedFrom",e,7)}panelShown(e,r){const o=B[e]||0;I.recordEnumeratedHistogram("DevTools.PanelShown",o,B.MaxValue),I.recordUserMetricsAction("DevTools_PanelShown_"+e),r||(this.#i=!0)}panelClosed(e){const r=B[e]||0;I.recordEnumeratedHistogram("DevTools.PanelClosed",r,B.MaxValue),this.#i=!0}panelShownInLocation(e,r){const o=j[`${e}-${r}`]||0;I.recordEnumeratedHistogram("DevTools.PanelShownInLocation",o,j.MaxValue)}elementsSidebarTabShown(e){const r=q[e]||0;I.recordEnumeratedHistogram("DevTools.Elements.SidebarTabShown",r,q.MaxValue)}sourcesSidebarTabShown(e){const r=G[e]||0;I.recordEnumeratedHistogram("DevTools.Sources.SidebarTabShown",r,G.MaxValue)}settingsPanelShown(e){this.panelShown("settings-"+e)}sourcesPanelFileDebugged(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.SourcesPanelFileDebugged",r,z.MaxValue)}sourcesPanelFileOpened(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.SourcesPanelFileOpened",r,z.MaxValue)}networkPanelResponsePreviewOpened(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.NetworkPanelResponsePreviewOpened",r,z.MaxValue)}actionTaken(e){I.recordEnumeratedHistogram("DevTools.ActionTaken",e,V.MaxValue)}panelLoaded(e,r){this.#a||e!==this.#d||(this.#a=!0,requestAnimationFrame((()=>{window.setTimeout((()=>{performance.mark(r),this.#i||I.recordPerformanceHistogram(r,performance.now())}),0)})))}setLaunchPanel(e){this.#d=e}performanceTraceLoad(e){I.recordPerformanceHistogram("DevTools.TraceLoad",e.duration)}keybindSetSettingChanged(e){const r=$[e]||0;I.recordEnumeratedHistogram("DevTools.KeybindSetSettingChanged",r,$.MaxValue)}keyboardShortcutFired(e){const r=X[e]||X.OtherShortcut;I.recordEnumeratedHistogram("DevTools.KeyboardShortcutFired",r,X.MaxValue)}issuesPanelOpenedFrom(e){I.recordEnumeratedHistogram("DevTools.IssuesPanelOpenedFrom",e,6)}issuesPanelIssueExpanded(e){if(void 0===e)return;const r=Q[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.IssuesPanelIssueExpanded",r,Q.MaxValue)}issuesPanelResourceOpened(e,r){const o=J[e+r];void 0!==o&&I.recordEnumeratedHistogram("DevTools.IssuesPanelResourceOpened",o,J.MaxValue)}issueCreated(e){const r=Y[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.IssueCreated",r,Y.MaxValue)}experimentEnabledAtLaunch(e){const r=K[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ExperimentEnabledAtLaunch",r,K.MaxValue)}experimentDisabledAtLaunch(e){const r=K[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ExperimentDisabledAtLaunch",r,K.MaxValue)}experimentChanged(e,r){const o=K[e];if(void 0===o)return;const t=r?"DevTools.ExperimentEnabled":"DevTools.ExperimentDisabled";I.recordEnumeratedHistogram(t,o,K.MaxValue)}developerResourceLoaded(e){e>=8||I.recordEnumeratedHistogram("DevTools.DeveloperResourceLoaded",e,8)}developerResourceScheme(e){e>=9||I.recordEnumeratedHistogram("DevTools.DeveloperResourceScheme",e,9)}inlineScriptParsed(e){e>=2||I.recordEnumeratedHistogram("DevTools.InlineScriptParsed",e,2)}vmInlineScriptContentShown(e){e>=2||I.recordEnumeratedHistogram("DevTools.VMInlineScriptShown",e,2)}language(e){const r=re[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.Language",r,re.MaxValue)}syncSetting(e){I.getSyncInformation((r=>{let o=1;r.isSyncActive&&!r.arePreferencesSynced?o=2:r.isSyncActive&&r.arePreferencesSynced&&(o=e?4:3),I.recordEnumeratedHistogram("DevTools.SyncSetting",o,5)}))}recordingAssertion(e){I.recordEnumeratedHistogram("DevTools.RecordingAssertion",e,4)}recordingToggled(e){I.recordEnumeratedHistogram("DevTools.RecordingToggled",e,3)}recordingReplayFinished(e){I.recordEnumeratedHistogram("DevTools.RecordingReplayFinished",e,5)}recordingReplaySpeed(e){I.recordEnumeratedHistogram("DevTools.RecordingReplaySpeed",e,5)}recordingReplayStarted(e){I.recordEnumeratedHistogram("DevTools.RecordingReplayStarted",e,4)}recordingEdited(e){I.recordEnumeratedHistogram("DevTools.RecordingEdited",e,11)}recordingExported(e){I.recordEnumeratedHistogram("DevTools.RecordingExported",e,6)}recordingCodeToggled(e){I.recordEnumeratedHistogram("DevTools.RecordingCodeToggled",e,3)}recordingCopiedToClipboard(e){I.recordEnumeratedHistogram("DevTools.RecordingCopiedToClipboard",e,9)}styleTextCopied(e){I.recordEnumeratedHistogram("DevTools.StyleTextCopied",e,11)}manifestSectionSelected(e){const r=oe[e]||oe.OtherSection;I.recordEnumeratedHistogram("DevTools.ManifestSectionSelected",r,oe.MaxValue)}cssHintShown(e){I.recordEnumeratedHistogram("DevTools.CSSHintShown",e,14)}lighthouseModeRun(e){I.recordEnumeratedHistogram("DevTools.LighthouseModeRun",e,4)}lighthouseCategoryUsed(e){I.recordEnumeratedHistogram("DevTools.LighthouseCategoryUsed",e,6)}colorConvertedFrom(e){I.recordEnumeratedHistogram("DevTools.ColorConvertedFrom",e,2)}colorPickerOpenedFrom(e){I.recordEnumeratedHistogram("DevTools.ColorPickerOpenedFrom",e,2)}cssPropertyDocumentation(e){I.recordEnumeratedHistogram("DevTools.CSSPropertyDocumentation",e,3)}swatchActivated(e){I.recordEnumeratedHistogram("DevTools.SwatchActivated",e,10)}badgeActivated(e){I.recordEnumeratedHistogram("DevTools.BadgeActivated",e,9)}breakpointsRestoredFromStorage(e){const r=this.#c(e);I.recordEnumeratedHistogram("DevTools.BreakpointsRestoredFromStorageCount",r,10)}animationPlaybackRateChanged(e){I.recordEnumeratedHistogram("DevTools.AnimationPlaybackRateChanged",e,4)}animationPointDragged(e){I.recordEnumeratedHistogram("DevTools.AnimationPointDragged",e,5)}#c(e){return e<100?0:e<300?1:e<1e3?2:e<3e3?3:e<1e4?4:e<3e4?5:e<1e5?6:e<3e5?7:e<1e6?8:9}workspacesPopulated(e){I.recordPerformanceHistogram("DevTools.Workspaces.PopulateWallClocktime",e)}visualLoggingProcessingDone(e){I.recordPerformanceHistogram("DevTools.VisualLogging.ProcessingTime",e)}legacyResourceTypeFilterNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,Z.MaxValue-1),1);I.recordEnumeratedHistogram("DevTools.LegacyResourceTypeFilterNumberOfSelectedChanged",r,Z.MaxValue)}legacyResourceTypeFilterItemSelected(e){const r=Z[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.LegacyResourceTypeFilterItemSelected",r,Z.MaxValue)}resourceTypeFilterNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,Z.MaxValue-1),1);I.recordEnumeratedHistogram("DevTools.ResourceTypeFilterNumberOfSelectedChanged",r,Z.MaxValue)}resourceTypeFilterItemSelected(e){const r=Z[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ResourceTypeFilterItemSelected",r,Z.MaxValue)}networkPanelMoreFiltersNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,ee.MaxValue),0);I.recordEnumeratedHistogram("DevTools.NetworkPanelMoreFiltersNumberOfSelectedChanged",r,ee.MaxValue)}networkPanelMoreFiltersItemSelected(e){const r=ee[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.NetworkPanelMoreFiltersItemSelected",r,ee.MaxValue)}}!function(e){e[e.WindowDocked=1]="WindowDocked",e[e.WindowUndocked=2]="WindowUndocked",e[e.ScriptsBreakpointSet=3]="ScriptsBreakpointSet",e[e.TimelineStarted=4]="TimelineStarted",e[e.ProfilesCPUProfileTaken=5]="ProfilesCPUProfileTaken",e[e.ProfilesHeapProfileTaken=6]="ProfilesHeapProfileTaken",e[e.ConsoleEvaluated=8]="ConsoleEvaluated",e[e.FileSavedInWorkspace=9]="FileSavedInWorkspace",e[e.DeviceModeEnabled=10]="DeviceModeEnabled",e[e.AnimationsPlaybackRateChanged=11]="AnimationsPlaybackRateChanged",e[e.RevisionApplied=12]="RevisionApplied",e[e.FileSystemDirectoryContentReceived=13]="FileSystemDirectoryContentReceived",e[e.StyleRuleEdited=14]="StyleRuleEdited",e[e.CommandEvaluatedInConsolePanel=15]="CommandEvaluatedInConsolePanel",e[e.DOMPropertiesExpanded=16]="DOMPropertiesExpanded",e[e.ResizedViewInResponsiveMode=17]="ResizedViewInResponsiveMode",e[e.TimelinePageReloadStarted=18]="TimelinePageReloadStarted",e[e.ConnectToNodeJSFromFrontend=19]="ConnectToNodeJSFromFrontend",e[e.ConnectToNodeJSDirectly=20]="ConnectToNodeJSDirectly",e[e.CpuThrottlingEnabled=21]="CpuThrottlingEnabled",e[e.CpuProfileNodeFocused=22]="CpuProfileNodeFocused",e[e.CpuProfileNodeExcluded=23]="CpuProfileNodeExcluded",e[e.SelectFileFromFilePicker=24]="SelectFileFromFilePicker",e[e.SelectCommandFromCommandMenu=25]="SelectCommandFromCommandMenu",e[e.ChangeInspectedNodeInElementsPanel=26]="ChangeInspectedNodeInElementsPanel",e[e.StyleRuleCopied=27]="StyleRuleCopied",e[e.CoverageStarted=28]="CoverageStarted",e[e.LighthouseStarted=29]="LighthouseStarted",e[e.LighthouseFinished=30]="LighthouseFinished",e[e.ShowedThirdPartyBadges=31]="ShowedThirdPartyBadges",e[e.LighthouseViewTrace=32]="LighthouseViewTrace",e[e.FilmStripStartedRecording=33]="FilmStripStartedRecording",e[e.CoverageReportFiltered=34]="CoverageReportFiltered",e[e.CoverageStartedPerBlock=35]="CoverageStartedPerBlock",e[e["SettingsOpenedFromGear-deprecated"]=36]="SettingsOpenedFromGear-deprecated",e[e["SettingsOpenedFromMenu-deprecated"]=37]="SettingsOpenedFromMenu-deprecated",e[e["SettingsOpenedFromCommandMenu-deprecated"]=38]="SettingsOpenedFromCommandMenu-deprecated",e[e.TabMovedToDrawer=39]="TabMovedToDrawer",e[e.TabMovedToMainPanel=40]="TabMovedToMainPanel",e[e.CaptureCssOverviewClicked=41]="CaptureCssOverviewClicked",e[e.VirtualAuthenticatorEnvironmentEnabled=42]="VirtualAuthenticatorEnvironmentEnabled",e[e.SourceOrderViewActivated=43]="SourceOrderViewActivated",e[e.UserShortcutAdded=44]="UserShortcutAdded",e[e.ShortcutRemoved=45]="ShortcutRemoved",e[e.ShortcutModified=46]="ShortcutModified",e[e.CustomPropertyLinkClicked=47]="CustomPropertyLinkClicked",e[e.CustomPropertyEdited=48]="CustomPropertyEdited",e[e.ServiceWorkerNetworkRequestClicked=49]="ServiceWorkerNetworkRequestClicked",e[e.ServiceWorkerNetworkRequestClosedQuickly=50]="ServiceWorkerNetworkRequestClosedQuickly",e[e.NetworkPanelServiceWorkerRespondWith=51]="NetworkPanelServiceWorkerRespondWith",e[e.NetworkPanelCopyValue=52]="NetworkPanelCopyValue",e[e.ConsoleSidebarOpened=53]="ConsoleSidebarOpened",e[e.PerfPanelTraceImported=54]="PerfPanelTraceImported",e[e.PerfPanelTraceExported=55]="PerfPanelTraceExported",e[e.StackFrameRestarted=56]="StackFrameRestarted",e[e.CaptureTestProtocolClicked=57]="CaptureTestProtocolClicked",e[e.BreakpointRemovedFromRemoveButton=58]="BreakpointRemovedFromRemoveButton",e[e.BreakpointGroupExpandedStateChanged=59]="BreakpointGroupExpandedStateChanged",e[e.HeaderOverrideFileCreated=60]="HeaderOverrideFileCreated",e[e.HeaderOverrideEnableEditingClicked=61]="HeaderOverrideEnableEditingClicked",e[e.HeaderOverrideHeaderAdded=62]="HeaderOverrideHeaderAdded",e[e.HeaderOverrideHeaderEdited=63]="HeaderOverrideHeaderEdited",e[e.HeaderOverrideHeaderRemoved=64]="HeaderOverrideHeaderRemoved",e[e.HeaderOverrideHeadersFileEdited=65]="HeaderOverrideHeadersFileEdited",e[e.PersistenceNetworkOverridesEnabled=66]="PersistenceNetworkOverridesEnabled",e[e.PersistenceNetworkOverridesDisabled=67]="PersistenceNetworkOverridesDisabled",e[e.BreakpointRemovedFromContextMenu=68]="BreakpointRemovedFromContextMenu",e[e.BreakpointsInFileRemovedFromRemoveButton=69]="BreakpointsInFileRemovedFromRemoveButton",e[e.BreakpointsInFileRemovedFromContextMenu=70]="BreakpointsInFileRemovedFromContextMenu",e[e.BreakpointsInFileCheckboxToggled=71]="BreakpointsInFileCheckboxToggled",e[e.BreakpointsInFileEnabledDisabledFromContextMenu=72]="BreakpointsInFileEnabledDisabledFromContextMenu",e[e.BreakpointConditionEditedFromSidebar=73]="BreakpointConditionEditedFromSidebar",e[e.WorkspaceTabAddFolder=74]="WorkspaceTabAddFolder",e[e.WorkspaceTabRemoveFolder=75]="WorkspaceTabRemoveFolder",e[e.OverrideTabAddFolder=76]="OverrideTabAddFolder",e[e.OverrideTabRemoveFolder=77]="OverrideTabRemoveFolder",e[e.WorkspaceSourceSelected=78]="WorkspaceSourceSelected",e[e.OverridesSourceSelected=79]="OverridesSourceSelected",e[e.StyleSheetInitiatorLinkClicked=80]="StyleSheetInitiatorLinkClicked",e[e.BreakpointRemovedFromGutterContextMenu=81]="BreakpointRemovedFromGutterContextMenu",e[e.BreakpointRemovedFromGutterToggle=82]="BreakpointRemovedFromGutterToggle",e[e.StylePropertyInsideKeyframeEdited=83]="StylePropertyInsideKeyframeEdited",e[e.OverrideContentFromSourcesContextMenu=84]="OverrideContentFromSourcesContextMenu",e[e.OverrideContentFromNetworkContextMenu=85]="OverrideContentFromNetworkContextMenu",e[e.OverrideScript=86]="OverrideScript",e[e.OverrideStyleSheet=87]="OverrideStyleSheet",e[e.OverrideDocument=88]="OverrideDocument",e[e.OverrideFetchXHR=89]="OverrideFetchXHR",e[e.OverrideImage=90]="OverrideImage",e[e.OverrideFont=91]="OverrideFont",e[e.OverrideContentContextMenuSetup=92]="OverrideContentContextMenuSetup",e[e.OverrideContentContextMenuAbandonSetup=93]="OverrideContentContextMenuAbandonSetup",e[e.OverrideContentContextMenuActivateDisabled=94]="OverrideContentContextMenuActivateDisabled",e[e.OverrideContentContextMenuOpenExistingFile=95]="OverrideContentContextMenuOpenExistingFile",e[e.OverrideContentContextMenuSaveNewFile=96]="OverrideContentContextMenuSaveNewFile",e[e.ShowAllOverridesFromSourcesContextMenu=97]="ShowAllOverridesFromSourcesContextMenu",e[e.ShowAllOverridesFromNetworkContextMenu=98]="ShowAllOverridesFromNetworkContextMenu",e[e.AnimationGroupsCleared=99]="AnimationGroupsCleared",e[e.AnimationsPaused=100]="AnimationsPaused",e[e.AnimationsResumed=101]="AnimationsResumed",e[e.AnimatedNodeDescriptionClicked=102]="AnimatedNodeDescriptionClicked",e[e.AnimationGroupScrubbed=103]="AnimationGroupScrubbed",e[e.AnimationGroupReplayed=104]="AnimationGroupReplayed",e[e.OverrideTabDeleteFolderContextMenu=105]="OverrideTabDeleteFolderContextMenu",e[e.WorkspaceDropFolder=107]="WorkspaceDropFolder",e[e.WorkspaceSelectFolder=108]="WorkspaceSelectFolder",e[e.OverrideContentContextMenuSourceMappedWarning=109]="OverrideContentContextMenuSourceMappedWarning",e[e.OverrideContentContextMenuRedirectToDeployed=110]="OverrideContentContextMenuRedirectToDeployed",e[e.NewStyleRuleAdded=111]="NewStyleRuleAdded",e[e.TraceExpanded=112]="TraceExpanded",e[e.InsightConsoleMessageShown=113]="InsightConsoleMessageShown",e[e.InsightRequestedViaContextMenu=114]="InsightRequestedViaContextMenu",e[e.InsightRequestedViaHoverButton=115]="InsightRequestedViaHoverButton",e[e.InsightRatedPositive=117]="InsightRatedPositive",e[e.InsightRatedNegative=118]="InsightRatedNegative",e[e.InsightClosed=119]="InsightClosed",e[e.InsightErrored=120]="InsightErrored",e[e.InsightHoverButtonShown=121]="InsightHoverButtonShown",e[e.SelfXssWarningConsoleMessageShown=122]="SelfXssWarningConsoleMessageShown",e[e.SelfXssWarningDialogShown=123]="SelfXssWarningDialogShown",e[e.SelfXssAllowPastingInConsole=124]="SelfXssAllowPastingInConsole",e[e.SelfXssAllowPastingInDialog=125]="SelfXssAllowPastingInDialog",e[e.ToggleEmulateFocusedPageFromStylesPaneOn=126]="ToggleEmulateFocusedPageFromStylesPaneOn",e[e.ToggleEmulateFocusedPageFromStylesPaneOff=127]="ToggleEmulateFocusedPageFromStylesPaneOff",e[e.ToggleEmulateFocusedPageFromRenderingTab=128]="ToggleEmulateFocusedPageFromRenderingTab",e[e.ToggleEmulateFocusedPageFromCommandMenu=129]="ToggleEmulateFocusedPageFromCommandMenu",e[e.InsightGenerated=130]="InsightGenerated",e[e.InsightErroredApi=131]="InsightErroredApi",e[e.InsightErroredMarkdown=132]="InsightErroredMarkdown",e[e.ToggleShowWebVitals=133]="ToggleShowWebVitals",e[e.InsightErroredPermissionDenied=134]="InsightErroredPermissionDenied",e[e.InsightErroredCannotSend=135]="InsightErroredCannotSend",e[e.InsightErroredRequestFailed=136]="InsightErroredRequestFailed",e[e.InsightErroredCannotParseChunk=137]="InsightErroredCannotParseChunk",e[e.InsightErroredUnknownChunk=138]="InsightErroredUnknownChunk",e[e.InsightErroredOther=139]="InsightErroredOther",e[e.MaxValue=140]="MaxValue"}(V||(V={})),function(e){e[e.elements=1]="elements",e[e.resources=2]="resources",e[e.network=3]="network",e[e.sources=4]="sources",e[e.timeline=5]="timeline",e[e["heap-profiler"]=6]="heap-profiler",e[e.console=8]="console",e[e.layers=9]="layers",e[e["console-view"]=10]="console-view",e[e.animations=11]="animations",e[e["network.config"]=12]="network.config",e[e.rendering=13]="rendering",e[e.sensors=14]="sensors",e[e["sources.search"]=15]="sources.search",e[e.security=16]="security",e[e["js-profiler"]=17]="js-profiler",e[e.lighthouse=18]="lighthouse",e[e.coverage=19]="coverage",e[e["protocol-monitor"]=20]="protocol-monitor",e[e["remote-devices"]=21]="remote-devices",e[e["web-audio"]=22]="web-audio",e[e["changes.changes"]=23]="changes.changes",e[e["performance.monitor"]=24]="performance.monitor",e[e["release-note"]=25]="release-note",e[e["live-heap-profile"]=26]="live-heap-profile",e[e["sources.quick"]=27]="sources.quick",e[e["network.blocked-urls"]=28]="network.blocked-urls",e[e["settings-preferences"]=29]="settings-preferences",e[e["settings-workspace"]=30]="settings-workspace",e[e["settings-experiments"]=31]="settings-experiments",e[e["settings-blackbox"]=32]="settings-blackbox",e[e["settings-devices"]=33]="settings-devices",e[e["settings-throttling-conditions"]=34]="settings-throttling-conditions",e[e["settings-emulation-locations"]=35]="settings-emulation-locations",e[e["settings-shortcuts"]=36]="settings-shortcuts",e[e["issues-pane"]=37]="issues-pane",e[e["settings-keybinds"]=38]="settings-keybinds",e[e.cssoverview=39]="cssoverview",e[e["chrome-recorder"]=40]="chrome-recorder",e[e["trust-tokens"]=41]="trust-tokens",e[e["reporting-api"]=42]="reporting-api",e[e["interest-groups"]=43]="interest-groups",e[e["back-forward-cache"]=44]="back-forward-cache",e[e["service-worker-cache"]=45]="service-worker-cache",e[e["background-service-background-fetch"]=46]="background-service-background-fetch",e[e["background-service-background-sync"]=47]="background-service-background-sync",e[e["background-service-push-messaging"]=48]="background-service-push-messaging",e[e["background-service-notifications"]=49]="background-service-notifications",e[e["background-service-payment-handler"]=50]="background-service-payment-handler",e[e["background-service-periodic-background-sync"]=51]="background-service-periodic-background-sync",e[e["service-workers"]=52]="service-workers",e[e["app-manifest"]=53]="app-manifest",e[e.storage=54]="storage",e[e.cookies=55]="cookies",e[e["frame-details"]=56]="frame-details",e[e["frame-resource"]=57]="frame-resource",e[e["frame-window"]=58]="frame-window",e[e["frame-worker"]=59]="frame-worker",e[e["dom-storage"]=60]="dom-storage",e[e["indexed-db"]=61]="indexed-db",e[e["web-sql"]=62]="web-sql",e[e["performance-insights"]=63]="performance-insights",e[e.preloading=64]="preloading",e[e["bounce-tracking-mitigations"]=65]="bounce-tracking-mitigations",e[e["developer-resources"]=66]="developer-resources",e[e["autofill-view"]=67]="autofill-view",e[e.MaxValue=68]="MaxValue"}(B||(B={})),function(e){e[e["elements-main"]=1]="elements-main",e[e["elements-drawer"]=2]="elements-drawer",e[e["resources-main"]=3]="resources-main",e[e["resources-drawer"]=4]="resources-drawer",e[e["network-main"]=5]="network-main",e[e["network-drawer"]=6]="network-drawer",e[e["sources-main"]=7]="sources-main",e[e["sources-drawer"]=8]="sources-drawer",e[e["timeline-main"]=9]="timeline-main",e[e["timeline-drawer"]=10]="timeline-drawer",e[e["heap_profiler-main"]=11]="heap_profiler-main",e[e["heap_profiler-drawer"]=12]="heap_profiler-drawer",e[e["console-main"]=13]="console-main",e[e["console-drawer"]=14]="console-drawer",e[e["layers-main"]=15]="layers-main",e[e["layers-drawer"]=16]="layers-drawer",e[e["console-view-main"]=17]="console-view-main",e[e["console-view-drawer"]=18]="console-view-drawer",e[e["animations-main"]=19]="animations-main",e[e["animations-drawer"]=20]="animations-drawer",e[e["network.config-main"]=21]="network.config-main",e[e["network.config-drawer"]=22]="network.config-drawer",e[e["rendering-main"]=23]="rendering-main",e[e["rendering-drawer"]=24]="rendering-drawer",e[e["sensors-main"]=25]="sensors-main",e[e["sensors-drawer"]=26]="sensors-drawer",e[e["sources.search-main"]=27]="sources.search-main",e[e["sources.search-drawer"]=28]="sources.search-drawer",e[e["security-main"]=29]="security-main",e[e["security-drawer"]=30]="security-drawer",e[e["js_profiler-main"]=31]="js_profiler-main",e[e["js_profiler-drawer"]=32]="js_profiler-drawer",e[e["lighthouse-main"]=33]="lighthouse-main",e[e["lighthouse-drawer"]=34]="lighthouse-drawer",e[e["coverage-main"]=35]="coverage-main",e[e["coverage-drawer"]=36]="coverage-drawer",e[e["protocol-monitor-main"]=37]="protocol-monitor-main",e[e["protocol-monitor-drawer"]=38]="protocol-monitor-drawer",e[e["remote-devices-main"]=39]="remote-devices-main",e[e["remote-devices-drawer"]=40]="remote-devices-drawer",e[e["web-audio-main"]=41]="web-audio-main",e[e["web-audio-drawer"]=42]="web-audio-drawer",e[e["changes.changes-main"]=43]="changes.changes-main",e[e["changes.changes-drawer"]=44]="changes.changes-drawer",e[e["performance.monitor-main"]=45]="performance.monitor-main",e[e["performance.monitor-drawer"]=46]="performance.monitor-drawer",e[e["release-note-main"]=47]="release-note-main",e[e["release-note-drawer"]=48]="release-note-drawer",e[e["live_heap_profile-main"]=49]="live_heap_profile-main",e[e["live_heap_profile-drawer"]=50]="live_heap_profile-drawer",e[e["sources.quick-main"]=51]="sources.quick-main",e[e["sources.quick-drawer"]=52]="sources.quick-drawer",e[e["network.blocked-urls-main"]=53]="network.blocked-urls-main",e[e["network.blocked-urls-drawer"]=54]="network.blocked-urls-drawer",e[e["settings-preferences-main"]=55]="settings-preferences-main",e[e["settings-preferences-drawer"]=56]="settings-preferences-drawer",e[e["settings-workspace-main"]=57]="settings-workspace-main",e[e["settings-workspace-drawer"]=58]="settings-workspace-drawer",e[e["settings-experiments-main"]=59]="settings-experiments-main",e[e["settings-experiments-drawer"]=60]="settings-experiments-drawer",e[e["settings-blackbox-main"]=61]="settings-blackbox-main",e[e["settings-blackbox-drawer"]=62]="settings-blackbox-drawer",e[e["settings-devices-main"]=63]="settings-devices-main",e[e["settings-devices-drawer"]=64]="settings-devices-drawer",e[e["settings-throttling-conditions-main"]=65]="settings-throttling-conditions-main",e[e["settings-throttling-conditions-drawer"]=66]="settings-throttling-conditions-drawer",e[e["settings-emulation-locations-main"]=67]="settings-emulation-locations-main",e[e["settings-emulation-locations-drawer"]=68]="settings-emulation-locations-drawer",e[e["settings-shortcuts-main"]=69]="settings-shortcuts-main",e[e["settings-shortcuts-drawer"]=70]="settings-shortcuts-drawer",e[e["issues-pane-main"]=71]="issues-pane-main",e[e["issues-pane-drawer"]=72]="issues-pane-drawer",e[e["settings-keybinds-main"]=73]="settings-keybinds-main",e[e["settings-keybinds-drawer"]=74]="settings-keybinds-drawer",e[e["cssoverview-main"]=75]="cssoverview-main",e[e["cssoverview-drawer"]=76]="cssoverview-drawer",e[e["chrome_recorder-main"]=77]="chrome_recorder-main",e[e["chrome_recorder-drawer"]=78]="chrome_recorder-drawer",e[e["trust_tokens-main"]=79]="trust_tokens-main",e[e["trust_tokens-drawer"]=80]="trust_tokens-drawer",e[e["reporting_api-main"]=81]="reporting_api-main",e[e["reporting_api-drawer"]=82]="reporting_api-drawer",e[e["interest_groups-main"]=83]="interest_groups-main",e[e["interest_groups-drawer"]=84]="interest_groups-drawer",e[e["back_forward_cache-main"]=85]="back_forward_cache-main",e[e["back_forward_cache-drawer"]=86]="back_forward_cache-drawer",e[e["service_worker_cache-main"]=87]="service_worker_cache-main",e[e["service_worker_cache-drawer"]=88]="service_worker_cache-drawer",e[e["background_service_backgroundFetch-main"]=89]="background_service_backgroundFetch-main",e[e["background_service_backgroundFetch-drawer"]=90]="background_service_backgroundFetch-drawer",e[e["background_service_backgroundSync-main"]=91]="background_service_backgroundSync-main",e[e["background_service_backgroundSync-drawer"]=92]="background_service_backgroundSync-drawer",e[e["background_service_pushMessaging-main"]=93]="background_service_pushMessaging-main",e[e["background_service_pushMessaging-drawer"]=94]="background_service_pushMessaging-drawer",e[e["background_service_notifications-main"]=95]="background_service_notifications-main",e[e["background_service_notifications-drawer"]=96]="background_service_notifications-drawer",e[e["background_service_paymentHandler-main"]=97]="background_service_paymentHandler-main",e[e["background_service_paymentHandler-drawer"]=98]="background_service_paymentHandler-drawer",e[e["background_service_periodicBackgroundSync-main"]=99]="background_service_periodicBackgroundSync-main",e[e["background_service_periodicBackgroundSync-drawer"]=100]="background_service_periodicBackgroundSync-drawer",e[e["service_workers-main"]=101]="service_workers-main",e[e["service_workers-drawer"]=102]="service_workers-drawer",e[e["app_manifest-main"]=103]="app_manifest-main",e[e["app_manifest-drawer"]=104]="app_manifest-drawer",e[e["storage-main"]=105]="storage-main",e[e["storage-drawer"]=106]="storage-drawer",e[e["cookies-main"]=107]="cookies-main",e[e["cookies-drawer"]=108]="cookies-drawer",e[e["frame_details-main"]=109]="frame_details-main",e[e["frame_details-drawer"]=110]="frame_details-drawer",e[e["frame_resource-main"]=111]="frame_resource-main",e[e["frame_resource-drawer"]=112]="frame_resource-drawer",e[e["frame_window-main"]=113]="frame_window-main",e[e["frame_window-drawer"]=114]="frame_window-drawer",e[e["frame_worker-main"]=115]="frame_worker-main",e[e["frame_worker-drawer"]=116]="frame_worker-drawer",e[e["dom_storage-main"]=117]="dom_storage-main",e[e["dom_storage-drawer"]=118]="dom_storage-drawer",e[e["indexed_db-main"]=119]="indexed_db-main",e[e["indexed_db-drawer"]=120]="indexed_db-drawer",e[e["web_sql-main"]=121]="web_sql-main",e[e["web_sql-drawer"]=122]="web_sql-drawer",e[e["performance_insights-main"]=123]="performance_insights-main",e[e["performance_insights-drawer"]=124]="performance_insights-drawer",e[e["preloading-main"]=125]="preloading-main",e[e["preloading-drawer"]=126]="preloading-drawer",e[e["bounce_tracking_mitigations-main"]=127]="bounce_tracking_mitigations-main",e[e["bounce_tracking_mitigations-drawer"]=128]="bounce_tracking_mitigations-drawer",e[e["developer-resources-main"]=129]="developer-resources-main",e[e["developer-resources-drawer"]=130]="developer-resources-drawer",e[e["autofill-view-main"]=131]="autofill-view-main",e[e["autofill-view-drawer"]=132]="autofill-view-drawer",e[e.MaxValue=133]="MaxValue"}(j||(j={})),function(e){e[e.OtherSidebarPane=0]="OtherSidebarPane",e[e.styles=1]="styles",e[e.computed=2]="computed",e[e["elements.layout"]=3]="elements.layout",e[e["elements.event-listeners"]=4]="elements.event-listeners",e[e["elements.dom-breakpoints"]=5]="elements.dom-breakpoints",e[e["elements.dom-properties"]=6]="elements.dom-properties",e[e["accessibility.view"]=7]="accessibility.view",e[e.MaxValue=8]="MaxValue"}(q||(q={})),function(e){e[e.OtherSidebarPane=0]="OtherSidebarPane",e[e["navigator-network"]=1]="navigator-network",e[e["navigator-files"]=2]="navigator-files",e[e["navigator-overrides"]=3]="navigator-overrides",e[e["navigator-content-scripts"]=4]="navigator-content-scripts",e[e["navigator-snippets"]=5]="navigator-snippets",e[e.MaxValue=6]="MaxValue"}(G||(G={})),function(e){e[e.Unknown=0]="Unknown",e[e["text/css"]=2]="text/css",e[e["text/html"]=3]="text/html",e[e["application/xml"]=4]="application/xml",e[e["application/wasm"]=5]="application/wasm",e[e["application/manifest+json"]=6]="application/manifest+json",e[e["application/x-aspx"]=7]="application/x-aspx",e[e["application/jsp"]=8]="application/jsp",e[e["text/x-c++src"]=9]="text/x-c++src",e[e["text/x-coffeescript"]=10]="text/x-coffeescript",e[e["application/vnd.dart"]=11]="application/vnd.dart",e[e["text/typescript"]=12]="text/typescript",e[e["text/typescript-jsx"]=13]="text/typescript-jsx",e[e["application/json"]=14]="application/json",e[e["text/x-csharp"]=15]="text/x-csharp",e[e["text/x-java"]=16]="text/x-java",e[e["text/x-less"]=17]="text/x-less",e[e["application/x-httpd-php"]=18]="application/x-httpd-php",e[e["text/x-python"]=19]="text/x-python",e[e["text/x-sh"]=20]="text/x-sh",e[e["text/x-gss"]=21]="text/x-gss",e[e["text/x-sass"]=22]="text/x-sass",e[e["text/x-scss"]=23]="text/x-scss",e[e["text/markdown"]=24]="text/markdown",e[e["text/x-clojure"]=25]="text/x-clojure",e[e["text/jsx"]=26]="text/jsx",e[e["text/x-go"]=27]="text/x-go",e[e["text/x-kotlin"]=28]="text/x-kotlin",e[e["text/x-scala"]=29]="text/x-scala",e[e["text/x.svelte"]=30]="text/x.svelte",e[e["text/javascript+plain"]=31]="text/javascript+plain",e[e["text/javascript+minified"]=32]="text/javascript+minified",e[e["text/javascript+sourcemapped"]=33]="text/javascript+sourcemapped",e[e["text/x.angular"]=34]="text/x.angular",e[e["text/x.vue"]=35]="text/x.vue",e[e.MaxValue=36]="MaxValue"}(z||(z={})),function(e){e[e.devToolsDefault=0]="devToolsDefault",e[e.vsCode=1]="vsCode",e[e.MaxValue=2]="MaxValue"}($||($={})),function(e){e[e.OtherShortcut=0]="OtherShortcut",e[e["quick-open.show-command-menu"]=1]="quick-open.show-command-menu",e[e["console.clear"]=2]="console.clear",e[e["console.toggle"]=3]="console.toggle",e[e["debugger.step"]=4]="debugger.step",e[e["debugger.step-into"]=5]="debugger.step-into",e[e["debugger.step-out"]=6]="debugger.step-out",e[e["debugger.step-over"]=7]="debugger.step-over",e[e["debugger.toggle-breakpoint"]=8]="debugger.toggle-breakpoint",e[e["debugger.toggle-breakpoint-enabled"]=9]="debugger.toggle-breakpoint-enabled",e[e["debugger.toggle-pause"]=10]="debugger.toggle-pause",e[e["elements.edit-as-html"]=11]="elements.edit-as-html",e[e["elements.hide-element"]=12]="elements.hide-element",e[e["elements.redo"]=13]="elements.redo",e[e["elements.toggle-element-search"]=14]="elements.toggle-element-search",e[e["elements.undo"]=15]="elements.undo",e[e["main.search-in-panel.find"]=16]="main.search-in-panel.find",e[e["main.toggle-drawer"]=17]="main.toggle-drawer",e[e["network.hide-request-details"]=18]="network.hide-request-details",e[e["network.search"]=19]="network.search",e[e["network.toggle-recording"]=20]="network.toggle-recording",e[e["quick-open.show"]=21]="quick-open.show",e[e["settings.show"]=22]="settings.show",e[e["sources.search"]=23]="sources.search",e[e["background-service.toggle-recording"]=24]="background-service.toggle-recording",e[e["components.collect-garbage"]=25]="components.collect-garbage",e[e["console.clear.history"]=26]="console.clear.history",e[e["console.create-pin"]=27]="console.create-pin",e[e["coverage.start-with-reload"]=28]="coverage.start-with-reload",e[e["coverage.toggle-recording"]=29]="coverage.toggle-recording",e[e["debugger.breakpoint-input-window"]=30]="debugger.breakpoint-input-window",e[e["debugger.evaluate-selection"]=31]="debugger.evaluate-selection",e[e["debugger.next-call-frame"]=32]="debugger.next-call-frame",e[e["debugger.previous-call-frame"]=33]="debugger.previous-call-frame",e[e["debugger.run-snippet"]=34]="debugger.run-snippet",e[e["debugger.toggle-breakpoints-active"]=35]="debugger.toggle-breakpoints-active",e[e["elements.capture-area-screenshot"]=36]="elements.capture-area-screenshot",e[e["emulation.capture-full-height-screenshot"]=37]="emulation.capture-full-height-screenshot",e[e["emulation.capture-node-screenshot"]=38]="emulation.capture-node-screenshot",e[e["emulation.capture-screenshot"]=39]="emulation.capture-screenshot",e[e["emulation.show-sensors"]=40]="emulation.show-sensors",e[e["emulation.toggle-device-mode"]=41]="emulation.toggle-device-mode",e[e["help.release-notes"]=42]="help.release-notes",e[e["help.report-issue"]=43]="help.report-issue",e[e["input.start-replaying"]=44]="input.start-replaying",e[e["input.toggle-pause"]=45]="input.toggle-pause",e[e["input.toggle-recording"]=46]="input.toggle-recording",e[e["inspector-main.focus-debuggee"]=47]="inspector-main.focus-debuggee",e[e["inspector-main.hard-reload"]=48]="inspector-main.hard-reload",e[e["inspector-main.reload"]=49]="inspector-main.reload",e[e["live-heap-profile.start-with-reload"]=50]="live-heap-profile.start-with-reload",e[e["live-heap-profile.toggle-recording"]=51]="live-heap-profile.toggle-recording",e[e["main.debug-reload"]=52]="main.debug-reload",e[e["main.next-tab"]=53]="main.next-tab",e[e["main.previous-tab"]=54]="main.previous-tab",e[e["main.search-in-panel.cancel"]=55]="main.search-in-panel.cancel",e[e["main.search-in-panel.find-next"]=56]="main.search-in-panel.find-next",e[e["main.search-in-panel.find-previous"]=57]="main.search-in-panel.find-previous",e[e["main.toggle-dock"]=58]="main.toggle-dock",e[e["main.zoom-in"]=59]="main.zoom-in",e[e["main.zoom-out"]=60]="main.zoom-out",e[e["main.zoom-reset"]=61]="main.zoom-reset",e[e["network-conditions.network-low-end-mobile"]=62]="network-conditions.network-low-end-mobile",e[e["network-conditions.network-mid-tier-mobile"]=63]="network-conditions.network-mid-tier-mobile",e[e["network-conditions.network-offline"]=64]="network-conditions.network-offline",e[e["network-conditions.network-online"]=65]="network-conditions.network-online",e[e["profiler.heap-toggle-recording"]=66]="profiler.heap-toggle-recording",e[e["profiler.js-toggle-recording"]=67]="profiler.js-toggle-recording",e[e["resources.clear"]=68]="resources.clear",e[e["settings.documentation"]=69]="settings.documentation",e[e["settings.shortcuts"]=70]="settings.shortcuts",e[e["sources.add-folder-to-workspace"]=71]="sources.add-folder-to-workspace",e[e["sources.add-to-watch"]=72]="sources.add-to-watch",e[e["sources.close-all"]=73]="sources.close-all",e[e["sources.close-editor-tab"]=74]="sources.close-editor-tab",e[e["sources.create-snippet"]=75]="sources.create-snippet",e[e["sources.go-to-line"]=76]="sources.go-to-line",e[e["sources.go-to-member"]=77]="sources.go-to-member",e[e["sources.jump-to-next-location"]=78]="sources.jump-to-next-location",e[e["sources.jump-to-previous-location"]=79]="sources.jump-to-previous-location",e[e["sources.rename"]=80]="sources.rename",e[e["sources.save"]=81]="sources.save",e[e["sources.save-all"]=82]="sources.save-all",e[e["sources.switch-file"]=83]="sources.switch-file",e[e["timeline.jump-to-next-frame"]=84]="timeline.jump-to-next-frame",e[e["timeline.jump-to-previous-frame"]=85]="timeline.jump-to-previous-frame",e[e["timeline.load-from-file"]=86]="timeline.load-from-file",e[e["timeline.next-recording"]=87]="timeline.next-recording",e[e["timeline.previous-recording"]=88]="timeline.previous-recording",e[e["timeline.record-reload"]=89]="timeline.record-reload",e[e["timeline.save-to-file"]=90]="timeline.save-to-file",e[e["timeline.show-history"]=91]="timeline.show-history",e[e["timeline.toggle-recording"]=92]="timeline.toggle-recording",e[e["sources.increment-css"]=93]="sources.increment-css",e[e["sources.increment-css-by-ten"]=94]="sources.increment-css-by-ten",e[e["sources.decrement-css"]=95]="sources.decrement-css",e[e["sources.decrement-css-by-ten"]=96]="sources.decrement-css-by-ten",e[e["layers.reset-view"]=97]="layers.reset-view",e[e["layers.pan-mode"]=98]="layers.pan-mode",e[e["layers.rotate-mode"]=99]="layers.rotate-mode",e[e["layers.zoom-in"]=100]="layers.zoom-in",e[e["layers.zoom-out"]=101]="layers.zoom-out",e[e["layers.up"]=102]="layers.up",e[e["layers.down"]=103]="layers.down",e[e["layers.left"]=104]="layers.left",e[e["layers.right"]=105]="layers.right",e[e["help.report-translation-issue"]=106]="help.report-translation-issue",e[e["rendering.toggle-prefers-color-scheme"]=107]="rendering.toggle-prefers-color-scheme",e[e["chrome-recorder.start-recording"]=108]="chrome-recorder.start-recording",e[e["chrome-recorder.replay-recording"]=109]="chrome-recorder.replay-recording",e[e["chrome-recorder.toggle-code-view"]=110]="chrome-recorder.toggle-code-view",e[e["chrome-recorder.copy-recording-or-step"]=111]="chrome-recorder.copy-recording-or-step",e[e["changes.revert"]=112]="changes.revert",e[e["changes.copy"]=113]="changes.copy",e[e["elements.new-style-rule"]=114]="elements.new-style-rule",e[e["elements.refresh-event-listeners"]=115]="elements.refresh-event-listeners",e[e["coverage.clear"]=116]="coverage.clear",e[e["coverage.export"]=117]="coverage.export",e[e.MaxValue=118]="MaxValue"}(X||(X={})),function(e){e[e["apply-custom-stylesheet"]=0]="apply-custom-stylesheet",e[e["capture-node-creation-stacks"]=1]="capture-node-creation-stacks",e[e["live-heap-profile"]=11]="live-heap-profile",e[e["protocol-monitor"]=13]="protocol-monitor",e[e["sampling-heap-profiler-timeline"]=17]="sampling-heap-profiler-timeline",e[e["show-option-tp-expose-internals-in-heap-snapshot"]=18]="show-option-tp-expose-internals-in-heap-snapshot",e[e["timeline-invalidation-tracking"]=26]="timeline-invalidation-tracking",e[e["timeline-show-all-events"]=27]="timeline-show-all-events",e[e["timeline-v8-runtime-call-stats"]=28]="timeline-v8-runtime-call-stats",e[e.apca=39]="apca",e[e["font-editor"]=41]="font-editor",e[e["full-accessibility-tree"]=42]="full-accessibility-tree",e[e["ignore-list-js-frames-on-timeline"]=43]="ignore-list-js-frames-on-timeline",e[e["contrast-issues"]=44]="contrast-issues",e[e["experimental-cookie-features"]=45]="experimental-cookie-features",e[e["styles-pane-css-changes"]=55]="styles-pane-css-changes",e[e["evaluate-expressions-with-source-maps"]=58]="evaluate-expressions-with-source-maps",e[e["instrumentation-breakpoints"]=61]="instrumentation-breakpoints",e[e["authored-deployed-grouping"]=63]="authored-deployed-grouping",e[e["important-dom-properties"]=64]="important-dom-properties",e[e["just-my-code"]=65]="just-my-code",e[e["timeline-as-console-profile-result-panel"]=67]="timeline-as-console-profile-result-panel",e[e["preloading-status-panel"]=68]="preloading-status-panel",e[e["outermost-target-selector"]=71]="outermost-target-selector",e[e["js-profiler-temporarily-enable"]=72]="js-profiler-temporarily-enable",e[e["highlight-errors-elements-panel"]=73]="highlight-errors-elements-panel",e[e["set-all-breakpoints-eagerly"]=74]="set-all-breakpoints-eagerly",e[e["self-xss-warning"]=75]="self-xss-warning",e[e["use-source-map-scopes"]=76]="use-source-map-scopes",e[e["storage-buckets-tree"]=77]="storage-buckets-tree",e[e["network-panel-filter-bar-redesign"]=79]="network-panel-filter-bar-redesign",e[e["track-context-menu"]=81]="track-context-menu",e[e["autofill-view"]=82]="autofill-view",e[e["sources-frame-indentation-markers-temporarily-disable"]=83]="sources-frame-indentation-markers-temporarily-disable",e[e["heap-snapshot-treat-backing-store-as-containing-object"]=84]="heap-snapshot-treat-backing-store-as-containing-object",e[e["css-type-component-length-deprecate"]=85]="css-type-component-length-deprecate",e[e.MaxValue=86]="MaxValue"}(K||(K={})),function(e){e[e.CrossOriginEmbedderPolicy=0]="CrossOriginEmbedderPolicy",e[e.MixedContent=1]="MixedContent",e[e.SameSiteCookie=2]="SameSiteCookie",e[e.HeavyAd=3]="HeavyAd",e[e.ContentSecurityPolicy=4]="ContentSecurityPolicy",e[e.Other=5]="Other",e[e.Generic=6]="Generic",e[e.ThirdPartyPhaseoutCookie=7]="ThirdPartyPhaseoutCookie",e[e.GenericCookie=8]="GenericCookie",e[e.MaxValue=9]="MaxValue"}(Q||(Q={})),function(e){e[e.CrossOriginEmbedderPolicyRequest=0]="CrossOriginEmbedderPolicyRequest",e[e.CrossOriginEmbedderPolicyElement=1]="CrossOriginEmbedderPolicyElement",e[e.MixedContentRequest=2]="MixedContentRequest",e[e.SameSiteCookieCookie=3]="SameSiteCookieCookie",e[e.SameSiteCookieRequest=4]="SameSiteCookieRequest",e[e.HeavyAdElement=5]="HeavyAdElement",e[e.ContentSecurityPolicyDirective=6]="ContentSecurityPolicyDirective",e[e.ContentSecurityPolicyElement=7]="ContentSecurityPolicyElement",e[e.MaxValue=13]="MaxValue"}(J||(J={})),function(e){e[e.MixedContentIssue=0]="MixedContentIssue",e[e["ContentSecurityPolicyIssue::kInlineViolation"]=1]="ContentSecurityPolicyIssue::kInlineViolation",e[e["ContentSecurityPolicyIssue::kEvalViolation"]=2]="ContentSecurityPolicyIssue::kEvalViolation",e[e["ContentSecurityPolicyIssue::kURLViolation"]=3]="ContentSecurityPolicyIssue::kURLViolation",e[e["ContentSecurityPolicyIssue::kTrustedTypesSinkViolation"]=4]="ContentSecurityPolicyIssue::kTrustedTypesSinkViolation",e[e["ContentSecurityPolicyIssue::kTrustedTypesPolicyViolation"]=5]="ContentSecurityPolicyIssue::kTrustedTypesPolicyViolation",e[e["HeavyAdIssue::NetworkTotalLimit"]=6]="HeavyAdIssue::NetworkTotalLimit",e[e["HeavyAdIssue::CpuTotalLimit"]=7]="HeavyAdIssue::CpuTotalLimit",e[e["HeavyAdIssue::CpuPeakLimit"]=8]="HeavyAdIssue::CpuPeakLimit",e[e["CrossOriginEmbedderPolicyIssue::CoepFrameResourceNeedsCoepHeader"]=9]="CrossOriginEmbedderPolicyIssue::CoepFrameResourceNeedsCoepHeader",e[e["CrossOriginEmbedderPolicyIssue::CoopSandboxedIFrameCannotNavigateToCoopPage"]=10]="CrossOriginEmbedderPolicyIssue::CoopSandboxedIFrameCannotNavigateToCoopPage",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameOrigin"]=11]="CrossOriginEmbedderPolicyIssue::CorpNotSameOrigin",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameOriginAfterDefaultedToSameOriginByCoep"]=12]="CrossOriginEmbedderPolicyIssue::CorpNotSameOriginAfterDefaultedToSameOriginByCoep",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameSite"]=13]="CrossOriginEmbedderPolicyIssue::CorpNotSameSite",e[e["CookieIssue::ExcludeSameSiteNoneInsecure::ReadCookie"]=14]="CookieIssue::ExcludeSameSiteNoneInsecure::ReadCookie",e[e["CookieIssue::ExcludeSameSiteNoneInsecure::SetCookie"]=15]="CookieIssue::ExcludeSameSiteNoneInsecure::SetCookie",e[e["CookieIssue::WarnSameSiteNoneInsecure::ReadCookie"]=16]="CookieIssue::WarnSameSiteNoneInsecure::ReadCookie",e[e["CookieIssue::WarnSameSiteNoneInsecure::SetCookie"]=17]="CookieIssue::WarnSameSiteNoneInsecure::SetCookie",e[e["CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Secure"]=18]="CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Secure",e[e["CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Insecure"]=19]="CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Insecure",e[e["CookieIssue::WarnCrossDowngrade::ReadCookie::Secure"]=20]="CookieIssue::WarnCrossDowngrade::ReadCookie::Secure",e[e["CookieIssue::WarnCrossDowngrade::ReadCookie::Insecure"]=21]="CookieIssue::WarnCrossDowngrade::ReadCookie::Insecure",e[e["CookieIssue::WarnCrossDowngrade::SetCookie::Secure"]=22]="CookieIssue::WarnCrossDowngrade::SetCookie::Secure",e[e["CookieIssue::WarnCrossDowngrade::SetCookie::Insecure"]=23]="CookieIssue::WarnCrossDowngrade::SetCookie::Insecure",e[e["CookieIssue::ExcludeNavigationContextDowngrade::Secure"]=24]="CookieIssue::ExcludeNavigationContextDowngrade::Secure",e[e["CookieIssue::ExcludeNavigationContextDowngrade::Insecure"]=25]="CookieIssue::ExcludeNavigationContextDowngrade::Insecure",e[e["CookieIssue::ExcludeContextDowngrade::ReadCookie::Secure"]=26]="CookieIssue::ExcludeContextDowngrade::ReadCookie::Secure",e[e["CookieIssue::ExcludeContextDowngrade::ReadCookie::Insecure"]=27]="CookieIssue::ExcludeContextDowngrade::ReadCookie::Insecure",e[e["CookieIssue::ExcludeContextDowngrade::SetCookie::Secure"]=28]="CookieIssue::ExcludeContextDowngrade::SetCookie::Secure",e[e["CookieIssue::ExcludeContextDowngrade::SetCookie::Insecure"]=29]="CookieIssue::ExcludeContextDowngrade::SetCookie::Insecure",e[e["CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::ReadCookie"]=30]="CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::ReadCookie",e[e["CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::SetCookie"]=31]="CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::SetCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::ReadCookie"]=32]="CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::ReadCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::SetCookie"]=33]="CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::SetCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::ReadCookie"]=34]="CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::ReadCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::SetCookie"]=35]="CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::SetCookie",e[e["SharedArrayBufferIssue::TransferIssue"]=36]="SharedArrayBufferIssue::TransferIssue",e[e["SharedArrayBufferIssue::CreationIssue"]=37]="SharedArrayBufferIssue::CreationIssue",e[e.LowTextContrastIssue=41]="LowTextContrastIssue",e[e["CorsIssue::InsecurePrivateNetwork"]=42]="CorsIssue::InsecurePrivateNetwork",e[e["CorsIssue::InvalidHeaders"]=44]="CorsIssue::InvalidHeaders",e[e["CorsIssue::WildcardOriginWithCredentials"]=45]="CorsIssue::WildcardOriginWithCredentials",e[e["CorsIssue::PreflightResponseInvalid"]=46]="CorsIssue::PreflightResponseInvalid",e[e["CorsIssue::OriginMismatch"]=47]="CorsIssue::OriginMismatch",e[e["CorsIssue::AllowCredentialsRequired"]=48]="CorsIssue::AllowCredentialsRequired",e[e["CorsIssue::MethodDisallowedByPreflightResponse"]=49]="CorsIssue::MethodDisallowedByPreflightResponse",e[e["CorsIssue::HeaderDisallowedByPreflightResponse"]=50]="CorsIssue::HeaderDisallowedByPreflightResponse",e[e["CorsIssue::RedirectContainsCredentials"]=51]="CorsIssue::RedirectContainsCredentials",e[e["CorsIssue::DisallowedByMode"]=52]="CorsIssue::DisallowedByMode",e[e["CorsIssue::CorsDisabledScheme"]=53]="CorsIssue::CorsDisabledScheme",e[e["CorsIssue::PreflightMissingAllowExternal"]=54]="CorsIssue::PreflightMissingAllowExternal",e[e["CorsIssue::PreflightInvalidAllowExternal"]=55]="CorsIssue::PreflightInvalidAllowExternal",e[e["CorsIssue::NoCorsRedirectModeNotFollow"]=57]="CorsIssue::NoCorsRedirectModeNotFollow",e[e["QuirksModeIssue::QuirksMode"]=58]="QuirksModeIssue::QuirksMode",e[e["QuirksModeIssue::LimitedQuirksMode"]=59]="QuirksModeIssue::LimitedQuirksMode",e[e.DeprecationIssue=60]="DeprecationIssue",e[e["ClientHintIssue::MetaTagAllowListInvalidOrigin"]=61]="ClientHintIssue::MetaTagAllowListInvalidOrigin",e[e["ClientHintIssue::MetaTagModifiedHTML"]=62]="ClientHintIssue::MetaTagModifiedHTML",e[e["CorsIssue::PreflightAllowPrivateNetworkError"]=63]="CorsIssue::PreflightAllowPrivateNetworkError",e[e["GenericIssue::CrossOriginPortalPostMessageError"]=64]="GenericIssue::CrossOriginPortalPostMessageError",e[e["GenericIssue::FormLabelForNameError"]=65]="GenericIssue::FormLabelForNameError",e[e["GenericIssue::FormDuplicateIdForInputError"]=66]="GenericIssue::FormDuplicateIdForInputError",e[e["GenericIssue::FormInputWithNoLabelError"]=67]="GenericIssue::FormInputWithNoLabelError",e[e["GenericIssue::FormAutocompleteAttributeEmptyError"]=68]="GenericIssue::FormAutocompleteAttributeEmptyError",e[e["GenericIssue::FormEmptyIdAndNameAttributesForInputError"]=69]="GenericIssue::FormEmptyIdAndNameAttributesForInputError",e[e["GenericIssue::FormAriaLabelledByToNonExistingId"]=70]="GenericIssue::FormAriaLabelledByToNonExistingId",e[e["GenericIssue::FormInputAssignedAutocompleteValueToIdOrNameAttributeError"]=71]="GenericIssue::FormInputAssignedAutocompleteValueToIdOrNameAttributeError",e[e["GenericIssue::FormLabelHasNeitherForNorNestedInput"]=72]="GenericIssue::FormLabelHasNeitherForNorNestedInput",e[e["GenericIssue::FormLabelForMatchesNonExistingIdError"]=73]="GenericIssue::FormLabelForMatchesNonExistingIdError",e[e["GenericIssue::FormHasPasswordFieldWithoutUsernameFieldError"]=74]="GenericIssue::FormHasPasswordFieldWithoutUsernameFieldError",e[e["GenericIssue::FormInputHasWrongButWellIntendedAutocompleteValueError"]=75]="GenericIssue::FormInputHasWrongButWellIntendedAutocompleteValueError",e[e["StylesheetLoadingIssue::LateImportRule"]=76]="StylesheetLoadingIssue::LateImportRule",e[e["StylesheetLoadingIssue::RequestFailed"]=77]="StylesheetLoadingIssue::RequestFailed",e[e["CorsIssue::PreflightMissingPrivateNetworkAccessId"]=78]="CorsIssue::PreflightMissingPrivateNetworkAccessId",e[e["CorsIssue::PreflightMissingPrivateNetworkAccessName"]=79]="CorsIssue::PreflightMissingPrivateNetworkAccessName",e[e["CorsIssue::PrivateNetworkAccessPermissionUnavailable"]=80]="CorsIssue::PrivateNetworkAccessPermissionUnavailable",e[e["CorsIssue::PrivateNetworkAccessPermissionDenied"]=81]="CorsIssue::PrivateNetworkAccessPermissionDenied",e[e["CookieIssue::WarnThirdPartyPhaseout::ReadCookie"]=82]="CookieIssue::WarnThirdPartyPhaseout::ReadCookie",e[e["CookieIssue::WarnThirdPartyPhaseout::SetCookie"]=83]="CookieIssue::WarnThirdPartyPhaseout::SetCookie",e[e["CookieIssue::ExcludeThirdPartyPhaseout::ReadCookie"]=84]="CookieIssue::ExcludeThirdPartyPhaseout::ReadCookie",e[e["CookieIssue::ExcludeThirdPartyPhaseout::SetCookie"]=85]="CookieIssue::ExcludeThirdPartyPhaseout::SetCookie",e[e.MaxValue=86]="MaxValue"}(Y||(Y={})),function(e){e[e.all=0]="all",e[e.Documents=1]="Documents",e[e.Scripts=2]="Scripts",e[e["Fetch and XHR"]=3]="Fetch and XHR",e[e.Stylesheets=4]="Stylesheets",e[e.Fonts=5]="Fonts",e[e.Images=6]="Images",e[e.Media=7]="Media",e[e.Manifest=8]="Manifest",e[e.WebSockets=9]="WebSockets",e[e.WebAssembly=10]="WebAssembly",e[e.Other=11]="Other",e[e.MaxValue=12]="MaxValue"}(Z||(Z={})),function(e){e[e["Hide data URLs"]=0]="Hide data URLs",e[e["Hide extension URLs"]=1]="Hide extension URLs",e[e["Blocked response cookies"]=2]="Blocked response cookies",e[e["Blocked requests"]=3]="Blocked requests",e[e["3rd-party requests"]=4]="3rd-party requests",e[e.MaxValue=5]="MaxValue"}(ee||(ee={})),function(e){e[e.af=1]="af",e[e.am=2]="am",e[e.ar=3]="ar",e[e.as=4]="as",e[e.az=5]="az",e[e.be=6]="be",e[e.bg=7]="bg",e[e.bn=8]="bn",e[e.bs=9]="bs",e[e.ca=10]="ca",e[e.cs=11]="cs",e[e.cy=12]="cy",e[e.da=13]="da",e[e.de=14]="de",e[e.el=15]="el",e[e["en-GB"]=16]="en-GB",e[e["en-US"]=17]="en-US",e[e["es-419"]=18]="es-419",e[e.es=19]="es",e[e.et=20]="et",e[e.eu=21]="eu",e[e.fa=22]="fa",e[e.fi=23]="fi",e[e.fil=24]="fil",e[e["fr-CA"]=25]="fr-CA",e[e.fr=26]="fr",e[e.gl=27]="gl",e[e.gu=28]="gu",e[e.he=29]="he",e[e.hi=30]="hi",e[e.hr=31]="hr",e[e.hu=32]="hu",e[e.hy=33]="hy",e[e.id=34]="id",e[e.is=35]="is",e[e.it=36]="it",e[e.ja=37]="ja",e[e.ka=38]="ka",e[e.kk=39]="kk",e[e.km=40]="km",e[e.kn=41]="kn",e[e.ko=42]="ko",e[e.ky=43]="ky",e[e.lo=44]="lo",e[e.lt=45]="lt",e[e.lv=46]="lv",e[e.mk=47]="mk",e[e.ml=48]="ml",e[e.mn=49]="mn",e[e.mr=50]="mr",e[e.ms=51]="ms",e[e.my=52]="my",e[e.ne=53]="ne",e[e.nl=54]="nl",e[e.no=55]="no",e[e.or=56]="or",e[e.pa=57]="pa",e[e.pl=58]="pl",e[e["pt-PT"]=59]="pt-PT",e[e.pt=60]="pt",e[e.ro=61]="ro",e[e.ru=62]="ru",e[e.si=63]="si",e[e.sk=64]="sk",e[e.sl=65]="sl",e[e.sq=66]="sq",e[e["sr-Latn"]=67]="sr-Latn",e[e.sr=68]="sr",e[e.sv=69]="sv",e[e.sw=70]="sw",e[e.ta=71]="ta",e[e.te=72]="te",e[e.th=73]="th",e[e.tr=74]="tr",e[e.uk=75]="uk",e[e.ur=76]="ur",e[e.uz=77]="uz",e[e.vi=78]="vi",e[e.zh=79]="zh",e[e["zh-HK"]=80]="zh-HK",e[e["zh-TW"]=81]="zh-TW",e[e.zu=82]="zu",e[e.MaxValue=83]="MaxValue"}(re||(re={})),function(e){e[e.OtherSection=0]="OtherSection",e[e.Identity=1]="Identity",e[e.Presentation=2]="Presentation",e[e["Protocol Handlers"]=3]="Protocol Handlers",e[e.Icons=4]="Icons",e[e["Window Controls Overlay"]=5]="Window Controls Overlay",e[e.MaxValue=6]="MaxValue"}(oe||(oe={}));var se=Object.freeze({__proto__:null,UserMetrics:ne,get Action(){return V},get PanelCodes(){return B},get PanelWithLocation(){return j},get ElementsSidebarTabCodes(){return q},get SourcesSidebarTabCodes(){return G},get MediaTypes(){return z},get KeybindSetSettings(){return $},get KeyboardShortcutAction(){return X},get DevtoolsExperiments(){return K},get IssueExpanded(){return Q},get IssueResourceOpened(){return J},get IssueCreated(){return Y},get ResourceType(){return Z},get NetworkPanelMoreFilters(){return ee},get Language(){return re},get ManifestSectionCodes(){return oe}});const ie=new ne,ae=L();export{T as AidaClient,E as InspectorFrontendHost,i as InspectorFrontendHostAPI,H as Platform,te as RNPerfMetrics,C as ResourceLoader,se as UserMetrics,ae as rnPerfMetrics,ie as userMetrics}; +import*as e from"../platform/platform.js";import*as r from"../root/root.js";import*as o from"../common/common.js";import*as t from"../i18n/i18n.js";var n;!function(e){e.AppendedToURL="appendedToURL",e.CanceledSaveURL="canceledSaveURL",e.ColorThemeChanged="colorThemeChanged",e.ContextMenuCleared="contextMenuCleared",e.ContextMenuItemSelected="contextMenuItemSelected",e.DeviceCountUpdated="deviceCountUpdated",e.DevicesDiscoveryConfigChanged="devicesDiscoveryConfigChanged",e.DevicesPortForwardingStatusChanged="devicesPortForwardingStatusChanged",e.DevicesUpdated="devicesUpdated",e.DispatchMessage="dispatchMessage",e.DispatchMessageChunk="dispatchMessageChunk",e.EnterInspectElementMode="enterInspectElementMode",e.EyeDropperPickedColor="eyeDropperPickedColor",e.FileSystemsLoaded="fileSystemsLoaded",e.FileSystemRemoved="fileSystemRemoved",e.FileSystemAdded="fileSystemAdded",e.FileSystemFilesChangedAddedRemoved="FileSystemFilesChangedAddedRemoved",e.IndexingTotalWorkCalculated="indexingTotalWorkCalculated",e.IndexingWorked="indexingWorked",e.IndexingDone="indexingDone",e.KeyEventUnhandled="keyEventUnhandled",e.ReattachRootTarget="reattachMainTarget",e.ReloadInspectedPage="reloadInspectedPage",e.RevealSourceLine="revealSourceLine",e.SavedURL="savedURL",e.SearchCompleted="searchCompleted",e.SetInspectedTabId="setInspectedTabId",e.SetUseSoftMenu="setUseSoftMenu",e.ShowPanel="showPanel"}(n||(n={}));const s=[[n.AppendedToURL,"appendedToURL",["url"]],[n.CanceledSaveURL,"canceledSaveURL",["url"]],[n.ColorThemeChanged,"colorThemeChanged",[]],[n.ContextMenuCleared,"contextMenuCleared",[]],[n.ContextMenuItemSelected,"contextMenuItemSelected",["id"]],[n.DeviceCountUpdated,"deviceCountUpdated",["count"]],[n.DevicesDiscoveryConfigChanged,"devicesDiscoveryConfigChanged",["config"]],[n.DevicesPortForwardingStatusChanged,"devicesPortForwardingStatusChanged",["status"]],[n.DevicesUpdated,"devicesUpdated",["devices"]],[n.DispatchMessage,"dispatchMessage",["messageObject"]],[n.DispatchMessageChunk,"dispatchMessageChunk",["messageChunk","messageSize"]],[n.EnterInspectElementMode,"enterInspectElementMode",[]],[n.EyeDropperPickedColor,"eyeDropperPickedColor",["color"]],[n.FileSystemsLoaded,"fileSystemsLoaded",["fileSystems"]],[n.FileSystemRemoved,"fileSystemRemoved",["fileSystemPath"]],[n.FileSystemAdded,"fileSystemAdded",["errorMessage","fileSystem"]],[n.FileSystemFilesChangedAddedRemoved,"fileSystemFilesChangedAddedRemoved",["changed","added","removed"]],[n.IndexingTotalWorkCalculated,"indexingTotalWorkCalculated",["requestId","fileSystemPath","totalWork"]],[n.IndexingWorked,"indexingWorked",["requestId","fileSystemPath","worked"]],[n.IndexingDone,"indexingDone",["requestId","fileSystemPath"]],[n.KeyEventUnhandled,"keyEventUnhandled",["event"]],[n.ReattachRootTarget,"reattachMainTarget",[]],[n.ReloadInspectedPage,"reloadInspectedPage",["hard"]],[n.RevealSourceLine,"revealSourceLine",["url","lineNumber","columnNumber"]],[n.SavedURL,"savedURL",["url","fileSystemPath"]],[n.SearchCompleted,"searchCompleted",["requestId","fileSystemPath","files"]],[n.SetInspectedTabId,"setInspectedTabId",["tabId"]],[n.SetUseSoftMenu,"setUseSoftMenu",["useSoftMenu"]],[n.ShowPanel,"showPanel",["panelName"]]];var i=Object.freeze({__proto__:null,get Events(){return n},EventDescriptors:s});const a={systemError:"System error",connectionError:"Connection error",certificateError:"Certificate error",httpError:"HTTP error",cacheError:"Cache error",signedExchangeError:"Signed Exchange error",ftpError:"FTP error",certificateManagerError:"Certificate manager error",dnsResolverError:"DNS resolver error",unknownError:"Unknown error",httpErrorStatusCodeSS:"HTTP error: status code {PH1}, {PH2}",invalidUrl:"Invalid URL",decodingDataUrlFailed:"Decoding Data URL failed"},d=t.i18n.registerUIStrings("core/host/ResourceLoader.ts",a),c=t.i18n.getLocalizedString.bind(void 0,d);let l=0;const u={},m=function(e){return u[++l]=e,l},g=function(e){u[e].close(),delete u[e]},p=function(e,r){u[e].write(r)};let h=function(e,r,t,n){const s=new o.StringOutputStream.StringOutputStream;w(e,r,s,(function(e,r,o){t(e,r,s.data(),o)}),n)};function v(e,r,o){if(void 0===e||void 0===o)return null;if(0!==e){if(function(e){return e<=-300&&e>-400}(e))return c(a.httpErrorStatusCodeSS,{PH1:String(r),PH2:o});const t=function(e){return c(e>-100?a.systemError:e>-200?a.connectionError:e>-300?a.certificateError:e>-400?a.httpError:e>-500?a.cacheError:e>-600?a.signedExchangeError:e>-700?a.ftpError:e>-800?a.certificateManagerError:e>-900?a.dnsResolverError:a.unknownError)}(e);return`${t}: ${o}`}return null}const w=function(e,r,t,n,s){const i=m(t);if(new o.ParsedURL.ParsedURL(e).isDataURL())return void(e=>new Promise(((r,o)=>{const t=new XMLHttpRequest;t.withCredentials=!1,t.open("GET",e,!0),t.onreadystatechange=function(){if(t.readyState===XMLHttpRequest.DONE){if(200!==t.status)return t.onreadystatechange=null,void o(new Error(String(t.status)));t.onreadystatechange=null,r(t.responseText)}},t.send(null)})))(e).then((function(e){p(i,e),l({statusCode:200})})).catch((function(e){l({statusCode:404,messageOverride:c(a.decodingDataUrlFailed)})}));if(!s&&function(e){try{const r=new URL(e);return"file:"===r.protocol&&""!==r.host}catch(e){return!1}}(e))return void(n&&n(!1,{},{statusCode:400,netError:-20,netErrorName:"net::BLOCKED_BY_CLIENT",message:"Loading from a remote file path is prohibited for security reasons."}));const d=[];if(r)for(const e in r)d.push(e+": "+r[e]);function l(e){if(n){const{success:r,description:o}=function(e){const{statusCode:r,netError:o,netErrorName:t,urlValid:n,messageOverride:s}=e;let i="";const d=r>=200&&r<300;if("string"==typeof s)i=s;else if(!d)if(void 0===o)i=c(!1===n?a.invalidUrl:a.unknownError);else{const e=v(o,r,t);e&&(i=e)}return console.assert(d===(0===i.length)),{success:d,description:{statusCode:r,netError:o,netErrorName:t,urlValid:n,message:i}}}(e);n(r,e.headers||{},o)}g(i)}I.loadNetworkResource(e,d.join("\r\n"),i,l)};var C=Object.freeze({__proto__:null,ResourceLoader:{},bindOutputStream:m,discardOutputStream:g,streamWrite:p,get load(){return h},setLoadForTest:function(e){h=e},netErrorToMessage:v,loadAsStream:w});const k={devtoolsS:"DevTools - {PH1}"},S=t.i18n.registerUIStrings("core/host/InspectorFrontendHost.ts",k),f=t.i18n.getLocalizedString.bind(void 0,S),y="/overrides";class b{#e;events;#r=null;recordedCountHistograms=[];recordedEnumeratedHistograms=[];recordedPerformanceHistograms=[];constructor(){function e(e){!("mac"===this.platform()?e.metaKey:e.ctrlKey)||"+"!==e.key&&"-"!==e.key||e.stopPropagation()}this.#e=new Map,"undefined"!=typeof document&&document.addEventListener("keydown",(r=>{e.call(this,r)}),!0)}platform(){const e=navigator.userAgent;return e.includes("Windows NT")?"windows":e.includes("Mac OS X")?"mac":"linux"}loadCompleted(){}bringToFront(){}closeWindow(){}setIsDocked(e,r){window.setTimeout(r,0)}showSurvey(e,r){window.setTimeout((()=>r({surveyShown:!1})),0)}canShowSurvey(e,r){window.setTimeout((()=>r({canShowSurvey:!1})),0)}setInspectedPageBounds(e){}inspectElementCompleted(){}setInjectedScriptForOrigin(e,r){}inspectedURLChanged(e){document.title=f(k.devtoolsS,{PH1:e.replace(/^https?:\/\//,"")})}copyText(e){null!=e&&navigator.clipboard.writeText(e)}openInNewTab(e){window.open(e,"_blank")}openSearchResultsInNewTab(e){o.Console.Console.instance().error("Search is not enabled in hosted mode. Please inspect using chrome://inspect")}showItemInFolder(e){o.Console.Console.instance().error("Show item in folder is not enabled in hosted mode. Please inspect using chrome://inspect")}save(e,r,o){let t=this.#e.get(e);t||(t=[],this.#e.set(e,t)),t.push(r),this.events.dispatchEventToListeners(n.SavedURL,{url:e,fileSystemPath:e})}append(e,r){const o=this.#e.get(e);o&&(o.push(r),this.events.dispatchEventToListeners(n.AppendedToURL,e))}close(r){const o=this.#e.get(r)||[];this.#e.delete(r);let t="";if(r)try{const o=e.StringUtilities.trimURL(r);t=e.StringUtilities.removeURLFragment(o)}catch(e){t=r}const n=document.createElement("a");n.download=t;const s=new Blob([o.join("")],{type:"text/plain"}),i=URL.createObjectURL(s);n.href=i,n.click(),URL.revokeObjectURL(i)}sendMessageToBackend(e){}recordCountHistogram(e,r,o,t,n){this.recordedCountHistograms.length>=100&&this.recordedCountHistograms.shift(),this.recordedCountHistograms.push({histogramName:e,sample:r,min:o,exclusiveMax:t,bucketSize:n})}recordEnumeratedHistogram(e,r,o){this.recordedEnumeratedHistograms.length>=100&&this.recordedEnumeratedHistograms.shift(),this.recordedEnumeratedHistograms.push({actionName:e,actionCode:r})}recordPerformanceHistogram(e,r){this.recordedPerformanceHistograms.length>=100&&this.recordedPerformanceHistograms.shift(),this.recordedPerformanceHistograms.push({histogramName:e,duration:r})}recordUserMetricsAction(e){}requestFileSystems(){this.events.dispatchEventToListeners(n.FileSystemsLoaded,[])}addFileSystem(e){window.webkitRequestFileSystem(window.TEMPORARY,1048576,(e=>{this.#r=e;const r={fileSystemName:"sandboxedRequestedFileSystem",fileSystemPath:y,rootURL:"filesystem:devtools://devtools/isolated/",type:"overrides"};this.events.dispatchEventToListeners(n.FileSystemAdded,{fileSystem:r})}))}removeFileSystem(e){const r=e=>{e.forEach((e=>{e.isDirectory?e.removeRecursively((()=>{})):e.isFile&&e.remove((()=>{}))}))};this.#r&&this.#r.root.createReader().readEntries(r),this.#r=null,this.events.dispatchEventToListeners(n.FileSystemRemoved,y)}isolatedFileSystem(e,r){return this.#r}loadNetworkResource(e,r,o,t){fetch(e).then((async e=>{const r=await e.arrayBuffer();let o=r;if(function(e){const r=new Uint8Array(e);return!(!r||r.length<3)&&31===r[0]&&139===r[1]&&8===r[2]}(r)){const e=new DecompressionStream("gzip"),t=e.writable.getWriter();t.write(r),t.close(),o=e.readable}return await new Response(o).text()})).then((function(e){p(o,e),t({statusCode:200,headers:void 0,messageOverride:void 0,netError:void 0,netErrorName:void 0,urlValid:void 0})})).catch((function(){t({statusCode:404,headers:void 0,messageOverride:void 0,netError:void 0,netErrorName:void 0,urlValid:void 0})}))}registerPreference(e,r){}getPreferences(e){const r={};for(const e in window.localStorage)r[e]=window.localStorage[e];e(r)}getPreference(e,r){r(window.localStorage[e])}setPreference(e,r){window.localStorage[e]=r}removePreference(e){delete window.localStorage[e]}clearPreferences(){window.localStorage.clear()}getSyncInformation(e){e({isSyncActive:!1,arePreferencesSynced:!1})}upgradeDraggedFileSystemPermissions(e){}indexPath(e,r,o){}stopIndexing(e){}searchInPath(e,r,o){}zoomFactor(){return 1}zoomIn(){}zoomOut(){}resetZoom(){}setWhitelistedShortcuts(e){}setEyeDropperActive(e){}showCertificateViewer(e){}reattach(e){e()}readyForTest(){}connectionReady(){}setOpenNewWindowForPopups(e){}setDevicesDiscoveryConfig(e){}setDevicesUpdatesEnabled(e){}performActionOnRemotePage(e,r){}openRemotePage(e,r){}openNodeFrontend(){}showContextMenuAtPoint(e,r,o,t){throw"Soft context menu should be used"}isHostedMode(){return!0}setAddExtensionCallback(e){}async initialTargetId(){return null}doAidaConversation(e,r,o){o({error:"Not implemened"})}registerAidaClientEvent(e){}recordImpression(e){}recordResize(e){}recordClick(e){}recordHover(e){}recordDrag(e){}recordChange(e){}recordKeyDown(e){}}let I=globalThis.InspectorFrontendHost;class x{constructor(){for(const e of s)this[e[1]]=this.dispatch.bind(this,e[0],e[2],e[3])}dispatch(e,r,o,...t){if(r.length<2){try{I.events.dispatchEventToListeners(e,t[0])}catch(e){console.error(e+" "+e.stack)}return}const n={};for(let e=0;e{let{promise:r,resolve:o,reject:t}=e.PromiseUtilities.promiseWithResolvers();return{write:async n=>{o(n),({promise:r,resolve:o,reject:t}=e.PromiseUtilities.promiseWithResolvers())},close:async()=>{o(null)},read:()=>r,fail:e=>t(e)}})(),t=m(o);let n;I.doAidaConversation(JSON.stringify(P.buildApiRequest(r)),t,(e=>{403===e.statusCode?o.fail(new Error("Server responded: permission denied")):e.error?o.fail(new Error(`Cannot send request: ${e.error} ${e.detail||""}`)):200!==e.statusCode?o.fail(new Error(`Request failed: ${JSON.stringify(e)}`)):o.close()}));const s=[];let i=!1;for(;n=await o.read();){if(!n.length)continue;let e;n.startsWith(",")&&(n=n.slice(1)),n.startsWith("[")||(n="["+n),n.endsWith("]")||(n+="]");try{e=JSON.parse(n)}catch(e){throw new Error("Cannot parse chunk: "+n,{cause:e})}const r="\n`````\n";for(const o of e)if("textChunk"in o)i&&(s.push(r),i=!1),s.push(o.textChunk.text);else{if(!("codeChunk"in o))throw"error"in o?new Error(`Server responded: ${JSON.stringify(o)}`):new Error("Unknown chunk result");i||(s.push(r),i=!0),s.push(o.codeChunk.code)}yield{explanation:s.join("")+(i?r:""),metadata:{rpcGlobalId:e[0]?.metadata?.rpcGlobalId}}}}}var T=Object.freeze({__proto__:null,AidaClient:P});let M,F,R,D,O;function _(){return M||(M=I.platform()),M}var A=Object.freeze({__proto__:null,platform:_,isMac:function(){return void 0===F&&(F="mac"===_()),F},isWin:function(){return void 0===R&&(R="windows"===_()),R},setPlatformForTests:function(e){M=e,F=void 0,R=void 0},isCustomDevtoolsFrontend:function(){return void 0===D&&(D=window.location.toString().startsWith("devtools://devtools/custom/")),D},fontFamily:function(){if(O)return O;switch(_()){case"linux":O="Roboto, Ubuntu, Arial, sans-serif";break;case"mac":O="'Lucida Grande', sans-serif";break;case"windows":O="'Segoe UI', Tahoma, sans-serif"}return O}});let H=null;function N(){return null===H&&(H=new L),H}class L{#o="error";#t=new Set;#n=null;addEventListener(e){this.#t.add(e);return()=>{this.#t.delete(e)}}removeAllEventListeners(){this.#t.clear()}sendEvent(e){if(!0!==globalThis.enableReactNativePerfMetrics)return;const r=this.#s(e),o=[];for(const e of this.#t)try{e(r)}catch(e){o.push(e)}if(o.length>0){const e=new AggregateError(o);console.error("Error occurred when calling event listeners",e)}}registerPerfMetricsGlobalPostMessageHandler(){!0===globalThis.enableReactNativePerfMetrics&&!0===globalThis.enableReactNativePerfMetricsGlobalPostMessage&&this.addEventListener((e=>{window.postMessage({event:e,tag:"react-native-chrome-devtools-perf-metrics"},window.location.origin)}))}registerGlobalErrorReporting(){window.addEventListener("error",(e=>{const[r,o]=W(`[RNPerfMetrics] uncaught error: ${e.message}`,e.error);this.sendEvent({eventName:"Browser.Error",params:{type:"error",message:r,error:o}})}),{passive:!0}),window.addEventListener("unhandledrejection",(e=>{const[r,o]=W("[RNPerfMetrics] unhandled promise rejection",e.reason);this.sendEvent({eventName:"Browser.Error",params:{type:"rejectedPromise",message:r,error:o}})}),{passive:!0});const e=globalThis.console,r=e[this.#o];e[this.#o]=(...o)=>{try{const e=o[0],[r,t]=W("[RNPerfMetrics] console.error",e);this.sendEvent({eventName:"Browser.Error",params:{message:r,error:t,type:"consoleError"}})}catch(e){const[r,o]=W("[RNPerfMetrics] Error handling console.error",e);this.sendEvent({eventName:"Browser.Error",params:{message:r,error:o,type:"consoleError"}})}finally{r.apply(e,o)}}}setLaunchId(e){this.#n=e}entryPointLoadingStarted(e){this.sendEvent({eventName:"Entrypoint.LoadingStarted",entryPoint:e})}entryPointLoadingFinished(e){this.sendEvent({eventName:"Entrypoint.LoadingFinished",entryPoint:e})}browserVisibilityChanged(e){this.sendEvent({eventName:"Browser.VisibilityChange",params:{visibilityState:e}})}remoteDebuggingTerminated(e){this.sendEvent({eventName:"Connection.DebuggingTerminated",params:{reason:e}})}developerResourceLoadingStarted(e,r){const o=U(e);this.sendEvent({eventName:"DeveloperResource.LoadingStarted",params:{url:o,loadingMethod:r}})}developerResourceLoadingFinished(e,r,o){const t=U(e);this.sendEvent({eventName:"DeveloperResource.LoadingFinished",params:{url:t,loadingMethod:r,success:o.success,errorMessage:o.errorDescription?.message}})}fuseboxSetClientMetadataStarted(){this.sendEvent({eventName:"FuseboxSetClientMetadataStarted"})}fuseboxSetClientMetadataFinished(e,r){if(e)this.sendEvent({eventName:"FuseboxSetClientMetadataFinished",params:{success:!0}});else{const[e,o]=W("[RNPerfMetrics] Fusebox setClientMetadata failed",r);this.sendEvent({eventName:"FuseboxSetClientMetadataFinished",params:{success:!1,error:o,errorMessage:e}})}}heapSnapshotStarted(){this.sendEvent({eventName:"MemoryPanelActionStarted",params:{action:"snapshot"}})}heapSnapshotFinished(e){this.sendEvent({eventName:"MemoryPanelActionFinished",params:{action:"snapshot",success:e}})}heapProfilingStarted(){this.sendEvent({eventName:"MemoryPanelActionStarted",params:{action:"profiling"}})}heapProfilingFinished(e){this.sendEvent({eventName:"MemoryPanelActionFinished",params:{action:"profiling",success:e}})}heapSamplingStarted(){this.sendEvent({eventName:"MemoryPanelActionStarted",params:{action:"sampling"}})}heapSamplingFinished(e){this.sendEvent({eventName:"MemoryPanelActionFinished",params:{action:"sampling",success:e}})}#s(e){return{...e,...{timestamp:performance.timeOrigin+performance.now(),launchId:this.#n}}}}function U(e){const{url:r}=e;return e.isHttpOrHttps()?r:`${r.slice(0,100)} …(omitted ${r.length-100} characters)`}function W(e,r){if(r instanceof Error){return[`${e}: ${r.message}`,r]}const o=`${e}: ${String(r)}`;return[o,new Error(o,{cause:r})]}var V,B,j,q,G,z,$,X,K,Q,J,Y,Z,ee,re,oe,te=Object.freeze({__proto__:null,getInstance:N});class ne{#i;#a;#d;constructor(){this.#i=!1,this.#a=!1,this.#d=""}breakpointWithConditionAdded(e){e>=2||I.recordEnumeratedHistogram("DevTools.BreakpointWithConditionAdded",e,2)}breakpointEditDialogRevealedFrom(e){e>=7||I.recordEnumeratedHistogram("DevTools.BreakpointEditDialogRevealedFrom",e,7)}panelShown(e,r){const o=B[e]||0;I.recordEnumeratedHistogram("DevTools.PanelShown",o,B.MaxValue),I.recordUserMetricsAction("DevTools_PanelShown_"+e),r||(this.#i=!0)}panelClosed(e){const r=B[e]||0;I.recordEnumeratedHistogram("DevTools.PanelClosed",r,B.MaxValue),this.#i=!0}panelShownInLocation(e,r){const o=j[`${e}-${r}`]||0;I.recordEnumeratedHistogram("DevTools.PanelShownInLocation",o,j.MaxValue)}elementsSidebarTabShown(e){const r=q[e]||0;I.recordEnumeratedHistogram("DevTools.Elements.SidebarTabShown",r,q.MaxValue)}sourcesSidebarTabShown(e){const r=G[e]||0;I.recordEnumeratedHistogram("DevTools.Sources.SidebarTabShown",r,G.MaxValue)}settingsPanelShown(e){this.panelShown("settings-"+e)}sourcesPanelFileDebugged(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.SourcesPanelFileDebugged",r,z.MaxValue)}sourcesPanelFileOpened(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.SourcesPanelFileOpened",r,z.MaxValue)}networkPanelResponsePreviewOpened(e){const r=e&&z[e]||z.Unknown;I.recordEnumeratedHistogram("DevTools.NetworkPanelResponsePreviewOpened",r,z.MaxValue)}actionTaken(e){I.recordEnumeratedHistogram("DevTools.ActionTaken",e,V.MaxValue)}panelLoaded(e,r){this.#a||e!==this.#d||(this.#a=!0,requestAnimationFrame((()=>{window.setTimeout((()=>{performance.mark(r),this.#i||I.recordPerformanceHistogram(r,performance.now())}),0)})))}setLaunchPanel(e){this.#d=e}performanceTraceLoad(e){I.recordPerformanceHistogram("DevTools.TraceLoad",e.duration)}keybindSetSettingChanged(e){const r=$[e]||0;I.recordEnumeratedHistogram("DevTools.KeybindSetSettingChanged",r,$.MaxValue)}keyboardShortcutFired(e){const r=X[e]||X.OtherShortcut;I.recordEnumeratedHistogram("DevTools.KeyboardShortcutFired",r,X.MaxValue)}issuesPanelOpenedFrom(e){I.recordEnumeratedHistogram("DevTools.IssuesPanelOpenedFrom",e,6)}issuesPanelIssueExpanded(e){if(void 0===e)return;const r=Q[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.IssuesPanelIssueExpanded",r,Q.MaxValue)}issuesPanelResourceOpened(e,r){const o=J[e+r];void 0!==o&&I.recordEnumeratedHistogram("DevTools.IssuesPanelResourceOpened",o,J.MaxValue)}issueCreated(e){const r=Y[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.IssueCreated",r,Y.MaxValue)}experimentEnabledAtLaunch(e){const r=K[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ExperimentEnabledAtLaunch",r,K.MaxValue)}experimentDisabledAtLaunch(e){const r=K[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ExperimentDisabledAtLaunch",r,K.MaxValue)}experimentChanged(e,r){const o=K[e];if(void 0===o)return;const t=r?"DevTools.ExperimentEnabled":"DevTools.ExperimentDisabled";I.recordEnumeratedHistogram(t,o,K.MaxValue)}developerResourceLoaded(e){e>=8||I.recordEnumeratedHistogram("DevTools.DeveloperResourceLoaded",e,8)}developerResourceScheme(e){e>=9||I.recordEnumeratedHistogram("DevTools.DeveloperResourceScheme",e,9)}inlineScriptParsed(e){e>=2||I.recordEnumeratedHistogram("DevTools.InlineScriptParsed",e,2)}vmInlineScriptContentShown(e){e>=2||I.recordEnumeratedHistogram("DevTools.VMInlineScriptShown",e,2)}language(e){const r=re[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.Language",r,re.MaxValue)}syncSetting(e){I.getSyncInformation((r=>{let o=1;r.isSyncActive&&!r.arePreferencesSynced?o=2:r.isSyncActive&&r.arePreferencesSynced&&(o=e?4:3),I.recordEnumeratedHistogram("DevTools.SyncSetting",o,5)}))}recordingAssertion(e){I.recordEnumeratedHistogram("DevTools.RecordingAssertion",e,4)}recordingToggled(e){I.recordEnumeratedHistogram("DevTools.RecordingToggled",e,3)}recordingReplayFinished(e){I.recordEnumeratedHistogram("DevTools.RecordingReplayFinished",e,5)}recordingReplaySpeed(e){I.recordEnumeratedHistogram("DevTools.RecordingReplaySpeed",e,5)}recordingReplayStarted(e){I.recordEnumeratedHistogram("DevTools.RecordingReplayStarted",e,4)}recordingEdited(e){I.recordEnumeratedHistogram("DevTools.RecordingEdited",e,11)}recordingExported(e){I.recordEnumeratedHistogram("DevTools.RecordingExported",e,6)}recordingCodeToggled(e){I.recordEnumeratedHistogram("DevTools.RecordingCodeToggled",e,3)}recordingCopiedToClipboard(e){I.recordEnumeratedHistogram("DevTools.RecordingCopiedToClipboard",e,9)}styleTextCopied(e){I.recordEnumeratedHistogram("DevTools.StyleTextCopied",e,11)}manifestSectionSelected(e){const r=oe[e]||oe.OtherSection;I.recordEnumeratedHistogram("DevTools.ManifestSectionSelected",r,oe.MaxValue)}cssHintShown(e){I.recordEnumeratedHistogram("DevTools.CSSHintShown",e,14)}lighthouseModeRun(e){I.recordEnumeratedHistogram("DevTools.LighthouseModeRun",e,4)}lighthouseCategoryUsed(e){I.recordEnumeratedHistogram("DevTools.LighthouseCategoryUsed",e,6)}colorConvertedFrom(e){I.recordEnumeratedHistogram("DevTools.ColorConvertedFrom",e,2)}colorPickerOpenedFrom(e){I.recordEnumeratedHistogram("DevTools.ColorPickerOpenedFrom",e,2)}cssPropertyDocumentation(e){I.recordEnumeratedHistogram("DevTools.CSSPropertyDocumentation",e,3)}swatchActivated(e){I.recordEnumeratedHistogram("DevTools.SwatchActivated",e,10)}badgeActivated(e){I.recordEnumeratedHistogram("DevTools.BadgeActivated",e,9)}breakpointsRestoredFromStorage(e){const r=this.#c(e);I.recordEnumeratedHistogram("DevTools.BreakpointsRestoredFromStorageCount",r,10)}animationPlaybackRateChanged(e){I.recordEnumeratedHistogram("DevTools.AnimationPlaybackRateChanged",e,4)}animationPointDragged(e){I.recordEnumeratedHistogram("DevTools.AnimationPointDragged",e,5)}#c(e){return e<100?0:e<300?1:e<1e3?2:e<3e3?3:e<1e4?4:e<3e4?5:e<1e5?6:e<3e5?7:e<1e6?8:9}workspacesPopulated(e){I.recordPerformanceHistogram("DevTools.Workspaces.PopulateWallClocktime",e)}visualLoggingProcessingDone(e){I.recordPerformanceHistogram("DevTools.VisualLogging.ProcessingTime",e)}legacyResourceTypeFilterNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,Z.MaxValue-1),1);I.recordEnumeratedHistogram("DevTools.LegacyResourceTypeFilterNumberOfSelectedChanged",r,Z.MaxValue)}legacyResourceTypeFilterItemSelected(e){const r=Z[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.LegacyResourceTypeFilterItemSelected",r,Z.MaxValue)}resourceTypeFilterNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,Z.MaxValue-1),1);I.recordEnumeratedHistogram("DevTools.ResourceTypeFilterNumberOfSelectedChanged",r,Z.MaxValue)}resourceTypeFilterItemSelected(e){const r=Z[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.ResourceTypeFilterItemSelected",r,Z.MaxValue)}networkPanelMoreFiltersNumberOfSelectedChanged(e){const r=Math.max(Math.min(e,ee.MaxValue),0);I.recordEnumeratedHistogram("DevTools.NetworkPanelMoreFiltersNumberOfSelectedChanged",r,ee.MaxValue)}networkPanelMoreFiltersItemSelected(e){const r=ee[e];void 0!==r&&I.recordEnumeratedHistogram("DevTools.NetworkPanelMoreFiltersItemSelected",r,ee.MaxValue)}}!function(e){e[e.WindowDocked=1]="WindowDocked",e[e.WindowUndocked=2]="WindowUndocked",e[e.ScriptsBreakpointSet=3]="ScriptsBreakpointSet",e[e.TimelineStarted=4]="TimelineStarted",e[e.ProfilesCPUProfileTaken=5]="ProfilesCPUProfileTaken",e[e.ProfilesHeapProfileTaken=6]="ProfilesHeapProfileTaken",e[e.ConsoleEvaluated=8]="ConsoleEvaluated",e[e.FileSavedInWorkspace=9]="FileSavedInWorkspace",e[e.DeviceModeEnabled=10]="DeviceModeEnabled",e[e.AnimationsPlaybackRateChanged=11]="AnimationsPlaybackRateChanged",e[e.RevisionApplied=12]="RevisionApplied",e[e.FileSystemDirectoryContentReceived=13]="FileSystemDirectoryContentReceived",e[e.StyleRuleEdited=14]="StyleRuleEdited",e[e.CommandEvaluatedInConsolePanel=15]="CommandEvaluatedInConsolePanel",e[e.DOMPropertiesExpanded=16]="DOMPropertiesExpanded",e[e.ResizedViewInResponsiveMode=17]="ResizedViewInResponsiveMode",e[e.TimelinePageReloadStarted=18]="TimelinePageReloadStarted",e[e.ConnectToNodeJSFromFrontend=19]="ConnectToNodeJSFromFrontend",e[e.ConnectToNodeJSDirectly=20]="ConnectToNodeJSDirectly",e[e.CpuThrottlingEnabled=21]="CpuThrottlingEnabled",e[e.CpuProfileNodeFocused=22]="CpuProfileNodeFocused",e[e.CpuProfileNodeExcluded=23]="CpuProfileNodeExcluded",e[e.SelectFileFromFilePicker=24]="SelectFileFromFilePicker",e[e.SelectCommandFromCommandMenu=25]="SelectCommandFromCommandMenu",e[e.ChangeInspectedNodeInElementsPanel=26]="ChangeInspectedNodeInElementsPanel",e[e.StyleRuleCopied=27]="StyleRuleCopied",e[e.CoverageStarted=28]="CoverageStarted",e[e.LighthouseStarted=29]="LighthouseStarted",e[e.LighthouseFinished=30]="LighthouseFinished",e[e.ShowedThirdPartyBadges=31]="ShowedThirdPartyBadges",e[e.LighthouseViewTrace=32]="LighthouseViewTrace",e[e.FilmStripStartedRecording=33]="FilmStripStartedRecording",e[e.CoverageReportFiltered=34]="CoverageReportFiltered",e[e.CoverageStartedPerBlock=35]="CoverageStartedPerBlock",e[e["SettingsOpenedFromGear-deprecated"]=36]="SettingsOpenedFromGear-deprecated",e[e["SettingsOpenedFromMenu-deprecated"]=37]="SettingsOpenedFromMenu-deprecated",e[e["SettingsOpenedFromCommandMenu-deprecated"]=38]="SettingsOpenedFromCommandMenu-deprecated",e[e.TabMovedToDrawer=39]="TabMovedToDrawer",e[e.TabMovedToMainPanel=40]="TabMovedToMainPanel",e[e.CaptureCssOverviewClicked=41]="CaptureCssOverviewClicked",e[e.VirtualAuthenticatorEnvironmentEnabled=42]="VirtualAuthenticatorEnvironmentEnabled",e[e.SourceOrderViewActivated=43]="SourceOrderViewActivated",e[e.UserShortcutAdded=44]="UserShortcutAdded",e[e.ShortcutRemoved=45]="ShortcutRemoved",e[e.ShortcutModified=46]="ShortcutModified",e[e.CustomPropertyLinkClicked=47]="CustomPropertyLinkClicked",e[e.CustomPropertyEdited=48]="CustomPropertyEdited",e[e.ServiceWorkerNetworkRequestClicked=49]="ServiceWorkerNetworkRequestClicked",e[e.ServiceWorkerNetworkRequestClosedQuickly=50]="ServiceWorkerNetworkRequestClosedQuickly",e[e.NetworkPanelServiceWorkerRespondWith=51]="NetworkPanelServiceWorkerRespondWith",e[e.NetworkPanelCopyValue=52]="NetworkPanelCopyValue",e[e.ConsoleSidebarOpened=53]="ConsoleSidebarOpened",e[e.PerfPanelTraceImported=54]="PerfPanelTraceImported",e[e.PerfPanelTraceExported=55]="PerfPanelTraceExported",e[e.StackFrameRestarted=56]="StackFrameRestarted",e[e.CaptureTestProtocolClicked=57]="CaptureTestProtocolClicked",e[e.BreakpointRemovedFromRemoveButton=58]="BreakpointRemovedFromRemoveButton",e[e.BreakpointGroupExpandedStateChanged=59]="BreakpointGroupExpandedStateChanged",e[e.HeaderOverrideFileCreated=60]="HeaderOverrideFileCreated",e[e.HeaderOverrideEnableEditingClicked=61]="HeaderOverrideEnableEditingClicked",e[e.HeaderOverrideHeaderAdded=62]="HeaderOverrideHeaderAdded",e[e.HeaderOverrideHeaderEdited=63]="HeaderOverrideHeaderEdited",e[e.HeaderOverrideHeaderRemoved=64]="HeaderOverrideHeaderRemoved",e[e.HeaderOverrideHeadersFileEdited=65]="HeaderOverrideHeadersFileEdited",e[e.PersistenceNetworkOverridesEnabled=66]="PersistenceNetworkOverridesEnabled",e[e.PersistenceNetworkOverridesDisabled=67]="PersistenceNetworkOverridesDisabled",e[e.BreakpointRemovedFromContextMenu=68]="BreakpointRemovedFromContextMenu",e[e.BreakpointsInFileRemovedFromRemoveButton=69]="BreakpointsInFileRemovedFromRemoveButton",e[e.BreakpointsInFileRemovedFromContextMenu=70]="BreakpointsInFileRemovedFromContextMenu",e[e.BreakpointsInFileCheckboxToggled=71]="BreakpointsInFileCheckboxToggled",e[e.BreakpointsInFileEnabledDisabledFromContextMenu=72]="BreakpointsInFileEnabledDisabledFromContextMenu",e[e.BreakpointConditionEditedFromSidebar=73]="BreakpointConditionEditedFromSidebar",e[e.WorkspaceTabAddFolder=74]="WorkspaceTabAddFolder",e[e.WorkspaceTabRemoveFolder=75]="WorkspaceTabRemoveFolder",e[e.OverrideTabAddFolder=76]="OverrideTabAddFolder",e[e.OverrideTabRemoveFolder=77]="OverrideTabRemoveFolder",e[e.WorkspaceSourceSelected=78]="WorkspaceSourceSelected",e[e.OverridesSourceSelected=79]="OverridesSourceSelected",e[e.StyleSheetInitiatorLinkClicked=80]="StyleSheetInitiatorLinkClicked",e[e.BreakpointRemovedFromGutterContextMenu=81]="BreakpointRemovedFromGutterContextMenu",e[e.BreakpointRemovedFromGutterToggle=82]="BreakpointRemovedFromGutterToggle",e[e.StylePropertyInsideKeyframeEdited=83]="StylePropertyInsideKeyframeEdited",e[e.OverrideContentFromSourcesContextMenu=84]="OverrideContentFromSourcesContextMenu",e[e.OverrideContentFromNetworkContextMenu=85]="OverrideContentFromNetworkContextMenu",e[e.OverrideScript=86]="OverrideScript",e[e.OverrideStyleSheet=87]="OverrideStyleSheet",e[e.OverrideDocument=88]="OverrideDocument",e[e.OverrideFetchXHR=89]="OverrideFetchXHR",e[e.OverrideImage=90]="OverrideImage",e[e.OverrideFont=91]="OverrideFont",e[e.OverrideContentContextMenuSetup=92]="OverrideContentContextMenuSetup",e[e.OverrideContentContextMenuAbandonSetup=93]="OverrideContentContextMenuAbandonSetup",e[e.OverrideContentContextMenuActivateDisabled=94]="OverrideContentContextMenuActivateDisabled",e[e.OverrideContentContextMenuOpenExistingFile=95]="OverrideContentContextMenuOpenExistingFile",e[e.OverrideContentContextMenuSaveNewFile=96]="OverrideContentContextMenuSaveNewFile",e[e.ShowAllOverridesFromSourcesContextMenu=97]="ShowAllOverridesFromSourcesContextMenu",e[e.ShowAllOverridesFromNetworkContextMenu=98]="ShowAllOverridesFromNetworkContextMenu",e[e.AnimationGroupsCleared=99]="AnimationGroupsCleared",e[e.AnimationsPaused=100]="AnimationsPaused",e[e.AnimationsResumed=101]="AnimationsResumed",e[e.AnimatedNodeDescriptionClicked=102]="AnimatedNodeDescriptionClicked",e[e.AnimationGroupScrubbed=103]="AnimationGroupScrubbed",e[e.AnimationGroupReplayed=104]="AnimationGroupReplayed",e[e.OverrideTabDeleteFolderContextMenu=105]="OverrideTabDeleteFolderContextMenu",e[e.WorkspaceDropFolder=107]="WorkspaceDropFolder",e[e.WorkspaceSelectFolder=108]="WorkspaceSelectFolder",e[e.OverrideContentContextMenuSourceMappedWarning=109]="OverrideContentContextMenuSourceMappedWarning",e[e.OverrideContentContextMenuRedirectToDeployed=110]="OverrideContentContextMenuRedirectToDeployed",e[e.NewStyleRuleAdded=111]="NewStyleRuleAdded",e[e.TraceExpanded=112]="TraceExpanded",e[e.InsightConsoleMessageShown=113]="InsightConsoleMessageShown",e[e.InsightRequestedViaContextMenu=114]="InsightRequestedViaContextMenu",e[e.InsightRequestedViaHoverButton=115]="InsightRequestedViaHoverButton",e[e.InsightRatedPositive=117]="InsightRatedPositive",e[e.InsightRatedNegative=118]="InsightRatedNegative",e[e.InsightClosed=119]="InsightClosed",e[e.InsightErrored=120]="InsightErrored",e[e.InsightHoverButtonShown=121]="InsightHoverButtonShown",e[e.SelfXssWarningConsoleMessageShown=122]="SelfXssWarningConsoleMessageShown",e[e.SelfXssWarningDialogShown=123]="SelfXssWarningDialogShown",e[e.SelfXssAllowPastingInConsole=124]="SelfXssAllowPastingInConsole",e[e.SelfXssAllowPastingInDialog=125]="SelfXssAllowPastingInDialog",e[e.ToggleEmulateFocusedPageFromStylesPaneOn=126]="ToggleEmulateFocusedPageFromStylesPaneOn",e[e.ToggleEmulateFocusedPageFromStylesPaneOff=127]="ToggleEmulateFocusedPageFromStylesPaneOff",e[e.ToggleEmulateFocusedPageFromRenderingTab=128]="ToggleEmulateFocusedPageFromRenderingTab",e[e.ToggleEmulateFocusedPageFromCommandMenu=129]="ToggleEmulateFocusedPageFromCommandMenu",e[e.InsightGenerated=130]="InsightGenerated",e[e.InsightErroredApi=131]="InsightErroredApi",e[e.InsightErroredMarkdown=132]="InsightErroredMarkdown",e[e.ToggleShowWebVitals=133]="ToggleShowWebVitals",e[e.InsightErroredPermissionDenied=134]="InsightErroredPermissionDenied",e[e.InsightErroredCannotSend=135]="InsightErroredCannotSend",e[e.InsightErroredRequestFailed=136]="InsightErroredRequestFailed",e[e.InsightErroredCannotParseChunk=137]="InsightErroredCannotParseChunk",e[e.InsightErroredUnknownChunk=138]="InsightErroredUnknownChunk",e[e.InsightErroredOther=139]="InsightErroredOther",e[e.MaxValue=140]="MaxValue"}(V||(V={})),function(e){e[e.elements=1]="elements",e[e.resources=2]="resources",e[e.network=3]="network",e[e.sources=4]="sources",e[e.timeline=5]="timeline",e[e["heap-profiler"]=6]="heap-profiler",e[e.console=8]="console",e[e.layers=9]="layers",e[e["console-view"]=10]="console-view",e[e.animations=11]="animations",e[e["network.config"]=12]="network.config",e[e.rendering=13]="rendering",e[e.sensors=14]="sensors",e[e["sources.search"]=15]="sources.search",e[e.security=16]="security",e[e["js-profiler"]=17]="js-profiler",e[e.lighthouse=18]="lighthouse",e[e.coverage=19]="coverage",e[e["protocol-monitor"]=20]="protocol-monitor",e[e["remote-devices"]=21]="remote-devices",e[e["web-audio"]=22]="web-audio",e[e["changes.changes"]=23]="changes.changes",e[e["performance.monitor"]=24]="performance.monitor",e[e["release-note"]=25]="release-note",e[e["live-heap-profile"]=26]="live-heap-profile",e[e["sources.quick"]=27]="sources.quick",e[e["network.blocked-urls"]=28]="network.blocked-urls",e[e["settings-preferences"]=29]="settings-preferences",e[e["settings-workspace"]=30]="settings-workspace",e[e["settings-experiments"]=31]="settings-experiments",e[e["settings-blackbox"]=32]="settings-blackbox",e[e["settings-devices"]=33]="settings-devices",e[e["settings-throttling-conditions"]=34]="settings-throttling-conditions",e[e["settings-emulation-locations"]=35]="settings-emulation-locations",e[e["settings-shortcuts"]=36]="settings-shortcuts",e[e["issues-pane"]=37]="issues-pane",e[e["settings-keybinds"]=38]="settings-keybinds",e[e.cssoverview=39]="cssoverview",e[e["chrome-recorder"]=40]="chrome-recorder",e[e["trust-tokens"]=41]="trust-tokens",e[e["reporting-api"]=42]="reporting-api",e[e["interest-groups"]=43]="interest-groups",e[e["back-forward-cache"]=44]="back-forward-cache",e[e["service-worker-cache"]=45]="service-worker-cache",e[e["background-service-background-fetch"]=46]="background-service-background-fetch",e[e["background-service-background-sync"]=47]="background-service-background-sync",e[e["background-service-push-messaging"]=48]="background-service-push-messaging",e[e["background-service-notifications"]=49]="background-service-notifications",e[e["background-service-payment-handler"]=50]="background-service-payment-handler",e[e["background-service-periodic-background-sync"]=51]="background-service-periodic-background-sync",e[e["service-workers"]=52]="service-workers",e[e["app-manifest"]=53]="app-manifest",e[e.storage=54]="storage",e[e.cookies=55]="cookies",e[e["frame-details"]=56]="frame-details",e[e["frame-resource"]=57]="frame-resource",e[e["frame-window"]=58]="frame-window",e[e["frame-worker"]=59]="frame-worker",e[e["dom-storage"]=60]="dom-storage",e[e["indexed-db"]=61]="indexed-db",e[e["web-sql"]=62]="web-sql",e[e["performance-insights"]=63]="performance-insights",e[e.preloading=64]="preloading",e[e["bounce-tracking-mitigations"]=65]="bounce-tracking-mitigations",e[e["developer-resources"]=66]="developer-resources",e[e["autofill-view"]=67]="autofill-view",e[e.MaxValue=68]="MaxValue"}(B||(B={})),function(e){e[e["elements-main"]=1]="elements-main",e[e["elements-drawer"]=2]="elements-drawer",e[e["resources-main"]=3]="resources-main",e[e["resources-drawer"]=4]="resources-drawer",e[e["network-main"]=5]="network-main",e[e["network-drawer"]=6]="network-drawer",e[e["sources-main"]=7]="sources-main",e[e["sources-drawer"]=8]="sources-drawer",e[e["timeline-main"]=9]="timeline-main",e[e["timeline-drawer"]=10]="timeline-drawer",e[e["heap_profiler-main"]=11]="heap_profiler-main",e[e["heap_profiler-drawer"]=12]="heap_profiler-drawer",e[e["console-main"]=13]="console-main",e[e["console-drawer"]=14]="console-drawer",e[e["layers-main"]=15]="layers-main",e[e["layers-drawer"]=16]="layers-drawer",e[e["console-view-main"]=17]="console-view-main",e[e["console-view-drawer"]=18]="console-view-drawer",e[e["animations-main"]=19]="animations-main",e[e["animations-drawer"]=20]="animations-drawer",e[e["network.config-main"]=21]="network.config-main",e[e["network.config-drawer"]=22]="network.config-drawer",e[e["rendering-main"]=23]="rendering-main",e[e["rendering-drawer"]=24]="rendering-drawer",e[e["sensors-main"]=25]="sensors-main",e[e["sensors-drawer"]=26]="sensors-drawer",e[e["sources.search-main"]=27]="sources.search-main",e[e["sources.search-drawer"]=28]="sources.search-drawer",e[e["security-main"]=29]="security-main",e[e["security-drawer"]=30]="security-drawer",e[e["js_profiler-main"]=31]="js_profiler-main",e[e["js_profiler-drawer"]=32]="js_profiler-drawer",e[e["lighthouse-main"]=33]="lighthouse-main",e[e["lighthouse-drawer"]=34]="lighthouse-drawer",e[e["coverage-main"]=35]="coverage-main",e[e["coverage-drawer"]=36]="coverage-drawer",e[e["protocol-monitor-main"]=37]="protocol-monitor-main",e[e["protocol-monitor-drawer"]=38]="protocol-monitor-drawer",e[e["remote-devices-main"]=39]="remote-devices-main",e[e["remote-devices-drawer"]=40]="remote-devices-drawer",e[e["web-audio-main"]=41]="web-audio-main",e[e["web-audio-drawer"]=42]="web-audio-drawer",e[e["changes.changes-main"]=43]="changes.changes-main",e[e["changes.changes-drawer"]=44]="changes.changes-drawer",e[e["performance.monitor-main"]=45]="performance.monitor-main",e[e["performance.monitor-drawer"]=46]="performance.monitor-drawer",e[e["release-note-main"]=47]="release-note-main",e[e["release-note-drawer"]=48]="release-note-drawer",e[e["live_heap_profile-main"]=49]="live_heap_profile-main",e[e["live_heap_profile-drawer"]=50]="live_heap_profile-drawer",e[e["sources.quick-main"]=51]="sources.quick-main",e[e["sources.quick-drawer"]=52]="sources.quick-drawer",e[e["network.blocked-urls-main"]=53]="network.blocked-urls-main",e[e["network.blocked-urls-drawer"]=54]="network.blocked-urls-drawer",e[e["settings-preferences-main"]=55]="settings-preferences-main",e[e["settings-preferences-drawer"]=56]="settings-preferences-drawer",e[e["settings-workspace-main"]=57]="settings-workspace-main",e[e["settings-workspace-drawer"]=58]="settings-workspace-drawer",e[e["settings-experiments-main"]=59]="settings-experiments-main",e[e["settings-experiments-drawer"]=60]="settings-experiments-drawer",e[e["settings-blackbox-main"]=61]="settings-blackbox-main",e[e["settings-blackbox-drawer"]=62]="settings-blackbox-drawer",e[e["settings-devices-main"]=63]="settings-devices-main",e[e["settings-devices-drawer"]=64]="settings-devices-drawer",e[e["settings-throttling-conditions-main"]=65]="settings-throttling-conditions-main",e[e["settings-throttling-conditions-drawer"]=66]="settings-throttling-conditions-drawer",e[e["settings-emulation-locations-main"]=67]="settings-emulation-locations-main",e[e["settings-emulation-locations-drawer"]=68]="settings-emulation-locations-drawer",e[e["settings-shortcuts-main"]=69]="settings-shortcuts-main",e[e["settings-shortcuts-drawer"]=70]="settings-shortcuts-drawer",e[e["issues-pane-main"]=71]="issues-pane-main",e[e["issues-pane-drawer"]=72]="issues-pane-drawer",e[e["settings-keybinds-main"]=73]="settings-keybinds-main",e[e["settings-keybinds-drawer"]=74]="settings-keybinds-drawer",e[e["cssoverview-main"]=75]="cssoverview-main",e[e["cssoverview-drawer"]=76]="cssoverview-drawer",e[e["chrome_recorder-main"]=77]="chrome_recorder-main",e[e["chrome_recorder-drawer"]=78]="chrome_recorder-drawer",e[e["trust_tokens-main"]=79]="trust_tokens-main",e[e["trust_tokens-drawer"]=80]="trust_tokens-drawer",e[e["reporting_api-main"]=81]="reporting_api-main",e[e["reporting_api-drawer"]=82]="reporting_api-drawer",e[e["interest_groups-main"]=83]="interest_groups-main",e[e["interest_groups-drawer"]=84]="interest_groups-drawer",e[e["back_forward_cache-main"]=85]="back_forward_cache-main",e[e["back_forward_cache-drawer"]=86]="back_forward_cache-drawer",e[e["service_worker_cache-main"]=87]="service_worker_cache-main",e[e["service_worker_cache-drawer"]=88]="service_worker_cache-drawer",e[e["background_service_backgroundFetch-main"]=89]="background_service_backgroundFetch-main",e[e["background_service_backgroundFetch-drawer"]=90]="background_service_backgroundFetch-drawer",e[e["background_service_backgroundSync-main"]=91]="background_service_backgroundSync-main",e[e["background_service_backgroundSync-drawer"]=92]="background_service_backgroundSync-drawer",e[e["background_service_pushMessaging-main"]=93]="background_service_pushMessaging-main",e[e["background_service_pushMessaging-drawer"]=94]="background_service_pushMessaging-drawer",e[e["background_service_notifications-main"]=95]="background_service_notifications-main",e[e["background_service_notifications-drawer"]=96]="background_service_notifications-drawer",e[e["background_service_paymentHandler-main"]=97]="background_service_paymentHandler-main",e[e["background_service_paymentHandler-drawer"]=98]="background_service_paymentHandler-drawer",e[e["background_service_periodicBackgroundSync-main"]=99]="background_service_periodicBackgroundSync-main",e[e["background_service_periodicBackgroundSync-drawer"]=100]="background_service_periodicBackgroundSync-drawer",e[e["service_workers-main"]=101]="service_workers-main",e[e["service_workers-drawer"]=102]="service_workers-drawer",e[e["app_manifest-main"]=103]="app_manifest-main",e[e["app_manifest-drawer"]=104]="app_manifest-drawer",e[e["storage-main"]=105]="storage-main",e[e["storage-drawer"]=106]="storage-drawer",e[e["cookies-main"]=107]="cookies-main",e[e["cookies-drawer"]=108]="cookies-drawer",e[e["frame_details-main"]=109]="frame_details-main",e[e["frame_details-drawer"]=110]="frame_details-drawer",e[e["frame_resource-main"]=111]="frame_resource-main",e[e["frame_resource-drawer"]=112]="frame_resource-drawer",e[e["frame_window-main"]=113]="frame_window-main",e[e["frame_window-drawer"]=114]="frame_window-drawer",e[e["frame_worker-main"]=115]="frame_worker-main",e[e["frame_worker-drawer"]=116]="frame_worker-drawer",e[e["dom_storage-main"]=117]="dom_storage-main",e[e["dom_storage-drawer"]=118]="dom_storage-drawer",e[e["indexed_db-main"]=119]="indexed_db-main",e[e["indexed_db-drawer"]=120]="indexed_db-drawer",e[e["web_sql-main"]=121]="web_sql-main",e[e["web_sql-drawer"]=122]="web_sql-drawer",e[e["performance_insights-main"]=123]="performance_insights-main",e[e["performance_insights-drawer"]=124]="performance_insights-drawer",e[e["preloading-main"]=125]="preloading-main",e[e["preloading-drawer"]=126]="preloading-drawer",e[e["bounce_tracking_mitigations-main"]=127]="bounce_tracking_mitigations-main",e[e["bounce_tracking_mitigations-drawer"]=128]="bounce_tracking_mitigations-drawer",e[e["developer-resources-main"]=129]="developer-resources-main",e[e["developer-resources-drawer"]=130]="developer-resources-drawer",e[e["autofill-view-main"]=131]="autofill-view-main",e[e["autofill-view-drawer"]=132]="autofill-view-drawer",e[e.MaxValue=133]="MaxValue"}(j||(j={})),function(e){e[e.OtherSidebarPane=0]="OtherSidebarPane",e[e.styles=1]="styles",e[e.computed=2]="computed",e[e["elements.layout"]=3]="elements.layout",e[e["elements.event-listeners"]=4]="elements.event-listeners",e[e["elements.dom-breakpoints"]=5]="elements.dom-breakpoints",e[e["elements.dom-properties"]=6]="elements.dom-properties",e[e["accessibility.view"]=7]="accessibility.view",e[e.MaxValue=8]="MaxValue"}(q||(q={})),function(e){e[e.OtherSidebarPane=0]="OtherSidebarPane",e[e["navigator-network"]=1]="navigator-network",e[e["navigator-files"]=2]="navigator-files",e[e["navigator-overrides"]=3]="navigator-overrides",e[e["navigator-content-scripts"]=4]="navigator-content-scripts",e[e["navigator-snippets"]=5]="navigator-snippets",e[e.MaxValue=6]="MaxValue"}(G||(G={})),function(e){e[e.Unknown=0]="Unknown",e[e["text/css"]=2]="text/css",e[e["text/html"]=3]="text/html",e[e["application/xml"]=4]="application/xml",e[e["application/wasm"]=5]="application/wasm",e[e["application/manifest+json"]=6]="application/manifest+json",e[e["application/x-aspx"]=7]="application/x-aspx",e[e["application/jsp"]=8]="application/jsp",e[e["text/x-c++src"]=9]="text/x-c++src",e[e["text/x-coffeescript"]=10]="text/x-coffeescript",e[e["application/vnd.dart"]=11]="application/vnd.dart",e[e["text/typescript"]=12]="text/typescript",e[e["text/typescript-jsx"]=13]="text/typescript-jsx",e[e["application/json"]=14]="application/json",e[e["text/x-csharp"]=15]="text/x-csharp",e[e["text/x-java"]=16]="text/x-java",e[e["text/x-less"]=17]="text/x-less",e[e["application/x-httpd-php"]=18]="application/x-httpd-php",e[e["text/x-python"]=19]="text/x-python",e[e["text/x-sh"]=20]="text/x-sh",e[e["text/x-gss"]=21]="text/x-gss",e[e["text/x-sass"]=22]="text/x-sass",e[e["text/x-scss"]=23]="text/x-scss",e[e["text/markdown"]=24]="text/markdown",e[e["text/x-clojure"]=25]="text/x-clojure",e[e["text/jsx"]=26]="text/jsx",e[e["text/x-go"]=27]="text/x-go",e[e["text/x-kotlin"]=28]="text/x-kotlin",e[e["text/x-scala"]=29]="text/x-scala",e[e["text/x.svelte"]=30]="text/x.svelte",e[e["text/javascript+plain"]=31]="text/javascript+plain",e[e["text/javascript+minified"]=32]="text/javascript+minified",e[e["text/javascript+sourcemapped"]=33]="text/javascript+sourcemapped",e[e["text/x.angular"]=34]="text/x.angular",e[e["text/x.vue"]=35]="text/x.vue",e[e.MaxValue=36]="MaxValue"}(z||(z={})),function(e){e[e.devToolsDefault=0]="devToolsDefault",e[e.vsCode=1]="vsCode",e[e.MaxValue=2]="MaxValue"}($||($={})),function(e){e[e.OtherShortcut=0]="OtherShortcut",e[e["quick-open.show-command-menu"]=1]="quick-open.show-command-menu",e[e["console.clear"]=2]="console.clear",e[e["console.toggle"]=3]="console.toggle",e[e["debugger.step"]=4]="debugger.step",e[e["debugger.step-into"]=5]="debugger.step-into",e[e["debugger.step-out"]=6]="debugger.step-out",e[e["debugger.step-over"]=7]="debugger.step-over",e[e["debugger.toggle-breakpoint"]=8]="debugger.toggle-breakpoint",e[e["debugger.toggle-breakpoint-enabled"]=9]="debugger.toggle-breakpoint-enabled",e[e["debugger.toggle-pause"]=10]="debugger.toggle-pause",e[e["elements.edit-as-html"]=11]="elements.edit-as-html",e[e["elements.hide-element"]=12]="elements.hide-element",e[e["elements.redo"]=13]="elements.redo",e[e["elements.toggle-element-search"]=14]="elements.toggle-element-search",e[e["elements.undo"]=15]="elements.undo",e[e["main.search-in-panel.find"]=16]="main.search-in-panel.find",e[e["main.toggle-drawer"]=17]="main.toggle-drawer",e[e["network.hide-request-details"]=18]="network.hide-request-details",e[e["network.search"]=19]="network.search",e[e["network.toggle-recording"]=20]="network.toggle-recording",e[e["quick-open.show"]=21]="quick-open.show",e[e["settings.show"]=22]="settings.show",e[e["sources.search"]=23]="sources.search",e[e["background-service.toggle-recording"]=24]="background-service.toggle-recording",e[e["components.collect-garbage"]=25]="components.collect-garbage",e[e["console.clear.history"]=26]="console.clear.history",e[e["console.create-pin"]=27]="console.create-pin",e[e["coverage.start-with-reload"]=28]="coverage.start-with-reload",e[e["coverage.toggle-recording"]=29]="coverage.toggle-recording",e[e["debugger.breakpoint-input-window"]=30]="debugger.breakpoint-input-window",e[e["debugger.evaluate-selection"]=31]="debugger.evaluate-selection",e[e["debugger.next-call-frame"]=32]="debugger.next-call-frame",e[e["debugger.previous-call-frame"]=33]="debugger.previous-call-frame",e[e["debugger.run-snippet"]=34]="debugger.run-snippet",e[e["debugger.toggle-breakpoints-active"]=35]="debugger.toggle-breakpoints-active",e[e["elements.capture-area-screenshot"]=36]="elements.capture-area-screenshot",e[e["emulation.capture-full-height-screenshot"]=37]="emulation.capture-full-height-screenshot",e[e["emulation.capture-node-screenshot"]=38]="emulation.capture-node-screenshot",e[e["emulation.capture-screenshot"]=39]="emulation.capture-screenshot",e[e["emulation.show-sensors"]=40]="emulation.show-sensors",e[e["emulation.toggle-device-mode"]=41]="emulation.toggle-device-mode",e[e["help.release-notes"]=42]="help.release-notes",e[e["help.report-issue"]=43]="help.report-issue",e[e["input.start-replaying"]=44]="input.start-replaying",e[e["input.toggle-pause"]=45]="input.toggle-pause",e[e["input.toggle-recording"]=46]="input.toggle-recording",e[e["inspector-main.focus-debuggee"]=47]="inspector-main.focus-debuggee",e[e["inspector-main.hard-reload"]=48]="inspector-main.hard-reload",e[e["inspector-main.reload"]=49]="inspector-main.reload",e[e["live-heap-profile.start-with-reload"]=50]="live-heap-profile.start-with-reload",e[e["live-heap-profile.toggle-recording"]=51]="live-heap-profile.toggle-recording",e[e["main.debug-reload"]=52]="main.debug-reload",e[e["main.next-tab"]=53]="main.next-tab",e[e["main.previous-tab"]=54]="main.previous-tab",e[e["main.search-in-panel.cancel"]=55]="main.search-in-panel.cancel",e[e["main.search-in-panel.find-next"]=56]="main.search-in-panel.find-next",e[e["main.search-in-panel.find-previous"]=57]="main.search-in-panel.find-previous",e[e["main.toggle-dock"]=58]="main.toggle-dock",e[e["main.zoom-in"]=59]="main.zoom-in",e[e["main.zoom-out"]=60]="main.zoom-out",e[e["main.zoom-reset"]=61]="main.zoom-reset",e[e["network-conditions.network-low-end-mobile"]=62]="network-conditions.network-low-end-mobile",e[e["network-conditions.network-mid-tier-mobile"]=63]="network-conditions.network-mid-tier-mobile",e[e["network-conditions.network-offline"]=64]="network-conditions.network-offline",e[e["network-conditions.network-online"]=65]="network-conditions.network-online",e[e["profiler.heap-toggle-recording"]=66]="profiler.heap-toggle-recording",e[e["profiler.js-toggle-recording"]=67]="profiler.js-toggle-recording",e[e["resources.clear"]=68]="resources.clear",e[e["settings.documentation"]=69]="settings.documentation",e[e["settings.shortcuts"]=70]="settings.shortcuts",e[e["sources.add-folder-to-workspace"]=71]="sources.add-folder-to-workspace",e[e["sources.add-to-watch"]=72]="sources.add-to-watch",e[e["sources.close-all"]=73]="sources.close-all",e[e["sources.close-editor-tab"]=74]="sources.close-editor-tab",e[e["sources.create-snippet"]=75]="sources.create-snippet",e[e["sources.go-to-line"]=76]="sources.go-to-line",e[e["sources.go-to-member"]=77]="sources.go-to-member",e[e["sources.jump-to-next-location"]=78]="sources.jump-to-next-location",e[e["sources.jump-to-previous-location"]=79]="sources.jump-to-previous-location",e[e["sources.rename"]=80]="sources.rename",e[e["sources.save"]=81]="sources.save",e[e["sources.save-all"]=82]="sources.save-all",e[e["sources.switch-file"]=83]="sources.switch-file",e[e["timeline.jump-to-next-frame"]=84]="timeline.jump-to-next-frame",e[e["timeline.jump-to-previous-frame"]=85]="timeline.jump-to-previous-frame",e[e["timeline.load-from-file"]=86]="timeline.load-from-file",e[e["timeline.next-recording"]=87]="timeline.next-recording",e[e["timeline.previous-recording"]=88]="timeline.previous-recording",e[e["timeline.record-reload"]=89]="timeline.record-reload",e[e["timeline.save-to-file"]=90]="timeline.save-to-file",e[e["timeline.show-history"]=91]="timeline.show-history",e[e["timeline.toggle-recording"]=92]="timeline.toggle-recording",e[e["sources.increment-css"]=93]="sources.increment-css",e[e["sources.increment-css-by-ten"]=94]="sources.increment-css-by-ten",e[e["sources.decrement-css"]=95]="sources.decrement-css",e[e["sources.decrement-css-by-ten"]=96]="sources.decrement-css-by-ten",e[e["layers.reset-view"]=97]="layers.reset-view",e[e["layers.pan-mode"]=98]="layers.pan-mode",e[e["layers.rotate-mode"]=99]="layers.rotate-mode",e[e["layers.zoom-in"]=100]="layers.zoom-in",e[e["layers.zoom-out"]=101]="layers.zoom-out",e[e["layers.up"]=102]="layers.up",e[e["layers.down"]=103]="layers.down",e[e["layers.left"]=104]="layers.left",e[e["layers.right"]=105]="layers.right",e[e["help.report-translation-issue"]=106]="help.report-translation-issue",e[e["rendering.toggle-prefers-color-scheme"]=107]="rendering.toggle-prefers-color-scheme",e[e["chrome-recorder.start-recording"]=108]="chrome-recorder.start-recording",e[e["chrome-recorder.replay-recording"]=109]="chrome-recorder.replay-recording",e[e["chrome-recorder.toggle-code-view"]=110]="chrome-recorder.toggle-code-view",e[e["chrome-recorder.copy-recording-or-step"]=111]="chrome-recorder.copy-recording-or-step",e[e["changes.revert"]=112]="changes.revert",e[e["changes.copy"]=113]="changes.copy",e[e["elements.new-style-rule"]=114]="elements.new-style-rule",e[e["elements.refresh-event-listeners"]=115]="elements.refresh-event-listeners",e[e["coverage.clear"]=116]="coverage.clear",e[e["coverage.export"]=117]="coverage.export",e[e.MaxValue=118]="MaxValue"}(X||(X={})),function(e){e[e["apply-custom-stylesheet"]=0]="apply-custom-stylesheet",e[e["capture-node-creation-stacks"]=1]="capture-node-creation-stacks",e[e["live-heap-profile"]=11]="live-heap-profile",e[e["protocol-monitor"]=13]="protocol-monitor",e[e["sampling-heap-profiler-timeline"]=17]="sampling-heap-profiler-timeline",e[e["show-option-tp-expose-internals-in-heap-snapshot"]=18]="show-option-tp-expose-internals-in-heap-snapshot",e[e["timeline-invalidation-tracking"]=26]="timeline-invalidation-tracking",e[e["timeline-show-all-events"]=27]="timeline-show-all-events",e[e["timeline-v8-runtime-call-stats"]=28]="timeline-v8-runtime-call-stats",e[e.apca=39]="apca",e[e["font-editor"]=41]="font-editor",e[e["full-accessibility-tree"]=42]="full-accessibility-tree",e[e["ignore-list-js-frames-on-timeline"]=43]="ignore-list-js-frames-on-timeline",e[e["contrast-issues"]=44]="contrast-issues",e[e["experimental-cookie-features"]=45]="experimental-cookie-features",e[e["styles-pane-css-changes"]=55]="styles-pane-css-changes",e[e["evaluate-expressions-with-source-maps"]=58]="evaluate-expressions-with-source-maps",e[e["instrumentation-breakpoints"]=61]="instrumentation-breakpoints",e[e["authored-deployed-grouping"]=63]="authored-deployed-grouping",e[e["important-dom-properties"]=64]="important-dom-properties",e[e["just-my-code"]=65]="just-my-code",e[e["timeline-as-console-profile-result-panel"]=67]="timeline-as-console-profile-result-panel",e[e["preloading-status-panel"]=68]="preloading-status-panel",e[e["outermost-target-selector"]=71]="outermost-target-selector",e[e["js-profiler-temporarily-enable"]=72]="js-profiler-temporarily-enable",e[e["highlight-errors-elements-panel"]=73]="highlight-errors-elements-panel",e[e["set-all-breakpoints-eagerly"]=74]="set-all-breakpoints-eagerly",e[e["self-xss-warning"]=75]="self-xss-warning",e[e["use-source-map-scopes"]=76]="use-source-map-scopes",e[e["storage-buckets-tree"]=77]="storage-buckets-tree",e[e["network-panel-filter-bar-redesign"]=79]="network-panel-filter-bar-redesign",e[e["track-context-menu"]=81]="track-context-menu",e[e["autofill-view"]=82]="autofill-view",e[e["sources-frame-indentation-markers-temporarily-disable"]=83]="sources-frame-indentation-markers-temporarily-disable",e[e["heap-snapshot-treat-backing-store-as-containing-object"]=84]="heap-snapshot-treat-backing-store-as-containing-object",e[e["css-type-component-length-deprecate"]=85]="css-type-component-length-deprecate",e[e.MaxValue=86]="MaxValue"}(K||(K={})),function(e){e[e.CrossOriginEmbedderPolicy=0]="CrossOriginEmbedderPolicy",e[e.MixedContent=1]="MixedContent",e[e.SameSiteCookie=2]="SameSiteCookie",e[e.HeavyAd=3]="HeavyAd",e[e.ContentSecurityPolicy=4]="ContentSecurityPolicy",e[e.Other=5]="Other",e[e.Generic=6]="Generic",e[e.ThirdPartyPhaseoutCookie=7]="ThirdPartyPhaseoutCookie",e[e.GenericCookie=8]="GenericCookie",e[e.MaxValue=9]="MaxValue"}(Q||(Q={})),function(e){e[e.CrossOriginEmbedderPolicyRequest=0]="CrossOriginEmbedderPolicyRequest",e[e.CrossOriginEmbedderPolicyElement=1]="CrossOriginEmbedderPolicyElement",e[e.MixedContentRequest=2]="MixedContentRequest",e[e.SameSiteCookieCookie=3]="SameSiteCookieCookie",e[e.SameSiteCookieRequest=4]="SameSiteCookieRequest",e[e.HeavyAdElement=5]="HeavyAdElement",e[e.ContentSecurityPolicyDirective=6]="ContentSecurityPolicyDirective",e[e.ContentSecurityPolicyElement=7]="ContentSecurityPolicyElement",e[e.MaxValue=13]="MaxValue"}(J||(J={})),function(e){e[e.MixedContentIssue=0]="MixedContentIssue",e[e["ContentSecurityPolicyIssue::kInlineViolation"]=1]="ContentSecurityPolicyIssue::kInlineViolation",e[e["ContentSecurityPolicyIssue::kEvalViolation"]=2]="ContentSecurityPolicyIssue::kEvalViolation",e[e["ContentSecurityPolicyIssue::kURLViolation"]=3]="ContentSecurityPolicyIssue::kURLViolation",e[e["ContentSecurityPolicyIssue::kTrustedTypesSinkViolation"]=4]="ContentSecurityPolicyIssue::kTrustedTypesSinkViolation",e[e["ContentSecurityPolicyIssue::kTrustedTypesPolicyViolation"]=5]="ContentSecurityPolicyIssue::kTrustedTypesPolicyViolation",e[e["HeavyAdIssue::NetworkTotalLimit"]=6]="HeavyAdIssue::NetworkTotalLimit",e[e["HeavyAdIssue::CpuTotalLimit"]=7]="HeavyAdIssue::CpuTotalLimit",e[e["HeavyAdIssue::CpuPeakLimit"]=8]="HeavyAdIssue::CpuPeakLimit",e[e["CrossOriginEmbedderPolicyIssue::CoepFrameResourceNeedsCoepHeader"]=9]="CrossOriginEmbedderPolicyIssue::CoepFrameResourceNeedsCoepHeader",e[e["CrossOriginEmbedderPolicyIssue::CoopSandboxedIFrameCannotNavigateToCoopPage"]=10]="CrossOriginEmbedderPolicyIssue::CoopSandboxedIFrameCannotNavigateToCoopPage",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameOrigin"]=11]="CrossOriginEmbedderPolicyIssue::CorpNotSameOrigin",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameOriginAfterDefaultedToSameOriginByCoep"]=12]="CrossOriginEmbedderPolicyIssue::CorpNotSameOriginAfterDefaultedToSameOriginByCoep",e[e["CrossOriginEmbedderPolicyIssue::CorpNotSameSite"]=13]="CrossOriginEmbedderPolicyIssue::CorpNotSameSite",e[e["CookieIssue::ExcludeSameSiteNoneInsecure::ReadCookie"]=14]="CookieIssue::ExcludeSameSiteNoneInsecure::ReadCookie",e[e["CookieIssue::ExcludeSameSiteNoneInsecure::SetCookie"]=15]="CookieIssue::ExcludeSameSiteNoneInsecure::SetCookie",e[e["CookieIssue::WarnSameSiteNoneInsecure::ReadCookie"]=16]="CookieIssue::WarnSameSiteNoneInsecure::ReadCookie",e[e["CookieIssue::WarnSameSiteNoneInsecure::SetCookie"]=17]="CookieIssue::WarnSameSiteNoneInsecure::SetCookie",e[e["CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Secure"]=18]="CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Secure",e[e["CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Insecure"]=19]="CookieIssue::WarnSameSiteStrictLaxDowngradeStrict::Insecure",e[e["CookieIssue::WarnCrossDowngrade::ReadCookie::Secure"]=20]="CookieIssue::WarnCrossDowngrade::ReadCookie::Secure",e[e["CookieIssue::WarnCrossDowngrade::ReadCookie::Insecure"]=21]="CookieIssue::WarnCrossDowngrade::ReadCookie::Insecure",e[e["CookieIssue::WarnCrossDowngrade::SetCookie::Secure"]=22]="CookieIssue::WarnCrossDowngrade::SetCookie::Secure",e[e["CookieIssue::WarnCrossDowngrade::SetCookie::Insecure"]=23]="CookieIssue::WarnCrossDowngrade::SetCookie::Insecure",e[e["CookieIssue::ExcludeNavigationContextDowngrade::Secure"]=24]="CookieIssue::ExcludeNavigationContextDowngrade::Secure",e[e["CookieIssue::ExcludeNavigationContextDowngrade::Insecure"]=25]="CookieIssue::ExcludeNavigationContextDowngrade::Insecure",e[e["CookieIssue::ExcludeContextDowngrade::ReadCookie::Secure"]=26]="CookieIssue::ExcludeContextDowngrade::ReadCookie::Secure",e[e["CookieIssue::ExcludeContextDowngrade::ReadCookie::Insecure"]=27]="CookieIssue::ExcludeContextDowngrade::ReadCookie::Insecure",e[e["CookieIssue::ExcludeContextDowngrade::SetCookie::Secure"]=28]="CookieIssue::ExcludeContextDowngrade::SetCookie::Secure",e[e["CookieIssue::ExcludeContextDowngrade::SetCookie::Insecure"]=29]="CookieIssue::ExcludeContextDowngrade::SetCookie::Insecure",e[e["CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::ReadCookie"]=30]="CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::ReadCookie",e[e["CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::SetCookie"]=31]="CookieIssue::ExcludeSameSiteUnspecifiedTreatedAsLax::SetCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::ReadCookie"]=32]="CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::ReadCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::SetCookie"]=33]="CookieIssue::WarnSameSiteUnspecifiedLaxAllowUnsafe::SetCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::ReadCookie"]=34]="CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::ReadCookie",e[e["CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::SetCookie"]=35]="CookieIssue::WarnSameSiteUnspecifiedCrossSiteContext::SetCookie",e[e["SharedArrayBufferIssue::TransferIssue"]=36]="SharedArrayBufferIssue::TransferIssue",e[e["SharedArrayBufferIssue::CreationIssue"]=37]="SharedArrayBufferIssue::CreationIssue",e[e.LowTextContrastIssue=41]="LowTextContrastIssue",e[e["CorsIssue::InsecurePrivateNetwork"]=42]="CorsIssue::InsecurePrivateNetwork",e[e["CorsIssue::InvalidHeaders"]=44]="CorsIssue::InvalidHeaders",e[e["CorsIssue::WildcardOriginWithCredentials"]=45]="CorsIssue::WildcardOriginWithCredentials",e[e["CorsIssue::PreflightResponseInvalid"]=46]="CorsIssue::PreflightResponseInvalid",e[e["CorsIssue::OriginMismatch"]=47]="CorsIssue::OriginMismatch",e[e["CorsIssue::AllowCredentialsRequired"]=48]="CorsIssue::AllowCredentialsRequired",e[e["CorsIssue::MethodDisallowedByPreflightResponse"]=49]="CorsIssue::MethodDisallowedByPreflightResponse",e[e["CorsIssue::HeaderDisallowedByPreflightResponse"]=50]="CorsIssue::HeaderDisallowedByPreflightResponse",e[e["CorsIssue::RedirectContainsCredentials"]=51]="CorsIssue::RedirectContainsCredentials",e[e["CorsIssue::DisallowedByMode"]=52]="CorsIssue::DisallowedByMode",e[e["CorsIssue::CorsDisabledScheme"]=53]="CorsIssue::CorsDisabledScheme",e[e["CorsIssue::PreflightMissingAllowExternal"]=54]="CorsIssue::PreflightMissingAllowExternal",e[e["CorsIssue::PreflightInvalidAllowExternal"]=55]="CorsIssue::PreflightInvalidAllowExternal",e[e["CorsIssue::NoCorsRedirectModeNotFollow"]=57]="CorsIssue::NoCorsRedirectModeNotFollow",e[e["QuirksModeIssue::QuirksMode"]=58]="QuirksModeIssue::QuirksMode",e[e["QuirksModeIssue::LimitedQuirksMode"]=59]="QuirksModeIssue::LimitedQuirksMode",e[e.DeprecationIssue=60]="DeprecationIssue",e[e["ClientHintIssue::MetaTagAllowListInvalidOrigin"]=61]="ClientHintIssue::MetaTagAllowListInvalidOrigin",e[e["ClientHintIssue::MetaTagModifiedHTML"]=62]="ClientHintIssue::MetaTagModifiedHTML",e[e["CorsIssue::PreflightAllowPrivateNetworkError"]=63]="CorsIssue::PreflightAllowPrivateNetworkError",e[e["GenericIssue::CrossOriginPortalPostMessageError"]=64]="GenericIssue::CrossOriginPortalPostMessageError",e[e["GenericIssue::FormLabelForNameError"]=65]="GenericIssue::FormLabelForNameError",e[e["GenericIssue::FormDuplicateIdForInputError"]=66]="GenericIssue::FormDuplicateIdForInputError",e[e["GenericIssue::FormInputWithNoLabelError"]=67]="GenericIssue::FormInputWithNoLabelError",e[e["GenericIssue::FormAutocompleteAttributeEmptyError"]=68]="GenericIssue::FormAutocompleteAttributeEmptyError",e[e["GenericIssue::FormEmptyIdAndNameAttributesForInputError"]=69]="GenericIssue::FormEmptyIdAndNameAttributesForInputError",e[e["GenericIssue::FormAriaLabelledByToNonExistingId"]=70]="GenericIssue::FormAriaLabelledByToNonExistingId",e[e["GenericIssue::FormInputAssignedAutocompleteValueToIdOrNameAttributeError"]=71]="GenericIssue::FormInputAssignedAutocompleteValueToIdOrNameAttributeError",e[e["GenericIssue::FormLabelHasNeitherForNorNestedInput"]=72]="GenericIssue::FormLabelHasNeitherForNorNestedInput",e[e["GenericIssue::FormLabelForMatchesNonExistingIdError"]=73]="GenericIssue::FormLabelForMatchesNonExistingIdError",e[e["GenericIssue::FormHasPasswordFieldWithoutUsernameFieldError"]=74]="GenericIssue::FormHasPasswordFieldWithoutUsernameFieldError",e[e["GenericIssue::FormInputHasWrongButWellIntendedAutocompleteValueError"]=75]="GenericIssue::FormInputHasWrongButWellIntendedAutocompleteValueError",e[e["StylesheetLoadingIssue::LateImportRule"]=76]="StylesheetLoadingIssue::LateImportRule",e[e["StylesheetLoadingIssue::RequestFailed"]=77]="StylesheetLoadingIssue::RequestFailed",e[e["CorsIssue::PreflightMissingPrivateNetworkAccessId"]=78]="CorsIssue::PreflightMissingPrivateNetworkAccessId",e[e["CorsIssue::PreflightMissingPrivateNetworkAccessName"]=79]="CorsIssue::PreflightMissingPrivateNetworkAccessName",e[e["CorsIssue::PrivateNetworkAccessPermissionUnavailable"]=80]="CorsIssue::PrivateNetworkAccessPermissionUnavailable",e[e["CorsIssue::PrivateNetworkAccessPermissionDenied"]=81]="CorsIssue::PrivateNetworkAccessPermissionDenied",e[e["CookieIssue::WarnThirdPartyPhaseout::ReadCookie"]=82]="CookieIssue::WarnThirdPartyPhaseout::ReadCookie",e[e["CookieIssue::WarnThirdPartyPhaseout::SetCookie"]=83]="CookieIssue::WarnThirdPartyPhaseout::SetCookie",e[e["CookieIssue::ExcludeThirdPartyPhaseout::ReadCookie"]=84]="CookieIssue::ExcludeThirdPartyPhaseout::ReadCookie",e[e["CookieIssue::ExcludeThirdPartyPhaseout::SetCookie"]=85]="CookieIssue::ExcludeThirdPartyPhaseout::SetCookie",e[e.MaxValue=86]="MaxValue"}(Y||(Y={})),function(e){e[e.all=0]="all",e[e.Documents=1]="Documents",e[e.Scripts=2]="Scripts",e[e["Fetch and XHR"]=3]="Fetch and XHR",e[e.Stylesheets=4]="Stylesheets",e[e.Fonts=5]="Fonts",e[e.Images=6]="Images",e[e.Media=7]="Media",e[e.Manifest=8]="Manifest",e[e.WebSockets=9]="WebSockets",e[e.WebAssembly=10]="WebAssembly",e[e.Other=11]="Other",e[e.MaxValue=12]="MaxValue"}(Z||(Z={})),function(e){e[e["Hide data URLs"]=0]="Hide data URLs",e[e["Hide extension URLs"]=1]="Hide extension URLs",e[e["Blocked response cookies"]=2]="Blocked response cookies",e[e["Blocked requests"]=3]="Blocked requests",e[e["3rd-party requests"]=4]="3rd-party requests",e[e.MaxValue=5]="MaxValue"}(ee||(ee={})),function(e){e[e.af=1]="af",e[e.am=2]="am",e[e.ar=3]="ar",e[e.as=4]="as",e[e.az=5]="az",e[e.be=6]="be",e[e.bg=7]="bg",e[e.bn=8]="bn",e[e.bs=9]="bs",e[e.ca=10]="ca",e[e.cs=11]="cs",e[e.cy=12]="cy",e[e.da=13]="da",e[e.de=14]="de",e[e.el=15]="el",e[e["en-GB"]=16]="en-GB",e[e["en-US"]=17]="en-US",e[e["es-419"]=18]="es-419",e[e.es=19]="es",e[e.et=20]="et",e[e.eu=21]="eu",e[e.fa=22]="fa",e[e.fi=23]="fi",e[e.fil=24]="fil",e[e["fr-CA"]=25]="fr-CA",e[e.fr=26]="fr",e[e.gl=27]="gl",e[e.gu=28]="gu",e[e.he=29]="he",e[e.hi=30]="hi",e[e.hr=31]="hr",e[e.hu=32]="hu",e[e.hy=33]="hy",e[e.id=34]="id",e[e.is=35]="is",e[e.it=36]="it",e[e.ja=37]="ja",e[e.ka=38]="ka",e[e.kk=39]="kk",e[e.km=40]="km",e[e.kn=41]="kn",e[e.ko=42]="ko",e[e.ky=43]="ky",e[e.lo=44]="lo",e[e.lt=45]="lt",e[e.lv=46]="lv",e[e.mk=47]="mk",e[e.ml=48]="ml",e[e.mn=49]="mn",e[e.mr=50]="mr",e[e.ms=51]="ms",e[e.my=52]="my",e[e.ne=53]="ne",e[e.nl=54]="nl",e[e.no=55]="no",e[e.or=56]="or",e[e.pa=57]="pa",e[e.pl=58]="pl",e[e["pt-PT"]=59]="pt-PT",e[e.pt=60]="pt",e[e.ro=61]="ro",e[e.ru=62]="ru",e[e.si=63]="si",e[e.sk=64]="sk",e[e.sl=65]="sl",e[e.sq=66]="sq",e[e["sr-Latn"]=67]="sr-Latn",e[e.sr=68]="sr",e[e.sv=69]="sv",e[e.sw=70]="sw",e[e.ta=71]="ta",e[e.te=72]="te",e[e.th=73]="th",e[e.tr=74]="tr",e[e.uk=75]="uk",e[e.ur=76]="ur",e[e.uz=77]="uz",e[e.vi=78]="vi",e[e.zh=79]="zh",e[e["zh-HK"]=80]="zh-HK",e[e["zh-TW"]=81]="zh-TW",e[e.zu=82]="zu",e[e.MaxValue=83]="MaxValue"}(re||(re={})),function(e){e[e.OtherSection=0]="OtherSection",e[e.Identity=1]="Identity",e[e.Presentation=2]="Presentation",e[e["Protocol Handlers"]=3]="Protocol Handlers",e[e.Icons=4]="Icons",e[e["Window Controls Overlay"]=5]="Window Controls Overlay",e[e.MaxValue=6]="MaxValue"}(oe||(oe={}));var se=Object.freeze({__proto__:null,UserMetrics:ne,get Action(){return V},get PanelCodes(){return B},get PanelWithLocation(){return j},get ElementsSidebarTabCodes(){return q},get SourcesSidebarTabCodes(){return G},get MediaTypes(){return z},get KeybindSetSettings(){return $},get KeyboardShortcutAction(){return X},get DevtoolsExperiments(){return K},get IssueExpanded(){return Q},get IssueResourceOpened(){return J},get IssueCreated(){return Y},get ResourceType(){return Z},get NetworkPanelMoreFilters(){return ee},get Language(){return re},get ManifestSectionCodes(){return oe}});const ie=new ne,ae=N();export{T as AidaClient,E as InspectorFrontendHost,i as InspectorFrontendHostAPI,A as Platform,te as RNPerfMetrics,C as ResourceLoader,se as UserMetrics,ae as rnPerfMetrics,ie as userMetrics}; diff --git a/packages/debugger-frontend/dist/third-party/front_end/core/i18n/locales/en-US.json b/packages/debugger-frontend/dist/third-party/front_end/core/i18n/locales/en-US.json index dcda53f66ebb78..3934ef44faca30 100644 --- a/packages/debugger-frontend/dist/third-party/front_end/core/i18n/locales/en-US.json +++ b/packages/debugger-frontend/dist/third-party/front_end/core/i18n/locales/en-US.json @@ -1 +1 @@ -{"core/common/ResourceType.ts | cspviolationreport":{"message":"CSPViolationReport"},"core/common/ResourceType.ts | css":{"message":"CSS"},"core/common/ResourceType.ts | doc":{"message":"Doc"},"core/common/ResourceType.ts | document":{"message":"Document"},"core/common/ResourceType.ts | eventsource":{"message":"EventSource"},"core/common/ResourceType.ts | fetch":{"message":"Fetch"},"core/common/ResourceType.ts | fetchAndXHR":{"message":"Fetch and XHR"},"core/common/ResourceType.ts | font":{"message":"Font"},"core/common/ResourceType.ts | image":{"message":"Image"},"core/common/ResourceType.ts | img":{"message":"Img"},"core/common/ResourceType.ts | javascript":{"message":"JavaScript"},"core/common/ResourceType.ts | js":{"message":"JS"},"core/common/ResourceType.ts | manifest":{"message":"Manifest"},"core/common/ResourceType.ts | media":{"message":"Media"},"core/common/ResourceType.ts | other":{"message":"Other"},"core/common/ResourceType.ts | ping":{"message":"Ping"},"core/common/ResourceType.ts | preflight":{"message":"Preflight"},"core/common/ResourceType.ts | script":{"message":"Script"},"core/common/ResourceType.ts | signedexchange":{"message":"SignedExchange"},"core/common/ResourceType.ts | stylesheet":{"message":"Stylesheet"},"core/common/ResourceType.ts | texttrack":{"message":"TextTrack"},"core/common/ResourceType.ts | wasm":{"message":"Wasm"},"core/common/ResourceType.ts | webassembly":{"message":"WebAssembly"},"core/common/ResourceType.ts | webbundle":{"message":"WebBundle"},"core/common/ResourceType.ts | websocket":{"message":"WebSocket"},"core/common/ResourceType.ts | webtransport":{"message":"WebTransport"},"core/common/ResourceType.ts | ws":{"message":"WS"},"core/common/Revealer.ts | applicationPanel":{"message":"Application panel"},"core/common/Revealer.ts | changesDrawer":{"message":"Changes drawer"},"core/common/Revealer.ts | elementsPanel":{"message":"Elements panel"},"core/common/Revealer.ts | issuesView":{"message":"Issues view"},"core/common/Revealer.ts | memoryInspectorPanel":{"message":"Memory inspector panel"},"core/common/Revealer.ts | networkPanel":{"message":"Network panel"},"core/common/Revealer.ts | sourcesPanel":{"message":"Sources panel"},"core/common/Revealer.ts | stylesSidebar":{"message":"styles sidebar"},"core/common/SettingRegistration.ts | adorner":{"message":"Adorner"},"core/common/SettingRegistration.ts | appearance":{"message":"Appearance"},"core/common/SettingRegistration.ts | console":{"message":"Console"},"core/common/SettingRegistration.ts | debugger":{"message":"Debugger"},"core/common/SettingRegistration.ts | elements":{"message":"Elements"},"core/common/SettingRegistration.ts | extension":{"message":"Extension"},"core/common/SettingRegistration.ts | global":{"message":"Global"},"core/common/SettingRegistration.ts | grid":{"message":"Grid"},"core/common/SettingRegistration.ts | memory":{"message":"Memory"},"core/common/SettingRegistration.ts | mobile":{"message":"Mobile"},"core/common/SettingRegistration.ts | network":{"message":"Network"},"core/common/SettingRegistration.ts | performance":{"message":"Performance"},"core/common/SettingRegistration.ts | persistence":{"message":"Persistence"},"core/common/SettingRegistration.ts | rendering":{"message":"Rendering"},"core/common/SettingRegistration.ts | sources":{"message":"Sources"},"core/common/SettingRegistration.ts | sync":{"message":"Sync"},"core/host/InspectorFrontendHost.ts | devtoolsS":{"message":"DevTools - {PH1}"},"core/host/ResourceLoader.ts | cacheError":{"message":"Cache error"},"core/host/ResourceLoader.ts | certificateError":{"message":"Certificate error"},"core/host/ResourceLoader.ts | certificateManagerError":{"message":"Certificate manager error"},"core/host/ResourceLoader.ts | connectionError":{"message":"Connection error"},"core/host/ResourceLoader.ts | decodingDataUrlFailed":{"message":"Decoding Data URL failed"},"core/host/ResourceLoader.ts | dnsResolverError":{"message":"DNS resolver error"},"core/host/ResourceLoader.ts | ftpError":{"message":"FTP error"},"core/host/ResourceLoader.ts | httpError":{"message":"HTTP error"},"core/host/ResourceLoader.ts | httpErrorStatusCodeSS":{"message":"HTTP error: status code {PH1}, {PH2}"},"core/host/ResourceLoader.ts | invalidUrl":{"message":"Invalid URL"},"core/host/ResourceLoader.ts | signedExchangeError":{"message":"Signed Exchange error"},"core/host/ResourceLoader.ts | systemError":{"message":"System error"},"core/host/ResourceLoader.ts | unknownError":{"message":"Unknown error"},"core/i18n/time-utilities.ts | fdays":{"message":"{PH1} days"},"core/i18n/time-utilities.ts | fhrs":{"message":"{PH1} hrs"},"core/i18n/time-utilities.ts | fmin":{"message":"{PH1} min"},"core/i18n/time-utilities.ts | fmms":{"message":"{PH1} μs"},"core/i18n/time-utilities.ts | fms":{"message":"{PH1} ms"},"core/i18n/time-utilities.ts | fs":{"message":"{PH1} s"},"core/sdk/ChildTargetManager.ts | main":{"message":"Main"},"core/sdk/CompilerSourceMappingContentProvider.ts | couldNotLoadContentForSS":{"message":"Could not load content for {PH1} ({PH2})"},"core/sdk/ConsoleModel.ts | bfcacheNavigation":{"message":"Navigation to {PH1} was restored from back/forward cache (see https://web.dev/bfcache/)"},"core/sdk/ConsoleModel.ts | failedToSaveToTempVariable":{"message":"Failed to save to temp variable."},"core/sdk/ConsoleModel.ts | navigatedToS":{"message":"Navigated to {PH1}"},"core/sdk/ConsoleModel.ts | profileSFinished":{"message":"Profile ''{PH1}'' finished."},"core/sdk/ConsoleModel.ts | profileSStarted":{"message":"Profile ''{PH1}'' started."},"core/sdk/CPUProfilerModel.ts | profileD":{"message":"Profile {PH1}"},"core/sdk/CSSStyleSheetHeader.ts | couldNotFindTheOriginalStyle":{"message":"Could not find the original style sheet."},"core/sdk/CSSStyleSheetHeader.ts | thereWasAnErrorRetrievingThe":{"message":"There was an error retrieving the source styles."},"core/sdk/DebuggerModel.ts | block":{"message":"Block"},"core/sdk/DebuggerModel.ts | catchBlock":{"message":"Catch block"},"core/sdk/DebuggerModel.ts | closure":{"message":"Closure"},"core/sdk/DebuggerModel.ts | expression":{"message":"Expression"},"core/sdk/DebuggerModel.ts | global":{"message":"Global"},"core/sdk/DebuggerModel.ts | local":{"message":"Local"},"core/sdk/DebuggerModel.ts | module":{"message":"Module"},"core/sdk/DebuggerModel.ts | script":{"message":"Script"},"core/sdk/DebuggerModel.ts | withBlock":{"message":"With block"},"core/sdk/NetworkManager.ts | fastG":{"message":"Fast 3G"},"core/sdk/NetworkManager.ts | noContentForPreflight":{"message":"No content available for preflight request"},"core/sdk/NetworkManager.ts | noContentForRedirect":{"message":"No content available because this request was redirected"},"core/sdk/NetworkManager.ts | noContentForWebSocket":{"message":"Content for WebSockets is currently not supported"},"core/sdk/NetworkManager.ts | noThrottling":{"message":"No throttling"},"core/sdk/NetworkManager.ts | offline":{"message":"Offline"},"core/sdk/NetworkManager.ts | requestWasBlockedByDevtoolsS":{"message":"Request was blocked by DevTools: \"{PH1}\""},"core/sdk/NetworkManager.ts | sFailedLoadingSS":{"message":"{PH1} failed loading: {PH2} \"{PH3}\"."},"core/sdk/NetworkManager.ts | sFinishedLoadingSS":{"message":"{PH1} finished loading: {PH2} \"{PH3}\"."},"core/sdk/NetworkManager.ts | slowG":{"message":"Slow 3G"},"core/sdk/NetworkRequest.ts | anUnknownErrorWasEncounteredWhenTrying":{"message":"An unknown error was encountered when trying to store this cookie."},"core/sdk/NetworkRequest.ts | binary":{"message":"(binary)"},"core/sdk/NetworkRequest.ts | blockedReasonInvalidDomain":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because its Domain attribute was invalid with regards to the current host url."},"core/sdk/NetworkRequest.ts | blockedReasonInvalidPrefix":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it used the \"__Secure-\" or \"__Host-\" prefix in its name and broke the additional rules applied to cookies with these prefixes as defined in https://tools.ietf.org/html/draft-west-cookie-prefixes-05."},"core/sdk/NetworkRequest.ts | blockedReasonOverwriteSecure":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it was not sent over a secure connection and would have overwritten a cookie with the Secure attribute."},"core/sdk/NetworkRequest.ts | blockedReasonSameSiteNoneInsecure":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"SameSite=None\" attribute but did not have the \"Secure\" attribute, which is required in order to use \"SameSite=None\"."},"core/sdk/NetworkRequest.ts | blockedReasonSameSiteStrictLax":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"{PH1}\" attribute but came from a cross-site response which was not the response to a top-level navigation."},"core/sdk/NetworkRequest.ts | blockedReasonSameSiteUnspecifiedTreatedAsLax":{"message":"This Set-Cookie header didn't specify a \"SameSite\" attribute and was defaulted to \"SameSite=Lax,\" and was blocked because it came from a cross-site response which was not the response to a top-level navigation. The Set-Cookie had to have been set with \"SameSite=None\" to enable cross-site usage."},"core/sdk/NetworkRequest.ts | blockedReasonSecureOnly":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"Secure\" attribute but was not received over a secure connection."},"core/sdk/NetworkRequest.ts | domainMismatch":{"message":"This cookie was blocked because neither did the request URL's domain exactly match the cookie's domain, nor was the request URL's domain a subdomain of the cookie's Domain attribute value."},"core/sdk/NetworkRequest.ts | exemptionReasonCorsOptIn":{"message":"This cookie is allowed by CORS opt-in. Learn more: goo.gle/cors"},"core/sdk/NetworkRequest.ts | exemptionReasonEnterprisePolicy":{"message":"This cookie is allowed by Chrome Enterprise policy. Learn more: goo.gle/ce-3pc"},"core/sdk/NetworkRequest.ts | exemptionReasonStorageAccessAPI":{"message":"This cookie is allowed by the Storage Access API. Learn more: goo.gle/saa"},"core/sdk/NetworkRequest.ts | exemptionReasonTopLevelStorageAccessAPI":{"message":"This cookie is allowed by the top-level Storage Access API. Learn more: goo.gle/saa-top"},"core/sdk/NetworkRequest.ts | exemptionReasonTPCDDeprecationTrial":{"message":"This cookie is allowed by third-party cookie phaseout deprecation trial."},"core/sdk/NetworkRequest.ts | exemptionReasonTPCDHeuristics":{"message":"This cookie is allowed by third-party cookie phaseout heuristics. Learn more: goo.gle/hbe"},"core/sdk/NetworkRequest.ts | exemptionReasonTPCDMetadata":{"message":"This cookie is allowed by a third-party cookie deprecation trial grace period. Learn more: goo.gle/ps-dt."},"core/sdk/NetworkRequest.ts | exemptionReasonUserSetting":{"message":"This cookie is allowed by user preference."},"core/sdk/NetworkRequest.ts | nameValuePairExceedsMaxSize":{"message":"This cookie was blocked because it was too large. The combined size of the name and value must be less than or equal to 4096 characters."},"core/sdk/NetworkRequest.ts | notOnPath":{"message":"This cookie was blocked because its path was not an exact match for or a superdirectory of the request url's path."},"core/sdk/NetworkRequest.ts | samePartyFromCrossPartyContext":{"message":"This cookie was blocked because it had the \"SameParty\" attribute but the request was cross-party. The request was considered cross-party because the domain of the resource's URL and the domains of the resource's enclosing frames/documents are neither owners nor members in the same First-Party Set."},"core/sdk/NetworkRequest.ts | sameSiteLax":{"message":"This cookie was blocked because it had the \"SameSite=Lax\" attribute and the request was made from a different site and was not initiated by a top-level navigation."},"core/sdk/NetworkRequest.ts | sameSiteNoneInsecure":{"message":"This cookie was blocked because it had the \"SameSite=None\" attribute but was not marked \"Secure\". Cookies without SameSite restrictions must be marked \"Secure\" and sent over a secure connection."},"core/sdk/NetworkRequest.ts | sameSiteStrict":{"message":"This cookie was blocked because it had the \"SameSite=Strict\" attribute and the request was made from a different site. This includes top-level navigation requests initiated by other sites."},"core/sdk/NetworkRequest.ts | sameSiteUnspecifiedTreatedAsLax":{"message":"This cookie didn't specify a \"SameSite\" attribute when it was stored and was defaulted to \"SameSite=Lax,\" and was blocked because the request was made from a different site and was not initiated by a top-level navigation. The cookie had to have been set with \"SameSite=None\" to enable cross-site usage."},"core/sdk/NetworkRequest.ts | schemefulSameSiteLax":{"message":"This cookie was blocked because it had the \"SameSite=Lax\" attribute but the request was cross-site and was not initiated by a top-level navigation. This request is considered cross-site because the URL has a different scheme than the current site."},"core/sdk/NetworkRequest.ts | schemefulSameSiteStrict":{"message":"This cookie was blocked because it had the \"SameSite=Strict\" attribute but the request was cross-site. This includes top-level navigation requests initiated by other sites. This request is considered cross-site because the URL has a different scheme than the current site."},"core/sdk/NetworkRequest.ts | schemefulSameSiteUnspecifiedTreatedAsLax":{"message":"This cookie didn't specify a \"SameSite\" attribute when it was stored, was defaulted to \"SameSite=Lax\", and was blocked because the request was cross-site and was not initiated by a top-level navigation. This request is considered cross-site because the URL has a different scheme than the current site."},"core/sdk/NetworkRequest.ts | secureOnly":{"message":"This cookie was blocked because it had the \"Secure\" attribute and the connection was not secure."},"core/sdk/NetworkRequest.ts | setcookieHeaderIsIgnoredIn":{"message":"Set-Cookie header is ignored in response from url: {PH1}. The combined size of the name and value must be less than or equal to 4096 characters."},"core/sdk/NetworkRequest.ts | theSchemeOfThisConnectionIsNot":{"message":"The scheme of this connection is not allowed to store cookies."},"core/sdk/NetworkRequest.ts | thirdPartyPhaseout":{"message":"This cookie was blocked due to third-party cookie phaseout. Learn more in the Issues tab."},"core/sdk/NetworkRequest.ts | thisSetcookieDidntSpecifyASamesite":{"message":"This Set-Cookie header didn't specify a \"SameSite\" attribute, was defaulted to \"SameSite=Lax\", and was blocked because it came from a cross-site response which was not the response to a top-level navigation. This response is considered cross-site because the URL has a different scheme than the current site."},"core/sdk/NetworkRequest.ts | thisSetcookieHadADisallowedCharacter":{"message":"This Set-Cookie header contained a disallowed character (a forbidden ASCII control character, or the tab character if it appears in the middle of the cookie name, value, an attribute name, or an attribute value)."},"core/sdk/NetworkRequest.ts | thisSetcookieHadInvalidSyntax":{"message":"This Set-Cookie header had invalid syntax."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedBecauseItHadTheSameparty":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"SameParty\" attribute but the request was cross-party. The request was considered cross-party because the domain of the resource's URL and the domains of the resource's enclosing frames/documents are neither owners nor members in the same First-Party Set."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedBecauseItHadTheSamepartyAttribute":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"SameParty\" attribute but also had other conflicting attributes. Chrome requires cookies that use the \"SameParty\" attribute to also have the \"Secure\" attribute, and to not be restricted to \"SameSite=Strict\"."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedBecauseItHadTheSamesiteStrictLax":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because it had the \"{PH1}\" attribute but came from a cross-site response which was not the response to a top-level navigation. This response is considered cross-site because the URL has a different scheme than the current site."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedBecauseTheNameValuePairExceedsMaxSize":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked because the cookie was too large. The combined size of the name and value must be less than or equal to 4096 characters."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedDueThirdPartyPhaseout":{"message":"Setting this cookie was blocked due to third-party cookie phaseout. Learn more in the Issues tab."},"core/sdk/NetworkRequest.ts | thisSetcookieWasBlockedDueToUser":{"message":"This attempt to set a cookie via a Set-Cookie header was blocked due to user preferences."},"core/sdk/NetworkRequest.ts | unknownError":{"message":"An unknown error was encountered when trying to send this cookie."},"core/sdk/NetworkRequest.ts | userPreferences":{"message":"This cookie was blocked due to user preferences."},"core/sdk/OverlayModel.ts | pausedInDebugger":{"message":"Paused in debugger"},"core/sdk/PageResourceLoader.ts | loadCanceledDueToReloadOf":{"message":"Load canceled due to reload of inspected page"},"core/sdk/Script.ts | scriptRemovedOrDeleted":{"message":"Script removed or deleted."},"core/sdk/Script.ts | unableToFetchScriptSource":{"message":"Unable to fetch script source."},"core/sdk/sdk-meta.ts | achromatopsia":{"message":"Achromatopsia (no color)"},"core/sdk/sdk-meta.ts | blurredVision":{"message":"Blurred vision"},"core/sdk/sdk-meta.ts | captureAsyncStackTraces":{"message":"Capture async stack traces"},"core/sdk/sdk-meta.ts | customFormatters":{"message":"Custom formatters"},"core/sdk/sdk-meta.ts | deuteranopia":{"message":"Deuteranopia (no green)"},"core/sdk/sdk-meta.ts | disableAsyncStackTraces":{"message":"Disable async stack traces"},"core/sdk/sdk-meta.ts | disableAvifFormat":{"message":"Disable AVIF format"},"core/sdk/sdk-meta.ts | disableCache":{"message":"Disable cache (while DevTools is open)"},"core/sdk/sdk-meta.ts | disableJavascript":{"message":"Disable JavaScript"},"core/sdk/sdk-meta.ts | disableLocalFonts":{"message":"Disable local fonts"},"core/sdk/sdk-meta.ts | disableNetworkRequestBlocking":{"message":"Disable network request blocking"},"core/sdk/sdk-meta.ts | disableWebpFormat":{"message":"Disable WebP format"},"core/sdk/sdk-meta.ts | doNotCaptureAsyncStackTraces":{"message":"Do not capture async stack traces"},"core/sdk/sdk-meta.ts | doNotEmulateAFocusedPage":{"message":"Do not emulate a focused page"},"core/sdk/sdk-meta.ts | doNotEmulateAnyVisionDeficiency":{"message":"Do not emulate any vision deficiency"},"core/sdk/sdk-meta.ts | doNotEmulateCss":{"message":"Do not emulate CSS {PH1}"},"core/sdk/sdk-meta.ts | doNotEmulateCssMediaType":{"message":"Do not emulate CSS media type"},"core/sdk/sdk-meta.ts | doNotExtendGridLines":{"message":"Do not extend grid lines"},"core/sdk/sdk-meta.ts | doNotHighlightAdFrames":{"message":"Do not highlight ad frames"},"core/sdk/sdk-meta.ts | doNotPauseOnExceptions":{"message":"Do not pause on exceptions"},"core/sdk/sdk-meta.ts | doNotPreserveLogUponNavigation":{"message":"Do not preserve log upon navigation"},"core/sdk/sdk-meta.ts | doNotShowGridNamedAreas":{"message":"Do not show grid named areas"},"core/sdk/sdk-meta.ts | doNotShowGridTrackSizes":{"message":"Do not show grid track sizes"},"core/sdk/sdk-meta.ts | doNotShowRulersOnHover":{"message":"Do not show rulers on hover"},"core/sdk/sdk-meta.ts | emulateAchromatopsia":{"message":"Emulate achromatopsia (no color)"},"core/sdk/sdk-meta.ts | emulateAFocusedPage":{"message":"Emulate a focused page"},"core/sdk/sdk-meta.ts | emulateAutoDarkMode":{"message":"Emulate auto dark mode"},"core/sdk/sdk-meta.ts | emulateBlurredVision":{"message":"Emulate blurred vision"},"core/sdk/sdk-meta.ts | emulateCss":{"message":"Emulate CSS {PH1}"},"core/sdk/sdk-meta.ts | emulateCssMediaFeature":{"message":"Emulate CSS media feature {PH1}"},"core/sdk/sdk-meta.ts | emulateCssMediaType":{"message":"Emulate CSS media type"},"core/sdk/sdk-meta.ts | emulateCssPrintMediaType":{"message":"Emulate CSS print media type"},"core/sdk/sdk-meta.ts | emulateCssScreenMediaType":{"message":"Emulate CSS screen media type"},"core/sdk/sdk-meta.ts | emulateDeuteranopia":{"message":"Emulate deuteranopia (no green)"},"core/sdk/sdk-meta.ts | emulateProtanopia":{"message":"Emulate protanopia (no red)"},"core/sdk/sdk-meta.ts | emulateReducedContrast":{"message":"Emulate reduced contrast"},"core/sdk/sdk-meta.ts | emulateTritanopia":{"message":"Emulate tritanopia (no blue)"},"core/sdk/sdk-meta.ts | emulateVisionDeficiencies":{"message":"Emulate vision deficiencies"},"core/sdk/sdk-meta.ts | enableAvifFormat":{"message":"Enable AVIF format"},"core/sdk/sdk-meta.ts | enableCache":{"message":"Enable cache"},"core/sdk/sdk-meta.ts | enableJavascript":{"message":"Enable JavaScript"},"core/sdk/sdk-meta.ts | enableLocalFonts":{"message":"Enable local fonts"},"core/sdk/sdk-meta.ts | enableNetworkRequestBlocking":{"message":"Enable network request blocking"},"core/sdk/sdk-meta.ts | enableRemoteFileLoading":{"message":"Allow DevTools to load resources, such as source maps, from remote file paths. Disabled by default for security reasons."},"core/sdk/sdk-meta.ts | enableWebpFormat":{"message":"Enable WebP format"},"core/sdk/sdk-meta.ts | extendGridLines":{"message":"Extend grid lines"},"core/sdk/sdk-meta.ts | hideCoreWebVitalsOverlay":{"message":"Hide Core Web Vitals overlay"},"core/sdk/sdk-meta.ts | hideFramesPerSecondFpsMeter":{"message":"Hide frames per second (FPS) meter"},"core/sdk/sdk-meta.ts | hideLayerBorders":{"message":"Hide layer borders"},"core/sdk/sdk-meta.ts | hideLayoutShiftRegions":{"message":"Hide layout shift regions"},"core/sdk/sdk-meta.ts | hideLineLabels":{"message":"Hide line labels"},"core/sdk/sdk-meta.ts | hidePaintFlashingRectangles":{"message":"Hide paint flashing rectangles"},"core/sdk/sdk-meta.ts | hideScrollPerformanceBottlenecks":{"message":"Hide scroll performance bottlenecks"},"core/sdk/sdk-meta.ts | highlightAdFrames":{"message":"Highlight ad frames"},"core/sdk/sdk-meta.ts | networkRequestBlocking":{"message":"Network request blocking"},"core/sdk/sdk-meta.ts | noEmulation":{"message":"No emulation"},"core/sdk/sdk-meta.ts | pauseOnExceptions":{"message":"Pause on exceptions"},"core/sdk/sdk-meta.ts | preserveLogUponNavigation":{"message":"Preserve log upon navigation"},"core/sdk/sdk-meta.ts | print":{"message":"print"},"core/sdk/sdk-meta.ts | protanopia":{"message":"Protanopia (no red)"},"core/sdk/sdk-meta.ts | query":{"message":"query"},"core/sdk/sdk-meta.ts | reducedContrast":{"message":"Reduced contrast"},"core/sdk/sdk-meta.ts | screen":{"message":"screen"},"core/sdk/sdk-meta.ts | showAreaNames":{"message":"Show area names"},"core/sdk/sdk-meta.ts | showCoreWebVitalsOverlay":{"message":"Show Core Web Vitals overlay"},"core/sdk/sdk-meta.ts | showFramesPerSecondFpsMeter":{"message":"Show frames per second (FPS) meter"},"core/sdk/sdk-meta.ts | showGridNamedAreas":{"message":"Show grid named areas"},"core/sdk/sdk-meta.ts | showGridTrackSizes":{"message":"Show grid track sizes"},"core/sdk/sdk-meta.ts | showLayerBorders":{"message":"Show layer borders"},"core/sdk/sdk-meta.ts | showLayoutShiftRegions":{"message":"Show layout shift regions"},"core/sdk/sdk-meta.ts | showLineLabels":{"message":"Show line labels"},"core/sdk/sdk-meta.ts | showLineNames":{"message":"Show line names"},"core/sdk/sdk-meta.ts | showLineNumbers":{"message":"Show line numbers"},"core/sdk/sdk-meta.ts | showPaintFlashingRectangles":{"message":"Show paint flashing rectangles"},"core/sdk/sdk-meta.ts | showRulersOnHover":{"message":"Show rulers on hover"},"core/sdk/sdk-meta.ts | showScrollPerformanceBottlenecks":{"message":"Show scroll performance bottlenecks"},"core/sdk/sdk-meta.ts | showTrackSizes":{"message":"Show track sizes"},"core/sdk/sdk-meta.ts | tritanopia":{"message":"Tritanopia (no blue)"},"core/sdk/ServerTiming.ts | deprecatedSyntaxFoundPleaseUse":{"message":"Deprecated syntax found. Please use: ;dur=;desc="},"core/sdk/ServerTiming.ts | duplicateParameterSIgnored":{"message":"Duplicate parameter \"{PH1}\" ignored."},"core/sdk/ServerTiming.ts | extraneousTrailingCharacters":{"message":"Extraneous trailing characters."},"core/sdk/ServerTiming.ts | noValueFoundForParameterS":{"message":"No value found for parameter \"{PH1}\"."},"core/sdk/ServerTiming.ts | unableToParseSValueS":{"message":"Unable to parse \"{PH1}\" value \"{PH2}\"."},"core/sdk/ServerTiming.ts | unrecognizedParameterS":{"message":"Unrecognized parameter \"{PH1}\"."},"core/sdk/ServiceWorkerCacheModel.ts | serviceworkercacheagentError":{"message":"ServiceWorkerCacheAgent error deleting cache entry {PH1} in cache: {PH2}"},"core/sdk/ServiceWorkerManager.ts | activated":{"message":"activated"},"core/sdk/ServiceWorkerManager.ts | activating":{"message":"activating"},"core/sdk/ServiceWorkerManager.ts | installed":{"message":"installed"},"core/sdk/ServiceWorkerManager.ts | installing":{"message":"installing"},"core/sdk/ServiceWorkerManager.ts | new":{"message":"new"},"core/sdk/ServiceWorkerManager.ts | redundant":{"message":"redundant"},"core/sdk/ServiceWorkerManager.ts | running":{"message":"running"},"core/sdk/ServiceWorkerManager.ts | sSS":{"message":"{PH1} #{PH2} ({PH3})"},"core/sdk/ServiceWorkerManager.ts | starting":{"message":"starting"},"core/sdk/ServiceWorkerManager.ts | stopped":{"message":"stopped"},"core/sdk/ServiceWorkerManager.ts | stopping":{"message":"stopping"},"entrypoints/inspector_main/inspector_main-meta.ts | autoOpenDevTools":{"message":"Auto-open DevTools for popups"},"entrypoints/inspector_main/inspector_main-meta.ts | blockAds":{"message":"Block ads on this site"},"entrypoints/inspector_main/inspector_main-meta.ts | colorVisionDeficiency":{"message":"color vision deficiency"},"entrypoints/inspector_main/inspector_main-meta.ts | cssMediaFeature":{"message":"CSS media feature"},"entrypoints/inspector_main/inspector_main-meta.ts | cssMediaType":{"message":"CSS media type"},"entrypoints/inspector_main/inspector_main-meta.ts | disablePaused":{"message":"Disable paused state overlay"},"entrypoints/inspector_main/inspector_main-meta.ts | doNotAutoOpen":{"message":"Do not auto-open DevTools for popups"},"entrypoints/inspector_main/inspector_main-meta.ts | forceAdBlocking":{"message":"Force ad blocking on this site"},"entrypoints/inspector_main/inspector_main-meta.ts | fps":{"message":"fps"},"entrypoints/inspector_main/inspector_main-meta.ts | hardReloadPage":{"message":"Hard reload page"},"entrypoints/inspector_main/inspector_main-meta.ts | layout":{"message":"layout"},"entrypoints/inspector_main/inspector_main-meta.ts | paint":{"message":"paint"},"entrypoints/inspector_main/inspector_main-meta.ts | reloadPage":{"message":"Reload page"},"entrypoints/inspector_main/inspector_main-meta.ts | rendering":{"message":"Rendering"},"entrypoints/inspector_main/inspector_main-meta.ts | showAds":{"message":"Show ads on this site, if allowed"},"entrypoints/inspector_main/inspector_main-meta.ts | showRendering":{"message":"Show Rendering"},"entrypoints/inspector_main/inspector_main-meta.ts | toggleCssPrefersColorSchemeMedia":{"message":"Toggle CSS media feature prefers-color-scheme"},"entrypoints/inspector_main/inspector_main-meta.ts | visionDeficiency":{"message":"vision deficiency"},"entrypoints/inspector_main/InspectorMain.ts | javascriptIsDisabled":{"message":"JavaScript is disabled"},"entrypoints/inspector_main/InspectorMain.ts | main":{"message":"Main"},"entrypoints/inspector_main/InspectorMain.ts | openDedicatedTools":{"message":"Open dedicated DevTools for Node.js"},"entrypoints/inspector_main/InspectorMain.ts | tab":{"message":"Tab"},"entrypoints/inspector_main/OutermostTargetSelector.ts | targetNotSelected":{"message":"Page: Not selected"},"entrypoints/inspector_main/OutermostTargetSelector.ts | targetS":{"message":"Page: {PH1}"},"entrypoints/inspector_main/RenderingOptions.ts | coreWebVitals":{"message":"Core Web Vitals"},"entrypoints/inspector_main/RenderingOptions.ts | disableAvifImageFormat":{"message":"Disable AVIF image format"},"entrypoints/inspector_main/RenderingOptions.ts | disableLocalFonts":{"message":"Disable local fonts"},"entrypoints/inspector_main/RenderingOptions.ts | disablesLocalSourcesInFontface":{"message":"Disables local() sources in @font-face rules. Requires a page reload to apply."},"entrypoints/inspector_main/RenderingOptions.ts | disableWebpImageFormat":{"message":"Disable WebP image format"},"entrypoints/inspector_main/RenderingOptions.ts | emulateAFocusedPage":{"message":"Emulate a focused page"},"entrypoints/inspector_main/RenderingOptions.ts | emulateAutoDarkMode":{"message":"Enable automatic dark mode"},"entrypoints/inspector_main/RenderingOptions.ts | emulatesAFocusedPage":{"message":"Keep page focused. Commonly used for debugging disappearing elements."},"entrypoints/inspector_main/RenderingOptions.ts | emulatesAutoDarkMode":{"message":"Enables automatic dark mode and sets prefers-color-scheme to dark."},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssColorgamutMediaFeature":{"message":"Forces CSS color-gamut media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssForcedColors":{"message":"Forces CSS forced-colors media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssPreferscolorschemeMedia":{"message":"Forces CSS prefers-color-scheme media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssPreferscontrastMedia":{"message":"Forces CSS prefers-contrast media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssPrefersreduceddataMedia":{"message":"Forces CSS prefers-reduced-data media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssPrefersreducedmotion":{"message":"Forces CSS prefers-reduced-motion media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesCssPrefersreducedtransparencyMedia":{"message":"Forces CSS prefers-reduced-transparency media feature"},"entrypoints/inspector_main/RenderingOptions.ts | forcesMediaTypeForTestingPrint":{"message":"Forces media type for testing print and screen styles"},"entrypoints/inspector_main/RenderingOptions.ts | forcesVisionDeficiencyEmulation":{"message":"Forces vision deficiency emulation"},"entrypoints/inspector_main/RenderingOptions.ts | frameRenderingStats":{"message":"Frame Rendering Stats"},"entrypoints/inspector_main/RenderingOptions.ts | highlightAdFrames":{"message":"Highlight ad frames"},"entrypoints/inspector_main/RenderingOptions.ts | highlightsAreasOfThePageBlueThat":{"message":"Highlights areas of the page (blue) that were shifted. May not be suitable for people prone to photosensitive epilepsy."},"entrypoints/inspector_main/RenderingOptions.ts | highlightsAreasOfThePageGreen":{"message":"Highlights areas of the page (green) that need to be repainted. May not be suitable for people prone to photosensitive epilepsy."},"entrypoints/inspector_main/RenderingOptions.ts | highlightsElementsTealThatCan":{"message":"Highlights elements (teal) that can slow down scrolling, including touch & wheel event handlers and other main-thread scrolling situations."},"entrypoints/inspector_main/RenderingOptions.ts | highlightsFramesRedDetectedToBe":{"message":"Highlights frames (red) detected to be ads."},"entrypoints/inspector_main/RenderingOptions.ts | layerBorders":{"message":"Layer borders"},"entrypoints/inspector_main/RenderingOptions.ts | layoutShiftRegions":{"message":"Layout Shift Regions"},"entrypoints/inspector_main/RenderingOptions.ts | paintFlashing":{"message":"Paint flashing"},"entrypoints/inspector_main/RenderingOptions.ts | plotsFrameThroughputDropped":{"message":"Plots frame throughput, dropped frames distribution, and GPU memory."},"entrypoints/inspector_main/RenderingOptions.ts | requiresAPageReloadToApplyAnd":{"message":"Requires a page reload to apply and disables caching for image requests."},"entrypoints/inspector_main/RenderingOptions.ts | scrollingPerformanceIssues":{"message":"Scrolling performance issues"},"entrypoints/inspector_main/RenderingOptions.ts | showsAnOverlayWithCoreWebVitals":{"message":"Shows an overlay with Core Web Vitals."},"entrypoints/inspector_main/RenderingOptions.ts | showsLayerBordersOrangeoliveAnd":{"message":"Shows layer borders (orange/olive) and tiles (cyan)."},"entrypoints/js_app/js_app.ts | main":{"message":"Main"},"entrypoints/js_app/js_app.ts | networkTitle":{"message":"Scripts"},"entrypoints/js_app/js_app.ts | showNode":{"message":"Show Scripts"},"entrypoints/main/main-meta.ts | auto":{"message":"auto"},"entrypoints/main/main-meta.ts | bottom":{"message":"Bottom"},"entrypoints/main/main-meta.ts | browserLanguage":{"message":"Browser UI language"},"entrypoints/main/main-meta.ts | cancelSearch":{"message":"Cancel search"},"entrypoints/main/main-meta.ts | darkCapital":{"message":"Dark"},"entrypoints/main/main-meta.ts | darkLower":{"message":"dark"},"entrypoints/main/main-meta.ts | devtoolsDefault":{"message":"DevTools (Default)"},"entrypoints/main/main-meta.ts | dockToBottom":{"message":"Dock to bottom"},"entrypoints/main/main-meta.ts | dockToLeft":{"message":"Dock to left"},"entrypoints/main/main-meta.ts | dockToRight":{"message":"Dock to right"},"entrypoints/main/main-meta.ts | enableCtrlShortcutToSwitchPanels":{"message":"Enable Ctrl + 1-9 shortcut to switch panels"},"entrypoints/main/main-meta.ts | enableShortcutToSwitchPanels":{"message":"Enable ⌘ + 1-9 shortcut to switch panels"},"entrypoints/main/main-meta.ts | enableSync":{"message":"Enable settings sync"},"entrypoints/main/main-meta.ts | findNextResult":{"message":"Find next result"},"entrypoints/main/main-meta.ts | findPreviousResult":{"message":"Find previous result"},"entrypoints/main/main-meta.ts | focusDebuggee":{"message":"Focus page"},"entrypoints/main/main-meta.ts | horizontal":{"message":"horizontal"},"entrypoints/main/main-meta.ts | language":{"message":"Language:"},"entrypoints/main/main-meta.ts | left":{"message":"Left"},"entrypoints/main/main-meta.ts | lightCapital":{"message":"Light"},"entrypoints/main/main-meta.ts | lightLower":{"message":"light"},"entrypoints/main/main-meta.ts | nextPanel":{"message":"Next panel"},"entrypoints/main/main-meta.ts | panelLayout":{"message":"Panel layout:"},"entrypoints/main/main-meta.ts | previousPanel":{"message":"Previous panel"},"entrypoints/main/main-meta.ts | reloadDevtools":{"message":"Reload DevTools"},"entrypoints/main/main-meta.ts | resetZoomLevel":{"message":"Reset zoom level"},"entrypoints/main/main-meta.ts | restoreLastDockPosition":{"message":"Restore last dock position"},"entrypoints/main/main-meta.ts | right":{"message":"Right"},"entrypoints/main/main-meta.ts | searchAsYouTypeCommand":{"message":"Enable search as you type"},"entrypoints/main/main-meta.ts | searchAsYouTypeSetting":{"message":"Search as you type"},"entrypoints/main/main-meta.ts | searchInPanel":{"message":"Search in panel"},"entrypoints/main/main-meta.ts | searchOnEnterCommand":{"message":"Disable search as you type (press Enter to search)"},"entrypoints/main/main-meta.ts | switchToDarkTheme":{"message":"Switch to dark theme"},"entrypoints/main/main-meta.ts | switchToLightTheme":{"message":"Switch to light theme"},"entrypoints/main/main-meta.ts | switchToSystemPreferredColor":{"message":"Switch to system preferred color theme"},"entrypoints/main/main-meta.ts | systemPreference":{"message":"System preference"},"entrypoints/main/main-meta.ts | theme":{"message":"Theme:"},"entrypoints/main/main-meta.ts | toggleDrawer":{"message":"Toggle drawer"},"entrypoints/main/main-meta.ts | undocked":{"message":"Undocked"},"entrypoints/main/main-meta.ts | undockIntoSeparateWindow":{"message":"Undock into separate window"},"entrypoints/main/main-meta.ts | useAutomaticPanelLayout":{"message":"Use automatic panel layout"},"entrypoints/main/main-meta.ts | useHorizontalPanelLayout":{"message":"Use horizontal panel layout"},"entrypoints/main/main-meta.ts | useVerticalPanelLayout":{"message":"Use vertical panel layout"},"entrypoints/main/main-meta.ts | vertical":{"message":"vertical"},"entrypoints/main/main-meta.ts | zoomIn":{"message":"Zoom in"},"entrypoints/main/main-meta.ts | zoomOut":{"message":"Zoom out"},"entrypoints/main/MainImpl.ts | customizeAndControlDevtools":{"message":"Customize and control DevTools"},"entrypoints/main/MainImpl.ts | dockSide":{"message":"Dock side"},"entrypoints/main/MainImpl.ts | dockSideNaviation":{"message":"Use left and right arrow keys to navigate the options"},"entrypoints/main/MainImpl.ts | dockToBottom":{"message":"Dock to bottom"},"entrypoints/main/MainImpl.ts | dockToLeft":{"message":"Dock to left"},"entrypoints/main/MainImpl.ts | dockToRight":{"message":"Dock to right"},"entrypoints/main/MainImpl.ts | focusDebuggee":{"message":"Focus page"},"entrypoints/main/MainImpl.ts | help":{"message":"Help"},"entrypoints/main/MainImpl.ts | hideConsoleDrawer":{"message":"Hide console drawer"},"entrypoints/main/MainImpl.ts | moreTools":{"message":"More tools"},"entrypoints/main/MainImpl.ts | placementOfDevtoolsRelativeToThe":{"message":"Placement of DevTools relative to the page. ({PH1} to restore last position)"},"entrypoints/main/MainImpl.ts | showConsoleDrawer":{"message":"Show console drawer"},"entrypoints/main/MainImpl.ts | undockIntoSeparateWindow":{"message":"Undock into separate window"},"entrypoints/node_app/node_app.ts | connection":{"message":"Connection"},"entrypoints/node_app/node_app.ts | networkTitle":{"message":"Node"},"entrypoints/node_app/node_app.ts | node":{"message":"node"},"entrypoints/node_app/node_app.ts | showConnection":{"message":"Show Connection"},"entrypoints/node_app/node_app.ts | showNode":{"message":"Show Node"},"entrypoints/node_app/NodeConnectionsPanel.ts | addConnection":{"message":"Add connection"},"entrypoints/node_app/NodeConnectionsPanel.ts | networkAddressEgLocalhost":{"message":"Network address (e.g. localhost:9229)"},"entrypoints/node_app/NodeConnectionsPanel.ts | noConnectionsSpecified":{"message":"No connections specified"},"entrypoints/node_app/NodeConnectionsPanel.ts | nodejsDebuggingGuide":{"message":"Node.js debugging guide"},"entrypoints/node_app/NodeConnectionsPanel.ts | specifyNetworkEndpointAnd":{"message":"Specify network endpoint and DevTools will connect to it automatically. Read {PH1} to learn more."},"entrypoints/node_app/NodeMain.ts | main":{"message":"Main"},"entrypoints/node_app/NodeMain.ts | nodejsS":{"message":"Node.js: {PH1}"},"entrypoints/rn_fusebox/rn_fusebox.ts | networkTitle":{"message":"React Native"},"entrypoints/rn_fusebox/rn_fusebox.ts | sendFeedback":{"message":"[FB-only] Send feedback"},"entrypoints/rn_fusebox/rn_fusebox.ts | showReactNative":{"message":"Show React Native"},"entrypoints/rn_inspector/rn_inspector.ts | networkTitle":{"message":"React Native"},"entrypoints/rn_inspector/rn_inspector.ts | showReactNative":{"message":"Show React Native"},"entrypoints/worker_app/WorkerMain.ts | main":{"message":"Main"},"generated/Deprecation.ts | AuthorizationCoveredByWildcard":{"message":"Authorization will not be covered by the wildcard symbol (*) in CORS Access-Control-Allow-Headers handling."},"generated/Deprecation.ts | CanRequestURLHTTPContainingNewline":{"message":"Resource requests whose URLs contained both removed whitespace \\(n|r|t) characters and less-than characters (<) are blocked. Please remove newlines and encode less-than characters from places like element attribute values in order to load these resources."},"generated/Deprecation.ts | ChromeLoadTimesConnectionInfo":{"message":"chrome.loadTimes() is deprecated, instead use standardized API: Navigation Timing 2."},"generated/Deprecation.ts | ChromeLoadTimesFirstPaintAfterLoadTime":{"message":"chrome.loadTimes() is deprecated, instead use standardized API: Paint Timing."},"generated/Deprecation.ts | ChromeLoadTimesWasAlternateProtocolAvailable":{"message":"chrome.loadTimes() is deprecated, instead use standardized API: nextHopProtocol in Navigation Timing 2."},"generated/Deprecation.ts | CookieWithTruncatingChar":{"message":"Cookies containing a \\(0|r|n) character will be rejected instead of truncated."},"generated/Deprecation.ts | CrossOriginAccessBasedOnDocumentDomain":{"message":"Relaxing the same-origin policy by setting document.domain is deprecated, and will be disabled by default. This deprecation warning is for a cross-origin access that was enabled by setting document.domain."},"generated/Deprecation.ts | CrossOriginWindowAlert":{"message":"Triggering window.alert from cross origin iframes has been deprecated and will be removed in the future."},"generated/Deprecation.ts | CrossOriginWindowConfirm":{"message":"Triggering window.confirm from cross origin iframes has been deprecated and will be removed in the future."},"generated/Deprecation.ts | CSSCustomStateDeprecatedSyntax":{"message":":--customstatename is deprecated. Please use the :state(customstatename) syntax instead."},"generated/Deprecation.ts | CSSSelectorInternalMediaControlsOverlayCastButton":{"message":"The disableRemotePlayback attribute should be used in order to disable the default Cast integration instead of using -internal-media-controls-overlay-cast-button selector."},"generated/Deprecation.ts | CSSValueAppearanceNonStandard":{"message":"CSS appearance values inner-spin-button, media-slider, media-sliderthumb, media-volume-slider, media-volume-sliderthumb, push-button, searchfield-cancel-button, slider-horizontal, sliderthumb-horizontal, sliderthumb-vertical, square-button are not standardized and will be removed."},"generated/Deprecation.ts | CSSValueAppearanceSliderVertical":{"message":"CSS appearance value slider-vertical is not standardized and will be removed."},"generated/Deprecation.ts | DataUrlInSvgUse":{"message":"Support for data: URLs in SVGUseElement is deprecated and it will be removed in the future."},"generated/Deprecation.ts | DocumentDomainSettingWithoutOriginAgentClusterHeader":{"message":"Relaxing the same-origin policy by setting document.domain is deprecated, and will be disabled by default. To continue using this feature, please opt-out of origin-keyed agent clusters by sending an Origin-Agent-Cluster: ?0 header along with the HTTP response for the document and frames. See https://developer.chrome.com/blog/immutable-document-domain/ for more details."},"generated/Deprecation.ts | DOMMutationEvents":{"message":"DOM Mutation Events, including DOMSubtreeModified, DOMNodeInserted, DOMNodeRemoved, DOMNodeRemovedFromDocument, DOMNodeInsertedIntoDocument, and DOMCharacterDataModified are deprecated (https://w3c.github.io/uievents/#legacy-event-types) and will be removed. Please use MutationObserver instead."},"generated/Deprecation.ts | GeolocationInsecureOrigin":{"message":"getCurrentPosition() and watchPosition() no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details."},"generated/Deprecation.ts | GeolocationInsecureOriginDeprecatedNotRemoved":{"message":"getCurrentPosition() and watchPosition() are deprecated on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details."},"generated/Deprecation.ts | GetUserMediaInsecureOrigin":{"message":"getUserMedia() no longer works on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details."},"generated/Deprecation.ts | HostCandidateAttributeGetter":{"message":"RTCPeerConnectionIceErrorEvent.hostCandidate is deprecated. Please use RTCPeerConnectionIceErrorEvent.address or RTCPeerConnectionIceErrorEvent.port instead."},"generated/Deprecation.ts | IdentityInCanMakePaymentEvent":{"message":"The merchant origin and arbitrary data from the canmakepayment service worker event are deprecated and will be removed: topOrigin, paymentRequestOrigin, methodData, modifiers."},"generated/Deprecation.ts | InsecurePrivateNetworkSubresourceRequest":{"message":"The website requested a subresource from a network that it could only access because of its users' privileged network position. These requests expose non-public devices and servers to the internet, increasing the risk of a cross-site request forgery (CSRF) attack, and/or information leakage. To mitigate these risks, Chrome deprecates requests to non-public subresources when initiated from non-secure contexts, and will start blocking them."},"generated/Deprecation.ts | InterestGroupDailyUpdateUrl":{"message":"The dailyUpdateUrl field of InterestGroups passed to joinAdInterestGroup() has been renamed to updateUrl, to more accurately reflect its behavior."},"generated/Deprecation.ts | LocalCSSFileExtensionRejected":{"message":"CSS cannot be loaded from file: URLs unless they end in a .css file extension."},"generated/Deprecation.ts | MediaSourceAbortRemove":{"message":"Using SourceBuffer.abort() to abort remove()'s asynchronous range removal is deprecated due to specification change. Support will be removed in the future. You should listen to the updateend event instead. abort() is intended to only abort an asynchronous media append or reset parser state."},"generated/Deprecation.ts | MediaSourceDurationTruncatingBuffered":{"message":"Setting MediaSource.duration below the highest presentation timestamp of any buffered coded frames is deprecated due to specification change. Support for implicit removal of truncated buffered media will be removed in the future. You should instead perform explicit remove(newDuration, oldDuration) on all sourceBuffers, where newDuration < oldDuration."},"generated/Deprecation.ts | NoSysexWebMIDIWithoutPermission":{"message":"Web MIDI will ask a permission to use even if the sysex is not specified in the MIDIOptions."},"generated/Deprecation.ts | NotificationInsecureOrigin":{"message":"The Notification API may no longer be used from insecure origins. You should consider switching your application to a secure origin, such as HTTPS. See https://goo.gle/chrome-insecure-origins for more details."},"generated/Deprecation.ts | NotificationPermissionRequestedIframe":{"message":"Permission for the Notification API may no longer be requested from a cross-origin iframe. You should consider requesting permission from a top-level frame or opening a new window instead."},"generated/Deprecation.ts | ObsoleteCreateImageBitmapImageOrientationNone":{"message":"Option imageOrientation: 'none' in createImageBitmap is deprecated. Please use createImageBitmap with option {imageOrientation: 'from-image'} instead."},"generated/Deprecation.ts | ObsoleteWebRtcCipherSuite":{"message":"Your partner is negotiating an obsolete (D)TLS version. Please check with your partner to have this fixed."},"generated/Deprecation.ts | OverflowVisibleOnReplacedElement":{"message":"Specifying overflow: visible on img, video and canvas tags may cause them to produce visual content outside of the element bounds. See https://github.com/WICG/shared-element-transitions/blob/main/debugging_overflow_on_images.md."},"generated/Deprecation.ts | PaymentInstruments":{"message":"paymentManager.instruments is deprecated. Please use just-in-time install for payment handlers instead."},"generated/Deprecation.ts | PaymentRequestCSPViolation":{"message":"Your PaymentRequest call bypassed Content-Security-Policy (CSP) connect-src directive. This bypass is deprecated. Please add the payment method identifier from the PaymentRequest API (in supportedMethods field) to your CSP connect-src directive."},"generated/Deprecation.ts | PersistentQuotaType":{"message":"StorageType.persistent is deprecated. Please use standardized navigator.storage instead."},"generated/Deprecation.ts | PictureSourceSrc":{"message":" with a parent is invalid and therefore ignored. Please use instead."},"generated/Deprecation.ts | PrefixedCancelAnimationFrame":{"message":"webkitCancelAnimationFrame is vendor-specific. Please use the standard cancelAnimationFrame instead."},"generated/Deprecation.ts | PrefixedRequestAnimationFrame":{"message":"webkitRequestAnimationFrame is vendor-specific. Please use the standard requestAnimationFrame instead."},"generated/Deprecation.ts | PrefixedVideoDisplayingFullscreen":{"message":"HTMLVideoElement.webkitDisplayingFullscreen is deprecated. Please use Document.fullscreenElement instead."},"generated/Deprecation.ts | PrefixedVideoEnterFullscreen":{"message":"HTMLVideoElement.webkitEnterFullscreen() is deprecated. Please use Element.requestFullscreen() instead."},"generated/Deprecation.ts | PrefixedVideoEnterFullScreen":{"message":"HTMLVideoElement.webkitEnterFullScreen() is deprecated. Please use Element.requestFullscreen() instead."},"generated/Deprecation.ts | PrefixedVideoExitFullscreen":{"message":"HTMLVideoElement.webkitExitFullscreen() is deprecated. Please use Document.exitFullscreen() instead."},"generated/Deprecation.ts | PrefixedVideoExitFullScreen":{"message":"HTMLVideoElement.webkitExitFullScreen() is deprecated. Please use Document.exitFullscreen() instead."},"generated/Deprecation.ts | PrefixedVideoSupportsFullscreen":{"message":"HTMLVideoElement.webkitSupportsFullscreen is deprecated. Please use Document.fullscreenEnabled instead."},"generated/Deprecation.ts | PrivacySandboxExtensionsAPI":{"message":"We're deprecating the API chrome.privacy.websites.privacySandboxEnabled, though it will remain active for backward compatibility until release M113. Instead, please use chrome.privacy.websites.topicsEnabled, chrome.privacy.websites.fledgeEnabled and chrome.privacy.websites.adMeasurementEnabled. See https://developer.chrome.com/docs/extensions/reference/privacy/#property-websites-privacySandboxEnabled."},"generated/Deprecation.ts | RangeExpand":{"message":"Range.expand() is deprecated. Please use Selection.modify() instead."},"generated/Deprecation.ts | RequestedSubresourceWithEmbeddedCredentials":{"message":"Subresource requests whose URLs contain embedded credentials (e.g. https://user:pass@host/) are blocked."},"generated/Deprecation.ts | RTCConstraintEnableDtlsSrtpFalse":{"message":"The constraint DtlsSrtpKeyAgreement is removed. You have specified a false value for this constraint, which is interpreted as an attempt to use the removed SDES key negotiation method. This functionality is removed; use a service that supports DTLS key negotiation instead."},"generated/Deprecation.ts | RTCConstraintEnableDtlsSrtpTrue":{"message":"The constraint DtlsSrtpKeyAgreement is removed. You have specified a true value for this constraint, which had no effect, but you can remove this constraint for tidiness."},"generated/Deprecation.ts | RTCPeerConnectionGetStatsLegacyNonCompliant":{"message":"The callback-based getStats() is deprecated and will be removed. Use the spec-compliant getStats() instead."},"generated/Deprecation.ts | RtcpMuxPolicyNegotiate":{"message":"The rtcpMuxPolicy option is deprecated and will be removed."},"generated/Deprecation.ts | SharedArrayBufferConstructedWithoutIsolation":{"message":"SharedArrayBuffer will require cross-origin isolation. See https://developer.chrome.com/blog/enabling-shared-array-buffer/ for more details."},"generated/Deprecation.ts | TextToSpeech_DisallowedByAutoplay":{"message":"speechSynthesis.speak() without user activation is deprecated and will be removed."},"generated/Deprecation.ts | UnloadHandler":{"message":"Unload event listeners are deprecated and will be removed."},"generated/Deprecation.ts | V8SharedArrayBufferConstructedInExtensionWithoutIsolation":{"message":"Extensions should opt into cross-origin isolation to continue using SharedArrayBuffer. See https://developer.chrome.com/docs/extensions/mv3/cross-origin-isolation/."},"generated/Deprecation.ts | WebSQL":{"message":"Web SQL is deprecated. Please use SQLite WebAssembly or Indexed Database"},"generated/Deprecation.ts | WindowPlacementPermissionDescriptorUsed":{"message":"The permission descriptor window-placement is deprecated. Use window-management instead. For more help, check https://bit.ly/window-placement-rename."},"generated/Deprecation.ts | WindowPlacementPermissionPolicyParsed":{"message":"The permission policy window-placement is deprecated. Use window-management instead. For more help, check https://bit.ly/window-placement-rename."},"generated/Deprecation.ts | XHRJSONEncodingDetection":{"message":"UTF-16 is not supported by response json in XMLHttpRequest"},"generated/Deprecation.ts | XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload":{"message":"Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/."},"generated/Deprecation.ts | XRSupportsSession":{"message":"supportsSession() is deprecated. Please use isSessionSupported() and check the resolved boolean value instead."},"models/bindings/ContentProviderBasedProject.ts | unknownErrorLoadingFile":{"message":"Unknown error loading file"},"models/bindings/DebuggerLanguagePlugins.ts | debugSymbolsIncomplete":{"message":"The debug information for function {PH1} is incomplete"},"models/bindings/DebuggerLanguagePlugins.ts | errorInDebuggerLanguagePlugin":{"message":"Error in debugger language plugin: {PH1}"},"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsFor":{"message":"[{PH1}] Failed to load debug symbols for {PH2} ({PH3})"},"models/bindings/DebuggerLanguagePlugins.ts | failedToLoadDebugSymbolsForFunction":{"message":"No debug information for function \"{PH1}\""},"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForButDidnt":{"message":"[{PH1}] Loaded debug symbols for {PH2}, but didn't find any source files"},"models/bindings/DebuggerLanguagePlugins.ts | loadedDebugSymbolsForFound":{"message":"[{PH1}] Loaded debug symbols for {PH2}, found {PH3} source file(s)"},"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsFor":{"message":"[{PH1}] Loading debug symbols for {PH2}..."},"models/bindings/DebuggerLanguagePlugins.ts | loadingDebugSymbolsForVia":{"message":"[{PH1}] Loading debug symbols for {PH2} (via {PH3})..."},"models/bindings/IgnoreListManager.ts | addAllContentScriptsToIgnoreList":{"message":"Add all extension scripts to ignore list"},"models/bindings/IgnoreListManager.ts | addAllThirdPartyScriptsToIgnoreList":{"message":"Add all third-party scripts to ignore list"},"models/bindings/IgnoreListManager.ts | addDirectoryToIgnoreList":{"message":"Add directory to ignore list"},"models/bindings/IgnoreListManager.ts | addScriptToIgnoreList":{"message":"Add script to ignore list"},"models/bindings/IgnoreListManager.ts | removeFromIgnoreList":{"message":"Remove from ignore list"},"models/bindings/ResourceScriptMapping.ts | liveEditCompileFailed":{"message":"LiveEdit compile failed: {PH1}"},"models/bindings/ResourceScriptMapping.ts | liveEditFailed":{"message":"LiveEdit failed: {PH1}"},"models/emulation/DeviceModeModel.ts | devicePixelRatioMustBeANumberOr":{"message":"Device pixel ratio must be a number or blank."},"models/emulation/DeviceModeModel.ts | devicePixelRatioMustBeGreater":{"message":"Device pixel ratio must be greater than or equal to {PH1}."},"models/emulation/DeviceModeModel.ts | devicePixelRatioMustBeLessThanOr":{"message":"Device pixel ratio must be less than or equal to {PH1}."},"models/emulation/DeviceModeModel.ts | heightCannotBeEmpty":{"message":"Height cannot be empty."},"models/emulation/DeviceModeModel.ts | heightMustBeANumber":{"message":"Height must be a number."},"models/emulation/DeviceModeModel.ts | heightMustBeGreaterThanOrEqualTo":{"message":"Height must be greater than or equal to {PH1}."},"models/emulation/DeviceModeModel.ts | heightMustBeLessThanOrEqualToS":{"message":"Height must be less than or equal to {PH1}."},"models/emulation/DeviceModeModel.ts | widthCannotBeEmpty":{"message":"Width cannot be empty."},"models/emulation/DeviceModeModel.ts | widthMustBeANumber":{"message":"Width must be a number."},"models/emulation/DeviceModeModel.ts | widthMustBeGreaterThanOrEqualToS":{"message":"Width must be greater than or equal to {PH1}."},"models/emulation/DeviceModeModel.ts | widthMustBeLessThanOrEqualToS":{"message":"Width must be less than or equal to {PH1}."},"models/emulation/EmulatedDevices.ts | laptopWithHiDPIScreen":{"message":"Laptop with HiDPI screen"},"models/emulation/EmulatedDevices.ts | laptopWithMDPIScreen":{"message":"Laptop with MDPI screen"},"models/emulation/EmulatedDevices.ts | laptopWithTouch":{"message":"Laptop with touch"},"models/har/Writer.ts | collectingContent":{"message":"Collecting content…"},"models/har/Writer.ts | writingFile":{"message":"Writing file…"},"models/issues_manager/BounceTrackingIssue.ts | bounceTrackingMitigations":{"message":"Bounce tracking mitigations"},"models/issues_manager/ClientHintIssue.ts | clientHintsInfrastructure":{"message":"Client Hints Infrastructure"},"models/issues_manager/ContentSecurityPolicyIssue.ts | contentSecurityPolicyEval":{"message":"Content Security Policy - Eval"},"models/issues_manager/ContentSecurityPolicyIssue.ts | contentSecurityPolicyInlineCode":{"message":"Content Security Policy - Inline Code"},"models/issues_manager/ContentSecurityPolicyIssue.ts | contentSecurityPolicySource":{"message":"Content Security Policy - Source Allowlists"},"models/issues_manager/ContentSecurityPolicyIssue.ts | trustedTypesFixViolations":{"message":"Trusted Types - Fix violations"},"models/issues_manager/ContentSecurityPolicyIssue.ts | trustedTypesPolicyViolation":{"message":"Trusted Types - Policy violation"},"models/issues_manager/CookieDeprecationMetadataIssue.ts | thirdPartyPhaseoutExplained":{"message":"Prepare for phasing out third-party cookies"},"models/issues_manager/CookieIssue.ts | anInsecure":{"message":"an insecure"},"models/issues_manager/CookieIssue.ts | aSecure":{"message":"a secure"},"models/issues_manager/CookieIssue.ts | fileCrosSiteRedirectBug":{"message":"File a bug"},"models/issues_manager/CookieIssue.ts | firstPartySetsExplained":{"message":"First-Party Sets and the SameParty attribute"},"models/issues_manager/CookieIssue.ts | howSchemefulSamesiteWorks":{"message":"How Schemeful Same-Site Works"},"models/issues_manager/CookieIssue.ts | samesiteCookiesExplained":{"message":"SameSite cookies explained"},"models/issues_manager/CookieIssue.ts | thirdPartyPhaseoutExplained":{"message":"Prepare for phasing out third-party cookies"},"models/issues_manager/CorsIssue.ts | CORS":{"message":"Cross-Origin Resource Sharing (CORS)"},"models/issues_manager/CorsIssue.ts | corsPrivateNetworkAccess":{"message":"Private Network Access"},"models/issues_manager/CrossOriginEmbedderPolicyIssue.ts | coopAndCoep":{"message":"COOP and COEP"},"models/issues_manager/CrossOriginEmbedderPolicyIssue.ts | samesiteAndSameorigin":{"message":"Same-Site and Same-Origin"},"models/issues_manager/DeprecationIssue.ts | feature":{"message":"Check the feature status page for more details."},"models/issues_manager/DeprecationIssue.ts | milestone":{"message":"This change will go into effect with milestone {milestone}."},"models/issues_manager/DeprecationIssue.ts | title":{"message":"Deprecated feature used"},"models/issues_manager/FederatedAuthRequestIssue.ts | fedCm":{"message":"Federated Credential Management API"},"models/issues_manager/FederatedAuthUserInfoRequestIssue.ts | fedCmUserInfo":{"message":"Federated Credential Management User Info API"},"models/issues_manager/GenericIssue.ts | autocompleteAttributePageTitle":{"message":"HTML attribute: autocomplete"},"models/issues_manager/GenericIssue.ts | corbExplainerPageTitle":{"message":"CORB explainer"},"models/issues_manager/GenericIssue.ts | crossOriginPortalPostMessage":{"message":"Portals - Same-origin communication channels"},"models/issues_manager/GenericIssue.ts | howDoesAutofillWorkPageTitle":{"message":"How does autofill work?"},"models/issues_manager/GenericIssue.ts | inputFormElementPageTitle":{"message":"The form input element"},"models/issues_manager/GenericIssue.ts | labelFormlementsPageTitle":{"message":"The label elements"},"models/issues_manager/HeavyAdIssue.ts | handlingHeavyAdInterventions":{"message":"Handling Heavy Ad Interventions"},"models/issues_manager/Issue.ts | breakingChangeIssue":{"message":"A breaking change issue: the page may stop working in an upcoming version of Chrome"},"models/issues_manager/Issue.ts | breakingChanges":{"message":"Breaking Changes"},"models/issues_manager/Issue.ts | improvementIssue":{"message":"An improvement issue: there is an opportunity to improve the page"},"models/issues_manager/Issue.ts | improvements":{"message":"Improvements"},"models/issues_manager/Issue.ts | pageErrorIssue":{"message":"A page error issue: the page is not working correctly"},"models/issues_manager/Issue.ts | pageErrors":{"message":"Page Errors"},"models/issues_manager/LowTextContrastIssue.ts | colorAndContrastAccessibility":{"message":"Color and contrast accessibility"},"models/issues_manager/MixedContentIssue.ts | preventingMixedContent":{"message":"Preventing mixed content"},"models/issues_manager/QuirksModeIssue.ts | documentCompatibilityMode":{"message":"Document compatibility mode"},"models/issues_manager/SharedArrayBufferIssue.ts | enablingSharedArrayBuffer":{"message":"Enabling SharedArrayBuffer"},"models/logs/logs-meta.ts | clear":{"message":"clear"},"models/logs/logs-meta.ts | doNotPreserveLogOnPageReload":{"message":"Do not preserve log on page reload / navigation"},"models/logs/logs-meta.ts | preserve":{"message":"preserve"},"models/logs/logs-meta.ts | preserveLog":{"message":"Preserve log"},"models/logs/logs-meta.ts | preserveLogOnPageReload":{"message":"Preserve log on page reload / navigation"},"models/logs/logs-meta.ts | recordNetworkLog":{"message":"Record network log"},"models/logs/logs-meta.ts | reset":{"message":"reset"},"models/logs/NetworkLog.ts | anonymous":{"message":""},"models/persistence/EditFileSystemView.ts | add":{"message":"Add"},"models/persistence/EditFileSystemView.ts | enterAPath":{"message":"Enter a path"},"models/persistence/EditFileSystemView.ts | enterAUniquePath":{"message":"Enter a unique path"},"models/persistence/EditFileSystemView.ts | excludedFolders":{"message":"Excluded folders"},"models/persistence/EditFileSystemView.ts | folderPath":{"message":"Folder path"},"models/persistence/EditFileSystemView.ts | none":{"message":"None"},"models/persistence/EditFileSystemView.ts | sViaDevtools":{"message":"{PH1} (via .devtools)"},"models/persistence/IsolatedFileSystem.ts | blobCouldNotBeLoaded":{"message":"Blob could not be loaded."},"models/persistence/IsolatedFileSystem.ts | cantReadFileSS":{"message":"Can't read file: {PH1}: {PH2}"},"models/persistence/IsolatedFileSystem.ts | fileSystemErrorS":{"message":"File system error: {PH1}"},"models/persistence/IsolatedFileSystem.ts | linkedToS":{"message":"Linked to {PH1}"},"models/persistence/IsolatedFileSystem.ts | unknownErrorReadingFileS":{"message":"Unknown error reading file: {PH1}"},"models/persistence/IsolatedFileSystemManager.ts | unableToAddFilesystemS":{"message":"Unable to add filesystem: {PH1}"},"models/persistence/persistence-meta.ts | disableOverrideNetworkRequests":{"message":"Disable override network requests"},"models/persistence/persistence-meta.ts | enableLocalOverrides":{"message":"Enable Local Overrides"},"models/persistence/persistence-meta.ts | enableOverrideNetworkRequests":{"message":"Enable override network requests"},"models/persistence/persistence-meta.ts | interception":{"message":"interception"},"models/persistence/persistence-meta.ts | network":{"message":"network"},"models/persistence/persistence-meta.ts | override":{"message":"override"},"models/persistence/persistence-meta.ts | request":{"message":"request"},"models/persistence/persistence-meta.ts | rewrite":{"message":"rewrite"},"models/persistence/persistence-meta.ts | showWorkspace":{"message":"Show Workspace settings"},"models/persistence/persistence-meta.ts | workspace":{"message":"Workspace"},"models/persistence/PersistenceActions.ts | openInContainingFolder":{"message":"Open in containing folder"},"models/persistence/PersistenceActions.ts | overrideContent":{"message":"Override content"},"models/persistence/PersistenceActions.ts | overrideSourceMappedFileExplanation":{"message":"‘{PH1}’ is a source mapped file and cannot be overridden."},"models/persistence/PersistenceActions.ts | overrideSourceMappedFileWarning":{"message":"Override ‘{PH1}’ instead?"},"models/persistence/PersistenceActions.ts | saveAs":{"message":"Save as..."},"models/persistence/PersistenceActions.ts | saveImage":{"message":"Save image"},"models/persistence/PersistenceActions.ts | showOverrides":{"message":"Show all overrides"},"models/persistence/PersistenceUtils.ts | linkedToS":{"message":"Linked to {PH1}"},"models/persistence/PersistenceUtils.ts | linkedToSourceMapS":{"message":"Linked to source map: {PH1}"},"models/persistence/PlatformFileSystem.ts | unableToReadFilesWithThis":{"message":"PlatformFileSystem cannot read files."},"models/persistence/WorkspaceSettingsTab.ts | addFolder":{"message":"Add folder…"},"models/persistence/WorkspaceSettingsTab.ts | folderExcludePattern":{"message":"Folder exclude pattern"},"models/persistence/WorkspaceSettingsTab.ts | mappingsAreInferredAutomatically":{"message":"Mappings are inferred automatically."},"models/persistence/WorkspaceSettingsTab.ts | remove":{"message":"Remove"},"models/persistence/WorkspaceSettingsTab.ts | workspace":{"message":"Workspace"},"models/timeline_model/TimelineJSProfile.ts | threadS":{"message":"Thread {PH1}"},"models/timeline_model/TimelineModel.ts | dedicatedWorker":{"message":"Dedicated Worker"},"models/timeline_model/TimelineModel.ts | threadS":{"message":"Thread {PH1}"},"models/timeline_model/TimelineModel.ts | workerS":{"message":"Worker — {PH1}"},"models/timeline_model/TimelineModel.ts | workerSS":{"message":"Worker: {PH1} — {PH2}"},"models/workspace/UISourceCode.ts | index":{"message":"(index)"},"models/workspace/UISourceCode.ts | thisFileWasChangedExternally":{"message":"This file was changed externally. Would you like to reload it?"},"panels/accessibility/accessibility-meta.ts | accessibility":{"message":"Accessibility"},"panels/accessibility/accessibility-meta.ts | shoAccessibility":{"message":"Show Accessibility"},"panels/accessibility/AccessibilityNodeView.ts | accessibilityNodeNotExposed":{"message":"Accessibility node not exposed"},"panels/accessibility/AccessibilityNodeView.ts | ancestorChildrenAreAll":{"message":"Ancestor's children are all presentational: "},"panels/accessibility/AccessibilityNodeView.ts | computedProperties":{"message":"Computed Properties"},"panels/accessibility/AccessibilityNodeView.ts | elementHasEmptyAltText":{"message":"Element has empty alt text."},"panels/accessibility/AccessibilityNodeView.ts | elementHasPlaceholder":{"message":"Element has {PH1}."},"panels/accessibility/AccessibilityNodeView.ts | elementIsHiddenBy":{"message":"Element is hidden by active modal dialog: "},"panels/accessibility/AccessibilityNodeView.ts | elementIsHiddenByChildTree":{"message":"Element is hidden by child tree: "},"panels/accessibility/AccessibilityNodeView.ts | elementIsInAnInertSubTree":{"message":"Element is in an inert subtree from "},"panels/accessibility/AccessibilityNodeView.ts | elementIsInert":{"message":"Element is inert."},"panels/accessibility/AccessibilityNodeView.ts | elementIsNotRendered":{"message":"Element is not rendered."},"panels/accessibility/AccessibilityNodeView.ts | elementIsNotVisible":{"message":"Element is not visible."},"panels/accessibility/AccessibilityNodeView.ts | elementIsPlaceholder":{"message":"Element is {PH1}."},"panels/accessibility/AccessibilityNodeView.ts | elementIsPresentational":{"message":"Element is presentational."},"panels/accessibility/AccessibilityNodeView.ts | elementNotInteresting":{"message":"Element not interesting for accessibility."},"panels/accessibility/AccessibilityNodeView.ts | elementsInheritsPresentational":{"message":"Element inherits presentational role from "},"panels/accessibility/AccessibilityNodeView.ts | invalidSource":{"message":"Invalid source."},"panels/accessibility/AccessibilityNodeView.ts | labelFor":{"message":"Label for "},"panels/accessibility/AccessibilityNodeView.ts | noAccessibilityNode":{"message":"No accessibility node"},"panels/accessibility/AccessibilityNodeView.ts | noNodeWithThisId":{"message":"No node with this ID."},"panels/accessibility/AccessibilityNodeView.ts | noTextContent":{"message":"No text content."},"panels/accessibility/AccessibilityNodeView.ts | notSpecified":{"message":"Not specified"},"panels/accessibility/AccessibilityNodeView.ts | partOfLabelElement":{"message":"Part of label element: "},"panels/accessibility/AccessibilityNodeView.ts | placeholderIsPlaceholderOnAncestor":{"message":"{PH1} is {PH2} on ancestor: "},"panels/accessibility/AccessibilityStrings.ts | activeDescendant":{"message":"Active descendant"},"panels/accessibility/AccessibilityStrings.ts | aHumanreadableVersionOfTheValue":{"message":"A human-readable version of the value of a range widget (where necessary)."},"panels/accessibility/AccessibilityStrings.ts | atomicLiveRegions":{"message":"Atomic (live regions)"},"panels/accessibility/AccessibilityStrings.ts | busyLiveRegions":{"message":"Busy (live regions)"},"panels/accessibility/AccessibilityStrings.ts | canSetValue":{"message":"Can set value"},"panels/accessibility/AccessibilityStrings.ts | checked":{"message":"Checked"},"panels/accessibility/AccessibilityStrings.ts | contents":{"message":"Contents"},"panels/accessibility/AccessibilityStrings.ts | controls":{"message":"Controls"},"panels/accessibility/AccessibilityStrings.ts | describedBy":{"message":"Described by"},"panels/accessibility/AccessibilityStrings.ts | description":{"message":"Description"},"panels/accessibility/AccessibilityStrings.ts | disabled":{"message":"Disabled"},"panels/accessibility/AccessibilityStrings.ts | editable":{"message":"Editable"},"panels/accessibility/AccessibilityStrings.ts | elementOrElementsWhichFormThe":{"message":"Element or elements which form the description of this element."},"panels/accessibility/AccessibilityStrings.ts | elementOrElementsWhichMayFormThe":{"message":"Element or elements which may form the name of this element."},"panels/accessibility/AccessibilityStrings.ts | elementOrElementsWhichShouldBe":{"message":"Element or elements which should be considered descendants of this element, despite not being descendants in the DOM."},"panels/accessibility/AccessibilityStrings.ts | elementOrElementsWhoseContentOr":{"message":"Element or elements whose content or presence is/are controlled by this widget."},"panels/accessibility/AccessibilityStrings.ts | elementToWhichTheUserMayChooseTo":{"message":"Element to which the user may choose to navigate after this one, instead of the next element in the DOM order."},"panels/accessibility/AccessibilityStrings.ts | expanded":{"message":"Expanded"},"panels/accessibility/AccessibilityStrings.ts | focusable":{"message":"Focusable"},"panels/accessibility/AccessibilityStrings.ts | focused":{"message":"Focused"},"panels/accessibility/AccessibilityStrings.ts | forARangeWidgetTheMaximumAllowed":{"message":"For a range widget, the maximum allowed value."},"panels/accessibility/AccessibilityStrings.ts | forARangeWidgetTheMinimumAllowed":{"message":"For a range widget, the minimum allowed value."},"panels/accessibility/AccessibilityStrings.ts | fromAttribute":{"message":"From attribute"},"panels/accessibility/AccessibilityStrings.ts | fromCaption":{"message":"From caption"},"panels/accessibility/AccessibilityStrings.ts | fromDescription":{"message":"From description"},"panels/accessibility/AccessibilityStrings.ts | fromLabel":{"message":"From label"},"panels/accessibility/AccessibilityStrings.ts | fromLabelFor":{"message":"From label (for= attribute)"},"panels/accessibility/AccessibilityStrings.ts | fromLabelWrapped":{"message":"From label (wrapped)"},"panels/accessibility/AccessibilityStrings.ts | fromLegend":{"message":"From legend"},"panels/accessibility/AccessibilityStrings.ts | fromNativeHtml":{"message":"From native HTML"},"panels/accessibility/AccessibilityStrings.ts | fromPlaceholderAttribute":{"message":"From placeholder attribute"},"panels/accessibility/AccessibilityStrings.ts | fromRubyAnnotation":{"message":"From ruby annotation"},"panels/accessibility/AccessibilityStrings.ts | fromStyle":{"message":"From style"},"panels/accessibility/AccessibilityStrings.ts | fromTitle":{"message":"From title"},"panels/accessibility/AccessibilityStrings.ts | hasAutocomplete":{"message":"Has autocomplete"},"panels/accessibility/AccessibilityStrings.ts | hasPopup":{"message":"Has popup"},"panels/accessibility/AccessibilityStrings.ts | help":{"message":"Help"},"panels/accessibility/AccessibilityStrings.ts | ifAndHowThisElementCanBeEdited":{"message":"If and how this element can be edited."},"panels/accessibility/AccessibilityStrings.ts | ifThisElementMayReceiveLive":{"message":"If this element may receive live updates, whether the entire live region should be presented to the user on changes, or only changed nodes."},"panels/accessibility/AccessibilityStrings.ts | ifThisElementMayReceiveLiveUpdates":{"message":"If this element may receive live updates, what type of updates should trigger a notification."},"panels/accessibility/AccessibilityStrings.ts | ifThisElementMayReceiveLiveUpdatesThe":{"message":"If this element may receive live updates, the root element of the containing live region."},"panels/accessibility/AccessibilityStrings.ts | ifTrueThisElementCanReceiveFocus":{"message":"If true, this element can receive focus."},"panels/accessibility/AccessibilityStrings.ts | ifTrueThisElementCurrentlyCannot":{"message":"If true, this element currently cannot be interacted with."},"panels/accessibility/AccessibilityStrings.ts | ifTrueThisElementCurrentlyHas":{"message":"If true, this element currently has focus."},"panels/accessibility/AccessibilityStrings.ts | ifTrueThisElementMayBeInteracted":{"message":"If true, this element may be interacted with, but its value cannot be changed."},"panels/accessibility/AccessibilityStrings.ts | ifTrueThisElementsUserentered":{"message":"If true, this element's user-entered value does not conform to validation requirement."},"panels/accessibility/AccessibilityStrings.ts | implicit":{"message":"Implicit"},"panels/accessibility/AccessibilityStrings.ts | implicitValue":{"message":"Implicit value."},"panels/accessibility/AccessibilityStrings.ts | indicatesThePurposeOfThisElement":{"message":"Indicates the purpose of this element, such as a user interface idiom for a widget, or structural role within a document."},"panels/accessibility/AccessibilityStrings.ts | invalidUserEntry":{"message":"Invalid user entry"},"panels/accessibility/AccessibilityStrings.ts | labeledBy":{"message":"Labeled by"},"panels/accessibility/AccessibilityStrings.ts | level":{"message":"Level"},"panels/accessibility/AccessibilityStrings.ts | liveRegion":{"message":"Live region"},"panels/accessibility/AccessibilityStrings.ts | liveRegionRoot":{"message":"Live region root"},"panels/accessibility/AccessibilityStrings.ts | maximumValue":{"message":"Maximum value"},"panels/accessibility/AccessibilityStrings.ts | minimumValue":{"message":"Minimum value"},"panels/accessibility/AccessibilityStrings.ts | multiline":{"message":"Multi-line"},"panels/accessibility/AccessibilityStrings.ts | multiselectable":{"message":"Multi-selectable"},"panels/accessibility/AccessibilityStrings.ts | orientation":{"message":"Orientation"},"panels/accessibility/AccessibilityStrings.ts | pressed":{"message":"Pressed"},"panels/accessibility/AccessibilityStrings.ts | readonlyString":{"message":"Read-only"},"panels/accessibility/AccessibilityStrings.ts | relatedElement":{"message":"Related element"},"panels/accessibility/AccessibilityStrings.ts | relevantLiveRegions":{"message":"Relevant (live regions)"},"panels/accessibility/AccessibilityStrings.ts | requiredString":{"message":"Required"},"panels/accessibility/AccessibilityStrings.ts | role":{"message":"Role"},"panels/accessibility/AccessibilityStrings.ts | selectedString":{"message":"Selected"},"panels/accessibility/AccessibilityStrings.ts | theAccessibleDescriptionForThis":{"message":"The accessible description for this element."},"panels/accessibility/AccessibilityStrings.ts | theComputedHelpTextForThis":{"message":"The computed help text for this element."},"panels/accessibility/AccessibilityStrings.ts | theComputedNameOfThisElement":{"message":"The computed name of this element."},"panels/accessibility/AccessibilityStrings.ts | theDescendantOfThisElementWhich":{"message":"The descendant of this element which is active; i.e. the element to which focus should be delegated."},"panels/accessibility/AccessibilityStrings.ts | theHierarchicalLevelOfThis":{"message":"The hierarchical level of this element."},"panels/accessibility/AccessibilityStrings.ts | theValueOfThisElementThisMayBe":{"message":"The value of this element; this may be user-provided or developer-provided, depending on the element."},"panels/accessibility/AccessibilityStrings.ts | value":{"message":"Value"},"panels/accessibility/AccessibilityStrings.ts | valueDescription":{"message":"Value description"},"panels/accessibility/AccessibilityStrings.ts | valueFromAttribute":{"message":"Value from attribute."},"panels/accessibility/AccessibilityStrings.ts | valueFromDescriptionElement":{"message":"Value from description element."},"panels/accessibility/AccessibilityStrings.ts | valueFromElementContents":{"message":"Value from element contents."},"panels/accessibility/AccessibilityStrings.ts | valueFromFigcaptionElement":{"message":"Value from figcaption element."},"panels/accessibility/AccessibilityStrings.ts | valueFromLabelElement":{"message":"Value from label element."},"panels/accessibility/AccessibilityStrings.ts | valueFromLabelElementWithFor":{"message":"Value from label element with for= attribute."},"panels/accessibility/AccessibilityStrings.ts | valueFromLabelElementWrapped":{"message":"Value from a wrapping label element."},"panels/accessibility/AccessibilityStrings.ts | valueFromLegendElement":{"message":"Value from legend element."},"panels/accessibility/AccessibilityStrings.ts | valueFromNativeHtmlRuby":{"message":"Value from plain HTML ruby annotation."},"panels/accessibility/AccessibilityStrings.ts | valueFromNativeHtmlUnknownSource":{"message":"Value from native HTML (unknown source)."},"panels/accessibility/AccessibilityStrings.ts | valueFromPlaceholderAttribute":{"message":"Value from placeholder attribute."},"panels/accessibility/AccessibilityStrings.ts | valueFromRelatedElement":{"message":"Value from related element."},"panels/accessibility/AccessibilityStrings.ts | valueFromStyle":{"message":"Value from style."},"panels/accessibility/AccessibilityStrings.ts | valueFromTableCaption":{"message":"Value from table caption."},"panels/accessibility/AccessibilityStrings.ts | valueFromTitleAttribute":{"message":"Value from title attribute."},"panels/accessibility/AccessibilityStrings.ts | whetherAndWhatPriorityOfLive":{"message":"Whether and what priority of live updates may be expected for this element."},"panels/accessibility/AccessibilityStrings.ts | whetherAndWhatTypeOfAutocomplete":{"message":"Whether and what type of autocomplete suggestions are currently provided by this element."},"panels/accessibility/AccessibilityStrings.ts | whetherAUserMaySelectMoreThanOne":{"message":"Whether a user may select more than one option from this widget."},"panels/accessibility/AccessibilityStrings.ts | whetherTheOptionRepresentedBy":{"message":"Whether the option represented by this element is currently selected."},"panels/accessibility/AccessibilityStrings.ts | whetherTheValueOfThisElementCan":{"message":"Whether the value of this element can be set."},"panels/accessibility/AccessibilityStrings.ts | whetherThisCheckboxRadioButtonOr":{"message":"Whether this checkbox, radio button or tree item is checked, unchecked, or mixed (e.g. has both checked and un-checked children)."},"panels/accessibility/AccessibilityStrings.ts | whetherThisElementHasCausedSome":{"message":"Whether this element has caused some kind of pop-up (such as a menu) to appear."},"panels/accessibility/AccessibilityStrings.ts | whetherThisElementIsARequired":{"message":"Whether this element is a required field in a form."},"panels/accessibility/AccessibilityStrings.ts | whetherThisElementOrAnother":{"message":"Whether this element, or another grouping element it controls, is expanded."},"panels/accessibility/AccessibilityStrings.ts | whetherThisElementOrItsSubtree":{"message":"Whether this element or its subtree are currently being updated (and thus may be in an inconsistent state)."},"panels/accessibility/AccessibilityStrings.ts | whetherThisLinearElements":{"message":"Whether this linear element's orientation is horizontal or vertical."},"panels/accessibility/AccessibilityStrings.ts | whetherThisTextBoxMayHaveMore":{"message":"Whether this text box may have more than one line."},"panels/accessibility/AccessibilityStrings.ts | whetherThisToggleButtonIs":{"message":"Whether this toggle button is currently in a pressed state."},"panels/accessibility/ARIAAttributesView.ts | ariaAttributes":{"message":"ARIA Attributes"},"panels/accessibility/ARIAAttributesView.ts | noAriaAttributes":{"message":"No ARIA attributes"},"panels/accessibility/AXBreadcrumbsPane.ts | accessibilityTree":{"message":"Accessibility Tree"},"panels/accessibility/AXBreadcrumbsPane.ts | fullTreeExperimentDescription":{"message":"The accessibility tree moved to the top right corner of the DOM tree."},"panels/accessibility/AXBreadcrumbsPane.ts | fullTreeExperimentName":{"message":"Enable full-page accessibility tree"},"panels/accessibility/AXBreadcrumbsPane.ts | ignored":{"message":"Ignored"},"panels/accessibility/AXBreadcrumbsPane.ts | reloadRequired":{"message":"Reload required before the change takes effect."},"panels/accessibility/AXBreadcrumbsPane.ts | scrollIntoView":{"message":"Scroll into view"},"panels/accessibility/SourceOrderView.ts | noSourceOrderInformation":{"message":"No source order information available"},"panels/accessibility/SourceOrderView.ts | showSourceOrder":{"message":"Show source order"},"panels/accessibility/SourceOrderView.ts | sourceOrderViewer":{"message":"Source Order Viewer"},"panels/accessibility/SourceOrderView.ts | thereMayBeADelayInDisplaying":{"message":"There may be a delay in displaying source order for elements with many children"},"panels/animation/animation-meta.ts | animations":{"message":"Animations"},"panels/animation/animation-meta.ts | showAnimations":{"message":"Show Animations"},"panels/animation/AnimationTimeline.ts | animationPreviews":{"message":"Animation previews"},"panels/animation/AnimationTimeline.ts | animationPreviewS":{"message":"Animation Preview {PH1}"},"panels/animation/AnimationTimeline.ts | clearAll":{"message":"Clear all"},"panels/animation/AnimationTimeline.ts | pause":{"message":"Pause"},"panels/animation/AnimationTimeline.ts | pauseAll":{"message":"Pause all"},"panels/animation/AnimationTimeline.ts | pauseTimeline":{"message":"Pause timeline"},"panels/animation/AnimationTimeline.ts | playbackRatePlaceholder":{"message":"{PH1}%"},"panels/animation/AnimationTimeline.ts | playbackRates":{"message":"Playback rates"},"panels/animation/AnimationTimeline.ts | playTimeline":{"message":"Play timeline"},"panels/animation/AnimationTimeline.ts | replayTimeline":{"message":"Replay timeline"},"panels/animation/AnimationTimeline.ts | resumeAll":{"message":"Resume all"},"panels/animation/AnimationTimeline.ts | selectAnEffectAboveToInspectAnd":{"message":"Select an effect above to inspect and modify."},"panels/animation/AnimationTimeline.ts | setSpeedToS":{"message":"Set speed to {PH1}"},"panels/animation/AnimationTimeline.ts | waitingForAnimations":{"message":"Waiting for animations..."},"panels/animation/AnimationUI.ts | animationEndpointSlider":{"message":"Animation Endpoint slider"},"panels/animation/AnimationUI.ts | animationKeyframeSlider":{"message":"Animation Keyframe slider"},"panels/animation/AnimationUI.ts | sSlider":{"message":"{PH1} slider"},"panels/application/application-meta.ts | application":{"message":"Application"},"panels/application/application-meta.ts | clearSiteData":{"message":"Clear site data"},"panels/application/application-meta.ts | clearSiteDataIncludingThirdparty":{"message":"Clear site data (including third-party cookies)"},"panels/application/application-meta.ts | pwa":{"message":"pwa"},"panels/application/application-meta.ts | showApplication":{"message":"Show Application"},"panels/application/application-meta.ts | startRecordingEvents":{"message":"Start recording events"},"panels/application/application-meta.ts | stopRecordingEvents":{"message":"Stop recording events"},"panels/application/ApplicationPanelSidebar.ts | application":{"message":"Application"},"panels/application/ApplicationPanelSidebar.ts | applicationSidebarPanel":{"message":"Application panel sidebar"},"panels/application/ApplicationPanelSidebar.ts | appManifest":{"message":"App Manifest"},"panels/application/ApplicationPanelSidebar.ts | backgroundServices":{"message":"Background services"},"panels/application/ApplicationPanelSidebar.ts | beforeInvokeAlert":{"message":"{PH1}: Invoke to scroll to this section in manifest"},"panels/application/ApplicationPanelSidebar.ts | clear":{"message":"Clear"},"panels/application/ApplicationPanelSidebar.ts | cookies":{"message":"Cookies"},"panels/application/ApplicationPanelSidebar.ts | cookiesUsedByFramesFromS":{"message":"Cookies used by frames from {PH1}"},"panels/application/ApplicationPanelSidebar.ts | documentNotAvailable":{"message":"Document not available"},"panels/application/ApplicationPanelSidebar.ts | frames":{"message":"Frames"},"panels/application/ApplicationPanelSidebar.ts | indexeddb":{"message":"IndexedDB"},"panels/application/ApplicationPanelSidebar.ts | keyPathS":{"message":"Key path: {PH1}"},"panels/application/ApplicationPanelSidebar.ts | localFiles":{"message":"Local Files"},"panels/application/ApplicationPanelSidebar.ts | localStorage":{"message":"Local storage"},"panels/application/ApplicationPanelSidebar.ts | manifest":{"message":"Manifest"},"panels/application/ApplicationPanelSidebar.ts | noManifestDetected":{"message":"No manifest detected"},"panels/application/ApplicationPanelSidebar.ts | onInvokeAlert":{"message":"Scrolled to {PH1}"},"panels/application/ApplicationPanelSidebar.ts | onInvokeManifestAlert":{"message":"Manifest: Invoke to scroll to the top of manifest"},"panels/application/ApplicationPanelSidebar.ts | openedWindows":{"message":"Opened Windows"},"panels/application/ApplicationPanelSidebar.ts | refreshIndexeddb":{"message":"Refresh IndexedDB"},"panels/application/ApplicationPanelSidebar.ts | sessionStorage":{"message":"Session storage"},"panels/application/ApplicationPanelSidebar.ts | storage":{"message":"Storage"},"panels/application/ApplicationPanelSidebar.ts | theContentOfThisDocumentHasBeen":{"message":"The content of this document has been generated dynamically via 'document.write()'."},"panels/application/ApplicationPanelSidebar.ts | thirdPartyPhaseout":{"message":"Cookies from {PH1} may have been blocked due to third-party cookie phaseout."},"panels/application/ApplicationPanelSidebar.ts | versionS":{"message":"Version: {PH1}"},"panels/application/ApplicationPanelSidebar.ts | versionSEmpty":{"message":"Version: {PH1} (empty)"},"panels/application/ApplicationPanelSidebar.ts | webWorkers":{"message":"Web Workers"},"panels/application/ApplicationPanelSidebar.ts | windowWithoutTitle":{"message":"Window without title"},"panels/application/ApplicationPanelSidebar.ts | worker":{"message":"worker"},"panels/application/AppManifestView.ts | actualHeightSpxOfSSDoesNotMatch":{"message":"Actual height ({PH1}px) of {PH2} {PH3} does not match specified height ({PH4}px)"},"panels/application/AppManifestView.ts | actualSizeSspxOfSSDoesNotMatch":{"message":"Actual size ({PH1}×{PH2})px of {PH3} {PH4} does not match specified size ({PH5}×{PH6}px)"},"panels/application/AppManifestView.ts | actualWidthSpxOfSSDoesNotMatch":{"message":"Actual width ({PH1}px) of {PH2} {PH3} does not match specified width ({PH4}px)"},"panels/application/AppManifestView.ts | appIdExplainer":{"message":"This is used by the browser to know whether the manifest should be updating an existing application, or whether it refers to a new web app that can be installed."},"panels/application/AppManifestView.ts | appIdNote":{"message":"{PH1} {PH2} is not specified in the manifest, {PH3} is used instead. To specify an App ID that matches the current identity, set the {PH4} field to {PH5} {PH6}."},"panels/application/AppManifestView.ts | aUrlInTheManifestContainsA":{"message":"A URL in the manifest contains a username, password, or port"},"panels/application/AppManifestView.ts | avoidPurposeAnyAndMaskable":{"message":"Declaring an icon with 'purpose' of 'any maskable' is discouraged. It is likely to look incorrect on some platforms due to too much or too little padding."},"panels/application/AppManifestView.ts | backgroundColor":{"message":"Background color"},"panels/application/AppManifestView.ts | computedAppId":{"message":"Computed App ID"},"panels/application/AppManifestView.ts | copiedToClipboard":{"message":"Copied suggested ID {PH1} to clipboard"},"panels/application/AppManifestView.ts | copyToClipboard":{"message":"Copy suggested ID to clipboard"},"panels/application/AppManifestView.ts | couldNotCheckServiceWorker":{"message":"Could not check service worker without a 'start_url' field in the manifest"},"panels/application/AppManifestView.ts | couldNotDownloadARequiredIcon":{"message":"Could not download a required icon from the manifest"},"panels/application/AppManifestView.ts | customizePwaTitleBar":{"message":"Customize the window controls overlay of your PWA's title bar"},"panels/application/AppManifestView.ts | darkBackgroundColor":{"message":"Dark background color"},"panels/application/AppManifestView.ts | darkThemeColor":{"message":"Dark theme color"},"panels/application/AppManifestView.ts | description":{"message":"Description"},"panels/application/AppManifestView.ts | descriptionMayBeTruncated":{"message":"Description may be truncated."},"panels/application/AppManifestView.ts | display":{"message":"Display"},"panels/application/AppManifestView.ts | documentationOnMaskableIcons":{"message":"documentation on maskable icons"},"panels/application/AppManifestView.ts | downloadedIconWasEmptyOr":{"message":"Downloaded icon was empty or corrupted"},"panels/application/AppManifestView.ts | errorsAndWarnings":{"message":"Errors and warnings"},"panels/application/AppManifestView.ts | formFactor":{"message":"Form factor"},"panels/application/AppManifestView.ts | icon":{"message":"Icon"},"panels/application/AppManifestView.ts | icons":{"message":"Icons"},"panels/application/AppManifestView.ts | identity":{"message":"Identity"},"panels/application/AppManifestView.ts | imageFromS":{"message":"Image from {PH1}"},"panels/application/AppManifestView.ts | installability":{"message":"Installability"},"panels/application/AppManifestView.ts | label":{"message":"Label"},"panels/application/AppManifestView.ts | learnMore":{"message":"Learn more"},"panels/application/AppManifestView.ts | manifestContainsDisplayoverride":{"message":"Manifest contains 'display_override' field, and the first supported display mode must be one of 'standalone', 'fullscreen', or 'minimal-ui'"},"panels/application/AppManifestView.ts | manifestCouldNotBeFetchedIsEmpty":{"message":"Manifest could not be fetched, is empty, or could not be parsed"},"panels/application/AppManifestView.ts | manifestDisplayPropertyMustBeOne":{"message":"Manifest 'display' property must be one of 'standalone', 'fullscreen', or 'minimal-ui'"},"panels/application/AppManifestView.ts | manifestDoesNotContainANameOr":{"message":"Manifest does not contain a 'name' or 'short_name' field"},"panels/application/AppManifestView.ts | manifestDoesNotContainASuitable":{"message":"Manifest does not contain a suitable icon—PNG, SVG, or WebP format of at least {PH1}px is required, the 'sizes' attribute must be set, and the 'purpose' attribute, if set, must include 'any'."},"panels/application/AppManifestView.ts | manifestSpecifies":{"message":"Manifest specifies 'prefer_related_applications: true'"},"panels/application/AppManifestView.ts | manifestStartUrlIsNotValid":{"message":"Manifest 'start_url' is not valid"},"panels/application/AppManifestView.ts | name":{"message":"Name"},"panels/application/AppManifestView.ts | needHelpReadOurS":{"message":"Need help? Read the {PH1}."},"panels/application/AppManifestView.ts | newNoteUrl":{"message":"New note URL"},"panels/application/AppManifestView.ts | noPlayStoreIdProvided":{"message":"No Play store ID provided"},"panels/application/AppManifestView.ts | noScreenshotsForRicherPWAInstallOnDesktop":{"message":"Richer PWA Install UI won’t be available on desktop. Please add at least one screenshot with the form_factor set to wide."},"panels/application/AppManifestView.ts | noScreenshotsForRicherPWAInstallOnMobile":{"message":"Richer PWA Install UI won’t be available on mobile. Please add at least one screenshot for which form_factor is not set or set to a value other than wide."},"panels/application/AppManifestView.ts | noSuppliedIconIsAtLeastSpxSquare":{"message":"No supplied icon is at least {PH1} pixels square in PNG, SVG, or WebP format, with the purpose attribute unset or set to 'any'."},"panels/application/AppManifestView.ts | note":{"message":"Note:"},"panels/application/AppManifestView.ts | orientation":{"message":"Orientation"},"panels/application/AppManifestView.ts | pageDoesNotWorkOffline":{"message":"Page does not work offline"},"panels/application/AppManifestView.ts | pageDoesNotWorkOfflineThePage":{"message":"Page does not work offline. Starting in Chrome 93, the installability criteria are changing, and this site will not be installable. See {PH1} for more information."},"panels/application/AppManifestView.ts | pageHasNoManifestLinkUrl":{"message":"Page has no manifest URL"},"panels/application/AppManifestView.ts | pageIsLoadedInAnIncognitoWindow":{"message":"Page is loaded in an incognito window"},"panels/application/AppManifestView.ts | pageIsNotLoadedInTheMainFrame":{"message":"Page is not loaded in the main frame"},"panels/application/AppManifestView.ts | pageIsNotServedFromASecureOrigin":{"message":"Page is not served from a secure origin"},"panels/application/AppManifestView.ts | platform":{"message":"Platform"},"panels/application/AppManifestView.ts | preferrelatedapplicationsIsOnly":{"message":"'prefer_related_applications' is only supported on Chrome Beta and Stable channels on Android."},"panels/application/AppManifestView.ts | presentation":{"message":"Presentation"},"panels/application/AppManifestView.ts | protocolHandlers":{"message":"Protocol Handlers"},"panels/application/AppManifestView.ts | screenshot":{"message":"Screenshot"},"panels/application/AppManifestView.ts | screenshotPixelSize":{"message":"Screenshot {url} should specify a pixel size [width]x[height] instead of any as first size."},"panels/application/AppManifestView.ts | screenshotS":{"message":"Screenshot #{PH1}"},"panels/application/AppManifestView.ts | screenshotsMustHaveSameAspectRatio":{"message":"All screenshots with the same form_factor must have the same aspect ratio as the first screenshot with that form_factor. Some screenshots will be ignored."},"panels/application/AppManifestView.ts | selectWindowControlsOverlayEmulationOs":{"message":"Emulate the Window Controls Overlay on"},"panels/application/AppManifestView.ts | shortcutS":{"message":"Shortcut #{PH1}"},"panels/application/AppManifestView.ts | shortcutsMayBeNotAvailable":{"message":"The maximum number of shortcuts is platform dependent. Some shortcuts may be not available."},"panels/application/AppManifestView.ts | shortcutSShouldIncludeAXPixel":{"message":"Shortcut #{PH1} should include a 96×96 pixel icon"},"panels/application/AppManifestView.ts | shortName":{"message":"Short name"},"panels/application/AppManifestView.ts | showOnlyTheMinimumSafeAreaFor":{"message":"Show only the minimum safe area for maskable icons"},"panels/application/AppManifestView.ts | sSDoesNotSpecifyItsSizeInThe":{"message":"{PH1} {PH2} does not specify its size in the manifest"},"panels/application/AppManifestView.ts | sSFailedToLoad":{"message":"{PH1} {PH2} failed to load"},"panels/application/AppManifestView.ts | sSHeightDoesNotComplyWithRatioRequirement":{"message":"{PH1} {PH2} height can't be more than 2.3 times as long as the width"},"panels/application/AppManifestView.ts | sSrcIsNotSet":{"message":"{PH1} 'src' is not set"},"panels/application/AppManifestView.ts | sSShouldHaveSquareIcon":{"message":"Most operating systems require square icons. Please include at least one square icon in the array."},"panels/application/AppManifestView.ts | sSShouldSpecifyItsSizeAs":{"message":"{PH1} {PH2} should specify its size as [width]x[height]"},"panels/application/AppManifestView.ts | sSSizeShouldBeAtLeast320":{"message":"{PH1} {PH2} size should be at least 320×320"},"panels/application/AppManifestView.ts | sSSizeShouldBeAtMost3840":{"message":"{PH1} {PH2} size should be at most 3840×3840"},"panels/application/AppManifestView.ts | sSWidthDoesNotComplyWithRatioRequirement":{"message":"{PH1} {PH2} width can't be more than 2.3 times as long as the height"},"panels/application/AppManifestView.ts | startUrl":{"message":"Start URL"},"panels/application/AppManifestView.ts | sUrlSFailedToParse":{"message":"{PH1} URL ''{PH2}'' failed to parse"},"panels/application/AppManifestView.ts | theAppIsAlreadyInstalled":{"message":"The app is already installed"},"panels/application/AppManifestView.ts | themeColor":{"message":"Theme color"},"panels/application/AppManifestView.ts | thePlayStoreAppUrlAndPlayStoreId":{"message":"The Play Store app URL and Play Store ID do not match"},"panels/application/AppManifestView.ts | theSpecifiedApplicationPlatform":{"message":"The specified application platform is not supported on Android"},"panels/application/AppManifestView.ts | tooManyScreenshotsForDesktop":{"message":"No more than 8 screenshots will be displayed on desktop. The rest will be ignored."},"panels/application/AppManifestView.ts | tooManyScreenshotsForMobile":{"message":"No more than 5 screenshots will be displayed on mobile. The rest will be ignored."},"panels/application/AppManifestView.ts | url":{"message":"URL"},"panels/application/AppManifestView.ts | wcoFound":{"message":"Chrome has successfully found the {PH1} value for the {PH2} field in the {PH3}."},"panels/application/AppManifestView.ts | wcoNeedHelpReadMore":{"message":"Need help? Read {PH1}."},"panels/application/AppManifestView.ts | wcoNotFound":{"message":"Define {PH1} in the manifest to use the Window Controls Overlay API and customize your app's title bar."},"panels/application/AppManifestView.ts | windowControlsOverlay":{"message":"Window Controls Overlay"},"panels/application/BackForwardCacheTreeElement.ts | backForwardCache":{"message":"Back/forward cache"},"panels/application/BackgroundServiceView.ts | backgroundFetch":{"message":"Background fetch"},"panels/application/BackgroundServiceView.ts | backgroundServices":{"message":"Background services"},"panels/application/BackgroundServiceView.ts | backgroundSync":{"message":"Background sync"},"panels/application/BackgroundServiceView.ts | clear":{"message":"Clear"},"panels/application/BackgroundServiceView.ts | clickTheRecordButtonSOrHitSTo":{"message":"Click the record button {PH1} or hit {PH2} to start recording."},"panels/application/BackgroundServiceView.ts | devtoolsWillRecordAllSActivity":{"message":"DevTools will record all {PH1} activity for up to 3 days, even when closed."},"panels/application/BackgroundServiceView.ts | empty":{"message":"empty"},"panels/application/BackgroundServiceView.ts | event":{"message":"Event"},"panels/application/BackgroundServiceView.ts | instanceId":{"message":"Instance ID"},"panels/application/BackgroundServiceView.ts | learnMore":{"message":"Learn more"},"panels/application/BackgroundServiceView.ts | noMetadataForThisEvent":{"message":"No metadata for this event"},"panels/application/BackgroundServiceView.ts | notifications":{"message":"Notifications"},"panels/application/BackgroundServiceView.ts | origin":{"message":"Origin"},"panels/application/BackgroundServiceView.ts | paymentHandler":{"message":"Payment handler"},"panels/application/BackgroundServiceView.ts | periodicBackgroundSync":{"message":"Periodic background sync"},"panels/application/BackgroundServiceView.ts | pushMessaging":{"message":"Push messaging"},"panels/application/BackgroundServiceView.ts | recordingSActivity":{"message":"Recording {PH1} activity..."},"panels/application/BackgroundServiceView.ts | saveEvents":{"message":"Save events"},"panels/application/BackgroundServiceView.ts | selectAnEntryToViewMetadata":{"message":"Select an entry to view metadata"},"panels/application/BackgroundServiceView.ts | showEventsForOtherStorageKeys":{"message":"Show events from other storage partitions"},"panels/application/BackgroundServiceView.ts | showEventsFromOtherDomains":{"message":"Show events from other domains"},"panels/application/BackgroundServiceView.ts | startRecordingEvents":{"message":"Start recording events"},"panels/application/BackgroundServiceView.ts | stopRecordingEvents":{"message":"Stop recording events"},"panels/application/BackgroundServiceView.ts | storageKey":{"message":"Storage Key"},"panels/application/BackgroundServiceView.ts | swScope":{"message":"Service Worker Scope"},"panels/application/BackgroundServiceView.ts | timestamp":{"message":"Timestamp"},"panels/application/BounceTrackingMitigationsTreeElement.ts | bounceTrackingMitigations":{"message":"Bounce tracking mitigations"},"panels/application/components/BackForwardCacheStrings.ts | appBanner":{"message":"Pages that requested an AppBanner are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | backForwardCacheDisabled":{"message":"Back/forward cache is disabled by flags. Visit chrome://flags/#back-forward-cache to enable it locally on this device."},"panels/application/components/BackForwardCacheStrings.ts | backForwardCacheDisabledByCommandLine":{"message":"Back/forward cache is disabled by the command line."},"panels/application/components/BackForwardCacheStrings.ts | backForwardCacheDisabledByLowMemory":{"message":"Back/forward cache is disabled due to insufficient memory."},"panels/application/components/BackForwardCacheStrings.ts | backForwardCacheDisabledForDelegate":{"message":"Back/forward cache is not supported by delegate."},"panels/application/components/BackForwardCacheStrings.ts | backForwardCacheDisabledForPrerender":{"message":"Back/forward cache is disabled for prerenderer."},"panels/application/components/BackForwardCacheStrings.ts | broadcastChannel":{"message":"The page cannot be cached because it has a BroadcastChannel instance with registered listeners."},"panels/application/components/BackForwardCacheStrings.ts | cacheControlNoStore":{"message":"Pages with cache-control:no-store header cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | cacheFlushed":{"message":"The cache was intentionally cleared."},"panels/application/components/BackForwardCacheStrings.ts | cacheLimit":{"message":"The page was evicted from the cache to allow another page to be cached."},"panels/application/components/BackForwardCacheStrings.ts | containsPlugins":{"message":"Pages containing plugins are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentFileChooser":{"message":"Pages that use FileChooser API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentFileSystemAccess":{"message":"Pages that use File System Access API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentMediaDevicesDispatcherHost":{"message":"Pages that use Media Device Dispatcher are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentMediaPlay":{"message":"A media player was playing upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | contentMediaSession":{"message":"Pages that use MediaSession API and set a playback state are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentMediaSessionService":{"message":"Pages that use MediaSession API and set action handlers are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentScreenReader":{"message":"Back/forward cache is disabled due to screen reader."},"panels/application/components/BackForwardCacheStrings.ts | contentSecurityHandler":{"message":"Pages that use SecurityHandler are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentSerial":{"message":"Pages that use Serial API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentWebAuthenticationAPI":{"message":"Pages that use WebAuthetication API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentWebBluetooth":{"message":"Pages that use WebBluetooth API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | contentWebUSB":{"message":"Pages that use WebUSB API are not eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | cookieDisabled":{"message":"Back/forward cache is disabled because cookies are disabled on a page that uses Cache-Control: no-store."},"panels/application/components/BackForwardCacheStrings.ts | CookieFlushed":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | dedicatedWorkerOrWorklet":{"message":"Pages that use a dedicated worker or worklet are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | documentLoaded":{"message":"The document did not finish loading before navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderAppBannerManager":{"message":"App Banner was present upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderChromePasswordManagerClientBindCredentialManager":{"message":"Chrome Password Manager was present upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderDomDistillerSelfDeletingRequestDelegate":{"message":"DOM distillation was in progress upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderDomDistillerViewerSource":{"message":"DOM Distiller Viewer was present upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderExtensionMessaging":{"message":"Back/forward cache is disabled due to extensions using messaging API."},"panels/application/components/BackForwardCacheStrings.ts | embedderExtensionMessagingForOpenPort":{"message":"Extensions with long-lived connection should close the connection before entering back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | embedderExtensions":{"message":"Back/forward cache is disabled due to extensions."},"panels/application/components/BackForwardCacheStrings.ts | embedderExtensionSentMessageToCachedFrame":{"message":"Extensions with long-lived connection attempted to send messages to frames in back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | embedderModalDialog":{"message":"Modal dialog such as form resubmission or http password dialog was shown for the page upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderOfflinePage":{"message":"The offline page was shown upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderOomInterventionTabHelper":{"message":"Out-Of-Memory Intervention bar was present upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderPermissionRequestManager":{"message":"There were permission requests upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderPopupBlockerTabHelper":{"message":"Popup blocker was present upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderSafeBrowsingThreatDetails":{"message":"Safe Browsing details were shown upon navigating away."},"panels/application/components/BackForwardCacheStrings.ts | embedderSafeBrowsingTriggeredPopupBlocker":{"message":"Safe Browsing considered this page to be abusive and blocked popup."},"panels/application/components/BackForwardCacheStrings.ts | enteredBackForwardCacheBeforeServiceWorkerHostAdded":{"message":"A service worker was activated while the page was in back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | errorDocument":{"message":"Back/forward cache is disabled due to a document error."},"panels/application/components/BackForwardCacheStrings.ts | fencedFramesEmbedder":{"message":"Pages using FencedFrames cannot be stored in bfcache."},"panels/application/components/BackForwardCacheStrings.ts | foregroundCacheLimit":{"message":"The page was evicted from the cache to allow another page to be cached."},"panels/application/components/BackForwardCacheStrings.ts | grantedMediaStreamAccess":{"message":"Pages that have granted media stream access are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | haveInnerContents":{"message":"Pages that use portals are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | HTTPAuthRequired":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | HTTPMethodNotGET":{"message":"Only pages loaded via a GET request are eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | HTTPStatusNotOK":{"message":"Only pages with a status code of 2XX can be cached."},"panels/application/components/BackForwardCacheStrings.ts | idleManager":{"message":"Pages that use IdleManager are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | indexedDBConnection":{"message":"Pages that have an open IndexedDB connection are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | indexedDBEvent":{"message":"Back/forward cache is disabled due to an IndexedDB event."},"panels/application/components/BackForwardCacheStrings.ts | ineligibleAPI":{"message":"Ineligible APIs were used."},"panels/application/components/BackForwardCacheStrings.ts | injectedJavascript":{"message":"Pages that JavaScript is injected into by extensions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | injectedStyleSheet":{"message":"Pages that a StyleSheet is injected into by extensions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | internalError":{"message":"Internal error."},"panels/application/components/BackForwardCacheStrings.ts | JavaScriptExecution":{"message":"Chrome detected an attempt to execute JavaScript while in the cache."},"panels/application/components/BackForwardCacheStrings.ts | jsNetworkRequestReceivedCacheControlNoStoreResource":{"message":"Back/forward cache is disabled because some JavaScript network request received resource with Cache-Control: no-store header."},"panels/application/components/BackForwardCacheStrings.ts | keepaliveRequest":{"message":"Back/forward cache is disabled due to a keepalive request."},"panels/application/components/BackForwardCacheStrings.ts | keyboardLock":{"message":"Pages that use Keyboard lock are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | LiveMediaStreamTrack":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | loading":{"message":"The page did not finish loading before navigating away."},"panels/application/components/BackForwardCacheStrings.ts | mainResourceHasCacheControlNoCache":{"message":"Pages whose main resource has cache-control:no-cache cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | mainResourceHasCacheControlNoStore":{"message":"Pages whose main resource has cache-control:no-store cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | navigationCancelledWhileRestoring":{"message":"Navigation was cancelled before the page could be restored from back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | networkExceedsBufferLimit":{"message":"The page was evicted from the cache because an active network connection received too much data. Chrome limits the amount of data that a page may receive while cached."},"panels/application/components/BackForwardCacheStrings.ts | networkRequestDatapipeDrainedAsBytesConsumer":{"message":"Pages that have inflight fetch() or XHR are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | networkRequestRedirected":{"message":"The page was evicted from back/forward cache because an active network request involved a redirect."},"panels/application/components/BackForwardCacheStrings.ts | networkRequestTimeout":{"message":"The page was evicted from the cache because a network connection was open too long. Chrome limits the amount of time that a page may receive data while cached."},"panels/application/components/BackForwardCacheStrings.ts | noResponseHead":{"message":"Pages that do not have a valid response head cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | notMainFrame":{"message":"Navigation happened in a frame other than the main frame."},"panels/application/components/BackForwardCacheStrings.ts | outstandingIndexedDBTransaction":{"message":"Page with ongoing indexed DB transactions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | outstandingNetworkRequestDirectSocket":{"message":"Pages with an in-flight network request are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | outstandingNetworkRequestFetch":{"message":"Pages with an in-flight fetch network request are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | outstandingNetworkRequestOthers":{"message":"Pages with an in-flight network request are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | outstandingNetworkRequestXHR":{"message":"Pages with an in-flight XHR network request are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | ParserAborted":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | paymentManager":{"message":"Pages that use PaymentManager are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | pictureInPicture":{"message":"Pages that use Picture-in-Picture are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | portal":{"message":"Pages that use portals are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | printing":{"message":"Pages that show Printing UI are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | relatedActiveContentsExist":{"message":"The page was opened using 'window.open()' and another tab has a reference to it, or the page opened a window."},"panels/application/components/BackForwardCacheStrings.ts | rendererProcessCrashed":{"message":"The renderer process for the page in back/forward cache crashed."},"panels/application/components/BackForwardCacheStrings.ts | rendererProcessKilled":{"message":"The renderer process for the page in back/forward cache was killed."},"panels/application/components/BackForwardCacheStrings.ts | requestedAudioCapturePermission":{"message":"Pages that have requested audio capture permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedBackForwardCacheBlockedSensors":{"message":"Pages that have requested sensor permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedBackgroundWorkPermission":{"message":"Pages that have requested background sync or fetch permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedMIDIPermission":{"message":"Pages that have requested MIDI permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedNotificationsPermission":{"message":"Pages that have requested notifications permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedStorageAccessGrant":{"message":"Pages that have requested storage access are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | requestedVideoCapturePermission":{"message":"Pages that have requested video capture permissions are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | schemeNotHTTPOrHTTPS":{"message":"Only pages whose URL scheme is HTTP / HTTPS can be cached."},"panels/application/components/BackForwardCacheStrings.ts | serviceWorkerClaim":{"message":"The page was claimed by a service worker while it is in back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | serviceWorkerPostMessage":{"message":"A service worker attempted to send the page in back/forward cache a MessageEvent."},"panels/application/components/BackForwardCacheStrings.ts | serviceWorkerUnregistration":{"message":"ServiceWorker was unregistered while a page was in back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | serviceWorkerVersionActivation":{"message":"The page was evicted from back/forward cache due to a service worker activation."},"panels/application/components/BackForwardCacheStrings.ts | sessionRestored":{"message":"Chrome restarted and cleared the back/forward cache entries."},"panels/application/components/BackForwardCacheStrings.ts | sharedWorker":{"message":"Pages that use SharedWorker are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | SmartCard":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | speechRecognizer":{"message":"Pages that use SpeechRecognizer are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | speechSynthesis":{"message":"Pages that use SpeechSynthesis are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | subframeIsNavigating":{"message":"An iframe on the page started a navigation that did not complete."},"panels/application/components/BackForwardCacheStrings.ts | subresourceHasCacheControlNoCache":{"message":"Pages whose subresource has cache-control:no-cache cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | subresourceHasCacheControlNoStore":{"message":"Pages whose subresource has cache-control:no-store cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | timeout":{"message":"The page exceeded the maximum time in back/forward cache and was expired."},"panels/application/components/BackForwardCacheStrings.ts | timeoutPuttingInCache":{"message":"The page timed out entering back/forward cache (likely due to long-running pagehide handlers)."},"panels/application/components/BackForwardCacheStrings.ts | UnloadHandler":{"message":"Undefined"},"panels/application/components/BackForwardCacheStrings.ts | unloadHandlerExistsInMainFrame":{"message":"The page has an unload handler in the main frame."},"panels/application/components/BackForwardCacheStrings.ts | unloadHandlerExistsInSubFrame":{"message":"The page has an unload handler in a sub frame."},"panels/application/components/BackForwardCacheStrings.ts | userAgentOverrideDiffers":{"message":"Browser has changed the user agent override header."},"panels/application/components/BackForwardCacheStrings.ts | wasGrantedMediaAccess":{"message":"Pages that have granted access to record video or audio are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webDatabase":{"message":"Pages that use WebDatabase are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webHID":{"message":"Pages that use WebHID are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webLocks":{"message":"Pages that use WebLocks are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webNfc":{"message":"Pages that use WebNfc are not currently eligible for back/forwad cache."},"panels/application/components/BackForwardCacheStrings.ts | webOTPService":{"message":"Pages that use WebOTPService are not currently eligible for bfcache."},"panels/application/components/BackForwardCacheStrings.ts | webRTC":{"message":"Pages with WebRTC cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webRTCSticky":{"message":"Back/forward cache is disabled because WebRTC has been used."},"panels/application/components/BackForwardCacheStrings.ts | webShare":{"message":"Pages that use WebShare are not currently eligible for back/forwad cache."},"panels/application/components/BackForwardCacheStrings.ts | webSocket":{"message":"Pages with WebSocket cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webSocketSticky":{"message":"Back/forward cache is disabled because WebSocket has been used."},"panels/application/components/BackForwardCacheStrings.ts | webTransport":{"message":"Pages with WebTransport cannot enter back/forward cache."},"panels/application/components/BackForwardCacheStrings.ts | webTransportSticky":{"message":"Back/forward cache is disabled because WebTransport has been used."},"panels/application/components/BackForwardCacheStrings.ts | webXR":{"message":"Pages that use WebXR are not currently eligible for back/forward cache."},"panels/application/components/BackForwardCacheView.ts | backForwardCacheTitle":{"message":"Back/forward cache"},"panels/application/components/BackForwardCacheView.ts | blankURLTitle":{"message":"Blank URL [{PH1}]"},"panels/application/components/BackForwardCacheView.ts | blockingExtensionId":{"message":"Extension id: "},"panels/application/components/BackForwardCacheView.ts | circumstantial":{"message":"Not Actionable"},"panels/application/components/BackForwardCacheView.ts | circumstantialExplanation":{"message":"These reasons are not actionable i.e. caching was prevented by something outside of the direct control of the page."},"panels/application/components/BackForwardCacheView.ts | filesPerIssue":{"message":"{n, plural, =1 {# file} other {# files}}"},"panels/application/components/BackForwardCacheView.ts | framesPerIssue":{"message":"{n, plural, =1 {# frame} other {# frames}}"},"panels/application/components/BackForwardCacheView.ts | framesTitle":{"message":"Frames"},"panels/application/components/BackForwardCacheView.ts | issuesInMultipleFrames":{"message":"{n, plural, =1 {# issue found in {m} frames.} other {# issues found in {m} frames.}}"},"panels/application/components/BackForwardCacheView.ts | issuesInSingleFrame":{"message":"{n, plural, =1 {# issue found in 1 frame.} other {# issues found in 1 frame.}}"},"panels/application/components/BackForwardCacheView.ts | learnMore":{"message":"Learn more: back/forward cache eligibility"},"panels/application/components/BackForwardCacheView.ts | mainFrame":{"message":"Main Frame"},"panels/application/components/BackForwardCacheView.ts | neverUseUnload":{"message":"Learn more: Never use unload handler"},"panels/application/components/BackForwardCacheView.ts | normalNavigation":{"message":"Not served from back/forward cache: to trigger back/forward cache, use Chrome's back/forward buttons, or use the test button below to automatically navigate away and back."},"panels/application/components/BackForwardCacheView.ts | pageSupportNeeded":{"message":"Actionable"},"panels/application/components/BackForwardCacheView.ts | pageSupportNeededExplanation":{"message":"These reasons are actionable i.e. they can be cleaned up to make the page eligible for back/forward cache."},"panels/application/components/BackForwardCacheView.ts | restoredFromBFCache":{"message":"Successfully served from back/forward cache."},"panels/application/components/BackForwardCacheView.ts | runningTest":{"message":"Running test"},"panels/application/components/BackForwardCacheView.ts | runTest":{"message":"Test back/forward cache"},"panels/application/components/BackForwardCacheView.ts | supportPending":{"message":"Pending Support"},"panels/application/components/BackForwardCacheView.ts | supportPendingExplanation":{"message":"Chrome support for these reasons is pending i.e. they will not prevent the page from being eligible for back/forward cache in a future version of Chrome."},"panels/application/components/BackForwardCacheView.ts | unavailable":{"message":"unavailable"},"panels/application/components/BackForwardCacheView.ts | unknown":{"message":"Unknown Status"},"panels/application/components/BackForwardCacheView.ts | url":{"message":"URL:"},"panels/application/components/BounceTrackingMitigationsView.ts | bounceTrackingMitigationsTitle":{"message":"Bounce tracking mitigations"},"panels/application/components/BounceTrackingMitigationsView.ts | checkingPotentialTrackers":{"message":"Checking for potential bounce tracking sites."},"panels/application/components/BounceTrackingMitigationsView.ts | featureDisabled":{"message":"Bounce tracking mitigations are disabled. To enable them, set the flag at {PH1} to \"Enabled With Deletion\"."},"panels/application/components/BounceTrackingMitigationsView.ts | featureFlag":{"message":"Bounce Tracking Mitigations Feature Flag"},"panels/application/components/BounceTrackingMitigationsView.ts | forceRun":{"message":"Force run"},"panels/application/components/BounceTrackingMitigationsView.ts | learnMore":{"message":"Learn more: Bounce Tracking Mitigations"},"panels/application/components/BounceTrackingMitigationsView.ts | noPotentialBounceTrackersIdentified":{"message":"State was not cleared for any potential bounce tracking sites. Either none were identified or third-party cookies are not blocked."},"panels/application/components/BounceTrackingMitigationsView.ts | runningMitigations":{"message":"Running"},"panels/application/components/BounceTrackingMitigationsView.ts | stateDeletedFor":{"message":"State was deleted for the following sites:"},"panels/application/components/EndpointsGrid.ts | noEndpointsToDisplay":{"message":"No endpoints to display"},"panels/application/components/FrameDetailsView.ts | additionalInformation":{"message":"Additional Information"},"panels/application/components/FrameDetailsView.ts | adStatus":{"message":"Ad Status"},"panels/application/components/FrameDetailsView.ts | aFrameAncestorIsAnInsecure":{"message":"A frame ancestor is an insecure context"},"panels/application/components/FrameDetailsView.ts | apiAvailability":{"message":"API availability"},"panels/application/components/FrameDetailsView.ts | availabilityOfCertainApisDepends":{"message":"Availability of certain APIs depends on the document being cross-origin isolated."},"panels/application/components/FrameDetailsView.ts | available":{"message":"available"},"panels/application/components/FrameDetailsView.ts | availableNotTransferable":{"message":"available, not transferable"},"panels/application/components/FrameDetailsView.ts | availableTransferable":{"message":"available, transferable"},"panels/application/components/FrameDetailsView.ts | child":{"message":"child"},"panels/application/components/FrameDetailsView.ts | childDescription":{"message":"This frame has been identified as a child frame of an ad"},"panels/application/components/FrameDetailsView.ts | clickToRevealInElementsPanel":{"message":"Click to reveal in Elements panel"},"panels/application/components/FrameDetailsView.ts | clickToRevealInNetworkPanel":{"message":"Click to reveal in Network panel"},"panels/application/components/FrameDetailsView.ts | clickToRevealInNetworkPanelMight":{"message":"Click to reveal in Network panel (might require page reload)"},"panels/application/components/FrameDetailsView.ts | clickToRevealInSourcesPanel":{"message":"Click to reveal in Sources panel"},"panels/application/components/FrameDetailsView.ts | contentSecurityPolicy":{"message":"Content Security Policy (CSP)"},"panels/application/components/FrameDetailsView.ts | createdByAdScriptExplanation":{"message":"There was an ad script in the (async) stack when this frame was created. Examining the creation stack trace of this frame might provide more insight."},"panels/application/components/FrameDetailsView.ts | creationStackTrace":{"message":"Frame Creation Stack Trace"},"panels/application/components/FrameDetailsView.ts | creationStackTraceExplanation":{"message":"This frame was created programmatically. The stack trace shows where this happened."},"panels/application/components/FrameDetailsView.ts | creatorAdScript":{"message":"Creator Ad Script"},"panels/application/components/FrameDetailsView.ts | crossoriginIsolated":{"message":"Cross-Origin Isolated"},"panels/application/components/FrameDetailsView.ts | document":{"message":"Document"},"panels/application/components/FrameDetailsView.ts | frameId":{"message":"Frame ID"},"panels/application/components/FrameDetailsView.ts | learnMore":{"message":"Learn more"},"panels/application/components/FrameDetailsView.ts | localhostIsAlwaysASecureContext":{"message":"Localhost is always a secure context"},"panels/application/components/FrameDetailsView.ts | matchedBlockingRuleExplanation":{"message":"This frame is considered an ad frame because its current (or previous) main document is an ad resource."},"panels/application/components/FrameDetailsView.ts | measureMemory":{"message":"Measure Memory"},"panels/application/components/FrameDetailsView.ts | no":{"message":"No"},"panels/application/components/FrameDetailsView.ts | none":{"message":"None"},"panels/application/components/FrameDetailsView.ts | origin":{"message":"Origin"},"panels/application/components/FrameDetailsView.ts | originTrialsExplanation":{"message":"Origin trials give you access to a new or experimental feature."},"panels/application/components/FrameDetailsView.ts | ownerElement":{"message":"Owner Element"},"panels/application/components/FrameDetailsView.ts | parentIsAdExplanation":{"message":"This frame is considered an ad frame because its parent frame is an ad frame."},"panels/application/components/FrameDetailsView.ts | reportingTo":{"message":"reporting to"},"panels/application/components/FrameDetailsView.ts | requiresCrossoriginIsolated":{"message":"requires cross-origin isolated context"},"panels/application/components/FrameDetailsView.ts | root":{"message":"root"},"panels/application/components/FrameDetailsView.ts | rootDescription":{"message":"This frame has been identified as the root frame of an ad"},"panels/application/components/FrameDetailsView.ts | secureContext":{"message":"Secure Context"},"panels/application/components/FrameDetailsView.ts | securityIsolation":{"message":"Security & Isolation"},"panels/application/components/FrameDetailsView.ts | sharedarraybufferConstructorIs":{"message":"SharedArrayBuffer constructor is available and SABs can be transferred via postMessage"},"panels/application/components/FrameDetailsView.ts | sharedarraybufferConstructorIsAvailable":{"message":"SharedArrayBuffer constructor is available but SABs cannot be transferred via postMessage"},"panels/application/components/FrameDetailsView.ts | theFramesSchemeIsInsecure":{"message":"The frame's scheme is insecure"},"panels/application/components/FrameDetailsView.ts | thePerformanceAPI":{"message":"The performance.measureUserAgentSpecificMemory() API is available"},"panels/application/components/FrameDetailsView.ts | thePerformancemeasureuseragentspecificmemory":{"message":"The performance.measureUserAgentSpecificMemory() API is not available"},"panels/application/components/FrameDetailsView.ts | thisAdditionalDebugging":{"message":"This additional (debugging) information is shown because the 'Protocol Monitor' experiment is enabled."},"panels/application/components/FrameDetailsView.ts | transferRequiresCrossoriginIsolatedPermission":{"message":"SharedArrayBuffer transfer requires enabling the permission policy:"},"panels/application/components/FrameDetailsView.ts | unavailable":{"message":"unavailable"},"panels/application/components/FrameDetailsView.ts | unreachableUrl":{"message":"Unreachable URL"},"panels/application/components/FrameDetailsView.ts | url":{"message":"URL"},"panels/application/components/FrameDetailsView.ts | willRequireCrossoriginIsolated":{"message":"⚠️ will require cross-origin isolated context in the future"},"panels/application/components/FrameDetailsView.ts | yes":{"message":"Yes"},"panels/application/components/InterestGroupAccessGrid.ts | allInterestGroupStorageEvents":{"message":"All interest group storage events."},"panels/application/components/InterestGroupAccessGrid.ts | eventTime":{"message":"Event Time"},"panels/application/components/InterestGroupAccessGrid.ts | eventType":{"message":"Access Type"},"panels/application/components/InterestGroupAccessGrid.ts | groupName":{"message":"Name"},"panels/application/components/InterestGroupAccessGrid.ts | groupOwner":{"message":"Owner"},"panels/application/components/InterestGroupAccessGrid.ts | noEvents":{"message":"No interest group events recorded."},"panels/application/components/OriginTrialTreeView.ts | expiryTime":{"message":"Expiry Time"},"panels/application/components/OriginTrialTreeView.ts | isThirdParty":{"message":"Third Party"},"panels/application/components/OriginTrialTreeView.ts | matchSubDomains":{"message":"Subdomain Matching"},"panels/application/components/OriginTrialTreeView.ts | noTrialTokens":{"message":"No trial tokens"},"panels/application/components/OriginTrialTreeView.ts | origin":{"message":"Origin"},"panels/application/components/OriginTrialTreeView.ts | rawTokenText":{"message":"Raw Token"},"panels/application/components/OriginTrialTreeView.ts | status":{"message":"Token Status"},"panels/application/components/OriginTrialTreeView.ts | token":{"message":"Token"},"panels/application/components/OriginTrialTreeView.ts | tokens":{"message":"{PH1} tokens"},"panels/application/components/OriginTrialTreeView.ts | trialName":{"message":"Trial Name"},"panels/application/components/OriginTrialTreeView.ts | usageRestriction":{"message":"Usage Restriction"},"panels/application/components/PermissionsPolicySection.ts | allowedFeatures":{"message":"Allowed Features"},"panels/application/components/PermissionsPolicySection.ts | clickToShowHeader":{"message":"Click to reveal the request whose \"Permissions-Policy\" HTTP header disables this feature."},"panels/application/components/PermissionsPolicySection.ts | clickToShowIframe":{"message":"Click to reveal the top-most iframe which does not allow this feature in the elements panel."},"panels/application/components/PermissionsPolicySection.ts | disabledByFencedFrame":{"message":"disabled inside a fencedframe"},"panels/application/components/PermissionsPolicySection.ts | disabledByHeader":{"message":"disabled by \"Permissions-Policy\" header"},"panels/application/components/PermissionsPolicySection.ts | disabledByIframe":{"message":"missing in iframe \"allow\" attribute"},"panels/application/components/PermissionsPolicySection.ts | disabledFeatures":{"message":"Disabled Features"},"panels/application/components/PermissionsPolicySection.ts | hideDetails":{"message":"Hide details"},"panels/application/components/PermissionsPolicySection.ts | showDetails":{"message":"Show details"},"panels/application/components/ProtocolHandlersView.ts | dropdownLabel":{"message":"Select protocol handler"},"panels/application/components/ProtocolHandlersView.ts | manifest":{"message":"manifest"},"panels/application/components/ProtocolHandlersView.ts | needHelpReadOur":{"message":"Need help? Read {PH1}."},"panels/application/components/ProtocolHandlersView.ts | protocolDetected":{"message":"Found valid protocol handler registration in the {PH1}. With the app installed, test the registered protocols."},"panels/application/components/ProtocolHandlersView.ts | protocolHandlerRegistrations":{"message":"URL protocol handler registration for PWAs"},"panels/application/components/ProtocolHandlersView.ts | protocolNotDetected":{"message":"Define protocol handlers in the {PH1} to register your app as a handler for custom protocols when your app is installed."},"panels/application/components/ProtocolHandlersView.ts | testProtocol":{"message":"Test protocol"},"panels/application/components/ProtocolHandlersView.ts | textboxLabel":{"message":"Query parameter or endpoint for protocol handler"},"panels/application/components/ProtocolHandlersView.ts | textboxPlaceholder":{"message":"Enter URL"},"panels/application/components/ReportsGrid.ts | destination":{"message":"Destination"},"panels/application/components/ReportsGrid.ts | generatedAt":{"message":"Generated at"},"panels/application/components/ReportsGrid.ts | noReportsToDisplay":{"message":"No reports to display"},"panels/application/components/ReportsGrid.ts | status":{"message":"Status"},"panels/application/components/SharedStorageAccessGrid.ts | allSharedStorageEvents":{"message":"All shared storage events for this page."},"panels/application/components/SharedStorageAccessGrid.ts | eventParams":{"message":"Optional Event Params"},"panels/application/components/SharedStorageAccessGrid.ts | eventTime":{"message":"Event Time"},"panels/application/components/SharedStorageAccessGrid.ts | eventType":{"message":"Access Type"},"panels/application/components/SharedStorageAccessGrid.ts | mainFrameId":{"message":"Main Frame ID"},"panels/application/components/SharedStorageAccessGrid.ts | noEvents":{"message":"No shared storage events recorded."},"panels/application/components/SharedStorageAccessGrid.ts | ownerOrigin":{"message":"Owner Origin"},"panels/application/components/SharedStorageAccessGrid.ts | sharedStorage":{"message":"Shared storage"},"panels/application/components/SharedStorageMetadataView.ts | budgetExplanation":{"message":"Remaining data leakage allowed within a 24-hour period for this origin in bits of entropy"},"panels/application/components/SharedStorageMetadataView.ts | creation":{"message":"Creation Time"},"panels/application/components/SharedStorageMetadataView.ts | entropyBudget":{"message":"Entropy Budget for Fenced Frames"},"panels/application/components/SharedStorageMetadataView.ts | notYetCreated":{"message":"Not yet created"},"panels/application/components/SharedStorageMetadataView.ts | numBytesUsed":{"message":"Number of Bytes Used"},"panels/application/components/SharedStorageMetadataView.ts | numEntries":{"message":"Number of Entries"},"panels/application/components/SharedStorageMetadataView.ts | resetBudget":{"message":"Reset Budget"},"panels/application/components/SharedStorageMetadataView.ts | sharedStorage":{"message":"Shared storage"},"panels/application/components/StackTrace.ts | cannotRenderStackTrace":{"message":"Cannot render stack trace"},"panels/application/components/StackTrace.ts | creationStackTrace":{"message":"Frame Creation Stack Trace"},"panels/application/components/StackTrace.ts | showLess":{"message":"Show less"},"panels/application/components/StackTrace.ts | showSMoreFrames":{"message":"{n, plural, =1 {Show # more frame} other {Show # more frames}}"},"panels/application/components/StorageMetadataView.ts | bucketName":{"message":"Bucket name"},"panels/application/components/StorageMetadataView.ts | confirmBucketDeletion":{"message":"Delete the \"{PH1}\" bucket?"},"panels/application/components/StorageMetadataView.ts | defaultBucket":{"message":"Default bucket"},"panels/application/components/StorageMetadataView.ts | deleteBucket":{"message":"Delete bucket"},"panels/application/components/StorageMetadataView.ts | durability":{"message":"Durability"},"panels/application/components/StorageMetadataView.ts | expiration":{"message":"Expiration"},"panels/application/components/StorageMetadataView.ts | isOpaque":{"message":"Is opaque"},"panels/application/components/StorageMetadataView.ts | isThirdParty":{"message":"Is third-party"},"panels/application/components/StorageMetadataView.ts | loading":{"message":"Loading…"},"panels/application/components/StorageMetadataView.ts | no":{"message":"No"},"panels/application/components/StorageMetadataView.ts | none":{"message":"None"},"panels/application/components/StorageMetadataView.ts | opaque":{"message":"(opaque)"},"panels/application/components/StorageMetadataView.ts | origin":{"message":"Origin"},"panels/application/components/StorageMetadataView.ts | persistent":{"message":"Is persistent"},"panels/application/components/StorageMetadataView.ts | quota":{"message":"Quota"},"panels/application/components/StorageMetadataView.ts | topLevelSite":{"message":"Top-level site"},"panels/application/components/StorageMetadataView.ts | yes":{"message":"Yes"},"panels/application/components/StorageMetadataView.ts | yesBecauseAncestorChainHasCrossSite":{"message":"Yes, because the ancestry chain contains a third-party origin"},"panels/application/components/StorageMetadataView.ts | yesBecauseKeyIsOpaque":{"message":"Yes, because the storage key is opaque"},"panels/application/components/StorageMetadataView.ts | yesBecauseOriginNotInTopLevelSite":{"message":"Yes, because the origin is outside of the top-level site"},"panels/application/components/StorageMetadataView.ts | yesBecauseTopLevelIsOpaque":{"message":"Yes, because the top-level site is opaque"},"panels/application/components/TrustTokensView.ts | allStoredTrustTokensAvailableIn":{"message":"All stored private state tokens available in this browser instance."},"panels/application/components/TrustTokensView.ts | deleteTrustTokens":{"message":"Delete all stored private state tokens issued by {PH1}."},"panels/application/components/TrustTokensView.ts | issuer":{"message":"Issuer"},"panels/application/components/TrustTokensView.ts | noTrustTokensStored":{"message":"No private state tokens are currently stored."},"panels/application/components/TrustTokensView.ts | storedTokenCount":{"message":"Stored token count"},"panels/application/components/TrustTokensView.ts | trustTokens":{"message":"Private state tokens"},"panels/application/CookieItemsView.ts | clearAllCookies":{"message":"Clear all cookies"},"panels/application/CookieItemsView.ts | clearFilteredCookies":{"message":"Clear filtered cookies"},"panels/application/CookieItemsView.ts | cookies":{"message":"Cookies"},"panels/application/CookieItemsView.ts | numberOfCookiesShownInTableS":{"message":"Number of cookies shown in table: {PH1}"},"panels/application/CookieItemsView.ts | onlyShowCookiesWhichHaveAn":{"message":"Only show cookies that have an associated issue"},"panels/application/CookieItemsView.ts | onlyShowCookiesWithAnIssue":{"message":"Only show cookies with an issue"},"panels/application/CookieItemsView.ts | selectACookieToPreviewItsValue":{"message":"Select a cookie to preview its value"},"panels/application/CookieItemsView.ts | showUrlDecoded":{"message":"Show URL-decoded"},"panels/application/DOMStorageItemsView.ts | domStorage":{"message":"DOM Storage"},"panels/application/DOMStorageItemsView.ts | domStorageItemDeleted":{"message":"The storage item was deleted."},"panels/application/DOMStorageItemsView.ts | domStorageItems":{"message":"DOM Storage Items"},"panels/application/DOMStorageItemsView.ts | domStorageItemsCleared":{"message":"DOM Storage Items cleared"},"panels/application/DOMStorageItemsView.ts | domStorageNumberEntries":{"message":"Number of entries shown in table: {PH1}"},"panels/application/DOMStorageItemsView.ts | key":{"message":"Key"},"panels/application/DOMStorageItemsView.ts | selectAValueToPreview":{"message":"Select a value to preview"},"panels/application/DOMStorageItemsView.ts | value":{"message":"Value"},"panels/application/IndexedDBViews.ts | clearObjectStore":{"message":"Clear object store"},"panels/application/IndexedDBViews.ts | collapse":{"message":"Collapse"},"panels/application/IndexedDBViews.ts | dataMayBeStale":{"message":"Data may be stale"},"panels/application/IndexedDBViews.ts | deleteDatabase":{"message":"Delete database"},"panels/application/IndexedDBViews.ts | deleteSelected":{"message":"Delete selected"},"panels/application/IndexedDBViews.ts | expandRecursively":{"message":"Expand Recursively"},"panels/application/IndexedDBViews.ts | idb":{"message":"IDB"},"panels/application/IndexedDBViews.ts | indexedDb":{"message":"Indexed DB"},"panels/application/IndexedDBViews.ts | keyGeneratorValueS":{"message":"Key generator value: {PH1}"},"panels/application/IndexedDBViews.ts | keyPath":{"message":"Key path: "},"panels/application/IndexedDBViews.ts | keyString":{"message":"Key"},"panels/application/IndexedDBViews.ts | objectStores":{"message":"Object stores"},"panels/application/IndexedDBViews.ts | pleaseConfirmDeleteOfSDatabase":{"message":"Please confirm delete of \"{PH1}\" database."},"panels/application/IndexedDBViews.ts | primaryKey":{"message":"Primary key"},"panels/application/IndexedDBViews.ts | refresh":{"message":"Refresh"},"panels/application/IndexedDBViews.ts | refreshDatabase":{"message":"Refresh database"},"panels/application/IndexedDBViews.ts | showNextPage":{"message":"Show next page"},"panels/application/IndexedDBViews.ts | showPreviousPage":{"message":"Show previous page"},"panels/application/IndexedDBViews.ts | someEntriesMayHaveBeenModified":{"message":"Some entries may have been modified"},"panels/application/IndexedDBViews.ts | startFromKey":{"message":"Start from key"},"panels/application/IndexedDBViews.ts | totalEntriesS":{"message":"Total entries: {PH1}"},"panels/application/IndexedDBViews.ts | valueString":{"message":"Value"},"panels/application/IndexedDBViews.ts | version":{"message":"Version"},"panels/application/InterestGroupStorageView.ts | clickToDisplayBody":{"message":"Click on any interest group event to display the group's current state"},"panels/application/InterestGroupStorageView.ts | noDataAvailable":{"message":"No details available for the selected interest group. The browser may have left the group."},"panels/application/InterestGroupTreeElement.ts | interestGroups":{"message":"Interest groups"},"panels/application/OpenedWindowDetailsView.ts | accessToOpener":{"message":"Access to opener"},"panels/application/OpenedWindowDetailsView.ts | clickToRevealInElementsPanel":{"message":"Click to reveal in Elements panel"},"panels/application/OpenedWindowDetailsView.ts | closed":{"message":"closed"},"panels/application/OpenedWindowDetailsView.ts | crossoriginEmbedderPolicy":{"message":"Cross-Origin Embedder Policy"},"panels/application/OpenedWindowDetailsView.ts | document":{"message":"Document"},"panels/application/OpenedWindowDetailsView.ts | no":{"message":"No"},"panels/application/OpenedWindowDetailsView.ts | openerFrame":{"message":"Opener Frame"},"panels/application/OpenedWindowDetailsView.ts | reportingTo":{"message":"reporting to"},"panels/application/OpenedWindowDetailsView.ts | security":{"message":"Security"},"panels/application/OpenedWindowDetailsView.ts | securityIsolation":{"message":"Security & Isolation"},"panels/application/OpenedWindowDetailsView.ts | showsWhetherTheOpenedWindowIs":{"message":"Shows whether the opened window is able to access its opener and vice versa"},"panels/application/OpenedWindowDetailsView.ts | type":{"message":"Type"},"panels/application/OpenedWindowDetailsView.ts | unknown":{"message":"Unknown"},"panels/application/OpenedWindowDetailsView.ts | url":{"message":"URL"},"panels/application/OpenedWindowDetailsView.ts | webWorker":{"message":"Web Worker"},"panels/application/OpenedWindowDetailsView.ts | windowWithoutTitle":{"message":"Window without title"},"panels/application/OpenedWindowDetailsView.ts | worker":{"message":"worker"},"panels/application/OpenedWindowDetailsView.ts | yes":{"message":"Yes"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | action":{"message":"Action"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | status":{"message":"Status"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusFailure":{"message":"Failure"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusNotTriggered":{"message":"Not triggered"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusPending":{"message":"Pending"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusReady":{"message":"Ready"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusRunning":{"message":"Running"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | statusSuccess":{"message":"Success"},"panels/application/preloading/components/MismatchedPreloadingGrid.ts | url":{"message":"URL"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | buttonClickToInspect":{"message":"Click to inspect prerendered page"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | buttonClickToRevealRuleSet":{"message":"Click to reveal rule set"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | buttonInspect":{"message":"Inspect"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusFailure":{"message":"Speculative load failed."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusNotTriggered":{"message":"Speculative load attempt is not yet triggered."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusPending":{"message":"Speculative load attempt is eligible but pending."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusReady":{"message":"Speculative load finished and the result is ready for the next navigation."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusRunning":{"message":"Speculative load is running."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailedStatusSuccess":{"message":"Speculative load finished and used for a navigation."},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailsAction":{"message":"Action"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailsDetailedInformation":{"message":"Detailed information"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailsFailureReason":{"message":"Failure reason"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailsRuleSet":{"message":"Rule set"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | detailsStatus":{"message":"Status"},"panels/application/preloading/components/PreloadingDetailsReportView.ts | selectAnElementForMoreDetails":{"message":"Select an element for more details"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | descriptionDisabledByBatterySaver":{"message":"Speculative loading is disabled because of the operating system's Battery Saver mode."},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | descriptionDisabledByDataSaver":{"message":"Speculative loading is disabled because of the operating system's Data Saver mode."},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | descriptionDisabledByHoldbackPrefetchSpeculationRules":{"message":"Prefetch is forced-enabled because DevTools is open. When DevTools is closed, prefetch will be disabled because this browser session is part of a holdback group used for performance comparisons."},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | descriptionDisabledByHoldbackPrerenderSpeculationRules":{"message":"Prerendering is forced-enabled because DevTools is open. When DevTools is closed, prerendering will be disabled because this browser session is part of a holdback group used for performance comparisons."},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | descriptionDisabledByPreference":{"message":"Speculative loading is disabled because of user settings or an extension. Go to {PH1} to update your preference. Go to {PH2} to disable any extension that blocks speculative loading."},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | extensionsSettings":{"message":"Extensions settings"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | footerLearnMore":{"message":"Learn more"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | headerDisabledByBatterySaver":{"message":"Battery Saver"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | headerDisabledByDataSaver":{"message":"Data Saver"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | headerDisabledByHoldbackPrefetchSpeculationRules":{"message":"Prefetch was disabled, but is force-enabled now"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | headerDisabledByHoldbackPrerenderSpeculationRules":{"message":"Prerendering was disabled, but is force-enabled now"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | headerDisabledByPreference":{"message":"User settings or extensions"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | infobarPreloadingIsDisabled":{"message":"Speculative loading is disabled"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | infobarPreloadingIsForceEnabled":{"message":"Speculative loading is force-enabled"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | preloadingPagesSettings":{"message":"Preload pages settings"},"panels/application/preloading/components/PreloadingDisabledInfobar.ts | titleReasonsPreventingPreloading":{"message":"Reasons preventing speculative loading"},"panels/application/preloading/components/PreloadingGrid.ts | action":{"message":"Action"},"panels/application/preloading/components/PreloadingGrid.ts | ruleSet":{"message":"Rule set"},"panels/application/preloading/components/PreloadingGrid.ts | status":{"message":"Status"},"panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts | activationNavigationValue":{"message":"Value in activation navigation"},"panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts | headerName":{"message":"Header name"},"panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts | initialNavigationValue":{"message":"Value in initial navigation"},"panels/application/preloading/components/PreloadingMismatchedHeadersGrid.ts | missing":{"message":"(missing)"},"panels/application/preloading/components/PreloadingString.ts | PrefetchEvictedAfterCandidateRemoved":{"message":"The prefetch was discarded because no speculation rule in the initating page triggers a prefetch for this URL anymore."},"panels/application/preloading/components/PreloadingString.ts | PrefetchEvictedForNewerPrefetch":{"message":"The prefetch was discarded because the initiating page has too many prefetches ongoing, and this was one of the oldest."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedIneligibleRedirect":{"message":"The prefetch was redirected, but the redirect URL is not eligible for prefetch."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedInvalidRedirect":{"message":"The prefetch was redirected, but there was a problem with the redirect."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedMIMENotSupported":{"message":"The prefetch failed because the response's Content-Type header was not supported."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedNetError":{"message":"The prefetch failed because of a network error."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedNon2XX":{"message":"The prefetch failed because of a non-2xx HTTP response status code."},"panels/application/preloading/components/PreloadingString.ts | PrefetchFailedPerPageLimitExceeded":{"message":"The prefetch was not performed because the initiating page already has too many prefetches ongoing."},"panels/application/preloading/components/PreloadingString.ts | PrefetchIneligibleRetryAfter":{"message":"A previous prefetch to the origin got a HTTP 503 response with an Retry-After header that has not elapsed yet."},"panels/application/preloading/components/PreloadingString.ts | PrefetchIsPrivacyDecoy":{"message":"The URL was not eligible to be prefetched because there was a registered service worker or cross-site cookies for that origin, but the prefetch was put on the network anyways and not used, to disguise that the user had some kind of previous relationship with the origin."},"panels/application/preloading/components/PreloadingString.ts | PrefetchIsStale":{"message":"Too much time elapsed between the prefetch and usage, so the prefetch was discarded."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleBatterySaverEnabled":{"message":"The prefetch was not performed because the Battery Saver setting was enabled."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleBrowserContextOffTheRecord":{"message":"The prefetch was not performed because the browser is in Incognito or Guest mode."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleDataSaverEnabled":{"message":"The prefetch was not performed because the operating system is in Data Saver mode."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleExistingProxy":{"message":"The URL is not eligible to be prefetched, because in the default network context it is configured to use a proxy server."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleHostIsNonUnique":{"message":"The URL was not eligible to be prefetched because its host was not unique (e.g., a non publicly routable IP address or a hostname which is not registry-controlled), but the prefetch was required to be proxied."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleNonDefaultStoragePartition":{"message":"The URL was not eligible to be prefetched because it uses a non-default storage partition."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligiblePreloadingDisabled":{"message":"The prefetch was not performed because speculative loading was disabled."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleSameSiteCrossOriginPrefetchRequiredProxy":{"message":"The URL was not eligible to be prefetched because the default network context cannot be configured to use the prefetch proxy for a same-site cross-origin prefetch request."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleSchemeIsNotHttps":{"message":"The URL was not eligible to be prefetched because its scheme was not https:."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleUserHasCookies":{"message":"The URL was not eligible to be prefetched because it was cross-site, but the user had cookies for that origin."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotEligibleUserHasServiceWorker":{"message":"The URL was not eligible to be prefetched because there was a registered service worker for that origin, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotUsedCookiesChanged":{"message":"The prefetch was not used because it was a cross-site prefetch, and cookies were added for that URL while the prefetch was ongoing, so the prefetched response is now out-of-date."},"panels/application/preloading/components/PreloadingString.ts | PrefetchNotUsedProbeFailed":{"message":"The prefetch was blocked by your Internet Service Provider or network administrator."},"panels/application/preloading/components/PreloadingString.ts | PrefetchProxyNotAvailable":{"message":"A network error was encountered when trying to set up a connection to the prefetching proxy."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusActivatedDuringMainFrameNavigation":{"message":"Prerendered page activated during initiating page's main frame navigation."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusActivatedWithAuxiliaryBrowsingContexts":{"message":"The prerender was not used because during activation time, there were other windows with an active opener reference to the initiating page, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusActivationFramePolicyNotCompatible":{"message":"The prerender was not used because the sandboxing flags or permissions policy of the initiating page was not compatible with those of the prerendering page."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusActivationNavigationParameterMismatch":{"message":"The prerender was not used because during activation time, different navigation parameters (e.g., HTTP headers) were calculated than during the original prerendering navigation request."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusActivationUrlHasEffectiveUrl":{"message":"The prerender was not used because during activation time, navigation has an effective URL that is different from its normal URL. (For example, the New Tab Page, or hosted apps.)"},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusAudioOutputDeviceRequested":{"message":"The prerendered page requested audio output, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusBatterySaverEnabled":{"message":"The prerender was not performed because the user requested that the browser use less battery."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusBlockedByClient":{"message":"Some resource load was blocked."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusClientCertRequested":{"message":"The prerendering navigation required a HTTP client certificate."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusCrossSiteNavigationInInitialNavigation":{"message":"The prerendering navigation failed because it targeted a cross-site URL."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusCrossSiteNavigationInMainFrameNavigation":{"message":"The prerendered page navigated to a cross-site URL."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusCrossSiteRedirectInInitialNavigation":{"message":"The prerendering navigation failed because the prerendered URL redirected to a cross-site URL."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusCrossSiteRedirectInMainFrameNavigation":{"message":"The prerendered page navigated to a URL which redirected to a cross-site URL."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusDataSaverEnabled":{"message":"The prerender was not performed because the user requested that the browser use less data."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusDownload":{"message":"The prerendered page attempted to initiate a download, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusHasEffectiveUrl":{"message":"The initiating page cannot perform prerendering, because it has an effective URL that is different from its normal URL. (For example, the New Tab Page, or hosted apps.)"},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusInvalidSchemeNavigation":{"message":"The URL was not eligible to be prerendered because its scheme was not http: or https:."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusInvalidSchemeRedirect":{"message":"The prerendering navigation failed because it redirected to a URL whose scheme was not http: or https:."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusLoginAuthRequested":{"message":"The prerendering navigation required HTTP authentication, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusLowEndDevice":{"message":"The prerender was not performed because this device does not have enough total system memory to support prerendering."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMainFrameNavigation":{"message":"The prerendered page navigated itself to another URL, which is currently not supported."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMaxNumOfRunningEagerPrerendersExceeded":{"message":"The prerender whose eagerness is \"eager\" was not performed because the initiating page already has too many prerenders ongoing. Remove other speculation rules with \"eager\" to enable further prerendering."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMaxNumOfRunningEmbedderPrerendersExceeded":{"message":"The browser-triggered prerender was not performed because the initiating page already has too many prerenders ongoing."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMaxNumOfRunningNonEagerPrerendersExceeded":{"message":"The old non-eager prerender (with a \"moderate\" or \"conservative\" eagerness and triggered by hovering or clicking links) was automatically canceled due to starting a new non-eager prerender. It can be retriggered by interacting with the link again."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMemoryLimitExceeded":{"message":"The prerender was not performed because the browser exceeded the prerendering memory limit."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMemoryPressureAfterTriggered":{"message":"The prerendered page was unloaded because the browser came under critical memory pressure."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMemoryPressureOnTrigger":{"message":"The prerender was not performed because the browser was under critical memory pressure."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMixedContent":{"message":"The prerendered page contained mixed content."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusMojoBinderPolicy":{"message":"The prerendered page used a forbidden JavaScript API that is currently not supported. (Internal Mojo interface: {PH1})"},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusNavigationBadHttpStatus":{"message":"The prerendering navigation failed because of a non-2xx HTTP response status code."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusNavigationRequestBlockedByCsp":{"message":"The prerendering navigation was blocked by a Content Security Policy."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusNavigationRequestNetworkError":{"message":"The prerendering navigation encountered a network error."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusPreloadingDisabled":{"message":"The prerender was not performed because the user disabled preloading in their browser settings."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusPrerenderingDisabledByDevTools":{"message":"The prerender was not performed because DevTools has been used to disable prerendering."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusPrerenderingUrlHasEffectiveUrl":{"message":"The prerendering navigation failed because it has an effective URL that is different from its normal URL. (For example, the New Tab Page, or hosted apps.)"},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusPrimaryMainFrameRendererProcessCrashed":{"message":"The initiating page crashed."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusPrimaryMainFrameRendererProcessKilled":{"message":"The initiating page was killed."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusRedirectedPrerenderingUrlHasEffectiveUrl":{"message":"The prerendering navigation failed because it redirected to an effective URL that is different from its normal URL. (For example, the New Tab Page, or hosted apps.)"},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusRendererProcessCrashed":{"message":"The prerendered page crashed."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusRendererProcessKilled":{"message":"The prerendered page was killed."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusSameSiteCrossOriginNavigationNotOptInInInitialNavigation":{"message":"The prerendering navigation failed because it was to a cross-origin same-site URL, but the destination response did not include the appropriate Supports-Loading-Mode header."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusSameSiteCrossOriginNavigationNotOptInInMainFrameNavigation":{"message":"The prerendered page navigated to a cross-origin same-site URL, but the destination response did not include the appropriate Supports-Loading-Mode header."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusSameSiteCrossOriginRedirectNotOptInInInitialNavigation":{"message":"The prerendering navigation failed because the prerendered URL redirected to a cross-origin same-site URL, but the destination response did not include the appropriate Supports-Loading-Mode header."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusSameSiteCrossOriginRedirectNotOptInInMainFrameNavigation":{"message":"The prerendered page navigated to a URL which redirected to a cross-origin same-site URL, but the destination response did not include the appropriate Supports-Loading-Mode header."},"panels/application/preloading/components/PreloadingString.ts | prerenderFinalStatusSpeculationRuleRemoved":{"message":"The prerendered page was unloaded because the initiating page removed the corresponding prerender rule from