@smileid/usesmileid-nodejs 12.0.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Smile Identity Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,335 @@
1
+ # @smileid/usesmileid-nodejs
2
+
3
+ ![npm version](https://img.shields.io/badge/npm-unpublished-lightgrey)
4
+ ![CI status](https://img.shields.io/badge/CI-pending-lightgrey)
5
+ ![license](https://img.shields.io/badge/license-MIT-blue)
6
+
7
+ Official Smile ID server-side SDK for JavaScript/TypeScript — V3 APIs.
8
+
9
+ This project is under active development and is not yet published to npm. The package name and API surface may change before the first release.
10
+
11
+ ## Requirements
12
+
13
+ Node.js 18 or later. The SDK uses the built-in global `fetch` and has no runtime dependencies. Development and CI use the version pinned in `.nvmrc`.
14
+
15
+ ## Install
16
+
17
+ ```sh
18
+ npm install @smileid/usesmileid-nodejs
19
+ ```
20
+
21
+ ## Create a client
22
+
23
+ Construct a client with your partner id and API key. The SDK handles authentication for you: it fetches an internal token, caches it until just before expiry, and refreshes it once on a 401. You never handle tokens yourself.
24
+
25
+ ```ts
26
+ import { SmileID } from '@smileid/usesmileid-nodejs';
27
+
28
+ const smile = new SmileID({
29
+ partnerId: '1234',
30
+ apiKey: process.env.SMILE_API_KEY!,
31
+ environment: 'sandbox', // the default
32
+ defaultCallbackUrl: 'https://app.example.com/smile/callback',
33
+ });
34
+ ```
35
+
36
+ Partner ids are displayed zero-padded (for example 002) but must be passed without leading zeros (2).
37
+
38
+ ### Environments and base URL
39
+
40
+ The client targets the sandbox by default. Set `environment: 'production'` to go live. Only `sandbox` and `production` are accepted; anything else is rejected at construction.
41
+
42
+ | Environment | Base URL |
43
+ | ------------ | ----------------------------------- |
44
+ | `sandbox` | `https://testapi.smileidentity.com` |
45
+ | `production` | `https://api.smileidentity.com` |
46
+
47
+ Any other host needs an explicit `baseUrl`, which wins over `environment`:
48
+
49
+ ```ts
50
+ const smile = new SmileID({
51
+ partnerId: '2',
52
+ apiKey: process.env.SMILE_API_KEY!,
53
+ baseUrl: process.env.SMILE_BASE_URL ?? 'https://your-environment.example.com',
54
+ });
55
+ ```
56
+
57
+ ### HTTPS requirements
58
+
59
+ The SDK talks to Smile ID over HTTPS only:
60
+
61
+ - `baseUrl` must be an absolute `https://` URL with no query string or fragment. There is no option to allow plain HTTP.
62
+ - `defaultCallbackUrl` and every per-request `callbackUrl` must be `https://` URLs. A non-HTTPS callback raises `ValidationError` before any request is sent.
63
+
64
+ Both are checked at client construction; per-request callback URLs are checked again before each send.
65
+
66
+ ### Other options
67
+
68
+ | Option | Default | Purpose |
69
+ | -------------------- | ---------- | ------------------------------------------------------------- |
70
+ | `defaultCallbackUrl` | unset | Used when a call omits `callbackUrl` |
71
+ | `timeout` | 30000 ms | Per-request total timeout |
72
+ | `maxRetries` | 2 | Retries for idempotent operations only |
73
+ | `fetch` | global | Injectable fetch implementation for testing or proxies |
74
+
75
+ ## Shared inputs
76
+
77
+ Every verification call takes a `consent` block and `userDetails`. Build consent with the `Consent.granted` helper. `userDetails` needs at least one of `email` or `phoneNumber` — the SDK checks this before sending.
78
+
79
+ ```ts
80
+ import { Consent } from '@smileid/usesmileid-nodejs';
81
+
82
+ const consent = Consent.granted({
83
+ grantedAt: new Date(),
84
+ noticeLanguage: 'EN',
85
+ noticePrivacyPolicyUrl: 'https://example.com/privacy',
86
+ });
87
+
88
+ const userDetails = {
89
+ givenNames: 'Amina Fatou',
90
+ lastName: 'Clearwater',
91
+ email: 'amina.clearwater@example.com',
92
+ };
93
+ ```
94
+
95
+ Non-production environments match test identities on given names, last name and email. An unrecognised identity resolves to `block`.
96
+
97
+ Image inputs (`selfieImage`, `livenessImages`, `document`, `comparisonImage`) accept a file path, a `Buffer`, a `Blob`, or a readable stream. Wrap one in `{ data, filename, contentType }` to override the filename or content type.
98
+
99
+ Every method takes an optional final `options` argument with `timeout`, `callbackUrl`, and `signal` (an `AbortSignal`).
100
+
101
+ ## Methods
102
+
103
+ ### Enhanced KYC
104
+
105
+ ```ts
106
+ const accepted = await smile.enhancedKyc.verify({
107
+ country: 'NG',
108
+ idType: 'NIN',
109
+ idNumber: '12345678901',
110
+ userDetails,
111
+ consent,
112
+ userId: 'user_01h8x9y2z3a4b5c6d7e8f9g0h1',
113
+ });
114
+ accepted.jobId; // "job_..."
115
+ accepted.isAccepted; // true
116
+ ```
117
+
118
+ ### Document verification
119
+
120
+ ```ts
121
+ const accepted = await smile.documents.verify({
122
+ country: 'NG',
123
+ selfieImage: './selfie.jpg',
124
+ livenessImages: ['./live1.jpg', './live2.jpg', './live3.jpg', './live4.jpg', './live5.jpg', './live6.jpg'],
125
+ document: './passport.jpg',
126
+ userDetails,
127
+ consent,
128
+ });
129
+ ```
130
+
131
+ ### Enhanced document verification
132
+
133
+ Same as document verification, but `idType` is required.
134
+
135
+ ```ts
136
+ const accepted = await smile.documents.verifyEnhanced({
137
+ country: 'NG',
138
+ idType: 'PASSPORT',
139
+ selfieImage: './selfie.jpg',
140
+ livenessImages: ['./live1.jpg', './live2.jpg', './live3.jpg', './live4.jpg', './live5.jpg', './live6.jpg'],
141
+ document: './passport.jpg',
142
+ userDetails,
143
+ consent,
144
+ });
145
+ ```
146
+
147
+ ### Biometric KYC
148
+
149
+ ```ts
150
+ const accepted = await smile.biometricKyc.verify({
151
+ country: 'NG',
152
+ idType: 'NIN',
153
+ idNumber: '12345678901',
154
+ selfieImage: './selfie.jpg',
155
+ livenessImages: ['./live1.jpg', './live2.jpg', './live3.jpg', './live4.jpg', './live5.jpg', './live6.jpg'],
156
+ userDetails,
157
+ consent,
158
+ });
159
+ ```
160
+
161
+ ### Biometric enrollment
162
+
163
+ ```ts
164
+ const accepted = await smile.biometric.enroll({
165
+ selfieImage: './selfie.jpg',
166
+ livenessImages: ['./live1.jpg', './live2.jpg', './live3.jpg', './live4.jpg', './live5.jpg', './live6.jpg'],
167
+ userDetails,
168
+ consent,
169
+ userId: 'user_01h8x9y2z3a4b5c6d7e8f9g0h1',
170
+ });
171
+ ```
172
+
173
+ ### Biometric authentication
174
+
175
+ `userId` is required and must match an enrolled user. Images are required unless `useEnrolledImage` is true.
176
+
177
+ ```ts
178
+ const accepted = await smile.biometric.authenticate({
179
+ userId: 'user_01h8x9y2z3a4b5c6d7e8f9g0h1',
180
+ selfieImage: './selfie.jpg',
181
+ livenessImages: ['./live1.jpg', './live2.jpg', './live3.jpg', './live4.jpg', './live5.jpg', './live6.jpg'],
182
+ userDetails,
183
+ consent,
184
+ });
185
+ ```
186
+
187
+ ### Selfie comparison
188
+
189
+ ```ts
190
+ const accepted = await smile.biometric.compare({
191
+ selfieImage: './selfie.jpg',
192
+ comparisonImage: './id-photo.jpg',
193
+ comparisonImageType: 'ID_PHOTO', // DOCUMENT | ID_PHOTO | PORTRAIT
194
+ userDetails,
195
+ consent,
196
+ });
197
+ ```
198
+
199
+ ### Check a verification
200
+
201
+ `retrieve` never throws on an unknown job: a 404 comes back as a `JobStatus` with `status: "not_found"` so polling can treat it as pending.
202
+
203
+ `status` is `processing` while the job runs, `not_found` for an unknown job, and otherwise the decision itself: `clear`, `block`, `attention` or `error`. `message` is a human-readable note, "Job completed" on a finished job — the decision is never in the message.
204
+
205
+ ```ts
206
+ const status = await smile.verifications.retrieve('job_01h8x9y2z3a4b5c6d7e8f9g0h1');
207
+ status.status; // e.g. "clear"
208
+ status.isComplete; // true on any decision, i.e. not processing and not not_found
209
+ status.isProcessing; // true while running
210
+ status.message; // e.g. "Job completed"
211
+ ```
212
+
213
+ ### Wait for completion
214
+
215
+ Polls while the job is `processing` (and, by default, while it is `not_found`), then returns the status carrying the decision. Throws `TimeoutError` when the deadline passes. Options: `interval` (default 2000 ms), `timeout` (default 60000 ms), and `treatNotFoundAsPending` (default true).
216
+
217
+ ```ts
218
+ const status = await smile.verifications.waitUntilComplete('job_01h8x9y2z3a4b5c6d7e8f9g0h1', {
219
+ interval: 2000,
220
+ timeout: 60000,
221
+ });
222
+ ```
223
+
224
+ ### Replay a callback
225
+
226
+ Only completed verifications can be replayed; a replay of a job that is still processing throws `ConflictError`.
227
+
228
+ ```ts
229
+ const accepted = await smile.verifications.replay('job_01h8x9y2z3a4b5c6d7e8f9g0h1', {
230
+ callbackUrl: 'https://app.example.com/smile/callback',
231
+ });
232
+ ```
233
+
234
+ ### Report fraud
235
+
236
+ `reason` is required when flagging fraud; `notes` is required when clearing it or when the reason is `OTHER`.
237
+
238
+ ```ts
239
+ const accepted = await smile.users.reportFraud('user_01h8x9y2z3a4b5c6d7e8f9g0h1', {
240
+ isFraud: true,
241
+ reason: 'ACCOUNT_TAKEOVER',
242
+ reportedBy: 'trust@example.com',
243
+ });
244
+ ```
245
+
246
+ The `flagFraud` and `clearFraud` wrappers set `isFraud` for you:
247
+
248
+ ```ts
249
+ await smile.users.flagFraud('user_01h8x9y2z3a4b5c6d7e8f9g0h1', {
250
+ reason: 'DOCUMENT_FORGERY',
251
+ reportedBy: 'trust@example.com',
252
+ });
253
+
254
+ await smile.users.clearFraud('user_01h8x9y2z3a4b5c6d7e8f9g0h1', {
255
+ notes: 'Investigated and cleared.',
256
+ reportedBy: 'trust@example.com',
257
+ });
258
+ ```
259
+
260
+ ### Bank codes
261
+
262
+ No authentication needed.
263
+
264
+ ```ts
265
+ const { bankCodes } = await smile.services.bankCodes({ country: 'NG' });
266
+ ```
267
+
268
+ ### Supported ID types
269
+
270
+ No authentication needed.
271
+
272
+ ```ts
273
+ const { idTypes } = await smile.services.supportedIdTypes({ country: 'NG' });
274
+ ```
275
+
276
+ ### Supported documents
277
+
278
+ No authentication needed.
279
+
280
+ ```ts
281
+ const { validDocuments } = await smile.services.supportedDocuments({ countryCode: 'NG' });
282
+ ```
283
+
284
+ ### ID provider status
285
+
286
+ ```ts
287
+ const status = await smile.services.idStatus({ country: 'NG', idType: 'NIN' });
288
+ status.lastKnownStatus; // "online"
289
+ ```
290
+
291
+ ## Error handling
292
+
293
+ Every failure throws a subclass of `SmileIDError`. Each error carries `statusCode`, `status`, `message`, `code` (services errors only), `requestId`, and `rawBody`.
294
+
295
+ | Error | When |
296
+ | ---------------------- | ---------------------------------------------------------- |
297
+ | `InvalidRequestError` | 400 or 415 |
298
+ | `ValidationError` | Client-side validation, before any request is sent |
299
+ | `AuthenticationError` | 401 after one token refresh has already been tried |
300
+ | `PaymentRequiredError` | 402, insufficient wallet balance |
301
+ | `PermissionError` | 403 |
302
+ | `NotFoundError` | 404 (not thrown by `verifications.retrieve`) |
303
+ | `ConflictError` | 409, e.g. replaying a job that is still processing |
304
+ | `PayloadTooLargeError` | 413 |
305
+ | `RateLimitError` | 429 |
306
+ | `APIError` | 5xx |
307
+ | `ConnectionError` | Network failure with no HTTP response |
308
+ | `UnexpectedResponseError` | A 2xx response whose body is not a JSON object |
309
+ | `TimeoutError` | `waitUntilComplete` deadline passed |
310
+
311
+ ```ts
312
+ import { PaymentRequiredError, SmileIDError } from '@smileid/usesmileid-nodejs';
313
+
314
+ try {
315
+ await smile.enhancedKyc.verify({ /* ... */ });
316
+ } catch (err) {
317
+ if (err instanceof PaymentRequiredError) {
318
+ // top up the wallet
319
+ } else if (err instanceof SmileIDError) {
320
+ console.error(err.statusCode, err.message);
321
+ }
322
+ }
323
+ ```
324
+
325
+ ### Retries
326
+
327
+ The SDK retries idempotent operations only (status and services reads, plus the internal token fetch) on connection errors, 408, 429, and 5xx, honouring the `Retry-After` header. It never retries verification submissions, replay, or fraud reports, and never retries a 409 — those are yours to decide.
328
+
329
+ ## Telemetry
330
+
331
+ Every request carries three headers identifying the SDK: `SmileID-Source-SDK: node`, `SmileID-Source-SDK-Version`, and a `User-Agent` with the runtime version. These are observability metadata only; they are never used for authentication and carry no personal data.
332
+
333
+ ## License
334
+
335
+ MIT — see [LICENSE](LICENSE).
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Internal JWT token lifecycle (spec §2.3, §2A).
3
+ *
4
+ * Partners never see or pass a token. The manager fetches one from
5
+ * POST /v3/token, caches it until `exp − 60s`, and refreshes on demand. Token
6
+ * fetches are stampede-safe: concurrent callers share a single in-flight
7
+ * promise, so the token endpoint is hit once (JavaScript's single-threaded
8
+ * model makes the in-flight promise the mutex).
9
+ *
10
+ * The fetch itself goes through the transport's execute path, so it gets the
11
+ * same retry policy (the token POST is idempotent, spec §2.6) and the same
12
+ * typed-error mapping (network failures raise ConnectionError) as every other
13
+ * idempotent operation.
14
+ */
15
+ import type { RequestPlan, TransportResult } from './transport.js';
16
+ /** Executes a request plan; provided by the transport. */
17
+ export type ExecuteFn = (plan: RequestPlan) => Promise<TransportResult>;
18
+ /** Manages the internal JWT: fetch, cache, refresh, stampede-safe. */
19
+ export declare class TokenManager {
20
+ private readonly partnerId;
21
+ private readonly apiKey;
22
+ private readonly execute;
23
+ private readonly now;
24
+ private cached;
25
+ private inflight;
26
+ constructor(partnerId: string, apiKey: string, execute: ExecuteFn, now?: () => number);
27
+ /** Return a valid cached token, fetching one if necessary. */
28
+ ensureToken(): Promise<string>;
29
+ /** Discard the cached token so the next call fetches a fresh one. */
30
+ invalidate(): void;
31
+ private fetchToken;
32
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ /**
3
+ * Internal JWT token lifecycle (spec §2.3, §2A).
4
+ *
5
+ * Partners never see or pass a token. The manager fetches one from
6
+ * POST /v3/token, caches it until `exp − 60s`, and refreshes on demand. Token
7
+ * fetches are stampede-safe: concurrent callers share a single in-flight
8
+ * promise, so the token endpoint is hit once (JavaScript's single-threaded
9
+ * model makes the in-flight promise the mutex).
10
+ *
11
+ * The fetch itself goes through the transport's execute path, so it gets the
12
+ * same retry policy (the token POST is idempotent, spec §2.6) and the same
13
+ * typed-error mapping (network failures raise ConnectionError) as every other
14
+ * idempotent operation.
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.TokenManager = void 0;
18
+ const index_js_1 = require("../errors/index.js");
19
+ const jwt_js_1 = require("../helpers/jwt.js");
20
+ /** Skew subtracted from token expiry so a token is refreshed before it lapses. */
21
+ const EXPIRY_SKEW_SECONDS = 60;
22
+ /** Manages the internal JWT: fetch, cache, refresh, stampede-safe. */
23
+ class TokenManager {
24
+ partnerId;
25
+ apiKey;
26
+ execute;
27
+ now;
28
+ cached = null;
29
+ inflight = null;
30
+ constructor(partnerId, apiKey, execute, now = () => Date.now()) {
31
+ this.partnerId = partnerId;
32
+ this.apiKey = apiKey;
33
+ this.execute = execute;
34
+ this.now = now;
35
+ }
36
+ /** Return a valid cached token, fetching one if necessary. */
37
+ async ensureToken() {
38
+ if (this.cached && this.now() < this.cached.expiresAt) {
39
+ return this.cached.jwt;
40
+ }
41
+ if (this.inflight) {
42
+ return this.inflight;
43
+ }
44
+ this.inflight = this.fetchToken().finally(() => {
45
+ this.inflight = null;
46
+ });
47
+ return this.inflight;
48
+ }
49
+ /** Discard the cached token so the next call fetches a fresh one. */
50
+ invalidate() {
51
+ this.cached = null;
52
+ }
53
+ async fetchToken() {
54
+ // The token endpoint documents lowercase header names; send them verbatim.
55
+ // No body is sent. The plan is unauthenticated (no SmileID-Token) and
56
+ // idempotent, so the transport retries transient failures (spec §2.6).
57
+ const result = await this.execute({
58
+ method: 'POST',
59
+ path: '/v3/token',
60
+ authenticated: false,
61
+ needsPartnerIdHeader: false,
62
+ idempotent: true,
63
+ headers: {
64
+ 'smileid-partner-id': this.partnerId,
65
+ 'smileid-api-key': this.apiKey,
66
+ },
67
+ });
68
+ const jwt = result.json?.token;
69
+ if (!jwt) {
70
+ throw (0, index_js_1.parseError)({
71
+ statusCode: result.statusCode,
72
+ rawBody: result.rawBody,
73
+ requestId: result.requestId,
74
+ });
75
+ }
76
+ const exp = (0, jwt_js_1.decodeJwtExp)(jwt);
77
+ // A decodable exp caches until exp − skew; an undecodable one refreshes next call.
78
+ const expiresAt = exp !== null ? (exp - EXPIRY_SKEW_SECONDS) * 1000 : this.now();
79
+ this.cached = { jwt, expiresAt };
80
+ return jwt;
81
+ }
82
+ }
83
+ exports.TokenManager = TokenManager;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * The SmileID client and its resource namespaces (spec §4).
3
+ *
4
+ * Canonical shape: `client.<resource>.<verb>(args, options)`. All 14 public
5
+ * operations plus the waitUntilComplete poll helper and the flagFraud /
6
+ * clearFraud convenience wrappers.
7
+ */
8
+ import { type SmileIDConfig } from './config.js';
9
+ import type { AcceptedResponse, AuthenticationParams, BankCodesParams, BankCodesResponse, BiometricKycParams, ClearFraudParams, CompareParams, DocumentVerificationParams, EnhancedDocumentVerificationParams, EnhancedKycParams, FlagFraudParams, IdStatusParams, IdStatusResponse, JobStatus, RegistrationParams, ReplayParams, ReportFraudParams, RequestOptions, SupportedDocumentsParams, SupportedDocumentsResponse, SupportedIdTypesParams, SupportedIdTypesResponse, WaitOptions } from '../generated/models/index.js';
10
+ /** The Smile ID V3 server-side client. */
11
+ export declare class SmileID {
12
+ private readonly transport;
13
+ /** enhanced_kyc (spec §6.1). */
14
+ readonly enhancedKyc: {
15
+ verify(params: EnhancedKycParams, options?: RequestOptions): Promise<AcceptedResponse>;
16
+ };
17
+ /** Document verification (spec §6.2, §6.3). */
18
+ readonly documents: {
19
+ verify(params: DocumentVerificationParams, options?: RequestOptions): Promise<AcceptedResponse>;
20
+ verifyEnhanced(params: EnhancedDocumentVerificationParams, options?: RequestOptions): Promise<AcceptedResponse>;
21
+ };
22
+ /** Biometric KYC (spec §6.4). */
23
+ readonly biometricKyc: {
24
+ verify(params: BiometricKycParams, options?: RequestOptions): Promise<AcceptedResponse>;
25
+ };
26
+ /** Biometric enroll / authenticate / compare (spec §6.5–§6.7). */
27
+ readonly biometric: {
28
+ enroll(params: RegistrationParams, options?: RequestOptions): Promise<AcceptedResponse>;
29
+ authenticate(params: AuthenticationParams, options?: RequestOptions): Promise<AcceptedResponse>;
30
+ compare(params: CompareParams, options?: RequestOptions): Promise<AcceptedResponse>;
31
+ };
32
+ /** Job status, polling, and callback replay (spec §6.8–§6.10). */
33
+ readonly verifications: {
34
+ retrieve(jobId: string, options?: RequestOptions): Promise<JobStatus>;
35
+ waitUntilComplete(jobId: string, options?: WaitOptions): Promise<JobStatus>;
36
+ replay(jobId: string, params?: ReplayParams, options?: RequestOptions): Promise<AcceptedResponse>;
37
+ };
38
+ /** Fraud reporting (spec §6.11). */
39
+ readonly users: {
40
+ reportFraud(userId: string, params: ReportFraudParams, options?: RequestOptions): Promise<AcceptedResponse>;
41
+ flagFraud(userId: string, params: FlagFraudParams, options?: RequestOptions): Promise<AcceptedResponse>;
42
+ clearFraud(userId: string, params: ClearFraudParams, options?: RequestOptions): Promise<AcceptedResponse>;
43
+ };
44
+ /** Services lookups (spec §6.12–§6.15). */
45
+ readonly services: {
46
+ bankCodes(params?: BankCodesParams, options?: RequestOptions): Promise<BankCodesResponse>;
47
+ supportedIdTypes(params?: SupportedIdTypesParams, options?: RequestOptions): Promise<SupportedIdTypesResponse>;
48
+ supportedDocuments(params?: SupportedDocumentsParams, options?: RequestOptions): Promise<SupportedDocumentsResponse>;
49
+ idStatus(params: IdStatusParams, options?: RequestOptions): Promise<IdStatusResponse>;
50
+ };
51
+ constructor(config: SmileIDConfig);
52
+ }
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ /**
3
+ * The SmileID client and its resource namespaces (spec §4).
4
+ *
5
+ * Canonical shape: `client.<resource>.<verb>(args, options)`. All 14 public
6
+ * operations plus the waitUntilComplete poll helper and the flagFraud /
7
+ * clearFraud convenience wrappers.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.SmileID = void 0;
44
+ const config_js_1 = require("./config.js");
45
+ const transport_js_1 = require("./transport.js");
46
+ const ops = __importStar(require("../generated/operations/index.js"));
47
+ const index_js_1 = require("../errors/index.js");
48
+ const poll_js_1 = require("../helpers/poll.js");
49
+ const validation_js_1 = require("../helpers/validation.js");
50
+ /** The Smile ID V3 server-side client. */
51
+ class SmileID {
52
+ transport;
53
+ /** enhanced_kyc (spec §6.1). */
54
+ enhancedKyc;
55
+ /** Document verification (spec §6.2, §6.3). */
56
+ documents;
57
+ /** Biometric KYC (spec §6.4). */
58
+ biometricKyc;
59
+ /** Biometric enroll / authenticate / compare (spec §6.5–§6.7). */
60
+ biometric;
61
+ /** Job status, polling, and callback replay (spec §6.8–§6.10). */
62
+ verifications;
63
+ /** Fraud reporting (spec §6.11). */
64
+ users;
65
+ /** Services lookups (spec §6.12–§6.15). */
66
+ services;
67
+ constructor(config) {
68
+ this.transport = new transport_js_1.Transport((0, config_js_1.resolveConfig)(config));
69
+ const t = this.transport;
70
+ this.enhancedKyc = {
71
+ verify: (params, options) => {
72
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
73
+ return ops.enhancedKyc(t, params, options);
74
+ },
75
+ };
76
+ this.documents = {
77
+ verify: (params, options) => {
78
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
79
+ return ops.documentVerification(t, params, options);
80
+ },
81
+ verifyEnhanced: (params, options) => {
82
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
83
+ // idType is required for enhanced document verification (spec §6.3);
84
+ // enforced at runtime for plain-JavaScript callers too.
85
+ if (!params.idType) {
86
+ throw new index_js_1.ValidationError({
87
+ message: 'idType is required for enhanced document verification.',
88
+ });
89
+ }
90
+ return ops.enhancedDocumentVerification(t, params, options);
91
+ },
92
+ };
93
+ this.biometricKyc = {
94
+ verify: (params, options) => {
95
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
96
+ return ops.biometricKyc(t, params, options);
97
+ },
98
+ };
99
+ this.biometric = {
100
+ enroll: (params, options) => {
101
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
102
+ return ops.registration(t, params, options);
103
+ },
104
+ authenticate: (params, options) => {
105
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
106
+ (0, validation_js_1.validateAuthentication)(params);
107
+ return ops.authentication(t, params, options);
108
+ },
109
+ compare: (params, options) => {
110
+ (0, validation_js_1.validateUserDetails)(params.userDetails);
111
+ return ops.compare(t, params, options);
112
+ },
113
+ };
114
+ this.verifications = {
115
+ retrieve: (jobId, options) => ops.verificationStatus(t, jobId, options),
116
+ waitUntilComplete: (jobId, options) => (0, poll_js_1.waitUntilComplete)(() => ops.verificationStatus(t, jobId, {
117
+ signal: options?.signal,
118
+ timeout: options?.requestTimeout,
119
+ }), options),
120
+ replay: (jobId, params, options) => ops.replayCallback(t, jobId, params, options),
121
+ };
122
+ this.users = {
123
+ reportFraud: (userId, params, options) => {
124
+ (0, validation_js_1.validateReportFraud)(params);
125
+ return ops.reportFraud(t, userId, params, options);
126
+ },
127
+ flagFraud: (userId, params, options) => {
128
+ const report = {
129
+ isFraud: true,
130
+ reason: params.reason,
131
+ notes: params.notes,
132
+ reportedBy: params.reportedBy,
133
+ };
134
+ (0, validation_js_1.validateReportFraud)(report);
135
+ return ops.reportFraud(t, userId, report, options);
136
+ },
137
+ clearFraud: (userId, params, options) => {
138
+ const report = {
139
+ isFraud: false,
140
+ notes: params.notes,
141
+ reportedBy: params.reportedBy,
142
+ };
143
+ (0, validation_js_1.validateReportFraud)(report);
144
+ return ops.reportFraud(t, userId, report, options);
145
+ },
146
+ };
147
+ this.services = {
148
+ bankCodes: (params, options) => ops.bankCodes(t, params, options),
149
+ supportedIdTypes: (params, options) => ops.supportedIdTypes(t, params, options),
150
+ supportedDocuments: (params, options) => ops.supportedDocuments(t, params, options),
151
+ idStatus: (params, options) => ops.idStatus(t, params, options),
152
+ };
153
+ }
154
+ }
155
+ exports.SmileID = SmileID;