UNPKG

@aashari/mcp-server-atlassian-confluence

Version:

Node.js/TypeScript MCP server for Atlassian Confluence. Provides tools enabling AI systems (LLMs) to list/get spaces & pages (content formatted as Markdown) and search via CQL. Connects AI seamlessly to Confluence knowledge bases using the standard MCP in

107 lines (106 loc) 4.12 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PaginationType = void 0; exports.extractPaginationInfo = extractPaginationInfo; const logger_util_js_1 = require("./logger.util.js"); /** * Types of pagination mechanisms used by different Atlassian APIs */ var PaginationType; (function (PaginationType) { /** * Offset-based pagination (startAt, maxResults, total) * Used by Jira APIs */ PaginationType["OFFSET"] = "offset"; /** * Cursor-based pagination (cursor in URL) * Used by Confluence APIs */ PaginationType["CURSOR"] = "cursor"; /** * Page-based pagination (page parameter in URL) * Used by Bitbucket APIs */ PaginationType["PAGE"] = "page"; })(PaginationType || (exports.PaginationType = PaginationType = {})); /** * Extract pagination information from API response * @param data The API response containing pagination information * @param paginationType The type of pagination mechanism used * @returns Object with nextCursor, hasMore, and count properties */ function extractPaginationInfo(data, paginationType) { const paginationLogger = logger_util_js_1.Logger.forContext('utils/pagination.util.ts', 'extractPaginationInfo'); let nextCursor; let count; try { // Extract count from the appropriate data field based on pagination type switch (paginationType) { case PaginationType.OFFSET: { const offsetData = data; count = offsetData.values?.length; // Handle Jira's offset-based pagination if (offsetData.startAt !== undefined && offsetData.maxResults !== undefined && offsetData.total !== undefined && offsetData.startAt + offsetData.maxResults < offsetData.total) { nextCursor = String(offsetData.startAt + offsetData.maxResults); } else if (offsetData.nextPage) { nextCursor = offsetData.nextPage; } break; } case PaginationType.CURSOR: { const cursorData = data; count = cursorData.results?.length; // Handle Confluence's cursor-based pagination if (cursorData._links && cursorData._links.next) { const nextUrl = cursorData._links.next; const cursorMatch = nextUrl.match(/cursor=([^&]+)/); if (cursorMatch && cursorMatch[1]) { nextCursor = decodeURIComponent(cursorMatch[1]); } } break; } case PaginationType.PAGE: { const pageData = data; count = pageData.values?.length; // Handle Bitbucket's page-based pagination if (pageData.next) { try { const nextUrl = new URL(pageData.next); const nextPage = nextUrl.searchParams.get('page'); if (nextPage) { nextCursor = nextPage; } } catch (error) { paginationLogger.warn(`Failed to parse next URL: ${pageData.next}`, { error }); } } break; } default: paginationLogger.warn(`Unknown pagination type: ${paginationType}`); } if (nextCursor) { paginationLogger.debug(`Next cursor: ${nextCursor}`); } if (count !== undefined) { paginationLogger.debug(`Count: ${count}`); } return { nextCursor, hasMore: !!nextCursor, count, }; } catch (error) { paginationLogger.warn(`Error extracting pagination information: ${error instanceof Error ? error.message : String(error)}`); return { hasMore: false }; } }