@simasfin/smmf-sdk 0.0.0-stage → 0.2.3

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.
Files changed (53) hide show
  1. package/README.md +84 -2
  2. package/android/build.gradle +51 -0
  3. package/android/maven/id/co/onepass/onepass-sdk/0.2.3/onepass-sdk-0.2.3.aar +0 -0
  4. package/android/maven/id/co/onepass/onepass-sdk/0.2.3/onepass-sdk-0.2.3.pom +52 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/id/co/onepass/expo/OnePassSignatureExpoView.kt +25 -0
  7. package/android/src/main/java/id/co/onepass/expo/OnepassExpoModule.kt +134 -0
  8. package/app.plugin.js +1 -0
  9. package/build/OnePassSignatureView.d.ts +19 -0
  10. package/build/OnePassSignatureView.d.ts.map +1 -0
  11. package/build/OnePassSignatureView.js +15 -0
  12. package/build/OnePassSignatureView.js.map +1 -0
  13. package/build/index.d.ts +21 -0
  14. package/build/index.d.ts.map +1 -0
  15. package/build/index.js +10 -0
  16. package/build/index.js.map +1 -0
  17. package/expo-module.config.json +9 -0
  18. package/ios/OnePassSDK/DesignSystem.swift +139 -0
  19. package/ios/OnePassSDK/IconView.swift +54 -0
  20. package/ios/OnePassSDK/IconsaxPath.swift +216 -0
  21. package/ios/OnePassSDK/Liveness/FaceAnalyzer.swift +114 -0
  22. package/ios/OnePassSDK/Liveness/FaceLandmarkMetrics.swift +28 -0
  23. package/ios/OnePassSDK/Liveness/FaceSnapshotMapper.swift +37 -0
  24. package/ios/OnePassSDK/Liveness/LivenessGate.swift +155 -0
  25. package/ios/OnePassSDK/Liveness/LivenessImagePreparer.swift +44 -0
  26. package/ios/OnePassSDK/Liveness/LivenessViewController.swift +724 -0
  27. package/ios/OnePassSDK/Ocr/CoverFitCrop.swift +37 -0
  28. package/ios/OnePassSDK/Ocr/KtpFrameOverlayView.swift +98 -0
  29. package/ios/OnePassSDK/Ocr/KtpImagePreparer.swift +90 -0
  30. package/ios/OnePassSDK/Ocr/KtpOcrViewController.swift +703 -0
  31. package/ios/OnePassSDK/Ocr/KtpPhotoInspector.swift +93 -0
  32. package/ios/OnePassSDK/Ocr/KtpQualityGate.swift +185 -0
  33. package/ios/OnePassSDK/OnePass.swift +28 -0
  34. package/ios/OnePassSDK/Resources/hindari_pemakaian.png +0 -0
  35. package/ios/OnePassSDK/Resources/inter_bold.ttf +0 -0
  36. package/ios/OnePassSDK/Resources/inter_medium.ttf +0 -0
  37. package/ios/OnePassSDK/Resources/inter_regular.ttf +0 -0
  38. package/ios/OnePassSDK/Resources/inter_semibold.ttf +0 -0
  39. package/ios/OnePassSDK/Resources/ktp_illustration.webp +0 -0
  40. package/ios/OnePassSDK/Resources/logo_smmf.png +0 -0
  41. package/ios/OnePassSDK/Resources/placeholder_head.png +0 -0
  42. package/ios/OnePassSDK/Signature/SignaturePadView.swift +144 -0
  43. package/ios/OnePassSignatureExpoView.swift +22 -0
  44. package/ios/OnepassExpo.podspec +23 -0
  45. package/ios/OnepassExpoModule.swift +77 -0
  46. package/licenses/Iconsax-MIT.txt +26 -0
  47. package/licenses/Inter-OFL-1.1.txt +93 -0
  48. package/package.json +49 -4
  49. package/plugin/src/inject.js +31 -0
  50. package/plugin/withOnePass.js +32 -0
  51. package/scripts/sync-native.js +84 -0
  52. package/src/OnePassSignatureView.tsx +34 -0
  53. package/src/index.ts +44 -0
package/README.md CHANGED
@@ -1,3 +1,85 @@
1
- # Temporary Holding Version
1
+ # @simasfin/smmf-sdk
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Modul Expo untuk liveness wajah, foto KTP, dan kanvas tanda tangan. Android dan iOS.
4
+
5
+ > Modul ini berisi kode native, jadi butuh **development build / EAS Build**. Tidak bisa dijalankan di Expo Go.
6
+
7
+ ### 1. Pasang paket
8
+
9
+ ```bash
10
+ npx expo install @simasfin/smmf-sdk
11
+ ```
12
+
13
+ ### 2. Daftarkan config plugin
14
+
15
+ Di `app.json` (atau `app.config.js`):
16
+
17
+ ```json
18
+ {
19
+ "expo": {
20
+ "plugins": ["@simasfin/smmf-sdk"]
21
+ }
22
+ }
23
+ ```
24
+
25
+ Config plugin akan otomatis menambahkan `NSCameraUsageDescription` (iOS) dan permission kamera Android bila belum ada.
26
+
27
+ Opsi tambahan (bentuk `["@simasfin/smmf-sdk", { ... }]`):
28
+
29
+ | Opsi | Wajib | Default | Keterangan |
30
+ |---|---|---|---|
31
+ | `cameraUsageDescription` | tidak | "Kamera dibutuhkan untuk verifikasi wajah dan pengambilan foto KTP." | Teks izin kamera iOS. Tidak menimpa nilai yang sudah Anda set. |
32
+
33
+ ### 3. Generate project native
34
+
35
+ ```bash
36
+ npx expo prebuild
37
+ ```
38
+
39
+ ### 4. Panggil Liveness
40
+
41
+ ```ts
42
+ import { startLiveness } from '@simasfin/smmf-sdk';
43
+
44
+ const result = await startLiveness({
45
+ primaryColorHex: '#EC1F27' // opsional
46
+ });
47
+
48
+ if (result.status === 'SUCCESS') {
49
+ const base64 = result.imageBase64; // JPEG base64, kirim ke backend Anda
50
+ }
51
+ ```
52
+
53
+ ### 5. Panggil Foto KTP
54
+
55
+ ```ts
56
+ import { startKtpOcr } from '@simasfin/smmf-sdk';
57
+
58
+ const result = await startKtpOcr();
59
+
60
+ if (result.status === 'SUCCESS') {
61
+ const base64 = result.imageBase64; // JPEG base64, kirim ke backend Anda untuk OCR
62
+ }
63
+ ```
64
+
65
+ ### 6. Kanvas Tanda Tangan
66
+
67
+ Kanvas native yang ditaruh inline di layar Anda. Hasilnya PNG transparan seukuran kanvas, base64 polos.
68
+
69
+ ```tsx
70
+ import { OnePassSignatureView, OnePassSignatureViewRef } from '@simasfin/smmf-sdk';
71
+
72
+ const signatureRef = useRef<OnePassSignatureViewRef>(null);
73
+
74
+ <OnePassSignatureView
75
+ ref={signatureRef}
76
+ style={{ height: 240 }}
77
+ penColor="#0A2730" // hex
78
+ strokeWidth={4} // ketebalan garis (dp/pt)
79
+ onBegin={() => setScrollEnabled(false)}
80
+ onEnd={() => setScrollEnabled(true)}
81
+ />
82
+
83
+ await signatureRef.current?.clear();
84
+ const base64 = await signatureRef.current?.readSignature(); // null bila kanvas masih kosong
85
+ ```
@@ -0,0 +1,51 @@
1
+ apply plugin: 'com.android.library'
2
+ apply plugin: 'kotlin-android'
3
+
4
+ group = 'id.co.onepass.expo'
5
+ version = '0.1.0'
6
+
7
+ def onepassSdkVersion = new groovy.json.JsonSlurper().parse(file('../package.json')).version
8
+
9
+ def safeExtGet(prop, fallback) {
10
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
11
+ }
12
+
13
+ android {
14
+ namespace 'id.co.onepass.expo'
15
+ compileSdk safeExtGet('compileSdkVersion', 34)
16
+
17
+ defaultConfig {
18
+ minSdkVersion safeExtGet('minSdkVersion', 24)
19
+ targetSdkVersion safeExtGet('targetSdkVersion', 34)
20
+ }
21
+
22
+ compileOptions {
23
+ sourceCompatibility JavaVersion.VERSION_17
24
+ targetCompatibility JavaVersion.VERSION_17
25
+ }
26
+
27
+ kotlinOptions {
28
+ jvmTarget = '17'
29
+ }
30
+ }
31
+
32
+ repositories {
33
+ maven { url "$projectDir/maven" }
34
+ mavenCentral()
35
+ google()
36
+ }
37
+
38
+ dependencies {
39
+ implementation project(':expo-modules-core')
40
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion"
41
+
42
+ api "id.co.onepass:onepass-sdk:${onepassSdkVersion}"
43
+
44
+ implementation 'androidx.appcompat:appcompat:1.7.0'
45
+ implementation 'androidx.camera:camera-core:1.4.1'
46
+ implementation 'androidx.camera:camera-camera2:1.4.1'
47
+ implementation 'androidx.camera:camera-lifecycle:1.4.1'
48
+ implementation 'androidx.camera:camera-view:1.4.1'
49
+ implementation 'com.google.mlkit:face-detection:16.1.7'
50
+ implementation 'com.google.mlkit:text-recognition:16.0.1'
51
+ }
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0">
3
+ <modelVersion>4.0.0</modelVersion>
4
+ <groupId>id.co.onepass</groupId>
5
+ <artifactId>onepass-sdk</artifactId>
6
+ <version>0.2.3</version>
7
+ <packaging>aar</packaging>
8
+ <dependencies>
9
+ <dependency>
10
+ <groupId>androidx.appcompat</groupId>
11
+ <artifactId>appcompat</artifactId>
12
+ <version>1.7.0</version>
13
+ <scope>runtime</scope>
14
+ </dependency>
15
+ <dependency>
16
+ <groupId>androidx.camera</groupId>
17
+ <artifactId>camera-core</artifactId>
18
+ <version>1.4.1</version>
19
+ <scope>runtime</scope>
20
+ </dependency>
21
+ <dependency>
22
+ <groupId>androidx.camera</groupId>
23
+ <artifactId>camera-camera2</artifactId>
24
+ <version>1.4.1</version>
25
+ <scope>runtime</scope>
26
+ </dependency>
27
+ <dependency>
28
+ <groupId>androidx.camera</groupId>
29
+ <artifactId>camera-lifecycle</artifactId>
30
+ <version>1.4.1</version>
31
+ <scope>runtime</scope>
32
+ </dependency>
33
+ <dependency>
34
+ <groupId>androidx.camera</groupId>
35
+ <artifactId>camera-view</artifactId>
36
+ <version>1.4.1</version>
37
+ <scope>runtime</scope>
38
+ </dependency>
39
+ <dependency>
40
+ <groupId>com.google.mlkit</groupId>
41
+ <artifactId>face-detection</artifactId>
42
+ <version>16.1.7</version>
43
+ <scope>runtime</scope>
44
+ </dependency>
45
+ <dependency>
46
+ <groupId>com.google.mlkit</groupId>
47
+ <artifactId>text-recognition</artifactId>
48
+ <version>16.0.1</version>
49
+ <scope>runtime</scope>
50
+ </dependency>
51
+ </dependencies>
52
+ </project>
@@ -0,0 +1,2 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ </manifest>
@@ -0,0 +1,25 @@
1
+ package id.co.onepass.expo
2
+
3
+ import android.content.Context
4
+ import expo.modules.kotlin.AppContext
5
+ import expo.modules.kotlin.viewevent.EventDispatcher
6
+ import expo.modules.kotlin.views.ExpoView
7
+ import id.co.onepass.sdk.signature.SignaturePadView
8
+
9
+ class OnePassSignatureExpoView(context: Context, appContext: AppContext) :
10
+ ExpoView(context, appContext) {
11
+
12
+ val pad = SignaturePadView(context)
13
+ private val onBegin by EventDispatcher()
14
+ private val onEnd by EventDispatcher()
15
+
16
+ init {
17
+ addView(pad)
18
+ pad.onBegin = { onBegin(emptyMap()) }
19
+ pad.onEnd = { onEnd(emptyMap()) }
20
+ }
21
+
22
+ override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
23
+ pad.layout(0, 0, right - left, bottom - top)
24
+ }
25
+ }
@@ -0,0 +1,134 @@
1
+ package id.co.onepass.expo
2
+
3
+ import android.app.Activity
4
+ import android.content.Intent
5
+ import android.graphics.Color
6
+ import expo.modules.kotlin.Promise
7
+ import expo.modules.kotlin.exception.Exceptions
8
+ import expo.modules.kotlin.functions.Queues
9
+ import expo.modules.kotlin.modules.Module
10
+ import expo.modules.kotlin.modules.ModuleDefinition
11
+ import id.co.onepass.sdk.KtpOcrContract
12
+ import id.co.onepass.sdk.KtpOcrInput
13
+ import id.co.onepass.sdk.KtpOcrStatusCode
14
+ import id.co.onepass.sdk.LivenessContract
15
+ import id.co.onepass.sdk.LivenessInput
16
+ import id.co.onepass.sdk.LivenessStatus
17
+
18
+ class OnepassExpoModule : Module() {
19
+
20
+ companion object {
21
+ private const val REQUEST_LIVENESS = 0x0F01
22
+ private const val REQUEST_KTP_OCR = 0x0F02
23
+ }
24
+
25
+ private var pendingPromise: Promise? = null
26
+ private var pendingRequestCode: Int? = null
27
+
28
+ private val currentActivity: Activity
29
+ get() = appContext.currentActivity ?: throw Exceptions.MissingActivity()
30
+
31
+ override fun definition() = ModuleDefinition {
32
+ Name("OnepassExpo")
33
+
34
+ AsyncFunction("startLiveness") { options: Map<String, Any?>, promise: Promise ->
35
+ val input = LivenessInput(primaryColorHex = options["primaryColorHex"] as? String)
36
+ launch(
37
+ REQUEST_LIVENESS,
38
+ LivenessContract().createIntent(currentActivity, input),
39
+ promise,
40
+ )
41
+ }
42
+
43
+ AsyncFunction("startKtpOcr") { options: Map<String, Any?>, promise: Promise ->
44
+ val input = KtpOcrInput(primaryColorHex = options["primaryColorHex"] as? String)
45
+ launch(
46
+ REQUEST_KTP_OCR,
47
+ KtpOcrContract().createIntent(currentActivity, input),
48
+ promise,
49
+ )
50
+ }
51
+
52
+ View(OnePassSignatureExpoView::class) {
53
+ Events("onBegin", "onEnd")
54
+
55
+ Prop("penColor") { view: OnePassSignatureExpoView, color: String? ->
56
+ view.pad.penColor =
57
+ color?.let { runCatching { Color.parseColor(it) }.getOrNull() } ?: Color.BLACK
58
+ }
59
+
60
+ Prop("strokeWidth") { view: OnePassSignatureExpoView, width: Float? ->
61
+ view.pad.strokeWidthDp = width ?: 2f
62
+ }
63
+
64
+ AsyncFunction("clear") { view: OnePassSignatureExpoView ->
65
+ view.pad.clear()
66
+ }.runOnQueue(Queues.MAIN)
67
+
68
+ AsyncFunction("readSignature") { view: OnePassSignatureExpoView ->
69
+ view.pad.toBase64Png()
70
+ }.runOnQueue(Queues.MAIN)
71
+ }
72
+
73
+ OnActivityResult { _, payload ->
74
+ when (payload.requestCode) {
75
+ REQUEST_LIVENESS -> resolveLiveness(payload.resultCode, payload.data)
76
+ REQUEST_KTP_OCR -> resolveKtpOcr(payload.resultCode, payload.data)
77
+ }
78
+ }
79
+ }
80
+
81
+ private fun launch(requestCode: Int, intent: Intent, promise: Promise) {
82
+ if (pendingPromise != null) {
83
+ promise.reject(
84
+ "ONEPASS_BUSY",
85
+ "Verifikasi OnePass lain sedang berjalan",
86
+ null,
87
+ )
88
+ return
89
+ }
90
+ pendingPromise = promise
91
+ pendingRequestCode = requestCode
92
+ currentActivity.startActivityForResult(intent, requestCode)
93
+ }
94
+
95
+ private fun consumePromise(requestCode: Int): Promise? {
96
+ if (pendingRequestCode != requestCode) return null
97
+ val promise = pendingPromise
98
+ pendingPromise = null
99
+ pendingRequestCode = null
100
+ return promise
101
+ }
102
+
103
+ private fun resolveLiveness(resultCode: Int, data: Intent?) {
104
+ val promise = consumePromise(REQUEST_LIVENESS) ?: return
105
+ val result = LivenessContract().parseResult(resultCode, data)
106
+ promise.resolve(
107
+ mapOf(
108
+ "status" to when (result.status) {
109
+ LivenessStatus.SUCCESS -> "SUCCESS"
110
+ LivenessStatus.FAILED -> "FAILED"
111
+ LivenessStatus.CANCELLED -> "CANCELLED"
112
+ },
113
+ "imageBase64" to result.imageBase64,
114
+ "errorMessage" to result.errorMessage,
115
+ )
116
+ )
117
+ }
118
+
119
+ private fun resolveKtpOcr(resultCode: Int, data: Intent?) {
120
+ val promise = consumePromise(REQUEST_KTP_OCR) ?: return
121
+ val result = KtpOcrContract().parseResult(resultCode, data)
122
+ promise.resolve(
123
+ mapOf(
124
+ "status" to when (result.status) {
125
+ KtpOcrStatusCode.SUCCESS -> "SUCCESS"
126
+ KtpOcrStatusCode.FAILED -> "FAILED"
127
+ KtpOcrStatusCode.CANCELLED -> "CANCELLED"
128
+ },
129
+ "imageBase64" to result.imageBase64,
130
+ "errorMessage" to result.errorMessage,
131
+ )
132
+ )
133
+ }
134
+ }
package/app.plugin.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./plugin/withOnePass');
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import type { ViewProps } from 'react-native';
3
+ export type OnePassSignatureViewProps = ViewProps & {
4
+ penColor?: string;
5
+ strokeWidth?: number;
6
+ onBegin?: () => void;
7
+ onEnd?: () => void;
8
+ };
9
+ export type OnePassSignatureViewRef = {
10
+ clear(): Promise<void>;
11
+ readSignature(): Promise<string | null>;
12
+ };
13
+ export declare const OnePassSignatureView: React.ForwardRefExoticComponent<ViewProps & {
14
+ penColor?: string;
15
+ strokeWidth?: number;
16
+ onBegin?: () => void;
17
+ onEnd?: () => void;
18
+ } & React.RefAttributes<OnePassSignatureViewRef>>;
19
+ //# sourceMappingURL=OnePassSignatureView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnePassSignatureView.d.ts","sourceRoot":"","sources":["../src/OnePassSignatureView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAkD,MAAM,OAAO,CAAC;AACvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,MAAM,yBAAyB,GAAG,SAAS,GAAG;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,IAAI,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,aAAa,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACzC,CAAC;AAMF,eAAO,MAAM,oBAAoB;eAfpB,MAAM;kBACH,MAAM;cACV,MAAM,IAAI;YACZ,MAAM,IAAI;iDAyBnB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { requireNativeViewManager } from 'expo-modules-core';
3
+ import { forwardRef, useImperativeHandle, useRef } from 'react';
4
+ const NativeSignatureView = requireNativeViewManager('OnepassExpo');
5
+ export const OnePassSignatureView = forwardRef(function OnePassSignatureView(props, ref) {
6
+ const nativeRef = useRef(null);
7
+ useImperativeHandle(ref, () => ({
8
+ clear: async () => {
9
+ await nativeRef.current?.clear();
10
+ },
11
+ readSignature: async () => (await nativeRef.current?.readSignature()) ?? null,
12
+ }));
13
+ return _jsx(NativeSignatureView, { ...props, ref: nativeRef });
14
+ });
15
+ //# sourceMappingURL=OnePassSignatureView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnePassSignatureView.js","sourceRoot":"","sources":["../src/OnePassSignatureView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAc,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAevE,MAAM,mBAAmB,GAAG,wBAAwB,CAClD,aAAa,CACmF,CAAC;AAEnG,MAAM,CAAC,MAAM,oBAAoB,GAAG,UAAU,CAC5C,SAAS,oBAAoB,CAAC,KAAK,EAAE,GAAG;IACtC,MAAM,SAAS,GAAG,MAAM,CAA0B,IAAI,CAAC,CAAC;IAExD,mBAAmB,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;QAC9B,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;QACnC,CAAC;QACD,aAAa,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,MAAM,SAAS,CAAC,OAAO,EAAE,aAAa,EAAE,CAAC,IAAI,IAAI;KAC9E,CAAC,CAAC,CAAC;IAEJ,OAAO,KAAC,mBAAmB,OAAK,KAAK,EAAE,GAAG,EAAE,SAAS,GAAI,CAAC;AAC5D,CAAC,CACF,CAAC"}
@@ -0,0 +1,21 @@
1
+ export { OnePassSignatureView, type OnePassSignatureViewProps, type OnePassSignatureViewRef, } from './OnePassSignatureView';
2
+ export type CaptureStatus = 'SUCCESS' | 'FAILED' | 'CANCELLED';
3
+ export type LivenessOptions = {
4
+ primaryColorHex?: string;
5
+ };
6
+ export type LivenessResult = {
7
+ status: CaptureStatus;
8
+ imageBase64?: string;
9
+ errorMessage?: string;
10
+ };
11
+ export type KtpOcrOptions = {
12
+ primaryColorHex?: string;
13
+ };
14
+ export type KtpOcrResult = {
15
+ status: CaptureStatus;
16
+ imageBase64?: string;
17
+ errorMessage?: string;
18
+ };
19
+ export declare function startLiveness(options?: LivenessOptions): Promise<LivenessResult>;
20
+ export declare function startKtpOcr(options?: KtpOcrOptions): Promise<KtpOcrResult>;
21
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,KAAK,uBAAuB,GAC7B,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/D,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,MAAM,EAAE,aAAa,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AASF,wBAAgB,aAAa,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,CAEpF;AAED,wBAAgB,WAAW,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAE9E"}
package/build/index.js ADDED
@@ -0,0 +1,10 @@
1
+ import { requireNativeModule } from 'expo-modules-core';
2
+ export { OnePassSignatureView, } from './OnePassSignatureView';
3
+ const OnepassExpo = requireNativeModule('OnepassExpo');
4
+ export function startLiveness(options = {}) {
5
+ return OnepassExpo.startLiveness(options);
6
+ }
7
+ export function startKtpOcr(options = {}) {
8
+ return OnepassExpo.startKtpOcr(options);
9
+ }
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD,OAAO,EACL,oBAAoB,GAGrB,MAAM,wBAAwB,CAAC;AA6BhC,MAAM,WAAW,GAAG,mBAAmB,CAA0B,aAAa,CAAC,CAAC;AAEhF,MAAM,UAAU,aAAa,CAAC,UAA2B,EAAE;IACzD,OAAO,WAAW,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,UAAyB,EAAE;IACrD,OAAO,WAAW,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC1C,CAAC"}
@@ -0,0 +1,9 @@
1
+ {
2
+ "platforms": ["android", "ios"],
3
+ "android": {
4
+ "modules": ["id.co.onepass.expo.OnepassExpoModule"]
5
+ },
6
+ "ios": {
7
+ "modules": ["OnepassExpoModule"]
8
+ }
9
+ }
@@ -0,0 +1,139 @@
1
+ import UIKit
2
+
3
+ enum OnePassColor {
4
+ static let simascore = UIColor(hex: "#EC1F27")
5
+ static let red500 = UIColor(hex: "#E53E3E")
6
+ static let greenCheckBadge = UIColor(hex: "#52BD94")
7
+ static let orangeWarningBadge = UIColor(hex: "#FF5630")
8
+ static let greenPhotoBorder = UIColor(hex: "#2DB089")
9
+ static let greenSpinner = UIColor(hex: "#48BB78")
10
+ static let gray50 = UIColor(hex: "#F7FAFC")
11
+ static let gray100 = UIColor(hex: "#EDF2F7")
12
+ static let gray200 = UIColor(hex: "#E2E8F0")
13
+ static let gray600 = UIColor(hex: "#4A5568")
14
+ static let gray800 = UIColor(hex: "#1A202C")
15
+ static let shutterBorder = UIColor(hex: "#808080")
16
+
17
+ static let primary500 = UIColor(hex: "#B82025")
18
+ static let primary600 = UIColor(hex: "#931A1E")
19
+ static let primary25 = UIColor(hex: "#FCEEEE")
20
+ static let warning50 = UIColor(hex: "#FFF7E9")
21
+ static let warning400 = UIColor(hex: "#FFC04D")
22
+ static let warning500 = UIColor(hex: "#FFB020")
23
+ static let error50 = UIColor(hex: "#FFEEEE")
24
+ static let error600 = UIColor(hex: "#E84E2C")
25
+ static let neutral100 = UIColor(hex: "#F2F4F7")
26
+ static let tertiary50 = UIColor(hex: "#FCFCFD")
27
+ static let tertiary500 = UIColor(hex: "#667085")
28
+ static let tertiary700 = UIColor(hex: "#334054")
29
+ static let tertiary900 = UIColor(hex: "#101828")
30
+ static let baseBlack = UIColor(hex: "#0A0A0B")
31
+ }
32
+
33
+ enum OnePassFont {
34
+ private static var registered = false
35
+
36
+ static func register() {
37
+ guard !registered else { return }
38
+ registered = true
39
+ ["inter_regular", "inter_medium", "inter_semibold", "inter_bold"].forEach { name in
40
+ guard
41
+ let url = Bundle.onePass.url(forResource: name, withExtension: "ttf"),
42
+ let data = try? Data(contentsOf: url),
43
+ let provider = CGDataProvider(data: data as CFData),
44
+ let font = CGFont(provider)
45
+ else { return }
46
+ CTFontManagerRegisterGraphicsFont(font, nil)
47
+ }
48
+ }
49
+
50
+ static func regular(_ size: CGFloat) -> UIFont { named("Inter-Regular", size, .regular) }
51
+ static func medium(_ size: CGFloat) -> UIFont { named("Inter-Medium", size, .medium) }
52
+ static func semibold(_ size: CGFloat) -> UIFont { named("Inter-SemiBold", size, .semibold) }
53
+ static func bold(_ size: CGFloat) -> UIFont { named("Inter-Bold", size, .bold) }
54
+
55
+ private static func named(_ name: String, _ size: CGFloat, _ weight: UIFont.Weight) -> UIFont {
56
+ register()
57
+ return UIFont(name: name, size: size) ?? .systemFont(ofSize: size, weight: weight)
58
+ }
59
+ }
60
+
61
+ extension Bundle {
62
+ static var onePass: Bundle {
63
+ #if SWIFT_PACKAGE
64
+ return .module
65
+ #else
66
+ let container = Bundle(for: LivenessViewController.self)
67
+ for name in ["OnePassSDK", "OnepassExpo-OnePassSDK"] {
68
+ if
69
+ let url = container.url(forResource: name, withExtension: "bundle"),
70
+ let resourceBundle = Bundle(url: url)
71
+ {
72
+ return resourceBundle
73
+ }
74
+ }
75
+ return container
76
+ #endif
77
+ }
78
+ }
79
+
80
+ extension UIColor {
81
+ convenience init(hex: String) {
82
+ var value = hex.trimmingCharacters(in: .whitespacesAndNewlines)
83
+ if value.hasPrefix("#") { value.removeFirst() }
84
+ var rgb: UInt64 = 0
85
+ Scanner(string: value).scanHexInt64(&rgb)
86
+ let hasAlpha = value.count == 8
87
+ let divisor: CGFloat = 255
88
+ if hasAlpha {
89
+ self.init(
90
+ red: CGFloat((rgb & 0xFF00_0000) >> 24) / divisor,
91
+ green: CGFloat((rgb & 0x00FF_0000) >> 16) / divisor,
92
+ blue: CGFloat((rgb & 0x0000_FF00) >> 8) / divisor,
93
+ alpha: CGFloat(rgb & 0x0000_00FF) / divisor
94
+ )
95
+ } else {
96
+ self.init(
97
+ red: CGFloat((rgb & 0xFF0000) >> 16) / divisor,
98
+ green: CGFloat((rgb & 0x00FF00) >> 8) / divisor,
99
+ blue: CGFloat(rgb & 0x0000FF) / divisor,
100
+ alpha: 1
101
+ )
102
+ }
103
+ }
104
+ }
105
+
106
+ extension UIImage {
107
+ static func onePass(_ name: String) -> UIImage? {
108
+ UIImage(named: name, in: .onePass, compatibleWith: nil)
109
+ }
110
+ }
111
+
112
+ final class OnePassButton: UIButton {
113
+ enum Style {
114
+ case solid(UIColor)
115
+ case outline(border: UIColor, text: UIColor)
116
+ }
117
+
118
+ init(title: String, style: Style, cornerRadius: CGFloat, font: UIFont) {
119
+ super.init(frame: .zero)
120
+ setTitle(title, for: .normal)
121
+ titleLabel?.font = font
122
+ layer.cornerRadius = cornerRadius
123
+ layer.masksToBounds = true
124
+ contentEdgeInsets = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16)
125
+ switch style {
126
+ case .solid(let color):
127
+ backgroundColor = color
128
+ setTitleColor(.white, for: .normal)
129
+ case .outline(let border, let text):
130
+ backgroundColor = .white
131
+ layer.borderWidth = 1
132
+ layer.borderColor = border.cgColor
133
+ setTitleColor(text, for: .normal)
134
+ }
135
+ }
136
+
137
+ @available(*, unavailable)
138
+ required init?(coder: NSCoder) { fatalError("tidak dipakai") }
139
+ }
@@ -0,0 +1,54 @@
1
+ import UIKit
2
+
3
+ final class IconView: UIView {
4
+
5
+ private static let viewportSize: CGFloat = 24
6
+
7
+ private let shape = CAShapeLayer()
8
+ private let segments: [IconSegment]
9
+
10
+ init(segments: [IconSegment], size: CGFloat, color: UIColor) {
11
+ self.segments = segments
12
+ super.init(frame: CGRect(x: 0, y: 0, width: size, height: size))
13
+ backgroundColor = .clear
14
+ shape.fillColor = color.cgColor
15
+ shape.fillRule = .nonZero
16
+ layer.addSublayer(shape)
17
+ translatesAutoresizingMaskIntoConstraints = false
18
+ NSLayoutConstraint.activate([
19
+ widthAnchor.constraint(equalToConstant: size),
20
+ heightAnchor.constraint(equalToConstant: size),
21
+ ])
22
+ }
23
+
24
+ @available(*, unavailable)
25
+ required init?(coder: NSCoder) { fatalError("tidak dipakai") }
26
+
27
+ var color: UIColor = .white {
28
+ didSet { shape.fillColor = color.cgColor }
29
+ }
30
+
31
+ override func layoutSubviews() {
32
+ super.layoutSubviews()
33
+ shape.frame = bounds
34
+ let scale = min(bounds.width, bounds.height) / Self.viewportSize
35
+ let path = CGMutablePath()
36
+ for segment in segments {
37
+ switch segment {
38
+ case .move(let x, let y):
39
+ path.move(to: CGPoint(x: x * scale, y: y * scale))
40
+ case .line(let x, let y):
41
+ path.addLine(to: CGPoint(x: x * scale, y: y * scale))
42
+ case .curve(let x1, let y1, let x2, let y2, let x, let y):
43
+ path.addCurve(
44
+ to: CGPoint(x: x * scale, y: y * scale),
45
+ control1: CGPoint(x: x1 * scale, y: y1 * scale),
46
+ control2: CGPoint(x: x2 * scale, y: y2 * scale)
47
+ )
48
+ case .close:
49
+ path.closeSubpath()
50
+ }
51
+ }
52
+ shape.path = path
53
+ }
54
+ }