@kaddo/mcp 3.88.2 → 3.88.4
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.js +52 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -12295,7 +12295,7 @@ function buildJql(filters) {
|
|
|
12295
12295
|
if (filters?.updatedAfter) clauses.push(`updated >= ${escapeJql(filters.updatedAfter)}`);
|
|
12296
12296
|
if (filters?.search) clauses.push(`(summary ~ ${escapeJql(filters.search)} OR description ~ ${escapeJql(filters.search)})`);
|
|
12297
12297
|
if (filters?.providerQuery) clauses.push(`(${filters.providerQuery})`);
|
|
12298
|
-
return clauses.join(" AND ")
|
|
12298
|
+
return clauses.join(" AND ");
|
|
12299
12299
|
}
|
|
12300
12300
|
function normalizeBaseUrl(raw) {
|
|
12301
12301
|
let url = raw.trim();
|
|
@@ -12306,6 +12306,26 @@ function authHeader(email, token) {
|
|
|
12306
12306
|
const encoded = typeof Buffer !== "undefined" ? Buffer.from(`${email}:${token}`).toString("base64") : btoa(`${email}:${token}`);
|
|
12307
12307
|
return `Basic ${encoded}`;
|
|
12308
12308
|
}
|
|
12309
|
+
async function handleJiraResponse(res) {
|
|
12310
|
+
if (res.status === 401) throw integrationError("INTEGRATION_UNAUTHORIZED");
|
|
12311
|
+
if (res.status === 403) throw integrationError("INTEGRATION_FORBIDDEN");
|
|
12312
|
+
if (res.status === 404) throw integrationError("INTEGRATION_NOT_FOUND");
|
|
12313
|
+
if (res.status === 410) throw integrationError("INTEGRATION_UNAVAILABLE", "Jira API endpoint deprecated (410 Gone).");
|
|
12314
|
+
if (res.status === 429) throw integrationError("INTEGRATION_RATE_LIMITED");
|
|
12315
|
+
if (res.status >= 500) throw integrationError("INTEGRATION_UNAVAILABLE");
|
|
12316
|
+
if (!res.ok) {
|
|
12317
|
+
let detail = "";
|
|
12318
|
+
try {
|
|
12319
|
+
const body = await res.json();
|
|
12320
|
+
const msgs = body.errorMessages?.filter(Boolean) ?? [];
|
|
12321
|
+
const fieldErrs = body.errors ? Object.entries(body.errors).map(([k2, v]) => `${k2}: ${v}`) : [];
|
|
12322
|
+
detail = [...msgs, ...fieldErrs].join("; ");
|
|
12323
|
+
} catch {
|
|
12324
|
+
}
|
|
12325
|
+
throw integrationError("INTEGRATION_PROVIDER_ERROR", detail || `Jira responded with status ${res.status}.`);
|
|
12326
|
+
}
|
|
12327
|
+
return await res.json();
|
|
12328
|
+
}
|
|
12309
12329
|
async function jiraFetch(baseUrl, path6, auth, timeoutMs, params) {
|
|
12310
12330
|
const url = new URL(path6, baseUrl + "/");
|
|
12311
12331
|
if (params) for (const [k2, v] of Object.entries(params)) url.searchParams.set(k2, v);
|
|
@@ -12317,14 +12337,26 @@ async function jiraFetch(baseUrl, path6, auth, timeoutMs, params) {
|
|
|
12317
12337
|
headers: { Authorization: auth, Accept: "application/json" },
|
|
12318
12338
|
signal: controller.signal
|
|
12319
12339
|
});
|
|
12320
|
-
|
|
12321
|
-
|
|
12322
|
-
if (
|
|
12323
|
-
|
|
12324
|
-
|
|
12325
|
-
|
|
12326
|
-
|
|
12327
|
-
|
|
12340
|
+
return await handleJiraResponse(res);
|
|
12341
|
+
} catch (err) {
|
|
12342
|
+
if (err instanceof Error && err.name === "AbortError") throw integrationError("INTEGRATION_TIMEOUT");
|
|
12343
|
+
throw normalizeProviderError(err);
|
|
12344
|
+
} finally {
|
|
12345
|
+
clearTimeout(timer);
|
|
12346
|
+
}
|
|
12347
|
+
}
|
|
12348
|
+
async function jiraPost(baseUrl, path6, auth, timeoutMs, body) {
|
|
12349
|
+
const url = new URL(path6, baseUrl + "/");
|
|
12350
|
+
const controller = new AbortController();
|
|
12351
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
12352
|
+
try {
|
|
12353
|
+
const res = await fetch(url.toString(), {
|
|
12354
|
+
method: "POST",
|
|
12355
|
+
headers: { Authorization: auth, Accept: "application/json", "Content-Type": "application/json" },
|
|
12356
|
+
body: JSON.stringify(body),
|
|
12357
|
+
signal: controller.signal
|
|
12358
|
+
});
|
|
12359
|
+
return await handleJiraResponse(res);
|
|
12328
12360
|
} catch (err) {
|
|
12329
12361
|
if (err instanceof Error && err.name === "AbortError") throw integrationError("INTEGRATION_TIMEOUT");
|
|
12330
12362
|
throw normalizeProviderError(err);
|
|
@@ -12443,18 +12475,19 @@ function createJiraAdapter() {
|
|
|
12443
12475
|
const auth = authHeader(email, apiToken);
|
|
12444
12476
|
const jql = buildJql(request.filters);
|
|
12445
12477
|
const pageSize = Math.min(Math.max(1, request.pageSize ?? DEFAULT_PAGE_SIZE), 100);
|
|
12446
|
-
const
|
|
12478
|
+
const nextPageToken = request.cursor || void 0;
|
|
12447
12479
|
try {
|
|
12448
|
-
const
|
|
12449
|
-
|
|
12450
|
-
|
|
12451
|
-
maxResults:
|
|
12452
|
-
fields: SEARCH_FIELDS
|
|
12453
|
-
}
|
|
12480
|
+
const fullJql = jql ? jql + " ORDER BY updated DESC" : "updated >= -30d ORDER BY updated DESC";
|
|
12481
|
+
const body = {
|
|
12482
|
+
jql: fullJql,
|
|
12483
|
+
maxResults: pageSize,
|
|
12484
|
+
fields: SEARCH_FIELDS.split(",")
|
|
12485
|
+
};
|
|
12486
|
+
if (nextPageToken) body.nextPageToken = nextPageToken;
|
|
12487
|
+
const data = await jiraPost(baseUrl, "/rest/api/3/search/jql", auth, request.context.timeoutMs, body);
|
|
12454
12488
|
const items = data.issues.map((issue) => normalizeIssue(issue, baseUrl, request.context.integrationId));
|
|
12455
|
-
const
|
|
12456
|
-
|
|
12457
|
-
return { items, hasMore, ...hasMore ? { nextCursor: String(nextStart) } : {} };
|
|
12489
|
+
const hasMore = data.isLast === false;
|
|
12490
|
+
return { items, hasMore, ...hasMore && data.nextPageToken ? { nextCursor: data.nextPageToken } : {} };
|
|
12458
12491
|
} catch (err) {
|
|
12459
12492
|
throw normalizeProviderError(err);
|
|
12460
12493
|
}
|
package/package.json
CHANGED