From ae7db6a3a66369b6175f039f1086d3ea68fe0efd Mon Sep 17 00:00:00 2001 From: Heimer Nguyen Date: Fri, 5 Sep 2025 22:30:03 +0700 Subject: [PATCH] chore: enhanced scan results and improved example app --- .gitignore | 18 +++-- .npmignore | 2 + CHANGELOG.md | 62 ++++------------ README.md | 74 ++++++++++++------- RNImageCodeScanner.podspec | 2 +- .../ImageCodeScannerModule.kt | 25 ++++++- example/App.tsx | 27 +++++-- example/package.json | 2 +- example/react-native.config.js | 21 ++++++ example/src/App.tsx | 21 +++++- example/tsconfig.json | 12 +-- ios/ImageCodeScanner.swift | 47 ++++++++++-- package.json | 19 ----- react-native.config.js | 13 ---- src/NativeImageCodeScanner.ts | 7 +- src/index.tsx | 5 +- tsconfig.json | 9 ++- yarn.lock | 66 ++++++++--------- 18 files changed, 255 insertions(+), 177 deletions(-) create mode 100644 example/react-native.config.js delete mode 100644 react-native.config.js diff --git a/.gitignore b/.gitignore index 9fbaafb..48dcc69 100644 --- a/.gitignore +++ b/.gitignore @@ -95,11 +95,19 @@ example/android/ example/dist/ example/build/ example/.bundle/ -example/.watchmanconfig -example/Gemfile -example/jest.config.js -example/metro.config.js -example/react-native.config.js + +example/.yarn/* +!example/.yarn/patches +!example/.yarn/plugins +!example/.yarn/releases +!example/.yarn/sdks +!example/.yarn/versions + +example/.yarn/cache +example/.yarn/unplugged +example/.yarn/build-state.yml +example/.yarn/install-state.gz +example/.pnp.* # Expo build artifacts example/.expo/ diff --git a/.npmignore b/.npmignore index 95cff85..6bbcba4 100644 --- a/.npmignore +++ b/.npmignore @@ -21,6 +21,8 @@ turbo.json # Build and development example/ modules/ +scripts/ +test-install/ android/build/ ios/build/ .turbo/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bde150..95b4918 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,62 +5,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [1.0.0] - 2025-08-28 +## [1.1.0] - 2025-09-05 ### Added -- Initial release of React Native Image Code Scanner -- Native implementation for iOS using Vision Framework -- Native implementation for Android using ML Kit -- Support for 13 barcode formats (QR Code, Code 128, Code 39, etc.) -- **Automatic image preprocessing** for optimal recognition: - - Contrast enhancement - - Grayscale conversion - - Multiple rotation attempts (0°, 90°, 180°, 270°) -- **Ultra-simple API** - just pass image path and formats, preprocessing is automatic by default -- Full support for React Native's New Architecture (Turbo Modules) -- TypeScript support with complete type definitions -- Comprehensive documentation and examples -- **Expo compatibility** with prebuild support -- **Expo example app** with modern UI and full feature demonstration -- Cross-platform example app (iOS, Android, Web) +- **Enhanced scan results** - Now returns both content and format information +- New `ScanResult` interface with `content` and `format` properties +- Format detection for all supported barcode types (QR_CODE, CODE_128, EAN_13, etc.) +- Updated example app to display both content and barcode format +- TypeScript support for the new result format ### Changed -- **Major Version Release**: Stable 1.0.0 release with production-ready features -- Enhanced CI pipeline and build reliability -- Improved cross-platform compatibility +- **Breaking Change**: `ImageCodeScanner.scan()` now returns `ScanResult[]` instead of `string[]` +- Updated API to provide more detailed scan results +- Enhanced example app UI to show barcode format alongside content +- Improved result display with format badges ### Fixed -- Resolved CI and Android build issues with Yarn lockfile and JVM compatibility -- Improved build pipeline stability -- Enhanced cross-platform build reliability -- CI pipeline improvements and stability enhancements -- Android build compatibility improvements -- Yarn lockfile consistency fixes +- Better type safety with comprehensive result interface +- Enhanced debugging capabilities with format information -### Features +[1.1.0]: https://github.com/nguyenthanhan/react-native-image-code-scanner/releases/tag/v1.1.0 -- Lightweight and performant native implementation -- **Automatic preprocessing** enabled by default for best results -- Smart retry logic with multiple image enhancement techniques -- No additional setup required for Android -- Minimal iOS setup with just pod install -- **Expo integration** with proper prebuild workflow -- **Modern example app** using Expo Image Picker and StatusBar -- **Simplified API** - just pass image path and formats -- **Performance metrics** and timing measurements - -### Example App Features - -- Modern Expo-based example application -- Barcode format selection UI with real-time toggles -- Automatic preprocessing info with optional disable switch -- Improved error handling and user feedback -- Comprehensive setup documentation -- Support for both Expo Go (UI testing) and prebuild (full functionality) -- Cross-platform compatibility (iOS, Android, Web) -- Performance timing and metrics display - -[1.0.0]: https://github.com/nguyenthanhan/react-native-image-code-scanner/releases/tag/v1.0.0 +_This changelog will be updated with each new release to document all changes, improvements, and new features._ diff --git a/README.md b/README.md index 7fab81f..785e6d7 100644 --- a/README.md +++ b/README.md @@ -60,8 +60,6 @@ A lightweight, high-performance React Native library for scanning QR codes and b | **0.79.x** | ✅ **1.0.x** | **New Architecture (default)** | **Latest - Full Support** | | 0.80.x+ | 🔜 1.0.x | New Architecture | Ready when released | -**Latest Version**: v1.0.0 - Major stable release with enhanced CI pipeline and build reliability improvements - ### Requirements - **React Native**: >=0.70.0 @@ -129,15 +127,19 @@ npx expo run:android ### Basic Usage ```typescript -import ImageCodeScanner from 'react-native-image-code-scanner'; +import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner'; // Scan QR code from image const scanQRCode = async (imagePath: string) => { try { - const results = await ImageCodeScanner.scan({ path: imagePath }); + const results: ScanResult[] = await ImageCodeScanner.scan({ + path: imagePath, + }); if (results.length > 0) { - console.log('QR Code found:', results[0]); + const firstResult = results[0]; + console.log('QR Code found:', firstResult.content); + console.log('Format:', firstResult.format); // "QR_CODE" } else { console.log('No QR code found in image'); } @@ -152,11 +154,12 @@ const scanQRCode = async (imagePath: string) => { ```typescript import ImageCodeScanner, { BarcodeFormat, + ScanResult, } from 'react-native-image-code-scanner'; const scanMultipleFormats = async (imagePath: string) => { try { - const results = await ImageCodeScanner.scan({ + const results: ScanResult[] = await ImageCodeScanner.scan({ path: imagePath, formats: [ BarcodeFormat.QR_CODE, @@ -166,7 +169,10 @@ const scanMultipleFormats = async (imagePath: string) => { // Automatic preprocessing is enabled by default for optimal recognition }); - console.log('Found barcodes:', results); + results.forEach((result, index) => { + console.log(`Barcode ${index + 1}:`, result.content); + console.log(`Format:`, result.format); + }); } catch (error) { console.error('Scan error:', error); } @@ -187,7 +193,7 @@ As soon as a barcode is detected with any technique, the result is returned imme ### With Image Picker ```typescript -import ImageCodeScanner from 'react-native-image-code-scanner'; +import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner'; import { launchImageLibrary } from 'react-native-image-picker'; const scanFromGallery = async () => { @@ -199,14 +205,17 @@ const scanFromGallery = async () => { if (result.assets && result.assets[0]) { const imagePath = result.assets[0].uri; - const scanResults = await ImageCodeScanner.scan({ + const scanResults: ScanResult[] = await ImageCodeScanner.scan({ path: imagePath, formats: [ImageCodeScanner.BarcodeFormat.QR_CODE], // Automatic preprocessing is enabled by default }); if (scanResults.length > 0) { - console.log('Barcode data:', scanResults); + scanResults.forEach((result) => { + console.log('Content:', result.content); + console.log('Format:', result.format); + }); } } }; @@ -215,7 +224,7 @@ const scanFromGallery = async () => { ### With Expo Image Picker ```typescript -import ImageCodeScanner from 'react-native-image-code-scanner'; +import ImageCodeScanner, { ScanResult } from 'react-native-image-code-scanner'; import * as ImagePicker from 'expo-image-picker'; const scanFromGallery = async () => { @@ -228,14 +237,17 @@ const scanFromGallery = async () => { if (!result.canceled && result.assets && result.assets[0]) { const imagePath = result.assets[0].uri; - const scanResults = await ImageCodeScanner.scan({ + const scanResults: ScanResult[] = await ImageCodeScanner.scan({ path: imagePath, formats: [ImageCodeScanner.BarcodeFormat.QR_CODE], // Automatic preprocessing is enabled by default }); if (scanResults.length > 0) { - console.log('Barcode data:', scanResults); + scanResults.forEach((result) => { + console.log('Content:', result.content); + console.log('Format:', result.format); + }); } } }; @@ -246,18 +258,23 @@ const scanFromGallery = async () => { ```typescript import ImageCodeScanner, { BarcodeFormat, + ScanResult, } from 'react-native-image-code-scanner'; // Scan with automatic preprocessing and multiple formats -const scanEverything = async (imagePath: string) => { +const scanEverything = async (imagePath: string): Promise => { try { - const results = await ImageCodeScanner.scan({ + const results: ScanResult[] = await ImageCodeScanner.scan({ path: imagePath, formats: Object.values(BarcodeFormat), // All supported formats // Automatic preprocessing is enabled by default }); - console.log(`Found ${results.length} barcodes:`, results); + console.log(`Found ${results.length} barcodes:`); + results.forEach((result, index) => { + console.log(`${index + 1}. ${result.format}: ${result.content}`); + }); + return results; } catch (error) { console.error('Scan failed:', error); @@ -289,7 +306,16 @@ interface ScanOptions { #### Returns -`Promise` - Array of decoded barcode values +`Promise` - Array of scan results with content and format information + +#### ScanResult + +```typescript +interface ScanResult { + content: string; // The decoded barcode content + format: string; // The detected barcode format (e.g., "QR_CODE", "EAN_13") +} +``` ### `ImageCodeScanner.BarcodeFormat` @@ -396,8 +422,8 @@ The example app demonstrates: **Platform Support:** -- 📱 **iOS**: Full camera and gallery access -- 🤖 **Android**: Full camera and gallery access +- 📱 **iOS**: Gallery access +- 🤖 **Android**: Gallery access ## 🤝 Contributing @@ -413,18 +439,10 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f ## 📄 License -MIT © [Heimer Nguyen](https://github.com/nguyenthanhan) +MIT ## 🆘 Support - 🐛 [Report Issues](https://github.com/nguyenthanhan/react-native-image-code-scanner/issues) - 💬 [Discussions](https://github.com/nguyenthanhan/react-native-image-code-scanner/discussions) - ⭐ Star us on [GitHub](https://github.com/nguyenthanhan/react-native-image-code-scanner) - -## 📝 Changelog - -See [CHANGELOG.md](CHANGELOG.md) for version history. - ---- - -Made with ❤️ by [Heimer Nguyen](https://github.com/nguyenthanhan) diff --git a/RNImageCodeScanner.podspec b/RNImageCodeScanner.podspec index e3eb119..5447aa0 100644 --- a/RNImageCodeScanner.podspec +++ b/RNImageCodeScanner.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.platforms = { :ios => "13.4" } s.source = { :git => "https://github.com/nguyenthanhan/react-native-image-code-scanner.git", :tag => "#{s.version}" } - s.source_files = "ios/**/*.{h,m,mm,swift}" + s.source_files = "ios/**/*.{h,m,mm,cpp,swift}" s.swift_version = "5.0" # Required frameworks for Vision and image processing diff --git a/android/src/main/java/com/imagecodescanner/ImageCodeScannerModule.kt b/android/src/main/java/com/imagecodescanner/ImageCodeScannerModule.kt index 21964eb..0eda901 100644 --- a/android/src/main/java/com/imagecodescanner/ImageCodeScannerModule.kt +++ b/android/src/main/java/com/imagecodescanner/ImageCodeScannerModule.kt @@ -225,9 +225,30 @@ class ImageCodeScannerModule(reactContext: ReactApplicationContext) : val codes = barcodes .mapNotNull { barcode -> val value = barcode.displayValue ?: barcode.rawValue - value + if (value != null && value.isNotEmpty()) { + val format = when (barcode.format) { + Barcode.FORMAT_QR_CODE -> "QR_CODE" + Barcode.FORMAT_CODE_128 -> "CODE_128" + Barcode.FORMAT_CODE_39 -> "CODE_39" + Barcode.FORMAT_CODE_93 -> "CODE_93" + Barcode.FORMAT_EAN_13 -> "EAN_13" + Barcode.FORMAT_EAN_8 -> "EAN_8" + Barcode.FORMAT_UPC_A -> "UPC_A" + Barcode.FORMAT_UPC_E -> "UPC_E" + Barcode.FORMAT_PDF417 -> "PDF_417" + Barcode.FORMAT_DATA_MATRIX -> "DATA_MATRIX" + Barcode.FORMAT_AZTEC -> "AZTEC" + Barcode.FORMAT_ITF -> "ITF" + Barcode.FORMAT_CODABAR -> "CODABAR" + else -> "UNKNOWN" + } + val resultMap = Arguments.createMap() + resultMap.putString("content", value) + resultMap.putString("format", format) + resultMap + } else null } - .filter { it.isNotEmpty() } + .filter { it != null } val arr = Arguments.fromList(codes) promise.resolve(arr) diff --git a/example/App.tsx b/example/App.tsx index 3331147..62af0ec 100644 --- a/example/App.tsx +++ b/example/App.tsx @@ -15,10 +15,11 @@ import { StatusBar } from 'expo-status-bar'; import * as ImagePicker from 'expo-image-picker'; import ImageCodeScanner, { BarcodeFormat, + type ScanResult, } from 'react-native-image-code-scanner'; -interface ScanResult { - data: string[]; +interface ScanResultWithTime { + data: ScanResult[]; time: number; } @@ -33,7 +34,7 @@ const BARCODE_FORMATS = [ export default function App() { const [selectedImage, setSelectedImage] = useState(null); - const [scanResult, setScanResult] = useState(null); + const [scanResult, setScanResult] = useState(null); const [isScanning, setIsScanning] = useState(false); const [selectedFormats, setSelectedFormats] = useState([ BarcodeFormat.QR_CODE, @@ -255,15 +256,18 @@ export default function App() { key={index} style={styles.resultItem} onPress={() => { - Alert.alert('Code Content', code); + Alert.alert('Code Content', code.content); }} > Code {index + 1} Tap to view + + {code.format} + - {code} + {code.content} ))} @@ -471,6 +475,19 @@ const styles = StyleSheet.create({ fontSize: 11, color: '#007AFF', }, + formatContainer: { + marginBottom: 8, + }, + formatText: { + fontSize: 12, + color: '#007AFF', + fontWeight: '600', + backgroundColor: '#E3F2FD', + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 6, + alignSelf: 'flex-start', + }, resultText: { fontSize: 15, color: '#333', diff --git a/example/package.json b/example/package.json index 75a6f23..cc0f7a1 100644 --- a/example/package.json +++ b/example/package.json @@ -13,7 +13,7 @@ "prebuild": "expo prebuild", "prebuild:clean": "expo prebuild --clean", "build:android": "expo prebuild --platform android && cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug", - "build:ios": "expo prebuild --platform ios && cd ios && pod install && xcodebuild -workspace ImageCodeScannerExample.xcworkspace -scheme ImageCodeScannerExample -configuration Debug -sdk iphonesimulator -derivedDataPath build" + "build:ios": "expo prebuild --clean --platform ios && cd ios && pod install --repo-update && xcodebuild -workspace ImageCodeScannerExample.xcworkspace -scheme ImageCodeScannerExample -configuration Debug -sdk iphonesimulator -derivedDataPath build" }, "dependencies": { "expo": "~52.0.0", diff --git a/example/react-native.config.js b/example/react-native.config.js new file mode 100644 index 0000000..59d9698 --- /dev/null +++ b/example/react-native.config.js @@ -0,0 +1,21 @@ +const path = require('path'); +const pkg = require('../package.json'); + +module.exports = { + project: { + ios: { + automaticPodsInstallation: true, + }, + }, + dependencies: { + [pkg.name]: { + root: path.join(__dirname, '..'), + platforms: { + // Codegen script incorrectly fails without this + // So we explicitly specify the platforms with empty object + ios: {}, + android: {}, + }, + }, + }, +}; diff --git a/example/src/App.tsx b/example/src/App.tsx index 374efaa..40f3839 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -14,12 +14,13 @@ import { } from 'react-native'; import ImageCodeScanner, { BarcodeFormat, + type ScanResult, } from 'react-native-image-code-scanner'; import * as ImagePicker from 'expo-image-picker'; import { StatusBar } from 'expo-status-bar'; -interface ScanResult { - data: string[]; +interface ScanResultWithTime { + data: ScanResult[]; time: number; preprocessingUsed?: string; } @@ -35,7 +36,7 @@ const BARCODE_FORMATS = [ export default function App() { const [selectedImage, setSelectedImage] = useState(null); - const [scanResult, setScanResult] = useState(null); + const [scanResult, setScanResult] = useState(null); const [isScanning, setIsScanning] = useState(false); const [selectedFormats, setSelectedFormats] = useState([ BarcodeFormat.QR_CODE, @@ -242,7 +243,8 @@ export default function App() { {scanResult.data.map((code, index) => ( Code {index + 1}: - {code} + {code.format} + {code.content} ))} @@ -373,6 +375,17 @@ const styles = StyleSheet.create({ color: '#333', fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace', }, + formatText: { + fontSize: 12, + color: '#007AFF', + fontWeight: '600', + backgroundColor: '#E3F2FD', + paddingHorizontal: 8, + paddingVertical: 4, + borderRadius: 6, + alignSelf: 'flex-start', + marginBottom: 4, + }, noResults: { fontSize: 16, color: '#999', diff --git a/example/tsconfig.json b/example/tsconfig.json index 2ba8c43..06aa2a6 100644 --- a/example/tsconfig.json +++ b/example/tsconfig.json @@ -12,13 +12,9 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react-jsx" + "jsx": "react-jsx", + "baseUrl": "." }, - "include": [ - "**/*.ts", - "**/*.tsx" - ], - "exclude": [ - "node_modules" - ] + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] } diff --git a/ios/ImageCodeScanner.swift b/ios/ImageCodeScanner.swift index ed59b51..c4a6b32 100644 --- a/ios/ImageCodeScanner.swift +++ b/ios/ImageCodeScanner.swift @@ -246,18 +246,53 @@ class ImageCodeScanner: NSObject, RCTBridgeModule { return } - // Extract barcode payload strings - let barcodeStrings = results.compactMap { observation in - observation.payloadStringValue + // Extract barcode payload strings with format information + let barcodeResults = results.compactMap { observation -> [String: Any]? in + guard let payload = observation.payloadStringValue else { return nil } + + let format: String + switch observation.symbology { + case .qr: + format = "QR_CODE" + case .code128: + format = "CODE_128" + case .code39: + format = "CODE_39" + case .code93: + format = "CODE_93" + case .ean13: + format = "EAN_13" + case .ean8: + format = "EAN_8" + case .upce: + format = "UPC_E" + case .pdf417: + format = "PDF_417" + case .dataMatrix: + format = "DATA_MATRIX" + case .aztec: + format = "AZTEC" + case .itf14: + format = "ITF" + case .codabar: + format = "CODABAR" + default: + format = "UNKNOWN" + } + + return [ + "content": payload, + "format": format + ] } - if barcodeStrings.isEmpty { + if barcodeResults.isEmpty { print("ImageCodeScanner iOS - \(description): No barcodes found") // Try next image tryScanning(images: images, index: index + 1) } else { - print("ImageCodeScanner iOS - Success with \(description)! Found \(barcodeStrings.count) codes") - safeResolve(barcodeStrings) + print("ImageCodeScanner iOS - Success with \(description)! Found \(barcodeResults.count) codes") + safeResolve(barcodeResults) } } } diff --git a/package.json b/package.json index 1f69bbb..1bb2a2a 100644 --- a/package.json +++ b/package.json @@ -12,26 +12,7 @@ }, "./package.json": "./package.json" }, - "files": [ - "src", - "lib", - "android", - "ios", - "*.podspec", - "react-native.config.js", - "!ios/build", - "!android/build", - "!android/gradle", - "!android/gradlew", - "!android/gradlew.bat", - "!android/local.properties", - "!**/__tests__", - "!**/__fixtures__", - "!**/__mocks__", - "!**/.*" - ], "scripts": { - "example": "yarn workspace react-native-image-code-scanner-example", "test": "jest", "test:coverage": "jest --coverage", "typecheck": "tsc --noEmit", diff --git a/react-native.config.js b/react-native.config.js deleted file mode 100644 index 0c76877..0000000 --- a/react-native.config.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = { - dependency: { - platforms: { - ios: { - podspecPath: './RNImageCodeScanner.podspec', - }, - android: { - sourceDir: './android', - manifestPath: './android/src/main/AndroidManifest.xml', - }, - }, - }, -}; diff --git a/src/NativeImageCodeScanner.ts b/src/NativeImageCodeScanner.ts index 00ffab6..c52a292 100644 --- a/src/NativeImageCodeScanner.ts +++ b/src/NativeImageCodeScanner.ts @@ -1,6 +1,11 @@ import type { TurboModule } from 'react-native'; import { TurboModuleRegistry } from 'react-native'; +export interface ScanResult { + content: string; + format: string; +} + export interface Spec extends TurboModule { scanFromPath( path: string, @@ -10,7 +15,7 @@ export interface Spec extends TurboModule { convertToGrayscale: boolean; tryRotations: boolean; } - ): Promise; + ): Promise; } export default TurboModuleRegistry.getEnforcing('ImageCodeScanner'); diff --git a/src/index.tsx b/src/index.tsx index 9a0a897..413bc25 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import ImageCodeScanner from './NativeImageCodeScanner'; +import ImageCodeScanner, { type ScanResult } from './NativeImageCodeScanner'; // Common formats supported by both iOS Vision and Android ML Kit export enum BarcodeFormat { @@ -23,7 +23,7 @@ export interface ScanOptions { } const ImageCodeScannerModule = { - scan: (options: ScanOptions): Promise => { + scan: (options: ScanOptions): Promise => { const { path, formats = [BarcodeFormat.QR_CODE] } = options; if (!path) { return Promise.reject(new Error('Image path is required')); @@ -50,4 +50,5 @@ const ImageCodeScannerModule = { BarcodeFormat, }; +export { type ScanResult } from './NativeImageCodeScanner'; export default ImageCodeScannerModule; diff --git a/tsconfig.json b/tsconfig.json index 174adfd..a6532c0 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -25,5 +25,12 @@ "strict": true, "target": "ESNext", "verbatimModuleSyntax": true - } + }, + "exclude": [ + "example/**/*", + "node_modules", + "lib", + "**/*.test.*", + "**/*.spec.*" + ] } diff --git a/yarn.lock b/yarn.lock index d0bb3c3..9ca3425 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2209,13 +2209,13 @@ __metadata: languageName: node linkType: hard -"@expo/json-file@npm:^10.0.3": - version: 10.0.3 - resolution: "@expo/json-file@npm:10.0.3" +"@expo/json-file@npm:^10.0.6": + version: 10.0.6 + resolution: "@expo/json-file@npm:10.0.6" dependencies: "@babel/code-frame": ~7.10.4 json5: ^2.2.3 - checksum: ccae65a818aa0f9b66365e1973269e4b9dbe00e6f152e413c8bd788f4437d8b17b74a04e1cbdaa60b73e8f7c5fc61b78a64184837a58047c2791913ec9a3ae47 + checksum: 9fb9a2ddcb41384fd805bfdb823c592d9932bc5c8b93bd3ffa0831566892a1c3c480e26b6b114c6f96a971988895bf7b5bbcc6539c40668bdbe93fb84eb01124 languageName: node linkType: hard @@ -2267,26 +2267,26 @@ __metadata: linkType: hard "@expo/osascript@npm:^2.1.6": - version: 2.3.3 - resolution: "@expo/osascript@npm:2.3.3" + version: 2.3.6 + resolution: "@expo/osascript@npm:2.3.6" dependencies: "@expo/spawn-async": ^1.7.2 exec-async: ^2.2.0 - checksum: e6080611317aa09eb78219454b5bf087525af705686c317d5c7fd073fbbbba54fe910e8b527da5eaef3e3f486d68576ca49224bd4b55419b378933e2be41b2a7 + checksum: ad187d5a669fb3ff183359370cf341fc60f41be4a5b95e79bbd90f618890a9bc1ae62ac0462d49786c916fd1429692013dd8bb3cb7b15f28d60922e1c669cd1d languageName: node linkType: hard "@expo/package-manager@npm:^1.7.2": - version: 1.9.3 - resolution: "@expo/package-manager@npm:1.9.3" + version: 1.9.6 + resolution: "@expo/package-manager@npm:1.9.6" dependencies: - "@expo/json-file": ^10.0.3 + "@expo/json-file": ^10.0.6 "@expo/spawn-async": ^1.7.2 chalk: ^4.0.0 npm-package-arg: ^11.0.0 ora: ^3.4.0 resolve-workspace-root: ^2.0.0 - checksum: 53555f20eed81f038448f8a366ccf396fb15cf3cf7f60b925b32036a4898e77e2862961f2b9055265b9cfed4a83c1f0c08bff8b9c481bd15782c9c9bc25eb51f + checksum: 36ef232b943aa56acadaf6947073cffa1c534abc113abfd3b8613cae6e990541eaf44c56ecae11cb1d79957b626ab8e78a0f025a48f7a489727e32385a4b6bd7 languageName: node linkType: hard @@ -4908,16 +4908,16 @@ __metadata: linkType: hard "browserslist@npm:^4.20.4, browserslist@npm:^4.24.0, browserslist@npm:^4.25.3": - version: 4.25.3 - resolution: "browserslist@npm:4.25.3" + version: 4.25.4 + resolution: "browserslist@npm:4.25.4" dependencies: - caniuse-lite: ^1.0.30001735 - electron-to-chromium: ^1.5.204 + caniuse-lite: ^1.0.30001737 + electron-to-chromium: ^1.5.211 node-releases: ^2.0.19 update-browserslist-db: ^1.1.3 bin: browserslist: cli.js - checksum: 05444b3493724084aa1a8ed23175bc6bbcccc369d687dfd7542dc5c3ff773f65724606afeed33fa267afe6def43c9e8c1d3bbe30c8723def0b81b0a4d3956fc0 + checksum: 936db8d7801576a93bc47f0ecd5a2d8424417bd62e0c94dbd7e6aa02493108e4362b4140d1904c070bcc64430c4d6987980fa02b75d38839db75af3951ce3605 languageName: node linkType: hard @@ -5124,7 +5124,7 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:^1.0.30001735": +"caniuse-lite@npm:^1.0.30001737": version: 1.0.30001737 resolution: "caniuse-lite@npm:1.0.30001737" checksum: 347ad0dccd76d04d86163fdd59ec89894660cced949252ff05c65aea4a35ffeba5814a60733c0b44ee1b56c083ae9aba4ab715b783ab72b69d8a653ef3ab6c9e @@ -5947,9 +5947,9 @@ __metadata: linkType: hard "dayjs@npm:^1.8.15": - version: 1.11.13 - resolution: "dayjs@npm:1.11.13" - checksum: f388db88a6aa93956c1f6121644e783391c7b738b73dbc54485578736565c8931bdfba4bb94e9b1535c6e509c97d5deb918bbe1ae6b34358d994de735055cca9 + version: 1.11.15 + resolution: "dayjs@npm:1.11.15" + checksum: e7d9a0eac598b6a9c835d2f4ce11ffeeb3904a836c7eda611331ae6cdfe8bc69cc177dc7efa72bb2fec83e02a632480ed1cb1c3db39afea0d93557f2ab4fe2c0 languageName: node linkType: hard @@ -6319,10 +6319,10 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.5.204": - version: 1.5.209 - resolution: "electron-to-chromium@npm:1.5.209" - checksum: 8c9ae3a019057b8f7c88ec7ac4dfd2fb2fa4b7daf2a788585510fbae5e8f9f6efafd3a57b13215bf65fc6cb0d976ea34f01a03f9f3979c42f16ad991b8f05911 +"electron-to-chromium@npm:^1.5.211": + version: 1.5.211 + resolution: "electron-to-chromium@npm:1.5.211" + checksum: 8e385c9680dd00c047eac92fba68f3fd8fc778369b3b074804183df63024c59e25bac0e5e4e0f3eba5f9b1e9c741dc159b12facd9127104aff545f135ca964f6 languageName: node linkType: hard @@ -6334,9 +6334,9 @@ __metadata: linkType: hard "emoji-regex@npm:^10.3.0": - version: 10.4.0 - resolution: "emoji-regex@npm:10.4.0" - checksum: a6d9a0e454829a52e664e049847776ee1fff5646617b06cd87de7c03ce1dfcce4102a3b154d5e9c8e90f8125bc120fc1fe114d523dddf60a8a161f26c72658d2 + version: 10.5.0 + resolution: "emoji-regex@npm:10.5.0" + checksum: 3a5164bfc2ac4685aa2fda613bb2b58d1d4e05b6ace9d87f8e119fe8cd39779875adfe1919b64f06f5dcd2b522238ad23b50caaaff7fb600bd53c84ff86e4b61 languageName: node linkType: hard @@ -7563,9 +7563,9 @@ __metadata: linkType: hard "flow-parser@npm:0.*": - version: 0.279.0 - resolution: "flow-parser@npm:0.279.0" - checksum: 1aaad7cac067cda2be86862a45815a0f1330f630654bb1310fede0c47b8b3404d0e76e6cee095d825e99ddcc87ef21a3f0255a786e560ba797087cd700cc66f8 + version: 0.281.0 + resolution: "flow-parser@npm:0.281.0" + checksum: 395d7eff52dc05233a06f94e76a090a80499b41cf6c0881811aac218870488a708b7934ec659600ca9a2b0acca3b2c1b1e1ac5e308c2d92bf3433ccf1f30c582 languageName: node linkType: hard @@ -9897,9 +9897,9 @@ __metadata: linkType: hard "ky@npm:^1.2.0": - version: 1.9.0 - resolution: "ky@npm:1.9.0" - checksum: 38cdbe46918ba20c0316114f61a61a9c861c5e080cf3a4585ba879a7a0752c623b3da70e5ba3015276fe2106348fd1f86646fcb6d27ea5423affaf78f338460b + version: 1.9.1 + resolution: "ky@npm:1.9.1" + checksum: df3de560c8398a2769a83fbc48d7e079c1a4cfd862fbed3aba370cba9629630fed8bc60dd3857f0b5d6536d61d1fb6412fefb1debb7f065c7a1a3fbba50ab07a languageName: node linkType: hard