-
Notifications
You must be signed in to change notification settings - Fork 144
/
Copy pathindex.tsx
157 lines (134 loc) · 4.74 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import { h, render } from 'preact'
import { getCountryCodes } from 'react-phone-number-input/modules/countries'
import labels from 'react-phone-number-input/locale/default.json'
import 'custom-event-polyfill'
// TODO: These IE11 polyfills are missing in `development` after the Typescript conversion.
// But on PRs where the components that use these Array methods have been converted the polyfills seem to be included.
// Should be fine to remove when those PRs are merged in eventually.
import 'array-flat-polyfill'
import 'core-js/es/object/entries'
import 'core-js/es/object/from-entries'
import { noop } from '~utils/func'
import { upperCase } from '~utils/string'
import { buildStepFinder } from '~utils/steps'
import { cssVarsPonyfill } from '~utils/cssVarsPonyfill'
import type { NormalisedSdkOptions } from '~types/commons'
import type { SdkOptions, SdkHandle } from '~types/sdk'
import type { StepConfig, StepTypes } from '~types/steps'
import App from './components/App'
if (process.env.NODE_ENV === 'development') {
require('preact/debug')
}
const onfidoRender = (
options: NormalisedSdkOptions,
el: Element | Document | ShadowRoot | DocumentFragment,
merge?: Element | Text
) => render(<App options={options} />, el, merge)
const defaults: SdkOptions = {
token: undefined,
containerId: 'onfido-mount',
onComplete: noop,
onError: noop,
onUserExit: noop,
}
const formatStep = (typeOrStep: StepConfig | StepTypes): StepConfig => {
if (typeof typeOrStep === 'string') {
return { type: typeOrStep }
}
return typeOrStep
}
const formatOptions = ({
steps,
smsNumberCountryCode,
...otherOptions
}: SdkOptions): NormalisedSdkOptions => {
const mandatorySteps: StepTypes[] = ['document', 'face', 'complete']
const defaultSteps: StepTypes[] =
process.env.SDK_ENV === 'Auth'
? ['welcome', 'auth', ...mandatorySteps]
: ['welcome', ...mandatorySteps]
return {
...otherOptions,
smsNumberCountryCode: validateSmsCountryCode(smsNumberCountryCode),
steps: (steps || defaultSteps).map(formatStep),
}
}
const experimentalFeatureWarnings = ({ steps }: NormalisedSdkOptions) => {
const documentStep = buildStepFinder(steps)('document')
if (documentStep?.options?.useWebcam) {
console.warn(
'`useWebcam` is an experimental option and is currently discouraged'
)
}
if (documentStep?.options?.useLiveDocumentCapture) {
console.warn(
'`useLiveDocumentCapture` is a beta feature and is still subject to ongoing changes'
)
}
}
const isSMSCountryCodeValid = (smsNumberCountryCode: string) => {
// If you need to refactor this code, remember not to introduce large libraries such as
// libphonenumber-js in the main bundle!
const countries = getCountryCodes(labels)
const isCodeValid = countries.includes(smsNumberCountryCode)
if (!isCodeValid) {
console.warn(
"`smsNumberCountryCode` must be a valid two-characters ISO Country Code. 'GB' will be used instead."
)
}
return isCodeValid
}
const validateSmsCountryCode = (
smsNumberCountryCode?: string
): string | undefined => {
if (!smsNumberCountryCode) return 'GB'
const upperCaseCode = upperCase(smsNumberCountryCode)
return isSMSCountryCodeValid(upperCaseCode) ? upperCaseCode : 'GB'
}
const elementIsInPage = (node: HTMLElement) =>
node === document.body ? false : document.body.contains(node)
const getContainerElementById = (containerId: string) => {
const el = document.getElementById(containerId)
if (el && elementIsInPage(el)) {
return el
}
throw new Error(
`Element ID ${containerId} does not exist in current page body`
)
}
export const init = (opts: SdkOptions): SdkHandle => {
console.log('onfido_sdk_version', process.env.SDK_VERSION)
const options = formatOptions({ ...defaults, ...opts })
experimentalFeatureWarnings(options)
cssVarsPonyfill()
let containerEl: HTMLElement
if (options.containerEl) {
containerEl = options.containerEl
onfidoRender(options, containerEl)
} else if (options.containerId) {
containerEl = getContainerElementById(options.containerId)
onfidoRender(options, containerEl)
}
return {
options,
setOptions(changedOptions) {
this.options = formatOptions({ ...this.options, ...changedOptions })
if (
this.options.containerEl !== changedOptions.containerEl &&
changedOptions.containerEl
) {
containerEl = changedOptions.containerEl
} else if (
this.containerId !== changedOptions.containerId &&
changedOptions.containerId
) {
containerEl = getContainerElementById(changedOptions.containerId)
}
onfidoRender(this.options as NormalisedSdkOptions, containerEl)
return this.options
},
tearDown() {
render(null, containerEl)
},
}
}