@alter-ai/alter-sdk 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -21,8 +21,12 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
23
  APICallAuditLog: () => APICallAuditLog,
24
+ ActorType: () => ActorType,
24
25
  AlterSDKError: () => AlterSDKError,
25
26
  AlterVault: () => AlterVault,
27
+ ConnectSession: () => ConnectSession,
28
+ ConnectionInfo: () => ConnectionInfo,
29
+ ConnectionListResult: () => ConnectionListResult,
26
30
  ConnectionNotFoundError: () => ConnectionNotFoundError,
27
31
  HttpMethod: () => HttpMethod,
28
32
  NetworkError: () => NetworkError,
@@ -36,6 +40,9 @@ __export(index_exports, {
36
40
  });
37
41
  module.exports = __toCommonJS(index_exports);
38
42
 
43
+ // src/client.ts
44
+ var import_node_crypto = require("crypto");
45
+
39
46
  // src/exceptions.ts
40
47
  var AlterSDKError = class extends Error {
41
48
  details;
@@ -104,6 +111,12 @@ var TimeoutError = class extends NetworkError {
104
111
  };
105
112
 
106
113
  // src/models.ts
114
+ var ActorType = /* @__PURE__ */ ((ActorType2) => {
115
+ ActorType2["BACKEND_SERVICE"] = "backend_service";
116
+ ActorType2["AI_AGENT"] = "ai_agent";
117
+ ActorType2["MCP_SERVER"] = "mcp_server";
118
+ return ActorType2;
119
+ })(ActorType || {});
107
120
  var TokenResponse = class _TokenResponse {
108
121
  /** Token type (usually "Bearer") */
109
122
  tokenType;
@@ -115,12 +128,21 @@ var TokenResponse = class _TokenResponse {
115
128
  scopes;
116
129
  /** Connection ID that provided this token */
117
130
  connectionId;
131
+ /** Provider ID (google, github, etc.) */
132
+ providerId;
133
+ /** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
134
+ injectionHeader;
135
+ /** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
136
+ injectionFormat;
118
137
  constructor(data) {
119
138
  this.tokenType = data.token_type ?? "Bearer";
120
139
  this.expiresIn = data.expires_in ?? null;
121
140
  this.expiresAt = data.expires_at ? _TokenResponse.parseExpiresAt(data.expires_at) : null;
122
141
  this.scopes = data.scopes ?? [];
123
142
  this.connectionId = data.connection_id;
143
+ this.providerId = data.provider_id ?? "";
144
+ this.injectionHeader = data.injection_header ?? "Authorization";
145
+ this.injectionFormat = data.injection_format ?? "Bearer {token}";
124
146
  Object.freeze(this);
125
147
  }
126
148
  /**
@@ -182,6 +204,84 @@ var TokenResponse = class _TokenResponse {
182
204
  return this.toString();
183
205
  }
184
206
  };
207
+ var ConnectionInfo = class {
208
+ id;
209
+ providerId;
210
+ scopes;
211
+ accountIdentifier;
212
+ accountDisplayName;
213
+ status;
214
+ expiresAt;
215
+ createdAt;
216
+ lastUsedAt;
217
+ constructor(data) {
218
+ this.id = data.id;
219
+ this.providerId = data.provider_id;
220
+ this.scopes = data.scopes ?? [];
221
+ this.accountIdentifier = data.account_identifier ?? null;
222
+ this.accountDisplayName = data.account_display_name ?? null;
223
+ this.status = data.status;
224
+ this.expiresAt = data.expires_at ?? null;
225
+ this.createdAt = data.created_at;
226
+ this.lastUsedAt = data.last_used_at ?? null;
227
+ Object.freeze(this);
228
+ }
229
+ toJSON() {
230
+ return {
231
+ id: this.id,
232
+ provider_id: this.providerId,
233
+ scopes: this.scopes,
234
+ account_identifier: this.accountIdentifier,
235
+ account_display_name: this.accountDisplayName,
236
+ status: this.status,
237
+ expires_at: this.expiresAt,
238
+ created_at: this.createdAt,
239
+ last_used_at: this.lastUsedAt
240
+ };
241
+ }
242
+ toString() {
243
+ return `ConnectionInfo(id=${this.id}, provider=${this.providerId}, status=${this.status})`;
244
+ }
245
+ };
246
+ var ConnectSession = class {
247
+ sessionToken;
248
+ connectUrl;
249
+ expiresIn;
250
+ expiresAt;
251
+ constructor(data) {
252
+ this.sessionToken = data.session_token;
253
+ this.connectUrl = data.connect_url;
254
+ this.expiresIn = data.expires_in;
255
+ this.expiresAt = data.expires_at;
256
+ Object.freeze(this);
257
+ }
258
+ toJSON() {
259
+ return {
260
+ session_token: this.sessionToken,
261
+ connect_url: this.connectUrl,
262
+ expires_in: this.expiresIn,
263
+ expires_at: this.expiresAt
264
+ };
265
+ }
266
+ toString() {
267
+ return `ConnectSession(url=${this.connectUrl}, expires_in=${this.expiresIn})`;
268
+ }
269
+ };
270
+ var ConnectionListResult = class {
271
+ connections;
272
+ total;
273
+ limit;
274
+ offset;
275
+ hasMore;
276
+ constructor(data) {
277
+ this.connections = data.connections;
278
+ this.total = data.total;
279
+ this.limit = data.limit;
280
+ this.offset = data.offset;
281
+ this.hasMore = data.has_more;
282
+ Object.freeze(this);
283
+ }
284
+ };
185
285
  var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
186
286
  "authorization",
187
287
  "cookie",
@@ -276,9 +376,8 @@ function _extractAccessToken(token) {
276
376
  return value;
277
377
  }
278
378
  var _fetch;
279
- var SDK_VERSION = "0.2.1";
379
+ var SDK_VERSION = "0.3.0";
280
380
  var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
281
- var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
282
381
  var HTTP_FORBIDDEN = 403;
283
382
  var HTTP_NOT_FOUND = 404;
284
383
  var HTTP_BAD_REQUEST = 400;
@@ -358,6 +457,8 @@ var AlterVault = class _AlterVault {
358
457
  // SECURITY LAYER 4: ES2022 private fields — truly private at runtime.
359
458
  // These are NOT accessible via (obj as any), Object.keys(), or prototype.
360
459
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
460
+ /** HMAC signing key (derived from API key using AWS SigV4 pattern, raw bytes) */
461
+ #hmacKey;
361
462
  /** HTTP Client for Alter Backend (has x-api-key) */
362
463
  #alterClient;
363
464
  /** HTTP Client for External Provider APIs (NO x-api-key) */
@@ -395,10 +496,8 @@ var AlterVault = class _AlterVault {
395
496
  for (const [name, value] of actorStrings) {
396
497
  _AlterVault.#validateActorString(value, name);
397
498
  }
398
- this.baseUrl = (options.baseUrl ?? "https://api.alter.com").replace(
399
- /\/+$/,
400
- ""
401
- );
499
+ this.#hmacKey = (0, import_node_crypto.createHmac)("sha256", options.apiKey).update("alter-signing-v1").digest();
500
+ this.baseUrl = (process.env.ALTER_BASE_URL ?? "https://backend.alterai.dev").replace(/\/+$/, "");
402
501
  const timeoutMs = options.timeout ?? 3e4;
403
502
  this.#actorType = options.actorType;
404
503
  this.#actorIdentifier = options.actorIdentifier;
@@ -451,14 +550,20 @@ var AlterVault = class _AlterVault {
451
550
  if (!apiKey.startsWith("alter_key_")) {
452
551
  throw new AlterSDKError("api_key must start with 'alter_key_'");
453
552
  }
454
- if (actorType && !VALID_ACTOR_TYPES.includes(actorType)) {
455
- throw new AlterSDKError("actor_type must be 'ai_agent' or 'mcp_server'");
553
+ if (!actorType) {
554
+ throw new AlterSDKError(
555
+ "actor_type is required (use ActorType.AI_AGENT, ActorType.MCP_SERVER, or ActorType.BACKEND_SERVICE)"
556
+ );
456
557
  }
457
- if (actorType && !actorIdentifier) {
558
+ const validValues = Object.values(ActorType);
559
+ if (!validValues.includes(String(actorType))) {
458
560
  throw new AlterSDKError(
459
- "actor_identifier is required when actor_type is set"
561
+ `actor_type must be one of ${JSON.stringify(validValues.sort())}, got '${String(actorType)}'`
460
562
  );
461
563
  }
564
+ if (!actorIdentifier) {
565
+ throw new AlterSDKError("actor_identifier is required");
566
+ }
462
567
  }
463
568
  /**
464
569
  * Build default headers for the Alter backend HTTP client.
@@ -485,6 +590,28 @@ var AlterVault = class _AlterVault {
485
590
  }
486
591
  return headers;
487
592
  }
593
+ /**
594
+ * Compute HMAC-SHA256 signature headers for an Alter backend request.
595
+ *
596
+ * String-to-sign format: METHOD\nPATH_WITH_SORTED_QUERY\nTIMESTAMP\nCONTENT_HASH
597
+ *
598
+ * The path should include sorted query parameters if present (e.g. "/sdk/endpoint?a=1&b=2").
599
+ * Currently all SDK→backend calls are POSTs without query params, so the path is clean.
600
+ */
601
+ #computeHmacHeaders(method, path, body) {
602
+ const timestamp = String(Math.floor(Date.now() / 1e3));
603
+ const contentHash = (0, import_node_crypto.createHash)("sha256").update(body ?? "").digest("hex");
604
+ const stringToSign = `${method.toUpperCase()}
605
+ ${path}
606
+ ${timestamp}
607
+ ${contentHash}`;
608
+ const signature = (0, import_node_crypto.createHmac)("sha256", this.#hmacKey).update(stringToSign).digest("hex");
609
+ return {
610
+ "X-Alter-Timestamp": timestamp,
611
+ "X-Alter-Content-SHA256": contentHash,
612
+ "X-Alter-Signature": signature
613
+ };
614
+ }
488
615
  /**
489
616
  * Build per-request actor headers for instance tracking.
490
617
  */
@@ -581,7 +708,7 @@ var AlterVault = class _AlterVault {
581
708
  if (response.status === HTTP_NOT_FOUND) {
582
709
  const errorData = await _AlterVault.#safeParseJson(response);
583
710
  throw new ConnectionNotFoundError(
584
- errorData.message ?? "OAuth connection not found for these attributes",
711
+ errorData.message ?? "OAuth connection not found for the given connection_id",
585
712
  errorData
586
713
  );
587
714
  }
@@ -627,21 +754,24 @@ var AlterVault = class _AlterVault {
627
754
  * This is a private method. Tokens are NEVER exposed to developers.
628
755
  * Use request() instead, which handles tokens internally.
629
756
  */
630
- async #getToken(providerId, attributes, reason, runId, threadId, toolCallId) {
757
+ async #getToken(connectionId, reason, requestMetadata, runId, threadId, toolCallId) {
631
758
  const actorHeaders = this.#getActorRequestHeaders(
632
759
  runId,
633
760
  threadId,
634
761
  toolCallId
635
762
  );
636
763
  let response;
764
+ const tokenBody = {
765
+ connection_id: connectionId,
766
+ reason: reason ?? null,
767
+ request: requestMetadata ?? null
768
+ };
769
+ const tokenPath = "/sdk/token";
770
+ const hmacHeaders = this.#computeHmacHeaders("POST", tokenPath, JSON.stringify(tokenBody));
637
771
  try {
638
- response = await this.#alterClient.post("/oauth/token", {
639
- json: {
640
- provider_id: providerId,
641
- attributes,
642
- reason: reason ?? null
643
- },
644
- headers: actorHeaders
772
+ response = await this.#alterClient.post(tokenPath, {
773
+ json: tokenBody,
774
+ headers: { ...actorHeaders, ...hmacHeaders }
645
775
  });
646
776
  } catch (error) {
647
777
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
@@ -658,7 +788,7 @@ var AlterVault = class _AlterVault {
658
788
  }
659
789
  throw new TokenRetrievalError(
660
790
  `Failed to retrieve token: ${error instanceof Error ? error.message : String(error)}`,
661
- { provider_id: providerId, error: String(error) }
791
+ { connection_id: connectionId, error: String(error) }
662
792
  );
663
793
  }
664
794
  this.#cacheActorIdFromResponse(response);
@@ -666,6 +796,18 @@ var AlterVault = class _AlterVault {
666
796
  const tokenData = await response.json();
667
797
  const typedData = tokenData;
668
798
  const tokenResponse = new TokenResponse(typedData);
799
+ if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(tokenResponse.injectionHeader)) {
800
+ throw new TokenRetrievalError(
801
+ `Backend returned invalid injection_header: ${tokenResponse.injectionHeader}`,
802
+ { connectionId: String(connectionId) }
803
+ );
804
+ }
805
+ if (/[\r\n\x00]/.test(tokenResponse.injectionFormat)) {
806
+ throw new TokenRetrievalError(
807
+ `Backend returned invalid injection_format (contains control characters)`,
808
+ { connectionId: String(connectionId) }
809
+ );
810
+ }
669
811
  _storeAccessToken(tokenResponse, typedData.access_token);
670
812
  return tokenResponse;
671
813
  }
@@ -694,10 +836,13 @@ var AlterVault = class _AlterVault {
694
836
  toolCallId: params.toolCallId
695
837
  });
696
838
  const sanitized = auditLog.sanitize();
697
- const actorHeaders = this.#getActorRequestHeaders();
698
- const response = await this.#alterClient.post("/oauth/audit/api-call", {
699
- json: sanitized,
700
- headers: actorHeaders
839
+ const actorHeaders = this.#getActorRequestHeaders(params.runId);
840
+ const auditPath = "/sdk/oauth/audit/api-call";
841
+ const auditBody = sanitized;
842
+ const auditHmac = this.#computeHmacHeaders("POST", auditPath, JSON.stringify(auditBody));
843
+ const response = await this.#alterClient.post(auditPath, {
844
+ json: auditBody,
845
+ headers: { ...actorHeaders, ...auditHmac }
701
846
  });
702
847
  this.#cacheActorIdFromResponse(response);
703
848
  if (!response.ok) {
@@ -763,13 +908,13 @@ var AlterVault = class _AlterVault {
763
908
  * 4. Logs the call for audit (fire-and-forget)
764
909
  * 5. Returns the raw response
765
910
  */
766
- async request(provider, method, url, options) {
911
+ async request(connectionId, method, url, options) {
767
912
  if (this.#closed) {
768
913
  throw new AlterSDKError(
769
914
  "SDK instance has been closed. Create a new AlterVault instance to make requests."
770
915
  );
771
916
  }
772
- const providerStr = String(provider);
917
+ const runId = options?.runId ?? (0, import_node_crypto.randomUUID)();
773
918
  const methodStr = String(method).toUpperCase();
774
919
  const urlLower = url.toLowerCase();
775
920
  if (!ALLOWED_URL_SCHEMES.some((scheme) => urlLower.startsWith(scheme))) {
@@ -777,7 +922,7 @@ var AlterVault = class _AlterVault {
777
922
  `URL must start with https:// or http://, got: ${url.slice(0, 50)}`
778
923
  );
779
924
  }
780
- if (options.pathParams && Object.keys(options.pathParams).length > 0) {
925
+ if (options?.pathParams && Object.keys(options.pathParams).length > 0) {
781
926
  const encodedParams = {};
782
927
  for (const [key, value] of Object.entries(options.pathParams)) {
783
928
  encodedParams[key] = encodeURIComponent(String(value));
@@ -807,21 +952,25 @@ var AlterVault = class _AlterVault {
807
952
  );
808
953
  }
809
954
  }
810
- if (options.extraHeaders && "Authorization" in options.extraHeaders) {
955
+ const tokenResponse = await this.#getToken(
956
+ connectionId,
957
+ options?.reason,
958
+ { method: methodStr, url },
959
+ runId,
960
+ options?.threadId,
961
+ options?.toolCallId
962
+ );
963
+ const injectionHeaderLower = tokenResponse.injectionHeader.toLowerCase();
964
+ if (options?.extraHeaders && Object.keys(options.extraHeaders).some(
965
+ (k) => k.toLowerCase() === injectionHeaderLower
966
+ )) {
811
967
  console.warn(
812
- "extraHeaders contains 'Authorization' which will be overwritten with the auto-injected Bearer token"
968
+ `extraHeaders contains '${tokenResponse.injectionHeader}' which will be overwritten with the auto-injected credential`
813
969
  );
814
970
  }
815
- const tokenResponse = await this.#getToken(
816
- providerStr,
817
- options.user,
818
- options.reason,
819
- options.runId,
820
- options.threadId,
821
- options.toolCallId
822
- );
823
- const requestHeaders = options.extraHeaders ? { ...options.extraHeaders } : {};
824
- requestHeaders["Authorization"] = `Bearer ${_extractAccessToken(tokenResponse)}`;
971
+ const requestHeaders = options?.extraHeaders ? { ...options.extraHeaders } : {};
972
+ const accessToken = _extractAccessToken(tokenResponse);
973
+ requestHeaders[tokenResponse.injectionHeader] = tokenResponse.injectionFormat.replace("{token}", accessToken);
825
974
  if (!requestHeaders["User-Agent"]) {
826
975
  requestHeaders["User-Agent"] = SDK_USER_AGENT;
827
976
  }
@@ -829,16 +978,16 @@ var AlterVault = class _AlterVault {
829
978
  let response;
830
979
  try {
831
980
  response = await this.#providerClient.request(methodStr, url, {
832
- json: options.json,
981
+ json: options?.json,
833
982
  headers: requestHeaders,
834
- params: options.queryParams
983
+ params: options?.queryParams
835
984
  });
836
985
  } catch (error) {
837
986
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
838
987
  throw new TimeoutError(
839
988
  `Provider API request timed out: ${error instanceof Error ? error.message : String(error)}`,
840
989
  {
841
- provider: providerStr,
990
+ connection_id: connectionId,
842
991
  method: methodStr,
843
992
  url
844
993
  }
@@ -847,7 +996,7 @@ var AlterVault = class _AlterVault {
847
996
  throw new NetworkError(
848
997
  `Failed to call provider API: ${error instanceof Error ? error.message : String(error)}`,
849
998
  {
850
- provider: providerStr,
999
+ connection_id: connectionId,
851
1000
  method: methodStr,
852
1001
  url,
853
1002
  error: String(error)
@@ -857,7 +1006,7 @@ var AlterVault = class _AlterVault {
857
1006
  const latencyMs = Date.now() - startTime;
858
1007
  const auditHeaders = {};
859
1008
  for (const [key, value] of Object.entries(requestHeaders)) {
860
- if (key.toLowerCase() !== "authorization") {
1009
+ if (key.toLowerCase() !== injectionHeaderLower) {
861
1010
  auditHeaders[key] = value;
862
1011
  }
863
1012
  }
@@ -868,19 +1017,19 @@ var AlterVault = class _AlterVault {
868
1017
  });
869
1018
  this.#scheduleAuditLog({
870
1019
  connectionId: tokenResponse.connectionId,
871
- providerId: providerStr,
1020
+ providerId: tokenResponse.providerId || connectionId,
872
1021
  method: methodStr,
873
1022
  url,
874
1023
  requestHeaders: auditHeaders,
875
- requestBody: options.json ?? null,
1024
+ requestBody: options?.json ?? null,
876
1025
  responseStatus: response.status,
877
1026
  responseHeaders,
878
1027
  responseBody,
879
1028
  latencyMs,
880
- reason: options.reason ?? null,
881
- runId: options.runId ?? null,
882
- threadId: options.threadId ?? null,
883
- toolCallId: options.toolCallId ?? null
1029
+ reason: options?.reason ?? null,
1030
+ runId,
1031
+ threadId: options?.threadId ?? null,
1032
+ toolCallId: options?.toolCallId ?? null
884
1033
  });
885
1034
  if (response.status >= HTTP_CLIENT_ERROR_START) {
886
1035
  throw new ProviderAPIError(
@@ -888,7 +1037,7 @@ var AlterVault = class _AlterVault {
888
1037
  response.status,
889
1038
  responseBody,
890
1039
  {
891
- provider: providerStr,
1040
+ connection_id: connectionId,
892
1041
  method: methodStr,
893
1042
  url
894
1043
  }
@@ -896,6 +1045,117 @@ var AlterVault = class _AlterVault {
896
1045
  }
897
1046
  return response;
898
1047
  }
1048
+ /**
1049
+ * List OAuth connections for this app.
1050
+ *
1051
+ * Returns paginated connection metadata (no tokens).
1052
+ * Useful for discovering which services a user has connected.
1053
+ */
1054
+ async listConnections(options) {
1055
+ if (this.#closed) {
1056
+ throw new AlterSDKError(
1057
+ "SDK instance has been closed. Create a new AlterVault instance to make requests."
1058
+ );
1059
+ }
1060
+ const actorHeaders = this.#getActorRequestHeaders();
1061
+ let response;
1062
+ const listBody = {
1063
+ provider_id: options?.providerId ?? null,
1064
+ limit: options?.limit ?? 100,
1065
+ offset: options?.offset ?? 0
1066
+ };
1067
+ const listPath = "/sdk/oauth/connections/list";
1068
+ const listHmac = this.#computeHmacHeaders("POST", listPath, JSON.stringify(listBody));
1069
+ try {
1070
+ response = await this.#alterClient.post(listPath, {
1071
+ json: listBody,
1072
+ headers: { ...actorHeaders, ...listHmac }
1073
+ });
1074
+ } catch (error) {
1075
+ if (_AlterVault.#isTimeoutOrAbortError(error)) {
1076
+ throw new TimeoutError(
1077
+ `Request to Alter Vault backend timed out: ${error instanceof Error ? error.message : String(error)}`,
1078
+ { base_url: this.baseUrl }
1079
+ );
1080
+ }
1081
+ if (error instanceof TypeError) {
1082
+ throw new NetworkError(
1083
+ `Failed to connect to Alter Vault backend: ${error.message}`,
1084
+ { base_url: this.baseUrl }
1085
+ );
1086
+ }
1087
+ throw new AlterSDKError(
1088
+ `Failed to list connections: ${error instanceof Error ? error.message : String(error)}`
1089
+ );
1090
+ }
1091
+ this.#cacheActorIdFromResponse(response);
1092
+ await this.#handleErrorResponse(response);
1093
+ const data = await response.json();
1094
+ const connections = data.connections.map(
1095
+ (c) => new ConnectionInfo(
1096
+ c
1097
+ )
1098
+ );
1099
+ return new ConnectionListResult({
1100
+ connections,
1101
+ total: data.total,
1102
+ limit: data.limit,
1103
+ offset: data.offset,
1104
+ has_more: data.has_more
1105
+ });
1106
+ }
1107
+ /**
1108
+ * Create a Connect session for initiating OAuth flows.
1109
+ *
1110
+ * Returns a URL the user can open in their browser to authorize access.
1111
+ */
1112
+ async createConnectSession(options) {
1113
+ if (this.#closed) {
1114
+ throw new AlterSDKError(
1115
+ "SDK instance has been closed. Create a new AlterVault instance to make requests."
1116
+ );
1117
+ }
1118
+ if (!options.endUser?.id) {
1119
+ throw new AlterSDKError("endUser.id is required");
1120
+ }
1121
+ const actorHeaders = this.#getActorRequestHeaders();
1122
+ let response;
1123
+ const sessionBody = {
1124
+ end_user: options.endUser,
1125
+ allowed_providers: options.allowedProviders ?? null,
1126
+ return_url: options.returnUrl ?? null,
1127
+ allowed_origin: options.allowedOrigin ?? null,
1128
+ metadata: options.metadata ?? null
1129
+ };
1130
+ const sessionPath = "/sdk/oauth/connect/session";
1131
+ const sessionHmac = this.#computeHmacHeaders("POST", sessionPath, JSON.stringify(sessionBody));
1132
+ try {
1133
+ response = await this.#alterClient.post(sessionPath, {
1134
+ json: sessionBody,
1135
+ headers: { ...actorHeaders, ...sessionHmac }
1136
+ });
1137
+ } catch (error) {
1138
+ if (_AlterVault.#isTimeoutOrAbortError(error)) {
1139
+ throw new TimeoutError(
1140
+ `Request to Alter Vault backend timed out: ${error instanceof Error ? error.message : String(error)}`,
1141
+ { base_url: this.baseUrl }
1142
+ );
1143
+ }
1144
+ if (error instanceof TypeError) {
1145
+ throw new NetworkError(
1146
+ `Failed to connect to Alter Vault backend: ${error.message}`,
1147
+ { base_url: this.baseUrl }
1148
+ );
1149
+ }
1150
+ throw new AlterSDKError(
1151
+ `Failed to create connect session: ${error instanceof Error ? error.message : String(error)}`
1152
+ );
1153
+ }
1154
+ this.#cacheActorIdFromResponse(response);
1155
+ await this.#handleErrorResponse(response);
1156
+ const data = await response.json();
1157
+ return new ConnectSession(data);
1158
+ }
899
1159
  /**
900
1160
  * Close HTTP clients and release resources.
901
1161
  * Waits for any pending audit tasks before closing.
@@ -924,8 +1184,6 @@ var Provider = /* @__PURE__ */ ((Provider2) => {
924
1184
  Provider2["GOOGLE"] = "google";
925
1185
  Provider2["GITHUB"] = "github";
926
1186
  Provider2["SLACK"] = "slack";
927
- Provider2["MICROSOFT"] = "microsoft";
928
- Provider2["SALESFORCE"] = "salesforce";
929
1187
  Provider2["SENTRY"] = "sentry";
930
1188
  return Provider2;
931
1189
  })(Provider || {});
@@ -942,8 +1200,12 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
942
1200
  // Annotate the CommonJS export names for ESM import in node:
943
1201
  0 && (module.exports = {
944
1202
  APICallAuditLog,
1203
+ ActorType,
945
1204
  AlterSDKError,
946
1205
  AlterVault,
1206
+ ConnectSession,
1207
+ ConnectionInfo,
1208
+ ConnectionListResult,
947
1209
  ConnectionNotFoundError,
948
1210
  HttpMethod,
949
1211
  NetworkError,