@sekyro/node 0.0.0-stage → 0.1.0-rc.1
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.
- package/CHANGELOG.md +13 -0
- package/LICENSE +20 -0
- package/README.md +149 -2
- package/dist/index.cjs +308 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +389 -0
- package/dist/index.d.ts +389 -0
- package/dist/index.js +272 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -4
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-level enums and shapes of the Sekyro partner API (`/api/v2`). These
|
|
3
|
+
* mirror the backend's frozen partner contract; they are plain string unions so
|
|
4
|
+
* a newer API value never throws at runtime — it simply widens the type in the
|
|
5
|
+
* next SDK release.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
*/
|
|
9
|
+
/** Session lifecycle status. @public */
|
|
10
|
+
type SessionStatus = "created" | "in_progress" | "review_pending" | "completed" | "expired" | "failed";
|
|
11
|
+
/**
|
|
12
|
+
* Terminal verdict, orthogonal to {@link SessionStatus}. `null` until the session
|
|
13
|
+
* reaches a terminal status; `review` when a human reviewer must adjudicate.
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
type SessionOutcome = "approved" | "review" | "rejected";
|
|
17
|
+
/** The verification checks a flow may contain. @public */
|
|
18
|
+
type CheckType = "liveness" | "face_match" | "doc_ocr" | "population_registry" | "phone_otp";
|
|
19
|
+
/** Per-check execution state within a session. @public */
|
|
20
|
+
type CheckState = "pending" | "input_required" | "processing" | "passed" | "failed" | "review" | "skipped";
|
|
21
|
+
/** Hosted-flow languages. @public */
|
|
22
|
+
type Locale = "ar" | "fr" | "en";
|
|
23
|
+
/** The environment a webhook was emitted from. @public */
|
|
24
|
+
type SekyroEnvironment = "sandbox" | "live";
|
|
25
|
+
/**
|
|
26
|
+
* One check of a session, as the partner API projects it: enum/id fields only,
|
|
27
|
+
* never civil data.
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
interface SessionStep {
|
|
31
|
+
checkType: CheckType;
|
|
32
|
+
state: CheckState;
|
|
33
|
+
/** Machine-readable failure/review reason, when the check has one. */
|
|
34
|
+
reason?: string;
|
|
35
|
+
/** Calibrated model score in [0, 1] for scored checks (liveness, face match). */
|
|
36
|
+
calibratedScore?: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Input of {@link SessionsApi.create}. Name the recipe by EITHER `flow` (the
|
|
40
|
+
* flow slug) OR `templateId` — exactly one; the API rejects both or neither.
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
interface CreateSessionInput {
|
|
44
|
+
/** Flow slug configured for your organisation. */
|
|
45
|
+
flow?: string;
|
|
46
|
+
/** Legacy template id (pre-flows path). Prefer `flow`. */
|
|
47
|
+
templateId?: string;
|
|
48
|
+
/** Pins the hosted-flow language. Omit to let the person's device decide. */
|
|
49
|
+
locale?: Locale;
|
|
50
|
+
/**
|
|
51
|
+
* Step inputs consumed server-side. The known anchors are typed (all
|
|
52
|
+
* strings — an `nni` is a 10-digit string, never a number); further keys
|
|
53
|
+
* pass through to the API as-is. `nni` binds the session to that identity:
|
|
54
|
+
* the hosted flow may omit it but cannot substitute another.
|
|
55
|
+
*/
|
|
56
|
+
input?: {
|
|
57
|
+
/** 10-digit Mauritanian NNI, as a string. */
|
|
58
|
+
nni?: string;
|
|
59
|
+
/** E.164 phone number, e.g. `+22236123456`. */
|
|
60
|
+
phone?: string;
|
|
61
|
+
fullName?: string;
|
|
62
|
+
/** ISO 8601 date (`YYYY-MM-DD`). */
|
|
63
|
+
birthDate?: string;
|
|
64
|
+
} & Record<string, unknown>;
|
|
65
|
+
}
|
|
66
|
+
/** Per-request options. @public */
|
|
67
|
+
interface RequestOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Sent as `X-Idempotency-Key`. Replaying the same key within 24 h returns the
|
|
70
|
+
* original response instead of creating a second session.
|
|
71
|
+
*/
|
|
72
|
+
idempotencyKey?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Result of {@link SessionsApi.create}. `clientToken` is returned ONCE and never
|
|
76
|
+
* again — hand it to the browser (`@sekyro/web`) and do not persist it.
|
|
77
|
+
* @public
|
|
78
|
+
*/
|
|
79
|
+
interface CreatedSession {
|
|
80
|
+
id: string;
|
|
81
|
+
status: SessionStatus;
|
|
82
|
+
/** One-time credential for the client SDK / hosted flow. */
|
|
83
|
+
clientToken: string;
|
|
84
|
+
/** Hosted verification link for this session. */
|
|
85
|
+
hostedUrl: string;
|
|
86
|
+
steps: SessionStep[];
|
|
87
|
+
/** ISO 8601 — when the session (and its link) stop accepting input. */
|
|
88
|
+
expiresAt: string;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The whitelisted session view returned by {@link SessionsApi.get}. Never
|
|
92
|
+
* contains the client token.
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
interface Session {
|
|
96
|
+
id: string;
|
|
97
|
+
status: SessionStatus;
|
|
98
|
+
outcome: SessionOutcome | null;
|
|
99
|
+
steps: SessionStep[];
|
|
100
|
+
/** ISO 8601. */
|
|
101
|
+
expiresAt: string;
|
|
102
|
+
/** ISO 8601. */
|
|
103
|
+
createdAt: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* `data` of the terminal / review-pending session lifecycle events
|
|
107
|
+
* (`session.completed` | `session.failed` | `session.review_pending` |
|
|
108
|
+
* `session.expired` | `session.rejected`) — ids and enums only, no civil data,
|
|
109
|
+
* scores or links. `outcome` and `steps` travel on `completed` / `failed`;
|
|
110
|
+
* `review_pending` carries `steps` without an outcome; `expired` carries the
|
|
111
|
+
* status alone.
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
interface SessionLifecycleEventData {
|
|
115
|
+
sessionId: string;
|
|
116
|
+
status: SessionStatus;
|
|
117
|
+
outcome?: SessionOutcome | null;
|
|
118
|
+
steps?: Array<Pick<SessionStep, "checkType" | "state">>;
|
|
119
|
+
/** Machine-readable reason, when the transition has one. */
|
|
120
|
+
reason?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* `data` of `session.step.completed` — the check that just passed.
|
|
124
|
+
* @public
|
|
125
|
+
*/
|
|
126
|
+
interface SessionStepCompletedEventData {
|
|
127
|
+
sessionId: string;
|
|
128
|
+
checkType: CheckType;
|
|
129
|
+
state: CheckState;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* `data` of `session.review_decided` — a human (or the review-timeout sweep)
|
|
133
|
+
* decided a pending review. `outcome` speaks the REVIEW vocabulary
|
|
134
|
+
* (`pass` | `fail`), not the session outcome; `reason` is the reviewer's code
|
|
135
|
+
* (e.g. `review_timeout` for an expired review).
|
|
136
|
+
* @public
|
|
137
|
+
*/
|
|
138
|
+
interface SessionReviewDecidedEventData {
|
|
139
|
+
sessionId: string;
|
|
140
|
+
outcome: "pass" | "fail";
|
|
141
|
+
reason: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Event type → the shape of its `data`. Session events are typed; the
|
|
145
|
+
* remaining events carry an open record until their payloads are frozen.
|
|
146
|
+
* @public
|
|
147
|
+
*/
|
|
148
|
+
interface WebhookEventDataMap {
|
|
149
|
+
"session.created": Record<string, unknown>;
|
|
150
|
+
"session.started": Record<string, unknown>;
|
|
151
|
+
"session.step.completed": SessionStepCompletedEventData;
|
|
152
|
+
"session.review_pending": SessionLifecycleEventData;
|
|
153
|
+
"session.review_decided": SessionReviewDecidedEventData;
|
|
154
|
+
"session.completed": SessionLifecycleEventData;
|
|
155
|
+
"session.rejected": SessionLifecycleEventData;
|
|
156
|
+
"session.expired": SessionLifecycleEventData;
|
|
157
|
+
"session.failed": SessionLifecycleEventData;
|
|
158
|
+
"subject.enrolled": Record<string, unknown>;
|
|
159
|
+
"subject.deleted": Record<string, unknown>;
|
|
160
|
+
"aml.match_flagged": Record<string, unknown>;
|
|
161
|
+
"payment.received": Record<string, unknown>;
|
|
162
|
+
"invoice.generated": Record<string, unknown>;
|
|
163
|
+
"invoice.paid": Record<string, unknown>;
|
|
164
|
+
"invoice.overdue": Record<string, unknown>;
|
|
165
|
+
"webhook.test": Record<string, unknown>;
|
|
166
|
+
}
|
|
167
|
+
/** Every event a partner endpoint may receive. @public */
|
|
168
|
+
type WebhookEventType = keyof WebhookEventDataMap;
|
|
169
|
+
/**
|
|
170
|
+
* The signed webhook payload for ONE event type. There is no global API
|
|
171
|
+
* version; each event carries its own per-event `version`. Retried deliveries
|
|
172
|
+
* keep the same `id` — de-duplicate on it.
|
|
173
|
+
* @public
|
|
174
|
+
*/
|
|
175
|
+
interface WebhookEnvelopeOf<E extends WebhookEventType> {
|
|
176
|
+
/** UUIDv7, stable across delivery retries. */
|
|
177
|
+
id: string;
|
|
178
|
+
event: E;
|
|
179
|
+
/** Per-event payload version. */
|
|
180
|
+
version: number;
|
|
181
|
+
/** ISO 8601. */
|
|
182
|
+
createdAt: string;
|
|
183
|
+
orgId: string;
|
|
184
|
+
env: SekyroEnvironment;
|
|
185
|
+
data: WebhookEventDataMap[E];
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* The signed webhook payload, discriminated on `event`: narrowing on
|
|
189
|
+
* `envelope.event` narrows `envelope.data` to that event's shape.
|
|
190
|
+
*
|
|
191
|
+
* @example
|
|
192
|
+
* ```ts
|
|
193
|
+
* const envelope = verifyWebhook(rawBody, header, secret);
|
|
194
|
+
* switch (envelope.event) {
|
|
195
|
+
* case "session.completed":
|
|
196
|
+
* envelope.data.outcome; // SessionOutcome | null | undefined
|
|
197
|
+
* break;
|
|
198
|
+
* case "session.review_decided":
|
|
199
|
+
* envelope.data.outcome; // "pass" | "fail"
|
|
200
|
+
* break;
|
|
201
|
+
* }
|
|
202
|
+
* ```
|
|
203
|
+
* @public
|
|
204
|
+
*/
|
|
205
|
+
type WebhookEnvelope<E extends WebhookEventType = WebhookEventType> = E extends WebhookEventType ? WebhookEnvelopeOf<E> : never;
|
|
206
|
+
/**
|
|
207
|
+
* `data` of any `session.*` event.
|
|
208
|
+
* @deprecated Use {@link SessionLifecycleEventData}, {@link SessionStepCompletedEventData}
|
|
209
|
+
* or {@link SessionReviewDecidedEventData}, or narrow a {@link WebhookEnvelope} on `event`.
|
|
210
|
+
* @public
|
|
211
|
+
*/
|
|
212
|
+
type SessionEventData = SessionLifecycleEventData | SessionStepCompletedEventData | SessionReviewDecidedEventData;
|
|
213
|
+
|
|
214
|
+
/** Default partner API origin + version prefix. @public */
|
|
215
|
+
declare const DEFAULT_BASE_URL = "https://api.sekyro.ai/api/v2";
|
|
216
|
+
/** Default per-request timeout. @public */
|
|
217
|
+
declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
218
|
+
/** `fetch`-compatible function; the global `fetch` by default. @public */
|
|
219
|
+
type FetchLike = typeof globalThis.fetch;
|
|
220
|
+
/** Constructor options of {@link Sekyro}. @public */
|
|
221
|
+
interface SekyroOptions {
|
|
222
|
+
/** Partner API key (server-side only). Sent as `Authorization: Bearer`. */
|
|
223
|
+
apiKey: string;
|
|
224
|
+
/** API base URL incl. the `/api/v2` prefix. Default {@link DEFAULT_BASE_URL}. */
|
|
225
|
+
baseUrl?: string;
|
|
226
|
+
/** Per-request timeout in ms. Default {@link DEFAULT_TIMEOUT_MS}. */
|
|
227
|
+
timeoutMs?: number;
|
|
228
|
+
/** Custom `fetch` (tests, proxies, custom agents). Default `globalThis.fetch`. */
|
|
229
|
+
fetch?: FetchLike;
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* `sekyro.sessions` — create and read verification sessions.
|
|
233
|
+
*
|
|
234
|
+
* Exported as a TYPE only (`import type { SessionsApi }`): the class value is
|
|
235
|
+
* not part of the package surface, so it can only be obtained through
|
|
236
|
+
* {@link Sekyro.sessions} — never constructed by hand with an unchecked
|
|
237
|
+
* transport.
|
|
238
|
+
* @public
|
|
239
|
+
*/
|
|
240
|
+
declare class SessionsApi {
|
|
241
|
+
private readonly call;
|
|
242
|
+
/**
|
|
243
|
+
* Constructed by {@link Sekyro}; the transport is kept out of the public
|
|
244
|
+
* surface on purpose (only its bound `call` crosses this boundary).
|
|
245
|
+
* @internal
|
|
246
|
+
*/
|
|
247
|
+
constructor(call: <T>(method: "GET" | "POST", path: string, body?: unknown, idempotencyKey?: string) => Promise<T>);
|
|
248
|
+
/**
|
|
249
|
+
* `POST /sessions`. Returns the one-time `clientToken` — hand it to the
|
|
250
|
+
* browser, never persist it. Pass an `idempotencyKey` so a retried call
|
|
251
|
+
* cannot create a second session.
|
|
252
|
+
*/
|
|
253
|
+
create(input: CreateSessionInput, opts?: RequestOptions): Promise<CreatedSession>;
|
|
254
|
+
/** `GET /sessions/:id` — the whitelisted view (no client token). */
|
|
255
|
+
get(id: string): Promise<Session>;
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Sekyro partner API client. Server-side only: it carries your API key.
|
|
259
|
+
*
|
|
260
|
+
* Throws {@link SekyroConfigError} synchronously when `apiKey` is missing or
|
|
261
|
+
* `baseUrl` is not `https:` (plain `http:` is accepted for `localhost`,
|
|
262
|
+
* `127.0.0.1` and `[::1]` only).
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* const sekyro = new Sekyro({ apiKey: process.env.SEKYRO_API_KEY! });
|
|
267
|
+
* const { id, clientToken } = await sekyro.sessions.create({ flow: "onboarding" });
|
|
268
|
+
* ```
|
|
269
|
+
* @public
|
|
270
|
+
*/
|
|
271
|
+
declare class Sekyro {
|
|
272
|
+
readonly sessions: SessionsApi;
|
|
273
|
+
constructor(opts: SekyroOptions);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** Why {@link verifyWebhook} rejected a delivery. @public */
|
|
277
|
+
type SekyroWebhookErrorCode = "invalid_signature" | "stale" | "malformed";
|
|
278
|
+
/**
|
|
279
|
+
* Thrown by {@link verifyWebhook}. Respond with a 4xx and do not process the
|
|
280
|
+
* body; Sekyro retries deliveries that do not receive a 2xx.
|
|
281
|
+
* @public
|
|
282
|
+
*/
|
|
283
|
+
declare class SekyroWebhookError extends Error {
|
|
284
|
+
readonly name = "SekyroWebhookError";
|
|
285
|
+
readonly code: SekyroWebhookErrorCode;
|
|
286
|
+
constructor(code: SekyroWebhookErrorCode, message?: string);
|
|
287
|
+
}
|
|
288
|
+
/** Why the {@link Sekyro} constructor rejected its options. @public */
|
|
289
|
+
type SekyroConfigErrorCode = "missing_api_key" | "invalid_base_url";
|
|
290
|
+
/**
|
|
291
|
+
* Thrown synchronously by `new Sekyro(...)` for an unusable configuration —
|
|
292
|
+
* before any request is made. Extends `TypeError` so existing
|
|
293
|
+
* `instanceof TypeError` guards keep working.
|
|
294
|
+
* @public
|
|
295
|
+
*/
|
|
296
|
+
declare class SekyroConfigError extends TypeError {
|
|
297
|
+
readonly name = "SekyroConfigError";
|
|
298
|
+
readonly code: SekyroConfigErrorCode;
|
|
299
|
+
constructor(code: SekyroConfigErrorCode, message?: string);
|
|
300
|
+
}
|
|
301
|
+
/** Constructor input of {@link SekyroApiError}. @public */
|
|
302
|
+
interface SekyroApiErrorInit {
|
|
303
|
+
/** HTTP status; `0` when no response was received (network / timeout). */
|
|
304
|
+
status: number;
|
|
305
|
+
/** API error code, or `network` | `timeout` | `http_error` | `malformed_response`. */
|
|
306
|
+
code: string;
|
|
307
|
+
message: string;
|
|
308
|
+
/** The API's `request_id`, when the response carried one. */
|
|
309
|
+
requestId?: string;
|
|
310
|
+
/** Underlying error (network failures, abort reasons, JSON parse errors). */
|
|
311
|
+
cause?: unknown;
|
|
312
|
+
}
|
|
313
|
+
/** Error codes the SDK itself produces (as opposed to codes from the API). @public */
|
|
314
|
+
type SekyroClientErrorCode = "network" | "timeout" | "http_error" | "malformed_response";
|
|
315
|
+
/**
|
|
316
|
+
* Any failed call through {@link Sekyro}: a non-2xx partner envelope
|
|
317
|
+
* `{ status: 'error', error: { code, message, request_id } }`, a non-JSON
|
|
318
|
+
* response, a network failure or a timeout.
|
|
319
|
+
*
|
|
320
|
+
* `retryable` is `true` for `network`, `timeout`, HTTP 429, HTTP 5xx and the
|
|
321
|
+
* `idempotency_in_progress` code — retry with the SAME idempotency key.
|
|
322
|
+
* @public
|
|
323
|
+
*/
|
|
324
|
+
declare class SekyroApiError extends Error {
|
|
325
|
+
readonly name = "SekyroApiError";
|
|
326
|
+
readonly status: number;
|
|
327
|
+
readonly code: string;
|
|
328
|
+
readonly requestId: string | undefined;
|
|
329
|
+
readonly retryable: boolean;
|
|
330
|
+
constructor(init: SekyroApiErrorInit);
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* The HTTP header carrying the webhook signature:
|
|
335
|
+
* `t=<unix seconds>,v1=<hex>[,v1=<hex>]`.
|
|
336
|
+
* @public
|
|
337
|
+
*/
|
|
338
|
+
declare const SEKYRO_SIGNATURE_HEADER = "x-sekyro-signature";
|
|
339
|
+
/**
|
|
340
|
+
* The pre-rebrand name of the signature header. Sekyro sends BOTH headers with
|
|
341
|
+
* the same value during the transition; prefer {@link SEKYRO_SIGNATURE_HEADER}
|
|
342
|
+
* and use {@link signatureFromHeaders} to accept either.
|
|
343
|
+
* @public
|
|
344
|
+
*/
|
|
345
|
+
declare const LEGACY_SIGNATURE_HEADER = "x-ibtikar-signature";
|
|
346
|
+
/**
|
|
347
|
+
* Pick the signature header out of an incoming request's headers: the
|
|
348
|
+
* `x-sekyro-signature` value when present, else the legacy
|
|
349
|
+
* `x-ibtikar-signature`, else `undefined`. Accepts a Fetch `Headers` object or
|
|
350
|
+
* a Node-style plain record (lower- or mixed-case keys; a multi-valued header
|
|
351
|
+
* yields its first value).
|
|
352
|
+
*
|
|
353
|
+
* @example
|
|
354
|
+
* ```ts
|
|
355
|
+
* verifyWebhook(rawBody, signatureFromHeaders(req.headers), secret);
|
|
356
|
+
* ```
|
|
357
|
+
* @public
|
|
358
|
+
*/
|
|
359
|
+
declare function signatureFromHeaders(headers: Headers | Record<string, string | string[] | undefined>): string | undefined;
|
|
360
|
+
/** Options of {@link verifyWebhook}. @public */
|
|
361
|
+
interface VerifyWebhookOptions {
|
|
362
|
+
/** Max |now − t| in seconds before a delivery is rejected as `stale`. Default 300. */
|
|
363
|
+
toleranceSec?: number;
|
|
364
|
+
/** Clock returning epoch milliseconds. Default `Date.now`. */
|
|
365
|
+
now?: () => number;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Verify a Sekyro webhook delivery and return its parsed envelope, discriminated
|
|
369
|
+
* on `event` (narrow with a `switch` to type `data`).
|
|
370
|
+
*
|
|
371
|
+
* - `rawBody` MUST be the request body exactly as received (before any JSON
|
|
372
|
+
* parsing / re-serialisation); the signature covers those bytes.
|
|
373
|
+
* - Accepts the delivery when ANY `v1` in the header matches, which is what
|
|
374
|
+
* makes secret rotation seamless (Sekyro signs with current + previous).
|
|
375
|
+
* - Uses `node:crypto` only; the digest compare is constant-time.
|
|
376
|
+
*
|
|
377
|
+
* Checks run in this order: header/secret present → header well-formed →
|
|
378
|
+
* timestamp within tolerance → signature → body is a JSON object.
|
|
379
|
+
*
|
|
380
|
+
* @param rawBody - The raw UTF-8 request body.
|
|
381
|
+
* @param header - The `x-sekyro-signature` header value (or the legacy
|
|
382
|
+
* `x-ibtikar-signature` — same format; see {@link signatureFromHeaders}).
|
|
383
|
+
* @param secret - The endpoint secret you hold (current or previous).
|
|
384
|
+
* @throws {@link SekyroWebhookError} with `code` `invalid_signature` | `stale` | `malformed`.
|
|
385
|
+
* @public
|
|
386
|
+
*/
|
|
387
|
+
declare function verifyWebhook(rawBody: string, header: string | null | undefined, secret: string, opts?: VerifyWebhookOptions): WebhookEnvelope;
|
|
388
|
+
|
|
389
|
+
export { type CheckState, type CheckType, type CreateSessionInput, type CreatedSession, DEFAULT_BASE_URL, DEFAULT_TIMEOUT_MS, type FetchLike, LEGACY_SIGNATURE_HEADER, type Locale, type RequestOptions, SEKYRO_SIGNATURE_HEADER, Sekyro, SekyroApiError, type SekyroApiErrorInit, type SekyroClientErrorCode, SekyroConfigError, type SekyroConfigErrorCode, type SekyroEnvironment, type SekyroOptions, SekyroWebhookError, type SekyroWebhookErrorCode, type Session, type SessionEventData, type SessionLifecycleEventData, type SessionOutcome, type SessionReviewDecidedEventData, type SessionStatus, type SessionStep, type SessionStepCompletedEventData, SessionsApi, type VerifyWebhookOptions, type WebhookEnvelope, type WebhookEnvelopeOf, type WebhookEventDataMap, type WebhookEventType, signatureFromHeaders, verifyWebhook };
|