smartcomply-web-sdk 1.0.98 → 1.0.100

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.
Files changed (43) hide show
  1. package/dist/client/Smartcomply.d.ts +1 -1
  2. package/dist/client/Smartcomply.d.ts.map +1 -1
  3. package/dist/client/Smartcomply.js +1 -1
  4. package/dist/client/Smartcomply.js.map +1 -1
  5. package/dist/esm/client/Smartcomply.d.ts +1 -1
  6. package/dist/esm/client/Smartcomply.d.ts.map +1 -1
  7. package/dist/esm/client/Smartcomply.js +1 -1
  8. package/dist/esm/client/Smartcomply.js.map +1 -1
  9. package/dist/esm/flow/DocumentCapture.d.ts +3 -19
  10. package/dist/esm/flow/DocumentCapture.d.ts.map +1 -1
  11. package/dist/esm/flow/DocumentCapture.js +22 -170
  12. package/dist/esm/flow/DocumentCapture.js.map +1 -1
  13. package/dist/esm/flow/SmartComplyFlow.d.ts +4 -3
  14. package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
  15. package/dist/esm/flow/SmartComplyFlow.js +35 -37
  16. package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
  17. package/dist/esm/utils/constants.d.ts +9 -8
  18. package/dist/esm/utils/constants.d.ts.map +1 -1
  19. package/dist/esm/utils/constants.js +10 -9
  20. package/dist/esm/utils/constants.js.map +1 -1
  21. package/dist/esm/utils/documentRules.d.ts +1 -2
  22. package/dist/esm/utils/documentRules.d.ts.map +1 -1
  23. package/dist/esm/utils/documentRules.js +1 -2
  24. package/dist/esm/utils/documentRules.js.map +1 -1
  25. package/dist/flow/DocumentCapture.d.ts +3 -19
  26. package/dist/flow/DocumentCapture.d.ts.map +1 -1
  27. package/dist/flow/DocumentCapture.js +22 -170
  28. package/dist/flow/DocumentCapture.js.map +1 -1
  29. package/dist/flow/SmartComplyFlow.d.ts +4 -3
  30. package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
  31. package/dist/flow/SmartComplyFlow.js +34 -36
  32. package/dist/flow/SmartComplyFlow.js.map +1 -1
  33. package/dist/smartcomply.browser.js +40 -184
  34. package/dist/smartcomply.browser.js.map +3 -3
  35. package/dist/utils/constants.d.ts +9 -8
  36. package/dist/utils/constants.d.ts.map +1 -1
  37. package/dist/utils/constants.js +10 -9
  38. package/dist/utils/constants.js.map +1 -1
  39. package/dist/utils/documentRules.d.ts +1 -2
  40. package/dist/utils/documentRules.d.ts.map +1 -1
  41. package/dist/utils/documentRules.js +1 -2
  42. package/dist/utils/documentRules.js.map +1 -1
  43. package/package.json +66 -66
@@ -2,10 +2,9 @@ import { SmartComply } from "../client/Smartcomply";
2
2
  import { getTheme, TYPE, RADIUS } from "./theme";
3
3
  import { DocumentCapture, DocumentCaptureCancelledError } from "./DocumentCapture";
4
4
  import { isUploadFieldType } from "../utils/channels";
5
- import { isPdf } from "../utils/documentFiles";
6
5
  import { collectDeviceMetadata } from "../utils/device";
7
6
  import { requiresBackSide } from "../utils/documentRules";
8
- import { DEFAULT_CHALLENGE_ACTIONS } from "../utils/constants";
7
+ import { DEFAULT_CHALLENGE_ACTIONS, MAX_DOCUMENT_BYTES } from "../utils/constants";
9
8
  import { icon } from "./icons";
10
9
  import { renderSpinner, renderInlineSpinner } from "./spinner";
11
10
  import { SDKError } from "../errors/SDKError";
@@ -86,8 +85,9 @@ export function isChannelDocumentFlow(idType, globalDocFlow) {
86
85
  }
87
86
  /**
88
87
  * Picks the channel list for the "Select document type" / "Select ID type"
89
- * screen — the one list that actually matches this screen's mode, not a
90
- * flat list mixing both categories.
88
+ * screen: the list matching this screen's mode, both lists when the config
89
+ * enables both modes, and the other list when this mode has nothing for the
90
+ * country (so the screen is never an empty dead end).
91
91
  *
92
92
  * Reported live: the deployed widget's document-scan screen showed a bare
93
93
  * "Passport" (data_verification, number-entry) right next to "Document
@@ -100,10 +100,21 @@ export function isChannelDocumentFlow(idType, globalDocFlow) {
100
100
  * what actually removes the duplicate, not just how each entry displays
101
101
  * (see isChannelDocumentFlow above, which only decides that).
102
102
  */
103
- export function selectIdTypesForScreen(byCategory, globalDocFlow) {
103
+ export function selectIdTypesForScreen(byCategory, globalDocFlow, verificationTypes = []) {
104
104
  if (!byCategory)
105
105
  return [];
106
- return (globalDocFlow ? byCategory.document_verification : byCategory.data_verification) || [];
106
+ const documents = byCategory.document_verification || [];
107
+ const data = byCategory.data_verification || [];
108
+ // A config with both modes offers both kinds; each card then routes on its
109
+ // own channel (isChannelDocumentFlow), scan or number entry.
110
+ if (verificationTypes.includes("document_verification") && verificationTypes.includes("data_verification")) {
111
+ return [...documents, ...data];
112
+ }
113
+ const primary = globalDocFlow ? documents : data;
114
+ // Reported live: a country with nothing in this screen's category showed
115
+ // an empty "Select document type" screen with no way forward. Showing the
116
+ // other category is what the widget did before the split (1.0.94).
117
+ return primary.length > 0 ? primary : (globalDocFlow ? data : documents);
107
118
  }
108
119
  /**
109
120
  * Whether a showErrorStep() message is about an expired/invalid resume or
@@ -292,24 +303,6 @@ function _parseOcrDate(raw) {
292
303
  const d = new Date(s);
293
304
  return isNaN(d.getTime()) ? null : d;
294
305
  }
295
- // ── W12: Image compression before document upload ────────────────────────────
296
- async function _compressImage(blob, maxWidth = 1600, quality = 0.85) {
297
- try {
298
- const bmp = await createImageBitmap(blob);
299
- const scale = Math.min(1, maxWidth / bmp.width);
300
- const w = Math.round(bmp.width * scale);
301
- const h = Math.round(bmp.height * scale);
302
- const canvas = document.createElement("canvas");
303
- canvas.width = w;
304
- canvas.height = h;
305
- canvas.getContext("2d").drawImage(bmp, 0, 0, w, h);
306
- bmp.close();
307
- return await new Promise((res, rej) => canvas.toBlob(b => b ? res(b) : rej(new Error("Compression failed")), "image/jpeg", quality));
308
- }
309
- catch {
310
- return blob; // fallback to original on any error
311
- }
312
- }
313
306
  // ── Document type code → human label ─────────────────────────────────────────
314
307
  function _formatDocType(code) {
315
308
  const map = {
@@ -1175,7 +1168,17 @@ export class SmartComplyFlow {
1175
1168
  : "Choose the ID you want to verify";
1176
1169
  container.appendChild(subtitle);
1177
1170
  const channels = this.sdkConfig?.channels || {};
1178
- const idTypes = selectIdTypesForScreen(channels[this.selectedCountry], globalDocFlow);
1171
+ const vType = this.sdkConfig?.verification_type;
1172
+ const verificationTypes = !vType ? [] : Array.isArray(vType) ? vType : [vType];
1173
+ const idTypes = selectIdTypesForScreen(channels[this.selectedCountry], globalDocFlow, verificationTypes);
1174
+ if (idTypes.length === 0) {
1175
+ const empty = document.createElement("div");
1176
+ empty.style.cssText = `color:${this.theme.textSecondary};font-size:13px;line-height:1.6;`;
1177
+ empty.textContent =
1178
+ "No ID types are set up for this country yet. Please go back and choose another country, or contact support.";
1179
+ container.appendChild(empty);
1180
+ return;
1181
+ }
1179
1182
  for (const idType of idTypes) {
1180
1183
  const typeName = typeof idType === "string" ? idType : idType.name;
1181
1184
  // Use code (canonical) for API calls, fallback to name for backward compatibility
@@ -2136,15 +2139,11 @@ export class SmartComplyFlow {
2136
2139
  * Process document capture result with front/back support
2137
2140
  */
2138
2141
  async processDocumentCaptureResult(result, captureContainer, container) {
2139
- // B2+P2: Compress both images once here. Do NOT assign documentBlob twice
2140
- // (old code set it to the raw blob first, then overwrote with compressed).
2141
- // processDocumentBlob also ran _compressImage — that second pass is removed
2142
- // below so compression only happens once.
2143
- // A PDF is sent as-is: only photos are re-encoded.
2144
- this.documentBlob = isPdf(result.front) ? result.front : await _compressImage(result.front, 1600, 0.85);
2145
- this.documentBackBlob = !result.back
2146
- ? null
2147
- : isPdf(result.back) ? result.back : await _compressImage(result.back, 1600, 0.85);
2142
+ // Uploaded exactly as captured or picked, photo or PDF: re-encoding a
2143
+ // small passport photo as JPEG blurred its machine-readable lines and the
2144
+ // OCR rejected a clear Rwandan passport as "country: unknown".
2145
+ this.documentBlob = result.front;
2146
+ this.documentBackBlob = result.back || null;
2148
2147
  this._documentViaCamera = result.viaCamera;
2149
2148
  // Process the front image — pass the already-compressed blob
2150
2149
  await this.processDocumentBlob(this.documentBlob, captureContainer, container);
@@ -2157,12 +2156,11 @@ export class SmartComplyFlow {
2157
2156
  let retryCount = 0;
2158
2157
  const attemptProcessing = async () => {
2159
2158
  try {
2160
- // Validate blob — compression already done in processDocumentCaptureResult (P2)
2161
2159
  if (!blob || blob.size === 0) {
2162
2160
  throw new Error("Failed to capture document. Please try again.");
2163
2161
  }
2164
- if (blob.size > 5 * 1024 * 1024) {
2165
- throw new Error("Document image is too large. Please retake in better lighting or use a clearer photo.");
2162
+ if (blob.size > MAX_DOCUMENT_BYTES) {
2163
+ throw new Error(`Document is too large. Please use a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`);
2166
2164
  }
2167
2165
  this.documentBlob = blob;
2168
2166
  // Show scanning state