@encatch/react-native-sdk 1.0.0-beta.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/LICENSE +21 -0
- package/README.md +204 -0
- package/dist/index.d.mts +409 -0
- package/dist/index.d.ts +409 -0
- package/dist/index.js +1910 -0
- package/dist/index.mjs +1906 -0
- package/package.json +71 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* All shared TypeScript interfaces and types for the Encatch React Native SDK.
|
|
5
|
+
*/
|
|
6
|
+
interface EncatchConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Base URL used for all API calls.
|
|
9
|
+
* Defaults to 'https://app.encatch.com'.
|
|
10
|
+
*/
|
|
11
|
+
apiBaseUrl?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Base URL used to load the react-native-sdk-form WebView page.
|
|
14
|
+
* Defaults to the same value as apiBaseUrl.
|
|
15
|
+
* Override this only if your web host differs from your API host.
|
|
16
|
+
*/
|
|
17
|
+
webHost?: string;
|
|
18
|
+
/** Default theme for forms. Defaults to 'system'. */
|
|
19
|
+
theme?: Theme;
|
|
20
|
+
/** When true, the form overlay is displayed full-screen. */
|
|
21
|
+
isFullScreen?: boolean;
|
|
22
|
+
/** Enable verbose SDK logging to the console. */
|
|
23
|
+
debugMode?: boolean;
|
|
24
|
+
/** Override app version (default: auto-detected from native app) */
|
|
25
|
+
appVersion?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Optional interceptor called before any form is shown (manual or automatic).
|
|
28
|
+
* If it returns false (or Promise<false>), the SDK form will not open; the app
|
|
29
|
+
* can show a custom widget using the payload. Prefills are cleared when false.
|
|
30
|
+
*/
|
|
31
|
+
onBeforeShowForm?: (payload: ShowFormInterceptorPayload) => boolean | Promise<boolean>;
|
|
32
|
+
}
|
|
33
|
+
interface ShowFormInterceptorPayload {
|
|
34
|
+
formId: string;
|
|
35
|
+
formConfig: ShowFormResponse;
|
|
36
|
+
resetMode: ResetMode;
|
|
37
|
+
triggerType: 'automatic' | 'manual';
|
|
38
|
+
/** Pre-filled responses from addToResponse() */
|
|
39
|
+
prefillResponses: Record<string, unknown>;
|
|
40
|
+
locale?: string;
|
|
41
|
+
theme?: Theme;
|
|
42
|
+
}
|
|
43
|
+
interface StartSessionOptions {
|
|
44
|
+
/** When true, do not call the immediate ping (30s ping interval still runs) */
|
|
45
|
+
skipImmediatePing?: boolean;
|
|
46
|
+
/** When true, do not send the initial trackScreen for the current screen (screen listeners still run) */
|
|
47
|
+
skipImmediateTrackScreen?: boolean;
|
|
48
|
+
}
|
|
49
|
+
interface UserTraits {
|
|
50
|
+
/** Set user attributes (overwrites existing values) */
|
|
51
|
+
$set?: Record<string, any>;
|
|
52
|
+
/** Set user attributes only if they don't already exist */
|
|
53
|
+
$setOnce?: Record<string, any>;
|
|
54
|
+
/** Increment numeric user attributes */
|
|
55
|
+
$increment?: Record<string, number>;
|
|
56
|
+
/** Decrement numeric user attributes */
|
|
57
|
+
$decrement?: Record<string, number>;
|
|
58
|
+
/** Remove user attributes */
|
|
59
|
+
$unset?: string[];
|
|
60
|
+
}
|
|
61
|
+
interface SecureOptions {
|
|
62
|
+
signature: string;
|
|
63
|
+
generatedDateTimeinUTC?: string;
|
|
64
|
+
}
|
|
65
|
+
interface IdentifyOptions {
|
|
66
|
+
locale?: string;
|
|
67
|
+
country?: string;
|
|
68
|
+
secure?: SecureOptions;
|
|
69
|
+
}
|
|
70
|
+
type Theme = 'light' | 'dark' | 'system';
|
|
71
|
+
/**
|
|
72
|
+
* Reset mode for form data when showing a form.
|
|
73
|
+
* - 'always': Clear form data every time showForm is called (default)
|
|
74
|
+
* - 'on-complete': Clear form data only if form was previously completed
|
|
75
|
+
* - 'never': Never clear form data (preserve user's previous answers)
|
|
76
|
+
*/
|
|
77
|
+
type ResetMode = 'always' | 'on-complete' | 'never';
|
|
78
|
+
interface ShowFormOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Controls when form data should be cleared.
|
|
81
|
+
* @default 'always'
|
|
82
|
+
*/
|
|
83
|
+
reset?: ResetMode;
|
|
84
|
+
}
|
|
85
|
+
type EventType = 'form:show' | 'form:started' | 'form:submit' | 'form:complete' | 'form:close' | 'form:dismissed' | 'form:error' | 'form:section:change' | 'form:answered';
|
|
86
|
+
interface EventPayload {
|
|
87
|
+
formId?: string;
|
|
88
|
+
timestamp: number;
|
|
89
|
+
data?: Record<string, unknown>;
|
|
90
|
+
}
|
|
91
|
+
type EventCallback = (eventType: EventType, payload: EventPayload) => void;
|
|
92
|
+
interface ApiDeviceInfo {
|
|
93
|
+
$deviceOs?: string;
|
|
94
|
+
$deviceVersion?: string;
|
|
95
|
+
$deviceOsVersion?: string;
|
|
96
|
+
$deviceType?: string;
|
|
97
|
+
$deviceSize?: 'mobile' | 'tablet' | 'desktop';
|
|
98
|
+
$sdkVersion?: string;
|
|
99
|
+
$appVersion?: string;
|
|
100
|
+
$app?: string;
|
|
101
|
+
$deviceLanguage?: string;
|
|
102
|
+
$userLanguage?: string;
|
|
103
|
+
$countryCode?: string;
|
|
104
|
+
$preferredTheme?: string;
|
|
105
|
+
$timezone?: string;
|
|
106
|
+
$urlOrScreenName?: string;
|
|
107
|
+
}
|
|
108
|
+
interface ShowFormResponse {
|
|
109
|
+
feedbackConfigurationId: string;
|
|
110
|
+
feedbackIdentifier?: string;
|
|
111
|
+
triggerType?: 'automatic' | 'manual';
|
|
112
|
+
formConfiguration?: Record<string, unknown>;
|
|
113
|
+
questionnaireFields?: any;
|
|
114
|
+
otherConfigurationProperties?: any;
|
|
115
|
+
welcomeScreenProperties?: any;
|
|
116
|
+
endScreenProperties?: any;
|
|
117
|
+
appearanceProperties?: any;
|
|
118
|
+
partialResponseEnabled?: boolean;
|
|
119
|
+
pingAgainIn?: number;
|
|
120
|
+
pingOnNextPageVisit?: boolean;
|
|
121
|
+
$feedbackTransactions?: string;
|
|
122
|
+
}
|
|
123
|
+
interface RefineTextRequest {
|
|
124
|
+
questionId: string;
|
|
125
|
+
feedbackConfigurationId: string;
|
|
126
|
+
userText: string;
|
|
127
|
+
$deviceInfo?: ApiDeviceInfo;
|
|
128
|
+
$feedbackTransactions?: string;
|
|
129
|
+
}
|
|
130
|
+
interface RefineTextResponse {
|
|
131
|
+
message?: string;
|
|
132
|
+
refinedText?: string;
|
|
133
|
+
status?: number;
|
|
134
|
+
error?: string;
|
|
135
|
+
pingAgainIn?: number;
|
|
136
|
+
pingOnNextPageVisit?: boolean;
|
|
137
|
+
$feedbackTransactions?: string;
|
|
138
|
+
}
|
|
139
|
+
interface QuestionAnswer {
|
|
140
|
+
nps?: number;
|
|
141
|
+
rating?: number;
|
|
142
|
+
singleChoice?: string;
|
|
143
|
+
singleChoiceOther?: string;
|
|
144
|
+
multipleChoiceMultiple?: string[];
|
|
145
|
+
multipleChoiceMultipleOther?: string;
|
|
146
|
+
nestedSelection?: string[];
|
|
147
|
+
shortAnswer?: string;
|
|
148
|
+
longText?: string;
|
|
149
|
+
annotation?: {
|
|
150
|
+
fileType?: string;
|
|
151
|
+
fileData?: string;
|
|
152
|
+
fileName?: string;
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
interface QuestionResponse {
|
|
156
|
+
questionId: string;
|
|
157
|
+
type?: string;
|
|
158
|
+
answer?: QuestionAnswer;
|
|
159
|
+
}
|
|
160
|
+
interface FormDetails {
|
|
161
|
+
formConfigurationId: string;
|
|
162
|
+
isPartialSubmit?: boolean;
|
|
163
|
+
feedbackIdentifier?: string;
|
|
164
|
+
responseLanguageCode?: string;
|
|
165
|
+
response?: {
|
|
166
|
+
questions?: QuestionResponse[];
|
|
167
|
+
};
|
|
168
|
+
completionTimeInSeconds?: number;
|
|
169
|
+
}
|
|
170
|
+
interface SubmitFormRequest {
|
|
171
|
+
triggerType?: 'automatic' | 'manual';
|
|
172
|
+
formDetails: FormDetails;
|
|
173
|
+
$deviceInfo?: ApiDeviceInfo;
|
|
174
|
+
$feedbackTransactions?: string;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Encatch React Native SDK — Core
|
|
179
|
+
*
|
|
180
|
+
* The main singleton class. Mirrors the web SDK's encatch.ts + api-client.ts
|
|
181
|
+
* but uses React Native APIs (AsyncStorage, fetch, Platform) instead of
|
|
182
|
+
* browser APIs (localStorage, ky, window).
|
|
183
|
+
*
|
|
184
|
+
* Architecture:
|
|
185
|
+
* - All public methods are static on the Encatch class.
|
|
186
|
+
* - An internal EventEmitter connects Encatch to EncatchWebView for form display.
|
|
187
|
+
* - A 30-second ping interval mirrors the web SDK behaviour.
|
|
188
|
+
* - A retry queue wraps identifyUser / trackEvent / trackScreen calls.
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
declare class EncatchSDK {
|
|
192
|
+
private _initialized;
|
|
193
|
+
private _debugMode;
|
|
194
|
+
private _apiKey;
|
|
195
|
+
private _apiBaseUrl;
|
|
196
|
+
private _webHost;
|
|
197
|
+
private _isFullScreen;
|
|
198
|
+
private _userName;
|
|
199
|
+
private _userId;
|
|
200
|
+
private _userSignature;
|
|
201
|
+
private _locale;
|
|
202
|
+
private _country;
|
|
203
|
+
private _theme;
|
|
204
|
+
private _currentScreen;
|
|
205
|
+
private _deviceId;
|
|
206
|
+
private _sessionId;
|
|
207
|
+
private _feedbackTransactions;
|
|
208
|
+
private _pingIntervalId;
|
|
209
|
+
private _pingTimeoutId;
|
|
210
|
+
private _pingIntervalMs;
|
|
211
|
+
private _isPingActive;
|
|
212
|
+
private _isFormVisible;
|
|
213
|
+
private _appVersion;
|
|
214
|
+
private _appPackageName;
|
|
215
|
+
private _eventCallbacks;
|
|
216
|
+
private _onBeforeShowForm;
|
|
217
|
+
private _logger;
|
|
218
|
+
init(apiKey: string, config?: EncatchConfig): Promise<void>;
|
|
219
|
+
identifyUser(userName: string, traits?: UserTraits, options?: IdentifyOptions): Promise<void>;
|
|
220
|
+
setLocale(locale: string): void;
|
|
221
|
+
setCountry(country: string): void;
|
|
222
|
+
setTheme(theme: Theme): void;
|
|
223
|
+
trackEvent(eventName: string): Promise<void>;
|
|
224
|
+
/**
|
|
225
|
+
* Best-effort server call for form lifecycle events (form:show, form:started, etc.).
|
|
226
|
+
* Not enqueued — matches web SDK behaviour where form events are fire-and-forget.
|
|
227
|
+
*/
|
|
228
|
+
_trackFormEvent(eventName: string, feedbackConfigurationId?: string): Promise<void>;
|
|
229
|
+
trackScreen(screenName: string): Promise<void>;
|
|
230
|
+
showForm(formId: string, options?: ShowFormOptions): Promise<void>;
|
|
231
|
+
private _showFormInternal;
|
|
232
|
+
/** Used internally when server returns a formConfigurationId auto-trigger */
|
|
233
|
+
private _showFormById;
|
|
234
|
+
dismissForm(formConfigurationId?: string): Promise<void>;
|
|
235
|
+
private _pendingResponses;
|
|
236
|
+
addToResponse(questionId: string, value: unknown): void;
|
|
237
|
+
getPendingResponses(): Record<string, unknown>;
|
|
238
|
+
clearPendingResponses(): void;
|
|
239
|
+
submitForm(params: SubmitFormRequest): Promise<void>;
|
|
240
|
+
refineText(params: RefineTextRequest): Promise<RefineTextResponse>;
|
|
241
|
+
startSession(options?: StartSessionOptions): Promise<void>;
|
|
242
|
+
resetUser(): Promise<void>;
|
|
243
|
+
private _startPingInterval;
|
|
244
|
+
private _stopPingInterval;
|
|
245
|
+
private _scheduleNextPing;
|
|
246
|
+
private _doPing;
|
|
247
|
+
setFormVisible(visible: boolean): void;
|
|
248
|
+
private _handleResponseMeta;
|
|
249
|
+
on(callback: EventCallback): () => void;
|
|
250
|
+
off(callback: EventCallback): void;
|
|
251
|
+
emitEvent(eventType: EventType, payload: Omit<EventPayload, 'timestamp'>): void;
|
|
252
|
+
private _buildDeviceInfo;
|
|
253
|
+
private _post;
|
|
254
|
+
get isInitialized(): boolean;
|
|
255
|
+
get apiKey(): string | null;
|
|
256
|
+
get baseUrl(): string;
|
|
257
|
+
get webHost(): string;
|
|
258
|
+
get isFullScreen(): boolean;
|
|
259
|
+
get theme(): Theme;
|
|
260
|
+
get locale(): string | null;
|
|
261
|
+
get deviceId(): string | null;
|
|
262
|
+
get sessionId(): string | null;
|
|
263
|
+
get userName(): string | null;
|
|
264
|
+
get userId(): string | null;
|
|
265
|
+
get debugMode(): boolean;
|
|
266
|
+
stop(): void;
|
|
267
|
+
}
|
|
268
|
+
declare const Encatch: EncatchSDK;
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* EncatchProvider
|
|
272
|
+
*
|
|
273
|
+
* React context provider that:
|
|
274
|
+
* 1. Calls Encatch.init() on mount (safe to call multiple times)
|
|
275
|
+
* 2. Auto-tracks screen changes via Expo Router or React Navigation
|
|
276
|
+
* 3. Exposes useEncatch() hook with the full SDK API surface
|
|
277
|
+
*
|
|
278
|
+
* Usage:
|
|
279
|
+
* <EncatchProvider apiKey="..." navigationType="expo-router">
|
|
280
|
+
* <App />
|
|
281
|
+
* </EncatchProvider>
|
|
282
|
+
*/
|
|
283
|
+
|
|
284
|
+
interface EncatchContextValue {
|
|
285
|
+
isInitialized: boolean;
|
|
286
|
+
/**
|
|
287
|
+
* True when the SDK has a confirmed server-issued identity (both userName and
|
|
288
|
+
* userId are present). Useful for gating auth-dependent UI without a separate
|
|
289
|
+
* auth store. Automatically restored from storage on cold start (option 3) and
|
|
290
|
+
* updated reactively when identifyUser succeeds or resetUser is called (option 1).
|
|
291
|
+
*/
|
|
292
|
+
isIdentified: boolean;
|
|
293
|
+
/** The identified user's userName, or null if not identified. */
|
|
294
|
+
userName: string | null;
|
|
295
|
+
/** Call Encatch.identifyUser */
|
|
296
|
+
identifyUser: (userName: string, traits?: UserTraits, options?: IdentifyOptions) => void;
|
|
297
|
+
/** Call Encatch.setLocale */
|
|
298
|
+
setLocale: (locale: string) => void;
|
|
299
|
+
/** Call Encatch.setCountry */
|
|
300
|
+
setCountry: (country: string) => void;
|
|
301
|
+
/** Call Encatch.setTheme */
|
|
302
|
+
setTheme: (theme: Theme) => void;
|
|
303
|
+
/** Call Encatch.trackEvent */
|
|
304
|
+
trackEvent: (eventName: string) => void;
|
|
305
|
+
/** Call Encatch.trackScreen */
|
|
306
|
+
trackScreen: (screenName: string) => void;
|
|
307
|
+
/** Call Encatch.showForm */
|
|
308
|
+
showForm: (formId: string, options?: ShowFormOptions) => void;
|
|
309
|
+
/** Call Encatch.dismissForm */
|
|
310
|
+
dismissForm: (formConfigurationId?: string) => void;
|
|
311
|
+
/** Call Encatch.addToResponse */
|
|
312
|
+
addToResponse: (questionId: string, value: unknown) => void;
|
|
313
|
+
/** Call Encatch.resetUser */
|
|
314
|
+
resetUser: () => void;
|
|
315
|
+
/** Subscribe to SDK events */
|
|
316
|
+
on: (callback: EventCallback) => () => void;
|
|
317
|
+
/** Unsubscribe from SDK events */
|
|
318
|
+
off: (callback: EventCallback) => void;
|
|
319
|
+
/**
|
|
320
|
+
* Submit form (for custom native forms when using onBeforeShowForm interceptor).
|
|
321
|
+
* Sends responses to the Encatch API.
|
|
322
|
+
*/
|
|
323
|
+
submitForm: (params: SubmitFormRequest) => void;
|
|
324
|
+
/**
|
|
325
|
+
* Emit a form event (for custom native forms when using onBeforeShowForm interceptor).
|
|
326
|
+
* Use to mirror WebView form events: form:show, form:started, form:answered, form:submit, form:complete, form:close, etc.
|
|
327
|
+
*/
|
|
328
|
+
emitEvent: (eventType: EventType, payload: Omit<EventPayload, 'timestamp'>) => void;
|
|
329
|
+
/**
|
|
330
|
+
* Refine text via AI (for custom native forms with AI enhance feature).
|
|
331
|
+
*/
|
|
332
|
+
refineText: (params: RefineTextRequest) => Promise<RefineTextResponse>;
|
|
333
|
+
}
|
|
334
|
+
interface EncatchProviderProps {
|
|
335
|
+
children: ReactNode;
|
|
336
|
+
/** Your Encatch API key */
|
|
337
|
+
apiKey: string;
|
|
338
|
+
/** SDK configuration (apiBaseUrl, webHost, theme, isFullScreen, debugMode) */
|
|
339
|
+
config?: EncatchConfig;
|
|
340
|
+
/**
|
|
341
|
+
* Navigation library used for automatic screen tracking.
|
|
342
|
+
* - 'expo-router': uses useSegments/usePathname from expo-router
|
|
343
|
+
* - 'react-navigation': uses useNavigationState from @react-navigation/native
|
|
344
|
+
* - null: no automatic tracking (call Encatch.trackScreen manually)
|
|
345
|
+
* @default null
|
|
346
|
+
*/
|
|
347
|
+
navigationType?: 'expo-router' | 'react-navigation' | null;
|
|
348
|
+
/** Screen names that should be skipped for tracking */
|
|
349
|
+
skippedRoutes?: string[];
|
|
350
|
+
}
|
|
351
|
+
declare const EncatchProvider: React.FC<EncatchProviderProps>;
|
|
352
|
+
declare function useEncatch(): EncatchContextValue;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* EncatchWebView
|
|
356
|
+
*
|
|
357
|
+
* Drop-in component that renders the Encatch form inside a WebView overlay.
|
|
358
|
+
* Place once anywhere in your app's root layout — no props required.
|
|
359
|
+
*
|
|
360
|
+
* Responsibilities:
|
|
361
|
+
* - Subscribes to the internal Encatch event emitter (showForm / dismissForm)
|
|
362
|
+
* - Loads the remote react-native-sdk-form URL in a react-native-webview
|
|
363
|
+
* - Bridges postMessages bidirectionally:
|
|
364
|
+
* WebView → Native: onMessage (form:ready, form:submit, form:close, etc.)
|
|
365
|
+
* Native → WebView: injectJavaScript (sdk:formConfig, sdk:theme, etc.)
|
|
366
|
+
* - Animated entrance/exit (slide from position or scale from center)
|
|
367
|
+
* - Responsive width: phone 100%, tablet 600px max, handles orientation changes
|
|
368
|
+
*/
|
|
369
|
+
|
|
370
|
+
declare const EncatchWebView: React.FC;
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Helpers for custom native forms (when using onBeforeShowForm interceptor).
|
|
374
|
+
* Use these to build SubmitFormRequest from your native form responses.
|
|
375
|
+
*/
|
|
376
|
+
|
|
377
|
+
interface NativeFormResponse {
|
|
378
|
+
questionId: string;
|
|
379
|
+
type: string;
|
|
380
|
+
value: string | number | string[];
|
|
381
|
+
}
|
|
382
|
+
interface BuildSubmitRequestOptions {
|
|
383
|
+
triggerType?: 'automatic' | 'manual';
|
|
384
|
+
formConfigurationId: string;
|
|
385
|
+
responseLanguageCode?: string;
|
|
386
|
+
completionTimeInSeconds?: number;
|
|
387
|
+
isPartialSubmit?: boolean;
|
|
388
|
+
feedbackIdentifier?: string;
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Builds a SubmitFormRequest from native form responses.
|
|
392
|
+
* Use when you have a custom native form and need to submit to the Encatch API.
|
|
393
|
+
*
|
|
394
|
+
* @example
|
|
395
|
+
* ```ts
|
|
396
|
+
* const responses = [
|
|
397
|
+
* { questionId: 'q1', type: 'rating', value: 5 },
|
|
398
|
+
* { questionId: 'q2', type: 'short_answer', value: 'Great product!' },
|
|
399
|
+
* ];
|
|
400
|
+
* const req = buildSubmitRequest(
|
|
401
|
+
* { formConfigurationId: formConfig.feedbackConfigurationId },
|
|
402
|
+
* responses
|
|
403
|
+
* );
|
|
404
|
+
* Encatch.submitForm(req);
|
|
405
|
+
* ```
|
|
406
|
+
*/
|
|
407
|
+
declare function buildSubmitRequest(options: BuildSubmitRequestOptions, responses: NativeFormResponse[]): SubmitFormRequest;
|
|
408
|
+
|
|
409
|
+
export { type ApiDeviceInfo, type BuildSubmitRequestOptions, Encatch, type EncatchConfig, type EncatchContextValue, EncatchProvider, type EncatchProviderProps, EncatchWebView, type EventCallback, type EventPayload, type EventType, type FormDetails, type IdentifyOptions, type NativeFormResponse, type QuestionAnswer, type QuestionResponse, type RefineTextRequest, type RefineTextResponse, type ResetMode, type SecureOptions, type ShowFormInterceptorPayload, type ShowFormOptions, type ShowFormResponse, type StartSessionOptions, type SubmitFormRequest, type Theme, type UserTraits, buildSubmitRequest, useEncatch };
|