@verne-software/sdk 1.1.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 Verne Software
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,217 @@
1
+ # Verne Software Node.js SDK
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@verne-software/sdk.svg)](https://npmjs.org/package/@verne-software/sdk)
4
+ [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](#)
5
+
6
+ The official Node.js and TypeScript library for the [Verne Nautilus](https://vernesoft.com) platform.
7
+
8
+ > **Server-side only.** API keys carry full service access and must never be used in browser or client-side code.
9
+
10
+ ## Requirements
11
+
12
+ Node.js 18 or later.
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @verne-software/sdk
18
+ # or
19
+ yarn add @verne-software/sdk
20
+ # or
21
+ pnpm add @verne-software/sdk
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```ts
27
+ import { Verne } from '@verne-software/sdk';
28
+
29
+ const verne = new Verne({
30
+ relay: process.env.VERNE_RELAY_KEY,
31
+ gate: process.env.VERNE_GATE_KEY,
32
+ });
33
+ ```
34
+
35
+ You can also instantiate services independently if you only need one:
36
+
37
+ ```ts
38
+ import { Relay, Gate } from '@verne-software/sdk';
39
+
40
+ const relay = new Relay({ apiKey: process.env.VERNE_RELAY_KEY });
41
+ const gate = new Gate({ apiKey: process.env.VERNE_GATE_KEY });
42
+ ```
43
+
44
+ ## Relay — Webhooks-as-a-Service
45
+
46
+ Send events to all subscribed endpoints:
47
+
48
+ ```ts
49
+ await verne.relay.messages.send({
50
+ event_type: 'user.created',
51
+ payload: { id: 'usr_123' },
52
+ });
53
+ ```
54
+
55
+ Optional parameters:
56
+
57
+ ```ts
58
+ await verne.relay.messages.send({
59
+ event_type: 'order.placed',
60
+ payload: { order_id: '999' },
61
+ idempotency_key: 'evt_abc', // prevent duplicate delivery within 24h
62
+ channels: ['team-a'], // restrict to specific endpoint channels
63
+ });
64
+ ```
65
+
66
+ List previously sent events:
67
+
68
+ ```ts
69
+ const page = await verne.relay.messages.list({ limit: 20, event_type: 'user.created' });
70
+
71
+ console.log(page.data); // Message[]
72
+ console.log(page.has_more); // boolean
73
+ console.log(page.next_cursor); // pass to the next call to paginate
74
+ ```
75
+
76
+ ## Gate — Auth-as-a-Service
77
+
78
+ ### Identity Management
79
+
80
+ Manage your end-users. The `tenant_id` is automatically scoped to your API key.
81
+
82
+ ```ts
83
+ // Create a user
84
+ const identity = await verne.gate.identities.create({
85
+ schema_id: 'user',
86
+ traits: {
87
+ email: 'user@example.com',
88
+ custom_data: { role: 'editor' },
89
+ },
90
+ credentials: {
91
+ password: { config: { password: 'StrongPassword123!' } },
92
+ },
93
+ state: 'active',
94
+ });
95
+
96
+ // Get a user
97
+ await verne.gate.identities.get(identity.id);
98
+
99
+ // Update a user (JSON Patch — RFC 6902)
100
+ await verne.gate.identities.patch(identity.id, [
101
+ { op: 'replace', path: '/traits/custom_data/role', value: 'admin' },
102
+ ]);
103
+
104
+ // Delete a user
105
+ await verne.gate.identities.delete(identity.id);
106
+
107
+ // Activate / deactivate a user (an inactive user cannot log in)
108
+ await verne.gate.identities.deactivate(identity.id);
109
+ await verne.gate.identities.activate(identity.id);
110
+ // …or set the state explicitly:
111
+ await verne.gate.identities.setState(identity.id, 'inactive');
112
+
113
+ // Resend the email verification link
114
+ await verne.gate.identities.resendVerification(identity.id);
115
+ ```
116
+
117
+ ### Security Settings
118
+
119
+ Read or replace the tenant's security settings (passwordless login, TOTP MFA):
120
+
121
+ ```ts
122
+ const security = await verne.gate.settings.getSecurity();
123
+ // security.passwordless_enabled, security.mfa_enabled
124
+
125
+ // Both fields are required — the update is a full replacement, not a merge.
126
+ await verne.gate.settings.updateSecurity({
127
+ passwordless_enabled: true,
128
+ mfa_enabled: false,
129
+ });
130
+ ```
131
+
132
+ ### Access Tokens
133
+
134
+ Exchange your long-lived API key for a short-lived access token:
135
+
136
+ ```ts
137
+ const token = await verne.gate.tokens.create({
138
+ subject: 'usr_123',
139
+ scopes: ['gate.tokens.read'], // optional
140
+ ttl_seconds: 3600, // optional, default 3600, max 86400
141
+ });
142
+
143
+ // token.access_token — attach to downstream requests
144
+ // token.expires_at — ISO 8601 expiry
145
+ ```
146
+
147
+ Validate a token:
148
+
149
+ ```ts
150
+ const info = await verne.gate.tokens.introspect(token.access_token);
151
+
152
+ if (!info.active) {
153
+ // token is expired or invalid
154
+ }
155
+ ```
156
+
157
+ ### Authorization
158
+
159
+ Check whether a subject is allowed to perform an action:
160
+
161
+ ```ts
162
+ const decision = await verne.gate.authorize({
163
+ subject: 'usr_123',
164
+ action: 'relay.messages.read',
165
+ resource: 'tenant:ten_001',
166
+ });
167
+
168
+ if (!decision.allowed) {
169
+ throw new Error('Forbidden');
170
+ }
171
+ ```
172
+
173
+ ## Error Handling
174
+
175
+ All API errors throw a `VerneAPIError` with structured fields:
176
+
177
+ ```ts
178
+ import { VerneAPIError } from '@verne-software/sdk';
179
+
180
+ try {
181
+ await verne.relay.messages.send({ event_type: 'ping', payload: {} });
182
+ } catch (err) {
183
+ if (err instanceof VerneAPIError) {
184
+ console.error(err.code); // e.g. 'invalid_payload', 'unauthorized'
185
+ console.error(err.status); // HTTP status code
186
+ console.error(err.requestId); // include in support requests
187
+ }
188
+ }
189
+ ```
190
+
191
+ Network failures and timeouts throw a base `VerneError`.
192
+
193
+ ## Configuration
194
+
195
+ Both `Verne` and the per-service clients accept an optional `timeoutMs` (default `30000`):
196
+
197
+ ```ts
198
+ const verne = new Verne({
199
+ relay: process.env.VERNE_RELAY_KEY,
200
+ timeoutMs: 10_000,
201
+ });
202
+ ```
203
+
204
+ Individual requests can be cancelled with an `AbortSignal`:
205
+
206
+ ```ts
207
+ const controller = new AbortController();
208
+
209
+ await verne.relay.messages.send(
210
+ { event_type: 'ping', payload: {} },
211
+ { signal: controller.signal },
212
+ );
213
+ ```
214
+
215
+ ## License
216
+
217
+ [MIT](LICENSE)
@@ -0,0 +1,421 @@
1
+ /**
2
+ * Paginated response wrapper returned by list endpoints.
3
+ */
4
+ interface Paginated<T> {
5
+ data: T[];
6
+ has_more: boolean;
7
+ next_cursor?: string;
8
+ }
9
+ /**
10
+ * Per-request options that can override client defaults.
11
+ */
12
+ interface RequestOptions {
13
+ /** Abort signal to cancel the request. */
14
+ signal?: AbortSignal;
15
+ /** Request timeout in milliseconds. Overrides the client-level default. */
16
+ timeoutMs?: number;
17
+ /** Extra headers merged into the request. */
18
+ headers?: Record<string, string>;
19
+ }
20
+ /**
21
+ * Configuration for the unified Verne client.
22
+ * Each key corresponds to a service; only provide keys for the services you use.
23
+ */
24
+ interface VerneConfig {
25
+ /** API key for the Relay (Webhooks-as-a-Service) service. Format: vrn_relay_<env>_<secret> */
26
+ relay?: string;
27
+ /** API key for the Gate (Auth-as-a-Service) service. Format: vrn_gate_<env>_<secret> */
28
+ gate?: string;
29
+ /** Base URL override. Defaults to https://api.vernesoft.com */
30
+ baseUrl?: string;
31
+ /** Default request timeout in milliseconds. Defaults to 30000. */
32
+ timeoutMs?: number;
33
+ }
34
+ /**
35
+ * Configuration for a single-service client (Relay or Gate).
36
+ */
37
+ interface ServiceConfig {
38
+ /** API key for the service. */
39
+ apiKey: string;
40
+ /** Base URL override. Defaults to https://api.vernesoft.com */
41
+ baseUrl?: string;
42
+ /** Default request timeout in milliseconds. Defaults to 30000. */
43
+ timeoutMs?: number;
44
+ }
45
+
46
+ interface HttpClientConfig {
47
+ apiKey: string;
48
+ baseUrl?: string;
49
+ timeoutMs?: number;
50
+ }
51
+ interface HttpRequestOptions extends RequestOptions {
52
+ /** When true, omit the Authorization header (used by gate.tokens.create). */
53
+ skipAuth?: boolean;
54
+ /** Body to send as JSON. */
55
+ body?: unknown;
56
+ }
57
+ declare class HttpClient {
58
+ private readonly apiKey;
59
+ private readonly baseUrl;
60
+ private readonly timeoutMs;
61
+ constructor(config: HttpClientConfig);
62
+ get<T>(path: string, options?: HttpRequestOptions): Promise<T>;
63
+ post<T>(path: string, options?: HttpRequestOptions): Promise<T>;
64
+ put<T>(path: string, options?: HttpRequestOptions): Promise<T>;
65
+ patch<T>(path: string, options?: HttpRequestOptions): Promise<T>;
66
+ delete<T>(path: string, options?: HttpRequestOptions): Promise<T>;
67
+ private request;
68
+ }
69
+
70
+ /** A Kratos identity managed by Gate. */
71
+ interface Identity {
72
+ id: string;
73
+ schema_id: string;
74
+ state: 'active' | 'inactive';
75
+ traits: IdentityTraits;
76
+ }
77
+ interface IdentityTraits {
78
+ email: string;
79
+ tenant_id: string;
80
+ custom_data?: Record<string, unknown>;
81
+ }
82
+ /**
83
+ * Parameters for creating a new identity (end-user) bound to your tenant.
84
+ * The `traits.tenant_id` is injected automatically by the Edge Gateway.
85
+ */
86
+ interface CreateIdentityParams {
87
+ /** Must be 'user'. */
88
+ schema_id: 'user';
89
+ traits: {
90
+ email: string;
91
+ /** Optional arbitrary fields for your application. */
92
+ custom_data?: Record<string, unknown>;
93
+ };
94
+ credentials?: {
95
+ password?: {
96
+ config: {
97
+ password: string;
98
+ };
99
+ };
100
+ };
101
+ state?: 'active' | 'inactive';
102
+ }
103
+ /**
104
+ * A single operation in a JSON Patch document (RFC 6902).
105
+ * Used by identities.patch() to partially update an identity.
106
+ */
107
+ interface JsonPatchOp {
108
+ op: 'add' | 'remove' | 'replace' | 'move' | 'copy' | 'test';
109
+ path: string;
110
+ value?: unknown;
111
+ from?: string;
112
+ }
113
+ /** Security-related Gate Identity settings for your tenant. */
114
+ interface SecuritySettings {
115
+ /** Whether email-OTP (passwordless) login is enabled. */
116
+ passwordless_enabled: boolean;
117
+ /** Whether TOTP two-factor authentication is enabled. */
118
+ mfa_enabled: boolean;
119
+ }
120
+ /**
121
+ * A social login (OAuth 2.0 / OIDC) provider and whether it is enabled for
122
+ * your tenant's end-users.
123
+ */
124
+ interface OidcProvider {
125
+ /** Provider identifier, e.g. `'github'`, `'google'`, `'gitlab'`. */
126
+ provider: string;
127
+ /** Whether the provider appears in your tenant's login/registration UI. */
128
+ enabled: boolean;
129
+ }
130
+ /**
131
+ * A Kratos self-service auth flow returned by {@link Gate.createLoginFlow}.
132
+ *
133
+ * The shape mirrors the raw Ory Kratos flow JSON (`ui.nodes`, `ui.action`,
134
+ * …); pass it straight to your browser-side code to render social buttons.
135
+ */
136
+ type LoginFlow = Record<string, unknown>;
137
+ /** Short-lived access token returned by tokens.create(). */
138
+ interface AccessToken {
139
+ access_token: string;
140
+ expires_at: string;
141
+ subject: string;
142
+ tenant_id: string;
143
+ }
144
+ /** Parameters for exchanging an API key for a short-lived access token. */
145
+ interface CreateTokenParams {
146
+ /** The ID of the user or service account this token represents. */
147
+ subject: string;
148
+ /** Optional list of scopes to narrow the token's permissions. */
149
+ scopes?: string[];
150
+ /** Custom lifetime in seconds. Default 3600, max 86400. */
151
+ ttl_seconds?: number;
152
+ }
153
+ /** Result of token introspection. */
154
+ interface IntrospectResult {
155
+ active: boolean;
156
+ subject: string;
157
+ tenant_id: string;
158
+ scopes: string[];
159
+ expires_at: string;
160
+ }
161
+ /** Parameters for checking whether a subject can perform an action. */
162
+ interface AuthorizeParams {
163
+ /** ID of the user or service account (e.g. 'usr_123'). */
164
+ subject: string;
165
+ /** Action being performed (e.g. 'relay.messages.read'). */
166
+ action: string;
167
+ /** Resource identifier (e.g. 'tenant:ten_001' or 'relay:key:key_123'). */
168
+ resource: string;
169
+ /** Optional extra attributes for policy evaluation. */
170
+ context?: Record<string, unknown>;
171
+ }
172
+ /** Authorization decision returned by gate.authorize(). */
173
+ interface AuthorizeResult {
174
+ allowed: boolean;
175
+ decision_id: string;
176
+ reason: string;
177
+ }
178
+
179
+ declare class IdentitiesResource {
180
+ private readonly http;
181
+ constructor(http: HttpClient);
182
+ /**
183
+ * Creates a new identity (end-user) bound to your tenant.
184
+ * The `traits.tenant_id` is injected automatically by the Edge Gateway.
185
+ */
186
+ create(params: CreateIdentityParams, options?: RequestOptions): Promise<Identity>;
187
+ /**
188
+ * Returns an identity by ID.
189
+ * The Gateway will reject the request if the identity does not belong to your tenant.
190
+ */
191
+ get(identityId: string, options?: RequestOptions): Promise<Identity>;
192
+ /**
193
+ * Partially updates an identity using a JSON Patch document (RFC 6902).
194
+ *
195
+ * @example
196
+ * await gate.identities.patch('identity_123', [
197
+ * { op: 'replace', path: '/traits/custom_data/role', value: 'admin' }
198
+ * ]);
199
+ */
200
+ patch(identityId: string, ops: JsonPatchOp[], options?: RequestOptions): Promise<Identity>;
201
+ /**
202
+ * Deletes an identity from Kratos.
203
+ * The Gateway will reject the request if the identity does not belong to your tenant.
204
+ */
205
+ delete(identityId: string, options?: RequestOptions): Promise<void>;
206
+ /**
207
+ * Activates or deactivates an identity. An `inactive` identity cannot log in —
208
+ * Kratos rejects its credentials automatically — until it is reactivated.
209
+ * The identity is not deleted. Fires the `identity.state_changed` webhook event.
210
+ *
211
+ * @example
212
+ * await gate.identities.setState('identity_123', 'inactive');
213
+ */
214
+ setState(identityId: string, state: 'active' | 'inactive', options?: RequestOptions): Promise<Identity>;
215
+ /** Convenience wrapper for {@link setState}(identityId, 'active'). */
216
+ activate(identityId: string, options?: RequestOptions): Promise<Identity>;
217
+ /** Convenience wrapper for {@link setState}(identityId, 'inactive'). */
218
+ deactivate(identityId: string, options?: RequestOptions): Promise<Identity>;
219
+ /**
220
+ * Triggers a new email verification flow for an identity — useful when the
221
+ * original verification email expired or was never received. The user receives
222
+ * a fresh verification email. Resolves on `204 No Content`.
223
+ */
224
+ resendVerification(identityId: string, options?: RequestOptions): Promise<void>;
225
+ }
226
+
227
+ declare class SettingsResource {
228
+ private readonly http;
229
+ constructor(http: HttpClient);
230
+ /**
231
+ * Returns the tenant's security settings (passwordless / MFA).
232
+ */
233
+ getSecurity(options?: RequestOptions): Promise<SecuritySettings>;
234
+ /**
235
+ * Replaces the tenant's security settings. Both fields are required — the
236
+ * update is a full replacement, not a merge.
237
+ *
238
+ * @example
239
+ * await gate.settings.updateSecurity({ passwordless_enabled: true, mfa_enabled: false });
240
+ */
241
+ updateSecurity(settings: SecuritySettings, options?: RequestOptions): Promise<void>;
242
+ /**
243
+ * Returns the tenant's social login (OIDC) providers and whether each is
244
+ * enabled. Covers all providers Gate supports, regardless of state.
245
+ */
246
+ getOidcProviders(options?: RequestOptions): Promise<OidcProvider[]>;
247
+ /**
248
+ * Sets the `enabled` flag for one or more social login providers. Any
249
+ * provider omitted from `providers` is left unchanged. Returns the full,
250
+ * updated provider list.
251
+ *
252
+ * @example
253
+ * await gate.settings.updateOidcProviders([
254
+ * { provider: 'github', enabled: true },
255
+ * { provider: 'google', enabled: true },
256
+ * ]);
257
+ */
258
+ updateOidcProviders(providers: OidcProvider[], options?: RequestOptions): Promise<OidcProvider[]>;
259
+ }
260
+
261
+ declare class TokensResource {
262
+ private readonly http;
263
+ private readonly apiKey;
264
+ constructor(http: HttpClient, apiKey: string);
265
+ /**
266
+ * Exchanges the Gate API key for a short-lived access token.
267
+ *
268
+ * Note: This endpoint does not use the Authorization header — the API key
269
+ * is passed in the request body per the Gate API specification.
270
+ */
271
+ create(params: CreateTokenParams, options?: RequestOptions): Promise<AccessToken>;
272
+ /**
273
+ * Validates a Gate access token and returns its decoded attributes.
274
+ */
275
+ introspect(accessToken: string, options?: RequestOptions): Promise<IntrospectResult>;
276
+ }
277
+
278
+ declare class Gate {
279
+ readonly identities: IdentitiesResource;
280
+ readonly tokens: TokensResource;
281
+ readonly settings: SettingsResource;
282
+ private readonly http;
283
+ constructor(config: ServiceConfig);
284
+ /**
285
+ * Checks whether a given subject is allowed to perform an action on a resource.
286
+ * This is the core building block for enforcing authorization in your services.
287
+ *
288
+ * @example
289
+ * const result = await gate.authorize({
290
+ * subject: 'usr_123',
291
+ * action: 'relay.messages.read',
292
+ * resource: 'tenant:ten_001',
293
+ * });
294
+ * if (!result.allowed) throw new Error('Forbidden');
295
+ */
296
+ authorize(params: AuthorizeParams, options?: RequestOptions): Promise<AuthorizeResult>;
297
+ /**
298
+ * Returns the list of social login providers currently enabled for a tenant.
299
+ * This is a public, unauthenticated endpoint — call it from your login /
300
+ * registration page to decide which social buttons to render.
301
+ *
302
+ * @example
303
+ * const providers = await gate.getEnabledProviders('ten_001');
304
+ * // → ['github', 'google']
305
+ */
306
+ getEnabledProviders(tenantId: string, options?: RequestOptions): Promise<string[]>;
307
+ /**
308
+ * Initializes a Kratos login flow using your Gate API key. Call this from
309
+ * your server and pass the returned flow JSON to your browser-side code to
310
+ * render social login buttons. The flow already contains only the providers
311
+ * your tenant has enabled.
312
+ *
313
+ * @example
314
+ * const flow = await gate.createLoginFlow();
315
+ * // send `flow` to the browser as JSON
316
+ */
317
+ createLoginFlow(options?: RequestOptions): Promise<LoginFlow>;
318
+ }
319
+
320
+ /** A message (event) as returned by the Relay API. */
321
+ interface Message {
322
+ /** Unique message identifier. */
323
+ id: string;
324
+ /** Dot-notated event name (e.g. 'user.created'). */
325
+ event_type: string;
326
+ /** Delivery status after being accepted by Relay. */
327
+ status: 'accepted';
328
+ /** ISO 8601 timestamp of when the event was accepted. */
329
+ timestamp: string;
330
+ }
331
+ /** Parameters for sending an event via Relay. */
332
+ interface SendMessageParams {
333
+ /** Dot-notated event name (e.g. 'user.created'). */
334
+ event_type: string;
335
+ /** Arbitrary JSON payload delivered to subscribers. */
336
+ payload: Record<string, unknown>;
337
+ /**
338
+ * Optional idempotency key to prevent duplicate delivery within a 24-hour window.
339
+ * If a message with the same key was already accepted, a 409 is returned.
340
+ */
341
+ idempotency_key?: string;
342
+ /** Restrict delivery to endpoints listening on these channels. */
343
+ channels?: string[];
344
+ }
345
+ /** Query parameters for listing sent events. */
346
+ interface ListMessagesParams {
347
+ /** Number of items per page. Max 100. Defaults to 20. */
348
+ limit?: number;
349
+ /** Pagination cursor from a previous response. */
350
+ cursor?: string;
351
+ /** Filter results by event type. */
352
+ event_type?: string;
353
+ }
354
+ /** Paginated list of messages returned by GET /v1/relay/messages. */
355
+ type ListMessagesResponse = Paginated<Message>;
356
+
357
+ declare class MessagesResource {
358
+ private readonly http;
359
+ constructor(http: HttpClient);
360
+ /**
361
+ * Publish an event to all endpoints subscribed to the given event_type.
362
+ * Automatically retries once on 429 (respects Retry-After header).
363
+ *
364
+ * @returns The accepted message with its assigned ID and timestamp.
365
+ */
366
+ send(params: SendMessageParams, options?: RequestOptions): Promise<Message>;
367
+ /**
368
+ * Returns a paginated list of previously sent events for the current tenant.
369
+ */
370
+ list(params?: ListMessagesParams, options?: RequestOptions): Promise<ListMessagesResponse>;
371
+ }
372
+
373
+ declare class Relay {
374
+ readonly messages: MessagesResource;
375
+ constructor(config: ServiceConfig);
376
+ }
377
+
378
+ declare class Verne {
379
+ private readonly config;
380
+ private _relay?;
381
+ private _gate?;
382
+ constructor(config: VerneConfig);
383
+ get relay(): Relay;
384
+ get gate(): Gate;
385
+ }
386
+
387
+ /**
388
+ * Base class for all errors thrown by the Verne SDK.
389
+ */
390
+ declare class VerneError extends Error {
391
+ constructor(message: string);
392
+ }
393
+ /**
394
+ * Thrown when the Verne API returns an error response.
395
+ * Contains structured information from the API error envelope.
396
+ */
397
+ declare class VerneAPIError extends VerneError {
398
+ /** Machine-readable error code (e.g. 'invalid_payload', 'unauthorized'). */
399
+ readonly code: string;
400
+ /** HTTP status code. */
401
+ readonly status: number;
402
+ /** Request ID to include when contacting support. */
403
+ readonly requestId: string;
404
+ constructor({ code, message, status, requestId, }: {
405
+ code: string;
406
+ message: string;
407
+ status: number;
408
+ requestId: string;
409
+ });
410
+ static fromResponse(status: number, body: APIErrorBody): VerneAPIError;
411
+ }
412
+ /** Shape of the API error envelope returned by all Verne services. */
413
+ interface APIErrorBody {
414
+ error: {
415
+ code: string;
416
+ message: string;
417
+ request_id: string;
418
+ };
419
+ }
420
+
421
+ export { type APIErrorBody, type AccessToken, type AuthorizeParams, type AuthorizeResult, type CreateIdentityParams, type CreateTokenParams, Gate, type Identity, type IdentityTraits, type IntrospectResult, type JsonPatchOp, type ListMessagesParams, type ListMessagesResponse, type LoginFlow, type Message, type OidcProvider, type Paginated, Relay, type RequestOptions, type SecuritySettings, type SendMessageParams, type ServiceConfig, Verne, VerneAPIError, type VerneConfig, VerneError };