feat: Allow configurable pagelength for Bitbucket Cloud provider

Signed-off-by: Joseph Roberto <robertoj921@yahoo.com>
This commit is contained in:
Joseph Roberto
2025-09-18 12:45:13 -05:00
parent a418e1961e
commit 2aded73e38
10 changed files with 101 additions and 5 deletions
@@ -79,6 +79,41 @@ describe('BitbucketCloudClient', () => {
expect(results[0].file!.path).toEqual('path/to/file');
});
it('searchCode with custom pagelen', async () => {
server.use(
rest.get(
`https://api.bitbucket.org/2.0/workspaces/ws/search/code`,
(req, res, ctx) => {
const pagelen = req.url.searchParams.get('pagelen');
expect(pagelen).toBe('50');
const response: Models.SearchResultPage = {
values: [
{
content_match_count: 1,
file: {
type: 'commit_file',
path: 'path/to/file',
},
},
],
};
return res(ctx.json(response));
},
),
);
const pagination = client.searchCode('ws', 'query', undefined, 50);
const results = [];
for await (const result of pagination.iterateResults()) {
results.push(result);
}
expect(results).toHaveLength(1);
expect(results[0].file!.path).toEqual('path/to/file');
});
it('listRepositoriesByWorkspace', async () => {
server.use(
rest.get(
@@ -40,6 +40,7 @@ export class BitbucketCloudClient {
workspace: string,
query: string,
options?: FilterAndSortOptions & PartialResponseOptions,
pagelen?: number,
): WithPagination<Models.SearchResultPage, Models.SearchCodeSearchResult> {
const workspaceEnc = encodeURIComponent(workspace);
return new WithPagination(
@@ -50,6 +51,7 @@ export class BitbucketCloudClient {
search_query: query,
}),
url => this.getTypeMapped(url),
pagelen,
);
}
@@ -24,7 +24,7 @@ interface TestResultItem {
interface TestPage extends Models.Paginated<TestResultItem> {}
describe('WithPagination', () => {
const createPagination = () =>
const createPagination = (pagelen?: number) =>
new WithPagination<TestPage, TestResultItem>(
opts =>
new URL(
@@ -45,6 +45,7 @@ describe('WithPagination', () => {
],
};
},
pagelen,
);
it('iterateResults', async () => {
@@ -121,4 +122,17 @@ describe('WithPagination', () => {
);
});
});
it('uses custom pagelen when provided', async () => {
const pagination = createPagination(50);
const page = await pagination.getPage();
expect(page.page).toEqual(1);
expect(page.next).toEqual('http://localhost/create-url?page=2&pagelen=50');
expect(page.values).toHaveLength(1);
expect((page.values! as TestResultItem[])[0].url).toEqual(
'http://localhost/create-url?page=1&pagelen=50',
);
});
});
@@ -30,10 +30,11 @@ export class WithPagination<
constructor(
private readonly createUrl: (options: PaginationOptions) => URL,
private readonly fetch: (url: URL) => Promise<TPage>,
private readonly pagelen?: number,
) {}
getPage(options?: PaginationOptions): Promise<TPage> {
const opts = { page: 1, pagelen: 100, ...options };
const opts = { page: 1, pagelen: this.pagelen ?? 100, ...options };
const url = this.createUrl(opts);
return this.fetch(url);
}
@@ -41,7 +42,7 @@ export class WithPagination<
async *iteratePages(
options?: PaginationOptions,
): AsyncGenerator<TPage, void> {
const opts = { page: 1, pagelen: 100, ...options };
const opts = { page: 1, pagelen: this.pagelen ?? 100, ...options };
let url: URL | undefined = this.createUrl(opts);
let res;
do {
@@ -52,7 +53,7 @@ export class WithPagination<
}
async *iterateResults(options?: PaginationOptions) {
const opts = { page: 1, pagelen: 100, ...options };
const opts = { page: 1, pagelen: this.pagelen ?? 100, ...options };
let url: URL | undefined = this.createUrl(opts);
let res;
do {