UNPKG

bitbucket-mcp

Version:

Model Context Protocol (MCP) server for Bitbucket Cloud and Server API integration

117 lines 4.32 kB
export const BITBUCKET_DEFAULT_PAGELEN = 10; export const BITBUCKET_MAX_PAGELEN = 100; export const BITBUCKET_ALL_ITEMS_CAP = 1000; export class BitbucketPaginator { constructor(api, logger) { this.api = api; this.logger = logger; } async fetchValues(path, options = {}) { const { pagelen, page, all = false, params = {}, defaultPagelen = BITBUCKET_DEFAULT_PAGELEN, maxItems = BITBUCKET_ALL_ITEMS_CAP, description, } = options; const resolvedPagelen = this.normalizePagelen(pagelen ?? defaultPagelen); const requestParams = { ...params, pagelen: resolvedPagelen, }; if (page !== undefined) { requestParams.page = page; } const shouldFetchAll = all === true && page === undefined; const requestDescriptor = { url: path, params: requestParams, }; if (!shouldFetchAll) { const response = await this.performRequest(requestDescriptor, description); const values = this.extractValues(response.data); return { values, page: response.data?.page ?? page, pagelen: response.data?.pagelen ?? resolvedPagelen, next: response.data?.next, previous: response.data?.previous, fetchedPages: 1, totalFetched: values.length, }; } const aggregated = []; let fetchedPages = 0; let nextRequest = requestDescriptor; let firstPageMeta = { pagelen: resolvedPagelen }; while (nextRequest && aggregated.length < maxItems) { const response = await this.performRequest(nextRequest, description, { page: fetchedPages + 1, }); fetchedPages += 1; if (fetchedPages === 1) { firstPageMeta = { page: response.data?.page, pagelen: response.data?.pagelen ?? resolvedPagelen, previous: response.data?.previous, }; } const values = this.extractValues(response.data); aggregated.push(...values); if (!response.data?.next) { nextRequest = undefined; break; } if (aggregated.length >= maxItems) { this.logger.debug("Bitbucket pagination cap reached", { description: description ?? path, maxItems, }); nextRequest = undefined; break; } this.logger.debug("Following Bitbucket pagination next link", { description: description ?? path, next: response.data.next, fetchedPages, totalFetched: aggregated.length, }); nextRequest = { url: response.data.next }; } if (aggregated.length > maxItems) { aggregated.length = maxItems; } return { values: aggregated, page: firstPageMeta.page, pagelen: firstPageMeta.pagelen, previous: firstPageMeta.previous, fetchedPages, totalFetched: aggregated.length, }; } async performRequest(request, description, extra) { this.logger.debug("Calling Bitbucket API", { description: description ?? request.url, url: request.url, params: request.params, ...extra, }); const config = request.params ? { params: request.params } : undefined; return this.api.get(request.url, config); } extractValues(data) { if (Array.isArray(data?.values)) { return data.values; } if (Array.isArray(data)) { return data; } return []; } normalizePagelen(value) { if (value === undefined || Number.isNaN(value)) { return BITBUCKET_DEFAULT_PAGELEN; } const integer = Math.floor(value); if (!Number.isFinite(integer) || integer < 1) { return 1; } return Math.min(integer, BITBUCKET_MAX_PAGELEN); } } //# sourceMappingURL=pagination.js.map