react-native-usesense 1.0.0 → 2.0.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.
- package/README.md +267 -373
- package/android/build.gradle +7 -2
- package/android/src/main/java/com/usesense/reactnative/UseSenseModule.kt +6 -1
- package/ios/UseSenseModule.swift +223 -88
- package/lib/commonjs/index.js +122 -101
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/index.js +123 -102
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/src/index.d.ts +157 -141
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/react-native-usesense.podspec +9 -3
- package/src/index.ts +222 -164
package/lib/commonjs/index.js
CHANGED
|
@@ -5,173 +5,194 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = exports.UseSense = void 0;
|
|
7
7
|
var _reactNative = require("react-native");
|
|
8
|
-
const {
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const LINKING_ERROR = `react-native-usesense: the native module could not be found.\n\n` + _reactNative.Platform.select({
|
|
9
|
+
ios: `iOS: run \`cd ios && pod install\` and rebuild the app.`,
|
|
10
|
+
android: `Android: rebuild the app after installing the package.`,
|
|
11
|
+
default: ''
|
|
12
|
+
}) + `\n\nIf you're using Expo, the plugin must be consumed through a development build; it does not support Expo Go because it wraps a native camera SDK.`;
|
|
13
|
+
const UseSenseModule = _reactNative.NativeModules.UseSenseModule;
|
|
11
14
|
if (!UseSenseModule) {
|
|
12
|
-
throw new Error(
|
|
15
|
+
throw new Error(LINKING_ERROR);
|
|
13
16
|
}
|
|
14
17
|
|
|
15
|
-
// ─── Types
|
|
18
|
+
// ─── Types ───────────────────────────────────────────────────────────────
|
|
16
19
|
|
|
17
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Target environment for the UseSense API. `auto` asks the native SDK
|
|
22
|
+
* to detect from the API key prefix (`sk_sandbox_*` → sandbox,
|
|
23
|
+
* `sk_prod_*` → production).
|
|
24
|
+
*/
|
|
18
25
|
|
|
19
|
-
/**
|
|
26
|
+
/** Type of verification session. */
|
|
20
27
|
|
|
21
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Decision returned by the native SDK.
|
|
30
|
+
*
|
|
31
|
+
* These values come straight from the server's verdict and are
|
|
32
|
+
* exposed to the integrator for UI feedback only. The definitive
|
|
33
|
+
* verdict arrives at your backend via an HMAC-signed webhook; never
|
|
34
|
+
* trust the client-side decision for access-control.
|
|
35
|
+
*/
|
|
22
36
|
|
|
23
|
-
/**
|
|
37
|
+
/**
|
|
38
|
+
* Branding overrides applied to the native camera UI.
|
|
39
|
+
*
|
|
40
|
+
* - `logoUrl`, `primaryColor`, `buttonRadius`, `fontFamily` are
|
|
41
|
+
* honoured on both iOS and Android.
|
|
42
|
+
* - `displayName`, `redirectUrl` are Android-only fields. They're
|
|
43
|
+
* accepted on iOS for cross-platform API parity but ignored.
|
|
44
|
+
*/
|
|
24
45
|
|
|
25
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Configuration for `UseSense.initialize`. The minimum required
|
|
48
|
+
* field is the API key; every other field has a sensible default.
|
|
49
|
+
*/
|
|
26
50
|
|
|
27
51
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```ts
|
|
32
|
-
* await UseSense.initialize({
|
|
33
|
-
* apiKey: 'your_api_key',
|
|
34
|
-
* environment: 'sandbox',
|
|
35
|
-
* });
|
|
36
|
-
* ```
|
|
52
|
+
* Request to start a verification session.
|
|
37
53
|
*/
|
|
38
54
|
|
|
39
55
|
/**
|
|
40
|
-
*
|
|
56
|
+
* Redacted decision object returned when a session completes.
|
|
41
57
|
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
58
|
+
* This is the ONLY shape the plugin exposes to React Native. Pillar
|
|
59
|
+
* scores (channel trust, liveness, matchsense risk) are intentionally
|
|
60
|
+
* not included — the native SDKs strip those fields before returning
|
|
61
|
+
* across the bridge to prevent reverse-engineering of the server-side
|
|
62
|
+
* scoring logic. If you need full scoring details, consume the signed
|
|
63
|
+
* webhook delivered to your backend.
|
|
44
64
|
*/
|
|
45
65
|
|
|
46
66
|
/**
|
|
47
|
-
* Error
|
|
67
|
+
* Error thrown when a verification session fails.
|
|
68
|
+
*
|
|
69
|
+
* Matches the native SDKs' error shape: machine-readable code,
|
|
70
|
+
* human-readable message, retry hint.
|
|
48
71
|
*/
|
|
49
72
|
|
|
50
73
|
/**
|
|
51
|
-
*
|
|
74
|
+
* Lifecycle event types emitted by the native SDK during a
|
|
75
|
+
* verification session.
|
|
52
76
|
*/
|
|
53
77
|
|
|
54
|
-
/**
|
|
55
|
-
|
|
56
|
-
/** Status of a verification session. */
|
|
78
|
+
/** Single event emitted during a session. */
|
|
57
79
|
|
|
58
|
-
/**
|
|
80
|
+
/** Handle returned by `UseSense.addListener`. */
|
|
59
81
|
|
|
60
|
-
// ─── Implementation
|
|
82
|
+
// ─── Implementation ──────────────────────────────────────────────────────
|
|
61
83
|
|
|
62
84
|
const eventEmitter = new _reactNative.NativeEventEmitter(UseSenseModule);
|
|
63
85
|
|
|
64
86
|
/**
|
|
65
87
|
* UseSense React Native plugin.
|
|
66
88
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
89
|
+
* Human presence verification wrapping the native iOS and Android
|
|
90
|
+
* UseSense SDKs. Every session runs inside a full-screen native
|
|
91
|
+
* camera activity; the plugin is a thin bridge that forwards
|
|
92
|
+
* initialization, verification requests, and lifecycle events to
|
|
93
|
+
* the platform SDK and returns a redacted decision object.
|
|
69
94
|
*
|
|
70
95
|
* @example
|
|
71
96
|
* ```ts
|
|
72
97
|
* import { UseSense } from 'react-native-usesense';
|
|
73
98
|
*
|
|
74
|
-
* await UseSense.initialize({
|
|
75
|
-
*
|
|
76
|
-
*
|
|
99
|
+
* await UseSense.initialize({
|
|
100
|
+
* apiKey: 'sk_sandbox_...',
|
|
101
|
+
* environment: 'sandbox',
|
|
102
|
+
* });
|
|
103
|
+
*
|
|
104
|
+
* const unsubscribe = UseSense.addListener((event) => {
|
|
105
|
+
* console.log(event.type, event.data);
|
|
106
|
+
* });
|
|
107
|
+
*
|
|
108
|
+
* try {
|
|
109
|
+
* const result = await UseSense.startVerification({
|
|
110
|
+
* sessionType: 'enrollment',
|
|
111
|
+
* });
|
|
112
|
+
* console.log(result.decision); // 'APPROVE' | 'REJECT' | 'MANUAL_REVIEW'
|
|
113
|
+
* } finally {
|
|
114
|
+
* unsubscribe.remove();
|
|
115
|
+
* }
|
|
77
116
|
* ```
|
|
78
117
|
*/
|
|
79
118
|
class UseSense {
|
|
80
119
|
/**
|
|
81
|
-
* Initialize the UseSense plugin. Must be called
|
|
120
|
+
* Initialize the UseSense plugin. Must be called before any other
|
|
121
|
+
* method. Calling again with a different API key or environment
|
|
122
|
+
* replaces the previous configuration.
|
|
82
123
|
*
|
|
83
|
-
* @
|
|
84
|
-
*
|
|
124
|
+
* @throws {UseSenseError} If the API key is empty or initialization
|
|
125
|
+
* fails on the native side.
|
|
85
126
|
*/
|
|
86
127
|
static async initialize(config) {
|
|
87
128
|
if (!config.apiKey) {
|
|
88
|
-
|
|
129
|
+
const err = {
|
|
89
130
|
code: 'invalid_config',
|
|
90
|
-
message: 'apiKey is required'
|
|
131
|
+
message: 'apiKey is required',
|
|
132
|
+
isRetryable: false
|
|
91
133
|
};
|
|
134
|
+
throw err;
|
|
92
135
|
}
|
|
93
136
|
return UseSenseModule.initialize({
|
|
94
137
|
apiKey: config.apiKey,
|
|
95
|
-
environment: config.environment ?? '
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
identityId: config.identityId,
|
|
99
|
-
challengePolicy: config.challengePolicy ?? 'standard',
|
|
100
|
-
enableAudio: config.enableAudio ?? false,
|
|
101
|
-
timeout: config.timeout ?? 60000,
|
|
102
|
-
metadata: config.metadata
|
|
138
|
+
environment: config.environment ?? 'auto',
|
|
139
|
+
apiEndpoint: config.apiEndpoint,
|
|
140
|
+
branding: config.branding
|
|
103
141
|
});
|
|
104
142
|
}
|
|
105
143
|
|
|
106
144
|
/**
|
|
107
|
-
* Start a verification session. Presents a full-screen native
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
* @param options - Optional overrides for session type and identity ID.
|
|
113
|
-
* @returns The verification result (for UI feedback only).
|
|
114
|
-
* @throws {UseSenseError} On failure or cancellation.
|
|
145
|
+
* Start a verification session. Presents a full-screen native
|
|
146
|
+
* camera activity. The returned promise resolves when the session
|
|
147
|
+
* completes or rejects with a `UseSenseError` (including the
|
|
148
|
+
* `USER_CANCELLED` / `session_cancelled` cases when the user
|
|
149
|
+
* dismisses the camera screen).
|
|
115
150
|
*/
|
|
116
|
-
static async
|
|
117
|
-
return UseSenseModule.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
* The camera UI is dismissed and the `startSession` promise rejects
|
|
124
|
-
* with a `session_cancelled` error.
|
|
125
|
-
*/
|
|
126
|
-
static async cancelSession() {
|
|
127
|
-
return UseSenseModule.cancelSession();
|
|
151
|
+
static async startVerification(request) {
|
|
152
|
+
return UseSenseModule.startVerification({
|
|
153
|
+
sessionType: request.sessionType,
|
|
154
|
+
externalUserId: request.externalUserId,
|
|
155
|
+
identityId: request.identityId,
|
|
156
|
+
metadata: request.metadata
|
|
157
|
+
});
|
|
128
158
|
}
|
|
129
159
|
|
|
130
160
|
/**
|
|
131
|
-
*
|
|
161
|
+
* Subscribe to real-time lifecycle events emitted by the native
|
|
162
|
+
* SDK during a verification session. Call this **before**
|
|
163
|
+
* `startVerification` so the subscription captures the earliest
|
|
164
|
+
* events (`SESSION_CREATED`, `PERMISSIONS_REQUESTED`).
|
|
132
165
|
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
166
|
+
* Returns a subscription handle; call `.remove()` to stop
|
|
167
|
+
* receiving events.
|
|
135
168
|
*/
|
|
136
|
-
static
|
|
137
|
-
|
|
169
|
+
static addListener(callback) {
|
|
170
|
+
const subscription = eventEmitter.addListener('UseSenseEvent', raw => {
|
|
171
|
+
callback(raw);
|
|
172
|
+
});
|
|
173
|
+
return {
|
|
174
|
+
remove: () => subscription.remove()
|
|
175
|
+
};
|
|
138
176
|
}
|
|
139
177
|
|
|
140
178
|
/**
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
*
|
|
145
|
-
* @param callback - Function invoked for each event.
|
|
146
|
-
* @returns A subscription handle with a `remove()` method.
|
|
147
|
-
*
|
|
148
|
-
* @example
|
|
149
|
-
* ```ts
|
|
150
|
-
* const listener = UseSense.addListener((event) => {
|
|
151
|
-
* console.log(event.type);
|
|
152
|
-
* });
|
|
153
|
-
* // Later:
|
|
154
|
-
* listener.remove();
|
|
155
|
-
* ```
|
|
179
|
+
* Clear all event listeners and release native resources. Does not
|
|
180
|
+
* need to be called explicitly during normal usage; the plugin
|
|
181
|
+
* cleans up on process teardown. Useful when you want to re-
|
|
182
|
+
* initialize against a different API key or during test teardown.
|
|
156
183
|
*/
|
|
157
|
-
static
|
|
158
|
-
UseSenseModule.
|
|
159
|
-
const subscription = eventEmitter.addListener('UseSenseEvent', callback);
|
|
160
|
-
return {
|
|
161
|
-
remove: () => {
|
|
162
|
-
subscription.remove();
|
|
163
|
-
UseSenseModule.unsubscribeFromEvents();
|
|
164
|
-
}
|
|
165
|
-
};
|
|
184
|
+
static async reset() {
|
|
185
|
+
return UseSenseModule.reset();
|
|
166
186
|
}
|
|
167
187
|
|
|
168
188
|
/**
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
189
|
+
* Whether the native plugin has an active `UseSense` client. Set
|
|
190
|
+
* to `true` after a successful `initialize` and `false` after
|
|
191
|
+
* `reset`. Useful for feature-flagging UI that should only show
|
|
192
|
+
* when the SDK is ready.
|
|
172
193
|
*/
|
|
173
|
-
static
|
|
174
|
-
return UseSenseModule.
|
|
194
|
+
static async isInitialized() {
|
|
195
|
+
return UseSenseModule.isInitialized();
|
|
175
196
|
}
|
|
176
197
|
}
|
|
177
198
|
exports.UseSense = UseSense;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_reactNative","require","UseSenseModule","NativeModules","Error","eventEmitter","NativeEventEmitter","UseSense","initialize","config","apiKey","
|
|
1
|
+
{"version":3,"names":["_reactNative","require","LINKING_ERROR","Platform","select","ios","android","default","UseSenseModule","NativeModules","Error","eventEmitter","NativeEventEmitter","UseSense","initialize","config","apiKey","err","code","message","isRetryable","environment","apiEndpoint","branding","startVerification","request","sessionType","externalUserId","identityId","metadata","addListener","callback","subscription","raw","remove","reset","isInitialized","exports","_default"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1,171 +1,192 @@
|
|
|
1
|
-
import { NativeModules, NativeEventEmitter } from 'react-native';
|
|
2
|
-
const {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
|
|
2
|
+
const LINKING_ERROR = `react-native-usesense: the native module could not be found.\n\n` + Platform.select({
|
|
3
|
+
ios: `iOS: run \`cd ios && pod install\` and rebuild the app.`,
|
|
4
|
+
android: `Android: rebuild the app after installing the package.`,
|
|
5
|
+
default: ''
|
|
6
|
+
}) + `\n\nIf you're using Expo, the plugin must be consumed through a development build; it does not support Expo Go because it wraps a native camera SDK.`;
|
|
7
|
+
const UseSenseModule = NativeModules.UseSenseModule;
|
|
5
8
|
if (!UseSenseModule) {
|
|
6
|
-
throw new Error(
|
|
9
|
+
throw new Error(LINKING_ERROR);
|
|
7
10
|
}
|
|
8
11
|
|
|
9
|
-
// ─── Types
|
|
12
|
+
// ─── Types ───────────────────────────────────────────────────────────────
|
|
10
13
|
|
|
11
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Target environment for the UseSense API. `auto` asks the native SDK
|
|
16
|
+
* to detect from the API key prefix (`sk_sandbox_*` → sandbox,
|
|
17
|
+
* `sk_prod_*` → production).
|
|
18
|
+
*/
|
|
12
19
|
|
|
13
|
-
/**
|
|
20
|
+
/** Type of verification session. */
|
|
14
21
|
|
|
15
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Decision returned by the native SDK.
|
|
24
|
+
*
|
|
25
|
+
* These values come straight from the server's verdict and are
|
|
26
|
+
* exposed to the integrator for UI feedback only. The definitive
|
|
27
|
+
* verdict arrives at your backend via an HMAC-signed webhook; never
|
|
28
|
+
* trust the client-side decision for access-control.
|
|
29
|
+
*/
|
|
16
30
|
|
|
17
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* Branding overrides applied to the native camera UI.
|
|
33
|
+
*
|
|
34
|
+
* - `logoUrl`, `primaryColor`, `buttonRadius`, `fontFamily` are
|
|
35
|
+
* honoured on both iOS and Android.
|
|
36
|
+
* - `displayName`, `redirectUrl` are Android-only fields. They're
|
|
37
|
+
* accepted on iOS for cross-platform API parity but ignored.
|
|
38
|
+
*/
|
|
18
39
|
|
|
19
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Configuration for `UseSense.initialize`. The minimum required
|
|
42
|
+
* field is the API key; every other field has a sensible default.
|
|
43
|
+
*/
|
|
20
44
|
|
|
21
45
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* ```ts
|
|
26
|
-
* await UseSense.initialize({
|
|
27
|
-
* apiKey: 'your_api_key',
|
|
28
|
-
* environment: 'sandbox',
|
|
29
|
-
* });
|
|
30
|
-
* ```
|
|
46
|
+
* Request to start a verification session.
|
|
31
47
|
*/
|
|
32
48
|
|
|
33
49
|
/**
|
|
34
|
-
*
|
|
50
|
+
* Redacted decision object returned when a session completes.
|
|
35
51
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
52
|
+
* This is the ONLY shape the plugin exposes to React Native. Pillar
|
|
53
|
+
* scores (channel trust, liveness, matchsense risk) are intentionally
|
|
54
|
+
* not included — the native SDKs strip those fields before returning
|
|
55
|
+
* across the bridge to prevent reverse-engineering of the server-side
|
|
56
|
+
* scoring logic. If you need full scoring details, consume the signed
|
|
57
|
+
* webhook delivered to your backend.
|
|
38
58
|
*/
|
|
39
59
|
|
|
40
60
|
/**
|
|
41
|
-
* Error
|
|
61
|
+
* Error thrown when a verification session fails.
|
|
62
|
+
*
|
|
63
|
+
* Matches the native SDKs' error shape: machine-readable code,
|
|
64
|
+
* human-readable message, retry hint.
|
|
42
65
|
*/
|
|
43
66
|
|
|
44
67
|
/**
|
|
45
|
-
*
|
|
68
|
+
* Lifecycle event types emitted by the native SDK during a
|
|
69
|
+
* verification session.
|
|
46
70
|
*/
|
|
47
71
|
|
|
48
|
-
/**
|
|
49
|
-
|
|
50
|
-
/** Status of a verification session. */
|
|
72
|
+
/** Single event emitted during a session. */
|
|
51
73
|
|
|
52
|
-
/**
|
|
74
|
+
/** Handle returned by `UseSense.addListener`. */
|
|
53
75
|
|
|
54
|
-
// ─── Implementation
|
|
76
|
+
// ─── Implementation ──────────────────────────────────────────────────────
|
|
55
77
|
|
|
56
78
|
const eventEmitter = new NativeEventEmitter(UseSenseModule);
|
|
57
79
|
|
|
58
80
|
/**
|
|
59
81
|
* UseSense React Native plugin.
|
|
60
82
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
83
|
+
* Human presence verification wrapping the native iOS and Android
|
|
84
|
+
* UseSense SDKs. Every session runs inside a full-screen native
|
|
85
|
+
* camera activity; the plugin is a thin bridge that forwards
|
|
86
|
+
* initialization, verification requests, and lifecycle events to
|
|
87
|
+
* the platform SDK and returns a redacted decision object.
|
|
63
88
|
*
|
|
64
89
|
* @example
|
|
65
90
|
* ```ts
|
|
66
91
|
* import { UseSense } from 'react-native-usesense';
|
|
67
92
|
*
|
|
68
|
-
* await UseSense.initialize({
|
|
69
|
-
*
|
|
70
|
-
*
|
|
93
|
+
* await UseSense.initialize({
|
|
94
|
+
* apiKey: 'sk_sandbox_...',
|
|
95
|
+
* environment: 'sandbox',
|
|
96
|
+
* });
|
|
97
|
+
*
|
|
98
|
+
* const unsubscribe = UseSense.addListener((event) => {
|
|
99
|
+
* console.log(event.type, event.data);
|
|
100
|
+
* });
|
|
101
|
+
*
|
|
102
|
+
* try {
|
|
103
|
+
* const result = await UseSense.startVerification({
|
|
104
|
+
* sessionType: 'enrollment',
|
|
105
|
+
* });
|
|
106
|
+
* console.log(result.decision); // 'APPROVE' | 'REJECT' | 'MANUAL_REVIEW'
|
|
107
|
+
* } finally {
|
|
108
|
+
* unsubscribe.remove();
|
|
109
|
+
* }
|
|
71
110
|
* ```
|
|
72
111
|
*/
|
|
73
112
|
export class UseSense {
|
|
74
113
|
/**
|
|
75
|
-
* Initialize the UseSense plugin. Must be called
|
|
114
|
+
* Initialize the UseSense plugin. Must be called before any other
|
|
115
|
+
* method. Calling again with a different API key or environment
|
|
116
|
+
* replaces the previous configuration.
|
|
76
117
|
*
|
|
77
|
-
* @
|
|
78
|
-
*
|
|
118
|
+
* @throws {UseSenseError} If the API key is empty or initialization
|
|
119
|
+
* fails on the native side.
|
|
79
120
|
*/
|
|
80
121
|
static async initialize(config) {
|
|
81
122
|
if (!config.apiKey) {
|
|
82
|
-
|
|
123
|
+
const err = {
|
|
83
124
|
code: 'invalid_config',
|
|
84
|
-
message: 'apiKey is required'
|
|
125
|
+
message: 'apiKey is required',
|
|
126
|
+
isRetryable: false
|
|
85
127
|
};
|
|
128
|
+
throw err;
|
|
86
129
|
}
|
|
87
130
|
return UseSenseModule.initialize({
|
|
88
131
|
apiKey: config.apiKey,
|
|
89
|
-
environment: config.environment ?? '
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
identityId: config.identityId,
|
|
93
|
-
challengePolicy: config.challengePolicy ?? 'standard',
|
|
94
|
-
enableAudio: config.enableAudio ?? false,
|
|
95
|
-
timeout: config.timeout ?? 60000,
|
|
96
|
-
metadata: config.metadata
|
|
132
|
+
environment: config.environment ?? 'auto',
|
|
133
|
+
apiEndpoint: config.apiEndpoint,
|
|
134
|
+
branding: config.branding
|
|
97
135
|
});
|
|
98
136
|
}
|
|
99
137
|
|
|
100
138
|
/**
|
|
101
|
-
* Start a verification session. Presents a full-screen native
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
* @param options - Optional overrides for session type and identity ID.
|
|
107
|
-
* @returns The verification result (for UI feedback only).
|
|
108
|
-
* @throws {UseSenseError} On failure or cancellation.
|
|
139
|
+
* Start a verification session. Presents a full-screen native
|
|
140
|
+
* camera activity. The returned promise resolves when the session
|
|
141
|
+
* completes or rejects with a `UseSenseError` (including the
|
|
142
|
+
* `USER_CANCELLED` / `session_cancelled` cases when the user
|
|
143
|
+
* dismisses the camera screen).
|
|
109
144
|
*/
|
|
110
|
-
static async
|
|
111
|
-
return UseSenseModule.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
* The camera UI is dismissed and the `startSession` promise rejects
|
|
118
|
-
* with a `session_cancelled` error.
|
|
119
|
-
*/
|
|
120
|
-
static async cancelSession() {
|
|
121
|
-
return UseSenseModule.cancelSession();
|
|
145
|
+
static async startVerification(request) {
|
|
146
|
+
return UseSenseModule.startVerification({
|
|
147
|
+
sessionType: request.sessionType,
|
|
148
|
+
externalUserId: request.externalUserId,
|
|
149
|
+
identityId: request.identityId,
|
|
150
|
+
metadata: request.metadata
|
|
151
|
+
});
|
|
122
152
|
}
|
|
123
153
|
|
|
124
154
|
/**
|
|
125
|
-
*
|
|
155
|
+
* Subscribe to real-time lifecycle events emitted by the native
|
|
156
|
+
* SDK during a verification session. Call this **before**
|
|
157
|
+
* `startVerification` so the subscription captures the earliest
|
|
158
|
+
* events (`SESSION_CREATED`, `PERMISSIONS_REQUESTED`).
|
|
126
159
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
160
|
+
* Returns a subscription handle; call `.remove()` to stop
|
|
161
|
+
* receiving events.
|
|
129
162
|
*/
|
|
130
|
-
static
|
|
131
|
-
|
|
163
|
+
static addListener(callback) {
|
|
164
|
+
const subscription = eventEmitter.addListener('UseSenseEvent', raw => {
|
|
165
|
+
callback(raw);
|
|
166
|
+
});
|
|
167
|
+
return {
|
|
168
|
+
remove: () => subscription.remove()
|
|
169
|
+
};
|
|
132
170
|
}
|
|
133
171
|
|
|
134
172
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* @param callback - Function invoked for each event.
|
|
140
|
-
* @returns A subscription handle with a `remove()` method.
|
|
141
|
-
*
|
|
142
|
-
* @example
|
|
143
|
-
* ```ts
|
|
144
|
-
* const listener = UseSense.addListener((event) => {
|
|
145
|
-
* console.log(event.type);
|
|
146
|
-
* });
|
|
147
|
-
* // Later:
|
|
148
|
-
* listener.remove();
|
|
149
|
-
* ```
|
|
173
|
+
* Clear all event listeners and release native resources. Does not
|
|
174
|
+
* need to be called explicitly during normal usage; the plugin
|
|
175
|
+
* cleans up on process teardown. Useful when you want to re-
|
|
176
|
+
* initialize against a different API key or during test teardown.
|
|
150
177
|
*/
|
|
151
|
-
static
|
|
152
|
-
UseSenseModule.
|
|
153
|
-
const subscription = eventEmitter.addListener('UseSenseEvent', callback);
|
|
154
|
-
return {
|
|
155
|
-
remove: () => {
|
|
156
|
-
subscription.remove();
|
|
157
|
-
UseSenseModule.unsubscribeFromEvents();
|
|
158
|
-
}
|
|
159
|
-
};
|
|
178
|
+
static async reset() {
|
|
179
|
+
return UseSenseModule.reset();
|
|
160
180
|
}
|
|
161
181
|
|
|
162
182
|
/**
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
183
|
+
* Whether the native plugin has an active `UseSense` client. Set
|
|
184
|
+
* to `true` after a successful `initialize` and `false` after
|
|
185
|
+
* `reset`. Useful for feature-flagging UI that should only show
|
|
186
|
+
* when the SDK is ready.
|
|
166
187
|
*/
|
|
167
|
-
static
|
|
168
|
-
return UseSenseModule.
|
|
188
|
+
static async isInitialized() {
|
|
189
|
+
return UseSenseModule.isInitialized();
|
|
169
190
|
}
|
|
170
191
|
}
|
|
171
192
|
export default UseSense;
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NativeModules","NativeEventEmitter","UseSenseModule","Error","eventEmitter","UseSense","initialize","config","apiKey","
|
|
1
|
+
{"version":3,"names":["NativeModules","NativeEventEmitter","Platform","LINKING_ERROR","select","ios","android","default","UseSenseModule","Error","eventEmitter","UseSense","initialize","config","apiKey","err","code","message","isRetryable","environment","apiEndpoint","branding","startVerification","request","sessionType","externalUserId","identityId","metadata","addListener","callback","subscription","raw","remove","reset","isInitialized"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|