diff --git a/.github/actions/e2e-ios/action.yml b/.github/actions/e2e-ios/action.yml
new file mode 100644
index 00000000..5264288a
--- /dev/null
+++ b/.github/actions/e2e-ios/action.yml
@@ -0,0 +1,101 @@
+name: iOS E2E (Detox)
+description: Build and run Detox iOS end-to-end tests for a brownfield example app
+
+inputs:
+ app-path:
+ description: 'Path to the app workspace (e.g. apps/RNApp)'
+ required: true
+
+ run-expo-prebuild:
+ description: 'Run brownfield codegen and Expo iOS prebuild before pod install'
+ required: false
+ default: 'false'
+
+ run-brownfield-codegen:
+ description: 'Run brownfield codegen before building (required for RNApp)'
+ required: false
+ default: 'false'
+
+ artifact-name:
+ description: 'Name prefix for Detox artifacts uploaded on failure'
+ required: false
+ default: 'detox'
+
+runs:
+ using: composite
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
+
+ - name: Setup
+ uses: ./.github/actions/setup
+
+ - name: Prepare iOS environment
+ uses: ./.github/actions/prepare-ios
+
+ - name: Install applesimutils
+ run: |
+ brew tap wix/brew
+ brew install applesimutils
+ shell: bash
+
+ - name: Brownfield codegen
+ if: inputs.run-brownfield-codegen == 'true'
+ run: yarn codegen
+ working-directory: ${{ inputs.app-path }}
+ shell: bash
+
+ - name: Expo iOS prebuild
+ if: inputs.run-expo-prebuild == 'true'
+ run: |
+ node ../../packages/cli/dist/main.js codegen
+ yarn expo prebuild --platform ios --no-install
+ working-directory: ${{ inputs.app-path }}
+ shell: bash
+
+ - name: Restore Pods cache
+ uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
+ with:
+ path: ${{ inputs.app-path }}/ios/Pods
+ key: ${{ runner.os }}-e2e-ios-pods-${{ inputs.app-path }}-${{ hashFiles(format('{0}/ios/Podfile.lock', inputs.app-path)) }}
+ restore-keys: |
+ ${{ runner.os }}-e2e-ios-pods-${{ inputs.app-path }}-
+
+ - name: Install CocoaPods
+ env:
+ # RNApp + RNScreens: prebuilt React-Core can fail Debug simulator linking.
+ RCT_USE_PREBUILT_RNCORE: ${{ inputs.app-path == 'apps/RNApp' && '0' || '' }}
+ run: pod install
+ working-directory: ${{ inputs.app-path }}/ios
+ shell: bash
+
+ - name: Restore Detox build cache
+ uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
+ with:
+ path: ${{ inputs.app-path }}/ios/build
+ key: ${{ runner.os }}-e2e-ios-build-${{ inputs.app-path }}-${{ hashFiles(format('{0}/ios/Podfile.lock', inputs.app-path), format('{0}/ios/*.xcodeproj/project.pbxproj', inputs.app-path)) }}
+ restore-keys: |
+ ${{ runner.os }}-e2e-ios-build-${{ inputs.app-path }}-
+
+ - name: Install Detox iOS artifacts
+ run: node node_modules/detox/scripts/postinstall.js
+ working-directory: ${{ inputs.app-path }}
+ shell: bash
+
+ - name: Detox build (iOS Simulator)
+ run: yarn e2e:build:ios
+ working-directory: ${{ inputs.app-path }}
+ shell: bash
+
+ - name: Detox test (iOS Simulator)
+ run: yarn e2e:test:ios
+ working-directory: ${{ inputs.app-path }}
+ shell: bash
+
+ - name: Upload Detox artifacts on failure
+ if: failure()
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
+ with:
+ name: ${{ inputs.artifact-name }}-ios
+ path: ${{ inputs.app-path }}/artifacts
+ if-no-files-found: ignore
diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml
index 0ad48b82..b74ae79b 100644
--- a/.github/actions/setup/action.yml
+++ b/.github/actions/setup/action.yml
@@ -17,6 +17,10 @@ runs:
cache: 'yarn'
- name: Install dependencies
+ env:
+ # Monorepo has detox in multiple workspaces; parallel postinstalls race on
+ # $HOME/Library/Detox/ios/framework. E2E jobs run postinstall once later.
+ DETOX_DISABLE_POSTINSTALL: '1'
run: yarn install
shell: bash
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c728c56e..2c2cf53d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -5,11 +5,16 @@ on:
branches: [main]
pull_request:
branches: [main]
+ workflow_dispatch:
concurrency:
- group: pr-${{ github.event.pull_request.number }}
+ group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
+permissions:
+ contents: read
+ actions: write
+
jobs:
filter:
name: Detect changed paths
@@ -35,10 +40,13 @@ jobs:
- 'packages/**'
rnapp:
- 'apps/RNApp/**'
+ - 'apps/brownfield-example-shared-tests/**'
expo54:
- 'apps/ExpoApp54/**'
+ - 'apps/brownfield-example-shared-tests/**'
expo55:
- 'apps/ExpoApp55/**'
+ - 'apps/brownfield-example-shared-tests/**'
androidapp:
- 'apps/AndroidApp/**'
appleapp:
@@ -220,3 +228,64 @@ jobs:
with:
variant: expo${{ matrix.version }}
rn-project-path: apps/ExpoApp${{ matrix.version }}
+
+ e2e-ios-rnapp:
+ name: E2E iOS (RNApp)
+ runs-on: macos-26
+ timeout-minutes: 90
+ permissions:
+ contents: read
+ actions: write
+ needs: [filter, build-lint]
+ if: |
+ always() &&
+ (
+ needs.filter.outputs.rnapp == 'true' ||
+ needs.filter.outputs.packages == 'true' ||
+ needs.filter.outputs.ci == 'true'
+ ) &&
+ (needs.build-lint.result == 'success' || needs.build-lint.result == 'skipped')
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
+
+ - name: Run Detox E2E (RNApp)
+ uses: ./.github/actions/e2e-ios
+ with:
+ app-path: apps/RNApp
+ artifact-name: detox-rnapp
+ run-brownfield-codegen: 'true'
+
+ e2e-ios-expo:
+ name: E2E iOS (Expo ${{ matrix.version }})
+ runs-on: macos-26
+ timeout-minutes: 90
+ permissions:
+ contents: read
+ actions: write
+ needs: [filter, build-lint]
+ if: |
+ always() &&
+ (
+ needs.filter.outputs.expo54 == 'true' ||
+ needs.filter.outputs.expo55 == 'true' ||
+ needs.filter.outputs.packages == 'true' ||
+ needs.filter.outputs.ci == 'true'
+ ) &&
+ (needs.build-lint.result == 'success' || needs.build-lint.result == 'skipped')
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - version: '54'
+ - version: '55'
+ steps:
+ - name: Checkout
+ uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
+
+ - name: Run Detox E2E (Expo ${{ matrix.version }})
+ uses: ./.github/actions/e2e-ios
+ with:
+ app-path: apps/ExpoApp${{ matrix.version }}
+ artifact-name: detox-expo${{ matrix.version }}
+ run-expo-prebuild: 'true'
diff --git a/apps/ExpoApp54/.detoxrc.cjs b/apps/ExpoApp54/.detoxrc.cjs
new file mode 100644
index 00000000..d3093290
--- /dev/null
+++ b/apps/ExpoApp54/.detoxrc.cjs
@@ -0,0 +1,43 @@
+const {
+ getIosSimulatorDeviceType,
+} = require('../brownfield-example-shared-tests/detox-ios-simulator-device.cjs');
+
+/**
+ * Requires a native tree from `expo prebuild` / `expo run:ios` (ios/ + Pods).
+ * @type {Detox.DetoxConfig}
+ */
+module.exports = {
+ testRunner: {
+ $0: 'jest',
+ args: {
+ config: 'e2e/jest.config.cjs',
+ _: ['e2e'],
+ },
+ jest: {
+ setupTimeout: 300000,
+ },
+ },
+ apps: {
+ 'ios.debug': {
+ type: 'ios.app',
+ binaryPath:
+ 'ios/build/Build/Products/Debug-iphonesimulator/ExpoApp54.app',
+ build:
+ 'xcodebuild -workspace ios/ExpoApp54.xcworkspace -scheme ExpoApp54 -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build',
+ },
+ },
+ devices: {
+ 'ios.sim': {
+ type: 'ios.simulator',
+ device: {
+ type: getIosSimulatorDeviceType(),
+ },
+ },
+ },
+ configurations: {
+ 'ios.sim.debug': {
+ device: 'ios.sim',
+ app: 'ios.debug',
+ },
+ },
+};
diff --git a/apps/ExpoApp54/.gitignore b/apps/ExpoApp54/.gitignore
index f8c6c2e8..2eed6de9 100644
--- a/apps/ExpoApp54/.gitignore
+++ b/apps/ExpoApp54/.gitignore
@@ -38,6 +38,9 @@ yarn-error.*
app-example
+# Detox
+artifacts/
+
# generated native folders
/ios
/android
diff --git a/apps/ExpoApp54/RNApp.tsx b/apps/ExpoApp54/RNApp.tsx
index 5f771364..5802333c 100644
--- a/apps/ExpoApp54/RNApp.tsx
+++ b/apps/ExpoApp54/RNApp.tsx
@@ -2,6 +2,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import { Button, StyleSheet, Text, View } from 'react-native';
import BrownfieldNavigation from '@callstack/brownfield-navigation';
+import PostMessageTab from './app/(tabs)/postMessage';
import Counter from './components/counter';
import { checkAndFetchUpdate } from './utils/expo-rn-updates';
@@ -13,29 +14,35 @@ type RNAppProps = {
export default function RNApp({ nativeOsVersionLabel }: RNAppProps) {
return (
- Expo React Native Brownfield
+
+ Expo React Native Brownfield
- {nativeOsVersionLabel ? (
-
- {nativeOsVersionLabel}
-
- ) : null}
+ {nativeOsVersionLabel ? (
+
+ {nativeOsVersionLabel}
+
+ ) : null}
-
-
+
+
-
+
+
+
+
);
@@ -45,7 +52,9 @@ const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#eeeeee',
- paddingTop: 20,
+ },
+ header: {
+ flexShrink: 0,
},
title: {
fontSize: 20,
@@ -59,10 +68,15 @@ const styles = StyleSheet.create({
marginTop: 4,
},
content: {
- flex: 1,
+ minHeight: 220,
justifyContent: 'center',
alignItems: 'center',
},
+ postMessageSection: {
+ flex: 1,
+ minHeight: 200,
+ marginTop: 8,
+ },
text: {
fontSize: 18,
textAlign: 'center',
diff --git a/apps/ExpoApp54/app/(tabs)/postMessage.tsx b/apps/ExpoApp54/app/(tabs)/postMessage.tsx
index e5efac2d..86b75e1b 100644
--- a/apps/ExpoApp54/app/(tabs)/postMessage.tsx
+++ b/apps/ExpoApp54/app/(tabs)/postMessage.tsx
@@ -1,6 +1,7 @@
import { StyleSheet, FlatList, TouchableOpacity } from 'react-native';
import { useCallback, useEffect, useRef, useState } from 'react';
+import { brownfieldE2eTestIds } from '@callstack/brownfield-example-shared-tests/e2eTestIds';
import ReactNativeBrownfield from '@callstack/react-native-brownfield';
import type { MessageEvent } from '@callstack/react-native-brownfield';
@@ -51,6 +52,7 @@ export default function PostMessageTab() {
return (
{isFromNative ? 'From Native' : 'From RN'}
- {item.text}
+
+ {item.text}
+
);
}
diff --git a/apps/ExpoApp54/e2e/jest.config.cjs b/apps/ExpoApp54/e2e/jest.config.cjs
new file mode 100644
index 00000000..184de8f1
--- /dev/null
+++ b/apps/ExpoApp54/e2e/jest.config.cjs
@@ -0,0 +1,23 @@
+const path = require('node:path');
+
+const appRoot = path.join(__dirname, '..');
+const sharedTestsRoot = path.join(
+ __dirname,
+ '../../brownfield-example-shared-tests'
+);
+
+module.exports = {
+ maxWorkers: 1,
+ rootDir: appRoot,
+ roots: [appRoot, sharedTestsRoot],
+ modulePaths: [path.join(appRoot, 'node_modules')],
+ testTimeout: 120000,
+ verbose: true,
+ reporters: ['detox/runners/jest/reporter'],
+ globalSetup: 'detox/runners/jest/globalSetup',
+ globalTeardown: 'detox/runners/jest/globalTeardown',
+ testEnvironment: 'detox/runners/jest/testEnvironment',
+ testMatch: [
+ path.join(sharedTestsRoot, 'e2e/expoPostMessageBrownfield.e2e.js'),
+ ],
+};
diff --git a/apps/ExpoApp54/entry.tsx b/apps/ExpoApp54/entry.tsx
index 86abd0e1..077fe6ef 100644
--- a/apps/ExpoApp54/entry.tsx
+++ b/apps/ExpoApp54/entry.tsx
@@ -1,12 +1,18 @@
-import { ExpoRoot } from 'expo-router';
+import type { ComponentProps } from 'react';
import { AppRegistry } from 'react-native';
+import { SafeAreaProvider } from 'react-native-safe-area-context';
+
import RNApp from './RNApp';
-function App() {
- const ctx = require.context('./app');
- return ;
+type RNAppRootProps = ComponentProps;
+
+function RNAppRoot(props: RNAppRootProps) {
+ return (
+
+
+
+ );
}
-AppRegistry.registerComponent('RNApp', () => RNApp);
-// Keep compatibility with Expo's default app key.
-AppRegistry.registerComponent('main', () => App);
+AppRegistry.registerComponent('RNApp', () => RNAppRoot);
+AppRegistry.registerComponent('main', () => RNAppRoot);
diff --git a/apps/ExpoApp54/package.json b/apps/ExpoApp54/package.json
index e40f5430..fa118f3f 100644
--- a/apps/ExpoApp54/package.json
+++ b/apps/ExpoApp54/package.json
@@ -6,11 +6,13 @@
"scripts": {
"start": "expo start",
"android": "expo run:android",
- "ios": "expo run:ios",
+ "ios": "yarn brownfield:package:ios && node ../../packages/cli/dist/main.js codegen && expo run:ios",
"web": "expo start --web",
"lint": "expo lint --no-cache",
"test": "jest --config jest.config.js",
- "prebuild": "expo prebuild",
+ "e2e:build:ios": "detox build --configuration ios.sim.debug",
+ "e2e:test:ios": "detox test --configuration ios.sim.debug",
+ "prebuild": "node ../../packages/cli/dist/main.js codegen && expo prebuild",
"brownfield:prepare:android:ci": "cd .. && node --experimental-strip-types --no-warnings ./scripts/prepare-android-build-gradle-for-ci.ts ExpoApp54",
"brownfield:package:android": "brownfield package:android --module-name brownfieldlib --variant release --verbose",
"brownfield:publish:android": "brownfield publish:android --module-name brownfieldlib --verbose",
@@ -18,6 +20,7 @@
"eas:stg": "EXPO_TOKEN=$EAS_TOKEN eas update --channel production --message 'testing 1st stg channel update' --platform android"
},
"dependencies": {
+ "@callstack/brownfield-example-shared-tests": "workspace:^",
"@callstack/brownfield-navigation": "workspace:^",
"@callstack/brownie": "workspace:^",
"@callstack/react-native-brownfield": "workspace:^",
@@ -44,10 +47,10 @@
"react-native-worklets": "0.5.1"
},
"devDependencies": {
- "@callstack/brownfield-example-shared-tests": "workspace:^",
"@testing-library/react-native": "^13.3.3",
"@types/jest": "^30.0.0",
"@types/react": "~19.1.10",
+ "detox": "^20.27.0",
"eslint": "^9.25.0",
"eslint-config-expo": "~10.0.0",
"jest": "^29.7.0",
diff --git a/apps/ExpoApp55/.detoxrc.cjs b/apps/ExpoApp55/.detoxrc.cjs
new file mode 100644
index 00000000..9589648b
--- /dev/null
+++ b/apps/ExpoApp55/.detoxrc.cjs
@@ -0,0 +1,45 @@
+const { getIosSimulatorDeviceType } = require('../brownfield-example-shared-tests/detox-ios-simulator-device.cjs');
+
+// Debug simulator builds normally skip JS bundling and load from Metro. E2E runs without
+// a packager, so embed main.jsbundle (tests pass -BrownfieldPreferEmbeddedBundleInDebug).
+const detoxIosDebugBuild =
+ 'FORCE_BUNDLING=1 xcodebuild -workspace ios/ExpoApp55.xcworkspace -scheme ExpoApp55 -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build ARCHS=arm64 ONLY_ACTIVE_ARCH=YES';
+
+/**
+ * Requires a native tree from `expo prebuild` / `expo run:ios` (ios/ + Pods).
+ * @type {Detox.DetoxConfig}
+ */
+module.exports = {
+ testRunner: {
+ $0: 'jest',
+ args: {
+ config: 'e2e/jest.config.cjs',
+ _: ['e2e'],
+ },
+ jest: {
+ setupTimeout: 300000,
+ },
+ },
+ apps: {
+ 'ios.debug': {
+ type: 'ios.app',
+ binaryPath:
+ 'ios/build/Build/Products/Debug-iphonesimulator/ExpoApp55.app',
+ build: detoxIosDebugBuild,
+ },
+ },
+ devices: {
+ 'ios.sim': {
+ type: 'ios.simulator',
+ device: {
+ type: getIosSimulatorDeviceType(),
+ },
+ },
+ },
+ configurations: {
+ 'ios.sim.debug': {
+ device: 'ios.sim',
+ app: 'ios.debug',
+ },
+ },
+};
diff --git a/apps/ExpoApp55/.gitignore b/apps/ExpoApp55/.gitignore
index f8c6c2e8..2eed6de9 100644
--- a/apps/ExpoApp55/.gitignore
+++ b/apps/ExpoApp55/.gitignore
@@ -38,6 +38,9 @@ yarn-error.*
app-example
+# Detox
+artifacts/
+
# generated native folders
/ios
/android
diff --git a/apps/ExpoApp55/RNApp.tsx b/apps/ExpoApp55/RNApp.tsx
index bb470700..47363bb0 100644
--- a/apps/ExpoApp55/RNApp.tsx
+++ b/apps/ExpoApp55/RNApp.tsx
@@ -3,6 +3,7 @@ import { Button, StyleSheet, Text, View } from 'react-native';
import BrownfieldNavigation from '@callstack/brownfield-navigation';
import { checkAndFetchUpdate } from './src/utils/expo-rn-updates';
+import PostMessageTab from '@/app/postMessage';
import Counter from './src/components/counter';
type RNAppProps = {
@@ -12,29 +13,35 @@ type RNAppProps = {
export default function RNApp({ nativeOsVersionLabel }: RNAppProps) {
return (
- Expo React Native Brownfield
+
+ Expo React Native Brownfield
- {nativeOsVersionLabel ? (
-
- {nativeOsVersionLabel}
-
- ) : null}
+ {nativeOsVersionLabel ? (
+
+ {nativeOsVersionLabel}
+
+ ) : null}
-
-
+
+
- BrownfieldNavigation.navigateToSettings()}
- />
- BrownfieldNavigation.navigateToReferrals('123')}
- />
-
+ BrownfieldNavigation.navigateToSettings()}
+ />
+ BrownfieldNavigation.navigateToReferrals('123')}
+ />
+
+
+
+
+
+
);
@@ -44,7 +51,9 @@ const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#eeeeee',
- paddingTop: 20,
+ },
+ header: {
+ flexShrink: 0,
},
title: {
fontSize: 20,
@@ -58,10 +67,15 @@ const styles = StyleSheet.create({
marginTop: 4,
},
content: {
- flex: 1,
+ minHeight: 220,
justifyContent: 'center',
alignItems: 'center',
},
+ postMessageSection: {
+ flex: 1,
+ minHeight: 200,
+ marginTop: 8,
+ },
text: {
fontSize: 18,
textAlign: 'center',
diff --git a/apps/ExpoApp55/e2e/jest.config.cjs b/apps/ExpoApp55/e2e/jest.config.cjs
new file mode 100644
index 00000000..fe43d41b
--- /dev/null
+++ b/apps/ExpoApp55/e2e/jest.config.cjs
@@ -0,0 +1,18 @@
+const path = require('node:path');
+
+const appRoot = path.join(__dirname, '..');
+const sharedTestsRoot = path.join(__dirname, '../../brownfield-example-shared-tests');
+
+module.exports = {
+ maxWorkers: 1,
+ rootDir: appRoot,
+ roots: [appRoot, sharedTestsRoot],
+ modulePaths: [path.join(appRoot, 'node_modules')],
+ testTimeout: 120000,
+ verbose: true,
+ reporters: ['detox/runners/jest/reporter'],
+ globalSetup: 'detox/runners/jest/globalSetup',
+ globalTeardown: 'detox/runners/jest/globalTeardown',
+ testEnvironment: 'detox/runners/jest/testEnvironment',
+ testMatch: [path.join(sharedTestsRoot, 'e2e/expoPostMessageBrownfield.e2e.js')],
+};
diff --git a/apps/ExpoApp55/entry.tsx b/apps/ExpoApp55/entry.tsx
index 852ce9ba..0c9b8c2d 100644
--- a/apps/ExpoApp55/entry.tsx
+++ b/apps/ExpoApp55/entry.tsx
@@ -1,12 +1,19 @@
-import { ExpoRoot } from 'expo-router';
+import type { ComponentProps } from 'react';
import { AppRegistry } from 'react-native';
+import { SafeAreaProvider } from 'react-native-safe-area-context';
+
import RNApp from './RNApp';
-function App() {
- const ctx = require.context('./src/app');
- return ;
+type RNAppRootProps = ComponentProps;
+
+function RNAppRoot(props: RNAppRootProps) {
+ return (
+
+
+
+ );
}
-AppRegistry.registerComponent('RNApp', () => RNApp);
-// Keep compatibility with Expo's default app key.
-AppRegistry.registerComponent('main', () => App);
+AppRegistry.registerComponent('RNApp', () => RNAppRoot);
+// Standalone `expo run:ios` / Detox load the `main` key — same root as brownfield `RNApp`.
+AppRegistry.registerComponent('main', () => RNAppRoot);
diff --git a/apps/ExpoApp55/package.json b/apps/ExpoApp55/package.json
index af003688..94029e04 100644
--- a/apps/ExpoApp55/package.json
+++ b/apps/ExpoApp55/package.json
@@ -5,11 +5,14 @@
"scripts": {
"start": "expo start",
"android": "expo run:android",
- "ios": "expo run:ios",
+ "ios": "yarn brownfield:package:ios && node ../../packages/cli/dist/main.js codegen && expo run:ios",
"web": "expo start --web",
"lint": "expo lint --no-cache",
"test": "jest --config jest.config.js",
- "prebuild": "expo prebuild",
+ "e2e:build:ios": "detox build --configuration ios.sim.debug",
+ "e2e:test:ios": "detox test --configuration ios.sim.debug",
+ "ci:local:e2e:ios": "bash ../../scripts/ci-local-expo55-ios-e2e.sh",
+ "prebuild": "node ../../packages/cli/dist/main.js codegen && expo prebuild",
"brownfield:prepare:android:ci": "cd .. && node --experimental-strip-types --no-warnings ./scripts/prepare-android-build-gradle-for-ci.ts ExpoApp55",
"brownfield:package:android": "brownfield package:android --module-name brownfieldlib --variant release --verbose",
"brownfield:publish:android": "brownfield publish:android --module-name brownfieldlib --verbose",
@@ -17,6 +20,7 @@
"eas:stg": "EXPO_TOKEN=$EAS_TOKEN eas update --channel production --message 'testing 1st stg channel update' --platform ios --environment staging"
},
"dependencies": {
+ "@callstack/brownfield-example-shared-tests": "workspace:^",
"@callstack/brownfield-navigation": "workspace:^",
"@callstack/brownie": "workspace:^",
"@callstack/react-native-brownfield": "workspace:^",
@@ -49,10 +53,10 @@
"react-native-worklets": "0.7.4"
},
"devDependencies": {
- "@callstack/brownfield-example-shared-tests": "workspace:^",
"@testing-library/react-native": "^13.3.3",
"@types/jest": "^30.0.0",
"@types/react": "~19.2.10",
+ "detox": "^20.27.0",
"eslint": "^9.25.0",
"eslint-config-expo": "~55.0.0",
"globals": "^17.6.0",
diff --git a/apps/ExpoApp55/src/app/postMessage.tsx b/apps/ExpoApp55/src/app/postMessage.tsx
index e5efac2d..86b75e1b 100644
--- a/apps/ExpoApp55/src/app/postMessage.tsx
+++ b/apps/ExpoApp55/src/app/postMessage.tsx
@@ -1,6 +1,7 @@
import { StyleSheet, FlatList, TouchableOpacity } from 'react-native';
import { useCallback, useEffect, useRef, useState } from 'react';
+import { brownfieldE2eTestIds } from '@callstack/brownfield-example-shared-tests/e2eTestIds';
import ReactNativeBrownfield from '@callstack/react-native-brownfield';
import type { MessageEvent } from '@callstack/react-native-brownfield';
@@ -51,6 +52,7 @@ export default function PostMessageTab() {
return (
{isFromNative ? 'From Native' : 'From RN'}
- {item.text}
+
+ {item.text}
+
);
}
diff --git a/apps/RNApp/.detoxrc.cjs b/apps/RNApp/.detoxrc.cjs
new file mode 100644
index 00000000..e65aa6b6
--- /dev/null
+++ b/apps/RNApp/.detoxrc.cjs
@@ -0,0 +1,43 @@
+const {
+ getIosSimulatorDeviceType,
+} = require('../brownfield-example-shared-tests/detox-ios-simulator-device.cjs');
+
+// Debug simulator builds normally skip JS bundling and load from Metro. E2E runs without
+// a packager, so embed main.jsbundle (tests pass -BrownfieldPreferEmbeddedBundleInDebug).
+const detoxIosDebugBuild =
+ 'FORCE_BUNDLING=1 xcodebuild -workspace ios/RNApp.xcworkspace -scheme RNApp -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build ARCHS=arm64 ONLY_ACTIVE_ARCH=YES';
+
+/** @type {Detox.DetoxConfig} */
+module.exports = {
+ testRunner: {
+ $0: 'jest',
+ args: {
+ config: 'e2e/jest.config.cjs',
+ _: ['e2e'],
+ },
+ jest: {
+ setupTimeout: 300000,
+ },
+ },
+ apps: {
+ 'ios.debug': {
+ type: 'ios.app',
+ binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/RNApp.app',
+ build: detoxIosDebugBuild,
+ },
+ },
+ devices: {
+ 'ios.sim': {
+ type: 'ios.simulator',
+ device: {
+ type: getIosSimulatorDeviceType(),
+ },
+ },
+ },
+ configurations: {
+ 'ios.sim.debug': {
+ device: 'ios.sim',
+ app: 'ios.debug',
+ },
+ },
+};
diff --git a/apps/RNApp/.gitignore b/apps/RNApp/.gitignore
index 60141bd4..ce0a2d5f 100644
--- a/apps/RNApp/.gitignore
+++ b/apps/RNApp/.gitignore
@@ -24,7 +24,6 @@ DerivedData
# Android/IntelliJ
#
-build/
.idea
.gradle
local.properties
@@ -65,6 +64,7 @@ yarn-error.log
# testing
/coverage
+/artifacts
# Yarn
.yarn/*
diff --git a/apps/RNApp/android/app/build.gradle b/apps/RNApp/android/app/build.gradle
index 3d43d51f..9e79628e 100644
--- a/apps/RNApp/android/app/build.gradle
+++ b/apps/RNApp/android/app/build.gradle
@@ -108,6 +108,8 @@ android {
}
dependencies {
+ implementation(project(":BrownfieldLib"))
+
// The version of react-native is set by the React Native Gradle Plugin
implementation("com.facebook.react:react-android")
diff --git a/apps/RNApp/android/app/src/main/java/com/rnapp/MainApplication.kt b/apps/RNApp/android/app/src/main/java/com/rnapp/MainApplication.kt
index cd9696d5..8610fd9d 100644
--- a/apps/RNApp/android/app/src/main/java/com/rnapp/MainApplication.kt
+++ b/apps/RNApp/android/app/src/main/java/com/rnapp/MainApplication.kt
@@ -1,11 +1,14 @@
package com.rnapp
import android.app.Application
+import com.callstack.brownie.registerStoreIfNeeded
import com.facebook.react.PackageList
import com.facebook.react.ReactApplication
import com.facebook.react.ReactHost
import com.facebook.react.ReactNativeApplicationEntryPoint.loadReactNative
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
+import com.rnapp.brownfieldlib.BrownfieldStore
+import com.rnapp.brownfieldlib.User
class MainApplication : Application(), ReactApplication {
override val reactHost: ReactHost by lazy {
@@ -21,6 +24,14 @@ class MainApplication : Application(), ReactApplication {
override fun onCreate() {
super.onCreate()
+
+ registerStoreIfNeeded(storeName = BrownfieldStore.STORE_NAME) {
+ BrownfieldStore(
+ counter = 0.0,
+ user = User(name = "Username"),
+ )
+ }
+
loadReactNative(this)
}
}
diff --git a/apps/RNApp/docs/brownfield-store-fix.md b/apps/RNApp/docs/brownfield-store-fix.md
new file mode 100644
index 00000000..f83b9c46
--- /dev/null
+++ b/apps/RNApp/docs/brownfield-store-fix.md
@@ -0,0 +1,200 @@
+# BrownfieldStore “not found” fix (RNApp iOS)
+
+This document summarizes the investigation and fixes for the Brownie error when running **RNApp** on iOS:
+
+```text
+[Brownie] Store "BrownfieldStore" not found.
+Make sure to register it on the native side before accessing it from JS.
+```
+
+**AppleApp** (brownfield host) worked with the same JS and store schema; only standalone **RNApp** failed until these changes were applied.
+
+---
+
+## The problem
+
+When running **RNApp** on iOS, React crashed on the first render of `Counter` with the error above. `useStore('BrownfieldStore', …)` in JavaScript could not see a store that native code was supposed to have registered.
+
+---
+
+## How Brownie works (short)
+
+Brownie shares state between native and React Native through two layers:
+
+1. **C++ `BrownieStoreManager`** — holds stores and backs `global.__brownieGetStore` (what JS uses).
+2. **Swift `Store` / `StoreManager`** — optional native-side wrapper; `BrownfieldStore.register(...)` creates a `Store` and calls into the C++ bridge.
+
+JavaScript (`@callstack/brownie`) reads stores via:
+
+```ts
+global.__brownieGetStore?.(key)
+```
+
+That global is installed by **`BrownieInstaller::install()`**, which must run when the Brownie turbo module is loaded under the **New Architecture**.
+
+Native registration must hit the **same** C++ manager instance that JavaScript uses.
+
+---
+
+## Root causes
+
+There were **two separate issues**, not one.
+
+### 1. Duplicate Brownie in RNApp (main RNApp bug)
+
+**RNApp** linked and **embedded `BrownfieldLib.framework`** into the app. That framework was built with `inherit! :complete` in the Podfile, so it contained a **full second copy** of Brownie (including its own `BrownieStoreManager` singleton).
+
+At runtime:
+
+| Action | Which Brownie copy |
+|--------|-------------------|
+| `AppDelegate` → `BrownfieldStore.register(...)` | Often the copy inside **BrownfieldLib** |
+| JS → `__brownieGetStore` → C++ lookup | Copy linked into **RNApp** / React Native pods |
+
+Registration and JS were talking to **different singletons**, so JS always saw “store not found” even though registration appeared to succeed on native.
+
+**AppleApp** avoids this: it links **one** `Brownie.xcframework` and **one** `BrownfieldLib.xcframework` separately, and registers via `import Brownie` in the app — not by embedding a BrownfieldLib that re-exports and duplicates Brownie.
+
+### 2. JSI bindings not installed on iOS New Architecture (brownie package bug)
+
+On iOS with **`RCT_NEW_ARCH_ENABLED`**, React installs turbo-module JSI bindings only when the module is a **C++** `TurboModuleWithJSIBindings`.
+
+`BrownieModule` only implemented the **ObjC** protocol `RCTTurboModuleWithJSIBindings`. In bridgeless / New Architecture, that path is **not** used; `dynamic_cast` on the C++ module fails, so **`BrownieInstaller::install()` never ran** and `global.__brownieGetStore` stayed undefined.
+
+Android already handled this in `BrownieModule.initialize()` via `installJSIBindingsIfNeeded()`.
+
+This could affect any iOS React Native 0.85+ app using Brownie; RNApp made it obvious because JS hits the store immediately on launch.
+
+---
+
+## What we changed
+
+### RNApp — iOS app target
+
+| File | Change | Problem addressed |
+|------|--------|-----------------|
+| `ios/RNApp.xcodeproj/project.pbxproj` | Removed **link**, **embed**, and **target dependency** on `BrownfieldLib` from the **RNApp** app target. The `BrownfieldLib` target remains for `brownfield package:ios`. | Duplicate Brownie singleton |
+| `ios/RNApp/AppDelegate.swift` | `import Brownie`; register store **before** `factory.startReactNative(...)` via `BrownieBootstrap.register(...)`. | Store not registered / wrong instance |
+| `ios/BrownfieldLib/BrownfieldLib.swift` | Removed `@_exported import Brownie`. Only re-exports `ReactBrownfield`. | Prevent duplicate Brownie inside packaged `BrownfieldLib` |
+
+### RNApp — Android
+
+| File | Change | Problem addressed |
+|------|--------|-----------------|
+| `android/app/src/main/java/com/rnapp/MainApplication.kt` | `registerStoreIfNeeded(...)` for `BrownfieldStore` **before** `loadReactNative(this)`. | No native registration on Android |
+| `android/app/build.gradle` | `implementation(project(":BrownfieldLib"))` for generated Kotlin types. | Types / brownfield lib on Android |
+
+### `@callstack/brownie` package
+
+| File | Change | Problem addressed |
+|------|--------|-----------------|
+| `packages/brownie/ios/BrownieModule.mm` | Introduced C++ `BrownieTurboModule` extending `NativeBrownieModuleSpecJSI` + `TurboModuleWithJSIBindings`; `getTurboModule` returns it; `installJSIBindingsWithRuntime` calls `BrownieInstaller::install(runtime)`. | `__brownieGetStore` never set on New Architecture |
+| `packages/brownie/ios/BrownieModule.h` | Dropped unused `RCTTurboModuleWithJSIBindings` import from header. | Cleanup |
+| `packages/brownie/ios/BrownieStore.swift` | Added **`BrownieBootstrap`** — registers via `BrownieStoreBridge` directly (C++ path JS uses). | Clear app entry-point API |
+
+### RNApp — tooling
+
+| File | Change | Problem addressed |
+|------|--------|-----------------|
+| `package.json` | `ios` / `android` scripts run `yarn codegen` first. | Generated Swift/Kotlin types are gitignored and must exist before build |
+
+### Codegen (operational)
+
+From `apps/RNApp`:
+
+```bash
+yarn codegen
+```
+
+This generates:
+
+- `packages/brownie/ios/Generated/BrownfieldStore.swift` (gitignored)
+- `android/BrownfieldLib/.../Generated/BrownfieldStore.kt`
+
+---
+
+## Why each fix works
+
+### Stop embedding `BrownfieldLib` in RNApp
+
+RNApp as a **standalone React Native app** does not need the brownfield packaging framework at runtime. Embedding it pulled in a second Brownie. After removal, there is **one** `BrownieStoreManager` in the process; registration and JS use the same store map.
+
+`BrownfieldLib` is still built for **`yarn brownfield:package:ios`**; it is just not part of the dev app binary anymore.
+
+### Register before React Native starts
+
+Brownie expects stores to exist **before** the JS bundle runs components that call `useStore`. Both `AppDelegate` (iOS) and `MainApplication` (Android) register initial state before starting RN.
+
+### `BrownieTurboModule` (library fix)
+
+When JS first loads the Brownie turbo module, React calls `TurboModuleWithJSIBindings::installJSIBindings` on the **C++** module. That runs `BrownieInstaller::install`, which defines `global.__brownieGetStore`. Without this, JS fails even with a correctly registered native store.
+
+### `BrownieBootstrap` (optional)
+
+`BrownfieldStore.register` creates a Swift `Store` and also talks to the bridge. After the duplicate was removed, **`BrownfieldStore.register` is sufficient** for RNApp again.
+
+`BrownieBootstrap` registers straight through `BrownieStoreBridge` and documents “use this from AppDelegate before RN starts.” You can use either:
+
+```swift
+// Option A — standard API (also updates Swift StoreManager for @UseStore)
+BrownfieldStore.register(initialState)
+
+// Option B — explicit C++ registration
+BrownieBootstrap.register(initialState)
+```
+
+### No Brownie re-export in `BrownfieldLib`
+
+Packaged `BrownfieldLib.xcframework` should not embed another full Brownie. Host apps (like AppleApp) link **Brownie** explicitly. That keeps brownfield packaging aligned with AppleApp’s working layout.
+
+---
+
+## Required vs optional going forward
+
+### Required for RNApp
+
+- Do **not** re-embed `BrownfieldLib` in the RNApp app target.
+- Register stores before RN starts (iOS + Android).
+- Keep **`BrownieTurboModule`** in `@callstack/brownie` for iOS New Architecture.
+- Run **`yarn codegen`** when store schemas change.
+
+### Optional
+
+- `BrownieBootstrap` vs `BrownfieldStore.register` in `AppDelegate` (equivalent after duplicate fix).
+- `yarn codegen &&` prepended to `ios` / `android` scripts.
+
+### Unchanged
+
+- **AppleApp**: `BrownfieldStore.register` in app `init`, separate `Brownie` + `BrownfieldLib` xcframeworks — no change needed.
+- **BrownfieldLib** Xcode target: still used for packaging, not for day-to-day RNApp runs.
+
+---
+
+## End-to-end flow after fixes (RNApp iOS)
+
+```mermaid
+sequenceDiagram
+ participant AD as AppDelegate
+ participant BB as Brownie C++ manager
+ participant RN as React Native
+ participant JS as JS useStore
+
+ AD->>BB: BrownieBootstrap / register store
+ AD->>RN: startReactNative
+ RN->>JS: Load bundle
+ JS->>RN: Require Brownie turbo module
+ RN->>BB: BrownieTurboModule installs __brownieGetStore
+ JS->>BB: __brownieGetStore("BrownfieldStore")
+ BB-->>JS: Host object with state
+```
+
+---
+
+## Takeaway
+
+The error looked like “forgot to register the store,” but RNApp actually had **two separate issues**:
+
+1. **Wrong Brownie instance** (duplicate via embedded `BrownfieldLib`) — why AppleApp worked and RNApp did not.
+2. **JS bridge never installed** on iOS New Architecture — fixed in the brownie library with `BrownieTurboModule`.
+
+Removing the duplicate was the decisive fix for RNApp; the turbo module fix is still necessary for correct Brownie behavior on modern React Native iOS.
diff --git a/apps/RNApp/e2e/jest.config.cjs b/apps/RNApp/e2e/jest.config.cjs
new file mode 100644
index 00000000..7e307f7a
--- /dev/null
+++ b/apps/RNApp/e2e/jest.config.cjs
@@ -0,0 +1,22 @@
+const path = require('node:path');
+
+const appRoot = path.join(__dirname, '..');
+const sharedTestsRoot = path.join(
+ __dirname,
+ '../../brownfield-example-shared-tests'
+);
+
+module.exports = {
+ maxWorkers: 1,
+ rootDir: appRoot,
+ roots: [appRoot, sharedTestsRoot],
+ // Shared E2E files live under brownfield-example-shared-tests; resolve host-app deps (detox) from here.
+ modulePaths: [path.join(appRoot, 'node_modules')],
+ testTimeout: 120000,
+ verbose: true,
+ reporters: ['detox/runners/jest/reporter'],
+ globalSetup: 'detox/runners/jest/globalSetup',
+ globalTeardown: 'detox/runners/jest/globalTeardown',
+ testEnvironment: 'detox/runners/jest/testEnvironment',
+ testMatch: [path.join(sharedTestsRoot, 'e2e/rnAppBrownfield.e2e.js')],
+};
diff --git a/apps/RNApp/ios/BrownfieldLib/BrownfieldLib.swift b/apps/RNApp/ios/BrownfieldLib/BrownfieldLib.swift
index 46332612..b9800748 100644
--- a/apps/RNApp/ios/BrownfieldLib/BrownfieldLib.swift
+++ b/apps/RNApp/ios/BrownfieldLib/BrownfieldLib.swift
@@ -1,6 +1,6 @@
-// Export helpers from @callstack/react-native-brownfield library
+// Export helpers from @callstack/react-native-brownfield library.
+// Brownie is not re-exported here to avoid duplicating it inside BrownfieldLib.framework.
@_exported import ReactBrownfield
-@_exported import Brownie
// Initializes a Bundle instance that points at the framework target.
public let ReactNativeBundle = Bundle(for: InternalClassForBundle.self)
class InternalClassForBundle {}
diff --git a/apps/RNApp/ios/Podfile b/apps/RNApp/ios/Podfile
index 6f9216fc..8c2e5bd7 100644
--- a/apps/RNApp/ios/Podfile
+++ b/apps/RNApp/ios/Podfile
@@ -4,6 +4,12 @@ require Pod::Executable.execute_command('node', ['-p',
"react-native/scripts/react_native_pods.rb",
{paths: [process.argv[1]]},
)', __dir__]).strip
+require File.join(File.dirname(`node --print "require.resolve('@callstack/react-native-brownfield/package.json')"`), "scripts/react_native_brownfield_post_integrate")
+
+# RNApp uses react-native-screens (Fabric). Prebuilt React-Core can fail to link Debug
+# simulator builds (undefined facebook::react::* from libRNScreens). Build RN from source
+# unless RCT_USE_PREBUILT_RNCORE=1 is set explicitly before pod install.
+ENV['RCT_USE_PREBUILT_RNCORE'] = '0' unless ENV['RCT_USE_PREBUILT_RNCORE'] == '1'
platform :ios, min_ios_version_supported
prepare_react_native_project!
@@ -34,5 +40,24 @@ target 'RNApp' do
:mac_catalyst_enabled => false,
:ccache_enabled => ENV['USE_CCACHE'] == '1'
)
+
+ # >>> react-native-brownfield Expo SDK 55+ swift defines >>>
+ installer.pods_project.targets.each do |target|
+ if target.name == 'ReactBrownfield'
+ puts "[Brownfield] Adding definition of EXPO_SDK_GTE_55 to target: #{target.name}"
+
+ target.build_configurations.each do |config|
+ conditions = config.build_settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] || '$(inherited)'
+ conditions = conditions.to_s
+ config.build_settings['SWIFT_ACTIVE_COMPILATION_CONDITIONS'] = "#{conditions} EXPO_SDK_GTE_55"
+ end
+ end
+ end
+ # <<< react-native-brownfield Expo SDK 55+ swift defines <<<
+
+ # >>> react-native-brownfield Xcode packaging workarounds >>>
+ react_native_brownfield_patch_fmt_consteval(installer)
+ react_native_brownfield_skip_swift_module_interface_verification(installer)
+ # <<< react-native-brownfield Xcode packaging workarounds <<<
end
end
diff --git a/apps/RNApp/ios/Podfile.lock b/apps/RNApp/ios/Podfile.lock
index 90fc0f1b..3373b0f2 100644
--- a/apps/RNApp/ios/Podfile.lock
+++ b/apps/RNApp/ios/Podfile.lock
@@ -1,10 +1,9 @@
PODS:
- - BrownfieldNavigation (3.8.1):
+ - BrownfieldNavigation (3.10.0):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -21,12 +20,11 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- Yoga
- - Brownie (3.8.1):
+ - Brownie (3.10.0):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -73,7 +71,6 @@ PODS:
- React-Core (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default (= 0.85.0)
- React-cxxreact
- React-featureflags
@@ -89,12 +86,9 @@ PODS:
- React-utils
- ReactNativeDependencies
- Yoga
- - React-Core-prebuilt (0.85.0):
- - ReactNativeDependencies
- React-Core/CoreModulesHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -113,7 +107,6 @@ PODS:
- React-Core/Default (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-cxxreact
- React-featureflags
- React-hermes
@@ -131,7 +124,6 @@ PODS:
- React-Core/DevSupport (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default (= 0.85.0)
- React-Core/RCTWebSocket (= 0.85.0)
- React-cxxreact
@@ -151,7 +143,6 @@ PODS:
- React-Core/RCTActionSheetHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -170,7 +161,6 @@ PODS:
- React-Core/RCTAnimationHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -189,7 +179,6 @@ PODS:
- React-Core/RCTBlobHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -208,7 +197,6 @@ PODS:
- React-Core/RCTImageHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -227,7 +215,6 @@ PODS:
- React-Core/RCTLinkingHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -246,7 +233,6 @@ PODS:
- React-Core/RCTNetworkHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -265,7 +251,6 @@ PODS:
- React-Core/RCTSettingsHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -284,7 +269,6 @@ PODS:
- React-Core/RCTTextHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -303,7 +287,6 @@ PODS:
- React-Core/RCTVibrationHeaders (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default
- React-cxxreact
- React-featureflags
@@ -322,7 +305,6 @@ PODS:
- React-Core/RCTWebSocket (0.85.0):
- hermes-engine
- RCTDeprecation
- - React-Core-prebuilt
- React-Core/Default (= 0.85.0)
- React-cxxreact
- React-featureflags
@@ -340,7 +322,6 @@ PODS:
- Yoga
- React-CoreModules (0.85.0):
- RCTTypeSafety (= 0.85.0)
- - React-Core-prebuilt
- React-Core/CoreModulesHeaders (= 0.85.0)
- React-debug
- React-jsi (= 0.85.0)
@@ -358,7 +339,6 @@ PODS:
- React-cxxreact (0.85.0):
- hermes-engine
- React-callinvoker (= 0.85.0)
- - React-Core-prebuilt
- React-debug (= 0.85.0)
- React-jsi (= 0.85.0)
- React-jsinspector
@@ -373,7 +353,6 @@ PODS:
- React-debug (0.85.0)
- React-defaultsnativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-domnativemodule
- React-Fabric/animated
- React-featureflags
@@ -389,7 +368,6 @@ PODS:
- Yoga
- React-domnativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-Fabric
- React-Fabric/bridging
- React-FabricComponents
@@ -406,7 +384,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/animated (= 0.85.0)
@@ -443,7 +420,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/animationbackend
@@ -463,7 +439,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -482,7 +457,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -501,7 +475,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -520,7 +493,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -539,7 +511,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -558,7 +529,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -577,7 +547,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/components/legacyviewmanagerinterop (= 0.85.0)
@@ -600,7 +569,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -619,7 +587,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -638,7 +605,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -657,7 +623,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -678,7 +643,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -697,7 +661,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -716,7 +679,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -735,7 +697,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -754,7 +715,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -773,7 +733,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -792,7 +751,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/observers/events (= 0.85.0)
@@ -813,7 +771,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -832,7 +789,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -851,7 +807,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/animationbackend
@@ -874,7 +829,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -893,7 +847,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric/uimanager/consistency (= 0.85.0)
@@ -914,7 +867,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -934,7 +886,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -957,7 +908,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -989,7 +939,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1010,7 +959,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1031,7 +979,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1052,7 +999,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1073,7 +1019,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1094,7 +1039,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1115,7 +1059,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1136,7 +1079,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1157,7 +1099,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1178,7 +1119,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1199,7 +1139,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1220,7 +1159,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-Fabric
@@ -1240,7 +1178,6 @@ PODS:
- hermes-engine
- RCTRequired (= 0.85.0)
- RCTTypeSafety (= 0.85.0)
- - React-Core-prebuilt
- React-Fabric
- React-featureflags
- React-graphics
@@ -1254,11 +1191,9 @@ PODS:
- ReactNativeDependencies
- Yoga
- React-featureflags (0.85.0):
- - React-Core-prebuilt
- ReactNativeDependencies
- React-featureflagsnativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-featureflags
- React-jsi
- React-jsiexecutor
@@ -1267,7 +1202,6 @@ PODS:
- ReactNativeDependencies
- React-graphics (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-featureflags
- React-jsi
- React-jsiexecutor
@@ -1275,7 +1209,6 @@ PODS:
- ReactNativeDependencies
- React-hermes (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact (= 0.85.0)
- React-jsi
- React-jsiexecutor (= 0.85.0)
@@ -1289,7 +1222,6 @@ PODS:
- ReactNativeDependencies
- React-idlecallbacksnativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-jsi
- React-jsiexecutor
- React-RCTFBReactNativeSpec
@@ -1298,7 +1230,6 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- React-ImageManager (0.85.0):
- - React-Core-prebuilt
- React-Core/Default
- React-debug
- React-Fabric
@@ -1308,7 +1239,6 @@ PODS:
- ReactNativeDependencies
- React-intersectionobservernativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact
- React-Fabric
- React-Fabric/bridging
@@ -1323,7 +1253,6 @@ PODS:
- Yoga
- React-jserrorhandler (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -1332,11 +1261,9 @@ PODS:
- ReactNativeDependencies
- React-jsi (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- ReactNativeDependencies
- React-jsiexecutor (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-jserrorhandler
@@ -1351,7 +1278,6 @@ PODS:
- ReactNativeDependencies
- React-jsinspector (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-featureflags
- React-jsi
- React-jsinspectorcdp
@@ -1363,15 +1289,12 @@ PODS:
- React-utils
- ReactNativeDependencies
- React-jsinspectorcdp (0.85.0):
- - React-Core-prebuilt
- ReactNativeDependencies
- React-jsinspectornetwork (0.85.0):
- - React-Core-prebuilt
- React-jsinspectorcdp
- ReactNativeDependencies
- React-jsinspectortracing (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-jsi
- React-jsinspectornetwork
- React-oscompat
@@ -1379,7 +1302,6 @@ PODS:
- ReactNativeDependencies
- React-jsitooling (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact (= 0.85.0)
- React-debug
- React-jsi (= 0.85.0)
@@ -1392,15 +1314,12 @@ PODS:
- React-jsitracing (0.85.0):
- React-jsi
- React-logger (0.85.0):
- - React-Core-prebuilt
- ReactNativeDependencies
- React-Mapbuffer (0.85.0):
- - React-Core-prebuilt
- React-debug
- ReactNativeDependencies
- React-microtasksnativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-jsi
- React-jsiexecutor
- React-RCTFBReactNativeSpec
@@ -1411,7 +1330,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1435,7 +1353,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1457,7 +1374,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1479,7 +1395,6 @@ PODS:
- hermes-engine
- React-callinvoker
- React-Core
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -1491,7 +1406,6 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- React-networking (0.85.0):
- - React-Core-prebuilt
- React-jsinspectornetwork
- React-jsinspectortracing
- React-performancetimeline
@@ -1499,18 +1413,15 @@ PODS:
- ReactNativeDependencies
- React-oscompat (0.85.0)
- React-perflogger (0.85.0):
- - React-Core-prebuilt
- ReactNativeDependencies
- React-performancecdpmetrics (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-jsi
- React-performancetimeline
- React-runtimeexecutor
- React-timing
- ReactNativeDependencies
- React-performancetimeline (0.85.0):
- - React-Core-prebuilt
- React-featureflags
- React-jsinspector
- React-jsinspectortracing
@@ -1521,7 +1432,6 @@ PODS:
- React-Core/RCTActionSheetHeaders (= 0.85.0)
- React-RCTAnimation (0.85.0):
- RCTTypeSafety
- - React-Core-prebuilt
- React-Core/RCTAnimationHeaders
- React-debug
- React-featureflags
@@ -1535,7 +1445,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-CoreModules
- React-debug
- React-defaultsnativemodule
@@ -1560,7 +1469,6 @@ PODS:
- ReactNativeDependencies
- React-RCTBlob (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-Core/RCTBlobHeaders
- React-Core/RCTWebSocket
- React-jsi
@@ -1575,7 +1483,6 @@ PODS:
- hermes-engine
- RCTSwiftUIWrapper
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-FabricComponents
@@ -1607,7 +1514,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-jsi
- React-NativeModulesApple
- React-RCTFBReactNativeSpec/components (= 0.85.0)
@@ -1618,7 +1524,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1632,7 +1537,6 @@ PODS:
- Yoga
- React-RCTImage (0.85.0):
- RCTTypeSafety
- - React-Core-prebuilt
- React-Core/RCTImageHeaders
- React-jsi
- React-NativeModulesApple
@@ -1649,7 +1553,6 @@ PODS:
- ReactCommon/turbomodule/core (= 0.85.0)
- React-RCTNetwork (0.85.0):
- RCTTypeSafety
- - React-Core-prebuilt
- React-Core/RCTNetworkHeaders
- React-debug
- React-featureflags
@@ -1664,7 +1567,6 @@ PODS:
- React-RCTRuntime (0.85.0):
- hermes-engine
- React-Core
- - React-Core-prebuilt
- React-debug
- React-jsi
- React-jsinspector
@@ -1679,7 +1581,6 @@ PODS:
- ReactNativeDependencies
- React-RCTSettings (0.85.0):
- RCTTypeSafety
- - React-Core-prebuilt
- React-Core/RCTSettingsHeaders
- React-jsi
- React-NativeModulesApple
@@ -1690,7 +1591,6 @@ PODS:
- React-Core/RCTTextHeaders (= 0.85.0)
- Yoga
- React-RCTVibration (0.85.0):
- - React-Core-prebuilt
- React-Core/RCTVibrationHeaders
- React-jsi
- React-NativeModulesApple
@@ -1702,13 +1602,11 @@ PODS:
- React-debug
- React-utils
- React-rendererdebug (0.85.0):
- - React-Core-prebuilt
- React-debug
- ReactNativeDependencies
- React-RuntimeApple (0.85.0):
- hermes-engine
- React-callinvoker
- - React-Core-prebuilt
- React-Core/Default
- React-CoreModules
- React-cxxreact
@@ -1730,7 +1628,6 @@ PODS:
- ReactNativeDependencies
- React-RuntimeCore (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact
- React-Fabric
- React-featureflags
@@ -1745,7 +1642,6 @@ PODS:
- React-utils
- ReactNativeDependencies
- React-runtimeexecutor (0.85.0):
- - React-Core-prebuilt
- React-debug
- React-featureflags
- React-jsi (= 0.85.0)
@@ -1753,7 +1649,6 @@ PODS:
- ReactNativeDependencies
- React-RuntimeHermes (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-featureflags
- React-hermes
- React-jsi
@@ -1769,7 +1664,6 @@ PODS:
- React-runtimescheduler (0.85.0):
- hermes-engine
- React-callinvoker
- - React-Core-prebuilt
- React-cxxreact
- React-debug
- React-featureflags
@@ -1786,13 +1680,11 @@ PODS:
- React-debug
- React-utils (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-debug
- React-jsi (= 0.85.0)
- ReactNativeDependencies
- React-webperformancenativemodule (0.85.0):
- hermes-engine
- - React-Core-prebuilt
- React-cxxreact
- React-jsi
- React-jsiexecutor
@@ -1803,12 +1695,11 @@ PODS:
- ReactNativeDependencies
- ReactAppDependencyProvider (0.85.0):
- ReactCodegen
- - ReactBrownfield (3.8.1):
+ - ReactBrownfield (3.10.0):
- hermes-engine
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1832,7 +1723,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-FabricImage
@@ -1848,13 +1738,11 @@ PODS:
- ReactCommon/turbomodule/core
- ReactNativeDependencies
- ReactCommon (0.85.0):
- - React-Core-prebuilt
- ReactCommon/turbomodule (= 0.85.0)
- ReactNativeDependencies
- ReactCommon/turbomodule (0.85.0):
- hermes-engine
- React-callinvoker (= 0.85.0)
- - React-Core-prebuilt
- React-cxxreact (= 0.85.0)
- React-jsi (= 0.85.0)
- React-logger (= 0.85.0)
@@ -1865,7 +1753,6 @@ PODS:
- ReactCommon/turbomodule/bridging (0.85.0):
- hermes-engine
- React-callinvoker (= 0.85.0)
- - React-Core-prebuilt
- React-cxxreact (= 0.85.0)
- React-jsi (= 0.85.0)
- React-logger (= 0.85.0)
@@ -1874,7 +1761,6 @@ PODS:
- ReactCommon/turbomodule/core (0.85.0):
- hermes-engine
- React-callinvoker (= 0.85.0)
- - React-Core-prebuilt
- React-cxxreact (= 0.85.0)
- React-debug (= 0.85.0)
- React-featureflags (= 0.85.0)
@@ -1889,7 +1775,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1913,7 +1798,6 @@ PODS:
- RCTRequired
- RCTTypeSafety
- React-Core
- - React-Core-prebuilt
- React-debug
- React-Fabric
- React-featureflags
@@ -1946,7 +1830,6 @@ DEPENDENCIES:
- React (from `../node_modules/react-native/`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Core (from `../node_modules/react-native/`)
- - React-Core-prebuilt (from `../node_modules/react-native/React-Core-prebuilt.podspec`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
@@ -2040,8 +1923,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Core:
:path: "../node_modules/react-native/"
- React-Core-prebuilt:
- :podspec: "../node_modules/react-native/React-Core-prebuilt.podspec"
React-CoreModules:
:path: "../node_modules/react-native/React/CoreModules"
React-cxxreact:
@@ -2174,85 +2055,84 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"
SPEC CHECKSUMS:
- BrownfieldNavigation: 6bab41701e536267009b77cf6dc6a8a509db1f4a
- Brownie: c0b61f2fd916a0bcb6b4918b49aa3eebec5e1cd6
- FBLazyVector: c00c20551d40126351a6783c47ce75f5b374851b
- hermes-engine: 891a8d77b6705a5c71992a8f3eaf2bfc2cfb1dda
- RCTDeprecation: 3bb167081b134461cfeb875ff7ae1945f8635257
- RCTRequired: 74839f55d5058a133a0bc4569b0afec750957f64
- RCTSwiftUI: 87a316382f3eab4dd13d2a0d0fd2adcce917361a
- RCTSwiftUIWrapper: a31d45fd2891c1e44c1912d9d0c0fac18ed275a0
- RCTTypeSafety: abdf2eaed5501a52f2000de668ccfc60b78c3b27
+ BrownfieldNavigation: 7b067e701bd4246699bbe6c714f5f3b5e072518f
+ Brownie: eb3729538f6fb8c0d1da6b56726ca14f6c00b164
+ FBLazyVector: dfb9ab6ee2eac316f7869edf6ec27b9e872329f0
+ hermes-engine: 44deb1bf084c4b9198077daaf41e5dcf79b8c11b
+ RCTDeprecation: df7412cdad525035c3adeb14c1dc35b344e98187
+ RCTRequired: 28a4bf1ef190650fcd6973d8a6a8f8beb30ef807
+ RCTSwiftUI: 3003f1af83c332be5946ec0433fedcf0ada06551
+ RCTSwiftUIWrapper: f85a763d72333a19fde51d89fbe549aa7eb2f2e3
+ RCTTypeSafety: 94675f4478b5bdc80edd36b017bcd61cda7ae48b
React: 1b1536b9099195944034e65b1830f463caaa8390
- React-callinvoker: 6dff6d17d1d6cc8fdf85468a649bafed473c65f5
- React-Core: 00faa4d038298089a1d5a5b21dde8660c4f0820d
- React-Core-prebuilt: ca4f822f6813ee31e20a965602ed5bbe611a003d
- React-CoreModules: a17807f849bfd86045b0b9a75ec8c19373b482f6
- React-cxxreact: c7b53ace5827be54048288bce5c55f337c41e95f
- React-debug: 1f20c32441d0090cf67e6b966895f4ccd929d84c
- React-defaultsnativemodule: a6ebd891f2d4d9351dc5f31c865e4e4cc7fd5596
- React-domnativemodule: 464aff9e0539fd739bf286786ce3c3462482ca65
- React-Fabric: c297ae62e6af0cbfe084b778439baf8eef6afe1d
- React-FabricComponents: bac22b6e8b43ae46d64a4b74eadb2cadfc7668b3
- React-FabricImage: 94b22abd2af1aecbbd7cb2c9710ec9d5b1046f7f
- React-featureflags: b6106128a8596c1be7d4271c826d9f0b721771ce
- React-featureflagsnativemodule: 9f68ae1386967ce313feca2627b6d5b3dd3eedc6
- React-graphics: d7d83bb83f5c20e56d6ca6f788e2e6b37058396e
- React-hermes: 2def7f96a41a78196e65722619aca3d285a19c53
- React-idlecallbacksnativemodule: 3e3183edac96e406fc23b18216bb0e8c3a866c85
- React-ImageManager: 4cd85ef9e5a1ca85d6ca6db9f35492c9002d295e
- React-intersectionobservernativemodule: 7e3bf5c45562b58d9a096fef5ab9a286372781b7
- React-jserrorhandler: 21c2a8bcfc58322275c8b79f4176e5feb8dddb59
- React-jsi: f4b843b6851635f64e2bc17fd176b33dec120ebc
- React-jsiexecutor: eb8bd947675ef44bedf6d8990a23681fc758aff0
- React-jsinspector: 897d491597d266f8658789bace8e3d7667a6920b
- React-jsinspectorcdp: 9c955d97d35a40dd2c805b245dafd76004462ade
- React-jsinspectornetwork: fb4ff1d7cbee2d6104b284eb268e786d1ce6e811
- React-jsinspectortracing: 22139f69ed2849ed337100ea49f020557c33cd48
- React-jsitooling: dbc3a9c1d145463f81b26b881922f75a13ad53fd
- React-jsitracing: 3967b9943abd18f1d3e8378f2ccefc4e67905838
- React-logger: ee47d5f3b59a46a006c65038ed5d0b1143e37510
- React-Mapbuffer: ecc590a57aaab305582cc545acc20972680d46b6
- React-microtasksnativemodule: 11067639ecc70dc33f5da19fc31fde80e25e1845
- react-native-safe-area-context: ba7283e541a5f57c6b27a7e33f2c40b8977888c0
- React-NativeModulesApple: 9c1f8815ebd72cc1c75587fe588513f6dd9cb708
- React-networking: 79d340f8cd323295d466afbc40ff5d4b596aa1a6
- React-oscompat: 5361d0fa7905ba1c3b3c5e7c464d6be9d2d85f4b
- React-perflogger: 44ecaa45852241f80e07c0787c8b65516f5e774f
- React-performancecdpmetrics: 38853c3cd78961de382c1edcc3ecb2504e37837d
- React-performancetimeline: c7884cf5a132a52674c5f2c496b00b57c833884f
- React-RCTActionSheet: e3d1db66ef805645e83e6e80f2e21922328a79a7
- React-RCTAnimation: dc39e18331edfa4e4f3631ab83086ce4ba15c4bb
- React-RCTAppDelegate: d08cad1065637eecaf347286807ca25d5e966396
- React-RCTBlob: bd5a11e3b206b86ccdcffa9538a5a4bea0acc0dd
- React-RCTFabric: 6b0a0b4b0efbab9f0a6e8d5fd329bf538940dbe1
- React-RCTFBReactNativeSpec: 432e0c674537ca58cef544e942a5ef141d35fe34
- React-RCTImage: 11407de524bafcc1790394728ca3fe40c6719093
- React-RCTLinking: 707855a5142f65472096a2910044444d390e8c96
- React-RCTNetwork: 8033c7c90b0983dcf994220a9bdeaef428f0b3da
- React-RCTRuntime: 1fce8f2eaec2fc9b9b6ec0c5adc53e47efb01b0e
- React-RCTSettings: cf450b5c44e1d8379b06ac9469c8a81c35ecd7c4
- React-RCTText: 19f706ee0de06dd92945da223d8558d849209e9d
- React-RCTVibration: 3383f98add29944aebdcdfa89598b09b1cadf13c
- React-rendererconsistency: 6851f38dab1216446a2fec803357ebbdfc32a0bb
- React-renderercss: 71e1618a5d0244143702293bc25d351c57218036
- React-rendererdebug: a6b409110a81409e9001ce236c1c779fa117e1f3
- React-RuntimeApple: ba296b048f1dd80883a73f3aae4d6acf9479f599
- React-RuntimeCore: e3cf61d86a908c3f10224b9aa1b67c13af67afe8
- React-runtimeexecutor: f70ca4ad104263dfd70bc32c187021485d1305e2
- React-RuntimeHermes: 32850102fe41ea5bf8248aeb0a76ccbe06a1c16f
- React-runtimescheduler: 5a8c857de6ad793dd1fba1916862ee419566226e
- React-timing: ab856c0faeb19d7ff5f360203c4ebdade7f7041a
- React-utils: f747ea9fa3f4b293533ec4ef7976d1e37f004ef8
- React-webperformancenativemodule: cf676ba871cc4b6ae175f75b92e8c689960c4141
- ReactAppDependencyProvider: 5787b37b8e2e51dfeab697ec031cc7c4080dcea2
- ReactBrownfield: 9acfec561aae66f2adbf6faa451a0712b17a38b2
- ReactCodegen: d9ba64702c846111b3eeb157ea2e15aa5bb2ea55
- ReactCommon: fe2a3af8975e63efa60f95fca8c34dc85deee360
- ReactNativeDependencies: 94375812b438d76ddfa8937a75fbb59cc0cd8fff
- RNScreens: 85c533985720c563272c6f6dd19e1278dfd0f5d4
- Yoga: ce94692032f0a4e4ca7ed9e52a284cb208fcdbbb
+ React-callinvoker: 4959a69fb49a4aa112b4c7bf0c1bd9ca3710d9a6
+ React-Core: 3ce55e83880fc0228affe12885392dc6f4bf29ef
+ React-CoreModules: 5d5b053d5f6ed88d7758d8d7675a8e40a516a697
+ React-cxxreact: 71a580171624787158edff32a8849ba803aa526d
+ React-debug: 1211cf37d67e53ef6f6eea0953b269a41a18385c
+ React-defaultsnativemodule: 9761c21932fb0d08ce8b3e688d2c10898a7935c3
+ React-domnativemodule: c1ac18fd09e3a9f810ad52c531286e2fba6cce9c
+ React-Fabric: be125354b9a12cd115c367accfeec50c794fc214
+ React-FabricComponents: 14e01bb831e597c61e607e0a5b714fdeb04e83ba
+ React-FabricImage: 4e87338e9b0e3935d5e7e38e1acb8e9e656538e2
+ React-featureflags: c68b0705ee740d23f7a94c800cfc25e77db6fd1c
+ React-featureflagsnativemodule: 26ab4b3612f26f08495fea97f19780a78a348559
+ React-graphics: 5222b05193bcc15f51f89a1f311d86f7276f95a5
+ React-hermes: f7da092992cca6620ead6324d13b28e8a81bbb71
+ React-idlecallbacksnativemodule: b6f8bed2c9ac633cacc49d51506945e09eb8946e
+ React-ImageManager: e999d2fb67d4b12ef171d9621e4f49d02aef5c99
+ React-intersectionobservernativemodule: 15659f38709a2fd3931dd7d0ef365f50c01905a3
+ React-jserrorhandler: 449649e6873432b01baad04433dd9bce83a80c31
+ React-jsi: 7bce8ab5adbb212df1d919453545bd805fcf2b05
+ React-jsiexecutor: c13a49ed3bf6e6f2c49984cc94521c4a7fa1e13d
+ React-jsinspector: 567febddd958bd6192ea775d799598afaecccdc5
+ React-jsinspectorcdp: 3924f6476360435eea9a42fc6a86d25212851ae2
+ React-jsinspectornetwork: 8353fb4c57b809c25ae1c156bd842188f31ed5f9
+ React-jsinspectortracing: e5aa58dcb41db03e52d1c54aeed98b3d0b3f6dc3
+ React-jsitooling: b0264ccb2edd0d4932354bcdcad3d3069e011d1f
+ React-jsitracing: 2707d1e8ed1372f7efed7f38556b1f2203f43ef9
+ React-logger: 2672be09f8bbea9d333ce90993229d2cb97bd88c
+ React-Mapbuffer: 18b84471ea62fe08cd1e8bb2b7f7157cb28b17e8
+ React-microtasksnativemodule: 3b7617c913cc03ca7aba24123f52be568669e5a4
+ react-native-safe-area-context: 9e5bc71daf3e49d12563467aa3f38d3229eed544
+ React-NativeModulesApple: f52e4afbf54e775512678e3b5826a70c9199604a
+ React-networking: 83ea514d969ac897789a14b3d4def81a6192df82
+ React-oscompat: 2c4945336d3a1e509944c6a6a530bc1b6e756581
+ React-perflogger: 5fd09615168f610d692f9d5b447b1f2beafed60c
+ React-performancecdpmetrics: 6b0abacd1949f6ca6829327cbe652f8154edb196
+ React-performancetimeline: e447639629e6c2d39762acefecb393e4bc1aeee6
+ React-RCTActionSheet: b4830feb56db4f96fb8c1b57f5b709260b2f3039
+ React-RCTAnimation: 23f690a34ffcfc86736b4d7595e3bd7315a71c9e
+ React-RCTAppDelegate: a4b10973321e4b38d4c2603c49dc3b46636a0d26
+ React-RCTBlob: 5e66f5a7b36c4a930574a36aed452d9cc8efb98b
+ React-RCTFabric: 79d797f70e1f1b85714498bc706ce7976ec540ff
+ React-RCTFBReactNativeSpec: 5ce90339fe2345091c9ef7d793fa132a7f50864b
+ React-RCTImage: edfa9e9e85d56fae0efb8ac8dc610bb5e63c350d
+ React-RCTLinking: 775ac43fe94885a0599087fb0c52f2b5b0063b87
+ React-RCTNetwork: 765db6ba87eb772d5d13a7187721f17a303f9c2f
+ React-RCTRuntime: 2ac062909f47077efd49df0c07769e2356cf1d44
+ React-RCTSettings: a1071026d0ee4469664cfdcd231decd03786342e
+ React-RCTText: 81cc409814037ecc0d67a9fd3077a00526d74cee
+ React-RCTVibration: eda9818e4590d42d06096e42c8daf420a8ea4613
+ React-rendererconsistency: 0a18e032dbb29ab164df4e6038fc492391d091e2
+ React-renderercss: e24a8e88142e2f425548b1e8b64d59e6b3695824
+ React-rendererdebug: 0d3c7ba854722d38d7fde109fb68938f08ba3f40
+ React-RuntimeApple: 758268250708329709a42b706c1aadb399a238d0
+ React-RuntimeCore: 045a7531efe97b43dc63c8e07f3d71723e69b848
+ React-runtimeexecutor: 8047c6abd869ac025149227cb6b383a73c9c40d0
+ React-RuntimeHermes: 62067b543404728239e272ecadc7abcac72895ad
+ React-runtimescheduler: d61bff8c61e5f4af83961c746ab78fa9175fe707
+ React-timing: 0ffd9fb34d1523e3d59d1067eb6a7a8afc7308ab
+ React-utils: a043b130659d28ecb63c645419a999f10c8f4cbb
+ React-webperformancenativemodule: 4ec96a6185ce3f7299718427c4c23351ef50ef47
+ ReactAppDependencyProvider: 706b65371b90b5cc797b6639e8979f2e5cecd6da
+ ReactBrownfield: 7ff10b16813f35d121c09cc67e64c6885bd62868
+ ReactCodegen: 3b63446e22acfdafa14e48a23c4a34b3ec99215e
+ ReactCommon: d588ff8119315f4d3341e06f954e60789b050710
+ ReactNativeDependencies: 7712c4eaacab8079bb23db36189ff31ec3aaa0a1
+ RNScreens: 95768361283b55ac64a746624e59e142dc9fb2b2
+ Yoga: 7549f28c2f55a71280f339554f8980f4a1414b0f
-PODFILE CHECKSUM: 7c116a16dd0744063c8c6293dbfc638c9d447c19
+PODFILE CHECKSUM: 9ed3db0e1a810da406aae84074364a6f2ae6e18e
-COCOAPODS: 1.15.2
+COCOAPODS: 1.16.2
diff --git a/apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj b/apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj
index 6f208d6e..56f0df35 100644
--- a/apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj
+++ b/apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj
@@ -9,45 +9,19 @@
/* Begin PBXBuildFile section */
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
761780ED2CA45674006654EE /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 761780EC2CA45674006654EE /* AppDelegate.swift */; };
- 79BD1EE92EEBFB76003AA29F /* BrownfieldLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79BD1EE32EEBFB76003AA29F /* BrownfieldLib.framework */; };
- 79BD1EEA2EEBFB76003AA29F /* BrownfieldLib.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 79BD1EE32EEBFB76003AA29F /* BrownfieldLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
79F35E8C2EEC1D4500E64860 /* BrownfieldLib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79F35E8A2EEC1D4500E64860 /* BrownfieldLib.swift */; };
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; };
- A0777EAAAA3FC7C5E02611A4 /* Pods_RNApp_BrownfieldLib.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FBC148EBB082E19EA065F91F /* Pods_RNApp_BrownfieldLib.framework */; };
C66C2A65406C527E9529D08F /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */; };
- ED0516C81FD8393A3D6B4371 /* Pods_RNApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2065C22D9167CC092D4BB5F7 /* Pods_RNApp.framework */; };
+ F02F27E3784DC88515C6E8F4 /* libPods-RNApp.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 264668A0A6A25B018CF90ADF /* libPods-RNApp.a */; };
+ F34F42A893EB134133D98528 /* libPods-RNApp-BrownfieldLib.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FBDE9BFB6AD0F60F250EF4F0 /* libPods-RNApp-BrownfieldLib.a */; };
/* End PBXBuildFile section */
-/* Begin PBXContainerItemProxy section */
- 79BD1EE72EEBFB76003AA29F /* PBXContainerItemProxy */ = {
- isa = PBXContainerItemProxy;
- containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
- proxyType = 1;
- remoteGlobalIDString = 79BD1EE22EEBFB76003AA29F;
- remoteInfo = BrownfieldLib;
- };
-/* End PBXContainerItemProxy section */
-
-/* Begin PBXCopyFilesBuildPhase section */
- 79BD1EEB2EEBFB76003AA29F /* Embed Frameworks */ = {
- isa = PBXCopyFilesBuildPhase;
- buildActionMask = 2147483647;
- dstPath = "";
- dstSubfolderSpec = 10;
- files = (
- 79BD1EEA2EEBFB76003AA29F /* BrownfieldLib.framework in Embed Frameworks */,
- );
- name = "Embed Frameworks";
- runOnlyForDeploymentPostprocessing = 0;
- };
-/* End PBXCopyFilesBuildPhase section */
-
/* Begin PBXFileReference section */
13B07F961A680F5B00A75B9A /* RNApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNApp/Images.xcassets; sourceTree = ""; };
13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNApp/Info.plist; sourceTree = ""; };
13B07FB81A68108700A75B9A /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = PrivacyInfo.xcprivacy; path = RNApp/PrivacyInfo.xcprivacy; sourceTree = ""; };
- 2065C22D9167CC092D4BB5F7 /* Pods_RNApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNApp.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 264668A0A6A25B018CF90ADF /* libPods-RNApp.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNApp.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B4392A12AC88292D35C810B /* Pods-RNApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNApp.debug.xcconfig"; path = "Target Support Files/Pods-RNApp/Pods-RNApp.debug.xcconfig"; sourceTree = ""; };
5709B34CF0A7D63546082F79 /* Pods-RNApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNApp.release.xcconfig"; path = "Target Support Files/Pods-RNApp/Pods-RNApp.release.xcconfig"; sourceTree = ""; };
761780EC2CA45674006654EE /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AppDelegate.swift; path = RNApp/AppDelegate.swift; sourceTree = ""; };
@@ -55,9 +29,11 @@
79F35E8A2EEC1D4500E64860 /* BrownfieldLib.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrownfieldLib.swift; sourceTree = ""; };
81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNApp/LaunchScreen.storyboard; sourceTree = ""; };
8A02E03D9F74B585B0A8F7F7 /* Pods-RNApp-BrownfieldLib.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNApp-BrownfieldLib.debug.xcconfig"; path = "Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib.debug.xcconfig"; sourceTree = ""; };
+ 8DE6C83C7F2BC83DBB759902 /* Pods-BrownfieldLib.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BrownfieldLib.release.xcconfig"; path = "Target Support Files/Pods-BrownfieldLib/Pods-BrownfieldLib.release.xcconfig"; sourceTree = ""; };
+ 95063596E6073550AEA8DCEA /* Pods-BrownfieldLib.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BrownfieldLib.debug.xcconfig"; path = "Target Support Files/Pods-BrownfieldLib/Pods-BrownfieldLib.debug.xcconfig"; sourceTree = ""; };
D8C030F60E402FD6CFBB3904 /* Pods-RNApp-BrownfieldLib.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNApp-BrownfieldLib.release.xcconfig"; path = "Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib.release.xcconfig"; sourceTree = ""; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
- FBC148EBB082E19EA065F91F /* Pods_RNApp_BrownfieldLib.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RNApp_BrownfieldLib.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ FBDE9BFB6AD0F60F250EF4F0 /* libPods-RNApp-BrownfieldLib.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNApp-BrownfieldLib.a"; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -65,8 +41,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 79BD1EE92EEBFB76003AA29F /* BrownfieldLib.framework in Frameworks */,
- ED0516C81FD8393A3D6B4371 /* Pods_RNApp.framework in Frameworks */,
+ F02F27E3784DC88515C6E8F4 /* libPods-RNApp.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -74,7 +49,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- A0777EAAAA3FC7C5E02611A4 /* Pods_RNApp_BrownfieldLib.framework in Frameworks */,
+ F34F42A893EB134133D98528 /* libPods-RNApp-BrownfieldLib.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -97,8 +72,8 @@
isa = PBXGroup;
children = (
ED297162215061F000B7C4FE /* JavaScriptCore.framework */,
- 2065C22D9167CC092D4BB5F7 /* Pods_RNApp.framework */,
- FBC148EBB082E19EA065F91F /* Pods_RNApp_BrownfieldLib.framework */,
+ 264668A0A6A25B018CF90ADF /* libPods-RNApp.a */,
+ FBDE9BFB6AD0F60F250EF4F0 /* libPods-RNApp-BrownfieldLib.a */,
);
name = Frameworks;
sourceTree = "";
@@ -149,6 +124,8 @@
5709B34CF0A7D63546082F79 /* Pods-RNApp.release.xcconfig */,
8A02E03D9F74B585B0A8F7F7 /* Pods-RNApp-BrownfieldLib.debug.xcconfig */,
D8C030F60E402FD6CFBB3904 /* Pods-RNApp-BrownfieldLib.release.xcconfig */,
+ 95063596E6073550AEA8DCEA /* Pods-BrownfieldLib.debug.xcconfig */,
+ 8DE6C83C7F2BC83DBB759902 /* Pods-BrownfieldLib.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -177,12 +154,10 @@
00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */,
00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */,
E235C05ADACE081382539298 /* [CP] Copy Pods Resources */,
- 79BD1EEB2EEBFB76003AA29F /* Embed Frameworks */,
);
buildRules = (
);
dependencies = (
- 79BD1EE82EEBFB76003AA29F /* PBXTargetDependency */,
);
name = RNApp;
productName = RNApp;
@@ -199,7 +174,7 @@
79BD1EE02EEBFB76003AA29F /* Frameworks */,
79BD1EE12EEBFB76003AA29F /* Resources */,
79BD1EF22EEBFC6F003AA29F /* Bundle React Native code and images */,
- 5D40A0F9F23D3E7986C15E2B /* [CP] Copy Pods Resources */,
+ 112A6FD8ACAA239E339C7376 /* [CP] Copy Pods Resources */,
);
buildRules = (
);
@@ -300,43 +275,43 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNApp/Pods-RNApp-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
- 24E8B7472F26616B6BFC142D /* [CP] Check Pods Manifest.lock */ = {
+ 112A6FD8ACAA239E339C7376 /* [CP] Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources-${CONFIGURATION}-input-files.xcfilelist",
);
- inputPaths = (
- "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
- "${PODS_ROOT}/Manifest.lock",
- );
- name = "[CP] Check Pods Manifest.lock";
+ name = "[CP] Copy Pods Resources";
outputFileListPaths = (
- );
- outputPaths = (
- "$(DERIVED_FILE_DIR)/Pods-RNApp-BrownfieldLib-checkManifestLockResult.txt",
+ "${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources-${CONFIGURATION}-output-files.xcfilelist",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources.sh\"\n";
showEnvVarsInLog = 0;
};
- 5D40A0F9F23D3E7986C15E2B /* [CP] Copy Pods Resources */ = {
+ 24E8B7472F26616B6BFC142D /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources-${CONFIGURATION}-input-files.xcfilelist",
);
- name = "[CP] Copy Pods Resources";
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
- "${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-RNApp-BrownfieldLib-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNApp-BrownfieldLib/Pods-RNApp-BrownfieldLib-resources.sh\"\n";
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
79BD1EF22EEBFC6F003AA29F /* Bundle React Native code and images */ = {
@@ -419,14 +394,6 @@
};
/* End PBXSourcesBuildPhase section */
-/* Begin PBXTargetDependency section */
- 79BD1EE82EEBFB76003AA29F /* PBXTargetDependency */ = {
- isa = PBXTargetDependency;
- target = 79BD1EE22EEBFB76003AA29F /* BrownfieldLib */;
- targetProxy = 79BD1EE72EEBFB76003AA29F /* PBXContainerItemProxy */;
- };
-/* End PBXTargetDependency section */
-
/* Begin XCBuildConfiguration section */
13B07F941A680F5B00A75B9A /* Debug */ = {
isa = XCBuildConfiguration;
diff --git a/apps/RNApp/ios/RNApp/AppDelegate.swift b/apps/RNApp/ios/RNApp/AppDelegate.swift
index eeb40c1d..2025b0d1 100644
--- a/apps/RNApp/ios/RNApp/AppDelegate.swift
+++ b/apps/RNApp/ios/RNApp/AppDelegate.swift
@@ -2,6 +2,7 @@ import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider
+import Brownie
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
@@ -23,6 +24,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
window = UIWindow(frame: UIScreen.main.bounds)
+ // Register in the same Brownie instance React Native uses (see BrownieBootstrap).
+ BrownieBootstrap.register(
+ BrownfieldStore(
+ counter: 0,
+ user: User(name: "Username")
+ )
+ )
+
factory.startReactNative(
withModuleName: "RNApp",
in: window,
@@ -40,9 +49,15 @@ class ReactNativeDelegate: RCTDefaultReactNativeFactoryDelegate {
override func bundleURL() -> URL? {
#if DEBUG
- RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
+ // Detox passes -BrownfieldPreferEmbeddedBundleInDebug; E2E builds embed main.jsbundle
+ // via FORCE_BUNDLING=1 (see apps/RNApp/.detoxrc.cjs). Local `yarn ios` keeps using Metro.
+ if ProcessInfo.processInfo.arguments.contains("-BrownfieldPreferEmbeddedBundleInDebug"),
+ let embedded = Bundle.main.url(forResource: "main", withExtension: "jsbundle") {
+ return embedded
+ }
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
#else
- Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
#endif
}
}
diff --git a/apps/RNApp/package.json b/apps/RNApp/package.json
index ee760f79..aa4a40c4 100644
--- a/apps/RNApp/package.json
+++ b/apps/RNApp/package.json
@@ -3,8 +3,8 @@
"version": "0.0.1",
"private": true,
"scripts": {
- "android": "react-native run-android",
- "ios": "react-native run-ios",
+ "android": "yarn brownfield:package:android && brownfield codegen && react-native run-android",
+ "ios": "yarn brownfield:package:ios && brownfield codegen && react-native run-ios",
"build:example:android-rn": "react-native build-android",
"build:example:ios-rn": "react-native build-ios",
"brownfield:package:android": "brownfield package:android --module-name :BrownfieldLib --variant release --verbose",
@@ -13,10 +13,14 @@
"lint": "eslint .",
"start": "react-native start",
"test": "jest --config jest.config.js",
+ "e2e:build:ios": "detox build --configuration ios.sim.debug",
+ "e2e:test:ios": "detox test --configuration ios.sim.debug",
+ "ci:local:e2e:ios": "bash ../../scripts/ci-local-rnapp-ios-e2e.sh",
"codegen": "brownfield codegen",
"codegen:navigation": "brownfield navigation:codegen brownfield.navigation.ts"
},
"dependencies": {
+ "@callstack/brownfield-example-shared-tests": "workspace:^",
"@callstack/brownfield-navigation": "workspace:^",
"@callstack/brownie": "workspace:^",
"@callstack/react-native-brownfield": "workspace:^",
@@ -31,7 +35,6 @@
"@babel/core": "^7.25.2",
"@babel/preset-env": "^7.25.3",
"@babel/runtime": "^7.25.0",
- "@callstack/brownfield-example-shared-tests": "workspace:^",
"@react-native-community/cli": "20.1.0",
"@react-native-community/cli-platform-android": "20.1.0",
"@react-native-community/cli-platform-ios": "20.1.0",
@@ -44,6 +47,7 @@
"@types/jest": "^30.0.0",
"@types/react": "^19.2.0",
"@types/react-test-renderer": "^19.1.0",
+ "detox": "^20.27.0",
"eslint": "^9.39.3",
"jest": "^29.7.0",
"prettier": "^3.8.1",
diff --git a/apps/RNApp/src/HomeScreen.tsx b/apps/RNApp/src/HomeScreen.tsx
index 159b5b7a..c0d20c29 100644
--- a/apps/RNApp/src/HomeScreen.tsx
+++ b/apps/RNApp/src/HomeScreen.tsx
@@ -10,6 +10,7 @@ import {
} from 'react-native';
import type { NativeStackScreenProps } from '@react-navigation/native-stack';
import ReactNativeBrownfield from '@callstack/react-native-brownfield';
+import { brownfieldE2eTestIds } from '@callstack/brownfield-example-shared-tests/e2eTestIds';
import BrownfieldNavigation from '@callstack/brownfield-navigation';
import { getRandomTheme } from './utils';
@@ -61,7 +62,14 @@ function MessageBubble({ item, color }: { item: Message; color: string }) {
{isFromNative ? 'From Native' : 'From RN'}
- {item.text}
+
+ {item.text}
+
);
}
@@ -119,8 +127,15 @@ export function HomeScreen({
}, []);
return (
-
-
+
+
React Native Screen
@@ -135,8 +150,36 @@ export function HomeScreen({
+
+
+ BrownfieldNavigation.navigateToSettings({
+ id: '123',
+ name: 'John Doe',
+ email: 'john.doe@example.com',
+ flags: ['admin', 'user'],
+ ids: ['123', '456'],
+ avatar: {
+ url: 'https://example.com/avatar.png',
+ },
+ })
+ }
+ color={colors.secondary}
+ title="Open native settings"
+ />
+
+ BrownfieldNavigation.navigateToReferrals('user-123')}
+ color={colors.secondary}
+ title="Open native referrals"
+ />
+
+
-
-
- BrownfieldNavigation.navigateToSettings({
- id: '123',
- name: 'John Doe',
- email: 'john.doe@example.com',
- flags: ['admin', 'user'],
- ids: ['123', '456'],
- avatar: {
- url: 'https://example.com/avatar.png',
- },
- })
- }
- color={colors.secondary}
- title="Open native settings"
- />
-
- BrownfieldNavigation.navigateToReferrals('user-123')}
- color={colors.secondary}
- title="Open native referrals"
- />
);
}
@@ -229,6 +249,7 @@ const styles = StyleSheet.create({
},
messageSection: {
flex: 1,
+ minHeight: 0,
width: '100%',
marginTop: 12,
},
@@ -245,6 +266,7 @@ const styles = StyleSheet.create({
},
messageList: {
flex: 1,
+ minHeight: 0,
},
messageListContent: {
paddingBottom: 8,
@@ -275,6 +297,12 @@ const styles = StyleSheet.create({
fontSize: 14,
color: '#fff',
},
+ nativeNavButtons: {
+ width: '100%',
+ gap: 8,
+ marginTop: 8,
+ marginBottom: 4,
+ },
navButtons: {
flexDirection: 'row',
gap: 12,
diff --git a/apps/RNApp/src/components/counter/index.tsx b/apps/RNApp/src/components/counter/index.tsx
index 20ca26e4..4cdd5f19 100644
--- a/apps/RNApp/src/components/counter/index.tsx
+++ b/apps/RNApp/src/components/counter/index.tsx
@@ -1,3 +1,4 @@
+import { brownfieldE2eTestIds } from '@callstack/brownfield-example-shared-tests/e2eTestIds';
import { Button, StyleSheet, Text } from 'react-native';
import { useStore } from '@callstack/brownie';
@@ -10,11 +11,16 @@ const Counter = ({ colors }: CounterProps) => {
return (
<>
-
+
Count: {counter}
setState((prev) => ({ counter: prev.counter + 1 }))}
color={colors.secondary}
title="Increment"
diff --git a/apps/brownfield-example-shared-tests/detox-ios-simulator-device.cjs b/apps/brownfield-example-shared-tests/detox-ios-simulator-device.cjs
new file mode 100644
index 00000000..aa2d450d
--- /dev/null
+++ b/apps/brownfield-example-shared-tests/detox-ios-simulator-device.cjs
@@ -0,0 +1,94 @@
+'use strict';
+
+const { execSync } = require('node:child_process');
+
+/** Used when simctl is unavailable (e.g. CI without Xcode) or lists no iPhones. */
+const FALLBACK_DEVICE_TYPE = 'iPhone 16';
+
+function tryExec(command) {
+ try {
+ return execSync(command, {
+ encoding: 'utf8',
+ stdio: ['ignore', 'pipe', 'pipe'],
+ });
+ } catch {
+ return '';
+ }
+}
+
+function listSimctlIphoneDeviceTypes() {
+ for (const command of [
+ // Newer Xcode releases may change support for the `available` suffix.
+ 'xcrun simctl list devicetypes available',
+ 'xcrun simctl list devicetypes',
+ ]) {
+ const out = tryExec(command);
+ if (!out) continue;
+
+ const types = [];
+ for (const line of out.split('\n')) {
+ const m = line.match(/^\s*(iPhone [^(\n]+?)\s*\(/);
+ if (m) types.push(m[1].trim());
+ }
+ if (types.length > 0) return types;
+ }
+
+ return [];
+}
+
+function listSimctlAvailableIphoneDevices() {
+ const out = tryExec('xcrun simctl list devices available');
+ if (!out) return [];
+
+ const devices = [];
+ for (const line of out.split('\n')) {
+ // Example: " iPhone 16 Pro (XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX) (Shutdown)"
+ const m = line.match(/^\s*(iPhone [^(]+)\s+\([0-9A-F-]+\)\s+\((?:Shutdown|Booted)\)\s*$/i);
+ if (m) devices.push(m[1].trim());
+ }
+ return devices;
+}
+
+function scoreDeviceType(name) {
+ const generation = name.match(/iPhone\s+(\d+)/i);
+ if (!generation) return -1;
+ let score = parseInt(generation[1], 10) * 10;
+ if (/pro max/i.test(name)) score += 3;
+ else if (/\bpro\b/i.test(name)) score += 2;
+ else if (/plus/i.test(name)) score += 1;
+ else if (/mini/i.test(name)) score += 0.5;
+ return score;
+}
+
+/**
+ * Device `type` string for Detox `ios.simulator` config (matches Xcode / simctl names).
+ *
+ * Override: `DETOX_DEVICE` or `DETOX_IOS_SIMULATOR_DEVICE` (e.g. same name as in Xcode’s
+ * “Product → Destination” list).
+ *
+ * Otherwise picks the highest-numbered iPhone \* device type reported by simctl.
+ */
+function getIosSimulatorDeviceType() {
+ const fromEnv =
+ process.env.DETOX_DEVICE?.trim() ||
+ process.env.DETOX_IOS_SIMULATOR_DEVICE?.trim();
+ if (fromEnv) return fromEnv;
+
+ const types = [
+ ...listSimctlIphoneDeviceTypes(),
+ ...listSimctlAvailableIphoneDevices(),
+ ];
+
+ let best = null;
+ let bestScore = -1;
+ for (const t of types) {
+ const s = scoreDeviceType(t);
+ if (s > bestScore) {
+ bestScore = s;
+ best = t;
+ }
+ }
+ return best || FALLBACK_DEVICE_TYPE;
+}
+
+module.exports = { getIosSimulatorDeviceType };
diff --git a/apps/brownfield-example-shared-tests/e2e/expoPostMessageBrownfield.e2e.js b/apps/brownfield-example-shared-tests/e2e/expoPostMessageBrownfield.e2e.js
new file mode 100644
index 00000000..a476e3d5
--- /dev/null
+++ b/apps/brownfield-example-shared-tests/e2e/expoPostMessageBrownfield.e2e.js
@@ -0,0 +1,55 @@
+const assert = require('node:assert/strict');
+const { device, element, by, waitFor, expect: detoxExpect } = require('detox');
+
+const ids = {
+ sendMessageToNative: 'brownfield-e2e-send-message-native',
+ rnPostMessageText: 'brownfield-e2e-rn-post-message-text',
+};
+
+function detoxAttrsText(attrs) {
+ if (!attrs || typeof attrs !== 'object') {
+ return '';
+ }
+ const fragment = (o) =>
+ [o.text, o.value, o.label, o.hint]
+ .filter((x) => x != null && String(x).length > 0)
+ .join('');
+ if ('elements' in attrs && Array.isArray(attrs.elements)) {
+ return attrs.elements.map(fragment).join('').trim();
+ }
+ return fragment(attrs).trim();
+}
+
+async function assertDetoxTextMatches(nativeElement, pattern) {
+ const attrs = await nativeElement.getAttributes();
+ assert.match(detoxAttrsText(attrs).trim(), pattern);
+}
+
+const sendMessageToNative = ids.sendMessageToNative;
+
+describe('Brownfield postMessage (Expo demo)', () => {
+ beforeEach(async () => {
+ // Full relaunch is more reliable than reloadReactNative() on newer RN/Xcode.
+ await device.launchApp({
+ newInstance: true,
+ launchArgs: { BrownfieldPreferEmbeddedBundleInDebug: 'YES' },
+ });
+ const sendMessageButton = element(by.id(sendMessageToNative));
+ try {
+ await waitFor(sendMessageButton).toBeVisible().withTimeout(45000);
+ } catch {
+ // Some CI runs start with an unmounted RN surface; one reload usually recovers.
+ await device.reloadReactNative();
+ await waitFor(sendMessageButton).toBeVisible().withTimeout(45000);
+ }
+ });
+
+ it('sends a message to native from the brownfield RN root', async () => {
+ await detoxExpect(element(by.id(sendMessageToNative))).toBeVisible();
+ await element(by.id(sendMessageToNative)).tap();
+ const bubble = element(by.id(ids.rnPostMessageText)).atIndex(0);
+ await detoxExpect(bubble).toBeVisible();
+ // iOS + Fabric: message text is often not matchable via by.text; attributes still carry it.
+ await assertDetoxTextMatches(bubble, /Hello from Expo!/);
+ });
+});
diff --git a/apps/brownfield-example-shared-tests/e2e/rnAppBrownfield.e2e.js b/apps/brownfield-example-shared-tests/e2e/rnAppBrownfield.e2e.js
new file mode 100644
index 00000000..a6532caf
--- /dev/null
+++ b/apps/brownfield-example-shared-tests/e2e/rnAppBrownfield.e2e.js
@@ -0,0 +1,78 @@
+const assert = require('node:assert/strict');
+const { device, element, by, waitFor, expect: detoxExpect } = require('detox');
+
+function detoxAttrsText(attrs) {
+ if (!attrs || typeof attrs !== 'object') {
+ return '';
+ }
+ const fragment = (o) =>
+ [o.text, o.value, o.label, o.hint]
+ .filter((x) => x != null && String(x).length > 0)
+ .join('');
+ if ('elements' in attrs && Array.isArray(attrs.elements)) {
+ return attrs.elements.map(fragment).join('').trim();
+ }
+ return fragment(attrs).trim();
+}
+
+async function assertDetoxTextMatches(nativeElement, pattern) {
+ const attrs = await nativeElement.getAttributes();
+ assert.match(detoxAttrsText(attrs).trim(), pattern);
+}
+
+const ids = {
+ rnAppHome: 'brownfield-e2e-rnapp-home',
+ rnAppHomeTitle: 'brownfield-e2e-rnapp-home-title',
+ sendMessageToNative: 'brownfield-e2e-send-message-native',
+ openNativeSettings: 'brownfield-e2e-open-native-settings',
+ openNativeReferrals: 'brownfield-e2e-open-native-referrals',
+ counterCount: 'brownfield-e2e-counter-count',
+ counterIncrement: 'brownfield-e2e-counter-increment',
+ rnPostMessageText: 'brownfield-e2e-rn-post-message-text',
+};
+
+describe('Brownfield (RNApp)', () => {
+ beforeEach(async () => {
+ // Full relaunch is more reliable than reloadReactNative() on newer RN/Xcode.
+ await device.launchApp({
+ newInstance: true,
+ launchArgs: { BrownfieldPreferEmbeddedBundleInDebug: 'YES' },
+ });
+ const home = element(by.id(ids.rnAppHome));
+ try {
+ await waitFor(home).toBeVisible().withTimeout(45000);
+ } catch {
+ // Some CI runs start with an unmounted RN surface; one reload usually recovers.
+ await device.reloadReactNative();
+ await waitFor(home).toBeVisible().withTimeout(45000);
+ }
+ });
+
+ it('shows the brownfield home surface', async () => {
+ await detoxExpect(element(by.id(ids.rnAppHome))).toBeVisible();
+ const title = element(by.id(ids.rnAppHomeTitle));
+ await detoxExpect(title).toBeVisible();
+ // iOS + Fabric often omit text from Detox's toHaveText; attributes still carry it.
+ await assertDetoxTextMatches(title, /React Native Screen/);
+ });
+
+ it('increments the shared-store counter', async () => {
+ const count = element(by.id(ids.counterCount));
+ await detoxExpect(count).toBeVisible();
+ await assertDetoxTextMatches(count, /Count:\s*0/);
+ await element(by.id(ids.counterIncrement)).tap();
+ await assertDetoxTextMatches(count, /Count:\s*1/);
+ });
+
+ it('fires postMessage when sending to native', async () => {
+ await element(by.id(ids.sendMessageToNative)).tap();
+ const bubble = element(by.id(ids.rnPostMessageText)).atIndex(0);
+ await detoxExpect(bubble).toBeVisible();
+ await assertDetoxTextMatches(bubble, /Hello from React Native!/);
+ });
+
+ it('shows brownfield native navigation actions', async () => {
+ await detoxExpect(element(by.id(ids.openNativeSettings))).toBeVisible();
+ await detoxExpect(element(by.id(ids.openNativeReferrals))).toBeVisible();
+ });
+});
diff --git a/apps/brownfield-example-shared-tests/package.json b/apps/brownfield-example-shared-tests/package.json
index 98220eb0..f2f1818d 100644
--- a/apps/brownfield-example-shared-tests/package.json
+++ b/apps/brownfield-example-shared-tests/package.json
@@ -10,6 +10,7 @@
"exports": {
".": "./src/index.ts",
"./jest/setup": "./jest/setup.js",
+ "./e2eTestIds": "./src/e2eTestIds.ts",
"./jest/expo-config": "./jest/expo-config.js"
},
"peerDependencies": {
diff --git a/apps/brownfield-example-shared-tests/src/e2eTestIds.ts b/apps/brownfield-example-shared-tests/src/e2eTestIds.ts
new file mode 100644
index 00000000..ae3e292d
--- /dev/null
+++ b/apps/brownfield-example-shared-tests/src/e2eTestIds.ts
@@ -0,0 +1,15 @@
+/**
+ * Stable identifiers for Detox (and optional Maestro) runs across demo apps.
+ */
+export const brownfieldE2eTestIds = {
+ rnAppHome: 'brownfield-e2e-rnapp-home',
+ /** Title copy on RNApp home — use for Detox instead of `by.text` (iOS accessibility / Fabric). */
+ rnAppHomeTitle: 'brownfield-e2e-rnapp-home-title',
+ sendMessageToNative: 'brownfield-e2e-send-message-native',
+ openNativeSettings: 'brownfield-e2e-open-native-settings',
+ openNativeReferrals: 'brownfield-e2e-open-native-referrals',
+ counterCount: 'brownfield-e2e-counter-count',
+ counterIncrement: 'brownfield-e2e-counter-increment',
+ /** RN-authored postMessage bubble body (may repeat across list — use atIndex(0) for newest). */
+ rnPostMessageText: 'brownfield-e2e-rn-post-message-text',
+} as const;
diff --git a/package.json b/package.json
index 3fe20689..d16ddbe4 100644
--- a/package.json
+++ b/package.json
@@ -21,12 +21,14 @@
"build:docs": "turbo run build:docs",
"generate:store": "node --experimental-strip-types --no-warnings ./scripts/generate-store.ts",
"skillgym:brownie": "skillgym run skillgym/suites/brownie-suite.ts",
- "skillgym:navigation": "skillgym run skillgym/suites/brownfield-navigation-suite.ts"
+ "skillgym:navigation": "skillgym run skillgym/suites/brownfield-navigation-suite.ts",
+ "ci:local:rnapp:e2e:ios": "bash ./scripts/ci-local-rnapp-ios-e2e.sh",
+ "ci:local:expo55:e2e:ios": "bash ./scripts/ci-local-expo55-ios-e2e.sh"
},
"resolutions": {
"@types/react": "19.1.1",
"chromium-edge-launcher": "0.3.0",
- "glob": "13.0.6"
+ "detox/glob": "npm:7.2.3"
},
"packageManager": "yarn@4.12.0",
"dependencies": {
diff --git a/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationDelegate.kt b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationDelegate.kt
index 780059a3..9f682995 100644
--- a/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationDelegate.kt
+++ b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationDelegate.kt
@@ -1,3 +1,6 @@
package com.callstack.nativebrownfieldnavigation
-interface BrownfieldNavigationDelegate
+interface BrownfieldNavigationDelegate {
+ fun navigateToSettings(user: UserType)
+ fun navigateToReferrals(userId: String)
+}
diff --git a/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationModels.kt b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationModels.kt
new file mode 100644
index 00000000..e6fb9549
--- /dev/null
+++ b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/BrownfieldNavigationModels.kt
@@ -0,0 +1,36 @@
+package com.callstack.nativebrownfieldnavigation
+
+import com.facebook.react.bridge.ReadableMap
+
+data class UserType (
+ val avatar: Avatar? = null,
+ val email: String? = null,
+ val flags: List,
+ val id: String,
+ val ids: List? = null,
+ val name: String
+)
+
+data class Avatar (
+ val url: String
+)
+
+
+fun toUserType(value: ReadableMap): UserType {
+ return UserType(avatar = value.getMap("avatar")?.let { toAvatar(it) }, email = value.getString("email"), flags = readStringArray(value, "flags", true)!!, id = value.getString("id")!!, ids = readStringArray(value, "ids", false), name = value.getString("name")!!)
+}
+
+fun toAvatar(value: ReadableMap): Avatar {
+ return Avatar(url = value.getString("url")!!)
+}
+
+private fun readStringArray(value: ReadableMap, key: String, required: Boolean): List? {
+ if (!value.hasKey(key) || value.isNull(key)) {
+ if (required) error("Missing required array field '$key'")
+ return null
+ }
+ val array = value.getArray(key) ?: return null
+ return array.toArrayList().map {
+ it as? String ?: error("Expected string elements for array field '$key'")
+ }
+}
\ No newline at end of file
diff --git a/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/NativeBrownfieldNavigationModule.kt b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/NativeBrownfieldNavigationModule.kt
index f118105a..455ca164 100644
--- a/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/NativeBrownfieldNavigationModule.kt
+++ b/packages/brownfield-navigation/android/src/main/java/com/callstack/nativebrownfieldnavigation/NativeBrownfieldNavigationModule.kt
@@ -1,15 +1,21 @@
package com.callstack.nativebrownfieldnavigation
-import android.util.Log
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactMethod
+import com.facebook.react.bridge.ReadableMap
class NativeBrownfieldNavigationModule(
reactContext: ReactApplicationContext
) : NativeBrownfieldNavigationSpec(reactContext) {
@ReactMethod
- override fun temporary() {
- Log.d(NAME, "temporary")
+ override fun navigateToSettings(user: ReadableMap) {
+ val userModel = user.let(::toUserType)
+ BrownfieldNavigationManager.getDelegate().navigateToSettings(userModel)
+ }
+
+ @ReactMethod
+ override fun navigateToReferrals(userId: String) {
+ BrownfieldNavigationManager.getDelegate().navigateToReferrals(userId)
}
companion object {
diff --git a/packages/brownfield-navigation/ios/BrownfieldNavigationDelegate.swift b/packages/brownfield-navigation/ios/BrownfieldNavigationDelegate.swift
index f4b2828d..49b73cf3 100644
--- a/packages/brownfield-navigation/ios/BrownfieldNavigationDelegate.swift
+++ b/packages/brownfield-navigation/ios/BrownfieldNavigationDelegate.swift
@@ -1,5 +1,6 @@
import Foundation
@objc public protocol BrownfieldNavigationDelegate: AnyObject {
-
+ @objc func navigateToSettings(_ user: UserType)
+ @objc func navigateToReferrals(_ userId: String)
}
diff --git a/packages/brownfield-navigation/ios/BrownfieldNavigationModels.swift b/packages/brownfield-navigation/ios/BrownfieldNavigationModels.swift
new file mode 100644
index 00000000..bfc184e1
--- /dev/null
+++ b/packages/brownfield-navigation/ios/BrownfieldNavigationModels.swift
@@ -0,0 +1,47 @@
+// This file was generated from JSON Schema using quicktype, do not modify it directly.
+// To parse the JSON, add this file to your project and do:
+//
+// let userType = try? JSONDecoder().decode(UserType.self, from: jsonData)
+
+import Foundation
+
+// MARK: - UserType
+@objcMembers public class UserType: NSObject, Codable {
+ public var avatar: Avatar?
+ public var email: String?
+ public var flags: [String]
+ public var id: String
+ public var ids: [String]?
+ public var name: String
+
+ public init(avatar: Avatar?, email: String?, flags: [String], id: String, ids: [String]?, name: String) {
+ self.avatar = avatar
+ self.email = email
+ self.flags = flags
+ self.id = id
+ self.ids = ids
+ self.name = name
+ }
+}
+
+// MARK: - Avatar
+@objcMembers public class Avatar: NSObject, Codable {
+ public var url: String
+
+ public init(url: String) {
+ self.url = url
+ }
+}
+
+
+@objc public extension UserType {
+ static func fromDictionary(_ value: NSDictionary) -> UserType {
+ return UserType(avatar: (value["avatar"] as? NSDictionary).map(Avatar.fromDictionary), email: value["email"] as? String, flags: value["flags"] as! [String], id: value["id"] as! String, ids: value["ids"] as? [String], name: value["name"] as! String)
+ }
+}
+
+@objc public extension Avatar {
+ static func fromDictionary(_ value: NSDictionary) -> Avatar {
+ return Avatar(url: value["url"] as! String)
+ }
+}
\ No newline at end of file
diff --git a/packages/brownfield-navigation/ios/NativeBrownfieldNavigation.mm b/packages/brownfield-navigation/ios/NativeBrownfieldNavigation.mm
index d92e3ef0..5cae4ff0 100644
--- a/packages/brownfield-navigation/ios/NativeBrownfieldNavigation.mm
+++ b/packages/brownfield-navigation/ios/NativeBrownfieldNavigation.mm
@@ -8,8 +8,13 @@
@implementation NativeBrownfieldNavigation
-- (void)temporary {
- NSLog(@"temporary");
+- (void)navigateToSettings:(NSDictionary *)user {
+ UserType *userModel = user == nil ? nil : [UserType fromDictionary:user];
+ [[[BrownfieldNavigationManager shared] getDelegate] navigateToSettings:userModel];
+}
+
+- (void)navigateToReferrals:(NSString *)userId {
+ [[[BrownfieldNavigationManager shared] getDelegate] navigateToReferrals:userId];
}
- (std::shared_ptr)getTurboModule:
diff --git a/packages/brownfield-navigation/src/NativeBrownfieldNavigation.ts b/packages/brownfield-navigation/src/NativeBrownfieldNavigation.ts
index 5d4ed84d..aed861a8 100644
--- a/packages/brownfield-navigation/src/NativeBrownfieldNavigation.ts
+++ b/packages/brownfield-navigation/src/NativeBrownfieldNavigation.ts
@@ -1,7 +1,21 @@
import { TurboModuleRegistry, type TurboModule } from 'react-native';
+export type UserType = {
+ id: string;
+ name: string;
+ email?: string;
+ flags: string[];
+ ids: string[] | null;
+ avatar?: AvatarType;
+};
+
+export type AvatarType = {
+ url: string;
+};
+
export interface Spec extends TurboModule {
- temporary(): void;
+ navigateToSettings(user: Object): void;
+ navigateToReferrals(userId: string): void;
}
export default TurboModuleRegistry.getEnforcing(
diff --git a/packages/brownfield-navigation/src/index.ts b/packages/brownfield-navigation/src/index.ts
index 5af516da..00aebf5d 100644
--- a/packages/brownfield-navigation/src/index.ts
+++ b/packages/brownfield-navigation/src/index.ts
@@ -1,8 +1,12 @@
import NativeBrownfieldNavigation from './NativeBrownfieldNavigation';
+import type { UserType } from './NativeBrownfieldNavigation';
const BrownfieldNavigation = {
- temporary: () => {
- NativeBrownfieldNavigation.temporary();
+ navigateToSettings: (user: UserType) => {
+ NativeBrownfieldNavigation.navigateToSettings(user);
+ },
+ navigateToReferrals: (userId: string) => {
+ NativeBrownfieldNavigation.navigateToReferrals(userId);
},
};
diff --git a/packages/brownie/ios/BrownieModule.h b/packages/brownie/ios/BrownieModule.h
index 8ef5f009..a3d04e47 100644
--- a/packages/brownie/ios/BrownieModule.h
+++ b/packages/brownie/ios/BrownieModule.h
@@ -1,7 +1,6 @@
#ifdef __cplusplus
#import
-#import
@interface BrownieModule : NativeBrownieModuleSpecBase
@end
diff --git a/packages/brownie/ios/BrownieModule.mm b/packages/brownie/ios/BrownieModule.mm
index 66f69f6f..0054d021 100644
--- a/packages/brownie/ios/BrownieModule.mm
+++ b/packages/brownie/ios/BrownieModule.mm
@@ -1,5 +1,6 @@
#import "BrownieModule.h"
#import
+#import
#if __has_include("Brownie/Brownie-Swift.h")
#import "Brownie/Brownie-Swift.h"
@@ -11,8 +12,25 @@
using namespace facebook;
-@interface BrownieModule (JSIBindings)
-@end
+namespace facebook::react {
+
+/**
+ * ObjC codegen TurboModules do not inherit TurboModuleWithJSIBindings in C++.
+ * Bridgeless mode only installs JSI globals via this hook when the module is first required from JS.
+ */
+class BrownieTurboModule : public NativeBrownieModuleSpecJSI,
+ public TurboModuleWithJSIBindings {
+ public:
+ explicit BrownieTurboModule(const ObjCTurboModule::InitParams ¶ms)
+ : NativeBrownieModuleSpecJSI(params) {}
+
+ private:
+ void installJSIBindingsWithRuntime(jsi::Runtime &runtime) override {
+ brownie::BrownieInstaller::install(runtime);
+ }
+};
+
+} // namespace facebook::react
@implementation BrownieModule {
NSMutableDictionary *_notificationObservers;
@@ -42,14 +60,9 @@ - (void)handleNotification:(NSNotification *)notification {
[self emitNativeStoreDidChange:userInfo];
}
-- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime
- callInvoker:(const std::shared_ptr &)callinvoker {
- brownie::BrownieInstaller::install(runtime);
-}
-
- (std::shared_ptr)getTurboModule:
(const facebook::react::ObjCTurboModule::InitParams &)params {
- return std::make_shared(params);
+ return std::make_shared(params);
}
@end
diff --git a/packages/brownie/ios/BrownieStore.swift b/packages/brownie/ios/BrownieStore.swift
index c7de4990..6554d2d3 100644
--- a/packages/brownie/ios/BrownieStore.swift
+++ b/packages/brownie/ios/BrownieStore.swift
@@ -17,6 +17,24 @@ public extension BrownieStoreProtocol {
}
}
+/// Registers a store in the C++ layer used by React Native JS.
+/// Use this from the app entry point (e.g. AppDelegate) before React Native starts.
+public enum BrownieBootstrap {
+ public static func registerStore(named storeName: String, state: [String: Any]) {
+ BrownieStoreBridge.registerStore(withKey: storeName)
+ BrownieStoreBridge.setState(from: state, forStore: storeName)
+ }
+
+ public static func register(_ initialState: State) {
+ guard let data = try? JSONEncoder().encode(initialState),
+ let state = try? JSONSerialization.jsonObject(with: data) as? [String: Any]
+ else {
+ return
+ }
+ registerStore(named: State.storeName, state: state)
+ }
+}
+
public struct StoreKey: EnvironmentKey {
public static var defaultValue: Store { fatalError("Store not provided") }
}
diff --git a/packages/react-native-brownfield/scripts/react_native_brownfield_post_integrate.rb b/packages/react-native-brownfield/scripts/react_native_brownfield_post_integrate.rb
index e02942ac..184f22c7 100644
--- a/packages/react-native-brownfield/scripts/react_native_brownfield_post_integrate.rb
+++ b/packages/react-native-brownfield/scripts/react_native_brownfield_post_integrate.rb
@@ -1,4 +1,49 @@
+def react_native_brownfield_patch_fmt_consteval(installer)
+ # Xcode 26+ clang: fmt's consteval format strings fail to compile (RCT-Folly dependency).
+ fmt_base_paths = [
+ File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h'),
+ File.join(installer.sandbox.root, 'ReactNativeDependencies', 'Headers', 'fmt', 'base.h'),
+ ]
+
+ fmt_base_paths.each do |fmt_base|
+ next unless File.exist?(fmt_base)
+
+ content = File.read(fmt_base)
+ next if content.include?('Xcode 26 workaround')
+
+ patched = content.gsub(
+ /^(#elif defined\(__cpp_consteval\)\n# define FMT_USE_CONSTEVAL) 1/,
+ "// Xcode 26 workaround: disable consteval\n\\1 0"
+ )
+ next if patched == content
+
+ File.chmod(0644, fmt_base)
+ File.write(fmt_base, patched)
+ end
+end
+
+def react_native_brownfield_skip_swift_module_interface_verification(installer)
+ # BrownfieldLib inherits BUILD_LIBRARY_FOR_DISTRIBUTION via CocoaPods xcconfigs;
+ # those values are not visible on target.build_settings during post_install.
+ # Newer Xcode fails SwiftVerifyEmittedModuleInterface for several pods (Brownie,
+ # ReachabilitySwift, etc.). Skip verification for all Pods targets; interfaces
+ # are still emitted when SWIFT_EMIT_MODULE_INTERFACE is enabled in xcconfig.
+ installer.pods_project.targets.each do |target|
+ target.build_configurations.each do |config|
+ flags = config.build_settings['OTHER_SWIFT_FLAGS'] || '$(inherited)'
+ flags = flags.is_a?(Array) ? flags.join(' ') : flags.to_s
+ next if flags.include?('-no-verify-emitted-module-interface')
+
+ config.build_settings['OTHER_SWIFT_FLAGS'] =
+ "#{flags} -no-verify-emitted-module-interface"
+ end
+ end
+end
+
def react_native_brownfield_post_integrate(installer)
+ react_native_brownfield_patch_fmt_consteval(installer)
+ react_native_brownfield_skip_swift_module_interface_verification(installer)
+
projects = installer.aggregate_targets.map(&:user_project).compact.uniq
projects.each do |project|
modified = false
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/__tests__/withDetoxEmbeddedBundleIosAppDelegate.test.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/__tests__/withDetoxEmbeddedBundleIosAppDelegate.test.ts
new file mode 100644
index 00000000..ec376e72
--- /dev/null
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/__tests__/withDetoxEmbeddedBundleIosAppDelegate.test.ts
@@ -0,0 +1,54 @@
+const EMBEDDED_BUNDLE_MARKER =
+ '// @callstack/react-native-brownfield: Detox embedded bundle in Debug';
+
+function patchAppDelegateContents(contents: string): string {
+ if (contents.includes(EMBEDDED_BUNDLE_MARKER)) {
+ return contents;
+ }
+
+ const debugMetroReturn =
+ /(#if DEBUG\r?\n\s*)return RCTBundleURLProvider\.sharedSettings\(\)\.jsBundleURL\(forBundleRoot: "([^"]+)"\)/;
+
+ if (!debugMetroReturn.test(contents)) {
+ return contents;
+ }
+
+ return contents.replace(
+ debugMetroReturn,
+ `$1${EMBEDDED_BUNDLE_MARKER}
+ if ProcessInfo.processInfo.arguments.contains("-BrownfieldPreferEmbeddedBundleInDebug"),
+ let embedded = Bundle.main.url(forResource: "main", withExtension: "jsbundle") {
+ return embedded
+ }
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "$2")`
+ );
+}
+
+describe('withDetoxEmbeddedBundleIosAppDelegate', () => {
+ it('injects embedded bundle fallback before Metro in Debug', () => {
+ const input = `class ReactNativeDelegate: ExpoReactNativeFactoryDelegate {
+ override func bundleURL() -> URL? {
+#if DEBUG
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")
+#else
+ return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
+#endif
+ }
+}`;
+
+ const output = patchAppDelegateContents(input);
+
+ expect(output).toContain(EMBEDDED_BUNDLE_MARKER);
+ expect(output).toContain('-BrownfieldPreferEmbeddedBundleInDebug');
+ expect(output).toContain(
+ 'return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: ".expo/.virtual-metro-entry")'
+ );
+ });
+
+ it('is idempotent', () => {
+ const once = patchAppDelegateContents(`#if DEBUG
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")`);
+ const twice = patchAppDelegateContents(once);
+ expect(twice).toBe(once);
+ });
+});
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/podfileHelpers.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/podfileHelpers.ts
index 0580ca6c..ce009fb0 100644
--- a/packages/react-native-brownfield/src/expo-config-plugin/ios/podfileHelpers.ts
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/podfileHelpers.ts
@@ -10,6 +10,10 @@ const BROWNFIELD_EXPO_GTE_55_SWIFT_DEFINES_MARKER_START =
'# >>> react-native-brownfield Expo SDK 55+ swift defines >>>';
const BROWNFIELD_EXPO_GTE_55_SWIFT_DEFINES_MARKER_END =
'# <<< react-native-brownfield Expo SDK 55+ swift defines <<<';
+const BROWNFIELD_XCODE_PACKAGING_WORKAROUNDS_MARKER_START =
+ '# >>> react-native-brownfield Xcode packaging workarounds >>>';
+const BROWNFIELD_XCODE_PACKAGING_WORKAROUNDS_MARKER_END =
+ '# <<< react-native-brownfield Xcode packaging workarounds <<<';
const BROWNFIELD_POST_INTEGRATE_REQUIRE = `require File.join(File.dirname(\`node --print "require.resolve('@callstack/react-native-brownfield/package.json')"\`), "scripts/react_native_brownfield_post_integrate")`;
const REACT_NATIVE_PODS_REQUIRE_REGEX =
/^require File\.join\(File\.dirname\(`node --print "require\.resolve\('react-native\/package\.json'\)"`\), "scripts\/react_native_pods"\)\s*$/m;
@@ -53,6 +57,31 @@ ${BROWNFIELD_POD_HOOK_MARKER_END}
return modifiedPodfile;
}
+function ensureXcodePackagingWorkaroundsInPostInstall(podfile: string): string {
+ if (podfile.includes(BROWNFIELD_XCODE_PACKAGING_WORKAROUNDS_MARKER_START)) {
+ return podfile;
+ }
+
+ const hook = `
+ ${BROWNFIELD_XCODE_PACKAGING_WORKAROUNDS_MARKER_START}
+ react_native_brownfield_patch_fmt_consteval(installer)
+ react_native_brownfield_skip_swift_module_interface_verification(installer)
+ ${BROWNFIELD_XCODE_PACKAGING_WORKAROUNDS_MARKER_END}
+`;
+
+ const postInstallMatch = podfile.match(
+ /(post_install\s+do\s+\|installer\|\s*\n)((?:(?!^\s*end\s*$)[\s\S])*)(^\s*end\s*$)/m
+ );
+
+ if (postInstallMatch) {
+ const [whole, start, content, end] = postInstallMatch;
+ const updated = `${start}${content.trimEnd()}\n${hook}\n${end}`;
+ return podfile.replace(whole, updated);
+ }
+
+ return `${podfile.trimEnd()}\n\npost_install do |installer|\n${hook}\nend\n`;
+}
+
function ensureExpoDefinesForSDK55AndAbove(podfile: string): string {
if (podfile.includes(BROWNFIELD_EXPO_GTE_55_SWIFT_DEFINES_MARKER_START)) {
return podfile;
@@ -95,56 +124,68 @@ function ensureExpoDefinesForSDK55AndAbove(podfile: string): string {
* @param expoMajor The major version of the Expo SDK
* @returns The modified Podfile content
*/
+export function applyBrownfieldPodfileHooks(
+ podfile: string,
+ expoMajor: number
+): string {
+ let modifiedPodfile = ensureBrownfieldPostIntegrateRequire(podfile);
+ modifiedPodfile =
+ ensureXcodePackagingWorkaroundsInPostInstall(modifiedPodfile);
+
+ if (expoMajor < 55) {
+ modifiedPodfile = ensureExpoPhaseOrderingHook(modifiedPodfile);
+ } else {
+ modifiedPodfile = ensureExpoDefinesForSDK55AndAbove(modifiedPodfile);
+ }
+
+ return modifiedPodfile;
+}
+
export function modifyPodfile(
podfile: string,
frameworkName: string,
expoMajor: number
): string {
- // check if the framework target is already included
+ let modifiedPodfile = podfile;
+
if (podfile.includes(`target '${frameworkName}'`)) {
Logger.logDebug(
- `Framework target "${frameworkName}" already in Podfile, skipping modification`
+ `Framework target "${frameworkName}" already in Podfile, syncing hooks`
+ );
+ } else {
+ Logger.logDebug(`Modifying Podfile for framework: ${frameworkName}`);
+
+ const frameworkTargetBlock = renderTemplate(
+ 'ios',
+ 'PodfileTargetBlock.rb',
+ {
+ '{{FRAMEWORK_NAME}}': frameworkName,
+ }
);
- return podfile;
- }
-
- Logger.logDebug(`Modifying Podfile for framework: ${frameworkName}`);
-
- // insert the framework target after the main target's "do"
- const frameworkTargetBlock = renderTemplate('ios', 'PodfileTargetBlock.rb', {
- '{{FRAMEWORK_NAME}}': frameworkName,
- });
-
- // find insertion point after the first target's content begins, before the end of the target block
- const mainTargetMatch = podfile.match(
- /(target\s+['"][^'"]+['"]\s+do\s*\n)([\s\S]*?)(^end\s*$)/m
- );
- if (!mainTargetMatch) {
- throw new SourceModificationError(
- 'Could not find main target in Podfile. Please manually add the framework target.'
+ const mainTargetMatch = podfile.match(
+ /(target\s+['"][^'"]+['"]\s+do\s*\n)([\s\S]*?)(^end\s*$)/m
);
- }
- const [, targetStart, targetContent] = mainTargetMatch;
- const insertIndex =
- podfile.indexOf(mainTargetMatch[0]) +
- targetStart.length +
- targetContent.length;
+ if (!mainTargetMatch) {
+ throw new SourceModificationError(
+ 'Could not find main target in Podfile. Please manually add the framework target.'
+ );
+ }
- let modifiedPodfile =
- podfile.slice(0, insertIndex) +
- frameworkTargetBlock +
- podfile.slice(insertIndex);
+ const [, targetStart, targetContent] = mainTargetMatch;
+ const insertIndex =
+ podfile.indexOf(mainTargetMatch[0]) +
+ targetStart.length +
+ targetContent.length;
- Logger.logDebug(`Added framework target "${frameworkName}" to Podfile`);
+ modifiedPodfile =
+ podfile.slice(0, insertIndex) +
+ frameworkTargetBlock +
+ podfile.slice(insertIndex);
- if (expoMajor < 55) {
- modifiedPodfile = ensureExpoPhaseOrderingHook(modifiedPodfile);
- } else {
- // Expo SDK >= 55
- modifiedPodfile = ensureExpoDefinesForSDK55AndAbove(modifiedPodfile);
+ Logger.logDebug(`Added framework target "${frameworkName}" to Podfile`);
}
- return modifiedPodfile;
+ return applyBrownfieldPodfileHooks(modifiedPodfile, expoMajor);
}
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/withBrownieIosAppDelegate.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/withBrownieIosAppDelegate.ts
new file mode 100644
index 00000000..dd26434d
--- /dev/null
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/withBrownieIosAppDelegate.ts
@@ -0,0 +1,50 @@
+import { withAppDelegate, type ConfigPlugin } from '@expo/config-plugins';
+
+const REGISTRATION_MARKER =
+ '// @callstack/react-native-brownfield: Brownie default store registration';
+
+/**
+ * Registers the default `BrownfieldStore` in AppDelegate before `startReactNative`,
+ * matching the bare RN brownfield pattern (see demo AppDelegate).
+ *
+ * Requires Brownie Swift codegen (`brownfield codegen`) so `BrownfieldStore` exists in the Brownie pod.
+ */
+export const withBrownieIosAppDelegate: ConfigPlugin = (config) => {
+ return withAppDelegate(config, (configWithMods) => {
+ const { modResults } = configWithMods;
+
+ if (modResults.language !== 'swift') {
+ return configWithMods;
+ }
+
+ let { contents } = modResults;
+
+ if (contents.includes(REGISTRATION_MARKER)) {
+ return configWithMods;
+ }
+
+ if (!contents.includes('import Brownie')) {
+ contents = `import Brownie\n${contents}`;
+ }
+
+ const needle = 'factory.startReactNative(';
+ if (!contents.includes(needle)) {
+ return configWithMods;
+ }
+
+ contents = contents.replace(
+ needle,
+ `${REGISTRATION_MARKER}
+ let brownfieldInitialState = BrownfieldStore(
+ counter: 0,
+ user: User(name: "Username")
+ )
+ BrownfieldStore.register(brownfieldInitialState)
+
+ factory.startReactNative(`
+ );
+
+ modResults.contents = contents;
+ return configWithMods;
+ });
+};
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxEmbeddedBundleIosAppDelegate.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxEmbeddedBundleIosAppDelegate.ts
new file mode 100644
index 00000000..5fcc1c00
--- /dev/null
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxEmbeddedBundleIosAppDelegate.ts
@@ -0,0 +1,44 @@
+import { withAppDelegate, type ConfigPlugin } from '@expo/config-plugins';
+
+const EMBEDDED_BUNDLE_MARKER =
+ '// @callstack/react-native-brownfield: Detox embedded bundle in Debug';
+
+/**
+ * Allows Detox / CI to load the embedded JS bundle in Debug when launch args include
+ * `-BrownfieldPreferEmbeddedBundleInDebug` (paired with FORCE_BUNDLING=1 at build time).
+ */
+export const withDetoxEmbeddedBundleIosAppDelegate: ConfigPlugin = (config) => {
+ return withAppDelegate(config, (configWithMods) => {
+ const { modResults } = configWithMods;
+
+ if (modResults.language !== 'swift') {
+ return configWithMods;
+ }
+
+ let { contents } = modResults;
+
+ if (contents.includes(EMBEDDED_BUNDLE_MARKER)) {
+ return configWithMods;
+ }
+
+ const debugMetroReturn =
+ /(#if DEBUG\r?\n\s*)return RCTBundleURLProvider\.sharedSettings\(\)\.jsBundleURL\(forBundleRoot: "([^"]+)"\)/;
+
+ if (!debugMetroReturn.test(contents)) {
+ return configWithMods;
+ }
+
+ contents = contents.replace(
+ debugMetroReturn,
+ `$1${EMBEDDED_BUNDLE_MARKER}
+ if ProcessInfo.processInfo.arguments.contains("-BrownfieldPreferEmbeddedBundleInDebug"),
+ let embedded = Bundle.main.url(forResource: "main", withExtension: "jsbundle") {
+ return embedded
+ }
+ return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "$2")`
+ );
+
+ modResults.contents = contents;
+ return configWithMods;
+ });
+};
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxIosXcodeEnvUpdates.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxIosXcodeEnvUpdates.ts
new file mode 100644
index 00000000..a9d0bd1b
--- /dev/null
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/withDetoxIosXcodeEnvUpdates.ts
@@ -0,0 +1,40 @@
+import fs from 'node:fs';
+import path from 'node:path';
+
+import { withDangerousMod, type ConfigPlugin } from '@expo/config-plugins';
+
+const XCODE_ENV_UPDATES_MARKER =
+ '# @callstack/react-native-brownfield: Detox / CI embedded bundle';
+
+const XCODE_ENV_UPDATES = `${XCODE_ENV_UPDATES_MARKER}
+# When FORCE_BUNDLING=1 (see apps/*/.detoxrc.cjs), embed JS for simulator E2E without Metro.
+if [[ -n "$FORCE_BUNDLING" ]]; then
+ unset SKIP_BUNDLING
+fi
+`;
+
+/**
+ * Expo Debug builds set SKIP_BUNDLING=1 on the app target; Detox passes FORCE_BUNDLING=1
+ * and relies on ios/.xcode.env.updates (sourced by the bundle script) to unset it.
+ */
+export const withDetoxIosXcodeEnvUpdates: ConfigPlugin = (config) => {
+ return withDangerousMod(config, [
+ 'ios',
+ async (configWithMods) => {
+ const filePath = path.join(
+ configWithMods.modRequest.platformProjectRoot,
+ '.xcode.env.updates'
+ );
+
+ if (
+ fs.existsSync(filePath) &&
+ fs.readFileSync(filePath, 'utf8').includes(XCODE_ENV_UPDATES_MARKER)
+ ) {
+ return configWithMods;
+ }
+
+ fs.writeFileSync(filePath, XCODE_ENV_UPDATES);
+ return configWithMods;
+ },
+ ]);
+};
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/ios/withFmtFix.ts b/packages/react-native-brownfield/src/expo-config-plugin/ios/withFmtFix.ts
index 99aaca4c..44f56230 100644
--- a/packages/react-native-brownfield/src/expo-config-plugin/ios/withFmtFix.ts
+++ b/packages/react-native-brownfield/src/expo-config-plugin/ios/withFmtFix.ts
@@ -18,7 +18,10 @@ const FMT_FIX_RUBY = `\
end`;
export function injectFmtFixIntoPodfile(podfile: string): string {
- if (podfile.includes(FMT_FIX_MARKER)) {
+ if (
+ podfile.includes(FMT_FIX_MARKER) ||
+ podfile.includes('react_native_brownfield_patch_fmt_consteval')
+ ) {
return podfile;
}
diff --git a/packages/react-native-brownfield/src/expo-config-plugin/withBrownfield.ts b/packages/react-native-brownfield/src/expo-config-plugin/withBrownfield.ts
index 9b9079be..fb2f15fd 100644
--- a/packages/react-native-brownfield/src/expo-config-plugin/withBrownfield.ts
+++ b/packages/react-native-brownfield/src/expo-config-plugin/withBrownfield.ts
@@ -7,6 +7,9 @@ import {
import type { ExpoConfig } from '@expo/config-types';
import { withBrownfieldIos } from './ios/withBrownfieldIos';
+import { withBrownieIosAppDelegate } from './ios/withBrownieIosAppDelegate';
+import { withDetoxEmbeddedBundleIosAppDelegate } from './ios/withDetoxEmbeddedBundleIosAppDelegate';
+import { withDetoxIosXcodeEnvUpdates } from './ios/withDetoxIosXcodeEnvUpdates';
import { withBrownfieldAndroid } from './android/withBrownfieldAndroid';
import type {
BrownfieldPluginConfig,
@@ -96,6 +99,9 @@ const withBrownfield: ConfigPlugin = (
if (resolvedConfig.ios) {
plugins.push([withBrownfieldIos, resolvedConfig]);
+ plugins.push(withBrownieIosAppDelegate);
+ plugins.push(withDetoxEmbeddedBundleIosAppDelegate);
+ plugins.push(withDetoxIosXcodeEnvUpdates);
}
if (resolvedConfig.android) {
diff --git a/yarn.lock b/yarn.lock
index 1524200e..31b57bdc 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1723,6 +1723,7 @@ __metadata:
"@testing-library/react-native": "npm:^13.3.3"
"@types/jest": "npm:^30.0.0"
"@types/react": "npm:~19.1.10"
+ detox: "npm:^20.27.0"
eslint: "npm:^9.25.0"
eslint-config-expo: "npm:~10.0.0"
expo: "npm:~54.0.34"
@@ -1767,6 +1768,7 @@ __metadata:
"@testing-library/react-native": "npm:^13.3.3"
"@types/jest": "npm:^30.0.0"
"@types/react": "npm:~19.2.10"
+ detox: "npm:^20.27.0"
eslint: "npm:^9.25.0"
eslint-config-expo: "npm:~55.0.0"
expo: "npm:~55.0.23"
@@ -1833,6 +1835,7 @@ __metadata:
"@types/jest": "npm:^30.0.0"
"@types/react": "npm:^19.2.0"
"@types/react-test-renderer": "npm:^19.1.0"
+ detox: "npm:^20.27.0"
eslint: "npm:^9.39.3"
jest: "npm:^29.7.0"
prettier: "npm:^3.8.1"
@@ -2284,6 +2287,13 @@ __metadata:
languageName: node
linkType: hard
+"@colors/colors@npm:1.6.0, @colors/colors@npm:^1.6.0":
+ version: 1.6.0
+ resolution: "@colors/colors@npm:1.6.0"
+ checksum: 10/66d00284a3a9a21e5e853b256942e17edbb295f4bd7b9aa7ef06bbb603568d5173eb41b0f64c1e51748bc29d382a23a67d99956e57e7431c64e47e74324182d9
+ languageName: node
+ linkType: hard
+
"@commitlint/cli@npm:^20.4.4":
version: 20.5.3
resolution: "@commitlint/cli@npm:20.5.3"
@@ -2498,6 +2508,17 @@ __metadata:
languageName: node
linkType: hard
+"@dabh/diagnostics@npm:^2.0.8":
+ version: 2.0.8
+ resolution: "@dabh/diagnostics@npm:2.0.8"
+ dependencies:
+ "@so-ric/colorspace": "npm:^1.1.6"
+ enabled: "npm:2.0.x"
+ kuler: "npm:^2.0.0"
+ checksum: 10/ac2267a4ee1874f608493f21d386ea29f0acac6716124e26e3e48e01ce5706b095585a14adce1bee14b6567d3b8fdd0c5a0bbb7ab0e15c9a743d55eb02f093ce
+ languageName: node
+ linkType: hard
+
"@egjs/hammerjs@npm:^2.0.17":
version: 2.0.17
resolution: "@egjs/hammerjs@npm:2.0.17"
@@ -3457,6 +3478,13 @@ __metadata:
languageName: node
linkType: hard
+"@flatten-js/interval-tree@npm:^1.1.2":
+ version: 1.1.4
+ resolution: "@flatten-js/interval-tree@npm:1.1.4"
+ checksum: 10/dd3d57f3e07594ef52f2af1647acab01bddce1beea7804f5b8f4f27f6b22356c920a803b4080f29732b67b27f2b18d87caf3b43f655ae3c9d65b7a6c19e11104
+ languageName: node
+ linkType: hard
+
"@glideapps/ts-necessities@npm:2.2.3":
version: 2.2.3
resolution: "@glideapps/ts-necessities@npm:2.2.3"
@@ -6409,6 +6437,16 @@ __metadata:
languageName: node
linkType: hard
+"@so-ric/colorspace@npm:^1.1.6":
+ version: 1.1.6
+ resolution: "@so-ric/colorspace@npm:1.1.6"
+ dependencies:
+ color: "npm:^5.0.2"
+ text-hex: "npm:1.0.x"
+ checksum: 10/fc3285e5cb9a458d255aa678d9453174ca40689a4c692f1617907996ab8eb78839542439604ced484c4f674a5297f7ba8b0e63fcfe901174f43c3d9c3c881b52
+ languageName: node
+ linkType: hard
+
"@standard-schema/spec@npm:^1.1.0":
version: 1.1.0
resolution: "@standard-schema/spec@npm:1.1.0"
@@ -6795,6 +6833,13 @@ __metadata:
languageName: node
linkType: hard
+"@types/triple-beam@npm:^1.3.2":
+ version: 1.3.5
+ resolution: "@types/triple-beam@npm:1.3.5"
+ checksum: 10/519b6a1b30d4571965c9706ad5400a200b94e4050feca3e7856e3ea7ac00ec9903e32e9a10e2762d0f7e472d5d03e5f4b29c16c0bd8c1f77c8876c683b2231f1
+ languageName: node
+ linkType: hard
+
"@types/unist@npm:*, @types/unist@npm:^3.0.0, @types/unist@npm:^3.0.3":
version: 3.0.3
resolution: "@types/unist@npm:3.0.3"
@@ -7281,6 +7326,33 @@ __metadata:
languageName: node
linkType: hard
+"@wix-pilot/core@npm:^3.4.2":
+ version: 3.4.2
+ resolution: "@wix-pilot/core@npm:3.4.2"
+ dependencies:
+ chalk: "npm:^4.1.0"
+ pngjs: "npm:^7.0.0"
+ winston: "npm:^3.17.0"
+ peerDependencies:
+ expect: "*"
+ peerDependenciesMeta:
+ expect:
+ optional: true
+ checksum: 10/cc3e2025eb9cf01248f35193159657f3b91d013441cf18f967ec11e9962556d325d99b8fd2d24108fd3c6ed837e430b2e348a2901a07ae57b80db1c7a05d7b95
+ languageName: node
+ linkType: hard
+
+"@wix-pilot/detox@npm:^1.0.13":
+ version: 1.0.13
+ resolution: "@wix-pilot/detox@npm:1.0.13"
+ peerDependencies:
+ "@wix-pilot/core": ^3.4.1
+ detox: ">=20.33.0"
+ expect: 29.x.x || 28.x.x || ^27.2.5
+ checksum: 10/5d9599e0236c55e308fe8f625790ecdfde20d8a84a92ccd252ea9d2972a818c2a2c368cb08d443d9d6b7dfd699f6a9549a165871bc548bb52afbb0538ed7ffc5
+ languageName: node
+ linkType: hard
+
"@xmldom/xmldom@npm:^0.8.8":
version: 0.8.13
resolution: "@xmldom/xmldom@npm:0.8.13"
@@ -7410,7 +7482,7 @@ __metadata:
languageName: node
linkType: hard
-"ajv@npm:^8.11.0":
+"ajv@npm:^8.11.0, ajv@npm:^8.6.3":
version: 8.20.0
resolution: "ajv@npm:8.20.0"
dependencies:
@@ -7789,6 +7861,13 @@ __metadata:
languageName: node
linkType: hard
+"async@npm:^3.2.3":
+ version: 3.2.6
+ resolution: "async@npm:3.2.6"
+ checksum: 10/cb6e0561a3c01c4b56a799cc8bab6ea5fef45f069ab32500b6e19508db270ef2dffa55e5aed5865c5526e9907b1f8be61b27530823b411ffafb5e1538c86c368
+ languageName: node
+ linkType: hard
+
"asynckit@npm:^0.4.0":
version: 0.4.0
resolution: "asynckit@npm:0.4.0"
@@ -8177,6 +8256,13 @@ __metadata:
languageName: node
linkType: hard
+"bluebird@npm:^3.5.4":
+ version: 3.7.2
+ resolution: "bluebird@npm:3.7.2"
+ checksum: 10/007c7bad22c5d799c8dd49c85b47d012a1fe3045be57447721e6afbd1d5be43237af1db62e26cb9b0d9ba812d2e4ca3bac82f6d7e016b6b88de06ee25ceb96e7
+ languageName: node
+ linkType: hard
+
"body-parser@npm:^1.20.3":
version: 1.20.5
resolution: "body-parser@npm:1.20.5"
@@ -8241,7 +8327,7 @@ __metadata:
languageName: node
linkType: hard
-"brace-expansion@npm:^2.0.2":
+"brace-expansion@npm:^2.0.1, brace-expansion@npm:^2.0.2":
version: 2.1.0
resolution: "brace-expansion@npm:2.1.0"
dependencies:
@@ -8292,6 +8378,13 @@ __metadata:
languageName: node
linkType: hard
+"browser-process-hrtime@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "browser-process-hrtime@npm:1.0.0"
+ checksum: 10/e30f868cdb770b1201afb714ad1575dd86366b6e861900884665fb627109b3cc757c40067d3bfee1ff2a29c835257ea30725a8018a9afd02ac1c24b408b1e45f
+ languageName: node
+ linkType: hard
+
"browserslist@npm:^4.24.0, browserslist@npm:^4.25.0, browserslist@npm:^4.28.1, browserslist@npm:^4.28.2":
version: 4.28.2
resolution: "browserslist@npm:4.28.2"
@@ -8343,6 +8436,87 @@ __metadata:
languageName: node
linkType: hard
+"bunyamin@npm:^1.5.2":
+ version: 1.6.3
+ resolution: "bunyamin@npm:1.6.3"
+ dependencies:
+ "@flatten-js/interval-tree": "npm:^1.1.2"
+ multi-sort-stream: "npm:^1.0.4"
+ stream-json: "npm:^1.7.5"
+ trace-event-lib: "npm:^1.3.1"
+ peerDependencies:
+ "@types/bunyan": ^1.8.8
+ bunyan: ^1.8.15 || ^2.0.0
+ peerDependenciesMeta:
+ "@types/bunyan":
+ optional: true
+ bunyan:
+ optional: true
+ checksum: 10/e3b4b9c75619002259192f344abf5cabefa593e8bdb40d2419f4d7af5a62b5dfd92e489849fa6f48901d9c6ca87572ca1d8141460a1b0daa17db93c26aa00ff9
+ languageName: node
+ linkType: hard
+
+"bunyan-debug-stream@npm:^3.1.0":
+ version: 3.1.1
+ resolution: "bunyan-debug-stream@npm:3.1.1"
+ dependencies:
+ chalk: "npm:^4.1.2"
+ peerDependencies:
+ bunyan: "*"
+ peerDependenciesMeta:
+ bunyan:
+ optional: true
+ checksum: 10/511791cff4e3b94866bdb29fb193ed94e3cde74b1b82dbb115ca288e73beca85fa024f2ddf21abd7bbf662abea6d3f322b2032c3858e3ab23b0fe73305837700
+ languageName: node
+ linkType: hard
+
+"bunyan@npm:^1.8.12":
+ version: 1.8.15
+ resolution: "bunyan@npm:1.8.15"
+ dependencies:
+ dtrace-provider: "npm:~0.8"
+ moment: "npm:^2.19.3"
+ mv: "npm:~2"
+ safe-json-stringify: "npm:~1"
+ dependenciesMeta:
+ dtrace-provider:
+ optional: true
+ moment:
+ optional: true
+ mv:
+ optional: true
+ safe-json-stringify:
+ optional: true
+ bin:
+ bunyan: bin/bunyan
+ checksum: 10/676f4beca08b8a53c99773664abea325c54bb51bf78f6290980f082ae08d9792e04c78e354e56d50fe683bdc0afd612dd42baf45b41d9f7ab15dc38baaa1567d
+ languageName: node
+ linkType: hard
+
+"bunyan@npm:^2.0.5":
+ version: 2.0.5
+ resolution: "bunyan@npm:2.0.5"
+ dependencies:
+ dtrace-provider: "npm:~0.8"
+ exeunt: "npm:1.1.0"
+ moment: "npm:^2.19.3"
+ mv: "npm:~2"
+ safe-json-stringify: "npm:~1"
+ dependenciesMeta:
+ dtrace-provider:
+ optional: true
+ moment:
+ optional: true
+ mv:
+ optional: true
+ safe-json-stringify:
+ optional: true
+ bin:
+ bunyan: bin/bunyan
+ checksum: 10/f6a8030dddf0c780b58eb0ab316054081714483ba9a56f7032c253009d589c7fa1f91d2dd26c5d740d6cc943cde7ac2803b805900375dd8442c1183d480dd51c
+ languageName: node
+ linkType: hard
+
"bytes@npm:3.1.2, bytes@npm:~3.1.2":
version: 3.1.2
resolution: "bytes@npm:3.1.2"
@@ -8350,6 +8524,13 @@ __metadata:
languageName: node
linkType: hard
+"caf@npm:^15.0.1":
+ version: 15.0.1
+ resolution: "caf@npm:15.0.1"
+ checksum: 10/7855c02460c405e6671f958deba5f4249821481ae5bb4c6330ff361b073f93046a066f9a59058bb99d4570bb7748621bad2299e11feae92f2d487ac62b93b5db
+ languageName: node
+ linkType: hard
+
"call-bind-apply-helpers@npm:^1.0.1, call-bind-apply-helpers@npm:^1.0.2":
version: 1.0.2
resolution: "call-bind-apply-helpers@npm:1.0.2"
@@ -8396,7 +8577,7 @@ __metadata:
languageName: node
linkType: hard
-"camelcase@npm:^6.2.0":
+"camelcase@npm:^6.0.0, camelcase@npm:^6.2.0":
version: 6.3.0
resolution: "camelcase@npm:6.3.0"
checksum: 10/8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d
@@ -8724,6 +8905,15 @@ __metadata:
languageName: node
linkType: hard
+"color-convert@npm:^3.1.3":
+ version: 3.1.3
+ resolution: "color-convert@npm:3.1.3"
+ dependencies:
+ color-name: "npm:^2.0.0"
+ checksum: 10/36b9b99c138f90eb11a28d1ad911054a9facd6cffde4f00dc49a34ebde7cae28454b2285ede64f273b6a8df9c3228b80e4352f4471978fa8b5005fe91341a67b
+ languageName: node
+ linkType: hard
+
"color-name@npm:1.1.3":
version: 1.1.3
resolution: "color-name@npm:1.1.3"
@@ -8738,6 +8928,13 @@ __metadata:
languageName: node
linkType: hard
+"color-name@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "color-name@npm:2.1.0"
+ checksum: 10/eb014f71d87408e318e95d3f554f188370d354ba8e0ffa4341d0fd19de391bfe2bc96e563d4f6614644d676bc24f475560dffee3fe310c2d6865d007410a9a2b
+ languageName: node
+ linkType: hard
+
"color-string@npm:^1.9.0":
version: 1.9.1
resolution: "color-string@npm:1.9.1"
@@ -8748,6 +8945,15 @@ __metadata:
languageName: node
linkType: hard
+"color-string@npm:^2.1.3":
+ version: 2.1.4
+ resolution: "color-string@npm:2.1.4"
+ dependencies:
+ color-name: "npm:^2.0.0"
+ checksum: 10/689a8688ac3cd55247792c83a9db9bfe675343c7412fedba1eb748ac6a8867dd2bb3d406e309ebfe90336809ee5067c7f2cccfbd10133c5cc9ef1dba5aad58f2
+ languageName: node
+ linkType: hard
+
"color@npm:^4.2.3":
version: 4.2.3
resolution: "color@npm:4.2.3"
@@ -8758,6 +8964,16 @@ __metadata:
languageName: node
linkType: hard
+"color@npm:^5.0.2":
+ version: 5.0.3
+ resolution: "color@npm:5.0.3"
+ dependencies:
+ color-convert: "npm:^3.1.3"
+ color-string: "npm:^2.1.3"
+ checksum: 10/88063ee058b995e5738092b5aa58888666275d1e967333f3814ff4fa334ce9a9e71de78a16fb1838f17c80793ea87f4878c20192037662809fe14eab2d474fd9
+ languageName: node
+ linkType: hard
+
"colorette@npm:^1.0.7":
version: 1.4.0
resolution: "colorette@npm:1.4.0"
@@ -8959,6 +9175,13 @@ __metadata:
languageName: node
linkType: hard
+"core-util-is@npm:~1.0.0":
+ version: 1.0.3
+ resolution: "core-util-is@npm:1.0.3"
+ checksum: 10/9de8597363a8e9b9952491ebe18167e3b36e7707569eed0ebf14f8bba773611376466ae34575bca8cfe3c767890c859c74056084738f09d4e4a6f902b2ad7d99
+ languageName: node
+ linkType: hard
+
"cosmiconfig-typescript-loader@npm:^6.1.0":
version: 6.3.0
resolution: "cosmiconfig-typescript-loader@npm:6.3.0"
@@ -9176,6 +9399,13 @@ __metadata:
languageName: node
linkType: hard
+"decamelize@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "decamelize@npm:4.0.0"
+ checksum: 10/b7d09b82652c39eead4d6678bb578e3bebd848add894b76d0f6b395bc45b2d692fb88d977e7cfb93c4ed6c119b05a1347cef261174916c2e75c0a8ca57da1809
+ languageName: node
+ linkType: hard
+
"decimal.js@npm:^10.4.2":
version: 10.6.0
resolution: "decimal.js@npm:10.6.0"
@@ -9341,6 +9571,58 @@ __metadata:
languageName: node
linkType: hard
+"detox@npm:^20.27.0":
+ version: 20.51.1
+ resolution: "detox@npm:20.51.1"
+ dependencies:
+ "@wix-pilot/core": "npm:^3.4.2"
+ "@wix-pilot/detox": "npm:^1.0.13"
+ ajv: "npm:^8.6.3"
+ bunyan: "npm:^1.8.12"
+ bunyan-debug-stream: "npm:^3.1.0"
+ caf: "npm:^15.0.1"
+ chalk: "npm:^4.0.0"
+ execa: "npm:^5.1.1"
+ find-up: "npm:^5.0.0"
+ fs-extra: "npm:^11.0.0"
+ funpermaproxy: "npm:^1.1.0"
+ glob: "npm:^8.0.3"
+ ini: "npm:^1.3.4"
+ jest-environment-emit: "npm:^1.2.0"
+ json-cycle: "npm:^1.3.0"
+ lodash: "npm:^4.17.11"
+ multi-sort-stream: "npm:^1.0.3"
+ multipipe: "npm:^4.0.0"
+ node-ipc: "npm:9.2.1"
+ promisify-child-process: "npm:^4.1.2"
+ proper-lockfile: "npm:^3.0.2"
+ resolve-from: "npm:^5.0.0"
+ sanitize-filename: "npm:^1.6.1"
+ semver: "npm:^7.0.0"
+ serialize-error: "npm:^8.0.1"
+ shell-quote: "npm:^1.7.2"
+ signal-exit: "npm:^3.0.3"
+ stream-json: "npm:^1.7.4"
+ strip-ansi: "npm:^6.0.1"
+ telnet-client: "npm:1.2.8"
+ tmp: "npm:^0.2.1"
+ trace-event-lib: "npm:^1.3.1"
+ which: "npm:^1.3.1"
+ ws: "npm:^7.0.0"
+ yargs: "npm:^17.0.0"
+ yargs-parser: "npm:^21.0.0"
+ yargs-unparser: "npm:^2.0.0"
+ peerDependencies:
+ jest: 30.x.x || 29.x.x || 28.x.x || ^27.2.5
+ peerDependenciesMeta:
+ jest:
+ optional: true
+ bin:
+ detox: local-cli/cli.js
+ checksum: 10/d6924ce496fbc7b429cacb255d1a9485a313fa01de05e0682d69135af7aef598fb9f902a765ec2834cce5d03a9b1974954f795248c0e682d7827bb181ec28ec5
+ languageName: node
+ linkType: hard
+
"devlop@npm:^1.0.0, devlop@npm:^1.1.0":
version: 1.1.0
resolution: "devlop@npm:1.1.0"
@@ -9437,6 +9719,16 @@ __metadata:
languageName: node
linkType: hard
+"dtrace-provider@npm:~0.8":
+ version: 0.8.8
+ resolution: "dtrace-provider@npm:0.8.8"
+ dependencies:
+ nan: "npm:^2.14.0"
+ node-gyp: "npm:latest"
+ checksum: 10/ab558f3bd04a91362a14ce4aeeaf4fac885d8762391612410c032bcf7bd0deed003c8faaf43f906c4ed87ff814893fb6dcc79e0c952d7967b325722b471b3775
+ languageName: node
+ linkType: hard
+
"dunder-proto@npm:^1.0.0, dunder-proto@npm:^1.0.1":
version: 1.0.1
resolution: "dunder-proto@npm:1.0.1"
@@ -9448,6 +9740,22 @@ __metadata:
languageName: node
linkType: hard
+"duplexer2@npm:^0.1.2":
+ version: 0.1.4
+ resolution: "duplexer2@npm:0.1.4"
+ dependencies:
+ readable-stream: "npm:^2.0.2"
+ checksum: 10/f60ff8b8955f992fd9524516e82faa5662d7aca5b99ee71c50bbbe1a3c970fafacb35d526d8b05cef8c08be56eed3663c096c50626c3c3651a52af36c408bf4d
+ languageName: node
+ linkType: hard
+
+"easy-stack@npm:^1.0.1":
+ version: 1.0.1
+ resolution: "easy-stack@npm:1.0.1"
+ checksum: 10/4b0d0f619db5a6c5a7aa4b8110b30f1adb956a42f3b77b5c2d6b5bbefe2f414643c2835624fd3eab9e6fe50cc76b1523dc8225c68db229af35200e644bcdd738
+ languageName: node
+ linkType: hard
+
"ee-first@npm:1.1.1":
version: 1.1.1
resolution: "ee-first@npm:1.1.1"
@@ -9483,6 +9791,13 @@ __metadata:
languageName: node
linkType: hard
+"enabled@npm:2.0.x":
+ version: 2.0.0
+ resolution: "enabled@npm:2.0.0"
+ checksum: 10/9d256d89f4e8a46ff988c6a79b22fa814b4ffd82826c4fdacd9b42e9b9465709d3b748866d0ab4d442dfc6002d81de7f7b384146ccd1681f6a7f868d2acca063
+ languageName: node
+ linkType: hard
+
"encodeurl@npm:~1.0.2":
version: 1.0.2
resolution: "encodeurl@npm:1.0.2"
@@ -10355,6 +10670,13 @@ __metadata:
languageName: node
linkType: hard
+"event-pubsub@npm:4.3.0":
+ version: 4.3.0
+ resolution: "event-pubsub@npm:4.3.0"
+ checksum: 10/8a1af789f85050c263eb102d5bd724065bbdc60e3be693fa90efe21d407c0eeb242a79139207a9488289f9f97458e369bfde3294328f21d49addb202439ced20
+ languageName: node
+ linkType: hard
+
"event-target-shim@npm:^5.0.0":
version: 5.0.1
resolution: "event-target-shim@npm:5.0.1"
@@ -10386,7 +10708,7 @@ __metadata:
languageName: node
linkType: hard
-"execa@npm:^5.0.0":
+"execa@npm:^5.0.0, execa@npm:^5.1.1":
version: 5.1.1
resolution: "execa@npm:5.1.1"
dependencies:
@@ -10403,6 +10725,13 @@ __metadata:
languageName: node
linkType: hard
+"exeunt@npm:1.1.0":
+ version: 1.1.0
+ resolution: "exeunt@npm:1.1.0"
+ checksum: 10/16c4c7e0ce6aa71df407322678b070e12bd14fb2fd736f355fbfa9017f72923194d7d5eb2022089dfab3a88247393c590bf30fc3b101b5b8219332316f37fa9c
+ languageName: node
+ linkType: hard
+
"exit@npm:^0.1.2":
version: 0.1.2
resolution: "exit@npm:0.1.2"
@@ -11433,6 +11762,13 @@ __metadata:
languageName: node
linkType: hard
+"fecha@npm:^4.2.0":
+ version: 4.2.3
+ resolution: "fecha@npm:4.2.3"
+ checksum: 10/534ce630c8f63c116292145607fc18c0f06bfa2fd74094357bf65daacc5d3f4f2b285bf8eb112c3bbf98c5caa6d386cced797f44b9b1b33da0c0a81020444826
+ languageName: node
+ linkType: hard
+
"fetch-nodeshim@npm:^0.4.10":
version: 0.4.10
resolution: "fetch-nodeshim@npm:0.4.10"
@@ -11528,6 +11864,15 @@ __metadata:
languageName: node
linkType: hard
+"flat@npm:^5.0.2":
+ version: 5.0.2
+ resolution: "flat@npm:5.0.2"
+ bin:
+ flat: cli.js
+ checksum: 10/72479e651c15eab53e25ce04c31bab18cfaac0556505cac19221dbbe85bbb9686bc76e4d397e89e5bf516ce667dcf818f8b07e585568edba55abc2bf1f698fb5
+ languageName: node
+ linkType: hard
+
"flatted@npm:^3.2.9":
version: 3.4.2
resolution: "flatted@npm:3.4.2"
@@ -11549,6 +11894,13 @@ __metadata:
languageName: node
linkType: hard
+"fn.name@npm:1.x.x":
+ version: 1.1.0
+ resolution: "fn.name@npm:1.1.0"
+ checksum: 10/000198af190ae02f0138ac5fa4310da733224c628e0230c81e3fff7c4e094af7e0e8bb9f4357cabd21db601759d89f3445da744afbae20623cfa41edf3888397
+ languageName: node
+ linkType: hard
+
"fontfaceobserver@npm:^2.1.0":
version: 2.3.0
resolution: "fontfaceobserver@npm:2.3.0"
@@ -11592,7 +11944,7 @@ __metadata:
languageName: node
linkType: hard
-"fs-extra@npm:^11.3.4":
+"fs-extra@npm:^11.0.0, fs-extra@npm:^11.3.4":
version: 11.3.5
resolution: "fs-extra@npm:11.3.5"
dependencies:
@@ -11635,6 +11987,13 @@ __metadata:
languageName: node
linkType: hard
+"fs.realpath@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "fs.realpath@npm:1.0.0"
+ checksum: 10/e703107c28e362d8d7b910bbcbfd371e640a3bb45ae157a362b5952c0030c0b6d4981140ec319b347bce7adc025dd7813da1ff908a945ac214d64f5402a51b96
+ languageName: node
+ linkType: hard
+
"fsevents@npm:^2.3.2, fsevents@npm:~2.3.2, fsevents@npm:~2.3.3":
version: 2.3.3
resolution: "fsevents@npm:2.3.3"
@@ -11682,6 +12041,13 @@ __metadata:
languageName: node
linkType: hard
+"funpermaproxy@npm:^1.1.0":
+ version: 1.1.0
+ resolution: "funpermaproxy@npm:1.1.0"
+ checksum: 10/b5bd84fb4a3069aee96d0ee6f4088d0b7f02e28d45be8b20624573bb33d6708b5dc1e0a6ea6a81823a2d7403e1a33d7e7b2d72f07889f69b4eb028c7a5a82f21
+ languageName: node
+ linkType: hard
+
"generator-function@npm:^2.0.0":
version: 2.0.1
resolution: "generator-function@npm:2.0.1"
@@ -11828,7 +12194,21 @@ __metadata:
languageName: node
linkType: hard
-"glob@npm:13.0.6":
+"glob@npm:7.2.3, glob@npm:^7.1.1, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:^7.1.7":
+ version: 7.2.3
+ resolution: "glob@npm:7.2.3"
+ dependencies:
+ fs.realpath: "npm:^1.0.0"
+ inflight: "npm:^1.0.4"
+ inherits: "npm:2"
+ minimatch: "npm:^3.1.1"
+ once: "npm:^1.3.0"
+ path-is-absolute: "npm:^1.0.0"
+ checksum: 10/59452a9202c81d4508a43b8af7082ca5c76452b9fcc4a9ab17655822e6ce9b21d4f8fbadabe4fe3faef448294cec249af305e2cd824b7e9aaf689240e5e96a7b
+ languageName: node
+ linkType: hard
+
+"glob@npm:^13.0.0, glob@npm:^13.0.6":
version: 13.0.6
resolution: "glob@npm:13.0.6"
dependencies:
@@ -11839,6 +12219,31 @@ __metadata:
languageName: node
linkType: hard
+"glob@npm:^6.0.1":
+ version: 6.0.4
+ resolution: "glob@npm:6.0.4"
+ dependencies:
+ inflight: "npm:^1.0.4"
+ inherits: "npm:2"
+ minimatch: "npm:2 || 3"
+ once: "npm:^1.3.0"
+ path-is-absolute: "npm:^1.0.0"
+ checksum: 10/b8fec415f772983ffbf7823c2c87aedd50aacf4f8db1868a11535db1023cf5180c9dd7487ce08f85bd64ed5cfd4268cea1a1c61c2772523d7d6194177d6d53a8
+ languageName: node
+ linkType: hard
+
+"glob@npm:^9.3.3":
+ version: 9.3.5
+ resolution: "glob@npm:9.3.5"
+ dependencies:
+ fs.realpath: "npm:^1.0.0"
+ minimatch: "npm:^8.0.2"
+ minipass: "npm:^4.2.4"
+ path-scurry: "npm:^1.6.1"
+ checksum: 10/e5fa8a58adf53525bca42d82a1fad9e6800032b7e4d372209b80cfdca524dd9a7dbe7d01a92d7ed20d89c572457f12c250092bc8817cb4f1c63efefdf9b658c0
+ languageName: node
+ linkType: hard
+
"global-directory@npm:^5.0.0":
version: 5.0.0
resolution: "global-directory@npm:5.0.0"
@@ -11914,7 +12319,7 @@ __metadata:
languageName: node
linkType: hard
-"graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.3, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
+"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.3, graceful-fs@npm:^4.1.5, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.11, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9":
version: 4.2.11
resolution: "graceful-fs@npm:4.2.11"
checksum: 10/bf152d0ed1dc159239db1ba1f74fdbc40cb02f626770dcd5815c427ce0688c2635a06ed69af364396da4636d0408fcf7d4afdf7881724c3307e46aff30ca49e2
@@ -12529,7 +12934,17 @@ __metadata:
languageName: node
linkType: hard
-"inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
+"inflight@npm:^1.0.4":
+ version: 1.0.6
+ resolution: "inflight@npm:1.0.6"
+ dependencies:
+ once: "npm:^1.3.0"
+ wrappy: "npm:1"
+ checksum: 10/d2ebd65441a38c8336c223d1b80b921b9fa737e37ea466fd7e253cb000c64ae1f17fa59e68130ef5bda92cfd8d36b83d37dab0eb0a4558bcfec8e8cdfd2dcb67
+ languageName: node
+ linkType: hard
+
+"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
version: 2.0.4
resolution: "inherits@npm:2.0.4"
checksum: 10/cd45e923bee15186c07fa4c89db0aace24824c482fb887b528304694b2aa6ff8a898da8657046a5dcf3e46cd6db6c61629551f9215f208d7c3f157cf9b290521
@@ -12543,7 +12958,7 @@ __metadata:
languageName: node
linkType: hard
-"ini@npm:~1.3.0":
+"ini@npm:^1.3.4, ini@npm:~1.3.0":
version: 1.3.8
resolution: "ini@npm:1.3.8"
checksum: 10/314ae176e8d4deb3def56106da8002b462221c174ddb7ce0c49ee72c8cd1f9044f7b10cc555a7d8850982c3b9ca96fc212122749f5234bc2b6fb05fb942ed566
@@ -12893,6 +13308,13 @@ __metadata:
languageName: node
linkType: hard
+"is-plain-obj@npm:^2.1.0":
+ version: 2.1.0
+ resolution: "is-plain-obj@npm:2.1.0"
+ checksum: 10/cec9100678b0a9fe0248a81743041ed990c2d4c99f893d935545cfbc42876cbe86d207f3b895700c690ad2fa520e568c44afc1605044b535a7820c1d40e38daa
+ languageName: node
+ linkType: hard
+
"is-plain-obj@npm:^4.0.0, is-plain-obj@npm:^4.1.0":
version: 4.1.0
resolution: "is-plain-obj@npm:4.1.0"
@@ -13076,6 +13498,13 @@ __metadata:
languageName: node
linkType: hard
+"isarray@npm:~1.0.0":
+ version: 1.0.0
+ resolution: "isarray@npm:1.0.0"
+ checksum: 10/f032df8e02dce8ec565cf2eb605ea939bdccea528dbcf565cdf92bfa2da9110461159d86a537388ef1acef8815a330642d7885b29010e8f7eac967c9993b65ab
+ languageName: node
+ linkType: hard
+
"isexe@npm:^2.0.0":
version: 2.0.0
resolution: "isexe@npm:2.0.0"
@@ -13318,6 +13747,39 @@ __metadata:
languageName: node
linkType: hard
+"jest-environment-emit@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "jest-environment-emit@npm:1.2.0"
+ dependencies:
+ bunyamin: "npm:^1.5.2"
+ bunyan: "npm:^2.0.5"
+ bunyan-debug-stream: "npm:^3.1.0"
+ funpermaproxy: "npm:^1.1.0"
+ lodash.merge: "npm:^4.6.2"
+ node-ipc: "npm:9.2.1"
+ strip-ansi: "npm:^6.0.0"
+ tslib: "npm:^2.5.3"
+ peerDependencies:
+ "@jest/environment": ">=27.2.5"
+ "@jest/types": ">=27.2.5"
+ jest: ">=27.2.5"
+ jest-environment-jsdom: ">=27.2.5"
+ jest-environment-node: ">=27.2.5"
+ peerDependenciesMeta:
+ "@jest/environment":
+ optional: true
+ "@jest/types":
+ optional: true
+ jest:
+ optional: true
+ jest-environment-jsdom:
+ optional: true
+ jest-environment-node:
+ optional: true
+ checksum: 10/30fe8dc39289be4bcc821610b16e681a562954dd6197b99cea8b338b1c9af3663f0345246960d1fea6d4385889466ca8122e3e468374ba162f85a13c08798764
+ languageName: node
+ linkType: hard
+
"jest-environment-jsdom@npm:^29.2.1":
version: 29.7.0
resolution: "jest-environment-jsdom@npm:29.7.0"
@@ -13829,6 +14291,22 @@ __metadata:
languageName: node
linkType: hard
+"js-message@npm:1.0.7":
+ version: 1.0.7
+ resolution: "js-message@npm:1.0.7"
+ checksum: 10/17a219374295fe57821a3864da6dc114d540d440bfe0dbad8843910b484996a31a5a86d948dcf3419db87251c9f15de1bcd8c757a7d1066c4d22e0a13af4234e
+ languageName: node
+ linkType: hard
+
+"js-queue@npm:2.0.2":
+ version: 2.0.2
+ resolution: "js-queue@npm:2.0.2"
+ dependencies:
+ easy-stack: "npm:^1.0.1"
+ checksum: 10/dbe3d343ad1357d07f6ec2a7ded0b194ddbe8289f2b899fe3339b48b9950da30ab20fe12e0ed02cee106516f7e73c42b14d7ec678ecdae5dd57bcbd3dbc93f66
+ languageName: node
+ linkType: hard
+
"js-tokens@npm:^10.0.0":
version: 10.0.0
resolution: "js-tokens@npm:10.0.0"
@@ -13928,6 +14406,13 @@ __metadata:
languageName: node
linkType: hard
+"json-cycle@npm:^1.3.0":
+ version: 1.5.0
+ resolution: "json-cycle@npm:1.5.0"
+ checksum: 10/4ce7594eb8f42e820c708ceaed12759168c4d29f91e0f8e213909331f7fd12b765a3b9c4a5e8f0e72bc25d5ed2a380211ff3ec95c3ba1cbb2cb5c68ea396ae9f
+ languageName: node
+ linkType: hard
+
"json-parse-even-better-errors@npm:^2.3.0":
version: 2.3.1
resolution: "json-parse-even-better-errors@npm:2.3.1"
@@ -14036,6 +14521,13 @@ __metadata:
languageName: node
linkType: hard
+"kuler@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "kuler@npm:2.0.0"
+ checksum: 10/9e10b5a1659f9ed8761d38df3c35effabffbd19fc6107324095238e4ef0ff044392cae9ac64a1c2dda26e532426485342226b93806bd97504b174b0dcf04ed81
+ languageName: node
+ linkType: hard
+
"lan-network@npm:^0.2.1":
version: 0.2.1
resolution: "lan-network@npm:0.2.1"
@@ -14376,7 +14868,7 @@ __metadata:
languageName: node
linkType: hard
-"lodash@npm:^4.17.19, lodash@npm:^4.17.21":
+"lodash@npm:^4.17.11, lodash@npm:^4.17.19, lodash@npm:^4.17.21":
version: 4.18.1
resolution: "lodash@npm:4.18.1"
checksum: 10/306fea53dfd39dad1f03d45ba654a2405aebd35797b673077f401edb7df2543623dc44b9effbb98f69b32152295fff725a4cec99c684098947430600c6af0c3f
@@ -14402,6 +14894,20 @@ __metadata:
languageName: node
linkType: hard
+"logform@npm:^2.7.0":
+ version: 2.7.0
+ resolution: "logform@npm:2.7.0"
+ dependencies:
+ "@colors/colors": "npm:1.6.0"
+ "@types/triple-beam": "npm:^1.3.2"
+ fecha: "npm:^4.2.0"
+ ms: "npm:^2.1.1"
+ safe-stable-stringify: "npm:^2.3.1"
+ triple-beam: "npm:^1.3.0"
+ checksum: 10/4b861bfd67efe599ab41113ae3ffe92b1873bf86793fb442f58971852430d8f416f9904da69e5043071fb3725690e2499a13acbfe92a57ba7d21690004f9edc0
+ languageName: node
+ linkType: hard
+
"logkitty@npm:^0.7.1":
version: 0.7.1
resolution: "logkitty@npm:0.7.1"
@@ -14433,7 +14939,7 @@ __metadata:
languageName: node
linkType: hard
-"lru-cache@npm:^10.0.1":
+"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0":
version: 10.4.3
resolution: "lru-cache@npm:10.4.3"
checksum: 10/e6e90267360476720fa8e83cc168aa2bf0311f3f2eea20a6ba78b90a885ae72071d9db132f40fda4129c803e7dcec3a6b6a6fbb44ca90b081630b810b5d6a41a
@@ -16046,6 +16552,15 @@ __metadata:
languageName: node
linkType: hard
+"minimatch@npm:2 || 3, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2, minimatch@npm:^3.1.5":
+ version: 3.1.5
+ resolution: "minimatch@npm:3.1.5"
+ dependencies:
+ brace-expansion: "npm:^1.1.7"
+ checksum: 10/b11a7ee5773cd34c1a0c8436cdbe910901018fb4b6cb47aa508a18d567f6efd2148507959e35fba798389b161b8604a2d704ccef751ea36bd4582f9852b7d63f
+ languageName: node
+ linkType: hard
+
"minimatch@npm:^10.0.1, minimatch@npm:^10.2.1, minimatch@npm:^10.2.2":
version: 10.2.5
resolution: "minimatch@npm:10.2.5"
@@ -16055,12 +16570,12 @@ __metadata:
languageName: node
linkType: hard
-"minimatch@npm:^3.0.4, minimatch@npm:^3.1.2, minimatch@npm:^3.1.5":
- version: 3.1.5
- resolution: "minimatch@npm:3.1.5"
+"minimatch@npm:^8.0.2":
+ version: 8.0.7
+ resolution: "minimatch@npm:8.0.7"
dependencies:
- brace-expansion: "npm:^1.1.7"
- checksum: 10/b11a7ee5773cd34c1a0c8436cdbe910901018fb4b6cb47aa508a18d567f6efd2148507959e35fba798389b161b8604a2d704ccef751ea36bd4582f9852b7d63f
+ brace-expansion: "npm:^2.0.1"
+ checksum: 10/dead7be9ad3eac2b0f9796373aa345a194aed608622880621ce53e100d75ace295ed68b9ae59c2a4de0854435b8dcd56fb7692812dda1c439463ba44dae5252c
languageName: node
linkType: hard
@@ -16080,7 +16595,14 @@ __metadata:
languageName: node
linkType: hard
-"minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3":
+"minipass@npm:^4.2.4":
+ version: 4.2.8
+ resolution: "minipass@npm:4.2.8"
+ checksum: 10/e148eb6dcb85c980234cad889139ef8ddf9d5bdac534f4f0268446c8792dd4c74f4502479be48de3c1cce2f6450f6da4d0d4a86405a8a12be04c1c36b339569a
+ languageName: node
+ linkType: hard
+
+"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.4, minipass@npm:^7.1.2, minipass@npm:^7.1.3":
version: 7.1.3
resolution: "minipass@npm:7.1.3"
checksum: 10/175e4d5e20980c3cd316ae82d2c031c42f6c746467d8b1905b51060a0ba4461441a0c25bb67c025fd9617f9a3873e152c7b543c6b5ac83a1846be8ade80dffd6
@@ -16105,6 +16627,24 @@ __metadata:
languageName: node
linkType: hard
+"mkdirp@npm:~0.5.1":
+ version: 0.5.6
+ resolution: "mkdirp@npm:0.5.6"
+ dependencies:
+ minimist: "npm:^1.2.6"
+ bin:
+ mkdirp: bin/cmd.js
+ checksum: 10/0c91b721bb12c3f9af4b77ebf73604baf350e64d80df91754dc509491ae93bf238581e59c7188360cec7cb62fc4100959245a42cfe01834efedc5e9d068376c2
+ languageName: node
+ linkType: hard
+
+"moment@npm:^2.19.3":
+ version: 2.30.1
+ resolution: "moment@npm:2.30.1"
+ checksum: 10/ae42d876d4ec831ef66110bdc302c0657c664991e45cf2afffc4b0f6cd6d251dde11375c982a5c0564ccc0fa593fc564576ddceb8c8845e87c15f58aa6baca69
+ languageName: node
+ linkType: hard
+
"mri@npm:^1.2.0":
version: 1.2.0
resolution: "mri@npm:1.2.0"
@@ -16126,6 +16666,23 @@ __metadata:
languageName: node
linkType: hard
+"multi-sort-stream@npm:^1.0.3, multi-sort-stream@npm:^1.0.4":
+ version: 1.0.4
+ resolution: "multi-sort-stream@npm:1.0.4"
+ checksum: 10/c8ca1d3837e54b2710994bdf1c07992e3a2deb5dc2e10910fca027f9552edcd5ecee54c360c7b452525cc943e32badf9e47965836a0fcfc5bc6369c42331d9a7
+ languageName: node
+ linkType: hard
+
+"multipipe@npm:^4.0.0":
+ version: 4.0.0
+ resolution: "multipipe@npm:4.0.0"
+ dependencies:
+ duplexer2: "npm:^0.1.2"
+ object-assign: "npm:^4.1.0"
+ checksum: 10/5a494ec2ce5bfdb389882ca595e3c4a33cae6c90dad879db2e3aa9a94484d8b164b0fb7b58ccf7593ae7e8c6213fd3f53a736b2c98e4f14c5ed1d38debc33f98
+ languageName: node
+ linkType: hard
+
"multitars@npm:^1.0.0":
version: 1.0.0
resolution: "multitars@npm:1.0.0"
@@ -16133,6 +16690,17 @@ __metadata:
languageName: node
linkType: hard
+"mv@npm:~2":
+ version: 2.1.1
+ resolution: "mv@npm:2.1.1"
+ dependencies:
+ mkdirp: "npm:~0.5.1"
+ ncp: "npm:~2.0.0"
+ rimraf: "npm:~2.4.0"
+ checksum: 10/59d4b5ebff6c265b452d6630ae8873d573c82e36fdc1ed9c34c7901a0bf2d3d357022f49db8e9bded127b743f709c7ef7befec249a2b3967578d649a8029aa06
+ languageName: node
+ linkType: hard
+
"mz@npm:^2.7.0":
version: 2.7.0
resolution: "mz@npm:2.7.0"
@@ -16144,6 +16712,15 @@ __metadata:
languageName: node
linkType: hard
+"nan@npm:^2.14.0":
+ version: 2.27.0
+ resolution: "nan@npm:2.27.0"
+ dependencies:
+ node-gyp: "npm:latest"
+ checksum: 10/bdce0630e417740501394c412bd9f0ed1c287825e3b8f9b7efb95cc3acd3ef69de60479b5f00a2d039b79321e5ce29b672b0b263cfe0e4d8f47c8f810a24a5ee
+ languageName: node
+ linkType: hard
+
"nano-spawn@npm:^0.2.0":
version: 0.2.1
resolution: "nano-spawn@npm:0.2.1"
@@ -16183,6 +16760,15 @@ __metadata:
languageName: node
linkType: hard
+"ncp@npm:~2.0.0":
+ version: 2.0.0
+ resolution: "ncp@npm:2.0.0"
+ bin:
+ ncp: ./bin/ncp
+ checksum: 10/b2a915b79eac43ababf256d0ba515b9dc5da2072b133946ccd168aab17e364bf0fcc7bcc68f2f3105aeeef389d56aeaedbb827122f7c4434104ae2aae1e002a6
+ languageName: node
+ linkType: hard
+
"negotiator@npm:0.6.3":
version: 0.6.3
resolution: "negotiator@npm:0.6.3"
@@ -16278,6 +16864,17 @@ __metadata:
languageName: node
linkType: hard
+"node-ipc@npm:9.2.1":
+ version: 9.2.1
+ resolution: "node-ipc@npm:9.2.1"
+ dependencies:
+ event-pubsub: "npm:4.3.0"
+ js-message: "npm:1.0.7"
+ js-queue: "npm:2.0.2"
+ checksum: 10/25309296bf5ecdaab491aca8fe5ff5bdf48a9f84a0cf827705919cb61c9b6f5259cc5ed6e3aedef45e68430213cacea54d7f5a28d715611b149d3d0ee721a1cc
+ languageName: node
+ linkType: hard
+
"node-releases@npm:^2.0.36":
version: 2.0.44
resolution: "node-releases@npm:2.0.44"
@@ -16513,7 +17110,7 @@ __metadata:
languageName: node
linkType: hard
-"once@npm:^1.3.1, once@npm:^1.4.0":
+"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
version: 1.4.0
resolution: "once@npm:1.4.0"
dependencies:
@@ -16522,6 +17119,15 @@ __metadata:
languageName: node
linkType: hard
+"one-time@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "one-time@npm:1.0.0"
+ dependencies:
+ fn.name: "npm:1.x.x"
+ checksum: 10/64d0160480eeae4e3b2a6fc0a02f452e05bb0cc8373a4ed56a4fc08c3939dcb91bc20075003ed499655bd16919feb63ca56f86eee7932c5251f7d629b55dfc90
+ languageName: node
+ linkType: hard
+
"onetime@npm:^2.0.0":
version: 2.0.1
resolution: "onetime@npm:2.0.1"
@@ -16870,6 +17476,13 @@ __metadata:
languageName: node
linkType: hard
+"path-is-absolute@npm:^1.0.0":
+ version: 1.0.1
+ resolution: "path-is-absolute@npm:1.0.1"
+ checksum: 10/060840f92cf8effa293bcc1bea81281bd7d363731d214cbe5c227df207c34cd727430f70c6037b5159c8a870b9157cba65e775446b0ab06fd5ecc7e54615a3b8
+ languageName: node
+ linkType: hard
+
"path-key@npm:^3.0.0, path-key@npm:^3.1.0":
version: 3.1.1
resolution: "path-key@npm:3.1.1"
@@ -16884,6 +17497,16 @@ __metadata:
languageName: node
linkType: hard
+"path-scurry@npm:^1.6.1":
+ version: 1.11.1
+ resolution: "path-scurry@npm:1.11.1"
+ dependencies:
+ lru-cache: "npm:^10.2.0"
+ minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0"
+ checksum: 10/5e8845c159261adda6f09814d7725683257fcc85a18f329880ab4d7cc1d12830967eae5d5894e453f341710d5484b8fdbbd4d75181b4d6e1eb2f4dc7aeadc434
+ languageName: node
+ linkType: hard
+
"path-scurry@npm:^2.0.2":
version: 2.0.2
resolution: "path-scurry@npm:2.0.2"
@@ -16993,6 +17616,13 @@ __metadata:
languageName: node
linkType: hard
+"pngjs@npm:^7.0.0":
+ version: 7.0.0
+ resolution: "pngjs@npm:7.0.0"
+ checksum: 10/e843ebbb0df092ee0f3a3e7dbd91ff87a239a4e4c4198fff202916bfb33b67622f4b83b3c29f3ccae94fcb97180c289df06068624554f61686fe6b9a4811f7db
+ languageName: node
+ linkType: hard
+
"possible-typed-array-names@npm:^1.0.0":
version: 1.1.0
resolution: "possible-typed-array-names@npm:1.1.0"
@@ -17123,6 +17753,13 @@ __metadata:
languageName: node
linkType: hard
+"process-nextick-args@npm:~2.0.0":
+ version: 2.0.1
+ resolution: "process-nextick-args@npm:2.0.1"
+ checksum: 10/1d38588e520dab7cea67cbbe2efdd86a10cc7a074c09657635e34f035277b59fbb57d09d8638346bf7090f8e8ebc070c96fa5fd183b777fff4f5edff5e9466cf
+ languageName: node
+ linkType: hard
+
"process@npm:^0.11.10":
version: 0.11.10
resolution: "process@npm:0.11.10"
@@ -17155,6 +17792,13 @@ __metadata:
languageName: node
linkType: hard
+"promisify-child-process@npm:^4.1.2":
+ version: 4.1.2
+ resolution: "promisify-child-process@npm:4.1.2"
+ checksum: 10/76662b53abeba8ba7eca38c9379037f29b2260076c0f443d0b15c8bbe7ad87bc7bb3eb052e2607be0610322234f03e02f28295709c88b7549a72e57c28ef7493
+ languageName: node
+ linkType: hard
+
"prompts@npm:^2.0.1, prompts@npm:^2.2.1, prompts@npm:^2.3.2, prompts@npm:^2.4.2":
version: 2.4.2
resolution: "prompts@npm:2.4.2"
@@ -17176,6 +17820,17 @@ __metadata:
languageName: node
linkType: hard
+"proper-lockfile@npm:^3.0.2":
+ version: 3.2.0
+ resolution: "proper-lockfile@npm:3.2.0"
+ dependencies:
+ graceful-fs: "npm:^4.1.11"
+ retry: "npm:^0.12.0"
+ signal-exit: "npm:^3.0.2"
+ checksum: 10/5025248895fbd69f115cdfe9a5cd63627357eefe67aa95d95175d87249dd5fe34a116bcc1d8b7cd126b24c8e4c875777f48ccdb5d2962079ee09a6e50f6ace72
+ languageName: node
+ linkType: hard
+
"property-information@npm:^7.0.0":
version: 7.1.0
resolution: "property-information@npm:7.1.0"
@@ -18089,7 +18744,22 @@ __metadata:
languageName: node
linkType: hard
-"readable-stream@npm:^3.4.0":
+"readable-stream@npm:^2.0.2":
+ version: 2.3.8
+ resolution: "readable-stream@npm:2.3.8"
+ dependencies:
+ core-util-is: "npm:~1.0.0"
+ inherits: "npm:~2.0.3"
+ isarray: "npm:~1.0.0"
+ process-nextick-args: "npm:~2.0.0"
+ safe-buffer: "npm:~5.1.1"
+ string_decoder: "npm:~1.1.1"
+ util-deprecate: "npm:~1.0.1"
+ checksum: 10/8500dd3a90e391d6c5d889256d50ec6026c059fadee98ae9aa9b86757d60ac46fff24fafb7a39fa41d54cb39d8be56cc77be202ebd4cd8ffcf4cb226cbaa40d4
+ languageName: node
+ linkType: hard
+
+"readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.2":
version: 3.6.2
resolution: "readable-stream@npm:3.6.2"
dependencies:
@@ -18593,6 +19263,13 @@ __metadata:
languageName: node
linkType: hard
+"retry@npm:^0.12.0":
+ version: 0.12.0
+ resolution: "retry@npm:0.12.0"
+ checksum: 10/1f914879f97e7ee931ad05fe3afa629bd55270fc6cf1c1e589b6a99fab96d15daad0fa1a52a00c729ec0078045fe3e399bd4fd0c93bcc906957bdc17f89cb8e6
+ languageName: node
+ linkType: hard
+
"reusify@npm:^1.0.4":
version: 1.1.0
resolution: "reusify@npm:1.1.0"
@@ -18600,6 +19277,17 @@ __metadata:
languageName: node
linkType: hard
+"rimraf@npm:~2.4.0":
+ version: 2.4.5
+ resolution: "rimraf@npm:2.4.5"
+ dependencies:
+ glob: "npm:^6.0.1"
+ bin:
+ rimraf: ./bin.js
+ checksum: 10/884c45de4195e4ce5ab6d8782d073302291a50004d1d79e628cf04b0a3594c882314b0639960333211cebe4ac888755c803cd09a5151d30e88a070af16b1573d
+ languageName: node
+ linkType: hard
+
"rolldown@npm:1.0.0":
version: 1.0.0
resolution: "rolldown@npm:1.0.0"
@@ -18699,6 +19387,20 @@ __metadata:
languageName: node
linkType: hard
+"safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1":
+ version: 5.1.2
+ resolution: "safe-buffer@npm:5.1.2"
+ checksum: 10/7eb5b48f2ed9a594a4795677d5a150faa7eb54483b2318b568dc0c4fc94092a6cce5be02c7288a0500a156282f5276d5688bce7259299568d1053b2150ef374a
+ languageName: node
+ linkType: hard
+
+"safe-json-stringify@npm:~1":
+ version: 1.2.0
+ resolution: "safe-json-stringify@npm:1.2.0"
+ checksum: 10/7121e746faf1ac73f586210b84b71f483b5bc89a3d6271f1628b89217221c8256566a91a3a26eb82def531184addf67dc6c236cb2f7e100bf843086c1b23c1b3
+ languageName: node
+ linkType: hard
+
"safe-push-apply@npm:^1.0.0":
version: 1.0.0
resolution: "safe-push-apply@npm:1.0.0"
@@ -18720,7 +19422,7 @@ __metadata:
languageName: node
linkType: hard
-"safe-stable-stringify@npm:^2.2.0":
+"safe-stable-stringify@npm:^2.2.0, safe-stable-stringify@npm:^2.3.1":
version: 2.5.0
resolution: "safe-stable-stringify@npm:2.5.0"
checksum: 10/2697fa186c17c38c3ca5309637b4ac6de2f1c3d282da27cd5e1e3c88eca0fb1f9aea568a6aabdf284111592c8782b94ee07176f17126031be72ab1313ed46c5c
@@ -18734,6 +19436,15 @@ __metadata:
languageName: node
linkType: hard
+"sanitize-filename@npm:^1.6.1":
+ version: 1.6.4
+ resolution: "sanitize-filename@npm:1.6.4"
+ dependencies:
+ truncate-utf8-bytes: "npm:^1.0.0"
+ checksum: 10/9fb32f8ae51b1931eb4f780ac140f3fa9ccbfd8c746231d426cd5f0bc95608557e6e2540186bab81a702b98cd301b622f4a80d3263d82680bebca90a38158b38
+ languageName: node
+ linkType: hard
+
"sax@npm:>=0.6.0":
version: 1.6.0
resolution: "sax@npm:1.6.0"
@@ -18800,6 +19511,15 @@ __metadata:
languageName: node
linkType: hard
+"semver@npm:^7.0.0":
+ version: 7.8.1
+ resolution: "semver@npm:7.8.1"
+ bin:
+ semver: bin/semver.js
+ checksum: 10/3244f6c4cb3f8126fea0426d353829ed4967e41e1f4696337c6fdcad87426466fe2badaf49d7dc85849acfc496ea0599432a4aecc33802d2d774e723acfa30e6
+ languageName: node
+ linkType: hard
+
"semver@npm:^7.1.3, semver@npm:^7.3.5, semver@npm:^7.5.2, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.7.1, semver@npm:^7.7.2, semver@npm:^7.7.3":
version: 7.8.0
resolution: "semver@npm:7.8.0"
@@ -18846,6 +19566,15 @@ __metadata:
languageName: node
linkType: hard
+"serialize-error@npm:^8.0.1":
+ version: 8.1.0
+ resolution: "serialize-error@npm:8.1.0"
+ dependencies:
+ type-fest: "npm:^0.20.2"
+ checksum: 10/2eef236d50edd2d7926e602c14fb500dc3a125ee52e9f08f67033181b8e0be5d1122498bdf7c23c80683cddcad083a27974e9e7111ce23165f4d3bcdd6d65102
+ languageName: node
+ linkType: hard
+
"serve-static@npm:^1.13.1, serve-static@npm:^1.16.2":
version: 1.16.3
resolution: "serve-static@npm:1.16.3"
@@ -18960,7 +19689,7 @@ __metadata:
languageName: node
linkType: hard
-"shell-quote@npm:^1.6.1, shell-quote@npm:^1.8.3":
+"shell-quote@npm:^1.6.1, shell-quote@npm:^1.7.2, shell-quote@npm:^1.8.3":
version: 1.8.3
resolution: "shell-quote@npm:1.8.3"
checksum: 10/5473e354637c2bd698911224129c9a8961697486cff1fb221f234d71c153fc377674029b0223d1d3c953a68d451d79366abfe53d1a0b46ee1f28eb9ade928f4c
@@ -19237,6 +19966,13 @@ __metadata:
languageName: node
linkType: hard
+"stack-trace@npm:0.0.x":
+ version: 0.0.10
+ resolution: "stack-trace@npm:0.0.10"
+ checksum: 10/7bd633f0e9ac46e81a0b0fe6538482c1d77031959cf94478228731709db4672fbbed59176f5b9a9fd89fec656b5dae03d084ef2d1b0c4c2f5683e05f2dbb1405
+ languageName: node
+ linkType: hard
+
"stack-utils@npm:^2.0.3, stack-utils@npm:^2.0.6":
version: 2.0.6
resolution: "stack-utils@npm:2.0.6"
@@ -19328,6 +20064,22 @@ __metadata:
languageName: node
linkType: hard
+"stream-chain@npm:^2.2.5":
+ version: 2.2.5
+ resolution: "stream-chain@npm:2.2.5"
+ checksum: 10/f9c65fe21251106083ca753d8b36f5a35dc426f5cb12851d9a872b6eb69e30ea2c94d87887bfda8c820503e842183812922532fb2adab18d5878d31a4516b956
+ languageName: node
+ linkType: hard
+
+"stream-json@npm:^1.7.4, stream-json@npm:^1.7.5":
+ version: 1.9.1
+ resolution: "stream-json@npm:1.9.1"
+ dependencies:
+ stream-chain: "npm:^2.2.5"
+ checksum: 10/8c97d3078127aaf70197b0e4b5ca668307f1768a4eb1ac4c2030056e1f862d7a11b83094b87d2b04c3c14f76a8a8657eb87b1760d57781c172e3a513c7e2b5fd
+ languageName: node
+ linkType: hard
+
"strict-uri-encode@npm:^2.0.0":
version: 2.0.0
resolution: "strict-uri-encode@npm:2.0.0"
@@ -19469,6 +20221,15 @@ __metadata:
languageName: node
linkType: hard
+"string_decoder@npm:~1.1.1":
+ version: 1.1.1
+ resolution: "string_decoder@npm:1.1.1"
+ dependencies:
+ safe-buffer: "npm:~5.1.0"
+ checksum: 10/7c41c17ed4dea105231f6df208002ebddd732e8e9e2d619d133cecd8e0087ddfd9587d2feb3c8caf3213cbd841ada6d057f5142cae68a4e62d3540778d9819b4
+ languageName: node
+ linkType: hard
+
"stringify-entities@npm:^4.0.0":
version: 4.0.4
resolution: "stringify-entities@npm:4.0.4"
@@ -19687,6 +20448,15 @@ __metadata:
languageName: node
linkType: hard
+"telnet-client@npm:1.2.8":
+ version: 1.2.8
+ resolution: "telnet-client@npm:1.2.8"
+ dependencies:
+ bluebird: "npm:^3.5.4"
+ checksum: 10/bd210a3f4d9d1640cca46a8c39574e3d5f951ed6cf5dff92e86003be99fdfd801ba46bcf953664de44afbabfd91b6918a0a26d938eccac3e3b4832fb6760a96f
+ languageName: node
+ linkType: hard
+
"term-size@npm:^2.1.0":
version: 2.2.1
resolution: "term-size@npm:2.2.1"
@@ -19729,6 +20499,13 @@ __metadata:
languageName: node
linkType: hard
+"text-hex@npm:1.0.x":
+ version: 1.0.0
+ resolution: "text-hex@npm:1.0.0"
+ checksum: 10/1138f68adc97bf4381a302a24e2352f04992b7b1316c5003767e9b0d3367ffd0dc73d65001ea02b07cd0ecc2a9d186de0cf02f3c2d880b8a522d4ccb9342244a
+ languageName: node
+ linkType: hard
+
"thenify-all@npm:^1.0.0":
version: 1.6.0
resolution: "thenify-all@npm:1.6.0"
@@ -19792,6 +20569,13 @@ __metadata:
languageName: node
linkType: hard
+"tmp@npm:^0.2.1":
+ version: 0.2.5
+ resolution: "tmp@npm:0.2.5"
+ checksum: 10/dd4b78b32385eab4899d3ae296007b34482b035b6d73e1201c4a9aede40860e90997a1452c65a2d21aee73d53e93cd167d741c3db4015d90e63b6d568a93d7ec
+ languageName: node
+ linkType: hard
+
"tmpl@npm:1.0.5":
version: 1.0.5
resolution: "tmpl@npm:1.0.5"
@@ -19866,6 +20650,15 @@ __metadata:
languageName: node
linkType: hard
+"trace-event-lib@npm:^1.3.1":
+ version: 1.4.1
+ resolution: "trace-event-lib@npm:1.4.1"
+ dependencies:
+ browser-process-hrtime: "npm:^1.0.0"
+ checksum: 10/84a6e368a8a182bd079ed537b7aae4f99a212893e57a3c476c417c824050fbcad8425900e23917004b40c1943617b970754a7b3a7bf65b1f90cfb031f18a9103
+ languageName: node
+ linkType: hard
+
"trim-lines@npm:^3.0.0":
version: 3.0.1
resolution: "trim-lines@npm:3.0.1"
@@ -19873,6 +20666,13 @@ __metadata:
languageName: node
linkType: hard
+"triple-beam@npm:^1.3.0":
+ version: 1.4.1
+ resolution: "triple-beam@npm:1.4.1"
+ checksum: 10/2e881a3e8e076b6f2b85b9ec9dd4a900d3f5016e6d21183ed98e78f9abcc0149e7d54d79a3f432b23afde46b0885bdcdcbff789f39bc75de796316961ec07f61
+ languageName: node
+ linkType: hard
+
"trough@npm:^2.0.0":
version: 2.2.0
resolution: "trough@npm:2.2.0"
@@ -19880,6 +20680,15 @@ __metadata:
languageName: node
linkType: hard
+"truncate-utf8-bytes@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "truncate-utf8-bytes@npm:1.0.2"
+ dependencies:
+ utf8-byte-length: "npm:^1.0.1"
+ checksum: 10/366e47a0e22cc271d37eb4e62820453fb877784b55b37218842758b7aa1d402eedd0f8833cfb5d6f7a6cae1535d84289bd5e32c4ee962d2a86962fb7038a6983
+ languageName: node
+ linkType: hard
+
"ts-api-utils@npm:^2.5.0":
version: 2.5.0
resolution: "ts-api-utils@npm:2.5.0"
@@ -19956,7 +20765,7 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.8.0":
+"tslib@npm:^2.0.0, tslib@npm:^2.1.0, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.5.3, tslib@npm:^2.8.0":
version: 2.8.1
resolution: "tslib@npm:2.8.1"
checksum: 10/3e2e043d5c2316461cb54e5c7fe02c30ef6dccb3384717ca22ae5c6b5bc95232a6241df19c622d9c73b809bea33b187f6dbc73030963e29950c2141bc32a79f7
@@ -20008,6 +20817,13 @@ __metadata:
languageName: node
linkType: hard
+"type-fest@npm:^0.20.2":
+ version: 0.20.2
+ resolution: "type-fest@npm:0.20.2"
+ checksum: 10/8907e16284b2d6cfa4f4817e93520121941baba36b39219ea36acfe64c86b9dbc10c9941af450bd60832c8f43464974d51c0957f9858bc66b952b66b6914cbb9
+ languageName: node
+ linkType: hard
+
"type-fest@npm:^0.21.3":
version: 0.21.3
resolution: "type-fest@npm:0.21.3"
@@ -20546,7 +21362,14 @@ __metadata:
languageName: node
linkType: hard
-"util-deprecate@npm:^1.0.1":
+"utf8-byte-length@npm:^1.0.1":
+ version: 1.0.5
+ resolution: "utf8-byte-length@npm:1.0.5"
+ checksum: 10/168edff8f7baca974b5bfb5256cebd57deaef8fbf2d0390301dd1009da52de64774d62f088254c94021e372147b6c938aa82f2318a3a19f9ebd21e48b7f40029
+ languageName: node
+ linkType: hard
+
+"util-deprecate@npm:^1.0.1, util-deprecate@npm:~1.0.1":
version: 1.0.2
resolution: "util-deprecate@npm:1.0.2"
checksum: 10/474acf1146cb2701fe3b074892217553dfcf9a031280919ba1b8d651a068c9b15d863b7303cb15bd00a862b498e6cf4ad7b4a08fb134edd5a6f7641681cb54a2
@@ -20966,6 +21789,17 @@ __metadata:
languageName: node
linkType: hard
+"which@npm:^1.3.1":
+ version: 1.3.1
+ resolution: "which@npm:1.3.1"
+ dependencies:
+ isexe: "npm:^2.0.0"
+ bin:
+ which: ./bin/which
+ checksum: 10/549dcf1752f3ee7fbb64f5af2eead4b9a2f482108b7de3e85c781d6c26d8cf6a52d37cfbe0642a155fa6470483fe892661a859c03157f24c669cf115f3bbab5e
+ languageName: node
+ linkType: hard
+
"which@npm:^2.0.1":
version: 2.0.2
resolution: "which@npm:2.0.2"
@@ -21000,6 +21834,36 @@ __metadata:
languageName: node
linkType: hard
+"winston-transport@npm:^4.9.0":
+ version: 4.9.0
+ resolution: "winston-transport@npm:4.9.0"
+ dependencies:
+ logform: "npm:^2.7.0"
+ readable-stream: "npm:^3.6.2"
+ triple-beam: "npm:^1.3.0"
+ checksum: 10/5946918720baadd7447823929e94cf0935f92c4cff6d9451c6fcb009bd9d20a3b3df9ad606109e79d1e9f4d2ff678477bf09f81cfefce2025baaf27a617129bb
+ languageName: node
+ linkType: hard
+
+"winston@npm:^3.17.0":
+ version: 3.19.0
+ resolution: "winston@npm:3.19.0"
+ dependencies:
+ "@colors/colors": "npm:^1.6.0"
+ "@dabh/diagnostics": "npm:^2.0.8"
+ async: "npm:^3.2.3"
+ is-stream: "npm:^2.0.0"
+ logform: "npm:^2.7.0"
+ one-time: "npm:^1.0.0"
+ readable-stream: "npm:^3.4.0"
+ safe-stable-stringify: "npm:^2.3.1"
+ stack-trace: "npm:0.0.x"
+ triple-beam: "npm:^1.3.0"
+ winston-transport: "npm:^4.9.0"
+ checksum: 10/8279e221d8017da601a725939d31d65de71504d8328051312a85b1b4d7ddc68634329f8d611fb1ff91cb797643409635f3e97ef5b4a650c587639e080af76b7b
+ languageName: node
+ linkType: hard
+
"wonka@npm:^6.3.2":
version: 6.3.6
resolution: "wonka@npm:6.3.6"
@@ -21087,7 +21951,7 @@ __metadata:
languageName: node
linkType: hard
-"ws@npm:^7, ws@npm:^7.5.10":
+"ws@npm:^7, ws@npm:^7.0.0, ws@npm:^7.5.10":
version: 7.5.10
resolution: "ws@npm:7.5.10"
peerDependencies:
@@ -21219,7 +22083,7 @@ __metadata:
languageName: node
linkType: hard
-"yargs-parser@npm:^21.1.1":
+"yargs-parser@npm:^21.0.0, yargs-parser@npm:^21.1.1":
version: 21.1.1
resolution: "yargs-parser@npm:21.1.1"
checksum: 10/9dc2c217ea3bf8d858041252d43e074f7166b53f3d010a8c711275e09cd3d62a002969a39858b92bbda2a6a63a585c7127014534a560b9c69ed2d923d113406e
@@ -21233,6 +22097,18 @@ __metadata:
languageName: node
linkType: hard
+"yargs-unparser@npm:^2.0.0":
+ version: 2.0.0
+ resolution: "yargs-unparser@npm:2.0.0"
+ dependencies:
+ camelcase: "npm:^6.0.0"
+ decamelize: "npm:^4.0.0"
+ flat: "npm:^5.0.2"
+ is-plain-obj: "npm:^2.1.0"
+ checksum: 10/68f9a542c6927c3768c2f16c28f71b19008710abd6b8f8efbac6dcce26bbb68ab6503bed1d5994bdbc2df9a5c87c161110c1dfe04c6a3fe5c6ad1b0e15d9a8a3
+ languageName: node
+ linkType: hard
+
"yargs@npm:^15.1.0":
version: 15.4.1
resolution: "yargs@npm:15.4.1"