@checktiv/sdk-web 1.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.
@@ -0,0 +1,13 @@
1
+ import { C as ChecktivInitOptions, a as ChecktivClient, I as InitOptions } from './types-CnlkFS7V.js';
2
+ export { b as ChecktivError, c as ChecktivErrorCode, d as ChecktivEvent, e as ChecktivFraudEvent, f as ChecktivIdvEvent, g as CrossDeviceHandoffHook, F as FraudHandle, h as FraudMountOptions, G as GetSessionToken, i as GetSessionTokenContext, j as IdvCoachingHint, k as IdvHandle, l as IdvMountOptions, m as InvalidPublishableKeyError, M as MountProvisionedOptions, P as ParsedPublishableKey, n as ProvisionedHandle, R as ResolvedIdvConfig, S as SdkMode, o as SdkRegion, p as SyntheticIdvScript, q as parsePublishableKey } from './types-CnlkFS7V.js';
3
+ export { ChecktivIdvProps, ChecktivProviderProps } from './react.js';
4
+ import './machine--zVZIM4F.js';
5
+ import './copy-DeUly5vr.js';
6
+ import 'react';
7
+
8
+ declare function init(opts: ChecktivInitOptions): ChecktivClient;
9
+
10
+ declare const version: string;
11
+ declare function mountButton(opts: InitOptions): void;
12
+
13
+ export { ChecktivClient, ChecktivInitOptions, InitOptions, init, mountButton, version };
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ import { parsePublishableKey } from './chunk-BYTKOKAD.js';
2
+ export { InvalidPublishableKeyError, init, parsePublishableKey } from './chunk-BYTKOKAD.js';
3
+ import './chunk-CXNPD67Z.js';
4
+ import { sdkPublicSettings } from './chunk-FGWZZNAN.js';
5
+ import { R, k } from './chunk-XOGHMNBX.js';
6
+ import { getServiceOrigin } from './chunk-QFA3K5ZV.js';
7
+ import './chunk-WQCYRLWP.js';
8
+ import './chunk-AIK7CDV6.js';
9
+
10
+ var HOST_TAG="checktiv-root";var MOUNTED_FLAG="__checktivMounted";var LEGACY_HOST_ATTR="data-autohost-kyc-host";var HOST_ATTR="data-checktiv-host";var shadowCache=new WeakMap;function mountShadowHost(target){const existing=findExistingHost(target);if(existing){const cached=shadowCache.get(existing);if(cached)return cached}const host=document.createElement("div");host.setAttribute(HOST_ATTR,HOST_TAG);host.setAttribute(LEGACY_HOST_ATTR,HOST_TAG);host[MOUNTED_FLAG]=true;target.appendChild(host);const shadow=host.attachShadow({mode:"closed"});shadowCache.set(host,shadow);return shadow}function findExistingHost(target){for(const child of Array.from(target.children)){if(!(child instanceof HTMLElement))continue;const candidate=child;if(candidate[MOUNTED_FLAG]===true)return candidate}return null}var version="1.0.0";var initialised=new WeakSet;function resolveVerifyOrigin(parsed){return getServiceOrigin(sdkPublicSettings.apps.verify.subdomain,"prod",parsed.region,sdkPublicSettings)}function buildPopupUrl(parsed,opts){const origin=resolveVerifyOrigin(parsed);if(opts.applicantLinkToken){return `${origin}/start?lt=${encodeURIComponent(opts.applicantLinkToken)}`}return `${origin}/`}function launchPopup(url){const w=460;const h=760;const left=Math.max(0,Math.floor((window.screen.width-w)/2));const top=Math.max(0,Math.floor((window.screen.height-h)/2));const features=`popup=yes,width=${w},height=${h},left=${left},top=${top}`;const popup=window.open(url,"checktiv",features);if(!popup){window.location.href=url;return null}return popup}var COMPLETE_EVENT_TYPE="autohost.kyc.complete";function isCompletionMessage(data){if(typeof data!=="object"||data===null)return false;if(!("type"in data))return false;return data.type===COMPLETE_EVENT_TYPE}function listenForCompletion(expectedOrigin,onComplete){if(!onComplete)return;const handler=event=>{if(event.origin!==expectedOrigin)return;const data=event.data;if(!isCompletionMessage(data))return;onComplete(data);};window.addEventListener("message",handler);}function buildButton(onClick){const children="Start verification";return k("button",{type:"button",onClick,style:'display: inline-flex; align-items: center; justify-content: center; padding: 10px 20px; font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", sans-serif; font-size: 14px; font-weight: 600; color: #fff; background: #0b5fff; border: none; border-radius: 6px; cursor: pointer;'},children)}function resolveTarget(opts){if(opts.target)return opts.target;return document.querySelector("[data-checktiv]")??document.querySelector("[data-autohost-kyc]")}function mountButton(opts){const parsed=parsePublishableKey(opts.publishableKey);const target=resolveTarget(opts);if(!target){console.warn("[Checktiv] No mount target found. Either pass `target` explicitly or add `<div data-checktiv>` to your page.");return}if(initialised.has(target))return;initialised.add(target);const shadow=mountShadowHost(target);const verifyOrigin=resolveVerifyOrigin(parsed);listenForCompletion(verifyOrigin,opts.onComplete);const onClick=()=>{const popupUrl=buildPopupUrl(parsed,opts);launchPopup(popupUrl);};R(buildButton(onClick),shadow);}
11
+
12
+ export { mountButton, version };
@@ -0,0 +1,144 @@
1
+ type CaptureDocumentSide = 'front' | 'back';
2
+ type CaptureErrorCode = 'cv_gate_failed' | 'upload_failed' | 'sdk_load_failed' | 'token_expired' | 'biometric_unsupported' | 'selfie_camera_denied' | 'liveness_camera_denied' | 'liveness_timeout' | 'liveness_server_error' | 'liveness_runtime_error' | 'liveness_cancelled' | 'protocol_mismatch';
3
+ interface SelfiePromptMap {
4
+ no_face?: string;
5
+ multiple_faces?: string;
6
+ too_dark?: string;
7
+ move_closer?: string;
8
+ not_centered?: string;
9
+ hold_still?: string;
10
+ ready?: string;
11
+ }
12
+ type DataMode = 'live' | 'test';
13
+ type TestHint = 'pass' | 'review' | 'fail' | 'doc_quality';
14
+ interface CaptureBrandTokens {
15
+ primary: string;
16
+ primaryHover: string;
17
+ onPrimary: string;
18
+ secondary: string;
19
+ onSecondary: string;
20
+ ring: string;
21
+ }
22
+ interface CaptureTheme {
23
+ colorMode: 'light' | 'dark';
24
+ brandTokens: CaptureBrandTokens | null;
25
+ }
26
+ type IdvDocumentType = 'passport' | 'drivers_license' | 'id_card';
27
+ interface IdVerificationConfig {
28
+ documentTypes: IdvDocumentType[];
29
+ biometricMode: 'none' | 'selfie' | 'liveness';
30
+ requireMrzMatch: boolean;
31
+ requireExpiryValid: boolean;
32
+ requireNameMatch: boolean;
33
+ documentAuthenticity: boolean;
34
+ minAge?: number;
35
+ }
36
+ interface CaptureInitMessage {
37
+ type: 'capture:init';
38
+ captureToken: string;
39
+ config: IdVerificationConfig;
40
+ locale: string;
41
+ theme: CaptureTheme;
42
+ mode?: DataMode;
43
+ testHint?: TestHint;
44
+ protocolVersion?: number;
45
+ beginScanPrompt?: string;
46
+ beginScanLabel?: string;
47
+ selfiePromptMap?: SelfiePromptMap;
48
+ }
49
+ interface IdvR2Keys {
50
+ front: string;
51
+ back?: string;
52
+ selfie?: string;
53
+ }
54
+ interface CaptureBehaviorStep {
55
+ stepId: string;
56
+ seconds: number;
57
+ pasteCount: number;
58
+ }
59
+ interface CaptureBehaviorTraits {
60
+ webdriver: boolean;
61
+ maxTouchPoints: number;
62
+ timezone: string | null;
63
+ pluginCount: number;
64
+ deviceModelHint: string | null;
65
+ }
66
+ interface CaptureBehaviorMessage {
67
+ type: 'capture:behavior';
68
+ steps: CaptureBehaviorStep[];
69
+ traits: CaptureBehaviorTraits;
70
+ }
71
+
72
+ type CapturePhase = 'ready' | 'document_front' | 'document_back' | 'selfie' | 'liveness' | 'uploading' | 'coaching';
73
+ type CoachingKind = 'move_closer' | 'move_farther' | 'reduce_glare' | 'too_dark' | 'wrong_side' | 'hold_steady';
74
+ type CaptureState = {
75
+ kind: 'minting';
76
+ } | {
77
+ kind: 'mint_error';
78
+ } | {
79
+ kind: 'waiting_for_init';
80
+ captureToken: string;
81
+ embedOrigin: string;
82
+ runIndex: number;
83
+ } | {
84
+ kind: 'ready';
85
+ embedOrigin: string;
86
+ runIndex: number;
87
+ } | {
88
+ kind: 'capturing';
89
+ embedOrigin: string;
90
+ runIndex: number;
91
+ phase: CapturePhase;
92
+ coaching: CoachingKind | null;
93
+ lastCvRejectReason: string | null;
94
+ biometricLoading: boolean;
95
+ } | {
96
+ kind: 'submitting';
97
+ } | {
98
+ kind: 'submit_error';
99
+ } | {
100
+ kind: 'submit_pending';
101
+ } | {
102
+ kind: 'token_expired';
103
+ } | {
104
+ kind: 'capture_error';
105
+ errorKind: CaptureErrorKind;
106
+ };
107
+ type CaptureErrorKind = Exclude<CaptureErrorCode, 'token_expired'>;
108
+ type CaptureAction = {
109
+ type: 'mint_ok';
110
+ captureToken: string;
111
+ embedOrigin: string;
112
+ runIndex: number;
113
+ } | {
114
+ type: 'mint_failed';
115
+ } | {
116
+ type: 'iframe_ready';
117
+ } | {
118
+ type: 'phase';
119
+ phase: CapturePhase;
120
+ } | {
121
+ type: 'coaching';
122
+ coaching: CoachingKind;
123
+ } | {
124
+ type: 'selfie_cv_reject';
125
+ reason: string | null;
126
+ } | {
127
+ type: 'biometric_camera_live';
128
+ } | {
129
+ type: 'submitting';
130
+ } | {
131
+ type: 'submit_failed';
132
+ } | {
133
+ type: 'submit_pending';
134
+ } | {
135
+ type: 'token_expired';
136
+ } | {
137
+ type: 'capture_error';
138
+ errorKind: CaptureErrorKind;
139
+ };
140
+ declare function reducer(state: CaptureState, action: CaptureAction): CaptureState;
141
+ declare function nextCapturePhaseAfterDocument(side: CaptureDocumentSide, documentTypes: IdVerificationConfig['documentTypes'], biometricMode: IdVerificationConfig['biometricMode']): CapturePhase;
142
+ declare function isBiometricPhase(phase: CapturePhase): boolean;
143
+
144
+ export { type CaptureBehaviorMessage as C, type IdvR2Keys as I, type SelfiePromptMap as S, type CoachingKind as a, type CaptureAction as b, type CaptureErrorKind as c, type CapturePhase as d, type CaptureState as e, type CaptureInitMessage as f, isBiometricPhase as i, nextCapturePhaseAfterDocument as n, reducer as r };
@@ -0,0 +1,23 @@
1
+ import { ReactNode, ReactElement } from 'react';
2
+ import { f as ChecktivIdvEvent, C as ChecktivInitOptions, r as ChecktivInitScope, a as ChecktivClient } from './types-CnlkFS7V.js';
3
+ import { C as CaptureBehaviorMessage } from './machine--zVZIM4F.js';
4
+ import { M as MountCopy } from './copy-DeUly5vr.js';
5
+
6
+ interface ChecktivProviderPropsBase {
7
+ getSessionToken: ChecktivInitOptions['getSessionToken'];
8
+ theme?: ChecktivInitOptions['theme'];
9
+ locale?: string;
10
+ children: ReactNode;
11
+ }
12
+ type ChecktivProviderProps = ChecktivProviderPropsBase & ChecktivInitScope;
13
+ declare function ChecktivProvider(props: ChecktivProviderProps): ReactElement | null;
14
+ declare function useChecktiv(): ChecktivClient;
15
+ interface ChecktivIdvProps {
16
+ onEvent: (e: ChecktivIdvEvent) => void;
17
+ copy?: MountCopy;
18
+ onBeforeSubmit?: () => Promise<void>;
19
+ onBehaviorSegment?: (segment: Pick<CaptureBehaviorMessage, 'steps' | 'traits'>) => void;
20
+ }
21
+ declare function ChecktivIdv({ onEvent, copy, onBeforeSubmit, onBehaviorSegment, }: ChecktivIdvProps): ReactElement | null;
22
+
23
+ export { ChecktivIdv, type ChecktivIdvProps, ChecktivProvider, type ChecktivProviderProps, type ChecktivProviderPropsBase, useChecktiv };
package/dist/react.js ADDED
@@ -0,0 +1,12 @@
1
+ import { init } from './chunk-BYTKOKAD.js';
2
+ import './chunk-CXNPD67Z.js';
3
+ import './chunk-FGWZZNAN.js';
4
+ import './chunk-QFA3K5ZV.js';
5
+ import './chunk-WQCYRLWP.js';
6
+ import './chunk-AIK7CDV6.js';
7
+ import { createContext, useMemo, useContext, useRef, useEffect } from 'react';
8
+ import { jsx } from 'react/jsx-runtime';
9
+
10
+ var ChecktivContext=createContext(null);function ChecktivProvider(props){if(typeof window==="undefined")return null;return jsx(ProviderImpl,{...props})}function ProviderImpl(props){const{getSessionToken,theme,locale,children}=props;const scope="publishableKey"in props?{publishableKey:props.publishableKey}:{region:props.region,mode:props.mode};const pk="publishableKey"in props?props.publishableKey:void 0;const region="publishableKey"in props?void 0:props.region;const mode="publishableKey"in props?void 0:props.mode;const themeKey=JSON.stringify(theme??null);const client=useMemo(()=>init({...scope,getSessionToken,theme,locale}),[pk,region,mode,getSessionToken,themeKey,locale]);return jsx(ChecktivContext.Provider,{value:client,children})}function useChecktiv(){const client=useContext(ChecktivContext);if(client===null){throw new Error("useChecktiv must be used within a <ChecktivProvider>. Wrap the component tree that needs the Checktiv client with <ChecktivProvider>.")}return client}function ChecktivIdv({onEvent,copy,onBeforeSubmit,onBehaviorSegment}){const client=useChecktiv();const containerRef=useRef(null);const handleRef=useRef(null);const mountConfigRef=useRef({copy,onBeforeSubmit,onBehaviorSegment});const onEventRef=useRef(onEvent);onEventRef.current=onEvent;useEffect(()=>{if(typeof window==="undefined")return;if(containerRef.current===null)return;if(handleRef.current!==null)return;const mountConfig=mountConfigRef.current;handleRef.current=client.mount("idv",{target:containerRef.current,onEvent:e=>onEventRef.current(e),...mountConfig.copy!==void 0?{copy:mountConfig.copy}:{},...mountConfig.onBeforeSubmit!==void 0?{onBeforeSubmit:mountConfig.onBeforeSubmit}:{},...mountConfig.onBehaviorSegment!==void 0?{onBehaviorSegment:mountConfig.onBehaviorSegment}:{}});return ()=>{handleRef.current?.destroy();handleRef.current=null;}},[client]);if(typeof window==="undefined")return null;return jsx("div",{ref:containerRef})}
11
+
12
+ export { ChecktivIdv, ChecktivProvider, useChecktiv };
@@ -0,0 +1,244 @@
1
+ import { a as CoachingKind, C as CaptureBehaviorMessage, S as SelfiePromptMap } from './machine--zVZIM4F.js';
2
+ import { M as MountCopy } from './copy-DeUly5vr.js';
3
+
4
+ declare const SystemModes: readonly ["live", "test"];
5
+ type SystemMode = (typeof SystemModes)[number];
6
+ declare const DataRegions: readonly ["us", "eu"];
7
+ type DataRegion = (typeof DataRegions)[number];
8
+
9
+ type SdkRegion = DataRegion;
10
+ type SdkMode = SystemMode;
11
+ interface InitOptions {
12
+ readonly publishableKey: string;
13
+ readonly applicantLinkToken?: string;
14
+ readonly target?: HTMLElement;
15
+ readonly onComplete?: (payload: unknown) => void;
16
+ }
17
+ interface ParsedPublishableKey {
18
+ readonly region: SdkRegion;
19
+ readonly mode: SdkMode;
20
+ }
21
+ declare class InvalidPublishableKeyError extends Error {
22
+ constructor(message: string);
23
+ }
24
+ declare function parsePublishableKey(key: string): ParsedPublishableKey;
25
+
26
+ interface TokenManager {
27
+ get(): Promise<string>;
28
+ refresh(reason: 'expired' | '401'): Promise<string>;
29
+ }
30
+
31
+ type ChecktivErrorCode = 'origin_not_allowed' | 'token_expired' | 'session_expired' | 'protocol_mismatch' | 'camera_denied' | 'cv_gate_failed' | 'upload_failed' | 'sdk_load_failed' | 'biometric_unsupported' | 'isolation_required';
32
+ interface ChecktivError {
33
+ code: ChecktivErrorCode;
34
+ recoverable: boolean;
35
+ recovery: 'retry' | 'cross_device' | 'refresh_session' | 'contact_operator';
36
+ message: string;
37
+ }
38
+
39
+ type ChecktivFraudEvent = {
40
+ type: 'checktiv.fraud.started';
41
+ } | {
42
+ type: 'checktiv.fraud.error';
43
+ error: ChecktivError;
44
+ };
45
+ interface FraudMountOptions {
46
+ onConsent: () => boolean | Promise<boolean>;
47
+ onEvent?: (e: ChecktivFraudEvent) => void;
48
+ fetchImpl?: typeof fetch;
49
+ }
50
+ interface FraudHandle {
51
+ destroy(): void;
52
+ }
53
+ declare function createFraud(ctx: SubstrateContext, opts: FraudMountOptions): FraudHandle;
54
+
55
+ type IdvCoachingHint = CoachingKind;
56
+ interface ResolvedIdvConfig {
57
+ documentTypes: readonly string[];
58
+ biometricMode: 'selfie' | 'liveness' | 'none';
59
+ }
60
+ type ChecktivIdvEvent = {
61
+ type: 'checktiv.idv.ready';
62
+ config: ResolvedIdvConfig;
63
+ } | {
64
+ type: 'checktiv.idv.phase';
65
+ phase: string;
66
+ } | {
67
+ type: 'checktiv.idv.coaching';
68
+ hint: IdvCoachingHint;
69
+ } | {
70
+ type: 'checktiv.idv.submitted';
71
+ sessionId: string;
72
+ } | {
73
+ type: 'checktiv.idv.processing';
74
+ } | {
75
+ type: 'checktiv.idv.error';
76
+ error: ChecktivError;
77
+ } | {
78
+ type: 'checktiv.idv.cross_device_opened';
79
+ } | {
80
+ type: 'checktiv.idv.cross_device_unavailable';
81
+ };
82
+ type ChecktivEvent = ChecktivIdvEvent | ChecktivFraudEvent | {
83
+ type: `checktiv.${string}`;
84
+ [k: string]: unknown;
85
+ };
86
+
87
+ interface SyntheticIdvScript {
88
+ injectError?: ChecktivErrorCode;
89
+ stepDelayMs?: number;
90
+ }
91
+
92
+ type CrossDeviceHandoffHook = () => Promise<{
93
+ kind: 'ok';
94
+ url: string;
95
+ } | {
96
+ kind: 'unavailable';
97
+ }>;
98
+ interface IdvMountOptions {
99
+ target: HTMLElement | string;
100
+ onEvent?: (e: ChecktivIdvEvent) => void;
101
+ copy?: MountCopy;
102
+ onBeforeSubmit?: () => Promise<void>;
103
+ onBehaviorSegment?: (segment: Pick<CaptureBehaviorMessage, 'steps' | 'traits'>) => void;
104
+ fetchImpl?: typeof fetch;
105
+ synthetic?: SyntheticIdvScript;
106
+ }
107
+ interface IdvHandle {
108
+ destroy(): void;
109
+ unmount(): void;
110
+ }
111
+ declare const REMINT_READY_TIMEOUT_MS = 15000;
112
+ declare function createIdv(ctx: SubstrateContext, opts: IdvMountOptions): IdvHandle;
113
+
114
+ interface CustomFormFieldCopy {
115
+ readonly label?: string;
116
+ readonly helpText?: string;
117
+ readonly options?: Readonly<Record<string, string>>;
118
+ }
119
+ interface CustomFormCopy {
120
+ readonly fields?: Readonly<Record<string, CustomFormFieldCopy>>;
121
+ readonly submit?: string;
122
+ readonly requiredError?: string;
123
+ readonly uploadError?: string;
124
+ readonly submitError?: string;
125
+ readonly booleanYes?: string;
126
+ readonly booleanNo?: string;
127
+ }
128
+
129
+ type ChecktivCustomFormEvent = {
130
+ type: 'checktiv.custom_form.ready';
131
+ } | {
132
+ type: 'checktiv.custom_form.submitted';
133
+ sessionId: string;
134
+ } | {
135
+ type: 'checktiv.custom_form.error';
136
+ error: ChecktivError;
137
+ };
138
+
139
+ declare const FORM_FIELD_TYPES: readonly ["short_text", "long_text", "number", "email", "phone", "date", "single_select", "multi_select", "boolean", "file_upload", "content_heading", "content_paragraph"];
140
+ type FormFieldType = (typeof FORM_FIELD_TYPES)[number];
141
+
142
+ type CustomFormApplicantLabel = Record<string, string>;
143
+ interface CustomFormApplicantFieldValidation {
144
+ minLength?: number;
145
+ maxLength?: number;
146
+ min?: number;
147
+ max?: number;
148
+ minSelections?: number;
149
+ maxSelections?: number;
150
+ }
151
+ interface CustomFormApplicantFieldOption {
152
+ value: string;
153
+ label: CustomFormApplicantLabel;
154
+ }
155
+ interface CustomFormApplicantField {
156
+ id: string;
157
+ type: FormFieldType;
158
+ label: CustomFormApplicantLabel;
159
+ helpText?: CustomFormApplicantLabel;
160
+ required: boolean;
161
+ validation?: CustomFormApplicantFieldValidation;
162
+ options?: CustomFormApplicantFieldOption[];
163
+ }
164
+ type CustomFormApplicantConfig = {
165
+ supportedLocales: string[];
166
+ fields: CustomFormApplicantField[];
167
+ };
168
+
169
+ interface CustomFormMountOptions {
170
+ target: HTMLElement | string;
171
+ config: CustomFormApplicantConfig;
172
+ copy?: CustomFormCopy;
173
+ onEvent?: (e: ChecktivCustomFormEvent) => void;
174
+ session?: {
175
+ sessionId: string;
176
+ stepId: string;
177
+ };
178
+ fetchImpl?: typeof fetch;
179
+ preview?: boolean;
180
+ }
181
+ interface CustomFormHandle {
182
+ destroy(): void;
183
+ }
184
+ declare function createCustomForm(ctx: SubstrateContext, opts: CustomFormMountOptions): CustomFormHandle;
185
+
186
+ interface ProvisionedHandle {
187
+ destroy(): void;
188
+ }
189
+ interface MountProvisionedOptions {
190
+ target: HTMLElement | string;
191
+ onEvent?: (e: ChecktivEvent) => void;
192
+ onConsent?: () => boolean | Promise<boolean>;
193
+ copy?: MountCopy;
194
+ onBeforeSubmit?: () => Promise<void>;
195
+ onBehaviorSegment?: (segment: Pick<CaptureBehaviorMessage, 'steps' | 'traits'>) => void;
196
+ fetchImpl?: typeof fetch;
197
+ synthetic?: IdvMountOptions['synthetic'];
198
+ customFormConfig?: CustomFormApplicantConfig;
199
+ customFormCopy?: CustomFormCopy;
200
+ }
201
+
202
+ interface GetSessionTokenContext {
203
+ sessionId: string;
204
+ reason: 'initial' | 'expired' | '401';
205
+ }
206
+ type GetSessionToken = string | ((ctx: GetSessionTokenContext) => Promise<string>);
207
+ interface ChecktivInitOptionsBase {
208
+ getSessionToken: GetSessionToken;
209
+ theme?: {
210
+ primaryColor?: string;
211
+ };
212
+ locale?: string;
213
+ apiBase?: string;
214
+ betas?: string[];
215
+ selfiePromptMap?: SelfiePromptMap;
216
+ }
217
+ type ChecktivInitScope = {
218
+ publishableKey: string;
219
+ } | {
220
+ region: SdkRegion;
221
+ mode: SdkMode;
222
+ };
223
+ type ChecktivInitOptions = ChecktivInitOptionsBase & ChecktivInitScope;
224
+ interface ChecktivClient {
225
+ mountProvisioned(opts: MountProvisionedOptions): ProvisionedHandle;
226
+ mount(module: 'idv', opts: IdvMountOptions): IdvHandle;
227
+ mount(module: 'fraud', opts: FraudMountOptions): FraudHandle;
228
+ mount(module: 'custom_form', opts: CustomFormMountOptions): CustomFormHandle;
229
+ }
230
+ interface SubstrateContext {
231
+ readonly region: SdkRegion;
232
+ readonly mode: SdkMode;
233
+ readonly publishableKey: string | undefined;
234
+ readonly apiBaseOrigin: string;
235
+ readonly theme?: ChecktivInitOptions['theme'];
236
+ readonly locale: string;
237
+ readonly betas: readonly string[];
238
+ readonly selfiePromptMap?: SelfiePromptMap;
239
+ readonly tokens: TokenManager;
240
+ getSessionId(): string;
241
+ setSessionId(id: string): void;
242
+ }
243
+
244
+ export { createCustomForm as A, type ChecktivInitOptions as C, type FraudHandle as F, type GetSessionToken as G, type InitOptions as I, type MountProvisionedOptions as M, type ParsedPublishableKey as P, type ResolvedIdvConfig as R, type SdkMode as S, type ChecktivClient as a, type ChecktivError as b, type ChecktivErrorCode as c, type ChecktivEvent as d, type ChecktivFraudEvent as e, type ChecktivIdvEvent as f, type CrossDeviceHandoffHook as g, type FraudMountOptions as h, type GetSessionTokenContext as i, type IdvCoachingHint as j, type IdvHandle as k, type IdvMountOptions as l, InvalidPublishableKeyError as m, type ProvisionedHandle as n, type SdkRegion as o, type SyntheticIdvScript as p, parsePublishableKey as q, type ChecktivInitScope as r, createFraud as s, REMINT_READY_TIMEOUT_MS as t, createIdv as u, type ChecktivCustomFormEvent as v, type CustomFormCopy as w, type CustomFormFieldCopy as x, type CustomFormHandle as y, type CustomFormMountOptions as z };
package/package.json ADDED
@@ -0,0 +1,130 @@
1
+ {
2
+ "name": "@checktiv/sdk-web",
3
+ "version": "1.0.0",
4
+ "private": false,
5
+ "license": "Apache-2.0",
6
+ "//publishConfigNameNote": "pnpm does NOT apply `publishConfig.name` (the publishConfig override list at https://pnpm.io/package_json#publishconfig excludes `name`; `pnpm pack` leaves the tarball `name` as the workspace name). The published `name` rewrite to `@checktiv/sdk-web` happens in the root `.pnpmfile.cjs` `beforePacking` hook (pnpm >= 10.28) instead — see that file's header. This field is retained ONLY as documentation of intent; the hook deletes it from the packed manifest. The packed-name gate in __tests__/dist-shape.test.ts reads the REAL extracted tarball, not this field.",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "//publishConfigExportsNote": "pnpm applies this `publishConfig.exports` override on `pnpm pack`/`pnpm publish` (NOT `npm pack`), so it defines the PUBLISHED npm shape while the top-level `exports` stays the in-repo (workspace) shape. Differences, both required: (1) every `types` target points at the built `./dist/*.d.ts` (the workspace map points `types` at `./src/*.ts` so in-repo consumers type-check against source with no build; those `.ts` files are NOT in the `files: [dist]` tarball, so publint --strict --pack would error on them). (2) `./agent` is OMITTED: it is a workspace-only export (not a customer API; keystone §5.1) that pulls the licensed, publishable-key-bound `@fingerprint/agent`, which must NEVER ship in the npm tarball (the C3 tarball guard's FORBIDDEN list proves it). `./agents` (the C13 machine-readable steering manifest -> ./dist/agents/manifest.json) IS published: C13's `scripts/generate-agent-steering.mjs` (chained into `build` after tsup) generates `dist/agents/manifest.json`, so it resolves in both the workspace map and this override; the dist-shape tarball test asserts `dist/agents/{AGENTS.md,manifest.json}` ship. publint --strict + attw (esm-only, against the pnpm-packed tarball) both validate THIS map.",
11
+ "description": "Customer-embed Web SDK (Checktiv): tsup dual build — (A) ESM npm package (`@checktiv/sdk-web`) with per-subpath tree-shaking and Checktiv.init substrate for managed IDV / fraud modules, React wrapper; (B) CDN IIFE assigned to window.Checktiv (with legacy window.AutohostKyc alias for existing snippets). Published dist/ is built by tsup; CDN IIFE lands at services/sdk-cdn/public/v1/sdk.js.",
12
+ "type": "module",
13
+ "//exportsNote": "Dual conditions: `types` resolves to the source `.ts` file so in-repo consumers (verify, console) type-check against source without a build step (mirrors @rf/schemas pattern). `import` resolves to the compiled `dist/*.js` for the published npm package. `./agent` is a SOURCE-ONLY interim export (tsup profile A does not build a dist/agent.js yet; the verify app consumes it via its own bundler). `./agents` ships the C13 machine-readable steering manifest; `AGENTS.md` lives alongside it in dist/agents/ (discoverable via the file tree, no export entry to avoid publint resolution warnings). `src/cdn.ts` is the CDN-IIFE-only entry (tsup profile B) and is NOT a published subpath.",
14
+ "//customFormStyleNote": "`./custom-form/style.css` exports the custom-form module's field stylesheet so the verify host can `import '@rf/sdk-web/custom-form/style.css'` from its island: the module renders REAL DOM field controls into the host document (unlike the IDV iframe), so its CSS must be injected into the host page. The workspace map points at the SOURCE css so verify's Vite processes + injects it WITHOUT a prior sdk-web dist build (dev-friendly); the publishConfig override points at the extracted `dist/custom-form.css` for CDN customers (who `<link>` it, like `capture-ui.css`). ONE stylesheet, single-sourced in `src/custom-form/custom-form.css`, theme-aware via `@rf/theme` tokens.",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js"
19
+ },
20
+ "./idv": {
21
+ "types": "./dist/idv.d.ts",
22
+ "import": "./dist/idv.js"
23
+ },
24
+ "./fraud": {
25
+ "types": "./dist/fraud.d.ts",
26
+ "import": "./dist/fraud.js"
27
+ },
28
+ "./custom-form": {
29
+ "types": "./dist/custom-form.d.ts",
30
+ "import": "./dist/custom-form.js"
31
+ },
32
+ "./custom-form/style.css": "./dist/custom-form.css",
33
+ "./react": {
34
+ "types": "./dist/react.d.ts",
35
+ "import": "./dist/react.js"
36
+ },
37
+ "./capture": {
38
+ "types": "./dist/capture.d.ts",
39
+ "import": "./dist/capture.js"
40
+ },
41
+ "./capture-ui": {
42
+ "types": "./dist/capture-ui.d.ts",
43
+ "import": "./dist/capture-ui.js"
44
+ },
45
+ "./cross-device": {
46
+ "types": "./dist/cross-device.d.ts",
47
+ "import": "./dist/cross-device.js"
48
+ },
49
+ "./idv/cross-device": {
50
+ "types": "./dist/idv/cross-device.d.ts",
51
+ "import": "./dist/idv/cross-device.js"
52
+ },
53
+ "./agents": "./dist/agents/manifest.json",
54
+ "./package.json": "./package.json"
55
+ },
56
+ "//sideEffectsNote": "The module-load seam (src/substrate/module-registry.ts) makes the `./idv`, `./fraud`, and `./custom-form` entries SIDE-EFFECTFUL: each calls registerModule(...) at import-eval time so the substrate's mount('idv'|'fraud'|'custom_form')/mountProvisioned can resolve it. A blanket `sideEffects: false` would let a consumer's bundler tree-shake those registrations away (breaking the seam), so this lists ONLY the module entry files (src + published dist forms). Everything else still tree-shakes, so the `.` and `./react` entries stay Zod-free and per-subpath tree-shaking holds. When plan-C rewrites this manifest, KEEP this array (do NOT replace it with `false`).",
57
+ "sideEffects": [
58
+ "./src/idv/index.ts",
59
+ "./src/fraud/index.ts",
60
+ "./src/custom-form/index.ts",
61
+ "./src/cdn.ts",
62
+ "./dist/idv.js",
63
+ "./dist/fraud.js",
64
+ "./dist/custom-form.js",
65
+ "*.css"
66
+ ],
67
+ "files": [
68
+ "dist"
69
+ ],
70
+ "dependencies": {
71
+ "qrcode-generator": "2.0.4"
72
+ },
73
+ "peerDependencies": {
74
+ "react": "^19.2.7",
75
+ "react-dom": "^19.2.7"
76
+ },
77
+ "peerDependenciesMeta": {
78
+ "react": {
79
+ "optional": true
80
+ },
81
+ "react-dom": {
82
+ "optional": true
83
+ }
84
+ },
85
+ "devDependencies": {
86
+ "@arethetypeswrong/cli": "^0.18.0",
87
+ "@aws-amplify/core": "6.16.4",
88
+ "@aws-amplify/ui-react": "6.15.4",
89
+ "@aws-amplify/ui-react-liveness": "3.6.7",
90
+ "@fingerprint/agent": "4.1.0",
91
+ "@microblink/capture": "^1.2.3",
92
+ "@tensorflow/tfjs-backend-wasm": "4.11.0",
93
+ "@tensorflow/tfjs-converter": "4.11.0",
94
+ "@tensorflow/tfjs-core": "4.11.0",
95
+ "@types/node": "^25.9.3",
96
+ "@types/react": "^19.2.17",
97
+ "@types/react-dom": "^19.2.3",
98
+ "aws-amplify": "6.18.0",
99
+ "esbuild": "^0.28.1",
100
+ "jsdom": "^29.1.1",
101
+ "preact": "^10.29.2",
102
+ "publint": "^0.3.0",
103
+ "tsup": "^8.5.0",
104
+ "typescript": "5.9.3",
105
+ "vitest": "^4.1.9",
106
+ "@rf/config": "0.0.0",
107
+ "@rf/schemas": "0.1.0",
108
+ "@rf/theme": "0.1.0",
109
+ "@rf/iam-core": "0.0.1"
110
+ },
111
+ "scripts": {
112
+ "build": "tsup && node scripts/generate-agent-steering.mjs && pnpm run build:embed-capture && pnpm run build:host-capture && pnpm run build:cross-device",
113
+ "build:embed-capture": "node scripts/build-embed-capture.mjs",
114
+ "build:host-capture": "node scripts/build-host-capture.mjs",
115
+ "build:cross-device": "node scripts/build-cross-device.mjs",
116
+ "test": "vitest run",
117
+ "typecheck": "tsc --noEmit",
118
+ "lint": "echo 'lint via tsc'",
119
+ "size": "node ../../scripts/audit-bundle-size.mjs ../../services/sdk-cdn/public/v1/sdk.js 106496",
120
+ "//sizeNote:host-capture": "MIRROR of the canonical gate scripts/audit-bundle-sizes.mjs (run by `pnpm audit:bundle-sizes` in the pre-push battery) - keep the limits in sync. Both host bundles rose one KiB to the next clean ceiling (capture.js 79->80, capture-ui.js 85->86) for the IDV branch: the new capture:biometric_camera_live wire-schema member is validated by safeParse in BOTH bundles (the controller ships in both) - an irreducible shared @rf/schemas/sdk contract - plus the controller's onBeforeSubmit SOC 2 fraud-flush hook (capture.js) and the biometric loading skeleton + MountCopy copy-seam + submit_pending render (capture-ui.js). The controller dispatch is already gzip-optimal (restructuring measurably worsens gzip).",
121
+ "size:host-capture": "node ../../scripts/audit-bundle-size.mjs ../../services/sdk-cdn/public/v1/capture.js 82944",
122
+ "size:host-capture-ui": "node ../../scripts/audit-bundle-size.mjs ../../services/sdk-cdn/public/v1/capture-ui.js 89088",
123
+ "//sizeNote:cross-device": "MIRROR of the canonical gate scripts/audit-bundle-sizes.mjs cross-device line. The cross-device chunk is hash-named by esbuild; this script globs for the current artifact. The limit (20 KiB = 20480 B) is a headroom-padded ceiling over the qrcode-generator + Preact fragment weight at gzip.",
124
+ "size:cross-device": "node ../../scripts/audit-bundle-size.mjs ../../services/sdk-cdn/public/v1/cross-device.js 20480",
125
+ "size:npm": "node ../../scripts/audit-sdk-entry-size.mjs",
126
+ "validate:publint": "publint --strict",
127
+ "validate:attw": "node ../../scripts/validate-sdk-attw.mjs",
128
+ "validate:tarball": "node ../../scripts/audit-sdk-publish-boundary.mjs"
129
+ }
130
+ }