@sekyro/web 0.1.0-rc.5 → 0.1.0-rc.7

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 (67) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/LICENSE +3 -3
  3. package/README.md +4 -4
  4. package/dist/chunk-B45J4KC3.js +1 -0
  5. package/dist/chunk-BMA36W2W.js +1 -0
  6. package/dist/chunk-FPXL63KZ.js +1 -0
  7. package/dist/chunk-IYUOYINS.js +1 -0
  8. package/dist/chunk-P7ECRN47.js +1 -0
  9. package/dist/chunk-SXZCL5NO.js +1 -0
  10. package/dist/chunk-YOB4ZTYN.js +1 -0
  11. package/dist/chunk-YQBK6OIM.js +1 -0
  12. package/dist/client/index.cjs +1 -357
  13. package/dist/client/index.d.cts +2 -2
  14. package/dist/client/index.d.ts +2 -2
  15. package/dist/client/index.js +1 -15
  16. package/dist/core/index.cjs +1 -1639
  17. package/dist/core/index.js +1 -139
  18. package/dist/core/v3/detect-worker.cjs +1 -392
  19. package/dist/core/v3/detect-worker.js +1 -13
  20. package/dist/{create-verification-CA-3szPI.d.cts → create-verification-C2JhOO6Y.d.cts} +100 -15
  21. package/dist/{create-verification-c98uAxbl.d.ts → create-verification-CGazwtAh.d.ts} +100 -15
  22. package/dist/detector-scanic-VQFFXKTL.js +1 -0
  23. package/dist/{hosted-client-DWzCRYJK.d.ts → hosted-client-kBeq-mnJ.d.cts} +188 -7
  24. package/dist/{hosted-client-DWzCRYJK.d.cts → hosted-client-kBeq-mnJ.d.ts} +188 -7
  25. package/dist/index.cjs +1 -3020
  26. package/dist/index.d.cts +2 -2
  27. package/dist/index.d.ts +2 -2
  28. package/dist/index.js +1 -85
  29. package/dist/internal/index.cjs +1 -4429
  30. package/dist/internal/index.d.cts +10 -7
  31. package/dist/internal/index.d.ts +10 -7
  32. package/dist/internal/index.js +1 -657
  33. package/dist/popup/index.cjs +1 -76
  34. package/dist/popup/index.js +1 -11
  35. package/dist/scanic-ml-stub-KW7IZHUT.js +1 -0
  36. package/package.json +5 -8
  37. package/sbom.cdx.json +195 -0
  38. package/dist/chunk-MWNFSNMP.js +0 -52
  39. package/dist/chunk-MWNFSNMP.js.map +0 -1
  40. package/dist/chunk-NILNKLK6.js +0 -50
  41. package/dist/chunk-NILNKLK6.js.map +0 -1
  42. package/dist/chunk-NWF46H7K.js +0 -359
  43. package/dist/chunk-NWF46H7K.js.map +0 -1
  44. package/dist/chunk-SGDXLAXR.js +0 -1163
  45. package/dist/chunk-SGDXLAXR.js.map +0 -1
  46. package/dist/chunk-TG5IE552.js +0 -1128
  47. package/dist/chunk-TG5IE552.js.map +0 -1
  48. package/dist/chunk-WY6U7AIK.js +0 -193
  49. package/dist/chunk-WY6U7AIK.js.map +0 -1
  50. package/dist/chunk-YVFF4Q4G.js +0 -327
  51. package/dist/chunk-YVFF4Q4G.js.map +0 -1
  52. package/dist/client/index.cjs.map +0 -1
  53. package/dist/client/index.js.map +0 -1
  54. package/dist/core/index.cjs.map +0 -1
  55. package/dist/core/index.js.map +0 -1
  56. package/dist/core/v3/detect-worker.cjs.map +0 -1
  57. package/dist/core/v3/detect-worker.js.map +0 -1
  58. package/dist/detector-scanic-4C6IEW2K.js +0 -787
  59. package/dist/detector-scanic-4C6IEW2K.js.map +0 -1
  60. package/dist/index.cjs.map +0 -1
  61. package/dist/index.js.map +0 -1
  62. package/dist/internal/index.cjs.map +0 -1
  63. package/dist/internal/index.js.map +0 -1
  64. package/dist/popup/index.cjs.map +0 -1
  65. package/dist/popup/index.js.map +0 -1
  66. package/dist/scanic-ml-stub-S2OZ6HEF.js +0 -10
  67. package/dist/scanic-ml-stub-S2OZ6HEF.js.map +0 -1
@@ -1,357 +1 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
- // src/client/index.ts
21
- var client_exports = {};
22
- __export(client_exports, {
23
- HostedApiError: () => HostedApiError,
24
- HostedClient: () => HostedClient,
25
- KNOWN_CODES: () => KNOWN_CODES,
26
- isKnownCode: () => isKnownCode,
27
- stripMimeParams: () => stripMimeParams
28
- });
29
- module.exports = __toCommonJS(client_exports);
30
-
31
- // src/client/errors.ts
32
- var KNOWN_CODES = [
33
- // auth / addressing (session-token.guard, controllers' own-session guards)
34
- "session_token_invalid",
35
- // 401 — missing/invalid/expired/revoked token
36
- "session_token_required",
37
- // 403 — non-session-token principal on a hosted route (defensive)
38
- "session_token_session_mismatch",
39
- // 403 — route :id differs from the token's bound session
40
- "session_not_found",
41
- // 404 — token's session missing/foreign (findOwned)
42
- // rate limiting (session-token.guard — per-token + per-IP buckets)
43
- "rate_limit_exceeded",
44
- // 429 + Retry-After header (seconds)
45
- // consent gate (Task 0 — submit AND media presign/complete)
46
- "consent_required",
47
- // 409 — record consent before uploading/submitting
48
- // submit flow (sessions.service.submitCheck)
49
- "session_not_active",
50
- // 409 — session is terminal/review; no further submissions
51
- "check_not_found",
52
- // 404 — session has no such checkType
53
- "check_already_finalized",
54
- // 409 — re-submit of a terminal/review check
55
- "check_out_of_order",
56
- // 409 — only the frontier check accepts a submission
57
- "check_type_unsupported",
58
- // 400 — no registered executor for the checkType
59
- "force_outcome_forbidden",
60
- // 403 — forceOutcome on a live session (plan D-C)
61
- "attestation_invalid",
62
- // 400 (Task 1) — Turnstile/attestation failed; reload and retry
63
- "nni_locked",
64
- // 409 (Plan A Task 2) — session is bound to a server-provided NNI; a different client NNI was sent
65
- // media (media.service)
66
- "media_content_type_not_allowed",
67
- // 400 — outside the per-kind MIME allowlist
68
- "media_too_large",
69
- // 413 — over the per-kind byte cap
70
- "media_key_invalid",
71
- // 400 — not a well-formed pending key
72
- "media_key_forbidden",
73
- // 403 — key names another session's pending space
74
- "media_not_found",
75
- // 404 — no uploaded object behind the key
76
- "media_unreadable",
77
- // 422 — magic-byte sniff rejected the object
78
- "media_session_invalid",
79
- // 400 — sessionId unusable as a key segment (never in practice)
80
- // idempotency (idempotency.interceptor — Task 2)
81
- "idempotency_key_collision",
82
- // 409 — same key, different body hash
83
- "idempotency_in_progress",
84
- // 409 — concurrent identical request mid-flight (client auto-retries)
85
- "idempotency_key_required",
86
- // 400 — only on @Idempotent({required:true}) routes (none hosted yet)
87
- // validation + fallback
88
- "validation_error",
89
- // 400 — ValibotPipe rejection (camelToSnake of 'ValidationError')
90
- "internal_error",
91
- // 500 — unhandled server error
92
- // client-synthesized (never sent by the backend)
93
- "unknown_error",
94
- // unparseable (non-JSON) response body — error OR 2xx (defensive)
95
- "upload_failed",
96
- // the bare Spaces PUT answered non-2xx
97
- "network_error",
98
- // fetch rejected: connection drop / DNS / CORS / mid-transfer (status 0)
99
- "timeout"
100
- // AbortSignal.timeout fired — API calls 30 s default, Spaces PUT 15 min (status 0)
101
- ];
102
- function isKnownCode(code) {
103
- return KNOWN_CODES.includes(code);
104
- }
105
- var HostedApiError = class extends Error {
106
- constructor(args) {
107
- super(args.message);
108
- this.name = "HostedApiError";
109
- this.status = args.status;
110
- this.code = args.code;
111
- if (args.retryAfterSeconds !== void 0) this.retryAfterSeconds = args.retryAfterSeconds;
112
- }
113
- };
114
-
115
- // src/client/hosted-client.ts
116
- var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
117
- var SPACES_PUT_TIMEOUT_MS = 9e5;
118
- var UPLOAD_ERROR_SNIPPET_CHARS = 200;
119
- var IN_PROGRESS_RETRY_ATTEMPTS = 5;
120
- var IN_PROGRESS_RETRY_DELAY_MS = 400;
121
- function stripMimeParams(contentType) {
122
- return (contentType.split(";")[0] ?? "").trim();
123
- }
124
- var MEDIA_INPUT_FIELD = {
125
- liveness: "clipKey",
126
- face_match: "imageKey",
127
- doc_ocr: "imageKey"
128
- };
129
- var HostedClient = class {
130
- constructor(opts) {
131
- this.sessionId = null;
132
- this.bootstrap = null;
133
- this.apiOrigin = opts.apiOrigin.replace(/\/+$/, "");
134
- this.sessionToken = opts.sessionToken;
135
- const impl = opts.fetch;
136
- this.fetchImpl = (input, init) => (impl ?? globalThis.fetch).call(globalThis, input, init);
137
- this.requestTimeoutMs = opts.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
138
- this.retryAttempts = opts.inProgressRetry?.attempts ?? IN_PROGRESS_RETRY_ATTEMPTS;
139
- this.retryDelayMs = opts.inProgressRetry?.delayMs ?? IN_PROGRESS_RETRY_DELAY_MS;
140
- }
141
- /** Token-addressed bootstrap — the hosted page's first call. Caches the sessionId. */
142
- async getSession() {
143
- const view = await this.api("GET", "/hosted/session");
144
- this.sessionId = view.sessionId;
145
- return view;
146
- }
147
- /**
148
- * Record consent once (201; an idempotent replay answers 200 with
149
- * `alreadyRecorded: true`). Until recorded, media presign/complete AND check
150
- * submission answer 409 `consent_required`.
151
- */
152
- async recordConsent(locale) {
153
- return this.api("POST", "/hosted/consent", { body: { locale } });
154
- }
155
- /**
156
- * Presign a Spaces PUT for a new pending object. `contentType` is stripped of
157
- * MIME parameters defensively (the allowlist holds bare types; the engine's
158
- * `clipMimeType` carries codec params) — PUT with the SAME bare type, or the
159
- * signed-header check rejects the upload.
160
- */
161
- async presign(kind, contentType, contentLength) {
162
- const id = await this.ensureSessionId();
163
- const body = { kind, contentType: stripMimeParams(contentType), contentLength };
164
- return this.api("POST", `/sessions/${id}/media`, { body });
165
- }
166
- /**
167
- * Bare PUT to the presigned Spaces URL: EXACTLY the signed headers — the
168
- * declared Content-Type and the blob body. NO `x-session-token` (the
169
- * signature IS the credential; an extra header breaks nothing but leaks the
170
- * token to a third-party host) and no JSON envelope.
171
- *
172
- * `contentType` is param-stripped here too (idempotent for bare types): the
173
- * presign strips internally, so a caller composing manually with the engine's
174
- * parameterful `clipMimeType` would otherwise sign `video/webm` but PUT
175
- * `video/webm;codecs=…` — a signed-header mismatch S3 rejects at runtime.
176
- *
177
- * Timeout: 15 min (`AbortSignal.timeout(900_000)`, matching the presign TTL)
178
- * rather than the API calls' 30 s — a 15 MB clip on a slow link legitimately
179
- * exceeds 30 s, but a stalled in-flight socket must still be bounded (the TTL
180
- * alone only bounds when a PUT can START).
181
- *
182
- * Failures are ALWAYS typed: non-2xx throws {@link HostedApiError} with the
183
- * client-synthesized `upload_failed` (message carries a truncated S3 body
184
- * snippet — e.g. SignatureDoesNotMatch); a mid-transfer drop → `network_error`;
185
- * the timeout → `timeout`.
186
- */
187
- async uploadToSpaces(uploadUrl, blob, contentType) {
188
- let res;
189
- try {
190
- res = await this.fetchImpl(uploadUrl, {
191
- method: "PUT",
192
- headers: { "content-type": stripMimeParams(contentType) },
193
- body: blob,
194
- signal: AbortSignal.timeout(SPACES_PUT_TIMEOUT_MS)
195
- });
196
- } catch (err) {
197
- throw asTransportError(err);
198
- }
199
- if (!res.ok) {
200
- const snippet = (await res.text().catch(() => "")).slice(0, UPLOAD_ERROR_SNIPPET_CHARS);
201
- throw new HostedApiError({
202
- status: res.status,
203
- code: "upload_failed",
204
- message: `media upload failed (HTTP ${res.status})${snippet ? `: ${snippet}` : ""}`
205
- });
206
- }
207
- }
208
- /** Finalize an upload: the backend sniffs + promotes; returns the PROMOTED key to submit. */
209
- async completeMedia(key) {
210
- const id = await this.ensureSessionId();
211
- return this.api("POST", `/sessions/${id}/media/complete`, {
212
- body: { key }
213
- });
214
- }
215
- /**
216
- * Submit one check. Sends `{input, forceOutcome?}` (SubmitCheckSchema) and the
217
- * optional `x-idempotency-key` header. Returns the whitelisted SessionView.
218
- */
219
- async submitCheck(checkType, input, opts = {}) {
220
- const id = await this.ensureSessionId();
221
- const body = {
222
- input,
223
- ...opts.forceOutcome !== void 0 ? { forceOutcome: opts.forceOutcome } : {}
224
- };
225
- return this.api("POST", `/sessions/${id}/checks/${checkType}`, {
226
- body,
227
- ...opts.idempotencyKey !== void 0 ? { idempotencyKey: opts.idempotencyKey } : {}
228
- });
229
- }
230
- /**
231
- * Convenience composition: presign → PUT → complete → submit, passing the
232
- * PROMOTED key (from complete's response — never the pending presign key)
233
- * into the check's media input field (`clipKey` for liveness, `imageKey` for
234
- * face_match/doc_ocr). `extraInput` carries the remaining input fields
235
- * (liveness `attestation`, doc_ocr `side`). The media content type is
236
- * param-stripped ONCE and used for both presign and PUT, so the signed
237
- * header always matches.
238
- */
239
- async uploadAndSubmit(checkType, media, extraInput, opts = {}) {
240
- const bareType = stripMimeParams(media.contentType);
241
- const presigned = await this.presign(media.kind, bareType, media.blob.size);
242
- await this.uploadToSpaces(presigned.uploadUrl, media.blob, bareType);
243
- const completed = await this.completeMedia(presigned.key);
244
- const input = {
245
- ...extraInput,
246
- [MEDIA_INPUT_FIELD[checkType]]: completed.key
247
- };
248
- return this.submitCheck(checkType, input, opts);
249
- }
250
- // ── transport ──────────────────────────────────────────────────────────────
251
- /** The token's own sessionId — cached from getSession(), lazily bootstrapped. */
252
- async ensureSessionId() {
253
- if (this.sessionId !== null) return this.sessionId;
254
- this.bootstrap ?? (this.bootstrap = this.getSession().finally(() => {
255
- this.bootstrap = null;
256
- }));
257
- return (await this.bootstrap).sessionId;
258
- }
259
- /**
260
- * One API request: `${apiOrigin}/api/v2${path}`, `x-session-token` always,
261
- * AbortSignal timeout (30 s default), `{success, data}` unwrap on 2xx, flat
262
- * `{code, message}` → {@link HostedApiError} on non-2xx. EVERY failure is
263
- * typed: a rejected fetch → `network_error`, the timeout → `timeout`, an
264
- * unparseable 2xx body → `unknown_error` — the page never sees a raw
265
- * TypeError/DOMException. The ONLY automatic retry is 409
266
- * `idempotency_in_progress` (bounded, short delay).
267
- */
268
- async api(method, path, opts = {}) {
269
- const url = `${this.apiOrigin}/api/v2${path}`;
270
- const headers = { "x-session-token": this.sessionToken };
271
- if (opts.body !== void 0) headers["content-type"] = "application/json";
272
- if (opts.idempotencyKey !== void 0) headers["x-idempotency-key"] = opts.idempotencyKey;
273
- for (let attempt = 0; ; attempt++) {
274
- let res;
275
- try {
276
- res = await this.fetchImpl(url, {
277
- method,
278
- headers,
279
- ...opts.body !== void 0 ? { body: JSON.stringify(opts.body) } : {},
280
- signal: AbortSignal.timeout(this.requestTimeoutMs)
281
- });
282
- } catch (err2) {
283
- throw asTransportError(err2);
284
- }
285
- if (res.ok) {
286
- let raw;
287
- try {
288
- raw = await res.json();
289
- } catch {
290
- throw new HostedApiError({
291
- status: res.status,
292
- code: "unknown_error",
293
- message: `response body was not valid JSON (HTTP ${res.status})`
294
- });
295
- }
296
- return unwrap(raw);
297
- }
298
- const err = await parseErrorResponse(res);
299
- if (err.code === "idempotency_in_progress" && attempt < this.retryAttempts) {
300
- if (this.retryDelayMs > 0) await sleep(this.retryDelayMs);
301
- continue;
302
- }
303
- throw err;
304
- }
305
- }
306
- };
307
- function asTransportError(err) {
308
- const name = typeof err === "object" && err !== null ? err.name : void 0;
309
- if (name === "TimeoutError") {
310
- return new HostedApiError({ status: 0, code: "timeout", message: "request timed out" });
311
- }
312
- const detail = err instanceof Error ? err.message : String(err);
313
- return new HostedApiError({
314
- status: 0,
315
- code: "network_error",
316
- message: `network request failed: ${detail}`
317
- });
318
- }
319
- function unwrap(raw) {
320
- if (raw !== null && typeof raw === "object" && "success" in raw && "data" in raw) {
321
- return raw.data;
322
- }
323
- return raw;
324
- }
325
- async function parseErrorResponse(res) {
326
- let code = "unknown_error";
327
- let message = `request failed (HTTP ${res.status})`;
328
- try {
329
- const body = await res.json();
330
- if (body !== null && typeof body === "object") {
331
- const env = body;
332
- if (typeof env.code === "string" && env.code.length > 0) code = env.code;
333
- if (typeof env.message === "string" && env.message.length > 0) message = env.message;
334
- }
335
- } catch {
336
- }
337
- const retryAfterRaw = res.headers.get("retry-after");
338
- const retryAfter = retryAfterRaw === null ? Number.NaN : Number.parseInt(retryAfterRaw, 10);
339
- return new HostedApiError({
340
- status: res.status,
341
- code,
342
- message,
343
- ...Number.isFinite(retryAfter) && retryAfter >= 0 ? { retryAfterSeconds: retryAfter } : {}
344
- });
345
- }
346
- function sleep(ms) {
347
- return new Promise((resolve) => setTimeout(resolve, ms));
348
- }
349
- // Annotate the CommonJS export names for ESM import in node:
350
- 0 && (module.exports = {
351
- HostedApiError,
352
- HostedClient,
353
- KNOWN_CODES,
354
- isKnownCode,
355
- stripMimeParams
356
- });
357
- //# sourceMappingURL=index.cjs.map
1
+ "use strict";var y=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var P=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},O=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of R(e))!I.call(t,o)&&o!==n&&y(t,o,{get:()=>e[o],enumerable:!(s=C(e,o))||s.enumerable});return t};var v=t=>O(y({},"__esModule",{value:!0}),t);var B={};P(B,{HostedApiError:()=>d,HostedClient:()=>p,KNOWN_CODES:()=>g,isKnownCode:()=>w,stripMimeParams:()=>c});module.exports=v(B);var _="0.1.0-rc.7";var b="sekyro.did",S;function T(){let t=globalThis.crypto;try{if(typeof t?.randomUUID=="function")return t.randomUUID()}catch{}try{if(typeof t?.getRandomValues=="function"){let e=t.getRandomValues(new Uint8Array(16));return Array.from(e,n=>n.toString(16).padStart(2,"0")).join("")}}catch{}}function M(){try{let t=localStorage.getItem(b);if(t)return t;let e=T();return e!==void 0&&localStorage.setItem(b,e),e}catch{return S??(S=T()),S}}async function E(){let t=globalThis.crypto?.subtle;if(!t)return"";let e=navigator,n=JSON.stringify([e.userAgent,e.platform,e.hardwareConcurrency??null,e.deviceMemory??null,e.maxTouchPoints??0,screen.width,screen.height,screen.colorDepth,globalThis.devicePixelRatio??1,Intl.DateTimeFormat().resolvedOptions().timeZone,e.languages?.join(",")??e.language]),s=await t.digest("SHA-256",new TextEncoder().encode(n));return Array.from(new Uint8Array(s),o=>o.toString(16).padStart(2,"0")).join("").slice(0,32)}function A(t){let e=new TextEncoder().encode(t),n="";for(let s of e)n+=String.fromCharCode(s);return btoa(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function x(t){let e,n;return{timezone(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone?.slice(0,64)||void 0}catch{return}},noteCameraLabel(s){s&&(e=s.slice(0,128))},async deviceHeader(){try{n??(n=E().catch(()=>""));let s=[];navigator.webdriver&&s.push("webdriver"),/HeadlessChrome/.test(navigator.userAgent)&&s.push("headless");let o=await n,i=M(),r={v:1,platform:"web",sdk:t.sdk.slice(0,64),ids:[...i?[{kind:"web_local",value:i.slice(0,128)}]:[],...o?[{kind:"web_fp",value:o}]:[]],screen:{w:screen.width,h:screen.height,dpr:globalThis.devicePixelRatio??1},...e?{cameraLabel:e}:{},...s.length?{signals:s}:{}};return A(JSON.stringify(r))}catch{return}}}}var m=Symbol.for("sekyro.web.clientContext"),f=globalThis,h=f[m]??(f[m]=x({sdk:`@sekyro/web@${_}`}));var g=["session_token_invalid","session_token_required","session_token_session_mismatch","session_not_found","rate_limit_exceeded","consent_required","session_not_active","check_not_found","check_already_finalized","check_out_of_order","check_type_unsupported","force_outcome_forbidden","attestation_invalid","inference_unavailable","mobile_required","nni_locked","method_required","method_locked","document_nni_mismatch","media_content_type_not_allowed","media_too_large","media_key_invalid","media_key_forbidden","media_not_found","media_unreadable","media_session_invalid","idempotency_key_collision","idempotency_in_progress","idempotency_key_required","validation_error","internal_error","unknown_error","upload_failed","network_error","timeout"];function w(t){return g.includes(t)}var d=class extends Error{constructor(e){super(e.message),this.name="HostedApiError",this.status=e.status,this.code=e.code,e.retryAfterSeconds!==void 0&&(this.retryAfterSeconds=e.retryAfterSeconds)}};var D=3e4,K=9e5,N=200,V=5,H=400;function c(t){return(t.split(";")[0]??"").trim()}var U={liveness:"clipKey",face_match:"imageKey",doc_ocr:"imageKey"},p=class{constructor(e){this.sessionId=null;this.bootstrap=null;this.apiOrigin=e.apiOrigin.replace(/\/+$/,""),this.sessionToken=e.sessionToken;let n=e.fetch;this.fetchImpl=(s,o)=>(n??globalThis.fetch).call(globalThis,s,o),this.requestTimeoutMs=e.requestTimeoutMs??D,this.retryAttempts=e.inProgressRetry?.attempts??V,this.retryDelayMs=e.inProgressRetry?.delayMs??H}async getSession(){let e=await this.api("GET","/hosted/session");return this.sessionId=e.sessionId,e}async recordConsent(e){return this.api("POST","/hosted/consent",{body:{locale:e}})}async selectMethod(e){let n=await this.api("POST","/hosted/method",{body:{method:e}});return this.sessionId=n.sessionId,n}async presign(e,n,s){let o=await this.ensureSessionId(),i={kind:e,contentType:c(n),contentLength:s};return this.api("POST",`/sessions/${o}/media`,{body:i})}async uploadToSpaces(e,n,s){let o;try{o=await this.fetchImpl(e,{method:"PUT",headers:{"content-type":c(s)},body:n,signal:AbortSignal.timeout(K)})}catch(i){throw k(i)}if(!o.ok){let i=(await o.text().catch(()=>"")).slice(0,N);throw new d({status:o.status,code:"upload_failed",message:`media upload failed (HTTP ${o.status})${i?`: ${i}`:""}`})}}async completeMedia(e){let n=await this.ensureSessionId();return this.api("POST",`/sessions/${n}/media/complete`,{body:{key:e}})}async submitCheck(e,n,s={}){let o=await this.ensureSessionId(),i={input:n,...s.forceOutcome!==void 0?{forceOutcome:s.forceOutcome}:{}};return this.api("POST",`/sessions/${o}/checks/${e}`,{body:i,...s.idempotencyKey!==void 0?{idempotencyKey:s.idempotencyKey}:{}})}async uploadAndSubmit(e,n,s,o={}){let i=c(n.contentType),r=await this.presign(n.kind,i,n.blob.size);await this.uploadToSpaces(r.uploadUrl,n.blob,i);let a=await this.completeMedia(r.key),u={...s,[U[e]]:a.key};return this.submitCheck(e,u,o)}async ensureSessionId(){return this.sessionId!==null?this.sessionId:(this.bootstrap??(this.bootstrap=this.getSession().finally(()=>{this.bootstrap=null})),(await this.bootstrap).sessionId)}async api(e,n,s={}){let o=`${this.apiOrigin}/api/v2${n}`,i={"x-session-token":this.sessionToken};s.body!==void 0&&(i["content-type"]="application/json"),s.idempotencyKey!==void 0&&(i["x-idempotency-key"]=s.idempotencyKey);try{let r=h.timezone();r!==void 0&&(i["sekyro-client-timezone"]=r)}catch{}try{let r=await h.deviceHeader();r!==void 0&&(i["sekyro-client-device"]=r)}catch{}for(let r=0;;r++){let a;try{a=await this.fetchImpl(o,{method:e,headers:i,...s.body!==void 0?{body:JSON.stringify(s.body)}:{},signal:AbortSignal.timeout(this.requestTimeoutMs)})}catch(l){throw k(l)}if(a.ok){let l;try{l=await a.json()}catch{throw new d({status:a.status,code:"unknown_error",message:`response body was not valid JSON (HTTP ${a.status})`})}return L(l)}let u=await q(a);if(u.code==="idempotency_in_progress"&&r<this.retryAttempts){this.retryDelayMs>0&&await $(this.retryDelayMs);continue}throw u}}};function k(t){if((typeof t=="object"&&t!==null?t.name:void 0)==="TimeoutError")return new d({status:0,code:"timeout",message:"request timed out"});let n=t instanceof Error?t.message:String(t);return new d({status:0,code:"network_error",message:`network request failed: ${n}`})}function L(t){return t!==null&&typeof t=="object"&&"success"in t&&"data"in t?t.data:t}async function q(t){let e="unknown_error",n=`request failed (HTTP ${t.status})`,s=Number.NaN;try{let r=await t.json();if(r!==null&&typeof r=="object"){let a=r;typeof a.code=="string"&&a.code.length>0&&(e=a.code),typeof a.message=="string"&&a.message.length>0&&(n=a.message),typeof a.retryAfterSeconds=="number"&&(s=a.retryAfterSeconds)}}catch{}let o=t.headers.get("retry-after"),i=o===null?Math.floor(s):Number.parseInt(o,10);return new d({status:t.status,code:e,message:n,...Number.isFinite(i)&&i>=0?{retryAfterSeconds:i}:{}})}function $(t){return new Promise(e=>setTimeout(e,t))}0&&(module.exports={HostedApiError,HostedClient,KNOWN_CODES,isKnownCode,stripMimeParams});
@@ -1,11 +1,11 @@
1
- export { A as AttestationInput, i as CheckInputByType, C as CheckReason, a as CheckState, b as CheckType, j as CompleteMediaResult, k as ConsentLocale, l as DocOcrInput, D as DocReason, m as DocSide, n as FaceMatchInput, F as FaceMatchReason, g as HostedClient, o as HostedClientOptions, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, p as LivenessCaptureInput, q as LivenessInput, L as LivenessReason, M as MediaCheckType, r as MediaKind, s as PhoneOtpInput, P as PhoneOtpReason, t as PopulationInput, e as PopulationReason, u as PresignRequest, v as PresignUploadResult, R as RecordConsentResult, S as SessionOutcome, f as SessionStatus, w as SessionStepView, h as SessionView, x as SubmitCheckBody, y as SubmitOptions, U as UploadMedia, z as stripMimeParams } from '../hosted-client-DWzCRYJK.cjs';
1
+ export { A as AcceptedDocumentType, p as AttestationInput, r as CheckInputByType, C as CheckReason, a as CheckState, b as CheckType, s as CompleteMediaResult, t as ConsentLocale, D as DecisionReason, u as DocOcrInput, c as DocReason, v as DocSide, w as FaceMatchInput, F as FaceMatchReason, o as HostedClient, x as HostedClientOptions, e as HostedOtpView, f as HostedSessionView, g as HostedStepView, h as HostedVoiceLocale, i as HostedVoiceView, I as IdentityMethod, y as LivenessCaptureInput, z as LivenessInput, L as LivenessReason, M as MatchReason, B as MediaCheckType, E as MediaKind, j as MethodChoiceView, G as PhoneOtpInput, P as PhoneOtpReason, k as PolicyFailureReason, J as PopulationInput, l as PopulationReason, K as PresignRequest, N as PresignUploadResult, R as RecordConsentResult, S as SessionFailureReason, m as SessionOutcome, n as SessionStatus, O as SessionStepView, q as SessionView, Q as SubmitCheckBody, T as SubmitOptions, U as UploadMedia, V as stripMimeParams } from '../hosted-client-kBeq-mnJ.cjs';
2
2
 
3
3
  /**
4
4
  * Every error code the hosted page can receive from the session-token surface.
5
5
  * A closed string-literal union — switch over {@link KnownCode} with a `never`
6
6
  * default arm for compile-checked exhaustiveness.
7
7
  */
8
- declare const KNOWN_CODES: readonly ["session_token_invalid", "session_token_required", "session_token_session_mismatch", "session_not_found", "rate_limit_exceeded", "consent_required", "session_not_active", "check_not_found", "check_already_finalized", "check_out_of_order", "check_type_unsupported", "force_outcome_forbidden", "attestation_invalid", "nni_locked", "media_content_type_not_allowed", "media_too_large", "media_key_invalid", "media_key_forbidden", "media_not_found", "media_unreadable", "media_session_invalid", "idempotency_key_collision", "idempotency_in_progress", "idempotency_key_required", "validation_error", "internal_error", "unknown_error", "upload_failed", "network_error", "timeout"];
8
+ declare const KNOWN_CODES: readonly ["session_token_invalid", "session_token_required", "session_token_session_mismatch", "session_not_found", "rate_limit_exceeded", "consent_required", "session_not_active", "check_not_found", "check_already_finalized", "check_out_of_order", "check_type_unsupported", "force_outcome_forbidden", "attestation_invalid", "inference_unavailable", "mobile_required", "nni_locked", "method_required", "method_locked", "document_nni_mismatch", "media_content_type_not_allowed", "media_too_large", "media_key_invalid", "media_key_forbidden", "media_not_found", "media_unreadable", "media_session_invalid", "idempotency_key_collision", "idempotency_in_progress", "idempotency_key_required", "validation_error", "internal_error", "unknown_error", "upload_failed", "network_error", "timeout"];
9
9
  /** Closed union of {@link KNOWN_CODES} — exhaustively switchable. */
10
10
  type KnownCode = (typeof KNOWN_CODES)[number];
11
11
  /** Narrow an arbitrary wire code to the known union (unknown codes stay `string`). */
@@ -1,11 +1,11 @@
1
- export { A as AttestationInput, i as CheckInputByType, C as CheckReason, a as CheckState, b as CheckType, j as CompleteMediaResult, k as ConsentLocale, l as DocOcrInput, D as DocReason, m as DocSide, n as FaceMatchInput, F as FaceMatchReason, g as HostedClient, o as HostedClientOptions, H as HostedOtpView, c as HostedSessionView, d as HostedStepView, p as LivenessCaptureInput, q as LivenessInput, L as LivenessReason, M as MediaCheckType, r as MediaKind, s as PhoneOtpInput, P as PhoneOtpReason, t as PopulationInput, e as PopulationReason, u as PresignRequest, v as PresignUploadResult, R as RecordConsentResult, S as SessionOutcome, f as SessionStatus, w as SessionStepView, h as SessionView, x as SubmitCheckBody, y as SubmitOptions, U as UploadMedia, z as stripMimeParams } from '../hosted-client-DWzCRYJK.js';
1
+ export { A as AcceptedDocumentType, p as AttestationInput, r as CheckInputByType, C as CheckReason, a as CheckState, b as CheckType, s as CompleteMediaResult, t as ConsentLocale, D as DecisionReason, u as DocOcrInput, c as DocReason, v as DocSide, w as FaceMatchInput, F as FaceMatchReason, o as HostedClient, x as HostedClientOptions, e as HostedOtpView, f as HostedSessionView, g as HostedStepView, h as HostedVoiceLocale, i as HostedVoiceView, I as IdentityMethod, y as LivenessCaptureInput, z as LivenessInput, L as LivenessReason, M as MatchReason, B as MediaCheckType, E as MediaKind, j as MethodChoiceView, G as PhoneOtpInput, P as PhoneOtpReason, k as PolicyFailureReason, J as PopulationInput, l as PopulationReason, K as PresignRequest, N as PresignUploadResult, R as RecordConsentResult, S as SessionFailureReason, m as SessionOutcome, n as SessionStatus, O as SessionStepView, q as SessionView, Q as SubmitCheckBody, T as SubmitOptions, U as UploadMedia, V as stripMimeParams } from '../hosted-client-kBeq-mnJ.js';
2
2
 
3
3
  /**
4
4
  * Every error code the hosted page can receive from the session-token surface.
5
5
  * A closed string-literal union — switch over {@link KnownCode} with a `never`
6
6
  * default arm for compile-checked exhaustiveness.
7
7
  */
8
- declare const KNOWN_CODES: readonly ["session_token_invalid", "session_token_required", "session_token_session_mismatch", "session_not_found", "rate_limit_exceeded", "consent_required", "session_not_active", "check_not_found", "check_already_finalized", "check_out_of_order", "check_type_unsupported", "force_outcome_forbidden", "attestation_invalid", "nni_locked", "media_content_type_not_allowed", "media_too_large", "media_key_invalid", "media_key_forbidden", "media_not_found", "media_unreadable", "media_session_invalid", "idempotency_key_collision", "idempotency_in_progress", "idempotency_key_required", "validation_error", "internal_error", "unknown_error", "upload_failed", "network_error", "timeout"];
8
+ declare const KNOWN_CODES: readonly ["session_token_invalid", "session_token_required", "session_token_session_mismatch", "session_not_found", "rate_limit_exceeded", "consent_required", "session_not_active", "check_not_found", "check_already_finalized", "check_out_of_order", "check_type_unsupported", "force_outcome_forbidden", "attestation_invalid", "inference_unavailable", "mobile_required", "nni_locked", "method_required", "method_locked", "document_nni_mismatch", "media_content_type_not_allowed", "media_too_large", "media_key_invalid", "media_key_forbidden", "media_not_found", "media_unreadable", "media_session_invalid", "idempotency_key_collision", "idempotency_in_progress", "idempotency_key_required", "validation_error", "internal_error", "unknown_error", "upload_failed", "network_error", "timeout"];
9
9
  /** Closed union of {@link KNOWN_CODES} — exhaustively switchable. */
10
10
  type KnownCode = (typeof KNOWN_CODES)[number];
11
11
  /** Narrow an arbitrary wire code to the known union (unknown codes stay `string`). */
@@ -1,15 +1 @@
1
- import {
2
- HostedApiError,
3
- HostedClient,
4
- KNOWN_CODES,
5
- isKnownCode,
6
- stripMimeParams
7
- } from "../chunk-YVFF4Q4G.js";
8
- export {
9
- HostedApiError,
10
- HostedClient,
11
- KNOWN_CODES,
12
- isKnownCode,
13
- stripMimeParams
14
- };
15
- //# sourceMappingURL=index.js.map
1
+ import{a as e,b as t,c as o,d as s,e as n}from"../chunk-YOB4ZTYN.js";import"../chunk-IYUOYINS.js";export{o as HostedApiError,n as HostedClient,e as KNOWN_CODES,t as isKnownCode,s as stripMimeParams};