diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e67229fa..7ace994c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,12 +3,47 @@ name: CI on: [pull_request] jobs: - test: + checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: .nvmrc + cache: 'npm' + + - run: npm ci + + # AirshipConfig.ts holds credentials and is gitignored, so the example + # cannot typecheck or bundle without one. + - name: Provide the example's Airship config + run: cp example/src/AirshipConfig.ts.example example/src/AirshipConfig.ts + + - run: npm run typecheck + - run: npm run lint + - run: npm test + + # The native jobs build Debug, which loads JS from Metro at runtime and + # never compiles it. Bundling is what fails on a missing import. + - name: Bundle the example + working-directory: example + run: | + npx react-native bundle \ + --platform android \ + --dev false \ + --entry-file index.js \ + --bundle-output "$RUNNER_TEMP/index.android.bundle" \ + --assets-dest "$RUNNER_TEMP/assets" + + native: runs-on: macos-26-xlarge steps: - uses: actions/checkout@v4 + - name: Set up JDK 17 - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: distribution: 'temurin' java-version: '17' @@ -16,8 +51,8 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '3.0.1' - + ruby-version: '3.3' + - name: Setup Node.js uses: actions/setup-node@v4 with: @@ -26,4 +61,4 @@ jobs: - run: npm ci - run: bash ./scripts/run_ci_tasks.sh -i - - run: bash ./scripts/run_ci_tasks.sh -a \ No newline at end of file + - run: bash ./scripts/run_ci_tasks.sh -a diff --git a/example/ios/Podfile b/example/ios/Podfile index 722a6923..0de3876d 100644 --- a/example/ios/Podfile +++ b/example/ios/Podfile @@ -37,6 +37,16 @@ target 'AirshipExample' do :mac_catalyst_enabled => false, # :ccache_enabled => true ) + + # RNCClipboard calls UTType APIs but its podspec declares only React-Core, + # so the framework carrying them is never linked and the pod fails to link. + installer.pods_project.targets.each do |target| + next unless target.name == 'RNCClipboard' + target.build_configurations.each do |config| + config.build_settings['OTHER_LDFLAGS'] = + "#{config.build_settings['OTHER_LDFLAGS'] || '$(inherited)'} -framework MobileCoreServices" + end + end end end diff --git a/example/package.json b/example/package.json index 4f909ff3..d37b1ae7 100644 --- a/example/package.json +++ b/example/package.json @@ -11,11 +11,16 @@ "build:ios": "react-native build-ios --mode Debug" }, "dependencies": { + "@react-native-clipboard/clipboard": "^1.16.3", "@react-native-vector-icons/material-icons": "^13.1.4", + "@react-navigation/native": "^7.5.0", + "@react-navigation/stack": "^7.12.0", "moment": "^2.30.1", "react": "19.2.3", "react-native": "0.87.1", - "react-native-safe-area-context": "^5.10.0" + "react-native-gesture-handler": "^3.3.0", + "react-native-safe-area-context": "^5.10.0", + "react-native-screens": "^4.28.0" }, "devDependencies": { "@babel/core": "^7.25.2", diff --git a/example/src/Styles.ts b/example/src/Styles.ts index a2f54e05..3e6887e2 100644 --- a/example/src/Styles.ts +++ b/example/src/Styles.ts @@ -98,6 +98,15 @@ export default StyleSheet.create({ padding: Spacing.xl, backgroundColor: Colors.background, }, + loadingIndicator: { + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, + alignItems: 'center', + justifyContent: 'center', + }, centered: { flex: 1, alignItems: 'center', diff --git a/example/src/navigation/AppNavigator.tsx b/example/src/navigation/AppNavigator.tsx index fbef69e0..3f5b3fa3 100644 --- a/example/src/navigation/AppNavigator.tsx +++ b/example/src/navigation/AppNavigator.tsx @@ -1,6 +1,5 @@ /* Copyright Airship and Contributors */ -import React from 'react'; import { Platform, UIManager } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createStackNavigator } from '@react-navigation/stack'; diff --git a/example/src/navigation/TabNavigator.tsx b/example/src/navigation/TabNavigator.tsx index bfb9b84f..a2e8cbff 100644 --- a/example/src/navigation/TabNavigator.tsx +++ b/example/src/navigation/TabNavigator.tsx @@ -103,7 +103,7 @@ const TabNavigator: React.FC = ({ case TabScreens.MESSAGE_CENTER: return ; case TabScreens.PREFERENCE_CENTER: - return ; + return ; case TabScreens.EMBEDDED_VIEWS: return ; case TabScreens.MESSAGE_DETAILS: diff --git a/example/src/screens/CustomEventsScreen.tsx b/example/src/screens/CustomEventsScreen.tsx index 54f02e9e..b46de98c 100644 --- a/example/src/screens/CustomEventsScreen.tsx +++ b/example/src/screens/CustomEventsScreen.tsx @@ -1,6 +1,6 @@ /* Copyright Airship and Contributors */ -import React, { useState } from 'react'; +import { useState } from 'react'; import { View, Text, @@ -32,13 +32,21 @@ export default function CustomEventsScreen(_props: CustomEventsScreenProps) { const updatePropertyKey = (text: string, index: number) => { const updatedProperties = [...eventProperties]; - updatedProperties[index].key = text; + const entry = updatedProperties[index]; + if (!entry) { + return; + } + entry.key = text; setEventProperties(updatedProperties); }; const updatePropertyValue = (text: string, index: number) => { const updatedProperties = [...eventProperties]; - updatedProperties[index].value = text; + const entry = updatedProperties[index]; + if (!entry) { + return; + } + entry.value = text; setEventProperties(updatedProperties); }; @@ -72,7 +80,7 @@ export default function CustomEventsScreen(_props: CustomEventsScreenProps) { await Airship.analytics.addCustomEvent({ eventName: eventName, eventValue: value, - properties: Object.keys(properties).length > 0 ? properties : undefined, + properties, }); Alert.alert('Success', 'Custom event sent successfully'); diff --git a/example/src/screens/Home Elements/ChannelCell.tsx b/example/src/screens/Home Elements/ChannelCell.tsx index 4a0bc605..32b839d5 100644 --- a/example/src/screens/Home Elements/ChannelCell.tsx +++ b/example/src/screens/Home Elements/ChannelCell.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { View, Text, TouchableHighlight } from 'react-native'; import Clipboard from '@react-native-clipboard/clipboard'; diff --git a/example/src/screens/Home Elements/NamedUserInputCell.tsx b/example/src/screens/Home Elements/NamedUserInputCell.tsx index 62dab05d..f4253a25 100644 --- a/example/src/screens/Home Elements/NamedUserInputCell.tsx +++ b/example/src/screens/Home Elements/NamedUserInputCell.tsx @@ -1,4 +1,3 @@ -import React from 'react'; import { View, TextInput } from 'react-native'; import styles from '../../Styles'; diff --git a/example/src/screens/HomeScreen.tsx b/example/src/screens/HomeScreen.tsx index 3fa743bc..dad130a6 100644 --- a/example/src/screens/HomeScreen.tsx +++ b/example/src/screens/HomeScreen.tsx @@ -1,6 +1,6 @@ /* Copyright Airship and Contributors */ -import React, { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { View, Text, @@ -15,6 +15,7 @@ import { } from 'react-native'; import styles from '../Styles'; import Airship, { + PromptPermissionFallback, EventType, AirshipEmbeddedView, SmsRegistrationOptions, @@ -54,7 +55,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) { const refreshNamedUser = useCallback(async () => { try { const fetchedNamedUser = await Airship.contact.getNamedUserId(); - setNamedUser(fetchedNamedUser); + setNamedUser(fetchedNamedUser ?? undefined); } catch { // Ignore errors fetching named user } @@ -143,7 +144,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) { try { if (enabled) { await Airship.push.enableUserNotifications({ - fallback: 'systemSettings', + fallback: PromptPermissionFallback.SystemSettings, }); } else { await Airship.push.setUserNotificationsEnabled(false); @@ -194,6 +195,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) { const activities = await Airship.iOS.liveActivityManager.listAll(); for (const element of activities) { await Airship.iOS.liveActivityManager.end({ + attributesType: 'ExampleWidgetsAttributes', activityId: element.id, dismissalPolicy: { type: 'immediate', @@ -222,6 +224,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) { const activities = await Airship.iOS.liveActivityManager.listAll(); for (const element of activities) { await Airship.iOS.liveActivityManager.update({ + attributesType: 'ExampleWidgetsAttributes', activityId: element.id, content: { state: { @@ -272,7 +275,7 @@ export default function HomeScreen({ navigation }: HomeScreenProps) { // Get named user const fetchedNamedUser = await Airship.contact.getNamedUserId(); - setNamedUser(fetchedNamedUser); + setNamedUser(fetchedNamedUser ?? undefined); } catch { // Expected error when Airship is not initialized } finally { diff --git a/example/src/screens/MessageCenterScreen.tsx b/example/src/screens/MessageCenterScreen.tsx index 39eaf612..4b15c7b2 100644 --- a/example/src/screens/MessageCenterScreen.tsx +++ b/example/src/screens/MessageCenterScreen.tsx @@ -1,6 +1,6 @@ /* Copyright Airship and Contributors */ -import React, { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback } from 'react'; import { Text, View, @@ -20,7 +20,7 @@ type MessageCenterScreenProps = { type MessageItem = { id: string; title: string; - sentDate: string; + sentDate: number; }; const Item = ({ diff --git a/example/src/screens/MessageDetailsScreen.tsx b/example/src/screens/MessageDetailsScreen.tsx index cf7b1bb0..750b430d 100644 --- a/example/src/screens/MessageDetailsScreen.tsx +++ b/example/src/screens/MessageDetailsScreen.tsx @@ -1,10 +1,11 @@ /* Copyright Airship and Contributors */ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { View, Text, ActivityIndicator, + Alert, Button, StyleSheet, } from 'react-native'; @@ -41,7 +42,7 @@ export default function MessageDetailsScreen({ const failedLoading = () => { setAnimating(false); - alert('Unable to load message. Please try again later'); + Alert.alert('Unable to load message. Please try again later'); navigation.goBack(); }; return ( @@ -92,7 +93,11 @@ const styles = StyleSheet.create({ position: 'relative', }, loadingContainer: { - ...StyleSheet.absoluteFillObject, + position: 'absolute', + top: 0, + left: 0, + right: 0, + bottom: 0, justifyContent: 'center', alignItems: 'center', backgroundColor: 'rgba(255, 255, 255, 0.7)', diff --git a/example/src/screens/MessageScreen.tsx b/example/src/screens/MessageScreen.tsx index a09739ee..0f81da8b 100644 --- a/example/src/screens/MessageScreen.tsx +++ b/example/src/screens/MessageScreen.tsx @@ -1,6 +1,6 @@ /* Copyright Airship and Contributors */ -import React, { useState, useEffect } from 'react'; +import { useState, useEffect } from 'react'; import { View, ActivityIndicator, Alert } from 'react-native'; import { MessageView } from '@ua/react-native-airship'; import type { StackNavigationProp } from '@react-navigation/stack'; diff --git a/package-lock.json b/package-lock.json index d7904c88..8108a928 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,11 +43,16 @@ "name": "@ua/react-native-airship-example", "version": "0.0.1", "dependencies": { + "@react-native-clipboard/clipboard": "^1.16.3", "@react-native-vector-icons/material-icons": "^13.1.4", + "@react-navigation/native": "^7.5.0", + "@react-navigation/stack": "^7.12.0", "moment": "^2.30.1", "react": "19.2.3", "react-native": "0.87.1", - "react-native-safe-area-context": "^5.10.0" + "react-native-gesture-handler": "^3.3.0", + "react-native-safe-area-context": "^5.10.0", + "react-native-screens": "^4.28.0" }, "devDependencies": { "@babel/core": "^7.25.2", @@ -3540,6 +3545,29 @@ "url": "https://opencollective.com/pkgr" } }, + "node_modules/@react-native-clipboard/clipboard": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@react-native-clipboard/clipboard/-/clipboard-1.16.3.tgz", + "integrity": "sha512-cMIcvoZKIrShzJHEaHbTAp458R9WOv0fB6UyC7Ek4Qk561Ow/DrzmmJmH/rAZg21Z6ixJ4YSdFDC14crqIBmCQ==", + "license": "MIT", + "workspaces": [ + "example" + ], + "peerDependencies": { + "react": ">= 16.9.0", + "react-native": ">= 0.61.5", + "react-native-macos": ">= 0.61.0", + "react-native-windows": ">= 0.61.0" + }, + "peerDependenciesMeta": { + "react-native-macos": { + "optional": true + }, + "react-native-windows": { + "optional": true + } + } + }, "node_modules/@react-native-community/cli": { "version": "20.1.0", "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-20.1.0.tgz", @@ -4239,6 +4267,98 @@ } } }, + "node_modules/@react-navigation/core": { + "version": "7.24.0", + "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-7.24.0.tgz", + "integrity": "sha512-PPMHGSgLB65eqWOBHeD/nGyzGJV3rcZ5sZbsCXlaC37HnLmwTEjB4CaOQn8CBVVv/Sc0Kl/W5dpPLls9Stk2WA==", + "license": "MIT", + "dependencies": { + "@react-navigation/routers": "^7.6.5", + "escape-string-regexp": "^4.0.0", + "fast-deep-equal": "^3.1.3", + "react-is": "^19.1.0", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "react": ">= 18.2.0" + } + }, + "node_modules/@react-navigation/core/node_modules/react-is": { + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.3.1.tgz", + "integrity": "sha512-RRieF6IyxQBkcK6pP8xOHprLTPW6QjRkbGdImtqNme+/hYVwCZkLQLdlZGOhUqXwkS9IEynaGvPJtv6XB/cz0Q==", + "license": "MIT" + }, + "node_modules/@react-navigation/elements": { + "version": "2.9.45", + "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-2.9.45.tgz", + "integrity": "sha512-r64qCgjA6asQo4Zlv2lAl68ARkfPbV+BNRm3n9JlMoFr4Ma2A+92Z+sWT1coJRoSXkAwVNb70+LjpM6fo6/D4A==", + "license": "MIT", + "dependencies": { + "color": "^4.2.3", + "use-latest-callback": "^0.2.4", + "use-sync-external-store": "^1.5.0" + }, + "peerDependencies": { + "@react-native-masked-view/masked-view": ">= 0.2.0", + "@react-navigation/native": "^7.5.1", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-safe-area-context": ">= 4.0.0" + }, + "peerDependenciesMeta": { + "@react-native-masked-view/masked-view": { + "optional": true + } + } + }, + "node_modules/@react-navigation/native": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.5.1.tgz", + "integrity": "sha512-p9xOvhG8q8rq0FPAoh0JC22ALbyRZt7U2uH8XrHRDjvqOEFrumME7szM6LaWW2WctolAVeZAfOTV+pUKULI/kQ==", + "license": "MIT", + "dependencies": { + "@react-navigation/core": "^7.24.0", + "escape-string-regexp": "^4.0.0", + "fast-deep-equal": "^3.1.3", + "nanoid": "^3.3.11", + "standard-navigation": "^0.0.8", + "use-latest-callback": "^0.2.4" + }, + "peerDependencies": { + "react": ">= 18.2.0", + "react-native": "*" + } + }, + "node_modules/@react-navigation/routers": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/@react-navigation/routers/-/routers-7.6.5.tgz", + "integrity": "sha512-hpvpVFt6wu3U014F/0Qy45VZCErlUvIV8kN1L6HovN5P9OpbXAzFTaRQmG7VW6czg2tSkUL5S3dZA0HIu5QirQ==", + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11" + } + }, + "node_modules/@react-navigation/stack": { + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-7.12.1.tgz", + "integrity": "sha512-4KEoho3yVy58B1Myj5ZNiSVmA8U8YfVbJrZT23uyA5pUy2dqPANH3REQ/zx/nMw4I62EVvqPHYLLbfGzI9/wTQ==", + "license": "MIT", + "dependencies": { + "@react-navigation/elements": "^2.9.45", + "color": "^4.2.3", + "use-latest-callback": "^0.2.4" + }, + "peerDependencies": { + "@react-navigation/native": "^7.5.1", + "react": ">= 18.2.0", + "react-native": "*", + "react-native-gesture-handler": ">= 2.0.0", + "react-native-safe-area-context": ">= 4.0.0", + "react-native-screens": ">= 4.0.0" + } + }, "node_modules/@shikijs/engine-oniguruma": { "version": "3.23.0", "resolved": "https://registry.npmjs.org/@shikijs/engine-oniguruma/-/engine-oniguruma-3.23.0.tgz", @@ -4477,12 +4597,20 @@ "version": "19.2.14", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.14.tgz", "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", - "devOptional": true, "license": "MIT", "dependencies": { "csstype": "^3.2.2" } }, + "node_modules/@types/react-test-renderer": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-19.3.0.tgz", + "integrity": "sha512-TX4p2D4Z2oigM3SXU7+QyLSUnSR0vR1S1Pfxm/qFL9nHQ3jclgi6ioGoWQmlIr1DeKRVmPJrmNlhgM0JlWlLUg==", + "license": "MIT", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -5912,6 +6040,19 @@ "dev": true, "license": "MIT" }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -5930,6 +6071,16 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "license": "MIT" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/colorette": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", @@ -6215,7 +6366,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "devOptional": true, "license": "MIT" }, "node_modules/dargs": { @@ -7423,7 +7573,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-diff": { @@ -11050,6 +11199,24 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "license": "MIT" }, + "node_modules/nanoid": { + "version": "3.3.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.20.tgz", + "integrity": "sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -11969,6 +12136,18 @@ } } }, + "node_modules/react-freeze": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/react-freeze/-/react-freeze-1.0.4.tgz", + "integrity": "sha512-r4F0Sec0BLxWicc7HEyo2x3/2icUTrRmDjaaRyzzn+7aDyFZliszMDOgLVwSnQnYENOlL1o569Ze2HZefk8clA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": ">=17.0.0" + } + }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -12285,6 +12464,20 @@ "node": ">= 10.0.0" } }, + "node_modules/react-native-gesture-handler": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-3.4.0.tgz", + "integrity": "sha512-jBg4ZWDvegeaZ4OHq9oxVOS/Qa6pV+LhtsUExothyhWxqzG0Lkg7kl2ztemPj/pnJxkq9j/+6wAw3jZGwdssww==", + "license": "MIT", + "dependencies": { + "@types/react-test-renderer": "^19.1.0", + "invariant": "^2.2.4" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native-monorepo-config": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/react-native-monorepo-config/-/react-native-monorepo-config-0.3.3.tgz", @@ -12319,6 +12512,20 @@ "react-native": "*" } }, + "node_modules/react-native-screens": { + "version": "4.30.0", + "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.30.0.tgz", + "integrity": "sha512-FrZG/Q5gqoDu0SgP4d2Ly0qdio5DR1KdGPEYImhkz7tmrhpML4C39m6RYLGd5TVLHZwcCh8NPvW9rylevjD0uQ==", + "license": "MIT", + "dependencies": { + "react-freeze": "^1.0.0", + "warn-once": "^0.1.0" + }, + "peerDependencies": { + "react": "*", + "react-native": "*" + } + }, "node_modules/react-native/node_modules/commander": { "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", @@ -13008,6 +13215,21 @@ "devOptional": true, "license": "ISC" }, + "node_modules/simple-swizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.4.tgz", + "integrity": "sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.4.tgz", + "integrity": "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==", + "license": "MIT" + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -13160,6 +13382,15 @@ "node": ">=8" } }, + "node_modules/standard-navigation": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/standard-navigation/-/standard-navigation-0.0.8.tgz", + "integrity": "sha512-TyVbo7INUDWtsUWDFn8RR7kwR87U0S4xHfLfbbnyeC581TmmyqQ+eM+nPw8rQTSD8QitRVcYfPaSHr/QJiUy1g==", + "license": "MIT", + "peerDependencies": { + "react": "*" + } + }, "node_modules/statuses": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", @@ -14096,6 +14327,24 @@ "punycode": "^2.1.0" } }, + "node_modules/use-latest-callback": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/use-latest-callback/-/use-latest-callback-0.2.6.tgz", + "integrity": "sha512-FvRG9i1HSo0wagmX63Vrm8SnlUU3LMM3WyZkQ76RnslpBrX694AdG4A0zQBx2B3ZifFA0yv/BaEHGBnEax5rZg==", + "license": "MIT", + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/use-sync-external-store": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.7.0.tgz", + "integrity": "sha512-6L+EeigHMQhdaIPNIFUKwfWJSwWFQ8gJbJ2DLOs5sDIegTwR9fRxvnM3uciHKjIZhFz+KAv2emhWMRvDmMcY8A==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -14153,6 +14402,12 @@ "makeerror": "1.0.12" } }, + "node_modules/warn-once": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/warn-once/-/warn-once-0.1.1.tgz", + "integrity": "sha512-VkQZJbO8zVImzYFteBXvBOZEl1qL175WH8VmZcxF2fZAoudNhNDvHi+doCaAEdU2l2vtcIwa2zn0QK5+I1HQ3Q==", + "license": "MIT" + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",