Skip to content

Commit 24cfe45

Browse files
committed
feat: api-client module for tech review
1 parent 6e2096d commit 24cfe45

File tree

4 files changed

+193
-0
lines changed

4 files changed

+193
-0
lines changed

packages/api-client/src/modules/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { LabrinthBillingInternalModule } from './labrinth/billing/internal'
88
import { LabrinthProjectsV2Module } from './labrinth/projects/v2'
99
import { LabrinthProjectsV3Module } from './labrinth/projects/v3'
1010
import { LabrinthStateModule } from './labrinth/state'
11+
import { LabrinthTechReviewInternalModule } from './labrinth/tech-review/internal'
1112

1213
type ModuleConstructor = new (client: AbstractModrinthClient) => AbstractModule
1314

@@ -29,6 +30,7 @@ export const MODULE_REGISTRY = {
2930
labrinth_projects_v2: LabrinthProjectsV2Module,
3031
labrinth_projects_v3: LabrinthProjectsV3Module,
3132
labrinth_state: LabrinthStateModule,
33+
labrinth_tech_review_internal: LabrinthTechReviewInternalModule,
3234
} as const satisfies Record<string, ModuleConstructor>
3335

3436
export type ModuleID = keyof typeof MODULE_REGISTRY

packages/api-client/src/modules/labrinth/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './billing/internal'
22
export * from './projects/v2'
33
export * from './projects/v3'
44
export * from './state'
5+
export * from './tech-review/internal'
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { AbstractModule } from '../../../core/abstract-module'
2+
import type { Labrinth } from '../types'
3+
4+
export class LabrinthTechReviewInternalModule extends AbstractModule {
5+
public getModuleID(): string {
6+
return 'labrinth_tech_review_internal'
7+
}
8+
9+
/**
10+
* Search for projects awaiting technical review.
11+
*
12+
* Returns a list of projects that have been flagged for technical review,
13+
* along with their associated reports, ownership information, and moderation threads.
14+
*
15+
* @param params - Search parameters including pagination, filters, and sorting
16+
* @returns Array of projects with their technical review details
17+
*
18+
* @example
19+
* ```typescript
20+
* const reviews = await client.labrinth.tech_review_internal.searchProjects({
21+
* limit: 20,
22+
* page: 0,
23+
* sort_by: 'CreatedAsc',
24+
* filter: {
25+
* project_type: ['mod', 'modpack']
26+
* }
27+
* })
28+
* ```
29+
*/
30+
public async searchProjects(
31+
params: Labrinth.TechReview.Internal.SearchProjectsRequest,
32+
): Promise<Labrinth.TechReview.Internal.ProjectReview[]> {
33+
return this.client.request<Labrinth.TechReview.Internal.ProjectReview[]>(
34+
'/moderation/tech-review/search',
35+
{
36+
api: 'labrinth',
37+
version: 'internal',
38+
method: 'POST',
39+
body: params,
40+
},
41+
)
42+
}
43+
44+
/**
45+
* Update the status of a technical review issue.
46+
*
47+
* Allows moderators to mark an issue as safe (false positive), unsafe (malicious),
48+
* or leave it as pending for further review.
49+
*
50+
* @param issueId - The ID of the issue to update
51+
* @param data - The new status for the issue
52+
* @returns Promise that resolves when the update is complete
53+
*
54+
* @example
55+
* ```typescript
56+
* await client.labrinth.tech_review_internal.updateIssue('issue-123', {
57+
* status: 'safe'
58+
* })
59+
* ```
60+
*/
61+
public async updateIssue(
62+
issueId: string,
63+
data: Labrinth.TechReview.Internal.UpdateIssueRequest,
64+
): Promise<void> {
65+
return this.client.request<void>(`/moderation/tech-review/issue/${issueId}`, {
66+
api: 'labrinth',
67+
version: 'internal',
68+
method: 'POST',
69+
body: data,
70+
})
71+
}
72+
}

packages/api-client/src/modules/labrinth/types.ts

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,4 +450,122 @@ export namespace Labrinth {
450450
errors: unknown[]
451451
}
452452
}
453+
454+
export namespace TechReview {
455+
export namespace Internal {
456+
export type SearchProjectsRequest = {
457+
limit?: number
458+
page?: number
459+
filter?: SearchProjectsFilter
460+
sort_by?: SearchProjectsSort
461+
}
462+
463+
export type SearchProjectsFilter = {
464+
project_type?: string[]
465+
}
466+
467+
export type SearchProjectsSort = 'CreatedAsc' | 'CreatedDesc'
468+
469+
export type UpdateIssueRequest = {
470+
status: DelphiReportIssueStatus
471+
}
472+
473+
export type ProjectReview = {
474+
project: Projects.v3.Project
475+
project_owner: Ownership
476+
thread: DBThread
477+
reports: ProjectReport[]
478+
}
479+
480+
export type ProjectReport = {
481+
created_at: string
482+
flag_reason: FlagReason
483+
severity: DelphiSeverity
484+
files: FileReview[]
485+
}
486+
487+
export type FileReview = {
488+
file_name: string
489+
file_size: number
490+
issues: FileIssue[]
491+
}
492+
493+
export type FileIssue = {
494+
issue_id: string
495+
kind: string
496+
status: DelphiReportIssueStatus
497+
details: FileIssueDetail[]
498+
}
499+
500+
export type FileIssueDetail = {
501+
class_name: string
502+
decompiled_source: string
503+
severity: DelphiSeverity
504+
}
505+
506+
export type Ownership =
507+
| {
508+
kind: 'user'
509+
id: string
510+
name: string
511+
icon_url?: string
512+
}
513+
| {
514+
kind: 'organization'
515+
id: string
516+
name: string
517+
icon_url?: string
518+
}
519+
520+
export type DBThread = {
521+
id: string
522+
project_id?: string
523+
report_id?: string
524+
type_: ThreadType
525+
messages: DBThreadMessage[]
526+
members: string[]
527+
}
528+
529+
export type DBThreadMessage = {
530+
id: string
531+
thread_id: string
532+
author_id?: string
533+
body: MessageBody
534+
created: string
535+
hide_identity: boolean
536+
}
537+
538+
export type MessageBody =
539+
| {
540+
type: 'text'
541+
body: string
542+
private?: boolean
543+
replying_to?: string
544+
associated_images?: string[]
545+
}
546+
| {
547+
type: 'status_change'
548+
new_status: Projects.v2.ProjectStatus
549+
old_status: Projects.v2.ProjectStatus
550+
}
551+
| {
552+
type: 'thread_closure'
553+
}
554+
| {
555+
type: 'thread_reopen'
556+
}
557+
| {
558+
type: 'deleted'
559+
private?: boolean
560+
}
561+
562+
export type ThreadType = 'report' | 'project' | 'direct_message'
563+
564+
export type FlagReason = 'delphi'
565+
566+
export type DelphiSeverity = 'LOW' | 'MEDIUM' | 'HIGH' | 'SEVERE'
567+
568+
export type DelphiReportIssueStatus = 'pending' | 'safe' | 'unsafe'
569+
}
570+
}
453571
}

0 commit comments

Comments
 (0)