react-native-biometrics-face 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,20 @@
1
+ require "json"
2
+
3
+ package = JSON.parse(File.read(File.join(__dir__, "package.json")))
4
+
5
+ Pod::Spec.new do |s|
6
+ s.name = "FaceRecognition"
7
+ s.version = package["version"]
8
+ s.summary = package["description"]
9
+ s.homepage = package["homepage"]
10
+ s.license = package["license"]
11
+ s.authors = package["author"]
12
+
13
+ s.platforms = { :ios => min_ios_version_supported }
14
+ s.source = { :git => "https://github.com/VASANTH3105/react-native-face-recognition.git.git", :tag => "#{s.version}" }
15
+
16
+ s.source_files = "ios/**/*.{h,m,mm,swift,cpp}"
17
+ s.private_header_files = "ios/**/*.h"
18
+
19
+ install_modules_dependencies(s)
20
+ end
package/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vasanth
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # react-native-face-recognition
2
+
3
+ Detect, Recognition face in offline
4
+
5
+ ## Installation
6
+
7
+
8
+ ```sh
9
+ npm install react-native-face-recognition
10
+ ```
11
+
12
+
13
+ ## Usage
14
+
15
+
16
+ ```js
17
+ import { multiply } from 'react-native-face-recognition';
18
+
19
+ // ...
20
+
21
+ const result = multiply(3, 7);
22
+ ```
23
+
24
+
25
+ ## Contributing
26
+
27
+ - [Development workflow](CONTRIBUTING.md#development-workflow)
28
+ - [Sending a pull request](CONTRIBUTING.md#sending-a-pull-request)
29
+ - [Code of conduct](CODE_OF_CONDUCT.md)
30
+
31
+ ## License
32
+
33
+ MIT
34
+
35
+ ---
36
+
37
+ Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
@@ -0,0 +1,100 @@
1
+ buildscript {
2
+ ext.getExtOrDefault = {name ->
3
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['FaceRecognition_' + name]
4
+ }
5
+
6
+ repositories {
7
+ google()
8
+ mavenCentral()
9
+ }
10
+
11
+ dependencies {
12
+ classpath "com.android.tools.build:gradle:8.7.2"
13
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
14
+ }
15
+ }
16
+
17
+ // --- ADDED: Helper function to check for New Architecture ---
18
+ def isNewArchitectureEnabled() {
19
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
20
+ }
21
+ // ------------------------------------------------------------
22
+
23
+ apply plugin: "com.android.library"
24
+ apply plugin: "kotlin-android"
25
+ apply plugin: "com.facebook.react"
26
+
27
+ def getExtOrIntegerDefault(name) {
28
+ return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["FaceRecognition_" + name]).toInteger()
29
+ }
30
+
31
+ android {
32
+ namespace "com.facerecognition"
33
+
34
+ compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
35
+
36
+ aaptOptions {
37
+ noCompress "tflite"
38
+ }
39
+
40
+ defaultConfig {
41
+ minSdkVersion getExtOrIntegerDefault("minSdkVersion")
42
+ targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
43
+
44
+ // --- ADDED: This generates the missing field in BuildConfig ---
45
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
46
+ // ------------------------------------------------------------
47
+ }
48
+
49
+ buildFeatures {
50
+ buildConfig true
51
+ }
52
+
53
+ buildTypes {
54
+ release {
55
+ minifyEnabled false
56
+ }
57
+ }
58
+
59
+ lintOptions {
60
+ disable "GradleCompatible"
61
+ }
62
+
63
+ compileOptions {
64
+ sourceCompatibility JavaVersion.VERSION_1_8
65
+ targetCompatibility JavaVersion.VERSION_1_8
66
+ }
67
+
68
+ sourceSets {
69
+ main {
70
+ java.srcDirs += [
71
+ "generated/java",
72
+ "generated/jni"
73
+ ]
74
+ }
75
+ }
76
+ }
77
+
78
+ repositories {
79
+ mavenCentral()
80
+ google()
81
+ }
82
+
83
+ def kotlin_version = getExtOrDefault("kotlinVersion")
84
+
85
+ dependencies {
86
+ implementation "com.facebook.react:react-android"
87
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
88
+
89
+ // 1. Google ML Kit (Face Detection)
90
+ implementation 'com.google.mlkit:face-detection:16.1.5'
91
+
92
+ // 2. TensorFlow Lite (The Core)
93
+ implementation 'org.tensorflow:tensorflow-lite:2.14.0'
94
+
95
+ // 3. TFLite Support (Helpers for Image/Tensor processing)
96
+ implementation 'org.tensorflow:tensorflow-lite-support:0.4.4'
97
+
98
+ // 4. GPU Delegate (Optional but recommended for performance)
99
+ implementation 'org.tensorflow:tensorflow-lite-gpu:2.14.0'
100
+ }
@@ -0,0 +1,5 @@
1
+ FaceRecognition_kotlinVersion=2.0.21
2
+ FaceRecognition_minSdkVersion=24
3
+ FaceRecognition_targetSdkVersion=34
4
+ FaceRecognition_compileSdkVersion=35
5
+ FaceRecognition_ndkVersion=27.1.12297006
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,156 @@
1
+ package com.facerecognition
2
+
3
+ import android.content.Context
4
+ import android.graphics.Bitmap
5
+ import android.graphics.BitmapFactory
6
+ import android.graphics.Rect
7
+ import android.util.Base64
8
+ import com.google.mlkit.vision.common.InputImage
9
+ import com.google.mlkit.vision.face.FaceDetection
10
+ import com.google.mlkit.vision.face.FaceDetectorOptions
11
+ import org.tensorflow.lite.Interpreter
12
+ import org.tensorflow.lite.support.common.FileUtil
13
+ import org.tensorflow.lite.support.common.ops.NormalizeOp
14
+ import org.tensorflow.lite.support.image.ImageProcessor
15
+ import org.tensorflow.lite.support.image.TensorImage
16
+ import org.tensorflow.lite.support.image.ops.ResizeOp
17
+ import java.nio.ByteBuffer
18
+ import java.util.concurrent.CountDownLatch
19
+ import kotlin.math.pow
20
+ import kotlin.math.sqrt
21
+
22
+ class FaceRecognitionEngine(context: Context) {
23
+
24
+ // Configuration
25
+ private val MODEL_NAME = "mobile_face_net.tflite"
26
+ private val INPUT_SIZE = 112
27
+ private val OUTPUT_SIZE = 192 // mobile_face_net output vector size
28
+ private val THRESHOLD = 1.0f // Standard threshold for mobile_face_net (adjust as needed)
29
+
30
+ // ML Kit Detector
31
+ private val detectorOptions = FaceDetectorOptions.Builder()
32
+ .setPerformanceMode(FaceDetectorOptions.PERFORMANCE_MODE_ACCURATE)
33
+ .setLandmarkMode(FaceDetectorOptions.LANDMARK_MODE_NONE)
34
+ .setClassificationMode(FaceDetectorOptions.CLASSIFICATION_MODE_NONE)
35
+ .build()
36
+ private val faceDetector = FaceDetection.getClient(detectorOptions)
37
+
38
+ // TFLite Interpreter
39
+ private var interpreter: Interpreter? = null
40
+
41
+ init {
42
+ try {
43
+ val modelFile = FileUtil.loadMappedFile(context, MODEL_NAME)
44
+ interpreter = Interpreter(modelFile)
45
+ } catch (e: Exception) {
46
+ e.printStackTrace()
47
+ }
48
+ }
49
+
50
+ fun verifyFaces(base64Source: String, base64Target: String): ApiResponse {
51
+ if (interpreter == null) {
52
+ return ApiResponse(500, "Model failed to load", null)
53
+ }
54
+
55
+ // 1. Decode Images
56
+ val sourceBitmap = decodeBase64(base64Source)
57
+ val targetBitmap = decodeBase64(base64Target)
58
+
59
+ if (sourceBitmap == null || targetBitmap == null) {
60
+ return ApiResponse(400, "Invalid Base64 input", null)
61
+ }
62
+
63
+ // 2. Detect & Crop Faces (Blocking Call for simplicity in this example)
64
+ val sourceFace = detectAndCrop(sourceBitmap)
65
+ val targetFace = detectAndCrop(targetBitmap)
66
+
67
+ if (sourceFace.error != null) return sourceFace.error
68
+ if (targetFace.error != null) return targetFace.error
69
+
70
+ // 3. Generate Embeddings
71
+ val sourceEmbedding = getEmbedding(sourceFace.bitmap!!)
72
+ val targetEmbedding = getEmbedding(targetFace.bitmap!!)
73
+
74
+ // 4. Calculate Distance (Euclidean)
75
+ var distance = 0f
76
+ for (i in sourceEmbedding.indices) {
77
+ distance += (sourceEmbedding[i] - targetEmbedding[i]).pow(2)
78
+ }
79
+ distance = sqrt(distance)
80
+
81
+ // 5. Calculate Accuracy (Simple mapping from distance)
82
+ // Note: This is a heuristic. distance 0 = 100%, distance > 1.2 = 0%
83
+ val accuracy = (1.0f - (distance / 2.0f)).coerceIn(0.0f, 1.0f) * 100
84
+ val isMatch = distance < THRESHOLD
85
+
86
+ return ApiResponse(200, "Comparison successful", VerificationResult(isMatch, distance, accuracy))
87
+ }
88
+
89
+ // --- Helper Classes & Methods ---
90
+
91
+ data class FaceResult(val bitmap: Bitmap? = null, val error: ApiResponse? = null)
92
+
93
+ private fun detectAndCrop(bitmap: Bitmap): FaceResult {
94
+ val latch = CountDownLatch(1)
95
+ var result = FaceResult(error = ApiResponse(500, "Detection timeout"))
96
+ val inputImage = InputImage.fromBitmap(bitmap, 0)
97
+
98
+ faceDetector.process(inputImage)
99
+ .addOnSuccessListener { faces ->
100
+ if (faces.isEmpty()) {
101
+ result = FaceResult(error = ApiResponse(400, "No face detected"))
102
+ } else if (faces.size > 1) {
103
+ result = FaceResult(error = ApiResponse(400, "Multiple faces detected"))
104
+ } else {
105
+ val face = faces[0]
106
+ val bounds = face.boundingBox
107
+ // Ensure bounds are within bitmap dimensions
108
+ val left = bounds.left.coerceAtLeast(0)
109
+ val top = bounds.top.coerceAtLeast(0)
110
+ val width = bounds.width().coerceAtMost(bitmap.width - left)
111
+ val height = bounds.height().coerceAtMost(bitmap.height - top)
112
+
113
+ val cropped = Bitmap.createBitmap(bitmap, left, top, width, height)
114
+ result = FaceResult(bitmap = cropped)
115
+ }
116
+ latch.countDown()
117
+ }
118
+ .addOnFailureListener {
119
+ result = FaceResult(error = ApiResponse(500, "Detection failed: ${it.message}"))
120
+ latch.countDown()
121
+ }
122
+
123
+ try { latch.await() } catch (e: InterruptedException) { }
124
+ return result
125
+ }
126
+
127
+ private fun getEmbedding(bitmap: Bitmap): FloatArray {
128
+ // Pre-process: Resize -> Normalize ( -128 / 128 )
129
+ val imageProcessor = ImageProcessor.Builder()
130
+ .add(ResizeOp(INPUT_SIZE, INPUT_SIZE, ResizeOp.ResizeMethod.BILINEAR))
131
+ .add(NormalizeOp(127.5f, 127.5f)) // Normalize to [-1, 1] for mobile_face_net
132
+ .build()
133
+
134
+ var tensorImage = TensorImage.fromBitmap(bitmap)
135
+ tensorImage = imageProcessor.process(tensorImage)
136
+
137
+ val outputBuffer = ByteBuffer.allocateDirect(OUTPUT_SIZE * 4) // Float (4 bytes)
138
+ outputBuffer.order(java.nio.ByteOrder.nativeOrder())
139
+
140
+ interpreter?.run(tensorImage.buffer, outputBuffer)
141
+
142
+ outputBuffer.rewind()
143
+ val floatArray = FloatArray(OUTPUT_SIZE)
144
+ outputBuffer.asFloatBuffer().get(floatArray)
145
+ return floatArray
146
+ }
147
+
148
+ private fun decodeBase64(base64Str: String): Bitmap? {
149
+ return try {
150
+ val decodedBytes = Base64.decode(base64Str, Base64.DEFAULT)
151
+ BitmapFactory.decodeByteArray(decodedBytes, 0, decodedBytes.size)
152
+ } catch (e: Exception) {
153
+ null
154
+ }
155
+ }
156
+ }
@@ -0,0 +1,35 @@
1
+ package com.facerecognition
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactMethod
5
+ import com.facebook.react.bridge.Promise
6
+ import kotlinx.coroutines.CoroutineScope
7
+ import kotlinx.coroutines.Dispatchers
8
+ import kotlinx.coroutines.launch
9
+
10
+ class FaceRecognitionModule(reactContext: ReactApplicationContext) :
11
+ FaceRecognitionSpec(reactContext) {
12
+
13
+ private val engine = FaceRecognitionEngine(reactContext)
14
+
15
+ override fun getName(): String {
16
+ return NAME
17
+ }
18
+
19
+ @ReactMethod
20
+ override fun verifyFaces(sourceImage: String, targetImage: String, promise: Promise) {
21
+ CoroutineScope(Dispatchers.IO).launch {
22
+ try {
23
+ val response = engine.verifyFaces(sourceImage, targetImage)
24
+ promise.resolve(response.toWritableMap())
25
+ } catch (e: Exception) {
26
+ val errorResponse = ApiResponse(500, "Native Module Error: ${e.message}")
27
+ promise.resolve(errorResponse.toWritableMap())
28
+ }
29
+ }
30
+ }
31
+
32
+ companion object {
33
+ const val NAME = "FaceRecognition"
34
+ }
35
+ }
@@ -0,0 +1,39 @@
1
+ package com.facerecognition
2
+
3
+ import com.facebook.react.TurboReactPackage
4
+ import com.facebook.react.bridge.NativeModule
5
+ import com.facebook.react.bridge.ReactApplicationContext
6
+ import com.facebook.react.module.model.ReactModuleInfo
7
+ import com.facebook.react.module.model.ReactModuleInfoProvider
8
+ import java.util.HashMap
9
+
10
+ class FaceRecognitionPackage : TurboReactPackage() {
11
+ override fun getModule(name: String, reactContext: ReactApplicationContext): NativeModule? {
12
+ return if (name == FaceRecognitionModule.NAME) {
13
+ FaceRecognitionModule(reactContext)
14
+ } else {
15
+ null
16
+ }
17
+ }
18
+
19
+ override fun getReactModuleInfoProvider(): ReactModuleInfoProvider {
20
+ return ReactModuleInfoProvider {
21
+ val moduleInfos: MutableMap<String, ReactModuleInfo> = HashMap()
22
+
23
+ // FIX: Set this to false.
24
+ // This tells RN to load it via the standard Bridge, which matches our Java class.
25
+ val isTurboModule = false
26
+
27
+ moduleInfos[FaceRecognitionModule.NAME] = ReactModuleInfo(
28
+ FaceRecognitionModule.NAME,
29
+ FaceRecognitionModule.NAME,
30
+ false, // canOverrideExistingModule
31
+ false, // needsEagerInit
32
+ true, // hasConstants
33
+ false, // isCxxModule
34
+ isTurboModule
35
+ )
36
+ moduleInfos
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,11 @@
1
+ package com.facerecognition
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule
5
+ import com.facebook.react.bridge.Promise
6
+
7
+ abstract class FaceRecognitionSpec(reactContext: ReactApplicationContext) :
8
+ ReactContextBaseJavaModule(reactContext) {
9
+
10
+ abstract fun verifyFaces(sourceImage: String, targetImage: String, promise: Promise)
11
+ }
@@ -0,0 +1,33 @@
1
+ package com.facerecognition
2
+
3
+ import com.facebook.react.bridge.WritableMap
4
+ import com.facebook.react.bridge.Arguments
5
+
6
+ data class VerificationResult(
7
+ val isMatch: Boolean,
8
+ val distance: Float,
9
+ val accuracy: Float
10
+ )
11
+
12
+ data class ApiResponse(
13
+ val statusCode: Int,
14
+ val message: String,
15
+ val result: VerificationResult? = null
16
+ ) {
17
+ fun toWritableMap(): WritableMap {
18
+ val map = Arguments.createMap()
19
+ map.putInt("statusCode", statusCode)
20
+ map.putString("message", message)
21
+
22
+ if (result != null) {
23
+ val resultMap = Arguments.createMap()
24
+ resultMap.putBoolean("isMatch", result.isMatch)
25
+ resultMap.putDouble("distance", result.distance.toDouble())
26
+ resultMap.putDouble("accuracy", result.accuracy.toDouble())
27
+ map.putMap("result", resultMap)
28
+ } else {
29
+ map.putNull("result")
30
+ }
31
+ return map
32
+ }
33
+ }
@@ -0,0 +1,5 @@
1
+ #import <FaceRecognitionSpec/FaceRecognitionSpec.h>
2
+
3
+ @interface FaceRecognition : NSObject <NativeFaceRecognitionSpec>
4
+
5
+ @end
@@ -0,0 +1,21 @@
1
+ #import "FaceRecognition.h"
2
+
3
+ @implementation FaceRecognition
4
+ - (NSNumber *)multiply:(double)a b:(double)b {
5
+ NSNumber *result = @(a * b);
6
+
7
+ return result;
8
+ }
9
+
10
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
11
+ (const facebook::react::ObjCTurboModule::InitParams &)params
12
+ {
13
+ return std::make_shared<facebook::react::NativeFaceRecognitionSpecJSI>(params);
14
+ }
15
+
16
+ + (NSString *)moduleName
17
+ {
18
+ return @"FaceRecognition";
19
+ }
20
+
21
+ @end
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ import { NativeModules, Platform } from 'react-native';
4
+
5
+ // Define the interface for TypeScript safety
6
+
7
+ // Access the module via the standard NativeModules bridge
8
+ const LINKING_ERROR = `The package 'react-native-face-recognition' doesn't seem to be linked. Make sure: \n\n` + Platform.select({
9
+ ios: "- You have run 'pod install'\n",
10
+ default: ''
11
+ }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n';
12
+
13
+ // Use standard NativeModules instead of TurboModuleRegistry
14
+ const FaceRecognition = NativeModules.FaceRecognition ? NativeModules.FaceRecognition : new Proxy({}, {
15
+ get() {
16
+ throw new Error(LINKING_ERROR);
17
+ }
18
+ });
19
+ export default FaceRecognition;
20
+ //# sourceMappingURL=NativeFaceRecognition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["NativeModules","Platform","LINKING_ERROR","select","ios","default","FaceRecognition","Proxy","get","Error"],"sourceRoot":"../../src","sources":["NativeFaceRecognition.ts"],"mappings":";;AAAA,SAASA,aAAa,EAAEC,QAAQ,QAAQ,cAAc;;AAEtD;;AAaA;AACA,MAAMC,aAAa,GACjB,wFAAwF,GACxFD,QAAQ,CAACE,MAAM,CAAC;EAAEC,GAAG,EAAE,gCAAgC;EAAEC,OAAO,EAAE;AAAG,CAAC,CAAC,GACvE,sDAAsD,GACtD,+BAA+B;;AAEjC;AACA,MAAMC,eAAe,GAAGN,aAAa,CAACM,eAAe,GACjDN,aAAa,CAACM,eAAe,GAC7B,IAAIC,KAAK,CACP,CAAC,CAAC,EACF;EACEC,GAAGA,CAAA,EAAG;IACJ,MAAM,IAAIC,KAAK,CAACP,aAAa,CAAC;EAChC;AACF,CACF,CAAC;AAEL,eAAeI,eAAe","ignoreList":[]}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ import FaceRecognition from "./NativeFaceRecognition.js";
4
+
5
+ // We export the types so your app can use them
6
+
7
+ /**
8
+ * Verifies if two faces match.
9
+ * * @param sourceImage Base64 string of the first image
10
+ * @param targetImage Base64 string of the second image
11
+ * @returns Promise resolving to the VerificationResponse object
12
+ */
13
+ export function verifyFaces(sourceImage, targetImage) {
14
+ return FaceRecognition.verifyFaces(sourceImage, targetImage);
15
+ }
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["FaceRecognition","verifyFaces","sourceImage","targetImage"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,eAAe,MAAM,4BAAyB;;AAGrD;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CACzBC,WAAmB,EACnBC,WAAmB,EACY;EAC/B,OAAOH,eAAe,CAACC,WAAW,CAACC,WAAW,EAAEC,WAAW,CAAC;AAC9D","ignoreList":[]}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1 @@
1
+ {"type":"module"}
@@ -0,0 +1,13 @@
1
+ export interface FaceVerificationResult {
2
+ isMatch: boolean;
3
+ distance: number;
4
+ accuracy: number;
5
+ }
6
+ export interface VerificationResponse {
7
+ statusCode: number;
8
+ message: string;
9
+ result: FaceVerificationResult | null;
10
+ }
11
+ declare const FaceRecognition: any;
12
+ export default FaceRecognition;
13
+ //# sourceMappingURL=NativeFaceRecognition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NativeFaceRecognition.d.ts","sourceRoot":"","sources":["../../../src/NativeFaceRecognition.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,sBAAsB,GAAG,IAAI,CAAC;CACvC;AAUD,QAAA,MAAM,eAAe,KAShB,CAAC;AAEN,eAAe,eAAe,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { VerificationResponse } from './NativeFaceRecognition';
2
+ export type { VerificationResponse, FaceVerificationResult } from './NativeFaceRecognition';
3
+ /**
4
+ * Verifies if two faces match.
5
+ * * @param sourceImage Base64 string of the first image
6
+ * @param targetImage Base64 string of the second image
7
+ * @returns Promise resolving to the VerificationResponse object
8
+ */
9
+ export declare function verifyFaces(sourceImage: string, targetImage: string): Promise<VerificationResponse>;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAGpE,YAAY,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAE5F;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,oBAAoB,CAAC,CAE/B"}
package/package.json ADDED
@@ -0,0 +1,137 @@
1
+ {
2
+ "name": "react-native-biometrics-face",
3
+ "version": "0.1.0",
4
+ "description": "Detect, Recognition face in offline",
5
+ "main": "./lib/module/index.js",
6
+ "types": "./lib/typescript/src/index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "source": "./src/index.tsx",
10
+ "types": "./lib/typescript/src/index.d.ts",
11
+ "default": "./lib/module/index.js"
12
+ },
13
+ "./package.json": "./package.json"
14
+ },
15
+ "files": [
16
+ "src",
17
+ "lib",
18
+ "android",
19
+ "ios",
20
+ "cpp",
21
+ "*.podspec",
22
+ "react-native.config.js",
23
+ "!ios/build",
24
+ "!android/build",
25
+ "!android/gradle",
26
+ "!android/gradlew",
27
+ "!android/gradlew.bat",
28
+ "!android/local.properties",
29
+ "!**/__tests__",
30
+ "!**/__fixtures__",
31
+ "!**/__mocks__",
32
+ "!**/.*"
33
+ ],
34
+ "scripts": {
35
+ "example": "yarn workspace react-native-face-recognition-example",
36
+ "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build lib",
37
+ "prepare": "bob build",
38
+ "typecheck": "tsc",
39
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
40
+ "test": "jest"
41
+ },
42
+ "keywords": [
43
+ "react-native",
44
+ "ios",
45
+ "android"
46
+ ],
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/VASANTH3105/react-native-face-recognition.git.git"
50
+ },
51
+ "author": "Vasanth <vasanth.it2125@gmail.com> (https://github.com/VASANTH3105/react-native-face-recognition)",
52
+ "license": "MIT",
53
+ "bugs": {
54
+ "url": "https://github.com/VASANTH3105/react-native-face-recognition.git/issues"
55
+ },
56
+ "homepage": "https://github.com/VASANTH3105/react-native-face-recognition.git#readme",
57
+ "publishConfig": {
58
+ "registry": "https://registry.npmjs.org/"
59
+ },
60
+ "devDependencies": {
61
+ "@eslint/compat": "^1.3.2",
62
+ "@eslint/eslintrc": "^3.3.1",
63
+ "@eslint/js": "^9.35.0",
64
+ "@react-native/babel-preset": "0.83.0",
65
+ "@react-native/eslint-config": "0.83.0",
66
+ "@types/jest": "^29.5.14",
67
+ "@types/react": "^19.2.0",
68
+ "del-cli": "^6.0.0",
69
+ "eslint": "^9.35.0",
70
+ "eslint-config-prettier": "^10.1.8",
71
+ "eslint-plugin-prettier": "^5.5.4",
72
+ "jest": "^29.7.0",
73
+ "prettier": "^2.8.8",
74
+ "react": "19.2.0",
75
+ "react-native": "0.83.0",
76
+ "react-native-builder-bob": "^0.40.13",
77
+ "turbo": "^2.5.6",
78
+ "typescript": "^5.9.2"
79
+ },
80
+ "peerDependencies": {
81
+ "react": "*",
82
+ "react-native": "*"
83
+ },
84
+ "workspaces": [
85
+ "example"
86
+ ],
87
+ "packageManager": "yarn@4.11.0",
88
+ "react-native-builder-bob": {
89
+ "source": "src",
90
+ "output": "lib",
91
+ "targets": [
92
+ [
93
+ "module",
94
+ {
95
+ "esm": true
96
+ }
97
+ ],
98
+ [
99
+ "typescript",
100
+ {
101
+ "project": "tsconfig.build.json"
102
+ }
103
+ ]
104
+ ]
105
+ },
106
+ "codegenConfig": {
107
+ "name": "FaceRecognitionSpec",
108
+ "type": "modules",
109
+ "jsSrcsDir": "src",
110
+ "android": {
111
+ "javaPackageName": "com.facerecognition"
112
+ }
113
+ },
114
+ "prettier": {
115
+ "quoteProps": "consistent",
116
+ "singleQuote": true,
117
+ "tabWidth": 2,
118
+ "trailingComma": "es5",
119
+ "useTabs": false
120
+ },
121
+ "jest": {
122
+ "preset": "react-native",
123
+ "modulePathIgnorePatterns": [
124
+ "<rootDir>/example/node_modules",
125
+ "<rootDir>/lib/"
126
+ ]
127
+ },
128
+ "create-react-native-library": {
129
+ "type": "turbo-module",
130
+ "languages": "kotlin-objc",
131
+ "tools": [
132
+ "eslint",
133
+ "jest"
134
+ ],
135
+ "version": "0.56.0"
136
+ }
137
+ }
@@ -0,0 +1,7 @@
1
+ module.exports = {
2
+ dependency: {
3
+ platforms: {
4
+ ios: null,
5
+ },
6
+ },
7
+ };
@@ -0,0 +1,35 @@
1
+ import { NativeModules, Platform } from 'react-native';
2
+
3
+ // Define the interface for TypeScript safety
4
+ export interface FaceVerificationResult {
5
+ isMatch: boolean;
6
+ distance: number;
7
+ accuracy: number;
8
+ }
9
+
10
+ export interface VerificationResponse {
11
+ statusCode: number;
12
+ message: string;
13
+ result: FaceVerificationResult | null;
14
+ }
15
+
16
+ // Access the module via the standard NativeModules bridge
17
+ const LINKING_ERROR =
18
+ `The package 'react-native-face-recognition' doesn't seem to be linked. Make sure: \n\n` +
19
+ Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
20
+ '- You rebuilt the app after installing the package\n' +
21
+ '- You are not using Expo Go\n';
22
+
23
+ // Use standard NativeModules instead of TurboModuleRegistry
24
+ const FaceRecognition = NativeModules.FaceRecognition
25
+ ? NativeModules.FaceRecognition
26
+ : new Proxy(
27
+ {},
28
+ {
29
+ get() {
30
+ throw new Error(LINKING_ERROR);
31
+ },
32
+ }
33
+ );
34
+
35
+ export default FaceRecognition;
package/src/index.tsx ADDED
@@ -0,0 +1,18 @@
1
+ import FaceRecognition from './NativeFaceRecognition';
2
+ import type { VerificationResponse } from './NativeFaceRecognition';
3
+
4
+ // We export the types so your app can use them
5
+ export type { VerificationResponse, FaceVerificationResult } from './NativeFaceRecognition';
6
+
7
+ /**
8
+ * Verifies if two faces match.
9
+ * * @param sourceImage Base64 string of the first image
10
+ * @param targetImage Base64 string of the second image
11
+ * @returns Promise resolving to the VerificationResponse object
12
+ */
13
+ export function verifyFaces(
14
+ sourceImage: string,
15
+ targetImage: string
16
+ ): Promise<VerificationResponse> {
17
+ return FaceRecognition.verifyFaces(sourceImage, targetImage);
18
+ }