in src/desktop/gitlab/gitlab_service.ts [704:839]
async getIssuables(params: CustomQuery, project: GitLabProject) {
const { type, scope, state, author, assignee, wip, draft, reviewer } = params;
let { searchIn } = params;
const config = {
type: type || 'merge_requests',
scope: scope || 'all',
state: state || 'opened',
};
if (config.type === 'vulnerabilities' && config.scope !== 'dismissed') {
config.scope = 'all';
} else if (
(config.type === 'issues' || config.type === 'merge_requests') &&
config.scope !== 'assigned_to_me' &&
config.scope !== 'created_by_me'
) {
config.scope = 'all';
}
let path = '';
const search = new Map<string, string>();
search.set('state', config.state);
/**
* Set path based on config.type
*/
if (config.type === 'epics') {
path = `/groups/${project.groupRestId}/${config.type}`;
search.set('include_ancestor_groups', 'true');
} else {
const searchKind =
config.type === CustomQueryType.VULNERABILITY ? 'vulnerability_findings' : config.type;
path = `/projects/${project.restId}/${searchKind}`;
search.set('scope', config.scope);
}
/**
* Author parameters
*/
if (config.type === 'issues') {
if (author) {
search.set('author_username', author);
}
} else if (author) {
const authorUser = await this.getFirstUserByUsername(author);
if (authorUser) search.set('author_id', String(authorUser.id));
}
/**
* Assignee parameters
*/
if (assignee === 'Any' || assignee === 'None') {
search.set('assignee_id', assignee);
} else if (assignee && config.type === 'issues') {
search.set('assignee_username', assignee);
} else if (assignee) {
const assigneeUser = await this.getFirstUserByUsername(assignee);
if (assigneeUser) search.set('assignee_id', String(assigneeUser.id));
}
/**
* Reviewer parameters
*/
if (reviewer === 'Any' || reviewer === 'None') {
search.set('reviewer_id', reviewer);
} else if (reviewer) {
search.set('reviewer_username', await this.handleCurrentUser(reviewer));
}
/**
* Search in parameters
*/
if (searchIn) {
if (searchIn === 'all') {
searchIn = 'title,description';
}
search.set('in', searchIn);
}
/**
* Handle Draft/WIP for merge_request config.type
* `wip` is an alias of `draft`.
*/
if (config.type === 'merge_requests') {
// `wip` does not have a default value, so check if it's been explicitly defined before
// falling back to `draft`, which does have a default
const draftParam = wip || draft;
if (draftParam) {
search.set('wip', draftParam);
}
}
/**
* Query parameters related to issues
*/
let issueQueryParams: Record<string, QueryValue> = {};
if (config.type === 'issues') {
issueQueryParams = {
confidential: params.confidential,
'not[labels]': params.excludeLabels,
'not[milestone]': params.excludeMilestone,
'not[author_username]': await this.handleCurrentUser(params.excludeAuthor),
'not[assignee_username]': await this.handleCurrentUser(params.excludeAssignee),
'not[search]': params.excludeSearch,
'not[in]': params.excludeSearchIn,
};
}
/**
* Miscellaneous parameters
*/
const queryParams: Record<string, QueryValue> = {
labels: params.labels,
milestone: params.milestone,
search: params.search,
created_before: params.createdBefore,
created_after: params.createdAfter,
updated_before: params.updatedBefore,
updated_after: params.updatedAfter,
order_by: params.orderBy,
sort: params.sort,
per_page: params.maxResults,
report_type: params.reportTypes,
severity: params.severityLevels,
confidence: params.confidenceLevels,
...issueQueryParams,
};
const issuables = (await this.#apiClient.fetch(
path,
{ ...Object.fromEntries(search), ...queryParams },
'issuables',
)) as RestIssuable[]; // FIXME: vulnerabilities don't conform to the RestIssuable interface (they don't have author field) https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/614
const { instanceUrl } = await this.getCredentials();
return issuables.map(normalizeAvatarUrl(instanceUrl));
}