import { BaseResource } from '@gitbeaker/requester-utils'; import { RequestHelper, endpoint } from '../infrastructure'; import type { BaseRequestOptions, GitlabAPIResponse, MappedOmit, OneOrNoneOf, PaginationRequestOptions, PaginationTypes, ShowExpanded, Sudo, UserAgentDetailSchema, } from '../infrastructure'; import type { SimpleUserSchema } from './Users'; import type { MergeRequestSchema } from './MergeRequests'; import type { TodoSchema } from './TodoLists'; import type { MetricImageSchema } from './AlertManagement'; import type { SimpleLabelSchema } from '../templates/ResourceLabels'; import type { MilestoneSchema } from '../templates/ResourceMilestones'; export interface TimeStatsSchema extends Record { time_estimate: number; total_time_spent: number; human_time_estimate: string | null; human_total_time_spent: string | null; } export interface IssueSchema extends Record { state: string; description: string; health_status?: string; weight?: number; author: MappedOmit; milestone?: MilestoneSchema; project_id: number; assignees?: MappedOmit[]; type: string; updated_at: string; closed_at?: string; closed_by?: string; id: number; title: string; created_at: string; moved_to_id?: string; iid: number; labels: string[] | SimpleLabelSchema[]; upvotes: number; downvotes: number; merge_requests_count: number; user_notes_count: number; due_date: string; web_url: string; references: { short: string; relative: string; full: string; }; time_stats: TimeStatsSchema; has_tasks: boolean; task_status: string; confidential: boolean; discussion_locked: boolean; _links: { self: string; notes: string; award_emoji: string; project: string; }; task_completion_status: { count: number; completed_count: number; }; subscribed: boolean; epic?: { id: number; iid: number; title: string; url: string; group_id: number; }; service_desk_reply_to?: string; } export interface IssueSchemaWithExpandedLabels extends IssueSchema { labels: SimpleLabelSchema[]; } export interface IssueSchemaWithBasicLabels extends IssueSchema { labels: string[]; } export type AllIssuesOptions = { assigneeId?: number; assigneeUsername?: string[]; authorId?: number; authorUsername?: string; confidential?: boolean; createdAfter?: string; createdBefore?: string; dueDate?: string; epicId?: number; healthStatus?: string; iids?: number[]; in?: string; issueType?: string; iterationId?: number; iterationTitle?: string; labels?: string; milestone?: string; milestoneId?: string; myReactionEmoji?: string; nonArchived?: boolean; not?: Record; orderBy?: string; scope?: string; search?: string; sort?: string; state?: string; updatedAfter?: string; updatedBefore?: string; weight?: number; withLabelsDetails?: boolean; }; export type CreateIssueOptions = { assigneeId?: number; assigneeIds?: number[]; confidential?: boolean; createdAt?: string; description?: string; discussionToResolve?: string; dueDate?: string; epicId?: number; epicIid?: number; iid?: number | string; issueType?: string; labels?: string; mergeRequestToResolveDiscussionsOf?: number; milestoneId?: number; weight?: number; }; export type EditIssueOptions = { addLabels?: string; assigneeId?: number; assigneeIds?: number[]; confidential?: boolean; description?: string; discussionLocked?: boolean; dueDate?: string; epicId?: number; epicIid?: number; issueType?: string; labels?: string; milestoneId?: number; removeLabels?: string; stateEvent?: string; title?: string; updatedAt?: string; weight?: number; }; export class Issues extends BaseResource { addSpentTime( projectId: string | number, issueIId: number, duration: string, options?: { summary?: string } & Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/add_spent_time`, { duration, ...options, }, ); } addTimeEstimate( projectId: string | number, issueIId: number, duration: string, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/time_estimate`, { duration, ...options, }, ); } all( options: OneOrNoneOf<{ projectId: string | number; groupId: string | number }> & PaginationRequestOptions

& Sudo & ShowExpanded & AllIssuesOptions & { withLabelsDetails: true }, ): Promise>; all( options?: OneOrNoneOf<{ projectId: string | number; groupId: string | number }> & PaginationRequestOptions

& Sudo & ShowExpanded & AllIssuesOptions & BaseRequestOptions & { withLabelsDetails?: false }, ): Promise>; all( { projectId, groupId, ...options }: OneOrNoneOf<{ projectId: string | number; groupId: string | number }> & PaginationRequestOptions

& Sudo & ShowExpanded & AllIssuesOptions & BaseRequestOptions = {} as any, ): Promise> { let url: string; if (projectId) url = endpoint`projects/${projectId}/issues`; else if (groupId) url = endpoint`groups/${groupId}/issues`; else url = 'issues'; return RequestHelper.get()(this, url, options); } allMetricImages( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.get()( this, endpoint`projects/${projectId}/issues/${issueIId}/metric_images`, options, ); } allParticipants( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise[], C, E, void>> { return RequestHelper.get[]>()( this, endpoint`projects/${projectId}/issues/${issueIId}/participants`, options, ); } allRelatedMergeRequests( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.get()( this, endpoint`projects/${projectId}/issues/${issueIId}/related_merge_requests`, options, ); } create( projectId: string | number, title: string, options?: CreateIssueOptions & Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()(this, endpoint`projects/${projectId}/issues`, { ...options, title, }); } createTodo( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/todo`, options, ); } clone( projectId: string | number, issueIId: number, destinationProjectId: string | number, options?: { withNotes?: boolean } & Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/clone`, { toProjectId: destinationProjectId, ...options, }, ); } edit( projectId: string | number, issueIId: number, options?: EditIssueOptions & Sudo & ShowExpanded, ): Promise> { return RequestHelper.put()( this, endpoint`projects/${projectId}/issues/${issueIId}`, options, ); } editMetricImage( projectId: string | number, issueIId: number, imageId: number, options?: { url?: string; urlText?: string } & Sudo & ShowExpanded, ): Promise> { return RequestHelper.put()( this, endpoint`projects/${projectId}/issues/${issueIId}/metric_images/${imageId}`, options, ); } move( projectId: string | number, issueIId: number, destinationProjectId: string | number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/move`, { toProjectId: destinationProjectId, ...options, }, ); } // Includes /promote already! promote( projectId: string | number, issueIId: number, body: string, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/notes`, { searchParams: { body: `${body} \n /promote`, }, ...options, }, ); } remove( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.del()(this, endpoint`projects/${projectId}/issues/${issueIId}`, options); } removeMetricImage( projectId: string | number, issueIId: number, imageId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.del()( this, endpoint`projects/${projectId}/issues/${issueIId}/metric_images/${imageId}`, options, ); } reorder( projectId: string | number, issueIId: number, options?: { moveAfterId?: number; moveBeforeId?: number } & Sudo & ShowExpanded, ): Promise> { return RequestHelper.put()( this, endpoint`projects/${projectId}/issues/${issueIId}/reorder`, options, ); } resetSpentTime( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/reset_spent_time`, options, ); } resetTimeEstimate( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/reset_time_estimate`, options, ); } show( issueId: number, { projectId, ...options }: { projectId?: string | number } & Sudo & ShowExpanded = {}, ): Promise> { const url = projectId ? endpoint`projects/${projectId}/issues/${issueId}` : `issues/${issueId}`; return RequestHelper.get()(this, url, options as Sudo & ShowExpanded); } subscribe( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/subscribe`, options, ); } allClosedByMergeRequestst( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.get()( this, endpoint`projects/${projectId}/issues/${issueIId}/closed_by`, options, ); } showTimeStats( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.get()( this, endpoint`projects/${projectId}/issues/${issueIId}/time_stats`, options, ); } unsubscribe( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/unsubscribe`, options, ); } uploadMetricImage( projectId: string | number, issueIId: number, metricImage: { content: Blob; filename: string }, options?: { url?: string; urlText?: string } & Sudo & ShowExpanded, ): Promise> { return RequestHelper.post()( this, endpoint`projects/${projectId}/issues/${issueIId}/metric_images`, { isForm: true, ...options, file: [metricImage.content, metricImage.filename], }, ); } showUserAgentDetails( projectId: string | number, issueIId: number, options?: Sudo & ShowExpanded, ): Promise> { return RequestHelper.get()( this, endpoint`projects/${projectId}/issues/${issueIId}/user_agent_details`, options, ); } }