okta-mcp-server
Version:
Model Context Protocol (MCP) server for Okta API operations with support for bulk operations and caching
94 lines • 3.5 kB
JavaScript
export class PaginationHelper {
static paginate(items, options = {}, baseUrl) {
const limit = Math.min(options.limit || 200, 1000); // Max 1000 items per page
let startIndex = 0;
let endIndex = items.length;
// Handle cursor-based pagination
if (options.after) {
const afterIndex = items.findIndex((item) => item.id === options.after);
if (afterIndex !== -1) {
startIndex = afterIndex + 1;
}
}
else if (options.before) {
const beforeIndex = items.findIndex((item) => item.id === options.before);
if (beforeIndex !== -1) {
endIndex = beforeIndex;
startIndex = Math.max(0, endIndex - limit);
}
}
// Calculate the page
const pageItems = items.slice(startIndex, Math.min(startIndex + limit, endIndex));
const hasMore = startIndex + limit < items.length;
const hasPrev = startIndex > 0;
// Build Link header
const links = [];
if (hasMore && pageItems.length > 0) {
const lastItem = pageItems[pageItems.length - 1];
if (lastItem) {
const nextUrl = `${baseUrl}?limit=${limit}&after=${lastItem.id}`;
links.push(`<${nextUrl}>; rel="next"`);
}
}
if (hasPrev && pageItems.length > 0) {
const firstItem = pageItems[0];
if (firstItem) {
const prevUrl = `${baseUrl}?limit=${limit}&before=${firstItem.id}`;
links.push(`<${prevUrl}>; rel="prev"`);
}
}
// Self link
const selfUrl = options.after
? `${baseUrl}?limit=${limit}&after=${options.after}`
: options.before
? `${baseUrl}?limit=${limit}&before=${options.before}`
: `${baseUrl}?limit=${limit}`;
links.push(`<${selfUrl}>; rel="self"`);
const result = {
data: pageItems,
headers: {
...(links.length > 0 && { link: links.join(', ') }),
'x-rate-limit-limit': '600',
'x-rate-limit-remaining': '599',
'x-rate-limit-reset': String(Math.floor(Date.now() / 1000) + 60),
},
hasMore,
};
// Only add cursors if they exist
if (hasMore && pageItems.length > 0) {
const lastItem = pageItems[pageItems.length - 1];
if (lastItem) {
result.nextCursor = lastItem.id;
}
}
if (hasPrev && pageItems.length > 0) {
const firstItem = pageItems[0];
if (firstItem) {
result.prevCursor = firstItem.id;
}
}
return result;
}
static parseQueryString(queryString) {
if (!queryString)
return {};
const params = new URLSearchParams(queryString);
const result = {};
if (params.has('limit')) {
result.limit = parseInt(params.get('limit'), 10);
}
const after = params.get('after');
if (after) {
result.after = after;
}
const before = params.get('before');
if (before) {
result.before = before;
}
return result;
}
static buildLinkHeader(links) {
return links.map((link) => `<${link.url}>; rel="${link.rel}"`).join(', ');
}
}
//# sourceMappingURL=pagination.js.map