@insureco/bio 0.4.0 → 0.6.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/dist/graph.js ADDED
@@ -0,0 +1,225 @@
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/graph.ts
21
+ var graph_exports = {};
22
+ __export(graph_exports, {
23
+ GraphClient: () => GraphClient
24
+ });
25
+ module.exports = __toCommonJS(graph_exports);
26
+
27
+ // src/errors.ts
28
+ var BioError = class extends Error {
29
+ /** HTTP status code (if from an API response) */
30
+ statusCode;
31
+ /** Machine-readable error code (e.g. 'invalid_grant', 'token_expired') */
32
+ code;
33
+ /** Additional error details from the API */
34
+ details;
35
+ constructor(message, code, statusCode, details) {
36
+ super(message);
37
+ this.name = "BioError";
38
+ this.code = code;
39
+ this.statusCode = statusCode;
40
+ this.details = details;
41
+ }
42
+ };
43
+
44
+ // src/utils.ts
45
+ function retryDelay(attempt) {
46
+ const baseDelay = Math.min(1e3 * 2 ** attempt, 5e3);
47
+ return baseDelay * (0.5 + Math.random() * 0.5);
48
+ }
49
+ function sleep(ms) {
50
+ return new Promise((resolve) => setTimeout(resolve, ms));
51
+ }
52
+ async function parseJsonResponse(response) {
53
+ try {
54
+ return await response.json();
55
+ } catch {
56
+ throw new BioError(
57
+ `Bio-ID returned ${response.status} with non-JSON body`,
58
+ "parse_error",
59
+ response.status
60
+ );
61
+ }
62
+ }
63
+
64
+ // src/graph.ts
65
+ var DEFAULT_TIMEOUT_MS = 1e4;
66
+ var BIO_GRAPH_URL = "https://bio-graph.tawa.pro";
67
+ var GraphClient = class _GraphClient {
68
+ graphUrl;
69
+ accessToken;
70
+ timeoutMs;
71
+ constructor(config = {}) {
72
+ this.graphUrl = (config.graphUrl ?? process.env.BIO_GRAPH_URL ?? BIO_GRAPH_URL).replace(/\/$/, "");
73
+ this.accessToken = config.accessToken;
74
+ this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
75
+ }
76
+ /**
77
+ * Create a GraphClient from environment variables.
78
+ * BIO_GRAPH_URL defaults to https://bio-graph.tawa.pro if not set.
79
+ */
80
+ static fromEnv(overrides) {
81
+ return new _GraphClient({
82
+ graphUrl: overrides?.graphUrl ?? process.env.BIO_GRAPH_URL,
83
+ accessToken: overrides?.accessToken,
84
+ timeoutMs: overrides?.timeoutMs
85
+ });
86
+ }
87
+ // ─── Public Profile Routes ────────────────────────────────────────────────
88
+ /** Look up an agent by NPN. Returns agent properties + employment chain. */
89
+ async getAgent(npn) {
90
+ return this.get(`/api/graph/agent/${encodeURIComponent(npn)}`);
91
+ }
92
+ /**
93
+ * Look up an agency by iecHash, raterspotId, or orgSlug.
94
+ * Returns agency properties + staff list + accessible programs.
95
+ */
96
+ async getAgency(iecHash) {
97
+ return this.get(`/api/graph/agency/${encodeURIComponent(iecHash)}`);
98
+ }
99
+ /**
100
+ * Look up a carrier by NAIC code, iecHash, raterspotId, or orgSlug.
101
+ * Returns carrier properties + managed programs.
102
+ */
103
+ async getCarrier(naic) {
104
+ return this.get(`/api/graph/carrier/${encodeURIComponent(naic)}`);
105
+ }
106
+ /**
107
+ * Look up a program by iecHash or raterspotId.
108
+ * Returns program properties + managing carrier or MGA.
109
+ */
110
+ async getProgram(iecHash) {
111
+ return this.get(`/api/graph/program/${encodeURIComponent(iecHash)}`);
112
+ }
113
+ // ─── Authenticated Routes ─────────────────────────────────────────────────
114
+ /**
115
+ * Find programs whose appetite covers a given risk.
116
+ * Requires an accessToken (auth: required).
117
+ *
118
+ * @param input - Risk criteria: NAICS code, state, line of business, optional limits
119
+ */
120
+ async matchAppetite(input) {
121
+ return this.post("/api/graph/appetite/match", input, { requiresAuth: true });
122
+ }
123
+ // ─── Internal ─────────────────────────────────────────────────────────────
124
+ async get(path, attempt = 0) {
125
+ const url = `${this.graphUrl}${path}`;
126
+ const controller = new AbortController();
127
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
128
+ let response;
129
+ try {
130
+ response = await fetch(url, {
131
+ headers: this.buildHeaders(),
132
+ signal: controller.signal
133
+ });
134
+ } catch (err) {
135
+ clearTimeout(timer);
136
+ const isTimeout = err instanceof Error && err.name === "AbortError";
137
+ if (!isTimeout && attempt < 2) {
138
+ await sleep(retryDelay(attempt));
139
+ return this.get(path, attempt + 1);
140
+ }
141
+ throw new BioError(
142
+ isTimeout ? "bio-graph request timed out" : `bio-graph request failed: ${String(err)}`,
143
+ isTimeout ? "timeout" : "network_error"
144
+ );
145
+ } finally {
146
+ clearTimeout(timer);
147
+ }
148
+ return this.handleResponse(response, path);
149
+ }
150
+ async post(path, body, opts = {}, attempt = 0) {
151
+ if (opts.requiresAuth && !this.accessToken) {
152
+ throw new BioError(
153
+ `bio-graph ${path} requires an accessToken \u2014 pass it in the GraphClient constructor`,
154
+ "config_error"
155
+ );
156
+ }
157
+ const url = `${this.graphUrl}${path}`;
158
+ const controller = new AbortController();
159
+ const timer = setTimeout(() => controller.abort(), this.timeoutMs);
160
+ let response;
161
+ try {
162
+ response = await fetch(url, {
163
+ method: "POST",
164
+ headers: { ...this.buildHeaders(), "Content-Type": "application/json" },
165
+ body: JSON.stringify(body),
166
+ signal: controller.signal
167
+ });
168
+ } catch (err) {
169
+ clearTimeout(timer);
170
+ const isTimeout = err instanceof Error && err.name === "AbortError";
171
+ if (!isTimeout && attempt < 2) {
172
+ await sleep(retryDelay(attempt));
173
+ return this.post(path, body, opts, attempt + 1);
174
+ }
175
+ throw new BioError(
176
+ isTimeout ? "bio-graph request timed out" : `bio-graph request failed: ${String(err)}`,
177
+ isTimeout ? "timeout" : "network_error"
178
+ );
179
+ } finally {
180
+ clearTimeout(timer);
181
+ }
182
+ return this.handleResponse(response, path);
183
+ }
184
+ buildHeaders() {
185
+ const headers = {};
186
+ if (this.accessToken) {
187
+ headers["Authorization"] = `Bearer ${this.accessToken}`;
188
+ }
189
+ return headers;
190
+ }
191
+ async handleResponse(response, path) {
192
+ if (response.status === 404) {
193
+ throw new BioError(`bio-graph entity not found: ${path}`, "not_found", 404);
194
+ }
195
+ if (response.status === 401) {
196
+ throw new BioError(
197
+ "bio-graph authentication failed \u2014 provide a valid accessToken",
198
+ "unauthorized",
199
+ 401
200
+ );
201
+ }
202
+ if (response.status === 402) {
203
+ throw new BioError(
204
+ "bio-graph call failed \u2014 insufficient gas tokens. Top up at tawa.insureco.io/wallet",
205
+ "insufficient_gas",
206
+ 402
207
+ );
208
+ }
209
+ if (!response.ok) {
210
+ const body2 = await parseJsonResponse(response).catch(() => ({}));
211
+ throw new BioError(
212
+ `bio-graph returned ${response.status} for ${path}`,
213
+ "api_error",
214
+ response.status,
215
+ body2
216
+ );
217
+ }
218
+ const body = await parseJsonResponse(response);
219
+ return body;
220
+ }
221
+ };
222
+ // Annotate the CommonJS export names for ESM import in node:
223
+ 0 && (module.exports = {
224
+ GraphClient
225
+ });
package/dist/graph.mjs ADDED
@@ -0,0 +1,7 @@
1
+ import {
2
+ GraphClient
3
+ } from "./chunk-PLN6QPED.mjs";
4
+ import "./chunk-NK5VXXWF.mjs";
5
+ export {
6
+ GraphClient
7
+ };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
- import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, j as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-Dkb-drHZ.mjs';
2
- export { k as AdminResponse, l as BioAddress, m as BioClientTokenPayload, n as BioMessaging, o as BioUsersConfig, O as OrgMember, p as OrgMemberFilters, q as OrgMembersResult } from './types-Dkb-drHZ.mjs';
1
+ import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, E as EmbedClientConfig, j as EmbedLoginParams, k as EmbedAuthResult, l as EmbedSignupParams, m as EmbedMagicLinkParams, n as EmbedVerifyParams, o as EmbedRefreshParams, p as EmbedLogoutParams, q as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-CJe1FP61.mjs';
2
+ export { r as AdminResponse, s as BioAddress, t as BioClientTokenPayload, u as BioMessaging, v as BioUsersConfig, w as EmbedBranding, x as EmbedUser, O as OrgMember, y as OrgMemberFilters, z as OrgMembersResult } from './types-CJe1FP61.mjs';
3
+ export { AgencyProfile, AgencyProgram, AgencyStaffMember, AgentEmployer, AgentProfile, AppetiteMatchInput, AppetiteMatchProgram, AppetiteMatchResult, CarrierProfile, CarrierProgram, GraphClient, GraphClientConfig, ProgramProfile } from './graph.mjs';
3
4
 
4
5
  /**
5
6
  * OAuth flow client for Bio-ID SSO.
@@ -104,6 +105,91 @@ declare class BioAdmin {
104
105
  private request;
105
106
  }
106
107
 
108
+ /**
109
+ * Client for Bio-ID headless embed endpoints.
110
+ *
111
+ * Use this when building custom login/signup UIs that authenticate
112
+ * directly against Bio-ID without redirects (no OAuth flow).
113
+ *
114
+ * All endpoints use X-Client-Id / X-Client-Secret header auth.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * import { EmbedClient } from '@insureco/bio'
119
+ *
120
+ * const embed = EmbedClient.fromEnv()
121
+ *
122
+ * // Login
123
+ * const result = await embed.login({ email: 'user@example.com', password: 'secret' })
124
+ * console.log(result.accessToken, result.user.bioId)
125
+ *
126
+ * // Refresh
127
+ * const refreshed = await embed.refresh({ refreshToken: result.refreshToken })
128
+ *
129
+ * // Logout
130
+ * await embed.logout({ refreshToken: result.refreshToken })
131
+ * ```
132
+ */
133
+ declare class EmbedClient {
134
+ private readonly bioIdUrl;
135
+ private readonly clientId;
136
+ private readonly clientSecret;
137
+ private readonly retries;
138
+ private readonly timeoutMs;
139
+ constructor(config: EmbedClientConfig);
140
+ /**
141
+ * Create an EmbedClient from environment variables.
142
+ *
143
+ * Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
144
+ */
145
+ static fromEnv(overrides?: Partial<EmbedClientConfig>): EmbedClient;
146
+ /**
147
+ * Authenticate a user with email and password.
148
+ *
149
+ * @param params - Email and password
150
+ * @returns Access token, refresh token, user profile, and optional branding
151
+ */
152
+ login(params: EmbedLoginParams): Promise<EmbedAuthResult>;
153
+ /**
154
+ * Create a new user account.
155
+ *
156
+ * @param params - Email, password, name, and optional invite token
157
+ * @returns Access token, refresh token, user profile, and optional branding
158
+ */
159
+ signup(params: EmbedSignupParams): Promise<EmbedAuthResult>;
160
+ /**
161
+ * Send a magic link email to the user.
162
+ *
163
+ * The user clicks the link to authenticate without a password.
164
+ * After sending, use `verify()` with the token from the link.
165
+ *
166
+ * @param params - Email address to send the magic link to
167
+ */
168
+ sendMagicLink(params: EmbedMagicLinkParams): Promise<void>;
169
+ /**
170
+ * Verify a magic link token and exchange it for auth tokens.
171
+ *
172
+ * @param params - The token from the magic link
173
+ * @returns Access token, refresh token, user profile, and optional branding
174
+ */
175
+ verify(params: EmbedVerifyParams): Promise<EmbedAuthResult>;
176
+ /**
177
+ * Refresh an expired access token using a refresh token.
178
+ *
179
+ * @param params - The refresh token to exchange
180
+ * @returns New access token, rotated refresh token, user profile, and optional branding
181
+ */
182
+ refresh(params: EmbedRefreshParams): Promise<EmbedAuthResult>;
183
+ /**
184
+ * Revoke a refresh token (logout).
185
+ *
186
+ * @param params - The refresh token to revoke
187
+ */
188
+ logout(params: EmbedLogoutParams): Promise<void>;
189
+ private embedRequest;
190
+ private fetchWithRetry;
191
+ }
192
+
107
193
  /** Error thrown by Bio SDK operations */
108
194
  declare class BioError extends Error {
109
195
  /** HTTP status code (if from an API response) */
@@ -154,4 +240,4 @@ declare function isTokenExpired(token: string, bufferSeconds?: number): boolean;
154
240
  */
155
241
  declare function verifyTokenJWKS(token: string, options?: JWKSVerifyOptions): Promise<BioTokenPayload>;
156
242
 
157
- export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
243
+ export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, EmbedAuthResult, EmbedClient, EmbedClientConfig, EmbedLoginParams, EmbedLogoutParams, EmbedMagicLinkParams, EmbedRefreshParams, EmbedSignupParams, EmbedVerifyParams, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, j as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-Dkb-drHZ.js';
2
- export { k as AdminResponse, l as BioAddress, m as BioClientTokenPayload, n as BioMessaging, o as BioUsersConfig, O as OrgMember, p as OrgMemberFilters, q as OrgMembersResult } from './types-Dkb-drHZ.js';
1
+ import { B as BioAuthConfig, A as AuthorizeOptions, a as AuthorizeResult, T as TokenResponse, b as BioUser, I as IntrospectResult, c as BioAdminConfig, U as UserFilters, d as UpdateUserData, e as BioDepartment, C as CreateDepartmentData, f as BioRole, g as CreateRoleData, h as BioOAuthClient, i as CreateClientData, E as EmbedClientConfig, j as EmbedLoginParams, k as EmbedAuthResult, l as EmbedSignupParams, m as EmbedMagicLinkParams, n as EmbedVerifyParams, o as EmbedRefreshParams, p as EmbedLogoutParams, q as BioTokenPayload, V as VerifyOptions, J as JWKSVerifyOptions } from './types-CJe1FP61.js';
2
+ export { r as AdminResponse, s as BioAddress, t as BioClientTokenPayload, u as BioMessaging, v as BioUsersConfig, w as EmbedBranding, x as EmbedUser, O as OrgMember, y as OrgMemberFilters, z as OrgMembersResult } from './types-CJe1FP61.js';
3
+ export { AgencyProfile, AgencyProgram, AgencyStaffMember, AgentEmployer, AgentProfile, AppetiteMatchInput, AppetiteMatchProgram, AppetiteMatchResult, CarrierProfile, CarrierProgram, GraphClient, GraphClientConfig, ProgramProfile } from './graph.js';
3
4
 
4
5
  /**
5
6
  * OAuth flow client for Bio-ID SSO.
@@ -104,6 +105,91 @@ declare class BioAdmin {
104
105
  private request;
105
106
  }
106
107
 
108
+ /**
109
+ * Client for Bio-ID headless embed endpoints.
110
+ *
111
+ * Use this when building custom login/signup UIs that authenticate
112
+ * directly against Bio-ID without redirects (no OAuth flow).
113
+ *
114
+ * All endpoints use X-Client-Id / X-Client-Secret header auth.
115
+ *
116
+ * @example
117
+ * ```typescript
118
+ * import { EmbedClient } from '@insureco/bio'
119
+ *
120
+ * const embed = EmbedClient.fromEnv()
121
+ *
122
+ * // Login
123
+ * const result = await embed.login({ email: 'user@example.com', password: 'secret' })
124
+ * console.log(result.accessToken, result.user.bioId)
125
+ *
126
+ * // Refresh
127
+ * const refreshed = await embed.refresh({ refreshToken: result.refreshToken })
128
+ *
129
+ * // Logout
130
+ * await embed.logout({ refreshToken: result.refreshToken })
131
+ * ```
132
+ */
133
+ declare class EmbedClient {
134
+ private readonly bioIdUrl;
135
+ private readonly clientId;
136
+ private readonly clientSecret;
137
+ private readonly retries;
138
+ private readonly timeoutMs;
139
+ constructor(config: EmbedClientConfig);
140
+ /**
141
+ * Create an EmbedClient from environment variables.
142
+ *
143
+ * Reads: BIO_CLIENT_ID, BIO_CLIENT_SECRET, BIO_ID_URL
144
+ */
145
+ static fromEnv(overrides?: Partial<EmbedClientConfig>): EmbedClient;
146
+ /**
147
+ * Authenticate a user with email and password.
148
+ *
149
+ * @param params - Email and password
150
+ * @returns Access token, refresh token, user profile, and optional branding
151
+ */
152
+ login(params: EmbedLoginParams): Promise<EmbedAuthResult>;
153
+ /**
154
+ * Create a new user account.
155
+ *
156
+ * @param params - Email, password, name, and optional invite token
157
+ * @returns Access token, refresh token, user profile, and optional branding
158
+ */
159
+ signup(params: EmbedSignupParams): Promise<EmbedAuthResult>;
160
+ /**
161
+ * Send a magic link email to the user.
162
+ *
163
+ * The user clicks the link to authenticate without a password.
164
+ * After sending, use `verify()` with the token from the link.
165
+ *
166
+ * @param params - Email address to send the magic link to
167
+ */
168
+ sendMagicLink(params: EmbedMagicLinkParams): Promise<void>;
169
+ /**
170
+ * Verify a magic link token and exchange it for auth tokens.
171
+ *
172
+ * @param params - The token from the magic link
173
+ * @returns Access token, refresh token, user profile, and optional branding
174
+ */
175
+ verify(params: EmbedVerifyParams): Promise<EmbedAuthResult>;
176
+ /**
177
+ * Refresh an expired access token using a refresh token.
178
+ *
179
+ * @param params - The refresh token to exchange
180
+ * @returns New access token, rotated refresh token, user profile, and optional branding
181
+ */
182
+ refresh(params: EmbedRefreshParams): Promise<EmbedAuthResult>;
183
+ /**
184
+ * Revoke a refresh token (logout).
185
+ *
186
+ * @param params - The refresh token to revoke
187
+ */
188
+ logout(params: EmbedLogoutParams): Promise<void>;
189
+ private embedRequest;
190
+ private fetchWithRetry;
191
+ }
192
+
107
193
  /** Error thrown by Bio SDK operations */
108
194
  declare class BioError extends Error {
109
195
  /** HTTP status code (if from an API response) */
@@ -154,4 +240,4 @@ declare function isTokenExpired(token: string, bufferSeconds?: number): boolean;
154
240
  */
155
241
  declare function verifyTokenJWKS(token: string, options?: JWKSVerifyOptions): Promise<BioTokenPayload>;
156
242
 
157
- export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };
243
+ export { AuthorizeOptions, AuthorizeResult, BioAdmin, BioAdminConfig, BioAuth, BioAuthConfig, BioDepartment, BioError, BioOAuthClient, BioRole, BioTokenPayload, BioUser, CreateClientData, CreateDepartmentData, CreateRoleData, EmbedAuthResult, EmbedClient, EmbedClientConfig, EmbedLoginParams, EmbedLogoutParams, EmbedMagicLinkParams, EmbedRefreshParams, EmbedSignupParams, EmbedVerifyParams, IntrospectResult, JWKSVerifyOptions, TokenResponse, UpdateUserData, UserFilters, VerifyOptions, decodeToken, generatePKCE, isTokenExpired, verifyToken, verifyTokenJWKS };