@alter-ai/alter-sdk 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -10
- package/dist/index.cjs +42 -20
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +42 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ Official TypeScript SDK for [Alter Vault](https://alterai.dev) -Credential manag
|
|
|
13
13
|
- **Automatic Token Refresh**: Tokens refreshed transparently by the backend
|
|
14
14
|
- **API Key and Custom Credential Support**: Handles OAuth tokens, API keys, and custom credential formats automatically
|
|
15
15
|
- **Actor Tracking**: First-class support for AI agent and MCP server observability
|
|
16
|
-
- **HMAC Request Signing**: All SDK-to-backend requests are signed
|
|
16
|
+
- **HMAC Request Signing**: All SDK-to-backend requests are cryptographically signed for integrity, authenticity, and replay protection
|
|
17
17
|
- **Native Promises**: Built on native `fetch` -no heavy dependencies
|
|
18
18
|
|
|
19
19
|
## Installation
|
|
@@ -37,7 +37,7 @@ const vault = new AlterVault({
|
|
|
37
37
|
const response = await vault.request(
|
|
38
38
|
"CONNECTION_ID", // from Alter Connect (see below)
|
|
39
39
|
HttpMethod.GET,
|
|
40
|
-
"https://
|
|
40
|
+
"https://api.example.com/v1/resource",
|
|
41
41
|
{
|
|
42
42
|
queryParams: { maxResults: "10" },
|
|
43
43
|
},
|
|
@@ -66,7 +66,7 @@ await vault.close();
|
|
|
66
66
|
// You can also discover connectionIds programmatically:
|
|
67
67
|
const result = await vault.listConnections({ providerId: "google" });
|
|
68
68
|
for (const conn of result.connections) {
|
|
69
|
-
console.log(`${conn.
|
|
69
|
+
console.log(`${conn.connectionId}: ${conn.accountDisplayName}`);
|
|
70
70
|
}
|
|
71
71
|
```
|
|
72
72
|
|
|
@@ -80,7 +80,7 @@ The `request()` method returns the raw `Response` object. The token is injected
|
|
|
80
80
|
const response = await vault.request(
|
|
81
81
|
connectionId,
|
|
82
82
|
HttpMethod.GET,
|
|
83
|
-
"https://
|
|
83
|
+
"https://api.example.com/v1/resource",
|
|
84
84
|
);
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -221,7 +221,7 @@ for (const result of results) {
|
|
|
221
221
|
const response = await vault.request(
|
|
222
222
|
results[0].connectionId,
|
|
223
223
|
HttpMethod.GET,
|
|
224
|
-
"https://
|
|
224
|
+
"https://api.example.com/v1/resource",
|
|
225
225
|
);
|
|
226
226
|
```
|
|
227
227
|
|
|
@@ -254,7 +254,7 @@ const vault = new AlterVault({
|
|
|
254
254
|
const response = await vault.request(
|
|
255
255
|
connectionId,
|
|
256
256
|
HttpMethod.GET,
|
|
257
|
-
"https://
|
|
257
|
+
"https://api.example.com/v1/resource",
|
|
258
258
|
{
|
|
259
259
|
runId: "550e8400-e29b-41d4-a716-446655440000", // auto-generated UUID if omitted
|
|
260
260
|
threadId: "thread-xyz",
|
|
@@ -289,12 +289,12 @@ const calendarAgent = new AlterVault({
|
|
|
289
289
|
await emailAgent.request(
|
|
290
290
|
gmailConnectionId, // from Alter Connect
|
|
291
291
|
HttpMethod.GET,
|
|
292
|
-
"https://
|
|
292
|
+
"https://api.example.com/v1/messages",
|
|
293
293
|
);
|
|
294
294
|
await calendarAgent.request(
|
|
295
295
|
calendarConnectionId, // from Alter Connect
|
|
296
296
|
HttpMethod.GET,
|
|
297
|
-
"https://
|
|
297
|
+
"https://api.example.com/v1/resource",
|
|
298
298
|
);
|
|
299
299
|
|
|
300
300
|
// Clean up each instance
|
|
@@ -370,7 +370,7 @@ try {
|
|
|
370
370
|
const response = await vault.request(
|
|
371
371
|
connectionId,
|
|
372
372
|
HttpMethod.GET,
|
|
373
|
-
"https://
|
|
373
|
+
"https://api.example.com/v1/resource",
|
|
374
374
|
);
|
|
375
375
|
} catch (error) {
|
|
376
376
|
// --- Connection unusable — user must re-authorize via Alter Connect ---
|
|
@@ -390,7 +390,7 @@ try {
|
|
|
390
390
|
|
|
391
391
|
// --- Policy restrictions — may resolve on its own ---
|
|
392
392
|
} else if (error instanceof PolicyViolationError) {
|
|
393
|
-
// Business hours, IP allowlist, or other
|
|
393
|
+
// Business hours, IP allowlist, or other policy denial
|
|
394
394
|
console.error(`Policy denied: ${error.message} (reason: ${error.policyError})`);
|
|
395
395
|
|
|
396
396
|
// --- Transient / infrastructure errors — safe to retry ---
|
|
@@ -404,6 +404,8 @@ try {
|
|
|
404
404
|
// Create a new Connect session so the user can grant updated scopes
|
|
405
405
|
} else if (error instanceof ProviderAPIError) {
|
|
406
406
|
console.error(`Provider error ${error.statusCode}: ${error.responseBody}`);
|
|
407
|
+
} else {
|
|
408
|
+
throw error;
|
|
407
409
|
}
|
|
408
410
|
}
|
|
409
411
|
```
|
package/dist/index.cjs
CHANGED
|
@@ -270,7 +270,8 @@ var TokenResponse = class _TokenResponse {
|
|
|
270
270
|
expires_in: this.expiresIn,
|
|
271
271
|
expires_at: this.expiresAt?.toISOString() ?? null,
|
|
272
272
|
scopes: this.scopes,
|
|
273
|
-
connection_id: this.connectionId
|
|
273
|
+
connection_id: this.connectionId,
|
|
274
|
+
provider_id: this.providerId
|
|
274
275
|
};
|
|
275
276
|
}
|
|
276
277
|
/**
|
|
@@ -287,7 +288,7 @@ var TokenResponse = class _TokenResponse {
|
|
|
287
288
|
}
|
|
288
289
|
};
|
|
289
290
|
var ConnectionInfo = class {
|
|
290
|
-
|
|
291
|
+
connectionId;
|
|
291
292
|
providerId;
|
|
292
293
|
scopes;
|
|
293
294
|
accountIdentifier;
|
|
@@ -298,7 +299,7 @@ var ConnectionInfo = class {
|
|
|
298
299
|
createdAt;
|
|
299
300
|
lastUsedAt;
|
|
300
301
|
constructor(data) {
|
|
301
|
-
this.
|
|
302
|
+
this.connectionId = data.connection_id;
|
|
302
303
|
this.providerId = data.provider_id;
|
|
303
304
|
this.scopes = data.scopes ?? [];
|
|
304
305
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
@@ -312,7 +313,7 @@ var ConnectionInfo = class {
|
|
|
312
313
|
}
|
|
313
314
|
toJSON() {
|
|
314
315
|
return {
|
|
315
|
-
|
|
316
|
+
connection_id: this.connectionId,
|
|
316
317
|
provider_id: this.providerId,
|
|
317
318
|
scopes: this.scopes,
|
|
318
319
|
account_identifier: this.accountIdentifier,
|
|
@@ -325,7 +326,7 @@ var ConnectionInfo = class {
|
|
|
325
326
|
};
|
|
326
327
|
}
|
|
327
328
|
toString() {
|
|
328
|
-
return `ConnectionInfo(
|
|
329
|
+
return `ConnectionInfo(connection_id=${this.connectionId}, provider=${this.providerId}, status=${this.status})`;
|
|
329
330
|
}
|
|
330
331
|
};
|
|
331
332
|
var ConnectSession = class {
|
|
@@ -378,7 +379,17 @@ var ConnectResult = class {
|
|
|
378
379
|
this.providerId = data.provider_id;
|
|
379
380
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
380
381
|
this.scopes = data.scopes ?? [];
|
|
381
|
-
|
|
382
|
+
const rawPolicy = data.connection_policy;
|
|
383
|
+
if (rawPolicy) {
|
|
384
|
+
const raw = rawPolicy;
|
|
385
|
+
this.connectionPolicy = Object.freeze({
|
|
386
|
+
expiresAt: raw["expires_at"] !== void 0 ? raw["expires_at"] : rawPolicy.expiresAt ?? null,
|
|
387
|
+
createdBy: raw["created_by"] !== void 0 ? raw["created_by"] : rawPolicy.createdBy ?? null,
|
|
388
|
+
createdAt: raw["created_at"] !== void 0 ? raw["created_at"] : rawPolicy.createdAt ?? null
|
|
389
|
+
});
|
|
390
|
+
} else {
|
|
391
|
+
this.connectionPolicy = null;
|
|
392
|
+
}
|
|
382
393
|
Object.freeze(this);
|
|
383
394
|
}
|
|
384
395
|
toJSON() {
|
|
@@ -387,7 +398,11 @@ var ConnectResult = class {
|
|
|
387
398
|
provider_id: this.providerId,
|
|
388
399
|
account_identifier: this.accountIdentifier,
|
|
389
400
|
scopes: this.scopes,
|
|
390
|
-
connection_policy: this.connectionPolicy
|
|
401
|
+
connection_policy: this.connectionPolicy ? {
|
|
402
|
+
expires_at: this.connectionPolicy.expiresAt ?? null,
|
|
403
|
+
created_by: this.connectionPolicy.createdBy ?? null,
|
|
404
|
+
created_at: this.connectionPolicy.createdAt ?? null
|
|
405
|
+
} : null
|
|
391
406
|
};
|
|
392
407
|
}
|
|
393
408
|
toString() {
|
|
@@ -401,7 +416,8 @@ var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
|
401
416
|
"x-api-key",
|
|
402
417
|
"x-auth-token",
|
|
403
418
|
"x-amz-date",
|
|
404
|
-
"x-amz-content-sha256"
|
|
419
|
+
"x-amz-content-sha256",
|
|
420
|
+
"x-amz-security-token"
|
|
405
421
|
]);
|
|
406
422
|
var APICallAuditLog = class {
|
|
407
423
|
connectionId;
|
|
@@ -480,6 +496,7 @@ var import_node_crypto = require("crypto");
|
|
|
480
496
|
var ALGORITHM = "AWS4-HMAC-SHA256";
|
|
481
497
|
var AWS_HOST_RE = /^(?<service>[a-z0-9-]+)\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.amazonaws\.com$/;
|
|
482
498
|
var S3_VIRTUAL_HOST_RE = /^[^.]+\.s3\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.amazonaws\.com$/;
|
|
499
|
+
var VPCE_HOST_RE = /^vpce-[a-z0-9-]+\.(?<service>[a-z0-9-]+)\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.vpce\.amazonaws\.com$/;
|
|
483
500
|
function hmacSha256(key, message) {
|
|
484
501
|
return (0, import_node_crypto.createHmac)("sha256", key).update(message, "utf8").digest();
|
|
485
502
|
}
|
|
@@ -502,6 +519,10 @@ function detectServiceAndRegion(hostname) {
|
|
|
502
519
|
if (s3m?.groups) {
|
|
503
520
|
return { service: "s3", region: s3m.groups.region };
|
|
504
521
|
}
|
|
522
|
+
const vpcem = VPCE_HOST_RE.exec(lower);
|
|
523
|
+
if (vpcem?.groups) {
|
|
524
|
+
return { service: vpcem.groups.service, region: vpcem.groups.region };
|
|
525
|
+
}
|
|
505
526
|
return { service: null, region: null };
|
|
506
527
|
}
|
|
507
528
|
function deriveSigningKey(secretKey, dateStamp, region, service) {
|
|
@@ -536,18 +557,21 @@ function canonicalQueryString(query) {
|
|
|
536
557
|
]);
|
|
537
558
|
}
|
|
538
559
|
}
|
|
539
|
-
|
|
560
|
+
const sigv4Encode = (s) => encodeURIComponent(s).replace(
|
|
561
|
+
/[!'()*]/g,
|
|
562
|
+
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
563
|
+
);
|
|
564
|
+
const encoded = sorted.map(
|
|
565
|
+
([k, v]) => [sigv4Encode(k), sigv4Encode(v)]
|
|
566
|
+
);
|
|
567
|
+
encoded.sort((a, b) => {
|
|
540
568
|
if (a[0] < b[0]) return -1;
|
|
541
569
|
if (a[0] > b[0]) return 1;
|
|
542
570
|
if (a[1] < b[1]) return -1;
|
|
543
571
|
if (a[1] > b[1]) return 1;
|
|
544
572
|
return 0;
|
|
545
573
|
});
|
|
546
|
-
|
|
547
|
-
/[!'()*]/g,
|
|
548
|
-
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
549
|
-
);
|
|
550
|
-
return sorted.map(([k, v]) => `${sigv4Encode(k)}=${sigv4Encode(v)}`).join("&");
|
|
574
|
+
return encoded.map(([k, v]) => `${k}=${v}`).join("&");
|
|
551
575
|
}
|
|
552
576
|
function canonicalHeadersAndSigned(headers) {
|
|
553
577
|
const canonical = {};
|
|
@@ -566,11 +590,9 @@ function signAwsRequest(opts) {
|
|
|
566
590
|
const parsed = new URL(opts.url);
|
|
567
591
|
const hostname = parsed.hostname;
|
|
568
592
|
let { region, service } = opts;
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
if (service == null) service = detected.service;
|
|
573
|
-
}
|
|
593
|
+
const detected = detectServiceAndRegion(hostname);
|
|
594
|
+
if (detected.region != null) region = detected.region;
|
|
595
|
+
if (detected.service != null) service = detected.service;
|
|
574
596
|
if (!region) {
|
|
575
597
|
throw new Error(
|
|
576
598
|
`Cannot determine AWS region from URL '${opts.url}'. Pass region explicitly via additional_credentials.`
|
|
@@ -653,7 +675,7 @@ function _extractAdditionalCredentials(token) {
|
|
|
653
675
|
return _additionalCredsStore.get(token);
|
|
654
676
|
}
|
|
655
677
|
var _fetch;
|
|
656
|
-
var SDK_VERSION = "0.
|
|
678
|
+
var SDK_VERSION = "0.6.0";
|
|
657
679
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
658
680
|
var HTTP_FORBIDDEN = 403;
|
|
659
681
|
var HTTP_NOT_FOUND = 404;
|
package/dist/index.d.cts
CHANGED
|
@@ -109,7 +109,7 @@ declare class TokenResponse {
|
|
|
109
109
|
* Returned by listConnections(). Contains metadata only — no tokens.
|
|
110
110
|
*/
|
|
111
111
|
declare class ConnectionInfo {
|
|
112
|
-
readonly
|
|
112
|
+
readonly connectionId: string;
|
|
113
113
|
readonly providerId: string;
|
|
114
114
|
readonly scopes: string[];
|
|
115
115
|
readonly accountIdentifier: string | null;
|
|
@@ -120,7 +120,7 @@ declare class ConnectionInfo {
|
|
|
120
120
|
readonly createdAt: string;
|
|
121
121
|
readonly lastUsedAt: string | null;
|
|
122
122
|
constructor(data: {
|
|
123
|
-
|
|
123
|
+
connection_id: string;
|
|
124
124
|
provider_id: string;
|
|
125
125
|
scopes?: string[];
|
|
126
126
|
account_identifier?: string | null;
|
|
@@ -185,11 +185,11 @@ declare class ConnectionListResult {
|
|
|
185
185
|
*/
|
|
186
186
|
interface ConnectionPolicy {
|
|
187
187
|
/** Hard expiry timestamp (ISO 8601 UTC) */
|
|
188
|
-
|
|
188
|
+
readonly expiresAt?: string | null;
|
|
189
189
|
/** Who set the policy: 'developer' or 'end_user' */
|
|
190
|
-
|
|
190
|
+
readonly createdBy?: string | null;
|
|
191
191
|
/** When the policy was set (ISO 8601 UTC) */
|
|
192
|
-
|
|
192
|
+
readonly createdAt?: string | null;
|
|
193
193
|
}
|
|
194
194
|
declare class ConnectResult {
|
|
195
195
|
readonly connectionId: string;
|
|
@@ -767,4 +767,4 @@ declare class TimeoutError extends NetworkError {
|
|
|
767
767
|
constructor(message: string, details?: Record<string, unknown>);
|
|
768
768
|
}
|
|
769
769
|
|
|
770
|
-
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, BackendError, ConnectConfigError, ConnectDeniedError, ConnectFlowError, type ConnectOptions, ConnectResult, ConnectSession, ConnectTimeoutError, ConnectionDeletedError, ConnectionExpiredError, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, ConnectionRevokedError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, ReAuthRequiredError, type RequestOptions, ScopeReauthRequiredError, TimeoutError, TokenResponse };
|
|
770
|
+
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, BackendError, ConnectConfigError, ConnectDeniedError, ConnectFlowError, type ConnectOptions, ConnectResult, ConnectSession, ConnectTimeoutError, ConnectionDeletedError, ConnectionExpiredError, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type ConnectionPolicy, ConnectionRevokedError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, ReAuthRequiredError, type RequestOptions, ScopeReauthRequiredError, TimeoutError, TokenResponse };
|
package/dist/index.d.ts
CHANGED
|
@@ -109,7 +109,7 @@ declare class TokenResponse {
|
|
|
109
109
|
* Returned by listConnections(). Contains metadata only — no tokens.
|
|
110
110
|
*/
|
|
111
111
|
declare class ConnectionInfo {
|
|
112
|
-
readonly
|
|
112
|
+
readonly connectionId: string;
|
|
113
113
|
readonly providerId: string;
|
|
114
114
|
readonly scopes: string[];
|
|
115
115
|
readonly accountIdentifier: string | null;
|
|
@@ -120,7 +120,7 @@ declare class ConnectionInfo {
|
|
|
120
120
|
readonly createdAt: string;
|
|
121
121
|
readonly lastUsedAt: string | null;
|
|
122
122
|
constructor(data: {
|
|
123
|
-
|
|
123
|
+
connection_id: string;
|
|
124
124
|
provider_id: string;
|
|
125
125
|
scopes?: string[];
|
|
126
126
|
account_identifier?: string | null;
|
|
@@ -185,11 +185,11 @@ declare class ConnectionListResult {
|
|
|
185
185
|
*/
|
|
186
186
|
interface ConnectionPolicy {
|
|
187
187
|
/** Hard expiry timestamp (ISO 8601 UTC) */
|
|
188
|
-
|
|
188
|
+
readonly expiresAt?: string | null;
|
|
189
189
|
/** Who set the policy: 'developer' or 'end_user' */
|
|
190
|
-
|
|
190
|
+
readonly createdBy?: string | null;
|
|
191
191
|
/** When the policy was set (ISO 8601 UTC) */
|
|
192
|
-
|
|
192
|
+
readonly createdAt?: string | null;
|
|
193
193
|
}
|
|
194
194
|
declare class ConnectResult {
|
|
195
195
|
readonly connectionId: string;
|
|
@@ -767,4 +767,4 @@ declare class TimeoutError extends NetworkError {
|
|
|
767
767
|
constructor(message: string, details?: Record<string, unknown>);
|
|
768
768
|
}
|
|
769
769
|
|
|
770
|
-
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, BackendError, ConnectConfigError, ConnectDeniedError, ConnectFlowError, type ConnectOptions, ConnectResult, ConnectSession, ConnectTimeoutError, ConnectionDeletedError, ConnectionExpiredError, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, ConnectionRevokedError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, ReAuthRequiredError, type RequestOptions, ScopeReauthRequiredError, TimeoutError, TokenResponse };
|
|
770
|
+
export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, BackendError, ConnectConfigError, ConnectDeniedError, ConnectFlowError, type ConnectOptions, ConnectResult, ConnectSession, ConnectTimeoutError, ConnectionDeletedError, ConnectionExpiredError, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type ConnectionPolicy, ConnectionRevokedError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, ReAuthRequiredError, type RequestOptions, ScopeReauthRequiredError, TimeoutError, TokenResponse };
|
package/dist/index.js
CHANGED
|
@@ -209,7 +209,8 @@ var TokenResponse = class _TokenResponse {
|
|
|
209
209
|
expires_in: this.expiresIn,
|
|
210
210
|
expires_at: this.expiresAt?.toISOString() ?? null,
|
|
211
211
|
scopes: this.scopes,
|
|
212
|
-
connection_id: this.connectionId
|
|
212
|
+
connection_id: this.connectionId,
|
|
213
|
+
provider_id: this.providerId
|
|
213
214
|
};
|
|
214
215
|
}
|
|
215
216
|
/**
|
|
@@ -226,7 +227,7 @@ var TokenResponse = class _TokenResponse {
|
|
|
226
227
|
}
|
|
227
228
|
};
|
|
228
229
|
var ConnectionInfo = class {
|
|
229
|
-
|
|
230
|
+
connectionId;
|
|
230
231
|
providerId;
|
|
231
232
|
scopes;
|
|
232
233
|
accountIdentifier;
|
|
@@ -237,7 +238,7 @@ var ConnectionInfo = class {
|
|
|
237
238
|
createdAt;
|
|
238
239
|
lastUsedAt;
|
|
239
240
|
constructor(data) {
|
|
240
|
-
this.
|
|
241
|
+
this.connectionId = data.connection_id;
|
|
241
242
|
this.providerId = data.provider_id;
|
|
242
243
|
this.scopes = data.scopes ?? [];
|
|
243
244
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
@@ -251,7 +252,7 @@ var ConnectionInfo = class {
|
|
|
251
252
|
}
|
|
252
253
|
toJSON() {
|
|
253
254
|
return {
|
|
254
|
-
|
|
255
|
+
connection_id: this.connectionId,
|
|
255
256
|
provider_id: this.providerId,
|
|
256
257
|
scopes: this.scopes,
|
|
257
258
|
account_identifier: this.accountIdentifier,
|
|
@@ -264,7 +265,7 @@ var ConnectionInfo = class {
|
|
|
264
265
|
};
|
|
265
266
|
}
|
|
266
267
|
toString() {
|
|
267
|
-
return `ConnectionInfo(
|
|
268
|
+
return `ConnectionInfo(connection_id=${this.connectionId}, provider=${this.providerId}, status=${this.status})`;
|
|
268
269
|
}
|
|
269
270
|
};
|
|
270
271
|
var ConnectSession = class {
|
|
@@ -317,7 +318,17 @@ var ConnectResult = class {
|
|
|
317
318
|
this.providerId = data.provider_id;
|
|
318
319
|
this.accountIdentifier = data.account_identifier ?? null;
|
|
319
320
|
this.scopes = data.scopes ?? [];
|
|
320
|
-
|
|
321
|
+
const rawPolicy = data.connection_policy;
|
|
322
|
+
if (rawPolicy) {
|
|
323
|
+
const raw = rawPolicy;
|
|
324
|
+
this.connectionPolicy = Object.freeze({
|
|
325
|
+
expiresAt: raw["expires_at"] !== void 0 ? raw["expires_at"] : rawPolicy.expiresAt ?? null,
|
|
326
|
+
createdBy: raw["created_by"] !== void 0 ? raw["created_by"] : rawPolicy.createdBy ?? null,
|
|
327
|
+
createdAt: raw["created_at"] !== void 0 ? raw["created_at"] : rawPolicy.createdAt ?? null
|
|
328
|
+
});
|
|
329
|
+
} else {
|
|
330
|
+
this.connectionPolicy = null;
|
|
331
|
+
}
|
|
321
332
|
Object.freeze(this);
|
|
322
333
|
}
|
|
323
334
|
toJSON() {
|
|
@@ -326,7 +337,11 @@ var ConnectResult = class {
|
|
|
326
337
|
provider_id: this.providerId,
|
|
327
338
|
account_identifier: this.accountIdentifier,
|
|
328
339
|
scopes: this.scopes,
|
|
329
|
-
connection_policy: this.connectionPolicy
|
|
340
|
+
connection_policy: this.connectionPolicy ? {
|
|
341
|
+
expires_at: this.connectionPolicy.expiresAt ?? null,
|
|
342
|
+
created_by: this.connectionPolicy.createdBy ?? null,
|
|
343
|
+
created_at: this.connectionPolicy.createdAt ?? null
|
|
344
|
+
} : null
|
|
330
345
|
};
|
|
331
346
|
}
|
|
332
347
|
toString() {
|
|
@@ -340,7 +355,8 @@ var SENSITIVE_HEADERS = /* @__PURE__ */ new Set([
|
|
|
340
355
|
"x-api-key",
|
|
341
356
|
"x-auth-token",
|
|
342
357
|
"x-amz-date",
|
|
343
|
-
"x-amz-content-sha256"
|
|
358
|
+
"x-amz-content-sha256",
|
|
359
|
+
"x-amz-security-token"
|
|
344
360
|
]);
|
|
345
361
|
var APICallAuditLog = class {
|
|
346
362
|
connectionId;
|
|
@@ -419,6 +435,7 @@ import { createHash, createHmac } from "crypto";
|
|
|
419
435
|
var ALGORITHM = "AWS4-HMAC-SHA256";
|
|
420
436
|
var AWS_HOST_RE = /^(?<service>[a-z0-9-]+)\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.amazonaws\.com$/;
|
|
421
437
|
var S3_VIRTUAL_HOST_RE = /^[^.]+\.s3\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.amazonaws\.com$/;
|
|
438
|
+
var VPCE_HOST_RE = /^vpce-[a-z0-9-]+\.(?<service>[a-z0-9-]+)\.(?<region>[a-z]{2}(?:-[a-z0-9]+)+-\d+)\.vpce\.amazonaws\.com$/;
|
|
422
439
|
function hmacSha256(key, message) {
|
|
423
440
|
return createHmac("sha256", key).update(message, "utf8").digest();
|
|
424
441
|
}
|
|
@@ -441,6 +458,10 @@ function detectServiceAndRegion(hostname) {
|
|
|
441
458
|
if (s3m?.groups) {
|
|
442
459
|
return { service: "s3", region: s3m.groups.region };
|
|
443
460
|
}
|
|
461
|
+
const vpcem = VPCE_HOST_RE.exec(lower);
|
|
462
|
+
if (vpcem?.groups) {
|
|
463
|
+
return { service: vpcem.groups.service, region: vpcem.groups.region };
|
|
464
|
+
}
|
|
444
465
|
return { service: null, region: null };
|
|
445
466
|
}
|
|
446
467
|
function deriveSigningKey(secretKey, dateStamp, region, service) {
|
|
@@ -475,18 +496,21 @@ function canonicalQueryString(query) {
|
|
|
475
496
|
]);
|
|
476
497
|
}
|
|
477
498
|
}
|
|
478
|
-
|
|
499
|
+
const sigv4Encode = (s) => encodeURIComponent(s).replace(
|
|
500
|
+
/[!'()*]/g,
|
|
501
|
+
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
502
|
+
);
|
|
503
|
+
const encoded = sorted.map(
|
|
504
|
+
([k, v]) => [sigv4Encode(k), sigv4Encode(v)]
|
|
505
|
+
);
|
|
506
|
+
encoded.sort((a, b) => {
|
|
479
507
|
if (a[0] < b[0]) return -1;
|
|
480
508
|
if (a[0] > b[0]) return 1;
|
|
481
509
|
if (a[1] < b[1]) return -1;
|
|
482
510
|
if (a[1] > b[1]) return 1;
|
|
483
511
|
return 0;
|
|
484
512
|
});
|
|
485
|
-
|
|
486
|
-
/[!'()*]/g,
|
|
487
|
-
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
488
|
-
);
|
|
489
|
-
return sorted.map(([k, v]) => `${sigv4Encode(k)}=${sigv4Encode(v)}`).join("&");
|
|
513
|
+
return encoded.map(([k, v]) => `${k}=${v}`).join("&");
|
|
490
514
|
}
|
|
491
515
|
function canonicalHeadersAndSigned(headers) {
|
|
492
516
|
const canonical = {};
|
|
@@ -505,11 +529,9 @@ function signAwsRequest(opts) {
|
|
|
505
529
|
const parsed = new URL(opts.url);
|
|
506
530
|
const hostname = parsed.hostname;
|
|
507
531
|
let { region, service } = opts;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
if (service == null) service = detected.service;
|
|
512
|
-
}
|
|
532
|
+
const detected = detectServiceAndRegion(hostname);
|
|
533
|
+
if (detected.region != null) region = detected.region;
|
|
534
|
+
if (detected.service != null) service = detected.service;
|
|
513
535
|
if (!region) {
|
|
514
536
|
throw new Error(
|
|
515
537
|
`Cannot determine AWS region from URL '${opts.url}'. Pass region explicitly via additional_credentials.`
|
|
@@ -592,7 +614,7 @@ function _extractAdditionalCredentials(token) {
|
|
|
592
614
|
return _additionalCredsStore.get(token);
|
|
593
615
|
}
|
|
594
616
|
var _fetch;
|
|
595
|
-
var SDK_VERSION = "0.
|
|
617
|
+
var SDK_VERSION = "0.6.0";
|
|
596
618
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
597
619
|
var HTTP_FORBIDDEN = 403;
|
|
598
620
|
var HTTP_NOT_FOUND = 404;
|