@itm-studio/partner-sdk 0.4.2 → 0.5.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 +19 -0
- package/dist/index.d.mts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +90 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +90 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5380,24 +5380,46 @@ assertNodeServerRuntime();
|
|
|
5380
5380
|
var DEFAULT_API_URL = "https://itm-backend-production.up.railway.app/graphql";
|
|
5381
5381
|
var RESERVED_AGENT_HEADERS = /* @__PURE__ */ new Set([
|
|
5382
5382
|
"authorization",
|
|
5383
|
+
"x-itm-integration-access-token",
|
|
5383
5384
|
"x-itm-agent-session-id",
|
|
5384
5385
|
"x-itm-agent-bootstrap-token",
|
|
5385
5386
|
"x-itm-agent-access-token",
|
|
5386
5387
|
"x-partner-api-key"
|
|
5387
5388
|
]);
|
|
5388
5389
|
function createITMPartnerClient(config) {
|
|
5389
|
-
const { baseUrl, headers: extraHeaders } = config;
|
|
5390
|
+
const { baseUrl, headers: extraHeaders, signal } = config;
|
|
5390
5391
|
const token = "token" in config ? config.token : void 0;
|
|
5391
5392
|
const agentSession = "agentSession" in config ? config.agentSession : void 0;
|
|
5392
5393
|
const agentAccess = "agentAccess" in config ? config.agentAccess : void 0;
|
|
5393
|
-
const
|
|
5394
|
+
const integration = "integration" in config ? config.integration : void 0;
|
|
5395
|
+
const providedModes = [token, agentSession, agentAccess, integration].filter(
|
|
5394
5396
|
(mode) => mode !== void 0
|
|
5395
5397
|
);
|
|
5396
5398
|
if (providedModes.length > 1) {
|
|
5397
5399
|
throw new Error(
|
|
5398
|
-
"ITM Partner SDK: provide exactly one of token, agentSession, or
|
|
5400
|
+
"ITM Partner SDK: provide exactly one of token, agentSession, agentAccess, or integration authentication."
|
|
5399
5401
|
);
|
|
5400
5402
|
}
|
|
5403
|
+
if (integration !== void 0) {
|
|
5404
|
+
if (typeof integration.accessToken !== "function" && (typeof integration.accessToken !== "string" || !integration.accessToken.trim())) {
|
|
5405
|
+
throw new Error("ITM Partner SDK: integration.accessToken is required.");
|
|
5406
|
+
}
|
|
5407
|
+
return createSafeClient({
|
|
5408
|
+
url: baseUrl ?? DEFAULT_API_URL,
|
|
5409
|
+
signal,
|
|
5410
|
+
headers: async () => {
|
|
5411
|
+
const extra = typeof extraHeaders === "function" ? await extraHeaders() : extraHeaders;
|
|
5412
|
+
let credential;
|
|
5413
|
+
try {
|
|
5414
|
+
credential = typeof integration.accessToken === "function" ? await integration.accessToken() : integration.accessToken;
|
|
5415
|
+
} catch {
|
|
5416
|
+
throw new Error("ITM Partner SDK: integration credential is unavailable.");
|
|
5417
|
+
}
|
|
5418
|
+
if (typeof credential !== "string" || !credential.trim()) throw new Error("ITM Partner SDK: integration credential is unavailable.");
|
|
5419
|
+
return { ...sanitizeHeaders(extra), "x-itm-integration-access-token": credential, "Content-Type": "application/json" };
|
|
5420
|
+
}
|
|
5421
|
+
});
|
|
5422
|
+
}
|
|
5401
5423
|
if (agentAccess !== void 0) {
|
|
5402
5424
|
if (typeof agentAccess.workloadToken !== "function") {
|
|
5403
5425
|
throw new Error(
|
|
@@ -5407,8 +5429,9 @@ function createITMPartnerClient(config) {
|
|
|
5407
5429
|
if (!agentAccess.accessToken) {
|
|
5408
5430
|
throw new Error("ITM Partner SDK: agentAccess.accessToken is required.");
|
|
5409
5431
|
}
|
|
5410
|
-
return
|
|
5432
|
+
return createSafeClient({
|
|
5411
5433
|
url: baseUrl ?? DEFAULT_API_URL,
|
|
5434
|
+
signal,
|
|
5412
5435
|
headers: async () => {
|
|
5413
5436
|
const resolvedExtraHeaders = typeof extraHeaders === "function" ? await extraHeaders() : extraHeaders;
|
|
5414
5437
|
const sanitizedExtraHeaders = Object.fromEntries(
|
|
@@ -5440,8 +5463,9 @@ function createITMPartnerClient(config) {
|
|
|
5440
5463
|
if (!agentSession.sessionUid) {
|
|
5441
5464
|
throw new Error("ITM Partner SDK: agentSession.sessionUid is required.");
|
|
5442
5465
|
}
|
|
5443
|
-
return
|
|
5466
|
+
return createSafeClient({
|
|
5444
5467
|
url: baseUrl ?? DEFAULT_API_URL,
|
|
5468
|
+
signal,
|
|
5445
5469
|
headers: async () => {
|
|
5446
5470
|
const resolvedExtraHeaders = typeof extraHeaders === "function" ? await extraHeaders() : extraHeaders;
|
|
5447
5471
|
const sanitizedExtraHeaders = Object.fromEntries(
|
|
@@ -5470,19 +5494,77 @@ function createITMPartnerClient(config) {
|
|
|
5470
5494
|
"ITM Partner SDK: token is required. Get one from backstage: Settings > Partner API."
|
|
5471
5495
|
);
|
|
5472
5496
|
}
|
|
5473
|
-
return
|
|
5497
|
+
return createSafeClient({
|
|
5474
5498
|
url: baseUrl ?? DEFAULT_API_URL,
|
|
5499
|
+
signal,
|
|
5475
5500
|
headers: async () => {
|
|
5476
5501
|
const resolvedExtraHeaders = typeof extraHeaders === "function" ? await extraHeaders() : extraHeaders;
|
|
5477
5502
|
return {
|
|
5478
|
-
...resolvedExtraHeaders
|
|
5503
|
+
...sanitizeHeaders(resolvedExtraHeaders),
|
|
5479
5504
|
"x-partner-api-key": token,
|
|
5480
5505
|
"Content-Type": "application/json"
|
|
5481
5506
|
};
|
|
5482
5507
|
}
|
|
5483
5508
|
});
|
|
5484
5509
|
}
|
|
5510
|
+
function sanitizeHeaders(headers) {
|
|
5511
|
+
return Object.fromEntries(Object.entries(headers ?? {}).filter(([name]) => !RESERVED_AGENT_HEADERS.has(name.toLowerCase())));
|
|
5512
|
+
}
|
|
5513
|
+
var ITMPartnerTransportError = class extends Error {
|
|
5514
|
+
constructor(status, requestId) {
|
|
5515
|
+
super(status ? `ITM Partner API request failed (HTTP ${status}).` : "ITM Partner API request failed.");
|
|
5516
|
+
this.status = status;
|
|
5517
|
+
this.requestId = requestId;
|
|
5518
|
+
}
|
|
5519
|
+
name = "ITMPartnerTransportError";
|
|
5520
|
+
};
|
|
5521
|
+
function createSafeClient(options) {
|
|
5522
|
+
return createClient2({ fetcher: async (operation) => {
|
|
5523
|
+
options.signal?.throwIfAborted();
|
|
5524
|
+
const headers = await withCancellation(options.headers, options.signal);
|
|
5525
|
+
options.signal?.throwIfAborted();
|
|
5526
|
+
let response;
|
|
5527
|
+
try {
|
|
5528
|
+
response = await fetch(options.url, { method: "POST", headers, body: JSON.stringify(operation), signal: options.signal, redirect: "error" });
|
|
5529
|
+
} catch {
|
|
5530
|
+
options.signal?.throwIfAborted();
|
|
5531
|
+
throw new ITMPartnerTransportError(void 0);
|
|
5532
|
+
}
|
|
5533
|
+
if (!response.ok) throw new ITMPartnerTransportError(response.status, response.headers.get("x-request-id") ?? void 0);
|
|
5534
|
+
let value;
|
|
5535
|
+
try {
|
|
5536
|
+
value = await response.json();
|
|
5537
|
+
} catch {
|
|
5538
|
+
options.signal?.throwIfAborted();
|
|
5539
|
+
throw new ITMPartnerTransportError(response.status);
|
|
5540
|
+
}
|
|
5541
|
+
if (!value || typeof value !== "object" || !("data" in value || "errors" in value)) throw new ITMPartnerTransportError(response.status);
|
|
5542
|
+
const result = value;
|
|
5543
|
+
const secrets = Object.entries(headers).filter(([key]) => RESERVED_AGENT_HEADERS.has(key.toLowerCase())).flatMap(([, v]) => [v, v.replace(/^Bearer /i, "")]).filter(Boolean);
|
|
5544
|
+
const redact = (message) => secrets.reduce((text, secret) => text.split(secret).join("[redacted]"), message);
|
|
5545
|
+
if (result.errors) result.errors = result.errors.map((error) => ({ name: "GraphQLError", message: redact(typeof error.message === "string" ? error.message : "GraphQL request failed"), extensions: typeof error.extensions?.code === "string" ? { code: redact(error.extensions.code) } : void 0 }));
|
|
5546
|
+
return result;
|
|
5547
|
+
} });
|
|
5548
|
+
}
|
|
5549
|
+
async function withCancellation(operation, signal) {
|
|
5550
|
+
signal?.throwIfAborted();
|
|
5551
|
+
if (!signal) return operation();
|
|
5552
|
+
let abort = () => {
|
|
5553
|
+
};
|
|
5554
|
+
try {
|
|
5555
|
+
return await Promise.race([
|
|
5556
|
+
operation(),
|
|
5557
|
+
new Promise((_resolve, reject) => {
|
|
5558
|
+
abort = () => reject(signal.reason);
|
|
5559
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
5560
|
+
if (signal.aborted) abort();
|
|
5561
|
+
})
|
|
5562
|
+
]);
|
|
5563
|
+
} finally {
|
|
5564
|
+
signal.removeEventListener("abort", abort);
|
|
5565
|
+
}
|
|
5566
|
+
}
|
|
5485
5567
|
|
|
5486
|
-
export { DEFAULT_API_URL, GenqlError, createITMPartnerClient, everything, generateMutationOp, generateQueryOp };
|
|
5568
|
+
export { DEFAULT_API_URL, GenqlError, ITMPartnerTransportError, createITMPartnerClient, everything, generateMutationOp, generateQueryOp };
|
|
5487
5569
|
//# sourceMappingURL=index.mjs.map
|
|
5488
5570
|
//# sourceMappingURL=index.mjs.map
|