mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-11 20:05:25 +00:00
fix(bitbucket): Bitbucket Cloud pagination not working beyond first page (#502)
This commit is contained in:
parent
aab4a92a87
commit
7cbda320cb
2 changed files with 32 additions and 12 deletions
|
|
@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
- Fixed Bitbucket Cloud pagination not working beyond first page. [#295](https://github.com/sourcebot-dev/sourcebot/issues/295)
|
||||
|
||||
## [4.6.7] - 2025-09-08
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -148,13 +148,14 @@ function cloudClient(user: string | undefined, token: string | undefined): Bitbu
|
|||
**/
|
||||
const getPaginatedCloud = async <T>(
|
||||
path: CloudGetRequestPath,
|
||||
get: (url: CloudGetRequestPath) => Promise<CloudPaginatedResponse<T>>
|
||||
get: (path: CloudGetRequestPath, query?: Record<string, string>) => Promise<CloudPaginatedResponse<T>>
|
||||
): Promise<T[]> => {
|
||||
const results: T[] = [];
|
||||
let url = path;
|
||||
let nextPath = path;
|
||||
let nextQuery = undefined;
|
||||
|
||||
while (true) {
|
||||
const response = await get(url);
|
||||
const response = await get(nextPath, nextQuery);
|
||||
|
||||
if (!response.values || response.values.length === 0) {
|
||||
break;
|
||||
|
|
@ -166,25 +167,38 @@ const getPaginatedCloud = async <T>(
|
|||
break;
|
||||
}
|
||||
|
||||
url = response.next as CloudGetRequestPath;
|
||||
const parsedUrl = parseUrl(response.next);
|
||||
nextPath = parsedUrl.path as CloudGetRequestPath;
|
||||
nextQuery = parsedUrl.query;
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the url into a path and query parameters to be used with the api client (openapi-fetch)
|
||||
*/
|
||||
function parseUrl(url: string): { path: string; query: Record<string, string>; } {
|
||||
const fullUrl = new URL(url);
|
||||
const path = fullUrl.pathname.replace(/^\/\d+(\.\d+)*/, ''); // remove version number in the beginning of the path
|
||||
const query = Object.fromEntries(fullUrl.searchParams);
|
||||
logger.debug(`Parsed url ${url} into path ${path} and query ${JSON.stringify(query)}`);
|
||||
return { path, query };
|
||||
}
|
||||
|
||||
|
||||
async function cloudGetReposForWorkspace(client: BitbucketClient, workspaces: string[]): Promise<{validRepos: CloudRepository[], notFoundWorkspaces: string[]}> {
|
||||
const results = await Promise.allSettled(workspaces.map(async (workspace) => {
|
||||
try {
|
||||
logger.debug(`Fetching all repos for workspace ${workspace}...`);
|
||||
|
||||
const path = `/repositories/${workspace}` as CloudGetRequestPath;
|
||||
const { durationMs, data } = await measure(async () => {
|
||||
const fetchFn = () => getPaginatedCloud<CloudRepository>(path, async (url) => {
|
||||
const response = await client.apiClient.GET(url, {
|
||||
const fetchFn = () => getPaginatedCloud<CloudRepository>(`/repositories/${workspace}` as CloudGetRequestPath, async (path, query) => {
|
||||
const response = await client.apiClient.GET(path, {
|
||||
params: {
|
||||
path: {
|
||||
workspace,
|
||||
}
|
||||
},
|
||||
query: query,
|
||||
}
|
||||
});
|
||||
const { data, error } = response;
|
||||
|
|
@ -238,11 +252,14 @@ async function cloudGetReposForProjects(client: BitbucketClient, projects: strin
|
|||
|
||||
logger.debug(`Fetching all repos for project ${project} for workspace ${workspace}...`);
|
||||
try {
|
||||
const path = `/repositories/${workspace}` as CloudGetRequestPath;
|
||||
const repos = await getPaginatedCloud<CloudRepository>(path, async (url) => {
|
||||
const response = await client.apiClient.GET(url, {
|
||||
const repos = await getPaginatedCloud<CloudRepository>(`/repositories/${workspace}` as CloudGetRequestPath, async (path, query) => {
|
||||
const response = await client.apiClient.GET(path, {
|
||||
params: {
|
||||
path: {
|
||||
workspace,
|
||||
},
|
||||
query: {
|
||||
...query,
|
||||
q: `project.key="${project_name}"`
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue