@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/README.md +145 -51
- package/dist/index.cjs +315 -53
- package/dist/index.d.cts +262 -137
- package/dist/index.d.ts +262 -137
- package/dist/index.js +311 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import { createHash, createHmac, randomUUID } from "crypto";
|
|
3
|
+
|
|
1
4
|
// src/exceptions.ts
|
|
2
5
|
var AlterSDKError = class extends Error {
|
|
3
6
|
details;
|
|
@@ -66,6 +69,12 @@ var TimeoutError = class extends NetworkError {
|
|
|
66
69
|
};
|
|
67
70
|
|
|
68
71
|
// src/models.ts
|
|
72
|
+
var ActorType = /* @__PURE__ */ ((ActorType2) => {
|
|
73
|
+
ActorType2["BACKEND_SERVICE"] = "backend_service";
|
|
74
|
+
ActorType2["AI_AGENT"] = "ai_agent";
|
|
75
|
+
ActorType2["MCP_SERVER"] = "mcp_server";
|
|
76
|
+
return ActorType2;
|
|
77
|
+
})(ActorType || {});
|
|
69
78
|
var TokenResponse = class _TokenResponse {
|
|
70
79
|
/** Token type (usually "Bearer") */
|
|
71
80
|
tokenType;
|
|
@@ -77,12 +86,21 @@ var TokenResponse = class _TokenResponse {
|
|
|
77
86
|
scopes;
|
|
78
87
|
/** Connection ID that provided this token */
|
|
79
88
|
connectionId;
|
|
89
|
+
/** Provider ID (google, github, etc.) */
|
|
90
|
+
providerId;
|
|
91
|
+
/** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
|
|
92
|
+
injectionHeader;
|
|
93
|
+
/** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
|
|
94
|
+
injectionFormat;
|
|
80
95
|
constructor(data) {
|
|
81
96
|
this.tokenType = data.token_type ?? "Bearer";
|
|
82
97
|
this.expiresIn = data.expires_in ?? null;
|
|
83
98
|
this.expiresAt = data.expires_at ? _TokenResponse.parseExpiresAt(data.expires_at) : null;
|
|
84
99
|
this.scopes = data.scopes ?? [];
|
|
85
100
|
this.connectionId = data.connection_id;
|
|
101
|
+
this.providerId = data.provider_id ?? "";
|
|
102
|
+
this.injectionHeader = data.injection_header ?? "Authorization";
|
|
103
|
+
this.injectionFormat = data.injection_format ?? "Bearer {token}";
|
|
86
104
|
Object.freeze(this);
|
|
87
105
|
}
|
|
88
106
|
/**
|
|
@@ -144,6 +162,84 @@ var TokenResponse = class _TokenResponse {
|
|
|
144
162
|
return this.toString();
|
|
145
163
|
}
|
|
146
164
|
};
|
|
165
|
+
var ConnectionInfo = class {
|
|
166
|
+
id;
|
|
167
|
+
providerId;
|
|
168
|
+
scopes;
|
|
169
|
+
accountIdentifier;
|
|
170
|
+
accountDisplayName;
|
|
171
|
+
status;
|
|
172
|
+
expiresAt;
|
|
173
|
+
createdAt;
|
|
174
|
+
lastUsedAt;
|
|
175
|
+
constructor(data) {
|
|
176
|
+
this.id = data.id;
|
|
177
|
+
this.providerId = data.provider_id;
|
|
178
|
+
this.scopes = data.scopes ?? [];
|
|
179
|
+
this.accountIdentifier = data.account_identifier ?? null;
|
|
180
|
+
this.accountDisplayName = data.account_display_name ?? null;
|
|
181
|
+
this.status = data.status;
|
|
182
|
+
this.expiresAt = data.expires_at ?? null;
|
|
183
|
+
this.createdAt = data.created_at;
|
|
184
|
+
this.lastUsedAt = data.last_used_at ?? null;
|
|
185
|
+
Object.freeze(this);
|
|
186
|
+
}
|
|
187
|
+
toJSON() {
|
|
188
|
+
return {
|
|
189
|
+
id: this.id,
|
|
190
|
+
provider_id: this.providerId,
|
|
191
|
+
scopes: this.scopes,
|
|
192
|
+
account_identifier: this.accountIdentifier,
|
|
193
|
+
account_display_name: this.accountDisplayName,
|
|
194
|
+
status: this.status,
|
|
195
|
+
expires_at: this.expiresAt,
|
|
196
|
+
created_at: this.createdAt,
|
|
197
|
+
last_used_at: this.lastUsedAt
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
toString() {
|
|
201
|
+
return `ConnectionInfo(id=${this.id}, provider=${this.providerId}, status=${this.status})`;
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
var ConnectSession = class {
|
|
205
|
+
sessionToken;
|
|
206
|
+
connectUrl;
|
|
207
|
+
expiresIn;
|
|
208
|
+
expiresAt;
|
|
209
|
+
constructor(data) {
|
|
210
|
+
this.sessionToken = data.session_token;
|
|
211
|
+
this.connectUrl = data.connect_url;
|
|
212
|
+
this.expiresIn = data.expires_in;
|
|
213
|
+
this.expiresAt = data.expires_at;
|
|
214
|
+
Object.freeze(this);
|
|
215
|
+
}
|
|
216
|
+
toJSON() {
|
|
217
|
+
return {
|
|
218
|
+
session_token: this.sessionToken,
|
|
219
|
+
connect_url: this.connectUrl,
|
|
220
|
+
expires_in: this.expiresIn,
|
|
221
|
+
expires_at: this.expiresAt
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
toString() {
|
|
225
|
+
return `ConnectSession(url=${this.connectUrl}, expires_in=${this.expiresIn})`;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
var ConnectionListResult = class {
|
|
229
|
+
connections;
|
|
230
|
+
total;
|
|
231
|
+
limit;
|
|
232
|
+
offset;
|
|
233
|
+
hasMore;
|
|
234
|
+
constructor(data) {
|
|
235
|
+
this.connections = data.connections;
|
|
236
|
+
this.total = data.total;
|
|
237
|
+
this.limit = data.limit;
|
|
238
|
+
this.offset = data.offset;
|
|
239
|
+
this.hasMore = data.has_more;
|
|
240
|
+
Object.freeze(this);
|
|
241
|
+
}
|
|
242
|
+
};
|
|
147
243
|
var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
148
244
|
"authorization",
|
|
149
245
|
"cookie",
|
|
@@ -238,9 +334,8 @@ function _extractAccessToken(token) {
|
|
|
238
334
|
return value;
|
|
239
335
|
}
|
|
240
336
|
var _fetch;
|
|
241
|
-
var SDK_VERSION = "0.
|
|
337
|
+
var SDK_VERSION = "0.3.0";
|
|
242
338
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
243
|
-
var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
|
|
244
339
|
var HTTP_FORBIDDEN = 403;
|
|
245
340
|
var HTTP_NOT_FOUND = 404;
|
|
246
341
|
var HTTP_BAD_REQUEST = 400;
|
|
@@ -320,6 +415,8 @@ var AlterVault = class _AlterVault {
|
|
|
320
415
|
// SECURITY LAYER 4: ES2022 private fields — truly private at runtime.
|
|
321
416
|
// These are NOT accessible via (obj as any), Object.keys(), or prototype.
|
|
322
417
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
418
|
+
/** HMAC signing key (derived from API key using AWS SigV4 pattern, raw bytes) */
|
|
419
|
+
#hmacKey;
|
|
323
420
|
/** HTTP Client for Alter Backend (has x-api-key) */
|
|
324
421
|
#alterClient;
|
|
325
422
|
/** HTTP Client for External Provider APIs (NO x-api-key) */
|
|
@@ -357,10 +454,8 @@ var AlterVault = class _AlterVault {
|
|
|
357
454
|
for (const [name, value] of actorStrings) {
|
|
358
455
|
_AlterVault.#validateActorString(value, name);
|
|
359
456
|
}
|
|
360
|
-
this
|
|
361
|
-
|
|
362
|
-
""
|
|
363
|
-
);
|
|
457
|
+
this.#hmacKey = createHmac("sha256", options.apiKey).update("alter-signing-v1").digest();
|
|
458
|
+
this.baseUrl = (process.env.ALTER_BASE_URL ?? "https://backend.alterai.dev").replace(/\/+$/, "");
|
|
364
459
|
const timeoutMs = options.timeout ?? 3e4;
|
|
365
460
|
this.#actorType = options.actorType;
|
|
366
461
|
this.#actorIdentifier = options.actorIdentifier;
|
|
@@ -413,14 +508,20 @@ var AlterVault = class _AlterVault {
|
|
|
413
508
|
if (!apiKey.startsWith("alter_key_")) {
|
|
414
509
|
throw new AlterSDKError("api_key must start with 'alter_key_'");
|
|
415
510
|
}
|
|
416
|
-
if (
|
|
417
|
-
throw new AlterSDKError(
|
|
511
|
+
if (!actorType) {
|
|
512
|
+
throw new AlterSDKError(
|
|
513
|
+
"actor_type is required (use ActorType.AI_AGENT, ActorType.MCP_SERVER, or ActorType.BACKEND_SERVICE)"
|
|
514
|
+
);
|
|
418
515
|
}
|
|
419
|
-
|
|
516
|
+
const validValues = Object.values(ActorType);
|
|
517
|
+
if (!validValues.includes(String(actorType))) {
|
|
420
518
|
throw new AlterSDKError(
|
|
421
|
-
|
|
519
|
+
`actor_type must be one of ${JSON.stringify(validValues.sort())}, got '${String(actorType)}'`
|
|
422
520
|
);
|
|
423
521
|
}
|
|
522
|
+
if (!actorIdentifier) {
|
|
523
|
+
throw new AlterSDKError("actor_identifier is required");
|
|
524
|
+
}
|
|
424
525
|
}
|
|
425
526
|
/**
|
|
426
527
|
* Build default headers for the Alter backend HTTP client.
|
|
@@ -447,6 +548,28 @@ var AlterVault = class _AlterVault {
|
|
|
447
548
|
}
|
|
448
549
|
return headers;
|
|
449
550
|
}
|
|
551
|
+
/**
|
|
552
|
+
* Compute HMAC-SHA256 signature headers for an Alter backend request.
|
|
553
|
+
*
|
|
554
|
+
* String-to-sign format: METHOD\nPATH_WITH_SORTED_QUERY\nTIMESTAMP\nCONTENT_HASH
|
|
555
|
+
*
|
|
556
|
+
* The path should include sorted query parameters if present (e.g. "/sdk/endpoint?a=1&b=2").
|
|
557
|
+
* Currently all SDK→backend calls are POSTs without query params, so the path is clean.
|
|
558
|
+
*/
|
|
559
|
+
#computeHmacHeaders(method, path, body) {
|
|
560
|
+
const timestamp = String(Math.floor(Date.now() / 1e3));
|
|
561
|
+
const contentHash = createHash("sha256").update(body ?? "").digest("hex");
|
|
562
|
+
const stringToSign = `${method.toUpperCase()}
|
|
563
|
+
${path}
|
|
564
|
+
${timestamp}
|
|
565
|
+
${contentHash}`;
|
|
566
|
+
const signature = createHmac("sha256", this.#hmacKey).update(stringToSign).digest("hex");
|
|
567
|
+
return {
|
|
568
|
+
"X-Alter-Timestamp": timestamp,
|
|
569
|
+
"X-Alter-Content-SHA256": contentHash,
|
|
570
|
+
"X-Alter-Signature": signature
|
|
571
|
+
};
|
|
572
|
+
}
|
|
450
573
|
/**
|
|
451
574
|
* Build per-request actor headers for instance tracking.
|
|
452
575
|
*/
|
|
@@ -543,7 +666,7 @@ var AlterVault = class _AlterVault {
|
|
|
543
666
|
if (response.status === HTTP_NOT_FOUND) {
|
|
544
667
|
const errorData = await _AlterVault.#safeParseJson(response);
|
|
545
668
|
throw new ConnectionNotFoundError(
|
|
546
|
-
errorData.message ?? "OAuth connection not found for
|
|
669
|
+
errorData.message ?? "OAuth connection not found for the given connection_id",
|
|
547
670
|
errorData
|
|
548
671
|
);
|
|
549
672
|
}
|
|
@@ -589,21 +712,24 @@ var AlterVault = class _AlterVault {
|
|
|
589
712
|
* This is a private method. Tokens are NEVER exposed to developers.
|
|
590
713
|
* Use request() instead, which handles tokens internally.
|
|
591
714
|
*/
|
|
592
|
-
async #getToken(
|
|
715
|
+
async #getToken(connectionId, reason, requestMetadata, runId, threadId, toolCallId) {
|
|
593
716
|
const actorHeaders = this.#getActorRequestHeaders(
|
|
594
717
|
runId,
|
|
595
718
|
threadId,
|
|
596
719
|
toolCallId
|
|
597
720
|
);
|
|
598
721
|
let response;
|
|
722
|
+
const tokenBody = {
|
|
723
|
+
connection_id: connectionId,
|
|
724
|
+
reason: reason ?? null,
|
|
725
|
+
request: requestMetadata ?? null
|
|
726
|
+
};
|
|
727
|
+
const tokenPath = "/sdk/token";
|
|
728
|
+
const hmacHeaders = this.#computeHmacHeaders("POST", tokenPath, JSON.stringify(tokenBody));
|
|
599
729
|
try {
|
|
600
|
-
response = await this.#alterClient.post(
|
|
601
|
-
json:
|
|
602
|
-
|
|
603
|
-
attributes,
|
|
604
|
-
reason: reason ?? null
|
|
605
|
-
},
|
|
606
|
-
headers: actorHeaders
|
|
730
|
+
response = await this.#alterClient.post(tokenPath, {
|
|
731
|
+
json: tokenBody,
|
|
732
|
+
headers: { ...actorHeaders, ...hmacHeaders }
|
|
607
733
|
});
|
|
608
734
|
} catch (error) {
|
|
609
735
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -620,7 +746,7 @@ var AlterVault = class _AlterVault {
|
|
|
620
746
|
}
|
|
621
747
|
throw new TokenRetrievalError(
|
|
622
748
|
`Failed to retrieve token: ${error instanceof Error ? error.message : String(error)}`,
|
|
623
|
-
{
|
|
749
|
+
{ connection_id: connectionId, error: String(error) }
|
|
624
750
|
);
|
|
625
751
|
}
|
|
626
752
|
this.#cacheActorIdFromResponse(response);
|
|
@@ -628,6 +754,18 @@ var AlterVault = class _AlterVault {
|
|
|
628
754
|
const tokenData = await response.json();
|
|
629
755
|
const typedData = tokenData;
|
|
630
756
|
const tokenResponse = new TokenResponse(typedData);
|
|
757
|
+
if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(tokenResponse.injectionHeader)) {
|
|
758
|
+
throw new TokenRetrievalError(
|
|
759
|
+
`Backend returned invalid injection_header: ${tokenResponse.injectionHeader}`,
|
|
760
|
+
{ connectionId: String(connectionId) }
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
if (/[\r\n\x00]/.test(tokenResponse.injectionFormat)) {
|
|
764
|
+
throw new TokenRetrievalError(
|
|
765
|
+
`Backend returned invalid injection_format (contains control characters)`,
|
|
766
|
+
{ connectionId: String(connectionId) }
|
|
767
|
+
);
|
|
768
|
+
}
|
|
631
769
|
_storeAccessToken(tokenResponse, typedData.access_token);
|
|
632
770
|
return tokenResponse;
|
|
633
771
|
}
|
|
@@ -656,10 +794,13 @@ var AlterVault = class _AlterVault {
|
|
|
656
794
|
toolCallId: params.toolCallId
|
|
657
795
|
});
|
|
658
796
|
const sanitized = auditLog.sanitize();
|
|
659
|
-
const actorHeaders = this.#getActorRequestHeaders();
|
|
660
|
-
const
|
|
661
|
-
|
|
662
|
-
|
|
797
|
+
const actorHeaders = this.#getActorRequestHeaders(params.runId);
|
|
798
|
+
const auditPath = "/sdk/oauth/audit/api-call";
|
|
799
|
+
const auditBody = sanitized;
|
|
800
|
+
const auditHmac = this.#computeHmacHeaders("POST", auditPath, JSON.stringify(auditBody));
|
|
801
|
+
const response = await this.#alterClient.post(auditPath, {
|
|
802
|
+
json: auditBody,
|
|
803
|
+
headers: { ...actorHeaders, ...auditHmac }
|
|
663
804
|
});
|
|
664
805
|
this.#cacheActorIdFromResponse(response);
|
|
665
806
|
if (!response.ok) {
|
|
@@ -725,13 +866,13 @@ var AlterVault = class _AlterVault {
|
|
|
725
866
|
* 4. Logs the call for audit (fire-and-forget)
|
|
726
867
|
* 5. Returns the raw response
|
|
727
868
|
*/
|
|
728
|
-
async request(
|
|
869
|
+
async request(connectionId, method, url, options) {
|
|
729
870
|
if (this.#closed) {
|
|
730
871
|
throw new AlterSDKError(
|
|
731
872
|
"SDK instance has been closed. Create a new AlterVault instance to make requests."
|
|
732
873
|
);
|
|
733
874
|
}
|
|
734
|
-
const
|
|
875
|
+
const runId = options?.runId ?? randomUUID();
|
|
735
876
|
const methodStr = String(method).toUpperCase();
|
|
736
877
|
const urlLower = url.toLowerCase();
|
|
737
878
|
if (!ALLOWED_URL_SCHEMES.some((scheme) => urlLower.startsWith(scheme))) {
|
|
@@ -739,7 +880,7 @@ var AlterVault = class _AlterVault {
|
|
|
739
880
|
`URL must start with https:// or http://, got: ${url.slice(0, 50)}`
|
|
740
881
|
);
|
|
741
882
|
}
|
|
742
|
-
if (options
|
|
883
|
+
if (options?.pathParams && Object.keys(options.pathParams).length > 0) {
|
|
743
884
|
const encodedParams = {};
|
|
744
885
|
for (const [key, value] of Object.entries(options.pathParams)) {
|
|
745
886
|
encodedParams[key] = encodeURIComponent(String(value));
|
|
@@ -769,21 +910,25 @@ var AlterVault = class _AlterVault {
|
|
|
769
910
|
);
|
|
770
911
|
}
|
|
771
912
|
}
|
|
772
|
-
|
|
913
|
+
const tokenResponse = await this.#getToken(
|
|
914
|
+
connectionId,
|
|
915
|
+
options?.reason,
|
|
916
|
+
{ method: methodStr, url },
|
|
917
|
+
runId,
|
|
918
|
+
options?.threadId,
|
|
919
|
+
options?.toolCallId
|
|
920
|
+
);
|
|
921
|
+
const injectionHeaderLower = tokenResponse.injectionHeader.toLowerCase();
|
|
922
|
+
if (options?.extraHeaders && Object.keys(options.extraHeaders).some(
|
|
923
|
+
(k) => k.toLowerCase() === injectionHeaderLower
|
|
924
|
+
)) {
|
|
773
925
|
console.warn(
|
|
774
|
-
|
|
926
|
+
`extraHeaders contains '${tokenResponse.injectionHeader}' which will be overwritten with the auto-injected credential`
|
|
775
927
|
);
|
|
776
928
|
}
|
|
777
|
-
const
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
options.reason,
|
|
781
|
-
options.runId,
|
|
782
|
-
options.threadId,
|
|
783
|
-
options.toolCallId
|
|
784
|
-
);
|
|
785
|
-
const requestHeaders = options.extraHeaders ? { ...options.extraHeaders } : {};
|
|
786
|
-
requestHeaders["Authorization"] = `Bearer ${_extractAccessToken(tokenResponse)}`;
|
|
929
|
+
const requestHeaders = options?.extraHeaders ? { ...options.extraHeaders } : {};
|
|
930
|
+
const accessToken = _extractAccessToken(tokenResponse);
|
|
931
|
+
requestHeaders[tokenResponse.injectionHeader] = tokenResponse.injectionFormat.replace("{token}", accessToken);
|
|
787
932
|
if (!requestHeaders["User-Agent"]) {
|
|
788
933
|
requestHeaders["User-Agent"] = SDK_USER_AGENT;
|
|
789
934
|
}
|
|
@@ -791,16 +936,16 @@ var AlterVault = class _AlterVault {
|
|
|
791
936
|
let response;
|
|
792
937
|
try {
|
|
793
938
|
response = await this.#providerClient.request(methodStr, url, {
|
|
794
|
-
json: options
|
|
939
|
+
json: options?.json,
|
|
795
940
|
headers: requestHeaders,
|
|
796
|
-
params: options
|
|
941
|
+
params: options?.queryParams
|
|
797
942
|
});
|
|
798
943
|
} catch (error) {
|
|
799
944
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
800
945
|
throw new TimeoutError(
|
|
801
946
|
`Provider API request timed out: ${error instanceof Error ? error.message : String(error)}`,
|
|
802
947
|
{
|
|
803
|
-
|
|
948
|
+
connection_id: connectionId,
|
|
804
949
|
method: methodStr,
|
|
805
950
|
url
|
|
806
951
|
}
|
|
@@ -809,7 +954,7 @@ var AlterVault = class _AlterVault {
|
|
|
809
954
|
throw new NetworkError(
|
|
810
955
|
`Failed to call provider API: ${error instanceof Error ? error.message : String(error)}`,
|
|
811
956
|
{
|
|
812
|
-
|
|
957
|
+
connection_id: connectionId,
|
|
813
958
|
method: methodStr,
|
|
814
959
|
url,
|
|
815
960
|
error: String(error)
|
|
@@ -819,7 +964,7 @@ var AlterVault = class _AlterVault {
|
|
|
819
964
|
const latencyMs = Date.now() - startTime;
|
|
820
965
|
const auditHeaders = {};
|
|
821
966
|
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
822
|
-
if (key.toLowerCase() !==
|
|
967
|
+
if (key.toLowerCase() !== injectionHeaderLower) {
|
|
823
968
|
auditHeaders[key] = value;
|
|
824
969
|
}
|
|
825
970
|
}
|
|
@@ -830,19 +975,19 @@ var AlterVault = class _AlterVault {
|
|
|
830
975
|
});
|
|
831
976
|
this.#scheduleAuditLog({
|
|
832
977
|
connectionId: tokenResponse.connectionId,
|
|
833
|
-
providerId:
|
|
978
|
+
providerId: tokenResponse.providerId || connectionId,
|
|
834
979
|
method: methodStr,
|
|
835
980
|
url,
|
|
836
981
|
requestHeaders: auditHeaders,
|
|
837
|
-
requestBody: options
|
|
982
|
+
requestBody: options?.json ?? null,
|
|
838
983
|
responseStatus: response.status,
|
|
839
984
|
responseHeaders,
|
|
840
985
|
responseBody,
|
|
841
986
|
latencyMs,
|
|
842
|
-
reason: options
|
|
843
|
-
runId
|
|
844
|
-
threadId: options
|
|
845
|
-
toolCallId: options
|
|
987
|
+
reason: options?.reason ?? null,
|
|
988
|
+
runId,
|
|
989
|
+
threadId: options?.threadId ?? null,
|
|
990
|
+
toolCallId: options?.toolCallId ?? null
|
|
846
991
|
});
|
|
847
992
|
if (response.status >= HTTP_CLIENT_ERROR_START) {
|
|
848
993
|
throw new ProviderAPIError(
|
|
@@ -850,7 +995,7 @@ var AlterVault = class _AlterVault {
|
|
|
850
995
|
response.status,
|
|
851
996
|
responseBody,
|
|
852
997
|
{
|
|
853
|
-
|
|
998
|
+
connection_id: connectionId,
|
|
854
999
|
method: methodStr,
|
|
855
1000
|
url
|
|
856
1001
|
}
|
|
@@ -858,6 +1003,117 @@ var AlterVault = class _AlterVault {
|
|
|
858
1003
|
}
|
|
859
1004
|
return response;
|
|
860
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* List OAuth connections for this app.
|
|
1008
|
+
*
|
|
1009
|
+
* Returns paginated connection metadata (no tokens).
|
|
1010
|
+
* Useful for discovering which services a user has connected.
|
|
1011
|
+
*/
|
|
1012
|
+
async listConnections(options) {
|
|
1013
|
+
if (this.#closed) {
|
|
1014
|
+
throw new AlterSDKError(
|
|
1015
|
+
"SDK instance has been closed. Create a new AlterVault instance to make requests."
|
|
1016
|
+
);
|
|
1017
|
+
}
|
|
1018
|
+
const actorHeaders = this.#getActorRequestHeaders();
|
|
1019
|
+
let response;
|
|
1020
|
+
const listBody = {
|
|
1021
|
+
provider_id: options?.providerId ?? null,
|
|
1022
|
+
limit: options?.limit ?? 100,
|
|
1023
|
+
offset: options?.offset ?? 0
|
|
1024
|
+
};
|
|
1025
|
+
const listPath = "/sdk/oauth/connections/list";
|
|
1026
|
+
const listHmac = this.#computeHmacHeaders("POST", listPath, JSON.stringify(listBody));
|
|
1027
|
+
try {
|
|
1028
|
+
response = await this.#alterClient.post(listPath, {
|
|
1029
|
+
json: listBody,
|
|
1030
|
+
headers: { ...actorHeaders, ...listHmac }
|
|
1031
|
+
});
|
|
1032
|
+
} catch (error) {
|
|
1033
|
+
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
1034
|
+
throw new TimeoutError(
|
|
1035
|
+
`Request to Alter Vault backend timed out: ${error instanceof Error ? error.message : String(error)}`,
|
|
1036
|
+
{ base_url: this.baseUrl }
|
|
1037
|
+
);
|
|
1038
|
+
}
|
|
1039
|
+
if (error instanceof TypeError) {
|
|
1040
|
+
throw new NetworkError(
|
|
1041
|
+
`Failed to connect to Alter Vault backend: ${error.message}`,
|
|
1042
|
+
{ base_url: this.baseUrl }
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
throw new AlterSDKError(
|
|
1046
|
+
`Failed to list connections: ${error instanceof Error ? error.message : String(error)}`
|
|
1047
|
+
);
|
|
1048
|
+
}
|
|
1049
|
+
this.#cacheActorIdFromResponse(response);
|
|
1050
|
+
await this.#handleErrorResponse(response);
|
|
1051
|
+
const data = await response.json();
|
|
1052
|
+
const connections = data.connections.map(
|
|
1053
|
+
(c) => new ConnectionInfo(
|
|
1054
|
+
c
|
|
1055
|
+
)
|
|
1056
|
+
);
|
|
1057
|
+
return new ConnectionListResult({
|
|
1058
|
+
connections,
|
|
1059
|
+
total: data.total,
|
|
1060
|
+
limit: data.limit,
|
|
1061
|
+
offset: data.offset,
|
|
1062
|
+
has_more: data.has_more
|
|
1063
|
+
});
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Create a Connect session for initiating OAuth flows.
|
|
1067
|
+
*
|
|
1068
|
+
* Returns a URL the user can open in their browser to authorize access.
|
|
1069
|
+
*/
|
|
1070
|
+
async createConnectSession(options) {
|
|
1071
|
+
if (this.#closed) {
|
|
1072
|
+
throw new AlterSDKError(
|
|
1073
|
+
"SDK instance has been closed. Create a new AlterVault instance to make requests."
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
if (!options.endUser?.id) {
|
|
1077
|
+
throw new AlterSDKError("endUser.id is required");
|
|
1078
|
+
}
|
|
1079
|
+
const actorHeaders = this.#getActorRequestHeaders();
|
|
1080
|
+
let response;
|
|
1081
|
+
const sessionBody = {
|
|
1082
|
+
end_user: options.endUser,
|
|
1083
|
+
allowed_providers: options.allowedProviders ?? null,
|
|
1084
|
+
return_url: options.returnUrl ?? null,
|
|
1085
|
+
allowed_origin: options.allowedOrigin ?? null,
|
|
1086
|
+
metadata: options.metadata ?? null
|
|
1087
|
+
};
|
|
1088
|
+
const sessionPath = "/sdk/oauth/connect/session";
|
|
1089
|
+
const sessionHmac = this.#computeHmacHeaders("POST", sessionPath, JSON.stringify(sessionBody));
|
|
1090
|
+
try {
|
|
1091
|
+
response = await this.#alterClient.post(sessionPath, {
|
|
1092
|
+
json: sessionBody,
|
|
1093
|
+
headers: { ...actorHeaders, ...sessionHmac }
|
|
1094
|
+
});
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
1097
|
+
throw new TimeoutError(
|
|
1098
|
+
`Request to Alter Vault backend timed out: ${error instanceof Error ? error.message : String(error)}`,
|
|
1099
|
+
{ base_url: this.baseUrl }
|
|
1100
|
+
);
|
|
1101
|
+
}
|
|
1102
|
+
if (error instanceof TypeError) {
|
|
1103
|
+
throw new NetworkError(
|
|
1104
|
+
`Failed to connect to Alter Vault backend: ${error.message}`,
|
|
1105
|
+
{ base_url: this.baseUrl }
|
|
1106
|
+
);
|
|
1107
|
+
}
|
|
1108
|
+
throw new AlterSDKError(
|
|
1109
|
+
`Failed to create connect session: ${error instanceof Error ? error.message : String(error)}`
|
|
1110
|
+
);
|
|
1111
|
+
}
|
|
1112
|
+
this.#cacheActorIdFromResponse(response);
|
|
1113
|
+
await this.#handleErrorResponse(response);
|
|
1114
|
+
const data = await response.json();
|
|
1115
|
+
return new ConnectSession(data);
|
|
1116
|
+
}
|
|
861
1117
|
/**
|
|
862
1118
|
* Close HTTP clients and release resources.
|
|
863
1119
|
* Waits for any pending audit tasks before closing.
|
|
@@ -886,8 +1142,6 @@ var Provider = /* @__PURE__ */ ((Provider2) => {
|
|
|
886
1142
|
Provider2["GOOGLE"] = "google";
|
|
887
1143
|
Provider2["GITHUB"] = "github";
|
|
888
1144
|
Provider2["SLACK"] = "slack";
|
|
889
|
-
Provider2["MICROSOFT"] = "microsoft";
|
|
890
|
-
Provider2["SALESFORCE"] = "salesforce";
|
|
891
1145
|
Provider2["SENTRY"] = "sentry";
|
|
892
1146
|
return Provider2;
|
|
893
1147
|
})(Provider || {});
|
|
@@ -903,8 +1157,12 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
|
|
|
903
1157
|
})(HttpMethod || {});
|
|
904
1158
|
export {
|
|
905
1159
|
APICallAuditLog,
|
|
1160
|
+
ActorType,
|
|
906
1161
|
AlterSDKError,
|
|
907
1162
|
AlterVault,
|
|
1163
|
+
ConnectSession,
|
|
1164
|
+
ConnectionInfo,
|
|
1165
|
+
ConnectionListResult,
|
|
908
1166
|
ConnectionNotFoundError,
|
|
909
1167
|
HttpMethod,
|
|
910
1168
|
NetworkError,
|