async getIssuables()

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));
  }