@alter-ai/alter-sdk 0.2.2 → 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 +93 -51
- package/dist/index.cjs +142 -75
- package/dist/index.d.cts +24 -18
- package/dist/index.d.ts +24 -18
- package/dist/index.js +141 -75
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,6 +21,7 @@ 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,
|
|
26
27
|
ConnectSession: () => ConnectSession,
|
|
@@ -39,6 +40,9 @@ __export(index_exports, {
|
|
|
39
40
|
});
|
|
40
41
|
module.exports = __toCommonJS(index_exports);
|
|
41
42
|
|
|
43
|
+
// src/client.ts
|
|
44
|
+
var import_node_crypto = require("crypto");
|
|
45
|
+
|
|
42
46
|
// src/exceptions.ts
|
|
43
47
|
var AlterSDKError = class extends Error {
|
|
44
48
|
details;
|
|
@@ -107,6 +111,12 @@ var TimeoutError = class extends NetworkError {
|
|
|
107
111
|
};
|
|
108
112
|
|
|
109
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 || {});
|
|
110
120
|
var TokenResponse = class _TokenResponse {
|
|
111
121
|
/** Token type (usually "Bearer") */
|
|
112
122
|
tokenType;
|
|
@@ -118,12 +128,21 @@ var TokenResponse = class _TokenResponse {
|
|
|
118
128
|
scopes;
|
|
119
129
|
/** Connection ID that provided this token */
|
|
120
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;
|
|
121
137
|
constructor(data) {
|
|
122
138
|
this.tokenType = data.token_type ?? "Bearer";
|
|
123
139
|
this.expiresIn = data.expires_in ?? null;
|
|
124
140
|
this.expiresAt = data.expires_at ? _TokenResponse.parseExpiresAt(data.expires_at) : null;
|
|
125
141
|
this.scopes = data.scopes ?? [];
|
|
126
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}";
|
|
127
146
|
Object.freeze(this);
|
|
128
147
|
}
|
|
129
148
|
/**
|
|
@@ -188,7 +207,6 @@ var TokenResponse = class _TokenResponse {
|
|
|
188
207
|
var ConnectionInfo = class {
|
|
189
208
|
id;
|
|
190
209
|
providerId;
|
|
191
|
-
attributes;
|
|
192
210
|
scopes;
|
|
193
211
|
accountIdentifier;
|
|
194
212
|
accountDisplayName;
|
|
@@ -199,7 +217,6 @@ var ConnectionInfo = class {
|
|
|
199
217
|
constructor(data) {
|
|
200
218
|
this.id = data.id;
|
|
201
219
|
this.providerId = data.provider_id;
|
|
202
|
-
this.attributes = data.attributes ?? {};
|
|
203
220
|
this.scopes = data.scopes ?? [];
|
|
204
221
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
205
222
|
this.accountDisplayName = data.account_display_name ?? null;
|
|
@@ -213,7 +230,6 @@ var ConnectionInfo = class {
|
|
|
213
230
|
return {
|
|
214
231
|
id: this.id,
|
|
215
232
|
provider_id: this.providerId,
|
|
216
|
-
attributes: this.attributes,
|
|
217
233
|
scopes: this.scopes,
|
|
218
234
|
account_identifier: this.accountIdentifier,
|
|
219
235
|
account_display_name: this.accountDisplayName,
|
|
@@ -360,9 +376,8 @@ function _extractAccessToken(token) {
|
|
|
360
376
|
return value;
|
|
361
377
|
}
|
|
362
378
|
var _fetch;
|
|
363
|
-
var SDK_VERSION = "0.
|
|
379
|
+
var SDK_VERSION = "0.3.0";
|
|
364
380
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
365
|
-
var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
|
|
366
381
|
var HTTP_FORBIDDEN = 403;
|
|
367
382
|
var HTTP_NOT_FOUND = 404;
|
|
368
383
|
var HTTP_BAD_REQUEST = 400;
|
|
@@ -442,6 +457,8 @@ var AlterVault = class _AlterVault {
|
|
|
442
457
|
// SECURITY LAYER 4: ES2022 private fields — truly private at runtime.
|
|
443
458
|
// These are NOT accessible via (obj as any), Object.keys(), or prototype.
|
|
444
459
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
460
|
+
/** HMAC signing key (derived from API key using AWS SigV4 pattern, raw bytes) */
|
|
461
|
+
#hmacKey;
|
|
445
462
|
/** HTTP Client for Alter Backend (has x-api-key) */
|
|
446
463
|
#alterClient;
|
|
447
464
|
/** HTTP Client for External Provider APIs (NO x-api-key) */
|
|
@@ -479,10 +496,8 @@ var AlterVault = class _AlterVault {
|
|
|
479
496
|
for (const [name, value] of actorStrings) {
|
|
480
497
|
_AlterVault.#validateActorString(value, name);
|
|
481
498
|
}
|
|
482
|
-
this
|
|
483
|
-
|
|
484
|
-
""
|
|
485
|
-
);
|
|
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(/\/+$/, "");
|
|
486
501
|
const timeoutMs = options.timeout ?? 3e4;
|
|
487
502
|
this.#actorType = options.actorType;
|
|
488
503
|
this.#actorIdentifier = options.actorIdentifier;
|
|
@@ -535,14 +550,20 @@ var AlterVault = class _AlterVault {
|
|
|
535
550
|
if (!apiKey.startsWith("alter_key_")) {
|
|
536
551
|
throw new AlterSDKError("api_key must start with 'alter_key_'");
|
|
537
552
|
}
|
|
538
|
-
if (
|
|
539
|
-
throw new AlterSDKError(
|
|
553
|
+
if (!actorType) {
|
|
554
|
+
throw new AlterSDKError(
|
|
555
|
+
"actor_type is required (use ActorType.AI_AGENT, ActorType.MCP_SERVER, or ActorType.BACKEND_SERVICE)"
|
|
556
|
+
);
|
|
540
557
|
}
|
|
541
|
-
|
|
558
|
+
const validValues = Object.values(ActorType);
|
|
559
|
+
if (!validValues.includes(String(actorType))) {
|
|
542
560
|
throw new AlterSDKError(
|
|
543
|
-
|
|
561
|
+
`actor_type must be one of ${JSON.stringify(validValues.sort())}, got '${String(actorType)}'`
|
|
544
562
|
);
|
|
545
563
|
}
|
|
564
|
+
if (!actorIdentifier) {
|
|
565
|
+
throw new AlterSDKError("actor_identifier is required");
|
|
566
|
+
}
|
|
546
567
|
}
|
|
547
568
|
/**
|
|
548
569
|
* Build default headers for the Alter backend HTTP client.
|
|
@@ -569,6 +590,28 @@ var AlterVault = class _AlterVault {
|
|
|
569
590
|
}
|
|
570
591
|
return headers;
|
|
571
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
|
+
}
|
|
572
615
|
/**
|
|
573
616
|
* Build per-request actor headers for instance tracking.
|
|
574
617
|
*/
|
|
@@ -665,7 +708,7 @@ var AlterVault = class _AlterVault {
|
|
|
665
708
|
if (response.status === HTTP_NOT_FOUND) {
|
|
666
709
|
const errorData = await _AlterVault.#safeParseJson(response);
|
|
667
710
|
throw new ConnectionNotFoundError(
|
|
668
|
-
errorData.message ?? "OAuth connection not found for
|
|
711
|
+
errorData.message ?? "OAuth connection not found for the given connection_id",
|
|
669
712
|
errorData
|
|
670
713
|
);
|
|
671
714
|
}
|
|
@@ -711,22 +754,24 @@ var AlterVault = class _AlterVault {
|
|
|
711
754
|
* This is a private method. Tokens are NEVER exposed to developers.
|
|
712
755
|
* Use request() instead, which handles tokens internally.
|
|
713
756
|
*/
|
|
714
|
-
async #getToken(
|
|
757
|
+
async #getToken(connectionId, reason, requestMetadata, runId, threadId, toolCallId) {
|
|
715
758
|
const actorHeaders = this.#getActorRequestHeaders(
|
|
716
759
|
runId,
|
|
717
760
|
threadId,
|
|
718
761
|
toolCallId
|
|
719
762
|
);
|
|
720
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));
|
|
721
771
|
try {
|
|
722
|
-
response = await this.#alterClient.post(
|
|
723
|
-
json:
|
|
724
|
-
|
|
725
|
-
attributes,
|
|
726
|
-
reason: reason ?? null,
|
|
727
|
-
request: requestMetadata ?? null
|
|
728
|
-
},
|
|
729
|
-
headers: actorHeaders
|
|
772
|
+
response = await this.#alterClient.post(tokenPath, {
|
|
773
|
+
json: tokenBody,
|
|
774
|
+
headers: { ...actorHeaders, ...hmacHeaders }
|
|
730
775
|
});
|
|
731
776
|
} catch (error) {
|
|
732
777
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -743,7 +788,7 @@ var AlterVault = class _AlterVault {
|
|
|
743
788
|
}
|
|
744
789
|
throw new TokenRetrievalError(
|
|
745
790
|
`Failed to retrieve token: ${error instanceof Error ? error.message : String(error)}`,
|
|
746
|
-
{
|
|
791
|
+
{ connection_id: connectionId, error: String(error) }
|
|
747
792
|
);
|
|
748
793
|
}
|
|
749
794
|
this.#cacheActorIdFromResponse(response);
|
|
@@ -751,6 +796,18 @@ var AlterVault = class _AlterVault {
|
|
|
751
796
|
const tokenData = await response.json();
|
|
752
797
|
const typedData = tokenData;
|
|
753
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
|
+
}
|
|
754
811
|
_storeAccessToken(tokenResponse, typedData.access_token);
|
|
755
812
|
return tokenResponse;
|
|
756
813
|
}
|
|
@@ -779,10 +836,13 @@ var AlterVault = class _AlterVault {
|
|
|
779
836
|
toolCallId: params.toolCallId
|
|
780
837
|
});
|
|
781
838
|
const sanitized = auditLog.sanitize();
|
|
782
|
-
const actorHeaders = this.#getActorRequestHeaders();
|
|
783
|
-
const
|
|
784
|
-
|
|
785
|
-
|
|
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 }
|
|
786
846
|
});
|
|
787
847
|
this.#cacheActorIdFromResponse(response);
|
|
788
848
|
if (!response.ok) {
|
|
@@ -848,13 +908,13 @@ var AlterVault = class _AlterVault {
|
|
|
848
908
|
* 4. Logs the call for audit (fire-and-forget)
|
|
849
909
|
* 5. Returns the raw response
|
|
850
910
|
*/
|
|
851
|
-
async request(
|
|
911
|
+
async request(connectionId, method, url, options) {
|
|
852
912
|
if (this.#closed) {
|
|
853
913
|
throw new AlterSDKError(
|
|
854
914
|
"SDK instance has been closed. Create a new AlterVault instance to make requests."
|
|
855
915
|
);
|
|
856
916
|
}
|
|
857
|
-
const
|
|
917
|
+
const runId = options?.runId ?? (0, import_node_crypto.randomUUID)();
|
|
858
918
|
const methodStr = String(method).toUpperCase();
|
|
859
919
|
const urlLower = url.toLowerCase();
|
|
860
920
|
if (!ALLOWED_URL_SCHEMES.some((scheme) => urlLower.startsWith(scheme))) {
|
|
@@ -862,7 +922,7 @@ var AlterVault = class _AlterVault {
|
|
|
862
922
|
`URL must start with https:// or http://, got: ${url.slice(0, 50)}`
|
|
863
923
|
);
|
|
864
924
|
}
|
|
865
|
-
if (options
|
|
925
|
+
if (options?.pathParams && Object.keys(options.pathParams).length > 0) {
|
|
866
926
|
const encodedParams = {};
|
|
867
927
|
for (const [key, value] of Object.entries(options.pathParams)) {
|
|
868
928
|
encodedParams[key] = encodeURIComponent(String(value));
|
|
@@ -892,22 +952,25 @@ var AlterVault = class _AlterVault {
|
|
|
892
952
|
);
|
|
893
953
|
}
|
|
894
954
|
}
|
|
895
|
-
if (options.extraHeaders && "Authorization" in options.extraHeaders) {
|
|
896
|
-
console.warn(
|
|
897
|
-
"extraHeaders contains 'Authorization' which will be overwritten with the auto-injected Bearer token"
|
|
898
|
-
);
|
|
899
|
-
}
|
|
900
955
|
const tokenResponse = await this.#getToken(
|
|
901
|
-
|
|
902
|
-
options
|
|
903
|
-
options.reason,
|
|
956
|
+
connectionId,
|
|
957
|
+
options?.reason,
|
|
904
958
|
{ method: methodStr, url },
|
|
905
|
-
|
|
906
|
-
options
|
|
907
|
-
options
|
|
959
|
+
runId,
|
|
960
|
+
options?.threadId,
|
|
961
|
+
options?.toolCallId
|
|
908
962
|
);
|
|
909
|
-
const
|
|
910
|
-
|
|
963
|
+
const injectionHeaderLower = tokenResponse.injectionHeader.toLowerCase();
|
|
964
|
+
if (options?.extraHeaders && Object.keys(options.extraHeaders).some(
|
|
965
|
+
(k) => k.toLowerCase() === injectionHeaderLower
|
|
966
|
+
)) {
|
|
967
|
+
console.warn(
|
|
968
|
+
`extraHeaders contains '${tokenResponse.injectionHeader}' which will be overwritten with the auto-injected credential`
|
|
969
|
+
);
|
|
970
|
+
}
|
|
971
|
+
const requestHeaders = options?.extraHeaders ? { ...options.extraHeaders } : {};
|
|
972
|
+
const accessToken = _extractAccessToken(tokenResponse);
|
|
973
|
+
requestHeaders[tokenResponse.injectionHeader] = tokenResponse.injectionFormat.replace("{token}", accessToken);
|
|
911
974
|
if (!requestHeaders["User-Agent"]) {
|
|
912
975
|
requestHeaders["User-Agent"] = SDK_USER_AGENT;
|
|
913
976
|
}
|
|
@@ -915,16 +978,16 @@ var AlterVault = class _AlterVault {
|
|
|
915
978
|
let response;
|
|
916
979
|
try {
|
|
917
980
|
response = await this.#providerClient.request(methodStr, url, {
|
|
918
|
-
json: options
|
|
981
|
+
json: options?.json,
|
|
919
982
|
headers: requestHeaders,
|
|
920
|
-
params: options
|
|
983
|
+
params: options?.queryParams
|
|
921
984
|
});
|
|
922
985
|
} catch (error) {
|
|
923
986
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
924
987
|
throw new TimeoutError(
|
|
925
988
|
`Provider API request timed out: ${error instanceof Error ? error.message : String(error)}`,
|
|
926
989
|
{
|
|
927
|
-
|
|
990
|
+
connection_id: connectionId,
|
|
928
991
|
method: methodStr,
|
|
929
992
|
url
|
|
930
993
|
}
|
|
@@ -933,7 +996,7 @@ var AlterVault = class _AlterVault {
|
|
|
933
996
|
throw new NetworkError(
|
|
934
997
|
`Failed to call provider API: ${error instanceof Error ? error.message : String(error)}`,
|
|
935
998
|
{
|
|
936
|
-
|
|
999
|
+
connection_id: connectionId,
|
|
937
1000
|
method: methodStr,
|
|
938
1001
|
url,
|
|
939
1002
|
error: String(error)
|
|
@@ -943,7 +1006,7 @@ var AlterVault = class _AlterVault {
|
|
|
943
1006
|
const latencyMs = Date.now() - startTime;
|
|
944
1007
|
const auditHeaders = {};
|
|
945
1008
|
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
946
|
-
if (key.toLowerCase() !==
|
|
1009
|
+
if (key.toLowerCase() !== injectionHeaderLower) {
|
|
947
1010
|
auditHeaders[key] = value;
|
|
948
1011
|
}
|
|
949
1012
|
}
|
|
@@ -954,19 +1017,19 @@ var AlterVault = class _AlterVault {
|
|
|
954
1017
|
});
|
|
955
1018
|
this.#scheduleAuditLog({
|
|
956
1019
|
connectionId: tokenResponse.connectionId,
|
|
957
|
-
providerId:
|
|
1020
|
+
providerId: tokenResponse.providerId || connectionId,
|
|
958
1021
|
method: methodStr,
|
|
959
1022
|
url,
|
|
960
1023
|
requestHeaders: auditHeaders,
|
|
961
|
-
requestBody: options
|
|
1024
|
+
requestBody: options?.json ?? null,
|
|
962
1025
|
responseStatus: response.status,
|
|
963
1026
|
responseHeaders,
|
|
964
1027
|
responseBody,
|
|
965
1028
|
latencyMs,
|
|
966
|
-
reason: options
|
|
967
|
-
runId
|
|
968
|
-
threadId: options
|
|
969
|
-
toolCallId: options
|
|
1029
|
+
reason: options?.reason ?? null,
|
|
1030
|
+
runId,
|
|
1031
|
+
threadId: options?.threadId ?? null,
|
|
1032
|
+
toolCallId: options?.toolCallId ?? null
|
|
970
1033
|
});
|
|
971
1034
|
if (response.status >= HTTP_CLIENT_ERROR_START) {
|
|
972
1035
|
throw new ProviderAPIError(
|
|
@@ -974,7 +1037,7 @@ var AlterVault = class _AlterVault {
|
|
|
974
1037
|
response.status,
|
|
975
1038
|
responseBody,
|
|
976
1039
|
{
|
|
977
|
-
|
|
1040
|
+
connection_id: connectionId,
|
|
978
1041
|
method: methodStr,
|
|
979
1042
|
url
|
|
980
1043
|
}
|
|
@@ -996,14 +1059,17 @@ var AlterVault = class _AlterVault {
|
|
|
996
1059
|
}
|
|
997
1060
|
const actorHeaders = this.#getActorRequestHeaders();
|
|
998
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));
|
|
999
1069
|
try {
|
|
1000
|
-
response = await this.#alterClient.post(
|
|
1001
|
-
json:
|
|
1002
|
-
|
|
1003
|
-
limit: options?.limit ?? 100,
|
|
1004
|
-
offset: options?.offset ?? 0
|
|
1005
|
-
},
|
|
1006
|
-
headers: actorHeaders
|
|
1070
|
+
response = await this.#alterClient.post(listPath, {
|
|
1071
|
+
json: listBody,
|
|
1072
|
+
headers: { ...actorHeaders, ...listHmac }
|
|
1007
1073
|
});
|
|
1008
1074
|
} catch (error) {
|
|
1009
1075
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -1054,17 +1120,19 @@ var AlterVault = class _AlterVault {
|
|
|
1054
1120
|
}
|
|
1055
1121
|
const actorHeaders = this.#getActorRequestHeaders();
|
|
1056
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));
|
|
1057
1132
|
try {
|
|
1058
|
-
response = await this.#alterClient.post(
|
|
1059
|
-
json:
|
|
1060
|
-
|
|
1061
|
-
attributes: options.attributes ?? null,
|
|
1062
|
-
allowed_providers: options.allowedProviders ?? null,
|
|
1063
|
-
return_url: options.returnUrl ?? null,
|
|
1064
|
-
allowed_origin: options.allowedOrigin ?? null,
|
|
1065
|
-
metadata: options.metadata ?? null
|
|
1066
|
-
},
|
|
1067
|
-
headers: actorHeaders
|
|
1133
|
+
response = await this.#alterClient.post(sessionPath, {
|
|
1134
|
+
json: sessionBody,
|
|
1135
|
+
headers: { ...actorHeaders, ...sessionHmac }
|
|
1068
1136
|
});
|
|
1069
1137
|
} catch (error) {
|
|
1070
1138
|
if (_AlterVault.#isTimeoutOrAbortError(error)) {
|
|
@@ -1116,8 +1184,6 @@ var Provider = /* @__PURE__ */ ((Provider2) => {
|
|
|
1116
1184
|
Provider2["GOOGLE"] = "google";
|
|
1117
1185
|
Provider2["GITHUB"] = "github";
|
|
1118
1186
|
Provider2["SLACK"] = "slack";
|
|
1119
|
-
Provider2["MICROSOFT"] = "microsoft";
|
|
1120
|
-
Provider2["SALESFORCE"] = "salesforce";
|
|
1121
1187
|
Provider2["SENTRY"] = "sentry";
|
|
1122
1188
|
return Provider2;
|
|
1123
1189
|
})(Provider || {});
|
|
@@ -1134,6 +1200,7 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
|
|
|
1134
1200
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1135
1201
|
0 && (module.exports = {
|
|
1136
1202
|
APICallAuditLog,
|
|
1203
|
+
ActorType,
|
|
1137
1204
|
AlterSDKError,
|
|
1138
1205
|
AlterVault,
|
|
1139
1206
|
ConnectSession,
|
package/dist/index.d.cts
CHANGED
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
* - TokenResponse: Object.freeze(this) prevents mutation after creation
|
|
10
10
|
* - toJSON() and toString() exclude access token from serialization
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Actor types for tracking SDK callers.
|
|
14
|
+
*/
|
|
15
|
+
declare enum ActorType {
|
|
16
|
+
BACKEND_SERVICE = "backend_service",
|
|
17
|
+
AI_AGENT = "ai_agent",
|
|
18
|
+
MCP_SERVER = "mcp_server"
|
|
19
|
+
}
|
|
12
20
|
/**
|
|
13
21
|
* OAuth token response from Alter Vault.
|
|
14
22
|
*
|
|
@@ -34,6 +42,12 @@ declare class TokenResponse {
|
|
|
34
42
|
readonly scopes: string[];
|
|
35
43
|
/** Connection ID that provided this token */
|
|
36
44
|
readonly connectionId: string;
|
|
45
|
+
/** Provider ID (google, github, etc.) */
|
|
46
|
+
readonly providerId: string;
|
|
47
|
+
/** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
|
|
48
|
+
readonly injectionHeader: string;
|
|
49
|
+
/** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
|
|
50
|
+
readonly injectionFormat: string;
|
|
37
51
|
constructor(data: {
|
|
38
52
|
access_token: string;
|
|
39
53
|
token_type?: string;
|
|
@@ -41,6 +55,9 @@ declare class TokenResponse {
|
|
|
41
55
|
expires_at?: string | null;
|
|
42
56
|
scopes?: string[];
|
|
43
57
|
connection_id: string;
|
|
58
|
+
provider_id?: string;
|
|
59
|
+
injection_header?: string;
|
|
60
|
+
injection_format?: string;
|
|
44
61
|
});
|
|
45
62
|
/**
|
|
46
63
|
* Parse expires_at from ISO string.
|
|
@@ -80,7 +97,6 @@ declare class TokenResponse {
|
|
|
80
97
|
declare class ConnectionInfo {
|
|
81
98
|
readonly id: string;
|
|
82
99
|
readonly providerId: string;
|
|
83
|
-
readonly attributes: Record<string, unknown>;
|
|
84
100
|
readonly scopes: string[];
|
|
85
101
|
readonly accountIdentifier: string | null;
|
|
86
102
|
readonly accountDisplayName: string | null;
|
|
@@ -91,7 +107,6 @@ declare class ConnectionInfo {
|
|
|
91
107
|
constructor(data: {
|
|
92
108
|
id: string;
|
|
93
109
|
provider_id: string;
|
|
94
|
-
attributes?: Record<string, unknown>;
|
|
95
110
|
scopes?: string[];
|
|
96
111
|
account_identifier?: string | null;
|
|
97
112
|
account_display_name?: string | null;
|
|
@@ -231,8 +246,6 @@ declare enum Provider {
|
|
|
231
246
|
GOOGLE = "google",
|
|
232
247
|
GITHUB = "github",
|
|
233
248
|
SLACK = "slack",
|
|
234
|
-
MICROSOFT = "microsoft",
|
|
235
|
-
SALESFORCE = "salesforce",
|
|
236
249
|
SENTRY = "sentry"
|
|
237
250
|
}
|
|
238
251
|
/**
|
|
@@ -265,14 +278,12 @@ declare enum HttpMethod {
|
|
|
265
278
|
interface AlterVaultOptions {
|
|
266
279
|
/** Alter Vault API key (must start with "alter_key_") */
|
|
267
280
|
apiKey: string;
|
|
268
|
-
/** Base URL for Alter Vault API */
|
|
269
|
-
baseUrl?: string;
|
|
270
281
|
/** HTTP request timeout in milliseconds (default: 30000) */
|
|
271
282
|
timeout?: number;
|
|
272
|
-
/** Actor type (
|
|
273
|
-
actorType
|
|
283
|
+
/** Actor type (use ActorType enum: AI_AGENT, MCP_SERVER, BACKEND_SERVICE) */
|
|
284
|
+
actorType: ActorType | string;
|
|
274
285
|
/** Unique identifier for the actor (e.g., "email-assistant-v2") */
|
|
275
|
-
actorIdentifier
|
|
286
|
+
actorIdentifier: string;
|
|
276
287
|
/** Human-readable name for the actor */
|
|
277
288
|
actorName?: string;
|
|
278
289
|
/** Actor version string (e.g., "1.0.0") */
|
|
@@ -286,8 +297,6 @@ interface AlterVaultOptions {
|
|
|
286
297
|
* Options for the request() method.
|
|
287
298
|
*/
|
|
288
299
|
interface RequestOptions {
|
|
289
|
-
/** User attributes to match connection (e.g., { user_id: "alice" }) */
|
|
290
|
-
user: Record<string, unknown>;
|
|
291
300
|
/** Optional JSON request body */
|
|
292
301
|
json?: Record<string, unknown>;
|
|
293
302
|
/** Optional additional headers */
|
|
@@ -326,8 +335,6 @@ interface CreateConnectSessionOptions {
|
|
|
326
335
|
email?: string;
|
|
327
336
|
name?: string;
|
|
328
337
|
};
|
|
329
|
-
/** User attributes for connection matching */
|
|
330
|
-
attributes?: Record<string, unknown>;
|
|
331
338
|
/** Restrict to specific providers (e.g., ["google", "github"]) */
|
|
332
339
|
allowedProviders?: string[];
|
|
333
340
|
/** URL to redirect after OAuth completion */
|
|
@@ -358,9 +365,8 @@ interface CreateConnectSessionOptions {
|
|
|
358
365
|
*
|
|
359
366
|
* // Make API request (token injected automatically)
|
|
360
367
|
* const response = await vault.request(
|
|
361
|
-
*
|
|
368
|
+
* "connection-uuid-here", HttpMethod.GET,
|
|
362
369
|
* "https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
363
|
-
* { user: { user_id: "alice" } },
|
|
364
370
|
* );
|
|
365
371
|
* const events = await response.json();
|
|
366
372
|
*
|
|
@@ -382,7 +388,7 @@ declare class AlterVault {
|
|
|
382
388
|
* 4. Logs the call for audit (fire-and-forget)
|
|
383
389
|
* 5. Returns the raw response
|
|
384
390
|
*/
|
|
385
|
-
request(
|
|
391
|
+
request(connectionId: string, method: HttpMethod | string, url: string, options?: RequestOptions): Promise<Response>;
|
|
386
392
|
/**
|
|
387
393
|
* List OAuth connections for this app.
|
|
388
394
|
*
|
|
@@ -440,7 +446,7 @@ declare class PolicyViolationError extends TokenRetrievalError {
|
|
|
440
446
|
/**
|
|
441
447
|
* Raised when OAuth connection not found.
|
|
442
448
|
*
|
|
443
|
-
* This indicates no connection exists for the given
|
|
449
|
+
* This indicates no connection exists for the given connection_id.
|
|
444
450
|
*/
|
|
445
451
|
declare class ConnectionNotFoundError extends TokenRetrievalError {
|
|
446
452
|
constructor(message: string, details?: Record<string, unknown>);
|
|
@@ -487,4 +493,4 @@ declare class TimeoutError extends NetworkError {
|
|
|
487
493
|
constructor(message: string, details?: Record<string, unknown>);
|
|
488
494
|
}
|
|
489
495
|
|
|
490
|
-
export { APICallAuditLog, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
|
|
496
|
+
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
|