UNPKG

@adyen/kyc-components

Version:

`adyen-kyc-components` provides the required pieces to build an onboarding flow based on a legal entity. To onboard and verify users, you need to create a user interface (UI) to collect user data. To speed up building your integration, Adyen offers onboar

562 lines (559 loc) 21.6 kB
; { try { let e = "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof globalThis ? globalThis : "undefined" != typeof self ? self : {}, n = new e.Error().stack; n && (e._sentryDebugIds = e._sentryDebugIds || {}, e._sentryDebugIds[n] = "cdc9ef73-b35e-43d1-8348-de631d307f4a", e._sentryDebugIdIdentifier = "sentry-dbid-cdc9ef73-b35e-43d1-8348-de631d307f4a"); } catch (e) { } } ; import { jsx, jsxs, Fragment } from "preact/jsx-runtime"; import { useMemo, useState } from "preact/hooks"; import { B as Button, T as Tag, e as entriesOf, I as InputText, u as useI18nContext, s as splitTaskIdentifier, a as TaskItemStatus, b as useExperimentsContext, c as useSettingsContext, d as useGlobalStore, l as listToRecord, v as valuesOf, f as useTaskStatuses, M as Modal, g as createLogger, h as Icon, S as SettingNames } from "./core-B_WrZP-J.js"; var ExperimentNames = /* @__PURE__ */ ((ExperimentNames2) => { ExperimentNames2["AllowMoreRolesForMainRootTrustee"] = "AllowMoreRolesForMainRootTrustee"; ExperimentNames2["ShowUnsupportedEntityType"] = "ShowUnsupportedEntityType"; ExperimentNames2["ShowExtraTaxExemptionReasons"] = "ShowExtraTaxExemptionReasons"; ExperimentNames2["EnableEInvoicingCodeField"] = "EnableEInvoicingCodeField"; ExperimentNames2["EnableCountryOfGoverningLawForUKCompanies"] = "EnableCountryOfGoverningLawForUKCompanies"; ExperimentNames2["HidePayoutAccountTask"] = "HidePayoutAccountTask"; ExperimentNames2["HidePciTask"] = "HidePciTask"; ExperimentNames2["EnableAgeVerification"] = "EnableAgeVerification"; ExperimentNames2["EnableNationalitySGHK"] = "EnableNationalitySGHK"; ExperimentNames2["EnablePreferInstantVerificationFlow"] = "EnablePreferInstantVerificationFlow"; ExperimentNames2["EnableFinancialInformationComponentV4"] = "EnableFinancialInformationComponentV4"; ExperimentNames2["StrictNameAndAddressValidationV4"] = "StrictNameAndAddressValidationV4"; ExperimentNames2["EnableDoingBusinessAsNameV4"] = "EnableDoingBusinessAsNameV4"; ExperimentNames2["EnablePhoneFieldScenario"] = "EnablePhoneFieldScenario"; ExperimentNames2["ShowCustomerSupportV4"] = "ShowCustomerSupportV4"; ExperimentNames2["EnableRegistrationAndTaxAbsentStatesV4"] = "EnableRegistrationAndTaxAbsentStatesV4"; ExperimentNames2["EnableManualCompanyTinVerification"] = "EnableManualCompanyTinVerification"; ExperimentNames2["EnableAutofillFlowForPureIndividualsInKeyMarkets"] = "EnableAutofillFlowForPureIndividualsInKeyMarkets"; ExperimentNames2["EnableAutofillFlowForPureIndividualsInAdditionalMarkets"] = "EnableAutofillFlowForPureIndividualsInAdditionalMarkets"; ExperimentNames2["EnableAutofillFlowForDecisionMakersInKeyMarkets"] = "EnableAutofillFlowForDecisionMakersInKeyMarkets"; ExperimentNames2["EnableAutofillFlowForDecisionMakersInAdditionalMarkets"] = "EnableAutofillFlowForDecisionMakersInAdditionalMarkets"; ExperimentNames2["EnablePreventPoBoxAddress"] = "EnablePreventPoBoxAddress"; ExperimentNames2["EnableLimitCountryBusinessAccountCustomers"] = "EnableLimitCountryBusinessAccountCustomers"; ExperimentNames2["EnableUnincorporatedPartnershipInHO"] = "EnableUnincorporatedPartnershipInHO"; ExperimentNames2["UseOnboardingComponentsForSingpass"] = "UseOnboardingComponentsForSingpass"; ExperimentNames2["EnableCheckOnCreateBankAccount"] = "EnableCheckOnCreateBankAccount"; ExperimentNames2["EnableTaxIdRequiredForBusinessAccountsScenarios"] = "EnableTaxIdRequiredForBusinessAccountsScenarios"; ExperimentNames2["EnableJaJPLocale"] = "EnableJaJPLocale"; ExperimentNames2["CredentialBankingWeightage_EmphasizeCredentialBankingFlow"] = "CredentialBankingWeightage_EmphasizeCredentialBankingFlow"; return ExperimentNames2; })(ExperimentNames || {}); const tabs = "adyen-kyc-tabs"; const styles$1 = { tabs }; const Tabs = ({ tabs: tabs2, activeTab, onChange }) => /* @__PURE__ */ jsx("div", { className: styles$1.tabs, children: tabs2.map(({ name, label, disabled }) => { const buttonVariant = activeTab === name ? "secondary" : "tertiary"; return /* @__PURE__ */ jsx( Button, { onClick: () => onChange(name), variant: buttonVariant, disabled, children: label }, name ); }) }); const filterData = (data, searchTerm) => data.filter(({ key }) => key.toLowerCase().includes(searchTerm.toLowerCase())); const sortData = (data) => [...data].sort(({ key: keyA }, { key: keyB }) => keyA.localeCompare(keyB)); const DebugTable = ({ data, heading, searchTerm, tagPosition = "after", sort = false }) => { const filteredData = useMemo(() => { const filtered = searchTerm ? filterData(data, searchTerm) : data; return sort ? sortData(filtered) : filtered; }, [data, searchTerm]); return /* @__PURE__ */ jsxs("div", { children: [ heading ? /* @__PURE__ */ jsx("h3", { children: heading }) : void 0, filteredData.length === 0 ? /* @__PURE__ */ jsxs("p", { children: [ "No results found for ", /* @__PURE__ */ jsx("strong", { children: searchTerm }) ] }) : /* @__PURE__ */ jsx("table", { children: /* @__PURE__ */ jsx("tbody", { children: filteredData.map(({ key, value, label, variant }) => /* @__PURE__ */ jsxs("tr", { children: [ tagPosition === "before" ? /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Tag, { variant: variant ?? "grey", children: value }) }) : void 0, /* @__PURE__ */ jsxs("td", { children: [ /* @__PURE__ */ jsx("span", { className: "adyen-kyc-debug-modal__table-key", children: key }), label && /* @__PURE__ */ jsx("span", { children: label }) ] }), tagPosition === "after" ? /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(Tag, { variant: variant ?? "grey", children: value }) }) : void 0 ] }, key)) }) }) ] }); }; const getSettingVariant = (value) => { switch (value) { case void 0: return "orange"; case true: return "green"; case false: return "red"; default: return "blue"; } }; const DebugExperimentsAndSettings = ({ experiments, settings }) => { const [searchTerm, setSearchTerm] = useState(""); const experimentRows = entriesOf(experiments).map( ([experimentName, enabled]) => ({ key: `${experimentName}`, value: enabled ? "Enabled" : "Disabled", variant: enabled ? "green" : "red" }) ); const settingRows = entriesOf(settings).map(([settingName, value]) => ({ key: settingName, value: `${value}`, variant: getSettingVariant(value) })); return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx( InputText, { name: "search", value: searchTerm, classNameModifiers: ["search"], onInput: (e) => setSearchTerm(e.target.value), placeholder: "Search for Experiments/Settings 🔎", trimOnBlur: true, spellCheck: false, "aria-label": "Search experiments or settings", "aria-invalid": false } ), /* @__PURE__ */ jsx( DebugTable, { tagPosition: "before", data: experimentRows, heading: "Experiments", searchTerm, sort: true } ), /* @__PURE__ */ jsx(DebugTable, { data: settingRows, heading: "Settings", searchTerm, sort: true }) ] }); }; const getRanges = (search, element) => { var _a; const textNode = element.childNodes[0]; const content = (_a = textNode.textContent) == null ? void 0 : _a.toLowerCase(); if (!content) return []; const indexes = []; const matches = [...content.matchAll(search)]; matches.forEach((match) => { indexes.push({ s: match.index, e: match.index + match[0].length }); }); return indexes.map((index) => { const range = new Range(); range.setStart(textNode, index.s); range.setEnd(textNode, index.e); return range; }); }; const createHighlightFn = (name, highlight, el, scope) => { return CSS.highlights.set(`${name}-${scope}`, new Highlight(...getRanges(highlight.regex, el))); }; const createHighlightCss = (name, highlight, scope) => { return `::highlight(${name}-${scope}) { color: var(${highlight.css}); }`; }; const transformModule = (highlights, codeNode, scope) => { return Object.entries(highlights).map(([name, definition]) => ({ apply: () => createHighlightFn(name, definition, codeNode, scope), css: createHighlightCss(name, definition, scope) })); }; const supportedModules = ["plaintext", "json", "yaml", "css"]; const moduleMap = { plaintext: () => import("./plaintext-DuNA8yq2.js"), json: () => import("./json-DbFHJS1e.js"), yaml: () => import("./yaml-CZT9wc9a.js"), css: () => import("./css-BdtMD5A5.js") }; const getModule = async (name) => { if (!supportedModules.includes(name)) { const plaintext = await moduleMap["plaintext"](); return plaintext.default; } const module = await moduleMap[name](); if (!module) { const plaintext = await moduleMap["plaintext"](); return plaintext.default; } return module.default; }; const cssProps = { text: "--mng-text", background: "--mng-background", string: "--mng-string", key: "--mng-key", number: "--mng-number", boolean: "--mng-boolean", null: "--mng-null", comment: "--mng-comment", curlyBrackets: "--mng-curly-brackets", squareBrackets: "--mng-square-brackets", keyword: "--mng-keyword", dashes: "--mng-dashes" }; const css = ` * { box-sizing: border-box; } :host { display: inline-grid; white-space: pre-line; } pre { width: 100%; height: 100%; padding: 1em; margin: 0; background-color: var(${cssProps.background}); color: var(${cssProps.text}); } code { width: 100%; height: 100%; display: inline-block; outline: none; white-space: pre-line; } :host { ${cssProps.text}: #213547; ${cssProps.background}: #f1f1f1; ${cssProps.string}: #8b251e; ${cssProps.key}: #c32b1d; ${cssProps.number}: #4a845b; ${cssProps.boolean}: #3716f5; ${cssProps.null}: #3716f5; ${cssProps.comment}: #4e862d; ${cssProps.curlyBrackets}: #59913e; ${cssProps.squareBrackets}: #59913e; ${cssProps.keyword}: #666; ${cssProps.dashes}: #444; } @media (prefers-color-scheme: dark) { :host { ${cssProps.text}: #f1f1f1; ${cssProps.background}: #1f1f1f; ${cssProps.string}: #ce916f; ${cssProps.key}: #9cdcfe; ${cssProps.number}: #b5cea8; ${cssProps.boolean}: #569cd6; ${cssProps.null}: #569cd6; ${cssProps.comment}: #438a55; ${cssProps.curlyBrackets}: #ffd708; ${cssProps.squareBrackets}: #da70b9; ${cssProps.keyword}: #dcdcaa; ${cssProps.dashes}: #ddd; } }`; let MonogonCode$1 = class MonogonCode extends HTMLElement { constructor() { super(); Object.defineProperty(this, "value", { enumerable: true, configurable: true, writable: true, value: "" }); Object.defineProperty(this, "codeEl", { enumerable: true, configurable: true, writable: true, value: null }); Object.defineProperty(this, "styleEl", { enumerable: true, configurable: true, writable: true, value: null }); Object.defineProperty(this, "applyHighlights", { enumerable: true, configurable: true, writable: true, value: () => { } }); } async connectedCallback() { await this.prepare(); setTimeout(() => { this.refresh(); }, 1); } async attributeChangedCallback(oldValue, newValue) { if (oldValue !== newValue) { await this.refresh(); } } async prepare() { const shadow = this.shadowRoot || this.attachShadow({ mode: "open" }); shadow.innerHTML = ""; const themeStyleEl = document.createElement("style"); themeStyleEl.textContent = css; shadow.appendChild(themeStyleEl); const preEl = document.createElement("pre"); const codeEl = document.createElement("code"); codeEl.setAttribute("contenteditable", "plaintext-only"); codeEl.setAttribute("spellcheck", "false"); shadow.appendChild(preEl); preEl.appendChild(codeEl); codeEl.addEventListener("input", () => { this.codeEl.normalize(); this.value = this.codeEl.textContent ?? ""; this.applyHighlights(); }); this.codeEl = codeEl; this.styleEl = themeStyleEl; } async refresh() { var _a; if (!this.codeEl) return; const moduleName = this.getAttribute("lang") ?? "plaintext"; const module = await getModule(moduleName); const content = this.getAttribute("content") ?? ""; this.value = content; this.codeEl.textContent = module.format ? module.format(content) : content; if (!((_a = this.codeEl.childNodes) == null ? void 0 : _a[0])) return; const littleHash = window.crypto.randomUUID().substring(0, 6); const definitions = transformModule(module.definitions, this.codeEl, littleHash); const moduleCss = definitions.map((m) => m.css).join(" "); this.styleEl.textContent += `${moduleCss}`; this.applyHighlights = () => { definitions.forEach((highlight) => { highlight.apply(); }); }; this.applyHighlights(); } }; Object.defineProperty(MonogonCode$1, "observedAttributes", { enumerable: true, configurable: true, writable: true, value: ["content", "lang"] }); if (!customElements.get("monogon-code")) customElements.define("monogon-code", MonogonCode$1); const MonogonCode2 = ({ content, lang }) => { return /* @__PURE__ */ jsx("monogon-code", { content, lang }); }; const DebugLegalEntityData = ({ legalEntityData }) => { var _a; if (!legalEntityData) return /* @__PURE__ */ jsx(Fragment, {}); const { rootLegalEntity, rootLegalEntityType } = legalEntityData; const uboDetails = ((_a = rootLegalEntity.entityAssociations) == null ? void 0 : _a.map( ({ name, type, jobTitle }) => ( // If `name` is undefined, replace the tuple with `null` to easily filter it out later. Checking this to ensure that the 'data' for DebugTable always has a keyName. name ? { key: name, value: `${type}`, label: jobTitle, variant: "blue" } : null ) ).filter(Boolean)) ?? []; return /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsxs("span", { children: [ "Root legal entity type: ", /* @__PURE__ */ jsx(Tag, { children: rootLegalEntityType }) ] }), uboDetails.length ? /* @__PURE__ */ jsx(DebugTable, { data: uboDetails, heading: "Decision Makers" }) : void 0, rootLegalEntity ? /* @__PURE__ */ jsx(MonogonCode2, { lang: "json", content: JSON.stringify(rootLegalEntity, null, 2) }) : void 0 ] }); }; const DebugMetadata = ({ metadata: { sdkVersion, locale, rootLegalEntityId } }) => { const rows = [ { key: "SDK version", value: sdkVersion, variant: "green" }, { key: "Locale", value: locale, variant: "blue" }, { key: "Root legal entity ID", value: rootLegalEntityId, variant: "teal" } ]; return /* @__PURE__ */ jsx("div", { className: "adyen-kyc-debug-modal__meta", children: /* @__PURE__ */ jsx(DebugTable, { data: rows }) }); }; const header = "adyen-kyc-header"; const taskName = "adyen-kyc-task-name"; const table = "adyen-kyc-table"; const styles = { header, taskName, table }; const DebugTaskStatuses = ({ taskStatuses }) => { const { i18n } = useI18nContext(); return /* @__PURE__ */ jsxs("table", { className: styles.table, children: [ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { className: styles.header, children: [ /* @__PURE__ */ jsx("th", { children: i18n.get("task") }), /* @__PURE__ */ jsx("th", { children: i18n.get("status") }), /* @__PURE__ */ jsx("th", { children: i18n.get("reason") }) ] }) }), /* @__PURE__ */ jsx("tbody", { children: entriesOf(taskStatuses).sort(([t1], [t2]) => t1.localeCompare(t2)).map(([task, status]) => { const { taskType, id } = splitTaskIdentifier(task); return /* @__PURE__ */ jsxs("tr", { children: [ /* @__PURE__ */ jsxs("td", { className: styles.taskName, children: [ taskType, id ? `: ${id}` : "" ] }), status ? /* @__PURE__ */ jsxs(Fragment, { children: [ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(TaskItemStatus, { status: status.status }) }), /* @__PURE__ */ jsxs("td", { children: [ i18n.get(status.reason), /* @__PURE__ */ jsx(ExplainDetails, { status }) ] }) ] }) : /* @__PURE__ */ jsx(Fragment, {}) ] }, task); }) }) ] }); }; const ExplainDetails = ({ status }) => { const { reason, details } = status; switch (reason) { case "invalidInputError": { const verificationError = details.verificationError; const subErrors = verificationError.subErrors; return /* @__PURE__ */ jsxs("div", { children: [ verificationError.code, ": ", verificationError.message, subErrors ? /* @__PURE__ */ jsx("ul", { children: (verificationError.subErrors ?? []).map((subError) => /* @__PURE__ */ jsxs("li", { children: [ subError.code, ": ", subError.message ] }, subError.code)) }) : /* @__PURE__ */ jsx(Fragment, {}) ] }); } case "dataMissingError": { const verificationError = details.verificationError; const subErrors = verificationError.subErrors; return /* @__PURE__ */ jsxs("div", { children: [ verificationError.code, ": ", verificationError.message, subErrors ? /* @__PURE__ */ jsx("ul", { children: (verificationError.subErrors ?? []).map((subError) => /* @__PURE__ */ jsxs("li", { children: [ subError.code, ": ", subError.message ] }, subError.code)) }) : /* @__PURE__ */ jsx(Fragment, {}) ] }); } case "pendingCapabilities": { const pendingCapabilities = details.pendingCapabilities; return /* @__PURE__ */ jsx("ul", { children: pendingCapabilities.map((capabilityName) => /* @__PURE__ */ jsx("li", { children: capabilityName }, capabilityName)) }); } } }; const logger = createLogger(); const DebugModal = ({ onExit }) => { const { isExperimentEnabled } = useExperimentsContext(); const { getSetting } = useSettingsContext(); const [debugInfoCopied, setDebugInfoCopied] = useState(false); const { i18n } = useI18nContext(); const [tab, setTab] = useState("metadata"); const rootLegalEntity = useGlobalStore((store) => store.rootLegalEntity); const metadata = { sdkVersion: "3.67.3", locale: i18n.locale, rootLegalEntityId: rootLegalEntity.id }; const experiments = listToRecord(valuesOf(ExperimentNames), isExperimentEnabled); const settings = listToRecord(valuesOf(SettingNames), getSetting); const taskStatuses = useTaskStatuses(); const legalEntityData = { rootLegalEntity, rootLegalEntityType: rootLegalEntity.type }; const copyToClipboard = async () => { const toCopy = { metadata, experiments, settings, taskStatuses, legalEntityData }; await window.navigator.clipboard.writeText(JSON.stringify(toCopy, null, 2)); setDebugInfoCopied(true); setTimeout(() => { setDebugInfoCopied(false); }, 5e3); }; return /* @__PURE__ */ jsx(Modal, { size: "fullscreen", onClose: onExit, ariaLabel: "Debug", children: /* @__PURE__ */ jsxs("div", { className: "adyen-kyc-debug-modal", children: [ /* @__PURE__ */ jsxs("div", { className: "adyen-kyc-debug-modal__header", children: [ /* @__PURE__ */ jsx("h1", { children: "Debug" }), " ", /* @__PURE__ */ jsx( Tabs, { activeTab: tab, onChange: (tab2) => setTab(tab2), tabs: [ { name: "metadata", label: "Metadata" }, { name: "experimentsSettings", label: "Experiments & Settings" }, { name: "taskStatuses", label: "Task Statuses" }, { name: "legalEntityData", label: "Legal Entity Data" } ] } ) ] }), /* @__PURE__ */ jsxs("div", { className: "adyen-kyc-debug-modal__content", children: [ tab === "metadata" ? /* @__PURE__ */ jsx(DebugMetadata, { metadata }) : void 0, tab === "taskStatuses" ? /* @__PURE__ */ jsx(DebugTaskStatuses, { taskStatuses }) : void 0, tab === "experimentsSettings" ? /* @__PURE__ */ jsx(DebugExperimentsAndSettings, { experiments, settings }) : void 0, tab === "legalEntityData" ? /* @__PURE__ */ jsx(DebugLegalEntityData, { legalEntityData }) : void 0 ] }), /* @__PURE__ */ jsx("div", { className: "adyen-kyc-debug-modal__footer", children: /* @__PURE__ */ jsxs("div", { children: [ /* @__PURE__ */ jsx( Button, { icon: "document", onClick: () => { copyToClipboard().catch((error) => { logger.error("Error copying to clipboard:", error); }); }, children: "Copy debug info" } ), debugInfoCopied ? /* @__PURE__ */ jsxs("span", { className: "adyen-kyc-debug-modal__footer--copy-status", children: [ /* @__PURE__ */ jsx(Icon, { name: "check" }), " Copied!" ] }) : void 0 ] }) }) ] }) }); }; const DebugModal$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ __proto__: null, DebugModal }, Symbol.toStringTag, { value: "Module" })); export { DebugModal$1 as D, cssProps as c };