@securelend/sdk 0.1.0-beta.5 → 0.2.0-beta.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/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
3
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4
+ import { createHash, createHmac, timingSafeEqual } from 'crypto';
4
5
 
5
6
  // src/client.ts
6
7
 
@@ -51,6 +52,30 @@ var ServerError = class extends SecureLendError {
51
52
  this.name = "ServerError";
52
53
  }
53
54
  };
55
+ var FeatureDisabledError = class extends SecureLendError {
56
+ constructor(message = "This feature is off for this workspace.", details) {
57
+ super(message, "feature_disabled", details);
58
+ this.name = "FeatureDisabledError";
59
+ }
60
+ };
61
+ var ConsentRequiredError = class extends SecureLendError {
62
+ constructor(message = "A live consent is required before this package can be read.", details) {
63
+ super(message, "consent_required", details);
64
+ this.name = "ConsentRequiredError";
65
+ }
66
+ };
67
+ var InvalidTransitionError = class extends SecureLendError {
68
+ constructor(message = "That outcome is not available.", details) {
69
+ super(message, "invalid_transition", details);
70
+ this.name = "InvalidTransitionError";
71
+ }
72
+ };
73
+ var WebhookSignatureError = class extends SecureLendError {
74
+ constructor(message = "Webhook signature did not match.", details) {
75
+ super(message, "webhook_signature", details);
76
+ this.name = "WebhookSignatureError";
77
+ }
78
+ };
54
79
 
55
80
  // src/utils/mcp.ts
56
81
  var MCPClient = class {
@@ -125,6 +150,197 @@ var MCPClient = class {
125
150
  this.debug = false;
126
151
  }
127
152
  };
153
+ var OUTCOME_STATES = [
154
+ "viewed",
155
+ "info_requested",
156
+ "declined",
157
+ "term_sheet",
158
+ "approved",
159
+ "funded",
160
+ "withdrawn"
161
+ ];
162
+ var DECLINE_REASON_CODES = [
163
+ "outside_credit_box",
164
+ "industry",
165
+ "time_in_business",
166
+ "dscr",
167
+ "collateral",
168
+ "amount",
169
+ "state",
170
+ "credit_score",
171
+ "docs_incomplete",
172
+ "capacity",
173
+ "other"
174
+ ];
175
+ var SHARE_SCOPES = ["summary", "memo", "checks", "documents"];
176
+ var FEEDBACK_TYPES = [
177
+ "rating",
178
+ "edit",
179
+ "comment",
180
+ "approve",
181
+ "reject",
182
+ "regenerate"
183
+ ];
184
+ var FEEDBACK_TARGETS = [
185
+ "memo_section",
186
+ "memo",
187
+ "tool",
188
+ "decision",
189
+ "lead_match"
190
+ ];
191
+ var EVENT_TYPES = [
192
+ "lead.created",
193
+ "lead.matched",
194
+ "lead.notified",
195
+ "package.shared",
196
+ "package.opened",
197
+ "consent.revoked",
198
+ "outcome.recorded",
199
+ "credit_box.updated",
200
+ "feedback.recorded"
201
+ ];
202
+ var leadSchema = z.object({
203
+ id: z.string(),
204
+ tenantId: z.string().nullable().optional(),
205
+ status: z.string().nullable().optional(),
206
+ productType: z.string().nullable().optional(),
207
+ amount: z.number().nullable().optional(),
208
+ legalName: z.string().nullable().optional(),
209
+ email: z.string().nullable().optional(),
210
+ caseId: z.string().nullable().optional(),
211
+ lenders: z.array(
212
+ z.object({
213
+ id: z.string().nullable().optional(),
214
+ name: z.string().optional(),
215
+ tenantId: z.string().nullable().optional()
216
+ }).passthrough()
217
+ ).optional(),
218
+ createdAt: z.string().optional(),
219
+ updatedAt: z.string().optional()
220
+ }).passthrough();
221
+ var leadListSchema = z.object({
222
+ items: z.array(leadSchema),
223
+ tenantId: z.string().optional()
224
+ }).passthrough();
225
+ var uploadResultSchema = z.object({
226
+ key: z.string().optional(),
227
+ filename: z.string().optional(),
228
+ documentType: z.string().optional(),
229
+ applicationId: z.string().optional()
230
+ }).passthrough();
231
+ var matchComponentsSchema = z.object({
232
+ rules: z.number().nullable().optional(),
233
+ fit: z.number().nullable().optional(),
234
+ outcome: z.number().nullable().optional(),
235
+ sba: z.number().nullable().optional(),
236
+ samples: z.number().nullable().optional()
237
+ }).passthrough();
238
+ var lenderMatchSchema = z.object({
239
+ lenderId: z.string().nullable().optional(),
240
+ score: z.number().nullable().optional(),
241
+ components: matchComponentsSchema.nullable().optional(),
242
+ generationId: z.string().nullable().optional()
243
+ }).passthrough();
244
+ var matchListSchema = z.object({
245
+ leadId: z.string(),
246
+ generationId: z.string().nullable().optional(),
247
+ lenders: z.array(lenderMatchSchema)
248
+ }).passthrough();
249
+ var packageSchema = z.object({
250
+ packageId: z.string().optional(),
251
+ caseId: z.string().optional(),
252
+ id: z.string().optional(),
253
+ generationId: z.string().nullable().optional(),
254
+ auth: z.string().optional(),
255
+ error: z.string().optional(),
256
+ deskUrl: z.string().optional()
257
+ }).passthrough();
258
+ var shareConsentSchema = z.object({
259
+ id: z.string(),
260
+ leadId: z.string(),
261
+ packageId: z.string(),
262
+ packageVersion: z.number(),
263
+ lenderId: z.string().optional(),
264
+ scope: z.array(z.string()),
265
+ expiresAt: z.string(),
266
+ revokedAt: z.string().nullable().optional(),
267
+ borrowerRef: z.string().optional(),
268
+ grantedAt: z.string().optional()
269
+ }).passthrough();
270
+ var shareReceiptSchema = z.object({
271
+ id: z.string(),
272
+ consentId: z.string(),
273
+ event: z.string(),
274
+ createdAt: z.string(),
275
+ lenderId: z.string().optional()
276
+ }).passthrough();
277
+ var leadOutcomeSchema = z.object({
278
+ id: z.string(),
279
+ leadId: z.string(),
280
+ lenderId: z.string(),
281
+ state: z.string(),
282
+ reasonCode: z.string().nullable().optional(),
283
+ reasonText: z.string().nullable().optional(),
284
+ fundedAmount: z.number().nullable().optional(),
285
+ fundedOn: z.string().nullable().optional(),
286
+ surface: z.string().optional(),
287
+ feedbackId: z.string().nullable().optional(),
288
+ matchGenerationId: z.string().nullable().optional(),
289
+ createdAt: z.string().optional()
290
+ }).passthrough();
291
+ var creditBoxSchema = z.object({
292
+ version: z.number(),
293
+ lenderId: z.string().optional(),
294
+ criteria: z.record(z.unknown()).optional(),
295
+ capacityPerWeek: z.number().nullable().optional(),
296
+ status: z.string(),
297
+ pausedUntil: z.string().nullable().optional(),
298
+ createdAt: z.string().optional()
299
+ }).passthrough();
300
+ var creditBoxViewSchema = z.object({
301
+ current: creditBoxSchema.nullable(),
302
+ versions: z.array(creditBoxSchema)
303
+ }).passthrough();
304
+ var feedbackEventSchema = z.object({
305
+ id: z.string(),
306
+ generationId: z.string().nullable().optional(),
307
+ caseId: z.string().nullable().optional(),
308
+ surface: z.string().optional(),
309
+ type: z.string(),
310
+ rating: z.number().nullable().optional(),
311
+ comment: z.string().nullable().optional(),
312
+ targetKind: z.string().optional(),
313
+ targetKey: z.string().optional(),
314
+ createdAt: z.string().optional()
315
+ }).passthrough();
316
+ var feedbackCreatedSchema = z.object({
317
+ id: z.string()
318
+ }).passthrough();
319
+ var liquidityCellSchema = z.object({
320
+ key: z.string(),
321
+ leads: z.number(),
322
+ matchRate: z.number().nullable().optional(),
323
+ responseRate48h: z.number().nullable().optional(),
324
+ medianResponseMs: z.number().nullable().optional(),
325
+ termSheetRate: z.number().nullable().optional(),
326
+ fundedRate: z.number().nullable().optional(),
327
+ fundedAmount: z.number().nullable().optional(),
328
+ lenderCount: z.number().optional()
329
+ }).passthrough();
330
+ var liquidityReportSchema = z.object({
331
+ view: z.string(),
332
+ groupBy: z.string(),
333
+ cells: z.array(liquidityCellSchema)
334
+ }).passthrough();
335
+ var secureLendEventSchema = z.object({
336
+ type: z.string(),
337
+ id: z.string(),
338
+ createdAt: z.string(),
339
+ tenantId: z.string(),
340
+ data: z.record(z.unknown()).optional()
341
+ }).passthrough();
342
+
343
+ // src/types/index.ts
128
344
  var anyObjectSchema = z.object({}).passthrough();
129
345
  var CreditTier = /* @__PURE__ */ ((CreditTier2) => {
130
346
  CreditTier2["PRIME"] = "PRIME";
@@ -695,6 +911,834 @@ var leaseVsPurchaseResponseSchema = z.object({
695
911
  }),
696
912
  widget: z.string().optional()
697
913
  });
914
+ var CONSENT_CODES = /* @__PURE__ */ new Set([
915
+ "consent_required",
916
+ "consent_revoked",
917
+ "consent_expired"
918
+ ]);
919
+ function sleep(ms) {
920
+ if (ms <= 0) return Promise.resolve();
921
+ return new Promise((resolve) => setTimeout(resolve, ms));
922
+ }
923
+ function newIdempotencyKey() {
924
+ const cryptoRef = globalThis.crypto;
925
+ if (cryptoRef && typeof cryptoRef.randomUUID === "function") {
926
+ return cryptoRef.randomUUID();
927
+ }
928
+ return `idem_${Date.now().toString(16)}_${Math.random().toString(16).slice(2)}`;
929
+ }
930
+ function bearer(apiKey) {
931
+ if (!apiKey) return void 0;
932
+ const trimmed = apiKey.trim();
933
+ if (!trimmed) return void 0;
934
+ return trimmed.toLowerCase().startsWith("bearer ") ? trimmed : `Bearer ${trimmed}`;
935
+ }
936
+ function retryDelay(response, fallback) {
937
+ const header = response.headers.get("retry-after");
938
+ if (header && /^\d+$/.test(header)) {
939
+ return Math.min(Number(header) * 1e3, 2e3);
940
+ }
941
+ return fallback;
942
+ }
943
+ function validationMessage(code) {
944
+ if (code === "reason_required") return "A decline needs a reason code.";
945
+ if (code === "funded_amount_required") return "Funded needs an amount.";
946
+ if (code === "funded_date_required") {
947
+ return "Funded needs a date as YYYY-MM-DD.";
948
+ }
949
+ if (code === "confirmation_required") {
950
+ return "The lead needs confirmation before it is created.";
951
+ }
952
+ return "The request was not accepted.";
953
+ }
954
+ var RestClient = class {
955
+ constructor(options) {
956
+ this.baseUrl = options.baseUrl.replace(/\/$/, "");
957
+ this.apiKey = options.apiKey;
958
+ this.fetchImpl = options.fetchImpl;
959
+ this.maxRetries = options.maxRetries ?? 2;
960
+ this.retryDelayMs = options.retryDelayMs ?? 0;
961
+ }
962
+ setApiKey(apiKey) {
963
+ this.apiKey = apiKey;
964
+ }
965
+ async send(request) {
966
+ const retries = request.form ? 0 : this.maxRetries;
967
+ const url = this.url(request.path, request.query);
968
+ const init = this.init(request);
969
+ let lastError = null;
970
+ for (let attempt = 0; attempt <= retries; attempt += 1) {
971
+ let response;
972
+ try {
973
+ response = await this.fetcher()(url, init);
974
+ } catch (err) {
975
+ const detail = err instanceof Error && err.message ? err.message.replace(/\s+/g, " ").slice(0, 180) : "";
976
+ lastError = new NetworkError(
977
+ detail ? `The request did not reach the server. ${detail}` : "The request did not reach the server."
978
+ );
979
+ if (attempt < retries) {
980
+ await sleep(this.retryDelayMs);
981
+ continue;
982
+ }
983
+ throw lastError;
984
+ }
985
+ if ((response.status === 429 || response.status >= 500) && attempt < retries) {
986
+ await sleep(retryDelay(response, this.retryDelayMs));
987
+ continue;
988
+ }
989
+ return this.read(response, request);
990
+ }
991
+ throw lastError || new NetworkError("The request did not reach the server.");
992
+ }
993
+ fetcher() {
994
+ if (this.fetchImpl) return this.fetchImpl;
995
+ if (typeof globalThis.fetch === "function") {
996
+ return globalThis.fetch.bind(globalThis);
997
+ }
998
+ throw new NetworkError("This runtime has no fetch implementation.");
999
+ }
1000
+ url(path, query) {
1001
+ const suffix = path.startsWith("/") ? path : `/${path}`;
1002
+ const params = new URLSearchParams();
1003
+ for (const [key, value] of Object.entries(query || {})) {
1004
+ if (value == null || value === "") continue;
1005
+ params.set(key, String(value));
1006
+ }
1007
+ const qs = params.toString();
1008
+ return `${this.baseUrl}${suffix}${qs ? `?${qs}` : ""}`;
1009
+ }
1010
+ init(request) {
1011
+ const headers = { accept: "application/json" };
1012
+ const authorization = bearer(this.apiKey);
1013
+ if (authorization) headers.authorization = authorization;
1014
+ const method = request.method.toUpperCase();
1015
+ if (method === "POST" || method === "PUT" || method === "PATCH") {
1016
+ headers["idempotency-key"] = request.idempotencyKey || newIdempotencyKey();
1017
+ }
1018
+ if (request.form) {
1019
+ return { method, headers, body: request.form };
1020
+ }
1021
+ if (request.body !== void 0) {
1022
+ headers["content-type"] = "application/json";
1023
+ return { method, headers, body: JSON.stringify(request.body) };
1024
+ }
1025
+ return { method, headers };
1026
+ }
1027
+ async read(response, request) {
1028
+ const text = await response.text();
1029
+ let payload = null;
1030
+ if (text) {
1031
+ try {
1032
+ payload = JSON.parse(text);
1033
+ } catch {
1034
+ payload = null;
1035
+ }
1036
+ }
1037
+ if (response.status >= 200 && response.status < 300) {
1038
+ try {
1039
+ return request.schema.parse(payload ?? {});
1040
+ } catch (err) {
1041
+ if (err instanceof z.ZodError) {
1042
+ throw new ValidationError(
1043
+ "The server response did not match the expected shape.",
1044
+ { issues: err.issues.map((issue) => issue.path.join(".")) }
1045
+ );
1046
+ }
1047
+ throw err;
1048
+ }
1049
+ }
1050
+ const code = String(payload?.error || "");
1051
+ const details = { status: response.status, error: code || void 0 };
1052
+ if (response.status === 401 || code === "invalid_signature") {
1053
+ throw new AuthenticationError("The API key was not accepted.");
1054
+ }
1055
+ if (response.status === 429) {
1056
+ const retryAfter = response.headers.get("retry-after");
1057
+ throw new RateLimitError(
1058
+ "The request was rate limited.",
1059
+ retryAfter && /^\d+$/.test(retryAfter) ? Number(retryAfter) : void 0
1060
+ );
1061
+ }
1062
+ if (CONSENT_CODES.has(code)) {
1063
+ const message = code === "consent_revoked" ? "This consent was revoked." : code === "consent_expired" ? "This consent has expired." : "A live consent is required before this package can be read.";
1064
+ throw new ConsentRequiredError(message, details);
1065
+ }
1066
+ if (code === "invalid_transition") {
1067
+ throw new InvalidTransitionError(
1068
+ "That outcome is not available.",
1069
+ details
1070
+ );
1071
+ }
1072
+ if (request.featureGated && (response.status === 404 || response.status === 403 && (code === "not_found" || code === "feature_disabled"))) {
1073
+ throw new FeatureDisabledError(
1074
+ "This feature is off for this workspace.",
1075
+ details
1076
+ );
1077
+ }
1078
+ if (response.status === 404) {
1079
+ throw new NotFoundError("The record was not found.");
1080
+ }
1081
+ if (response.status === 403) {
1082
+ throw new SecureLendError(
1083
+ "This action is not available for this session.",
1084
+ "forbidden",
1085
+ details
1086
+ );
1087
+ }
1088
+ if (response.status >= 500) {
1089
+ throw new ServerError("The server could not complete the request.");
1090
+ }
1091
+ throw new ValidationError(validationMessage(code), details);
1092
+ }
1093
+ };
1094
+
1095
+ // src/contract.ts
1096
+ var PLATFORM_ROUTES = {
1097
+ createLead: "/v1/placement/enquiries",
1098
+ listLeads: "/v1/leads",
1099
+ uploadLeadDocument: "/v1/placement/enquiries/:id/documents",
1100
+ compare: "/v1/placement/compare",
1101
+ lenderMcp: "/v1/lender/mcp",
1102
+ consents: "/v1/share-consents",
1103
+ revokeConsent: "/v1/share-consents/:id/revoke",
1104
+ receipts: "/v1/share-receipts",
1105
+ outcomes: "/v1/leads/:id/outcomes",
1106
+ creditBox: "/v1/credit-box",
1107
+ pauseCreditBox: "/v1/credit-box/pause",
1108
+ resumeCreditBox: "/v1/credit-box/resume",
1109
+ feedback: "/v1/feedback",
1110
+ caseFeedback: "/v1/cases/:id/feedback",
1111
+ liquidity: "/v1/marketplace/liquidity"
1112
+ };
1113
+ function routeWithId(template, id) {
1114
+ return template.replace(":id", encodeURIComponent(id));
1115
+ }
1116
+
1117
+ // src/resources/leads.ts
1118
+ var Leads = class {
1119
+ constructor(rest) {
1120
+ this.rest = rest;
1121
+ }
1122
+ async create(input, options = {}) {
1123
+ return this.rest.send({
1124
+ method: "POST",
1125
+ path: PLATFORM_ROUTES.createLead,
1126
+ body: input,
1127
+ schema: leadSchema,
1128
+ idempotencyKey: options.idempotencyKey
1129
+ });
1130
+ }
1131
+ async list(filter = {}) {
1132
+ const page = await this.rest.send({
1133
+ method: "GET",
1134
+ path: PLATFORM_ROUTES.listLeads,
1135
+ query: { status: filter.status || "pending" },
1136
+ schema: leadListSchema
1137
+ });
1138
+ return page.items;
1139
+ }
1140
+ /** Lender view. A lead outside this workspace is not found. */
1141
+ async get(id) {
1142
+ const wanted = String(id || "").trim();
1143
+ if (!wanted) throw new ValidationError("A lead id is required.");
1144
+ const items = await this.list({ status: "all" });
1145
+ const lead = items.find((row) => row.id === wanted);
1146
+ if (!lead) throw new NotFoundError("The record was not found.");
1147
+ return leadSchema.parse(lead);
1148
+ }
1149
+ /**
1150
+ * One HTTP request per file. The platform route stores a single file.
1151
+ */
1152
+ async uploadDocuments(enquiryId, files, options = {}) {
1153
+ const id = String(enquiryId || "").trim();
1154
+ if (!id) throw new ValidationError("A lead id is required.");
1155
+ if (!files?.length) throw new ValidationError("A file is required.");
1156
+ const saved = [];
1157
+ for (const file of files) {
1158
+ if (!file?.bytes?.byteLength) {
1159
+ throw new ValidationError("A file is required.");
1160
+ }
1161
+ const form = new FormData();
1162
+ const copy = new ArrayBuffer(file.bytes.byteLength);
1163
+ new Uint8Array(copy).set(file.bytes);
1164
+ const blob = new Blob([copy], { type: file.mime || "application/pdf" });
1165
+ form.append("file", blob, file.filename || "upload.pdf");
1166
+ if (file.documentType) form.append("documentType", file.documentType);
1167
+ saved.push(
1168
+ await this.rest.send({
1169
+ method: "POST",
1170
+ path: routeWithId(PLATFORM_ROUTES.uploadLeadDocument, id),
1171
+ form,
1172
+ schema: uploadResultSchema,
1173
+ idempotencyKey: options.idempotencyKey
1174
+ })
1175
+ );
1176
+ }
1177
+ return saved;
1178
+ }
1179
+ };
1180
+ var compareSchema = z.object({
1181
+ metadata: z.object({
1182
+ generationId: z.string().optional(),
1183
+ match: z.array(z.record(z.unknown())).optional()
1184
+ }).passthrough().optional()
1185
+ }).passthrough();
1186
+ var COMPARE_LOAN_PRODUCTS = /* @__PURE__ */ new Set([
1187
+ "personal_loans",
1188
+ "business_loans",
1189
+ "personal_mortgages",
1190
+ "business_mortgages",
1191
+ "car_loans",
1192
+ "student_loans"
1193
+ ]);
1194
+ var COMPARE_STATIC_PRODUCTS = /* @__PURE__ */ new Set([
1195
+ "personal_credit_cards",
1196
+ "business_credit_cards",
1197
+ "personal_banking",
1198
+ "business_banking",
1199
+ "savings_accounts"
1200
+ ]);
1201
+ function compareProductKey(value) {
1202
+ const raw = String(value || "").trim().toLowerCase().replace(/^compare_/, "").replace(/[\s-]+/g, "_");
1203
+ if (!raw) return null;
1204
+ if (COMPARE_LOAN_PRODUCTS.has(raw) || COMPARE_STATIC_PRODUCTS.has(raw)) {
1205
+ return raw;
1206
+ }
1207
+ if (raw === "personal_loan" || raw === "installment_loan") {
1208
+ return "personal_loans";
1209
+ }
1210
+ return null;
1211
+ }
1212
+ function numberOrNull(value) {
1213
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
1214
+ }
1215
+ function stringOrNull(value) {
1216
+ return typeof value === "string" && value ? value : null;
1217
+ }
1218
+ var Matches = class {
1219
+ constructor(rest) {
1220
+ this.rest = rest;
1221
+ }
1222
+ /**
1223
+ * Runs a match for this lead. generationId is set when outcome matching is on.
1224
+ * With the flag off, the lead's own lenders are returned and the ranking is unchanged.
1225
+ */
1226
+ async list(leadId) {
1227
+ const id = String(leadId || "").trim();
1228
+ if (!id) throw new ValidationError("A lead id is required.");
1229
+ const page = await this.rest.send({
1230
+ method: "GET",
1231
+ path: PLATFORM_ROUTES.listLeads,
1232
+ query: { status: "all" },
1233
+ schema: leadListSchema
1234
+ });
1235
+ const lead = page.items.find((row) => row.id === id);
1236
+ if (!lead) throw new NotFoundError("The record was not found.");
1237
+ const product = compareProductKey(lead.productType);
1238
+ const amount = numberOrNull(lead.amount);
1239
+ const needsAmount = product != null && COMPARE_LOAN_PRODUCTS.has(product);
1240
+ if (!product || needsAmount && !(amount != null && amount > 0)) {
1241
+ return matchListSchema.parse({
1242
+ leadId: id,
1243
+ generationId: null,
1244
+ lenders: (lead.lenders || []).map((lender) => ({
1245
+ lenderId: lender.id ?? null,
1246
+ score: null,
1247
+ generationId: null,
1248
+ components: null
1249
+ }))
1250
+ });
1251
+ }
1252
+ const compared = await this.rest.send({
1253
+ method: "POST",
1254
+ path: PLATFORM_ROUTES.compare,
1255
+ body: {
1256
+ productType: product,
1257
+ ...amount != null && amount > 0 ? { loanAmount: amount, amount } : {}
1258
+ },
1259
+ schema: compareSchema
1260
+ });
1261
+ const generationId = compared.metadata?.generationId ?? null;
1262
+ const rows = compared.metadata?.match;
1263
+ const lenders = Array.isArray(rows) ? rows.map((row) => ({
1264
+ lenderId: stringOrNull(row.lenderId),
1265
+ score: numberOrNull(row.score),
1266
+ generationId,
1267
+ components: matchComponentsSchema.parse({
1268
+ rules: numberOrNull(row.rules),
1269
+ fit: numberOrNull(row.fit),
1270
+ outcome: numberOrNull(row.outcome),
1271
+ sba: numberOrNull(row.sba),
1272
+ samples: numberOrNull(row.samples)
1273
+ })
1274
+ })) : (lead.lenders || []).map((lender) => ({
1275
+ lenderId: lender.id ?? null,
1276
+ score: null,
1277
+ generationId: null,
1278
+ components: null
1279
+ }));
1280
+ return matchListSchema.parse({ leadId: id, generationId, lenders });
1281
+ }
1282
+ };
1283
+ var rpcSchema = z.object({
1284
+ result: z.object({
1285
+ structuredContent: z.unknown().optional(),
1286
+ content: z.array(
1287
+ z.object({
1288
+ type: z.string(),
1289
+ text: z.string().optional()
1290
+ }).passthrough()
1291
+ ).optional(),
1292
+ isError: z.boolean().optional()
1293
+ }).passthrough().optional(),
1294
+ error: z.object({
1295
+ message: z.string().optional()
1296
+ }).passthrough().optional()
1297
+ }).passthrough();
1298
+ function payloadOf(rpc) {
1299
+ const structured = rpc.result?.structuredContent;
1300
+ if (structured && typeof structured === "object" && !Array.isArray(structured)) {
1301
+ return structured;
1302
+ }
1303
+ const text = rpc.result?.content?.find((item) => item.type === "text")?.text;
1304
+ if (text) {
1305
+ try {
1306
+ const parsed = JSON.parse(text);
1307
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
1308
+ return parsed;
1309
+ }
1310
+ } catch {
1311
+ throw new ValidationError(
1312
+ "The package response did not include a result."
1313
+ );
1314
+ }
1315
+ }
1316
+ throw new ValidationError("The package response did not include a result.");
1317
+ }
1318
+ function raiseToolError(payload) {
1319
+ const code = typeof payload.error === "string" ? payload.error : "";
1320
+ if (!code) return;
1321
+ if (code === "consent_required" || code === "consent_revoked" || code === "consent_expired") {
1322
+ throw new ConsentRequiredError(
1323
+ code === "consent_revoked" ? "This consent was revoked." : "A live consent is required before this package can be read.",
1324
+ { error: code }
1325
+ );
1326
+ }
1327
+ if (code === "not_found")
1328
+ throw new NotFoundError("The record was not found.");
1329
+ if (code === "sign_in_required") {
1330
+ throw new AuthenticationError("The API key was not accepted.");
1331
+ }
1332
+ throw new SecureLendError("The package request failed.", code, {
1333
+ error: code
1334
+ });
1335
+ }
1336
+ var Packages = class {
1337
+ constructor(rest) {
1338
+ this.rest = rest;
1339
+ }
1340
+ async start(input) {
1341
+ if (!input?.borrower || input.amount == null || !input.currency || !input.security) {
1342
+ throw new ValidationError(
1343
+ "A package needs a borrower, amount, currency, and security."
1344
+ );
1345
+ }
1346
+ return this.call("start_underwriting_package", { ...input });
1347
+ }
1348
+ async read(id, options = {}) {
1349
+ const packageId = String(id || "").trim();
1350
+ if (!packageId) throw new ValidationError("A package id is required.");
1351
+ const args = { caseId: packageId, packageId };
1352
+ if (options.version != null) args.packageVersion = options.version;
1353
+ return this.call("read_package", args);
1354
+ }
1355
+ async call(name, args) {
1356
+ const rpc = await this.rest.send({
1357
+ method: "POST",
1358
+ path: PLATFORM_ROUTES.lenderMcp,
1359
+ body: {
1360
+ jsonrpc: "2.0",
1361
+ id: 1,
1362
+ method: "tools/call",
1363
+ params: { name, arguments: args }
1364
+ },
1365
+ schema: rpcSchema
1366
+ });
1367
+ if (rpc.error) {
1368
+ throw new SecureLendError("The package request failed.", "mcp_error", {
1369
+ message: rpc.error.message
1370
+ });
1371
+ }
1372
+ const payload = payloadOf(rpc);
1373
+ raiseToolError(payload);
1374
+ return packageSchema.parse(payload);
1375
+ }
1376
+ };
1377
+ var consentListSchema = z.object({ items: z.array(shareConsentSchema) }).passthrough();
1378
+ var receiptListSchema = z.object({ items: z.array(shareReceiptSchema) }).passthrough();
1379
+ var Consents = class {
1380
+ constructor(rest) {
1381
+ this.rest = rest;
1382
+ }
1383
+ /**
1384
+ * One consent row per lender id. The live route stores a row only when the
1385
+ * lender id is the session tenant. Omit lenderIds to use that default.
1386
+ */
1387
+ async create(input, options = {}) {
1388
+ const leadId = String(input?.leadId || "").trim();
1389
+ const packageId = String(input?.packageId || "").trim();
1390
+ const borrowerRef = String(input?.borrowerRef || "").trim();
1391
+ if (!leadId || !packageId) {
1392
+ throw new ValidationError("A consent needs a lead and a package.");
1393
+ }
1394
+ if (!Number.isInteger(input.packageVersion) || input.packageVersion < 1) {
1395
+ throw new ValidationError("A consent needs a package version.");
1396
+ }
1397
+ if (!input.expiresAt)
1398
+ throw new ValidationError("A consent needs an expiry.");
1399
+ if (!borrowerRef)
1400
+ throw new ValidationError("A borrower reference is required.");
1401
+ if (borrowerRef.includes("@")) {
1402
+ throw new ValidationError(
1403
+ "Use a reference you choose. Do not type an email or an account number."
1404
+ );
1405
+ }
1406
+ const scope = input.scope?.length ? input.scope : ["summary"];
1407
+ if (scope.some(
1408
+ (item) => !SHARE_SCOPES.includes(item)
1409
+ )) {
1410
+ throw new ValidationError(
1411
+ "Scope must be summary, memo, checks, or documents."
1412
+ );
1413
+ }
1414
+ const lenderIds = input.lenderIds?.length ? input.lenderIds : [void 0];
1415
+ const saved = [];
1416
+ for (const lenderId of lenderIds) {
1417
+ const body = {
1418
+ leadId,
1419
+ packageId,
1420
+ packageVersion: input.packageVersion,
1421
+ scope,
1422
+ expiresAt: input.expiresAt,
1423
+ borrowerRef
1424
+ };
1425
+ if (lenderId) body.lenderId = lenderId;
1426
+ saved.push(
1427
+ await this.rest.send({
1428
+ method: "POST",
1429
+ path: PLATFORM_ROUTES.consents,
1430
+ body,
1431
+ schema: shareConsentSchema,
1432
+ featureGated: true,
1433
+ idempotencyKey: options.idempotencyKey
1434
+ })
1435
+ );
1436
+ }
1437
+ return saved;
1438
+ }
1439
+ async list(leadId) {
1440
+ const page = await this.rest.send({
1441
+ method: "GET",
1442
+ path: PLATFORM_ROUTES.consents,
1443
+ schema: consentListSchema,
1444
+ featureGated: true
1445
+ });
1446
+ if (!leadId) return page.items;
1447
+ return page.items.filter((row) => row.leadId === leadId);
1448
+ }
1449
+ async revoke(id, options = {}) {
1450
+ const consentId = String(id || "").trim();
1451
+ if (!consentId) throw new ValidationError("A consent id is required.");
1452
+ return this.rest.send({
1453
+ method: "POST",
1454
+ path: routeWithId(PLATFORM_ROUTES.revokeConsent, consentId),
1455
+ body: {},
1456
+ schema: shareConsentSchema,
1457
+ featureGated: true,
1458
+ idempotencyKey: options.idempotencyKey
1459
+ });
1460
+ }
1461
+ async receipts(id) {
1462
+ const page = await this.rest.send({
1463
+ method: "GET",
1464
+ path: PLATFORM_ROUTES.receipts,
1465
+ schema: receiptListSchema,
1466
+ featureGated: true
1467
+ });
1468
+ if (!id) return page.items;
1469
+ return page.items.filter((row) => row.consentId === id);
1470
+ }
1471
+ };
1472
+ function rawBytes(raw) {
1473
+ return Buffer.isBuffer(raw) ? raw : Buffer.from(raw, "utf8");
1474
+ }
1475
+ function safeEqualHex(expected, presented) {
1476
+ const left = Buffer.from(expected, "utf8");
1477
+ const right = Buffer.from(presented, "utf8");
1478
+ if (left.length !== right.length) return false;
1479
+ return timingSafeEqual(left, right);
1480
+ }
1481
+ function signOutcomePayload(raw, secret) {
1482
+ const digest = createHash("sha256").update(String(secret || ""), "utf8").update(".").update(rawBytes(raw)).digest("hex");
1483
+ return `sha256=${digest}`;
1484
+ }
1485
+ function signWebhook(raw, secret, timestampSec = Math.floor(Date.now() / 1e3)) {
1486
+ const mac = createHmac("sha256", String(secret || "")).update(`${timestampSec}.`).update(rawBytes(raw)).digest("hex");
1487
+ return `t=${timestampSec},v1=${mac}`;
1488
+ }
1489
+ function readStamp(header) {
1490
+ const match = header.match(/(?:^|,\s*)t=(\d+),v1=([a-fA-F0-9]+)/);
1491
+ if (!match) return null;
1492
+ return { t: Number(match[1]), mac: match[2].toLowerCase() };
1493
+ }
1494
+ function verifyWebhook(rawBody, signatureHeader, secret, options = {}) {
1495
+ const header = String(signatureHeader || "").trim();
1496
+ const key = String(secret || "");
1497
+ if (!key || !header) {
1498
+ throw new WebhookSignatureError("Webhook signature did not match.");
1499
+ }
1500
+ const stamp = readStamp(header);
1501
+ if (stamp) {
1502
+ const tolerance = options.toleranceSec ?? 300;
1503
+ const nowSec = Math.floor((options.nowMs ?? Date.now()) / 1e3);
1504
+ if (!Number.isFinite(stamp.t) || Math.abs(nowSec - stamp.t) > tolerance) {
1505
+ throw new WebhookSignatureError(
1506
+ "This webhook is outside the time window."
1507
+ );
1508
+ }
1509
+ const expected2 = signWebhook(rawBody, key, stamp.t).split("v1=")[1] || "";
1510
+ if (!safeEqualHex(expected2, stamp.mac)) {
1511
+ throw new WebhookSignatureError("Webhook signature did not match.");
1512
+ }
1513
+ return true;
1514
+ }
1515
+ const presented = header.replace(/^sha256=/i, "").trim().toLowerCase();
1516
+ const expected = signOutcomePayload(rawBody, key).replace(/^sha256=/, "");
1517
+ if (!safeEqualHex(expected, presented)) {
1518
+ throw new WebhookSignatureError("Webhook signature did not match.");
1519
+ }
1520
+ return true;
1521
+ }
1522
+ function parseEvent(input) {
1523
+ try {
1524
+ const event = secureLendEventSchema.parse(input);
1525
+ return { ...event, data: event.data ?? {} };
1526
+ } catch (err) {
1527
+ if (err instanceof z.ZodError) {
1528
+ throw new ValidationError(
1529
+ "The webhook event did not match the expected shape.",
1530
+ {
1531
+ issues: err.issues.map((issue) => issue.path.join("."))
1532
+ }
1533
+ );
1534
+ }
1535
+ throw err;
1536
+ }
1537
+ }
1538
+
1539
+ // src/resources/outcomes.ts
1540
+ var outcomeListSchema = z.object({ items: z.array(leadOutcomeSchema) }).passthrough();
1541
+ var Outcomes = class {
1542
+ constructor(rest) {
1543
+ this.rest = rest;
1544
+ }
1545
+ /**
1546
+ * Declined without a reason code, and funded without an amount and date,
1547
+ * fail here and do not call the server.
1548
+ */
1549
+ async record(leadId, input, options = {}) {
1550
+ const id = String(leadId || "").trim();
1551
+ const state = String(input?.state || "").trim();
1552
+ if (!id) throw new ValidationError("A lead id is required.");
1553
+ if (!OUTCOME_STATES.includes(state)) {
1554
+ throw new ValidationError("That outcome state is not recognized.");
1555
+ }
1556
+ const reasonCode = input.reasonCode ? String(input.reasonCode).trim() : "";
1557
+ if (state === "declined") {
1558
+ if (!DECLINE_REASON_CODES.includes(
1559
+ reasonCode
1560
+ )) {
1561
+ throw new ValidationError("A decline needs a reason code.");
1562
+ }
1563
+ if (reasonCode === "other" && !String(input.reasonText || "").trim()) {
1564
+ throw new ValidationError("A decline needs a reason code.");
1565
+ }
1566
+ }
1567
+ if (state === "funded") {
1568
+ const amount = Number(input.fundedAmount);
1569
+ const date = String(input.fundedOn || "").trim();
1570
+ if (!Number.isFinite(amount) || amount <= 0) {
1571
+ throw new ValidationError("Funded needs an amount.");
1572
+ }
1573
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) {
1574
+ throw new ValidationError("Funded needs a date as YYYY-MM-DD.");
1575
+ }
1576
+ }
1577
+ const body = { state };
1578
+ if (input.lenderId) body.lenderId = input.lenderId;
1579
+ if (reasonCode) body.reasonCode = reasonCode;
1580
+ if (input.reasonText) body.reasonText = input.reasonText;
1581
+ if (state === "funded") {
1582
+ body.fundedAmount = Number(input.fundedAmount);
1583
+ body.fundedOn = String(input.fundedOn);
1584
+ }
1585
+ if (input.surface) body.surface = input.surface;
1586
+ return this.rest.send({
1587
+ method: "POST",
1588
+ path: routeWithId(PLATFORM_ROUTES.outcomes, id),
1589
+ body,
1590
+ schema: leadOutcomeSchema,
1591
+ featureGated: true,
1592
+ idempotencyKey: options.idempotencyKey
1593
+ });
1594
+ }
1595
+ async list(leadId) {
1596
+ const id = String(leadId || "").trim();
1597
+ if (!id) throw new ValidationError("A lead id is required.");
1598
+ const page = await this.rest.send({
1599
+ method: "GET",
1600
+ path: routeWithId(PLATFORM_ROUTES.outcomes, id),
1601
+ schema: outcomeListSchema,
1602
+ featureGated: true
1603
+ });
1604
+ return page.items;
1605
+ }
1606
+ /** Header value for POST /v1/webhooks/lender-outcomes. */
1607
+ signPayload(rawBody, secret) {
1608
+ return signOutcomePayload(rawBody, secret);
1609
+ }
1610
+ };
1611
+
1612
+ // src/resources/creditBox.ts
1613
+ var CreditBoxClient = class {
1614
+ constructor(rest) {
1615
+ this.rest = rest;
1616
+ }
1617
+ async get() {
1618
+ return this.rest.send({
1619
+ method: "GET",
1620
+ path: PLATFORM_ROUTES.creditBox,
1621
+ schema: creditBoxViewSchema,
1622
+ featureGated: true
1623
+ });
1624
+ }
1625
+ async put(input, options = {}) {
1626
+ const body = writeBody(input);
1627
+ return this.rest.send({
1628
+ method: "PUT",
1629
+ path: PLATFORM_ROUTES.creditBox,
1630
+ body,
1631
+ schema: creditBoxSchema,
1632
+ featureGated: true,
1633
+ idempotencyKey: options.idempotencyKey
1634
+ });
1635
+ }
1636
+ async pause(input = {}, options = {}) {
1637
+ return this.rest.send({
1638
+ method: "POST",
1639
+ path: PLATFORM_ROUTES.pauseCreditBox,
1640
+ body: input.until ? { until: input.until } : {},
1641
+ schema: creditBoxSchema,
1642
+ featureGated: true,
1643
+ idempotencyKey: options.idempotencyKey
1644
+ });
1645
+ }
1646
+ async resume(options = {}) {
1647
+ return this.rest.send({
1648
+ method: "POST",
1649
+ path: PLATFORM_ROUTES.resumeCreditBox,
1650
+ body: {},
1651
+ schema: creditBoxSchema,
1652
+ featureGated: true,
1653
+ idempotencyKey: options.idempotencyKey
1654
+ });
1655
+ }
1656
+ };
1657
+ function writeBody(input) {
1658
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
1659
+ throw new ValidationError("A credit box needs criteria.");
1660
+ }
1661
+ if ("criteria" in input) {
1662
+ const criteria = input.criteria;
1663
+ if (!criteria || typeof criteria !== "object" || Array.isArray(criteria)) {
1664
+ throw new ValidationError("A credit box needs criteria.");
1665
+ }
1666
+ return input;
1667
+ }
1668
+ return { criteria: input };
1669
+ }
1670
+ var feedbackListSchema = z.object({ items: z.array(feedbackEventSchema) }).passthrough();
1671
+ var Feedback = class {
1672
+ constructor(rest) {
1673
+ this.rest = rest;
1674
+ }
1675
+ async submit(event, options = {}) {
1676
+ const type = String(event?.type || "").trim();
1677
+ const kind = String(event?.target?.kind || "").trim();
1678
+ const key = String(event?.target?.key || "").trim();
1679
+ if (!FEEDBACK_TYPES.includes(type)) {
1680
+ throw new ValidationError("That feedback type is not recognized.");
1681
+ }
1682
+ if (!FEEDBACK_TARGETS.includes(kind) || !key) {
1683
+ throw new ValidationError("Feedback needs a target.");
1684
+ }
1685
+ if (type === "rating") {
1686
+ const rating = Number(event.rating);
1687
+ if (!Number.isInteger(rating) || rating < 1 || rating > 9) {
1688
+ throw new ValidationError("A rating is a whole number from 1 to 9.");
1689
+ }
1690
+ }
1691
+ return this.rest.send({
1692
+ method: "POST",
1693
+ path: PLATFORM_ROUTES.feedback,
1694
+ body: {
1695
+ type,
1696
+ surface: event.surface || "api",
1697
+ target: { kind, key },
1698
+ ...event.rating != null ? { rating: event.rating } : {},
1699
+ ...event.comment ? { comment: event.comment } : {},
1700
+ ...event.generationId ? { generationId: event.generationId } : {},
1701
+ ...event.caseId ? { caseId: event.caseId } : {},
1702
+ ...event.before != null ? { before: event.before } : {},
1703
+ ...event.after != null ? { after: event.after } : {}
1704
+ },
1705
+ schema: feedbackCreatedSchema,
1706
+ featureGated: true,
1707
+ idempotencyKey: options.idempotencyKey
1708
+ });
1709
+ }
1710
+ async listForCase(caseId) {
1711
+ const id = String(caseId || "").trim();
1712
+ if (!id) throw new ValidationError("A case id is required.");
1713
+ const page = await this.rest.send({
1714
+ method: "GET",
1715
+ path: routeWithId(PLATFORM_ROUTES.caseFeedback, id),
1716
+ schema: feedbackListSchema,
1717
+ featureGated: true
1718
+ });
1719
+ return page.items;
1720
+ }
1721
+ };
1722
+
1723
+ // src/resources/liquidity.ts
1724
+ var Liquidity = class {
1725
+ constructor(rest) {
1726
+ this.rest = rest;
1727
+ }
1728
+ async get(query = {}) {
1729
+ return this.rest.send({
1730
+ method: "GET",
1731
+ path: PLATFORM_ROUTES.liquidity,
1732
+ query: {
1733
+ groupBy: query.groupBy || "product",
1734
+ from: query.from,
1735
+ to: query.to
1736
+ },
1737
+ schema: liquidityReportSchema,
1738
+ featureGated: true
1739
+ });
1740
+ }
1741
+ };
698
1742
 
699
1743
  // src/client.ts
700
1744
  var SecureLend = class {
@@ -710,8 +1754,28 @@ var SecureLend = class {
710
1754
  }
711
1755
  this.mcpClient = new MCPClient({ apiKey: config?.apiKey || "", mcpURL });
712
1756
  this.mcp = this.mcpClient.mcp;
1757
+ let apiBaseUrl = config?.apiBaseUrl || "https://securelend.ai";
1758
+ if (typeof window !== "undefined" && apiBaseUrl.startsWith("/")) {
1759
+ apiBaseUrl = window.location.origin + apiBaseUrl;
1760
+ }
1761
+ this.rest = new RestClient({
1762
+ baseUrl: apiBaseUrl,
1763
+ apiKey: config?.apiKey,
1764
+ fetchImpl: config?.fetch
1765
+ });
1766
+ this.leads = new Leads(this.rest);
1767
+ this.matches = new Matches(this.rest);
1768
+ this.packages = new Packages(this.rest);
1769
+ this.consents = new Consents(this.rest);
1770
+ this.outcomes = new Outcomes(this.rest);
1771
+ this.creditBox = new CreditBoxClient(this.rest);
1772
+ this.feedback = new Feedback(this.rest);
1773
+ this.liquidity = new Liquidity(this.rest);
1774
+ this.webhooks = { verify: verifyWebhook, parseEvent, sign: signWebhook };
713
1775
  }
714
1776
  // --- Loan Comparison ---
1777
+ // These methods call the comparison MCP (default https://mcp.securelend.ai/mcp).
1778
+ // They are not sent to /v1/lender/mcp.
715
1779
  async comparePersonalLoans(request) {
716
1780
  return this.callTool(
717
1781
  "compare_personal_loans",
@@ -877,6 +1941,7 @@ var SecureLend = class {
877
1941
  */
878
1942
  setApiKey(apiKey) {
879
1943
  this.mcpClient.setApiKey(apiKey);
1944
+ this.rest.setApiKey(apiKey);
880
1945
  }
881
1946
  // --- Private Helpers ---
882
1947
  async callTool(toolName, request, schema) {
@@ -937,6 +2002,6 @@ var SecureLend = class {
937
2002
  }
938
2003
  };
939
2004
 
940
- export { ApplicationStatus, ApplicationType, AuthenticationError, CreditTier, NetworkError, NotFoundError, ProductType, ProviderStatus, RateLimitError, SecureLend, SecureLendError, ServerError, ValidationError, anyOfferSchema, applicationProviderSchema, autoLoanSearchSchema, bankAccountOfferSchema, businessApplicantSchema, businessBankingComparisonResponseSchema, businessBankingOfferSchema, businessBankingSearchSchema, businessCreditCardComparisonResponseSchema, businessCreditCardOfferSchema, businessCreditCardSearchSchema, businessLoanSearchSchema, createBusinessApplicationSchema, createPersonalApplicationSchema, creditCardOfferSchema, displayOfferFormResponseSchema, displayOfferFormSchema, displayUploadDocumentsFormResponseSchema, displayUploadDocumentsFormSchema, documentTypeEnum, getMultipleOffersSchema, getOfferSchema, leaseVsPurchaseResponseSchema, leaseVsPurchaseSchema, loanComparisonResponseSchema, loanOfferSchema, loanPaymentResponseSchema, loanPaymentSchema, mortgagePaymentResponseSchema, mortgagePaymentSchema, mortgageSearchSchema, personalApplicantSchema, personalApplicationSchema, personalBankingComparisonResponseSchema, personalBankingOfferSchema, personalBankingSearchSchema, personalCreditCardComparisonResponseSchema, personalCreditCardOfferSchema, personalCreditCardSearchSchema, personalLoanSearchSchema, savingsComparisonResponseSchema, savingsOfferSchema, savingsSearchSchema, studentLoanSearchSchema, submitDocumentsResponseSchema, submitDocumentsSchema, trackOfferStatusResponseSchema, trackOfferStatusSchema };
2005
+ export { ApplicationStatus, ApplicationType, AuthenticationError, ConsentRequiredError, CreditTier, DECLINE_REASON_CODES, EVENT_TYPES, FEEDBACK_TARGETS, FEEDBACK_TYPES, FeatureDisabledError, InvalidTransitionError, NetworkError, NotFoundError, OUTCOME_STATES, ProductType, ProviderStatus, RateLimitError, SHARE_SCOPES, SecureLend, SecureLendError, ServerError, ValidationError, WebhookSignatureError, anyOfferSchema, applicationProviderSchema, autoLoanSearchSchema, bankAccountOfferSchema, businessApplicantSchema, businessBankingComparisonResponseSchema, businessBankingOfferSchema, businessBankingSearchSchema, businessCreditCardComparisonResponseSchema, businessCreditCardOfferSchema, businessCreditCardSearchSchema, businessLoanSearchSchema, createBusinessApplicationSchema, createPersonalApplicationSchema, creditBoxSchema, creditBoxViewSchema, creditCardOfferSchema, displayOfferFormResponseSchema, displayOfferFormSchema, displayUploadDocumentsFormResponseSchema, displayUploadDocumentsFormSchema, documentTypeEnum, feedbackCreatedSchema, feedbackEventSchema, getMultipleOffersSchema, getOfferSchema, leadListSchema, leadOutcomeSchema, leadSchema, leaseVsPurchaseResponseSchema, leaseVsPurchaseSchema, lenderMatchSchema, liquidityCellSchema, liquidityReportSchema, loanComparisonResponseSchema, loanOfferSchema, loanPaymentResponseSchema, loanPaymentSchema, matchComponentsSchema, matchListSchema, mortgagePaymentResponseSchema, mortgagePaymentSchema, mortgageSearchSchema, packageSchema, parseEvent, personalApplicantSchema, personalApplicationSchema, personalBankingComparisonResponseSchema, personalBankingOfferSchema, personalBankingSearchSchema, personalCreditCardComparisonResponseSchema, personalCreditCardOfferSchema, personalCreditCardSearchSchema, personalLoanSearchSchema, savingsComparisonResponseSchema, savingsOfferSchema, savingsSearchSchema, secureLendEventSchema, shareConsentSchema, shareReceiptSchema, signOutcomePayload, signWebhook, studentLoanSearchSchema, submitDocumentsResponseSchema, submitDocumentsSchema, trackOfferStatusResponseSchema, trackOfferStatusSchema, uploadResultSchema, verifyWebhook };
941
2006
  //# sourceMappingURL=index.mjs.map
942
2007
  //# sourceMappingURL=index.mjs.map