@regulaforensics/idv 3.2.1-nightly

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 (140) hide show
  1. package/README.md +30 -0
  2. package/RNIDV.podspec +21 -0
  3. package/android/CVDIDV.kt +48 -0
  4. package/android/build.gradle +32 -0
  5. package/android/cordova.gradle +20 -0
  6. package/android/src/main/java/com/regula/plugin/idv/JSONConstructor.kt +135 -0
  7. package/android/src/main/java/com/regula/plugin/idv/Main.kt +124 -0
  8. package/android/src/main/java/com/regula/plugin/idv/RNIDVModule.kt +71 -0
  9. package/android/src/main/java/com/regula/plugin/idv/Utils.kt +60 -0
  10. package/examples/capacitor/README.md +15 -0
  11. package/examples/capacitor/android/app/build.gradle +50 -0
  12. package/examples/capacitor/android/app/capacitor.build.gradle +22 -0
  13. package/examples/capacitor/android/app/proguard-rules.pro +21 -0
  14. package/examples/capacitor/android/app/src/main/AndroidManifest.xml +26 -0
  15. package/examples/capacitor/android/app/src/main/assets/Regula/.gitkeep +0 -0
  16. package/examples/capacitor/android/app/src/main/java/com/regula/example/idv/capacitor/MainActivity.java +5 -0
  17. package/examples/capacitor/android/app/src/main/res/drawable/ic_launcher.png +0 -0
  18. package/examples/capacitor/android/app/src/main/res/drawable/ic_launcher_foreground.png +0 -0
  19. package/examples/capacitor/android/app/src/main/res/drawable/ic_launcher_round.png +0 -0
  20. package/examples/capacitor/android/app/src/main/res/drawable/launcher.xml +4 -0
  21. package/examples/capacitor/android/app/src/main/res/drawable/launcher_round.xml +4 -0
  22. package/examples/capacitor/android/app/src/main/res/drawable/splash.png +0 -0
  23. package/examples/capacitor/android/app/src/main/res/layout/activity_main.xml +12 -0
  24. package/examples/capacitor/android/app/src/main/res/values/styles.xml +22 -0
  25. package/examples/capacitor/android/build.gradle +30 -0
  26. package/examples/capacitor/android/capacitor.settings.gradle +15 -0
  27. package/examples/capacitor/android/gradle/wrapper/gradle-wrapper.jar +0 -0
  28. package/examples/capacitor/android/gradle/wrapper/gradle-wrapper.properties +7 -0
  29. package/examples/capacitor/android/gradle.properties +22 -0
  30. package/examples/capacitor/android/gradlew +252 -0
  31. package/examples/capacitor/android/gradlew.bat +94 -0
  32. package/examples/capacitor/android/settings.gradle +5 -0
  33. package/examples/capacitor/android/variables.gradle +16 -0
  34. package/examples/capacitor/index.html +5 -0
  35. package/examples/capacitor/index.tsx +16 -0
  36. package/examples/capacitor/ionic.config.json +7 -0
  37. package/examples/capacitor/ios/App/App/App.entitlements +10 -0
  38. package/examples/capacitor/ios/App/App/AppDelegate.swift +49 -0
  39. package/examples/capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/AppIcon-512@2x.png +0 -0
  40. package/examples/capacitor/ios/App/App/Assets.xcassets/AppIcon.appiconset/Contents.json +14 -0
  41. package/examples/capacitor/ios/App/App/Assets.xcassets/Contents.json +6 -0
  42. package/examples/capacitor/ios/App/App/Assets.xcassets/Splash.imageset/Contents.json +23 -0
  43. package/examples/capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-1.png +0 -0
  44. package/examples/capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732-2.png +0 -0
  45. package/examples/capacitor/ios/App/App/Assets.xcassets/Splash.imageset/splash-2732x2732.png +0 -0
  46. package/examples/capacitor/ios/App/App/Base.lproj/LaunchScreen.storyboard +32 -0
  47. package/examples/capacitor/ios/App/App/Base.lproj/Main.storyboard +19 -0
  48. package/examples/capacitor/ios/App/App/Info.plist +65 -0
  49. package/examples/capacitor/ios/App/App.xcodeproj/project.pbxproj +418 -0
  50. package/examples/capacitor/ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  51. package/examples/capacitor/ios/App/App.xcworkspace/contents.xcworkspacedata +10 -0
  52. package/examples/capacitor/ios/App/App.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  53. package/examples/capacitor/ios/App/Podfile +26 -0
  54. package/examples/capacitor/package-lock.json +3350 -0
  55. package/examples/capacitor/package.json +27 -0
  56. package/examples/capacitor/public/assets/.gitkeep +0 -0
  57. package/examples/capacitor/scripts/android.sh +9 -0
  58. package/examples/capacitor/scripts/ios.sh +8 -0
  59. package/examples/capacitor/scripts/setup.sh +14 -0
  60. package/examples/capacitor/src/main.css +148 -0
  61. package/examples/capacitor/src/main.html +17 -0
  62. package/examples/capacitor/src/main.tsx +124 -0
  63. package/examples/capacitor/tsconfig.json +5 -0
  64. package/examples/capacitor/vite.config.ts +17 -0
  65. package/examples/ionic/README.md +15 -0
  66. package/examples/ionic/angular.json +39 -0
  67. package/examples/ionic/assets/.gitkeep +0 -0
  68. package/examples/ionic/config.xml +60 -0
  69. package/examples/ionic/images/icon.png +0 -0
  70. package/examples/ionic/index.html +19 -0
  71. package/examples/ionic/index.tsx +32 -0
  72. package/examples/ionic/ionic.config.json +7 -0
  73. package/examples/ionic/package-lock.json +14261 -0
  74. package/examples/ionic/package.json +46 -0
  75. package/examples/ionic/scripts/android.sh +8 -0
  76. package/examples/ionic/scripts/ios.sh +8 -0
  77. package/examples/ionic/scripts/setup.sh +8 -0
  78. package/examples/ionic/src/main.css +148 -0
  79. package/examples/ionic/src/main.html +17 -0
  80. package/examples/ionic/src/main.tsx +124 -0
  81. package/examples/ionic/tsconfig.json +14 -0
  82. package/examples/react_native/README.md +15 -0
  83. package/examples/react_native/app.config.ts +46 -0
  84. package/examples/react_native/assets/.gitkeep +0 -0
  85. package/examples/react_native/images/icon.png +0 -0
  86. package/examples/react_native/index.html +12 -0
  87. package/examples/react_native/index.tsx +63 -0
  88. package/examples/react_native/metro.config.js +7 -0
  89. package/examples/react_native/package-lock.json +8996 -0
  90. package/examples/react_native/package.json +29 -0
  91. package/examples/react_native/scripts/android.sh +13 -0
  92. package/examples/react_native/scripts/ios.sh +12 -0
  93. package/examples/react_native/scripts/setup.sh +12 -0
  94. package/examples/react_native/src/main.css +148 -0
  95. package/examples/react_native/src/main.html +17 -0
  96. package/examples/react_native/src/main.tsx +124 -0
  97. package/ios/CVDIDV.swift +51 -0
  98. package/ios/JSONConstructor.swift +132 -0
  99. package/ios/Main.swift +91 -0
  100. package/ios/RNIDV.m +11 -0
  101. package/ios/RNIDV.swift +47 -0
  102. package/ios/Utils.swift +52 -0
  103. package/package.json +38 -0
  104. package/plugin.xml +46 -0
  105. package/test/json.tsx +40 -0
  106. package/test/package-lock.json +584 -0
  107. package/test/package.json +9 -0
  108. package/test/test.tsx +13 -0
  109. package/test/utils.tsx +38 -0
  110. package/www/capacitor/config/api_key_connection_config.js +32 -0
  111. package/www/capacitor/config/credentials_connection_config.js +32 -0
  112. package/www/capacitor/config/prepare_workflow_config.js +20 -0
  113. package/www/capacitor/config/start_workflow_config.js +24 -0
  114. package/www/capacitor/config/token_connection_config.js +20 -0
  115. package/www/capacitor/index.js +110 -0
  116. package/www/capacitor/internal/bridge.js +30 -0
  117. package/www/capacitor/internal/cordova.js +17 -0
  118. package/www/capacitor/model/workflow.js +28 -0
  119. package/www/capacitor/model/workflow_result.js +21 -0
  120. package/www/capacitor/model/workflow_step.js +19 -0
  121. package/www/cordova.js +595 -0
  122. package/www/react-native/config/api_key_connection_config.js +32 -0
  123. package/www/react-native/config/credentials_connection_config.js +32 -0
  124. package/www/react-native/config/prepare_workflow_config.js +20 -0
  125. package/www/react-native/config/start_workflow_config.js +24 -0
  126. package/www/react-native/config/token_connection_config.js +20 -0
  127. package/www/react-native/index.js +110 -0
  128. package/www/react-native/internal/bridge.js +30 -0
  129. package/www/react-native/model/workflow.js +28 -0
  130. package/www/react-native/model/workflow_result.js +21 -0
  131. package/www/react-native/model/workflow_step.js +19 -0
  132. package/www/types/config/api_key_connection_config.d.ts +6 -0
  133. package/www/types/config/credentials_connection_config.d.ts +6 -0
  134. package/www/types/config/prepare_workflow_config.d.ts +3 -0
  135. package/www/types/config/start_workflow_config.d.ts +4 -0
  136. package/www/types/config/token_connection_config.d.ts +3 -0
  137. package/www/types/index.d.ts +62 -0
  138. package/www/types/model/workflow.d.ts +9 -0
  139. package/www/types/model/workflow_result.d.ts +8 -0
  140. package/www/types/model/workflow_step.d.ts +6 -0
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "idv",
3
+ "main": "./index.tsx",
4
+ "scripts": {
5
+ "setup": "scripts/setup.sh",
6
+ "ios": "scripts/ios.sh",
7
+ "android": "scripts/android.sh",
8
+ "start": "expo start"
9
+ },
10
+ "dependencies": {
11
+ "@regulaforensics/idv": "3.2.1-nightly",
12
+ "@regulaforensics/document-reader": "8.4.2-nightly",
13
+ "@regulaforensics/face-sdk": "8.1.1-nightly",
14
+ "@regulaforensics/document-reader-core-fullauthrfid": "8.4.7-nightly",
15
+ "@regulaforensics/face-core-basic": "8.1.1-nightly",
16
+ "@regulaforensics/idv-module-document-reader": "file:../ftp_5",
17
+ "@regulaforensics/idv-module-face": "file:../ftp_6",
18
+ "react-native": "^0.81.4",
19
+ "react-native-webview": "^13.16.0",
20
+ "@react-native/metro-config": "^0.81.1",
21
+ "react": "^19.1.1",
22
+ "@types/react": "^19.1.13",
23
+ "expo": "^54.0.7",
24
+ "expo-dev-client": "^6.0.12",
25
+ "expo-custom-assets": "^1.5.0",
26
+ "expo-build-properties": "^1.0.8",
27
+ "typescript": "5.9.2"
28
+ }
29
+ }
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env bash
2
+
3
+ adb reverse tcp:8081 tcp:8081 >/dev/null || :
4
+ if [[ $npm_config_o || $npm_config_open ]]; then
5
+ studio android || open -a 'Android Studio' android
6
+ # check if metro is already running
7
+ if ! pgrep -f "expo start" >/dev/null; then
8
+ watchman shutdown-server # fix potential errors
9
+ npm start
10
+ fi
11
+ else
12
+ expo run:android --device
13
+ fi
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+
3
+ if [[ $npm_config_o || $npm_config_open ]]; then
4
+ open ios/IDV.xcworkspace
5
+ # check if metro is already running
6
+ if ! pgrep -f "expo start" > /dev/null; then
7
+ watchman shutdown-server # fix potential errors
8
+ npm start
9
+ fi
10
+ else
11
+ npx expo run:ios --device
12
+ fi
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+
4
+ npm install
5
+ expo prebuild
6
+
7
+ mkdir -p android/app/src/main/assets/Regula
8
+ mv android/app/src/main/res/raw/regula.license android/app/src/main/assets/Regula/
9
+ mv android/app/src/main/res/raw/db.dat android/app/src/main/assets/Regula/
10
+
11
+ sed -i '' '$a\
12
+ android { buildFeatures { dataBinding true } }' android/app/build.gradle
@@ -0,0 +1,148 @@
1
+ html,
2
+ body {
3
+ margin: 0;
4
+ width: 100%;
5
+ height: 99vh;
6
+ display: flex;
7
+ overflow: hidden;
8
+ flex-direction: column;
9
+ }
10
+
11
+ /* Prevent text selection */
12
+ * {
13
+ user-select: none !important;
14
+ -webkit-user-select: none !important;
15
+ -webkit-user-drag: none !important;
16
+ -webkit-touch-callout: none !important;
17
+ }
18
+
19
+ .column {
20
+ display: flex;
21
+ flex-direction: column;
22
+ align-items: center;
23
+ justify-content: center;
24
+ width: 100%;
25
+ }
26
+
27
+ .row {
28
+ display: flex;
29
+ flex-direction: row;
30
+ align-items: center;
31
+ justify-content: center;
32
+ }
33
+
34
+ .header {
35
+ text-align: center;
36
+ padding-top: 80px;
37
+ margin-top: -10px;
38
+ background-color: rgba(0, 0, 0, 0.03);
39
+ font-weight: 600;
40
+ font-size: 18px;
41
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
42
+ }
43
+
44
+ .sub-header {
45
+ background-color: rgba(0, 0, 0, 0.03);
46
+ width: 100%;
47
+ padding-top: 13px;
48
+ text-align: center;
49
+ font-weight: 550;
50
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
51
+ }
52
+
53
+ .divider {
54
+ height: 1px;
55
+ background-color: rgba(0, 0, 0, 0.075);
56
+ margin-top: 13px;
57
+ }
58
+
59
+ .scroll {
60
+ flex-grow: 1;
61
+ overflow-y: auto;
62
+ }
63
+
64
+ .no-scroll {
65
+ flex-grow: 1;
66
+ overflow-y: hidden;
67
+ }
68
+
69
+ .button {
70
+ width: 175px;
71
+ height: 40px;
72
+ margin: 5px;
73
+ margin-top: 10px;
74
+ background-color: #4285F4;
75
+ color: white;
76
+ border: none;
77
+ padding: 10px 20px;
78
+ justify-content: center;
79
+ font-size: 16px;
80
+ border-radius: 100px;
81
+ cursor: pointer;
82
+ transition: all 0.3s ease;
83
+ user-select: none;
84
+ -webkit-user-select: none;
85
+ -moz-user-select: none;
86
+ -ms-user-select: none;
87
+ }
88
+
89
+ .button:active {
90
+ position: relative;
91
+ top: 1px;
92
+ }
93
+
94
+ .text-button {
95
+ background: none;
96
+ border: none;
97
+ color: #2196f3;
98
+ font-size: 20px;
99
+ font-weight: bold;
100
+ padding: 5px;
101
+ }
102
+
103
+ .text-button:active {
104
+ position: relative;
105
+ top: 1px;
106
+ }
107
+
108
+ .radio {
109
+ align-items: baseline;
110
+ padding: 15px;
111
+ }
112
+
113
+ input[type="checkbox"] {
114
+ width: 20px;
115
+ height: 20px;
116
+ border: 2px solid black;
117
+ background-color: white;
118
+ display: inline-block;
119
+ position: relative;
120
+ cursor: pointer;
121
+ }
122
+
123
+ input[type="text"] {
124
+ width: 173px;
125
+ height: 40px;
126
+ font-size: 15px;
127
+ margin: 5px;
128
+ border-radius: 100px;
129
+ padding-left: 10px;
130
+ padding-right: 10px;
131
+ margin-top: 10px;
132
+ }
133
+
134
+ .progress-bar {
135
+ width: 75%;
136
+ padding: 3px;
137
+ margin-top: 40px;
138
+ background-color: #eee;
139
+ border-radius: 8px;
140
+ box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.2);
141
+ }
142
+
143
+ #progress {
144
+ width: 0%;
145
+ height: 20px;
146
+ background-color: #4285F4;
147
+ border-radius: 5px;
148
+ }
@@ -0,0 +1,17 @@
1
+ <div class="column" style="height: 100%">
2
+ <div class="column header">
3
+ <span id="status">Initializing...</span>
4
+ <div class="column divider"></div>
5
+ </div>
6
+ <div id="sub-header" class="column sub-header" style="display: none;">
7
+ <span id="description"></span>
8
+ <div class="column divider"></div>
9
+ </div>
10
+ <div id="main" class="column no-scroll">
11
+ <div class="column no-scroll" style="padding-top: 15px; background-color: rgba(0, 0, 0, 0.03);">
12
+ <div id="radio-group" class="scroll"></div>
13
+ </div>
14
+ <button id="start-workflow" class="button" style="width: 360px">Start Workflow</button>
15
+ <div style="padding-top: 30px"></div>
16
+ </div>
17
+ </div>
@@ -0,0 +1,124 @@
1
+ import { IDV, Workflow } from '@regulaforensics/idv'
2
+
3
+ enum Configuration { credentials, token, apiKey }
4
+
5
+ const loginType: Configuration = Configuration.credentials
6
+ const baseUrl = "https://idv.regula.app"
7
+ const username = "username_placeholder"
8
+ const password = "password_placeholder"
9
+ const tokenUrl = "token_placeholder"
10
+ const apiKey = "api_key_placeholder"
11
+
12
+ var idv = IDV.instance
13
+ var selectedWorkflow = ""
14
+ var workflowIds: string[] = []
15
+
16
+ async function init() {
17
+ var [_, iError] = await idv.initialize()
18
+ if (handleException(iError, "initialize")) return
19
+
20
+ var success = ({
21
+ [Configuration.credentials]: async () => await configureWithCredentials(),
22
+ [Configuration.token]: async () => await configureWithToken(),
23
+ [Configuration.apiKey]: async () => await configureApiKey(),
24
+ })[loginType]!
25
+ if (!await success()) return
26
+
27
+ var [wfs, error] = await idv.getWorkflows()
28
+ if (handleException(error, "getWorkflows")) return
29
+ if (loginType == Configuration.token) {
30
+ wfs = wfs!.filter((wf: any) => workflowIds.includes(wf.id))
31
+ }
32
+
33
+ setWorkflows(wfs!)
34
+ setStatus("Ready")
35
+ }
36
+
37
+ async function configureWithCredentials(): Promise<boolean> {
38
+ var [success, error] = await idv.configureWithCredentials({
39
+ baseUrl: baseUrl,
40
+ userName: username,
41
+ password: password
42
+ })
43
+ handleException(error, "configureWithCredentials")
44
+ return success
45
+ }
46
+
47
+ async function configureWithToken(): Promise<boolean> {
48
+ var [wfIds, error] = await idv.configureWithToken({ url: tokenUrl })
49
+ if (handleException(error, "configureWithToken")) return false
50
+ workflowIds = wfIds!
51
+ return true
52
+ }
53
+
54
+ async function configureApiKey(): Promise<boolean> {
55
+ var [success, error] = await idv.configureWithApiKey({ baseUrl, apiKey })
56
+ handleException(error, "configureWithApiKey")
57
+ return success
58
+ }
59
+
60
+ async function startWorkflow(): Promise<void> {
61
+ if (selectedWorkflow.length == 0) return
62
+ setStatus("Preparing Workflow...")
63
+
64
+ var [_, prepareError] = await idv.prepareWorkflow({ workflowId: selectedWorkflow })
65
+ if (handleException(prepareError, "prepareWorkflow")) return
66
+
67
+ var [result, error] = await idv.startWorkflow()
68
+ if (handleException(error, "startWorkflow")) return
69
+
70
+ setStatus("Success")
71
+ setDescription(`SessionID: ${result?.sessionId}`)
72
+ }
73
+
74
+ function handleException(error?: string | null, tag?: string): boolean {
75
+ if (error == null) return false
76
+ setStatus(`Error - IDV.${tag}()`)
77
+ setDescription(error)
78
+ console.log(error)
79
+ return true
80
+ }
81
+
82
+ // --------------------------------------------------------------------------------------------------------------------
83
+
84
+ export function main() {
85
+ document.getElementById("start-workflow")!.onclick = () => startWorkflow()
86
+
87
+ init()
88
+ }
89
+
90
+ var setStatus = (data: string) => document.getElementById("status")!.innerHTML = data
91
+ var setDescription = (data: string) => {
92
+ document.getElementById("description")!.innerHTML = data
93
+ document.getElementById("sub-header")!.style.display = data.length > 0 ? "block" : "none"
94
+ }
95
+
96
+ var workflows: Workflow[] = []
97
+ function setWorkflows(data: Workflow[]) {
98
+ var radioGroup = document.getElementById("radio-group")!
99
+ workflows = data
100
+ if (workflows.length != 0) {
101
+ selectedWorkflow = workflows[0].id
102
+ }
103
+
104
+ data.forEach(item => {
105
+ var checked = selectedWorkflow == item.id ? "checked" : ""
106
+ var radioElement = `
107
+ <div class="row radio">
108
+ <input type="radio" name="radio" id="${item.id}" value="${item.id}" ${checked}>
109
+ <span id="${item.id}-caption" style="width: 200px; padding-left: 5px;">${item.name}</span>
110
+ </div>`
111
+ radioGroup.insertAdjacentHTML("beforeend", radioElement)
112
+ })
113
+
114
+ data.forEach(item => {
115
+ var element = document.getElementById(item.id) as HTMLInputElement
116
+ var elementCaption = document.getElementById(item.id + "-caption")!
117
+ var onclick = () => {
118
+ selectedWorkflow = item.id
119
+ element.checked = true
120
+ }
121
+ element.onclick = onclick
122
+ elementCaption.onclick = onclick
123
+ })
124
+ }
@@ -0,0 +1,51 @@
1
+ var eventCallbackIds: [String: String] = [:]
2
+ private var args: [Any?] = []
3
+ private var this: CVDIDV?
4
+
5
+ func sendEvent(_ event: String, _ data: Any? = nil) {
6
+ var callbackId = event
7
+ let eventId = eventCallbackIds[event]
8
+ if eventId != nil { callbackId = eventId! }
9
+
10
+ var sendable = data.toSendable() as Any?
11
+ if sendable is NSNull { sendable = nil }
12
+ let result = CDVPluginResult(status: CDVCommandStatus_OK, messageAs: sendable as! String?)!
13
+ result.setKeepCallbackAs(true)
14
+
15
+ this!.commandDelegate.send(result, callbackId: callbackId)
16
+ }
17
+
18
+ func args<T>(_ index: Int) -> T {
19
+ return args[index] as! T
20
+ }
21
+
22
+ func argsNullable<T>(_ index: Int) -> T? {
23
+ if (args[index] is NSNull) { return nil }
24
+ return args[index] as! T?
25
+ }
26
+
27
+ @objc(CVDIDV)
28
+ class CVDIDV: CDVPlugin {
29
+ @objc(exec:)
30
+ func exec(_ command: CDVInvokedUrlCommand) {
31
+ this = self
32
+ let method = command.arguments.first as! String
33
+ args = Array(command.arguments.dropFirst())
34
+
35
+ if method == "setEvent" {
36
+ eventCallbackIds[args.first as! String] = command.callbackId
37
+ return
38
+ }
39
+
40
+ methodCall(method, { data in sendEvent(command.callbackId, data) })
41
+ }
42
+ }
43
+
44
+ let rootViewController: () -> UIViewController? = {
45
+ for window in UIApplication.shared.windows {
46
+ if window.isKeyWindow {
47
+ return window.rootViewController
48
+ }
49
+ }
50
+ return nil
51
+ }
@@ -0,0 +1,132 @@
1
+ import IDVSDK
2
+ import IDVModule
3
+
4
+ public func generateCompletion(_ value: Any?, _ error: IDVModule.BaseError?) -> [String: Any?] {
5
+ return [
6
+ "success": value,
7
+ "error": error?.fullChain
8
+ ]
9
+ }
10
+
11
+ // MARK: - Config
12
+
13
+ public func credentialsConnectionConfigFromJSON(_ data: [String: Any?]) -> CredentialsConnectionConfig {
14
+ let result = CredentialsConnectionConfig (userName: data["userName"] as! String,
15
+ password: data["password"] as! String,
16
+ baseURL: data["baseUrl"] as! String)
17
+ if let httpTimeoutMs = data["httpTimeoutMs"] as? NSNumber { result.httpTimeoutMs = httpTimeoutMs }
18
+ return result
19
+ }
20
+
21
+ public func generateCredentialsConnectionConfig(_ data: CredentialsConnectionConfig) -> [String: Any?] {
22
+ return [
23
+ "baseUrl": data.baseURL,
24
+ "userName": data.userName,
25
+ "password": data.password,
26
+ "httpTimeoutMs": data.httpTimeoutMs,
27
+ ]
28
+ }
29
+
30
+ public func tokenConnectionConfigFromJSON(_ data: [String: Any?]) -> TokenConnectionConfig {
31
+ return TokenConnectionConfig(url: data["url"] as! String)
32
+ }
33
+
34
+ public func generateTokenConnectionConfig(_ data: TokenConnectionConfig) -> [String: Any?] {
35
+ return [
36
+ "url": data.url
37
+ ]
38
+ }
39
+
40
+ public func apiKeyConnectionConfigFromJSON(_ data: [String: Any?]) -> ApiKeyConnectionConfig {
41
+ let result = ApiKeyConnectionConfig(apiKey: data["apiKey"] as! String,
42
+ baseURL: data["baseUrl"] as! String,
43
+ ttl: data["ttl"] as? NSNumber)
44
+ if let httpTimeoutMs = data["httpTimeoutMs"] as? NSNumber { result.httpTimeoutMs = httpTimeoutMs }
45
+ return result
46
+ }
47
+
48
+ public func generateApiKeyConnectionConfig(_ data: ApiKeyConnectionConfig) -> [String: Any?] {
49
+ return [
50
+ "baseUrl": data.baseURL,
51
+ "apiKey": data.apiKey,
52
+ "ttl": data.ttl,
53
+ "httpTimeoutMs": data.httpTimeoutMs,
54
+ ]
55
+ }
56
+
57
+ public func prepareWorkflowConfigFromJSON(_ data: [String: Any?]) -> PrepareWorkflowConfig {
58
+ return PrepareWorkflowConfig(workflowId: data["workflowId"] as! String)
59
+ }
60
+
61
+ public func generatePrepareWorkflowConfig(_ data: PrepareWorkflowConfig) -> [String: Any?] {
62
+ return [
63
+ "workflowId": data.workflowId
64
+ ]
65
+ }
66
+
67
+ public func startWorkflowConfigFromJSON(input: [String: Any?]?) -> StartWorkflowConfig {
68
+ let result = StartWorkflowConfig.default()
69
+ guard let data = input else { return result }
70
+
71
+ if let locale = data["locale"] as? String { result.locale = locale }
72
+ if let metadata = data["metadata"] as? [String: Any] { result.metadata = metadata }
73
+
74
+ return result
75
+ }
76
+
77
+ public func generateStartWorkflowConfig(_ data: StartWorkflowConfig) -> [String: Any?] {
78
+ return [
79
+ "locale": data.locale,
80
+ "metadata": data.metadata
81
+ ]
82
+ }
83
+
84
+ // MARK: - Model
85
+
86
+ public func workflowFromJSON(_ input: [String: Any?]?) -> Workflow? {
87
+ guard var it = input else { return nil }
88
+ it["client"] = [String: Any]()
89
+ it["steps"] = [WorkflowStep]()
90
+ it["_description"] = it["description"]
91
+ return try! Workflow(from: it.toDecoder())
92
+ }
93
+
94
+ public func generateWorkflow(_ input: Workflow?) -> [String: Any?]? {
95
+ guard let it = input else { return nil }
96
+ return [
97
+ "id": it.id,
98
+ "name": it.name,
99
+ "version": it.version,
100
+ "description": it._description,
101
+ "defaultLocale": it.defaultLocale
102
+ ]
103
+ }
104
+
105
+ public func workflowStepFromJSON(_ input: [String: Any?]?) -> WorkflowStep? {
106
+ guard var it = input else { return nil }
107
+ it["type"] = ""
108
+ it["final"] = false
109
+ it["client"] = [String: Any]()
110
+ return try! WorkflowStep(from: it.toDecoder())
111
+ }
112
+
113
+ public func generateWorkflowStep(_ input: WorkflowStep?) -> [String: Any?]? {
114
+ guard let it = input else { return nil }
115
+ return [
116
+ "id": it.id,
117
+ "name": it.name
118
+ ]
119
+ }
120
+
121
+ public func workflowResultFromJSON(_ input: [String: Any?]?) -> WorkflowResult? {
122
+ guard let it = input else { return nil }
123
+ return try! WorkflowResult(from: it.toDecoder())
124
+ }
125
+
126
+ public func generateWorkflowResult(_ input: WorkflowResult?) -> [String: Any?]? {
127
+ guard let it = input else { return nil }
128
+ return [
129
+ "sessionId": it.sessionId,
130
+ "finalStep": generateWorkflowStep(it.finalStep)
131
+ ]
132
+ }
package/ios/Main.swift ADDED
@@ -0,0 +1,91 @@
1
+ import IDVSDK
2
+
3
+ let didStartSessionEvent = "didStartSessionEvent"
4
+ let didEndSessionEvent = "didEndSessionEvent"
5
+ let didStartRestoreSessionEvent = "didStartRestoreSessionEvent"
6
+ let didContinueRemoteSessionEvent = "didContinueRemoteSessionEvent"
7
+
8
+ func methodCall(_ method: String, _ callback: @escaping Callback) {
9
+ switch (method) {
10
+ case("setSessionRestoreMode"): IDV.shared.sessionRestoreMode = SessionRestoreMode(rawValue: args(0))!
11
+ case("getCurrentSessionId"): callback(IDV.shared.currentSessionId)
12
+ case ("initialize"): initialize(callback)
13
+ case("deinitialize"): deinitialize(callback)
14
+ case("configureWithToken"): configureWithToken(callback, args(0))
15
+ case("configureWithCredentials"): configureWithCredentials(callback, args(0))
16
+ case("configureWithApiKey"): configureWithApiKey(callback, args(0))
17
+ case("prepareWorkflow"): prepareWorkflow(callback, args(0))
18
+ case("startWorkflow"): startWorkflow(callback, argsNullable(0))
19
+ case("getWorkflows"): getWorkflows(callback)
20
+ default: break
21
+ }
22
+ }
23
+
24
+ // MARK: - Implementation
25
+
26
+ func initialize(_ callback: @escaping Callback) {
27
+ DispatchQueue.main.async {
28
+ IDV.shared.initialize(config: IDVInitConfig(), completion: { result in
29
+ IDV.shared.delegate = delegate
30
+ callback(generateCompletion(result.isSuccess, result.failureOrNil))
31
+ })
32
+ }
33
+ }
34
+
35
+ func deinitialize(_ callback: @escaping Callback) {
36
+ IDV.shared.deinitialize(completion: { result in
37
+ callback(generateCompletion(result.isSuccess, result.failureOrNil))
38
+ })
39
+ }
40
+
41
+ func configureWithToken(_ callback: @escaping Callback, _ data: [String: Any?]) {
42
+ IDV.shared.configure(with: tokenConnectionConfigFromJSON(data), completion: { result in
43
+ callback(generateCompletion(result.successOrNil, result.failureOrNil))
44
+ })
45
+ }
46
+
47
+ func configureWithCredentials(_ callback: @escaping Callback, _ data: [String: Any?]) {
48
+ IDV.shared.configure(with: credentialsConnectionConfigFromJSON(data), completion: { result in
49
+ callback(generateCompletion(result.isSuccess, result.failureOrNil))
50
+ })
51
+ }
52
+
53
+ func configureWithApiKey(_ callback: @escaping Callback, _ data: [String: Any?]) {
54
+ IDV.shared.configure(with: apiKeyConnectionConfigFromJSON(data), completion: { result in
55
+ callback(generateCompletion(result.isSuccess, result.failureOrNil))
56
+ })
57
+ }
58
+
59
+ func prepareWorkflow(_ callback: @escaping Callback, _ data: [String: Any?]) {
60
+ IDV.shared.prepareWorkflow(by: prepareWorkflowConfigFromJSON(data), completion: { result in
61
+ callback(generateCompletion(generateWorkflow(result.successOrNil), result.failureOrNil))
62
+ })
63
+ }
64
+
65
+ func startWorkflow(_ callback: @escaping Callback, _ data: [String: Any?]?) {
66
+ DispatchQueue.main.async {
67
+ IDV.shared.startWorkflow(presenter: rootViewController()!,
68
+ config: startWorkflowConfigFromJSON(input: data),
69
+ completion: { result in
70
+ callback(generateCompletion(generateWorkflowResult(result.successOrNil), result.failureOrNil))
71
+ })
72
+ }
73
+ }
74
+
75
+ func getWorkflows(_ callback: @escaping Callback) {
76
+ IDV.shared.getWorkflows(completion: { result in
77
+ callback(generateCompletion(result.successOrNil?.compactMap { generateWorkflow($0) },
78
+ result.failureOrNil))
79
+ })
80
+ }
81
+
82
+
83
+ // MARK: - WeakReference
84
+
85
+ class IDVDelegate: IDVSDK.IDVDelegate {
86
+ func didStartNewSession(idv: IDV) { sendEvent(didStartSessionEvent) }
87
+ func didEndSession(idv: IDV) { sendEvent(didEndSessionEvent) }
88
+ func didStartRestoreSession(idv: IDV) { sendEvent(didStartRestoreSessionEvent) }
89
+ func didContinueRemoteSession(idv: IDV) { sendEvent(didContinueRemoteSessionEvent) }
90
+ }
91
+ let delegate = IDVDelegate()
package/ios/RNIDV.m ADDED
@@ -0,0 +1,11 @@
1
+ #import <React/RCTEventEmitter.h>
2
+ #import <React/RCTBridgeModule.h>
3
+
4
+ @interface RCT_EXTERN_MODULE(RNIDV, RCTEventEmitter)
5
+
6
+ RCT_EXTERN_METHOD(exec: (NSString*)method
7
+ args:(NSArray*)args
8
+ resolve:(RCTPromiseResolveBlock)resolve
9
+ reject:(RCTPromiseRejectBlock)reject)
10
+
11
+ @end
@@ -0,0 +1,47 @@
1
+ import React
2
+
3
+ func sendEvent(_ event: String, _ data: Any? = nil) {
4
+ guard let plugin = this, hasListeners else { return }
5
+ DispatchQueue.main.async {
6
+ plugin.sendEvent(withName: event, body: data.toSendable())
7
+ }
8
+ }
9
+
10
+ func args<T>(_ index: Int) -> T {
11
+ return mArgs[index] as! T
12
+ }
13
+
14
+ func argsNullable<T>(_ index: Int) -> T? {
15
+ if (mArgs[index] is NSNull) { return nil }
16
+ return mArgs[index] as! T?
17
+ }
18
+
19
+ private var firedCallbacks: [RCTResponseSenderBlock] = []
20
+ private var hasListeners: Bool = false
21
+ private var this: RNIDV?
22
+ private var mArgs: [Any?] = []
23
+
24
+ @objc(RNIDV)
25
+ public class RNIDV: RCTEventEmitter {
26
+ override public func startObserving() { hasListeners = true }
27
+ override public func stopObserving() { hasListeners = false }
28
+ override public func supportedEvents()->[String] {
29
+ return [didStartSessionEvent,
30
+ didEndSessionEvent,
31
+ didStartRestoreSessionEvent,
32
+ didContinueRemoteSessionEvent];
33
+ }
34
+
35
+ @objc
36
+ func exec(_ method: String, args: [Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
37
+ this = self
38
+ mArgs = args
39
+ methodCall(method, { data in
40
+ if firedCallbacks.contains(where: { ($0 as AnyObject) === (resolve as AnyObject) }) { return }
41
+ firedCallbacks.append(resolve)
42
+ resolve(data.toSendable())
43
+ })
44
+ }
45
+ }
46
+
47
+ let rootViewController: () -> UIViewController? = { return RCTPresentedViewController() }