refactor: remove useBaseFetch for @modrinth/api-client (#5596)

* Reapply "fix: start swapping useBaseFetch usages to api-client"

This reverts commit f4f33db7019ea861addb2c66c204d736800b7b6c.

* fix: bugs

* fix: analytics

* fix: lint
This commit is contained in:
Calum H.
2026-03-17 20:06:19 +00:00
committed by GitHub
parent 58c1e225c8
commit 87c86c7d0d
64 changed files with 2073 additions and 691 deletions

View File

@@ -41,7 +41,7 @@ export class ArchonServersV0Module extends AbstractModule {
/**
* Check stock availability for a region
* POST /modrinth/v0/stock
* POST /modrinth/v0/stock?region=:region
*/
public async checkStock(
region: string,
@@ -52,6 +52,23 @@ export class ArchonServersV0Module extends AbstractModule {
version: 'modrinth/v0',
method: 'POST',
body: request,
skipAuth: true,
})
}
/**
* Check stock availability (without region filter)
* POST /modrinth/v0/stock
*/
public async checkStockGlobal(
request: Archon.Servers.v0.StockRequest,
): Promise<Archon.Servers.v0.StockResponse> {
return this.client.request<Archon.Servers.v0.StockResponse>('/stock', {
api: 'archon',
version: 'modrinth/v0',
method: 'POST',
body: request,
skipAuth: true,
})
}

View File

@@ -39,6 +39,7 @@ export class ArchonServersV1Module extends AbstractModule {
api: 'archon',
version: 1,
method: 'GET',
skipAuth: true,
})
}

View File

@@ -10,15 +10,28 @@ import { ISO3166Module } from './iso3166'
import { KyrosContentV1Module } from './kyros/content/v1'
import { KyrosFilesV0Module } from './kyros/files/v0'
import { LabrinthVersionsV2Module, LabrinthVersionsV3Module } from './labrinth'
import { LabrinthAffiliateInternalModule } from './labrinth/affiliate/internal'
import { LabrinthAuthInternalModule } from './labrinth/auth/internal'
import { LabrinthAuthV2Module } from './labrinth/auth/v2'
import { LabrinthBillingInternalModule } from './labrinth/billing/internal'
import { LabrinthGlobalsInternalModule } from './labrinth/globals/internal'
import { LabrinthNotificationsV2Module } from './labrinth/notifications/v2'
import { LabrinthOAuthInternalModule } from './labrinth/oauth/internal'
import { LabrinthCollectionsModule } from './labrinth/collections'
import { LabrinthOrganizationsV3Module } from './labrinth/organizations/v3'
import { LabrinthPatsV2Module } from './labrinth/pats/v2'
import { LabrinthLimitsV3Module } from './labrinth/limits/v3'
import { LabrinthPayoutV3Module } from './labrinth/payout/v3'
import { LabrinthPayoutsV3Module } from './labrinth/payouts/v3'
import { LabrinthReportsV3Module } from './labrinth/reports/v3'
import { LabrinthProjectsV2Module } from './labrinth/projects/v2'
import { LabrinthProjectsV3Module } from './labrinth/projects/v3'
import { LabrinthServerPingInternalModule } from './labrinth/server-ping/internal'
import { LabrinthSessionsV2Module } from './labrinth/sessions/v2'
import { LabrinthStateModule } from './labrinth/state'
import { LabrinthTagsV2Module } from './labrinth/tags/v2'
import { LabrinthTeamsV2Module } from './labrinth/teams/v2'
import { LabrinthTeamsV3Module } from './labrinth/teams/v3'
import { LabrinthTechReviewInternalModule } from './labrinth/tech-review/internal'
import { LabrinthThreadsV3Module } from './labrinth/threads/v3'
import { LabrinthUsersV2Module } from './labrinth/users/v2'
@@ -48,15 +61,28 @@ export const MODULE_REGISTRY = {
launchermeta_manifest_v0: LauncherMetaManifestV0Module,
kyros_content_v1: KyrosContentV1Module,
kyros_files_v0: KyrosFilesV0Module,
labrinth_affiliate_internal: LabrinthAffiliateInternalModule,
labrinth_auth_internal: LabrinthAuthInternalModule,
labrinth_auth_v2: LabrinthAuthV2Module,
labrinth_billing_internal: LabrinthBillingInternalModule,
labrinth_collections: LabrinthCollectionsModule,
labrinth_globals_internal: LabrinthGlobalsInternalModule,
labrinth_notifications_v2: LabrinthNotificationsV2Module,
labrinth_oauth_internal: LabrinthOAuthInternalModule,
labrinth_organizations_v3: LabrinthOrganizationsV3Module,
labrinth_pats_v2: LabrinthPatsV2Module,
labrinth_limits_v3: LabrinthLimitsV3Module,
labrinth_payout_v3: LabrinthPayoutV3Module,
labrinth_payouts_v3: LabrinthPayoutsV3Module,
labrinth_projects_v2: LabrinthProjectsV2Module,
labrinth_projects_v3: LabrinthProjectsV3Module,
labrinth_reports_v3: LabrinthReportsV3Module,
labrinth_server_ping_internal: LabrinthServerPingInternalModule,
labrinth_sessions_v2: LabrinthSessionsV2Module,
labrinth_state: LabrinthStateModule,
labrinth_tags_v2: LabrinthTagsV2Module,
labrinth_teams_v2: LabrinthTeamsV2Module,
labrinth_teams_v3: LabrinthTeamsV3Module,
labrinth_tech_review_internal: LabrinthTechReviewInternalModule,
labrinth_threads_v3: LabrinthThreadsV3Module,
labrinth_users_v2: LabrinthUsersV2Module,

View File

@@ -0,0 +1,72 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthAffiliateInternalModule extends AbstractModule {
public getModuleID(): string {
return 'labrinth_affiliate_internal'
}
/**
* Get all affiliate codes for the authenticated user (or all if admin)
* GET /_internal/affiliate
*/
public async getAll(): Promise<Labrinth.Affiliate.Internal.AffiliateCode[]> {
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode[]>('/affiliate', {
api: 'labrinth',
version: 'internal',
method: 'GET',
})
}
/**
* Create a new affiliate code
* PUT /_internal/affiliate
*/
public async create(
data: Labrinth.Affiliate.Internal.CreateRequest,
): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>('/affiliate', {
api: 'labrinth',
version: 'internal',
method: 'PUT',
body: data,
})
}
/**
* Get a specific affiliate code by ID
* GET /_internal/affiliate/{id}
*/
public async get(id: string): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {
return this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>(`/affiliate/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'GET',
})
}
/**
* Delete an affiliate code
* DELETE /_internal/affiliate/{id}
*/
public async delete(id: string): Promise<void> {
return this.client.request<void>(`/affiliate/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'DELETE',
})
}
/**
* Update an affiliate code's source name
* PATCH /_internal/affiliate/{id}
*/
public async patch(id: string, data: Labrinth.Affiliate.Internal.PatchRequest): Promise<void> {
return this.client.request<void>(`/affiliate/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'PATCH',
body: data,
})
}
}

View File

@@ -0,0 +1,87 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthAuthV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_auth_v2'
}
/**
* Log in with a password
*
* Returns a session token on success, or a flow ID if 2FA is required.
*
* @param data - Login credentials and captcha challenge
* @returns Promise resolving to a login response with session or flow
*/
public async login(data: Labrinth.Auth.v2.LoginRequest): Promise<Labrinth.Auth.v2.LoginResponse> {
return this.client.request<Labrinth.Auth.v2.LoginResponse>(`/auth/login`, {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Complete a 2FA login flow
*
* @param data - The 2FA code and flow ID
* @returns Promise resolving to a session response
*/
public async login2FA(
data: Labrinth.Auth.v2.Login2FARequest,
): Promise<Labrinth.Auth.v2.Login2FAResponse> {
return this.client.request<Labrinth.Auth.v2.Login2FAResponse>(`/auth/login/2fa`, {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Create a new account with a password
*
* @param data - Account creation data
* @returns Promise resolving to a session response
*/
public async createAccount(
data: Labrinth.Auth.v2.CreateAccountRequest,
): Promise<Labrinth.Auth.v2.CreateAccountResponse> {
return this.client.request<Labrinth.Auth.v2.CreateAccountResponse>(`/auth/create`, {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Begin a password reset flow by sending a recovery email
*
* @param data - The username/email and captcha challenge
*/
public async resetPasswordBegin(data: Labrinth.Auth.v2.ResetPasswordRequest): Promise<void> {
return this.client.request(`/auth/password/reset`, {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Change a user's password (via reset flow or with old password)
*
* @param data - The password change data
*/
public async changePassword(data: Labrinth.Auth.v2.ChangePasswordRequest): Promise<void> {
return this.client.request(`/auth/password`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
body: data,
})
}
}

View File

@@ -0,0 +1,22 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthGlobalsInternalModule extends AbstractModule {
public getModuleID(): string {
return 'labrinth_globals_internal'
}
/**
* Get configured global non-secret variables for this backend instance
*
* @returns Promise resolving to the global configuration
*/
public async get(): Promise<Labrinth.Globals.Internal.Globals> {
return this.client.request<Labrinth.Globals.Internal.Globals>(`/globals`, {
api: 'labrinth',
version: 'internal',
method: 'GET',
skipAuth: true,
})
}
}

View File

@@ -1,11 +1,20 @@
export * from './auth/internal'
export * from './auth/v2'
export * from './billing/internal'
export * from './collections'
export * from './globals/internal'
export * from './notifications/v2'
export * from './oauth/internal'
export * from './organizations/v3'
export * from './pats/v2'
export * from './limits/v3'
export * from './payout/v3'
export * from './payouts/v3'
export * from './projects/v2'
export * from './projects/v3'
export * from './reports/v3'
export * from './server-ping/internal'
export * from './sessions/v2'
export * from './state'
export * from './tech-review/internal'
export * from './threads/v3'

View File

@@ -0,0 +1,41 @@
import { AbstractModule } from '../../../core/abstract-module.js'
import type { Labrinth } from '../types'
export class LabrinthLimitsV3Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_limits_v3'
}
/**
* Get project creation limits for the authenticated user.
*/
public async getProjectLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/projects', {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
/**
* Get organization creation limits for the authenticated user.
*/
public async getOrganizationLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/organizations', {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
/**
* Get collection creation limits for the authenticated user.
*/
public async getCollectionLimits(): Promise<Labrinth.Limits.v3.UserLimits> {
return this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/collections', {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
}

View File

@@ -0,0 +1,128 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthNotificationsV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_notifications_v2'
}
/**
* Get all notifications for a user
*
* @param userId - The user's ID
* @returns Promise resolving to the user's notifications
*
* @example
* ```typescript
* const notifications = await client.labrinth.notifications_v2.getUserNotifications('user123')
* ```
*/
public async getUserNotifications(
userId: string,
): Promise<Labrinth.Notifications.v2.Notification[]> {
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
`/user/${userId}/notifications`,
{
api: 'labrinth',
version: 2,
method: 'GET',
},
)
}
/**
* Get multiple notifications by their IDs
*
* @param ids - Array of notification IDs
* @returns Promise resolving to an array of notifications
*
* @example
* ```typescript
* const notifications = await client.labrinth.notifications_v2.getMultiple(['id1', 'id2'])
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Notifications.v2.Notification[]> {
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
`/notifications?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 2,
method: 'GET',
},
)
}
/**
* Mark a single notification as read
*
* @param id - Notification ID
*
* @example
* ```typescript
* await client.labrinth.notifications_v2.markAsRead('notif123')
* ```
*/
public async markAsRead(id: string): Promise<void> {
return this.client.request(`/notification/${id}`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
})
}
/**
* Mark multiple notifications as read
*
* @param ids - Array of notification IDs to mark as read
*
* @example
* ```typescript
* await client.labrinth.notifications_v2.markMultipleAsRead(['id1', 'id2'])
* ```
*/
public async markMultipleAsRead(ids: string[]): Promise<void> {
return this.client.request(`/notifications`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
params: { ids: JSON.stringify([...new Set(ids)]) },
})
}
/**
* Delete a single notification
*
* @param id - Notification ID
*
* @example
* ```typescript
* await client.labrinth.notifications_v2.delete('notif123')
* ```
*/
public async delete(id: string): Promise<void> {
return this.client.request(`/notification/${id}`, {
api: 'labrinth',
version: 2,
method: 'DELETE',
})
}
/**
* Delete multiple notifications
*
* @param ids - Array of notification IDs to delete
*
* @example
* ```typescript
* await client.labrinth.notifications_v2.deleteMultiple(['id1', 'id2'])
* ```
*/
public async deleteMultiple(ids: string[]): Promise<void> {
return this.client.request(`/notifications`, {
api: 'labrinth',
version: 2,
method: 'DELETE',
params: { ids: JSON.stringify([...new Set(ids)]) },
})
}
}

View File

@@ -0,0 +1,208 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { UploadHandle } from '../../../types/upload'
import type { Labrinth } from '../types'
export class LabrinthOAuthInternalModule extends AbstractModule {
public getModuleID(): string {
return 'labrinth_oauth_internal'
}
/**
* Get a user's OAuth applications
*
* @param userId - The user's ID
* @returns Promise resolving to an array of the user's OAuth clients
*/
public async getUserApps(userId: string): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(
`/user/${userId}/oauth_apps`,
{
api: 'labrinth',
version: 3,
method: 'GET',
},
)
}
/**
* Get a single OAuth application by ID
*
* @param id - The OAuth client ID
* @returns Promise resolving to the OAuth client
*/
public async getApp(id: string): Promise<Labrinth.OAuth.Internal.OAuthClient> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClient>(`/oauth/app/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'GET',
})
}
/**
* Get multiple OAuth applications by their IDs
*
* @param ids - Array of OAuth client IDs
* @returns Promise resolving to an array of OAuth clients
*/
public async getApps(ids: string[]): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(
`/oauth/apps?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 'internal',
method: 'GET',
},
)
}
/**
* Create a new OAuth application
*
* @param data - The OAuth app creation data
* @returns Promise resolving to the created OAuth client with its client secret
*/
public async createApp(
data: Labrinth.OAuth.Internal.CreateOAuthAppRequest,
): Promise<Labrinth.OAuth.Internal.OAuthClientCreationResult> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClientCreationResult>(`/oauth/app`, {
api: 'labrinth',
version: 'internal',
method: 'POST',
body: data,
})
}
/**
* Edit an existing OAuth application
*
* @param id - The OAuth client ID
* @param data - The fields to update
*/
public async editApp(
id: string,
data: Labrinth.OAuth.Internal.EditOAuthAppRequest,
): Promise<void> {
return this.client.request(`/oauth/app/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'PATCH',
body: data,
})
}
/**
* Delete an OAuth application
*
* @param id - The OAuth client ID
*/
public async deleteApp(id: string): Promise<void> {
return this.client.request(`/oauth/app/${id}`, {
api: 'labrinth',
version: 'internal',
method: 'DELETE',
})
}
/**
* Update the icon for an OAuth application
*
* @param id - The OAuth client ID
* @param file - The icon file
* @param ext - The file extension (e.g. 'png', 'jpeg')
* @returns UploadHandle for progress tracking and cancellation
*/
public uploadAppIcon(id: string, file: File | Blob, ext: string): UploadHandle<void> {
return this.client.upload<void>(`/oauth/app/${id}/icon`, {
api: 'labrinth',
version: 'internal',
file,
params: { ext },
})
}
/**
* Get the current user's OAuth authorizations
*
* @returns Promise resolving to an array of OAuth client authorizations
*/
public async getAuthorizations(): Promise<Labrinth.OAuth.Internal.OAuthClientAuthorization[]> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClientAuthorization[]>(
`/oauth/authorizations`,
{
api: 'labrinth',
version: 'internal',
method: 'GET',
},
)
}
/**
* Revoke an OAuth authorization for a client
*
* @param clientId - The OAuth client ID to revoke
*/
public async revokeAuthorization(clientId: string): Promise<void> {
return this.client.request(`/oauth/authorizations`, {
api: 'labrinth',
version: 'internal',
method: 'DELETE',
params: { client_id: clientId },
})
}
/**
* Initialize an OAuth authorization flow
*
* Returns either an OAuthClientAccessRequest (if user needs to approve)
* or a redirect URL string (if already authorized).
*
* @param params - The OAuth query parameters
* @returns Promise resolving to an access request object or redirect URL string
*/
public async authorize(params: {
client_id: string
redirect_uri: string
scope: string
state?: string
}): Promise<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string> {
return this.client.request<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string>(
`/oauth/authorize`,
{
api: 'labrinth',
version: 'internal',
method: 'GET',
params: params as Record<string, string>,
},
)
}
/**
* Accept an OAuth authorization request
*
* @param data - The flow ID to accept
* @returns Promise resolving to a redirect URL string
*/
public async accept(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {
return this.client.request<string>(`/oauth/accept`, {
api: 'labrinth',
version: 'internal',
method: 'POST',
body: data,
})
}
/**
* Reject an OAuth authorization request
*
* @param data - The flow ID to reject
* @returns Promise resolving to a redirect URL string
*/
public async reject(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {
return this.client.request<string>(`/oauth/reject`, {
api: 'labrinth',
version: 'internal',
method: 'POST',
body: data,
})
}
}

View File

@@ -49,4 +49,74 @@ export class LabrinthOrganizationsV3Module extends AbstractModule {
},
)
}
/**
* Get multiple organizations by their IDs
*
* @param ids - Array of organization IDs
* @returns Promise resolving to an array of organizations
*
* @example
* ```typescript
* const orgs = await client.labrinth.organizations_v3.getMultiple(['id1', 'id2'])
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Organizations.v3.Organization[]> {
return this.client.request<Labrinth.Organizations.v3.Organization[]>(
`/organizations?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 3,
method: 'GET',
},
)
}
/**
* Add a project to an organization
*
* @param idOrSlug - Organization ID or slug
* @param request - The project to add
*
* @example
* ```typescript
* await client.labrinth.organizations_v3.addProject('my-org', { project_id: 'AABBCCDD' })
* ```
*/
public async addProject(
idOrSlug: string,
request: Labrinth.Organizations.v3.AddProjectRequest,
): Promise<void> {
return this.client.request(`/organization/${idOrSlug}/projects`, {
api: 'labrinth',
version: 3,
method: 'POST',
body: request,
})
}
/**
* Remove a project from an organization
*
* @param idOrSlug - Organization ID or slug
* @param projectId - Project ID to remove
* @param data - Request body containing the new_owner user ID
*
* @example
* ```typescript
* await client.labrinth.organizations_v3.removeProject('my-org', 'proj123', { new_owner: 'user456' })
* ```
*/
public async removeProject(
idOrSlug: string,
projectId: string,
data: Labrinth.Organizations.v3.RemoveProjectRequest,
): Promise<void> {
return this.client.request(`/organization/${idOrSlug}/projects/${projectId}`, {
api: 'labrinth',
version: 3,
method: 'DELETE',
body: data,
})
}
}

View File

@@ -0,0 +1,66 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthPatsV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_pats_v2'
}
/**
* Get all personal access tokens for the authenticated user
*
* @returns Promise resolving to an array of PATs
*/
public async list(): Promise<Labrinth.Pats.v2.PersonalAccessToken[]> {
return this.client.request<Labrinth.Pats.v2.PersonalAccessToken[]>('/pat', {
api: 'labrinth',
version: 2,
method: 'GET',
})
}
/**
* Create a new personal access token
*
* @param data - The PAT creation request data
* @returns Promise resolving to the newly created PAT (includes access_token)
*/
public async create(
data: Labrinth.Pats.v2.CreatePatRequest,
): Promise<Labrinth.Pats.v2.PersonalAccessToken> {
return this.client.request<Labrinth.Pats.v2.PersonalAccessToken>('/pat', {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Modify an existing personal access token
*
* @param id - The PAT ID
* @param data - The fields to update
*/
public async modify(id: string, data: Labrinth.Pats.v2.ModifyPatRequest): Promise<void> {
return this.client.request(`/pat/${id}`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
body: data,
})
}
/**
* Delete a personal access token
*
* @param id - The PAT ID
*/
public async delete(id: string): Promise<void> {
return this.client.request(`/pat/${id}`, {
api: 'labrinth',
version: 2,
method: 'DELETE',
})
}
}

View File

@@ -18,4 +18,45 @@ export class LabrinthPayoutV3Module extends AbstractModule {
method: 'GET',
})
}
/**
* Get the authenticated user's transaction history (withdrawals and payouts)
*
* @returns Promise resolving to an array of transaction items
*/
public async getHistory(): Promise<Labrinth.Payout.v3.TransactionItem[]> {
return this.client.request<Labrinth.Payout.v3.TransactionItem[]>('/payout/history', {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
/**
* Get available payout methods, optionally filtered by country
*
* @param country - Optional ISO country code to filter methods by supported countries
* @returns Promise resolving to an array of payout methods
*/
public async getMethods(country?: string): Promise<Labrinth.Payout.v3.PayoutMethod[]> {
return this.client.request<Labrinth.Payout.v3.PayoutMethod[]>('/payout/methods', {
api: 'labrinth',
version: 3,
method: 'GET',
params: country ? { country } : undefined,
})
}
/**
* Cancel a pending payout
*
* @param id - The payout ID to cancel
*/
public async cancel(id: string): Promise<void> {
return this.client.request<void>(`/payout/${id}`, {
api: 'labrinth',
version: 3,
method: 'DELETE',
})
}
}

View File

@@ -0,0 +1,26 @@
import { AbstractModule } from '../../../core/abstract-module.js'
import type { Labrinth } from '../types'
export class LabrinthPayoutsV3Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_payouts_v3'
}
/**
* Get platform revenue data.
*
* @param params - Optional start/end date filters
* @returns Promise resolving to platform revenue data
*/
public async getPlatformRevenue(params?: {
start?: string
end?: string
}): Promise<Labrinth.Payouts.v3.RevenueResponse> {
return this.client.request<Labrinth.Payouts.v3.RevenueResponse>('/payout/platform_revenue', {
api: 'labrinth',
version: 3,
method: 'GET',
params: params as Record<string, string>,
})
}
}

View File

@@ -256,4 +256,31 @@ export class LabrinthProjectsV2Module extends AbstractModule {
params: { count: String(count) },
})
}
/**
* Bulk edit multiple projects at once
*
* @param ids - Array of project IDs to edit
* @param data - Fields to update across all specified projects
*
* @example
* ```typescript
* await client.labrinth.projects_v2.bulkEdit(['id1', 'id2'], {
* issues_url: 'https://github.com/issues',
* source_url: null,
* })
* ```
*/
public async bulkEdit(
ids: string[],
data: Labrinth.Projects.v2.BulkEditProjectRequest,
): Promise<void> {
return this.client.request(`/projects`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
params: { ids: JSON.stringify(ids) },
body: data,
})
}
}

View File

@@ -0,0 +1,141 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthReportsV3Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_reports_v3'
}
/**
* Get a report by ID
*
* @param id - Report ID
* @returns Promise resolving to the report data
*
* @example
* ```typescript
* const report = await client.labrinth.reports_v3.get('abc123')
* ```
*/
public async get(id: string): Promise<Labrinth.Reports.v3.Report> {
return this.client.request<Labrinth.Reports.v3.Report>(`/report/${id}`, {
api: 'labrinth',
version: 3,
method: 'GET',
})
}
/**
* List reports for the current user (or all reports if moderator)
*
* @param params - Optional query parameters for count, offset, and whether to show all reports
* @returns Promise resolving to an array of reports
*
* @example
* ```typescript
* const reports = await client.labrinth.reports_v3.list({ count: 100 })
* ```
*/
public async list(
params?: Labrinth.Reports.v3.ListReportsParams,
): Promise<Labrinth.Reports.v3.Report[]> {
const queryParams: Record<string, string> = {}
if (params?.count != null) queryParams.count = String(params.count)
if (params?.offset != null) queryParams.offset = String(params.offset)
if (params?.all != null) queryParams.all = String(params.all)
return this.client.request<Labrinth.Reports.v3.Report[]>(`/report`, {
api: 'labrinth',
version: 3,
method: 'GET',
params: Object.keys(queryParams).length > 0 ? queryParams : undefined,
})
}
/**
* Get multiple reports by IDs
*
* @param ids - Array of report IDs
* @returns Promise resolving to an array of reports
*
* @example
* ```typescript
* const reports = await client.labrinth.reports_v3.getMultiple(['id1', 'id2'])
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Reports.v3.Report[]> {
return this.client.request<Labrinth.Reports.v3.Report[]>(
`/reports?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 3,
method: 'GET',
},
)
}
/**
* Create a new report
*
* @param data - Report creation data
* @returns Promise resolving to the created report
*
* @example
* ```typescript
* const report = await client.labrinth.reports_v3.create({
* report_type: 'spam',
* item_id: 'project123',
* item_type: 'project',
* body: 'This project is spam',
* })
* ```
*/
public async create(
data: Labrinth.Reports.v3.CreateReportRequest,
): Promise<Labrinth.Reports.v3.Report> {
return this.client.request<Labrinth.Reports.v3.Report>(`/report`, {
api: 'labrinth',
version: 3,
method: 'POST',
body: data,
})
}
/**
* Edit a report
*
* @param id - Report ID
* @param data - Report edit data
*
* @example
* ```typescript
* await client.labrinth.reports_v3.edit('abc123', { closed: true })
* ```
*/
public async edit(id: string, data: Labrinth.Reports.v3.EditReportRequest): Promise<void> {
return this.client.request(`/report/${id}`, {
api: 'labrinth',
version: 3,
method: 'PATCH',
body: data,
})
}
/**
* Delete a report (moderator only)
*
* @param id - Report ID
*
* @example
* ```typescript
* await client.labrinth.reports_v3.delete('abc123')
* ```
*/
public async delete(id: string): Promise<void> {
return this.client.request(`/report/${id}`, {
api: 'labrinth',
version: 3,
method: 'DELETE',
})
}
}

View File

@@ -0,0 +1,34 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthSessionsV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_sessions_v2'
}
/**
* List all sessions for the authenticated user
*
* @returns Promise resolving to an array of sessions
*/
public async list(): Promise<Labrinth.Sessions.v2.Session[]> {
return this.client.request<Labrinth.Sessions.v2.Session[]>('/session/list', {
api: 'labrinth',
version: 2,
method: 'GET',
})
}
/**
* Delete (revoke) a session
*
* @param id - The session ID
*/
public async delete(id: string): Promise<void> {
return this.client.request(`/session/${id}`, {
api: 'labrinth',
version: 2,
method: 'DELETE',
})
}
}

View File

@@ -0,0 +1,29 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthTagsV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_tags_v2'
}
/**
* Get license text by SPDX identifier
*
* @param licenseId - SPDX license identifier (e.g., 'MIT', 'Apache-2.0')
* @returns Promise resolving to the license title and body text
*
* @example
* ```typescript
* const license = await client.labrinth.tags_v2.getLicenseText('MIT')
* console.log(license.title) // "MIT License"
* console.log(license.body) // full license text
* ```
*/
public async getLicenseText(licenseId: string): Promise<Labrinth.Tags.v2.LicenseText> {
return this.client.request<Labrinth.Tags.v2.LicenseText>(`/tag/license/${licenseId}`, {
api: 'labrinth',
version: 2,
method: 'GET',
})
}
}

View File

@@ -0,0 +1,101 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthTeamsV2Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_teams_v2'
}
/**
* Add a member to a team
*
* @param teamId - Team ID
* @param data - New member data including user_id
*
* @example
* ```typescript
* await client.labrinth.teams_v2.addMember('team123', { user_id: 'user456' })
* ```
*/
public async addMember(
teamId: string,
data: Labrinth.Teams.v2.AddTeamMemberRequest,
): Promise<void> {
return this.client.request(`/team/${teamId}/members`, {
api: 'labrinth',
version: 2,
method: 'POST',
body: data,
})
}
/**
* Edit a team member
*
* @param teamId - Team ID
* @param userId - User ID of the member to edit
* @param data - Member update data
*
* @example
* ```typescript
* await client.labrinth.teams_v2.editMember('team123', 'user456', {
* role: 'Developer',
* permissions: 0b111,
* })
* ```
*/
public async editMember(
teamId: string,
userId: string,
data: Labrinth.Teams.v2.EditTeamMemberRequest,
): Promise<void> {
return this.client.request(`/team/${teamId}/members/${userId}`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
body: data,
})
}
/**
* Remove a member from a team
*
* @param teamId - Team ID
* @param userId - User ID of the member to remove
*
* @example
* ```typescript
* await client.labrinth.teams_v2.removeMember('team123', 'user456')
* ```
*/
public async removeMember(teamId: string, userId: string): Promise<void> {
return this.client.request(`/team/${teamId}/members/${userId}`, {
api: 'labrinth',
version: 2,
method: 'DELETE',
})
}
/**
* Transfer team ownership to another member
*
* @param teamId - Team ID
* @param data - Transfer data including the new owner's user_id
*
* @example
* ```typescript
* await client.labrinth.teams_v2.transferOwnership('team123', { user_id: 'user456' })
* ```
*/
public async transferOwnership(
teamId: string,
data: Labrinth.Teams.v2.TransferOwnershipRequest,
): Promise<void> {
return this.client.request(`/team/${teamId}/owner`, {
api: 'labrinth',
version: 2,
method: 'PATCH',
body: data,
})
}
}

View File

@@ -0,0 +1,31 @@
import { AbstractModule } from '../../../core/abstract-module'
import type { Labrinth } from '../types'
export class LabrinthTeamsV3Module extends AbstractModule {
public getModuleID(): string {
return 'labrinth_teams_v3'
}
/**
* Get multiple teams by their IDs
*
* @param ids - Array of team IDs
* @returns Promise resolving to an array of team member arrays (one per team)
*
* @example
* ```typescript
* const teams = await client.labrinth.teams_v3.getMultiple(['team1', 'team2'])
* // teams[0] = members of team1, teams[1] = members of team2
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.TeamMember[][]> {
return this.client.request<Labrinth.Projects.v3.TeamMember[][]>(
`/teams?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 3,
method: 'GET',
},
)
}
}

View File

@@ -26,6 +26,28 @@ export class LabrinthThreadsV3Module extends AbstractModule {
})
}
/**
* Get multiple threads by IDs (v3)
*
* @param ids - Array of thread IDs
* @returns Promise resolving to an array of threads
*
* @example
* ```typescript
* const threads = await client.labrinth.threads_v3.getMultiple(['id1', 'id2'])
* ```
*/
public async getMultiple(ids: string[]): Promise<Labrinth.Threads.v3.Thread[]> {
return this.client.request<Labrinth.Threads.v3.Thread[]>(
`/threads?ids=${encodeURIComponent(JSON.stringify(ids))}`,
{
api: 'labrinth',
version: 3,
method: 'GET',
},
)
}
/**
* Send a message to a thread (v3)
*

View File

@@ -158,6 +158,83 @@ export namespace Labrinth {
requested_form_type: string | null
form_completion_status: string | null
}
export type PayoutStatus =
| 'success'
| 'in-transit'
| 'cancelled'
| 'cancelling'
| 'failed'
| 'unknown'
export type PayoutMethodType = 'venmo' | 'paypal' | 'tremendous' | 'muralpay'
export type PayoutSource = 'creator_rewards' | 'affilites'
export type TransactionItem =
| {
type: 'withdrawal'
id: string
status: PayoutStatus
created: string
amount: number
fee: number | null
method_type: PayoutMethodType | null
method_id: string | null
method_address: string | null
}
| {
type: 'payout_available'
created: string
payout_source: PayoutSource
amount: number
}
export type WithdrawalFees = {
net_usd: number
fee: number
exchange_rate: number | null
}
export type PayoutDecimal = number
export type PayoutInterval = {
standard?: { min: number; max: number }
fixed?: { values: PayoutDecimal[] }
}
export type PayoutMethod = {
id: string
type: PayoutMethodType
name: string
category: string | null
image_url: string | null
image_logo_url: string | null
interval: PayoutInterval
currency_code: string | null
exchange_rate: number | null
}
}
}
export namespace Affiliate {
export namespace Internal {
export type AffiliateCode = {
id: string
created_at: string | null
created_by: string | null
affiliate: string
source_name: string
}
export type CreateRequest = {
affiliate?: string
source_name: string
}
export type PatchRequest = {
source_name: string
}
}
}
@@ -167,6 +244,123 @@ export namespace Labrinth {
subscribed: boolean
}
}
export namespace v2 {
export type LoginRequest = {
username: string
password: string
challenge: string
}
export type LoginResponse = {
session?: string
flow?: string
}
export type Login2FARequest = {
code: string
flow: string
}
export type Login2FAResponse = {
session: string
}
export type CreateAccountRequest = {
username: string
password: string
email: string
challenge: string
sign_up_newsletter?: boolean
}
export type CreateAccountResponse = {
session: string
}
export type ResetPasswordRequest = {
username: string
challenge: string
}
export type ChangePasswordRequest = {
flow?: string
old_password?: string
new_password?: string
}
}
}
export namespace Globals {
export namespace Internal {
export type Globals = {
tax_compliance_thresholds: Record<string, number>
captcha_enabled: boolean
}
}
}
export namespace OAuth {
export namespace Internal {
export type OAuthClientAccessRequest = {
flow_id: string
client_id: string
client_name: string
client_icon: string | null
requested_scopes: number
}
export type AcceptRejectRequest = {
flow: string
}
export type OAuthRedirectUri = {
id: string
client_id: string
uri: string
}
export type OAuthClient = {
id: string
name: string
icon_url: string | null
max_scopes: number
redirect_uris: OAuthRedirectUri[]
created_by: string
created: string
url: string | null
description: string | null
}
export type OAuthClientCreationResult = OAuthClient & {
client_secret: string
}
export type OAuthClientAuthorization = {
id: string
app_id: string
user_id: string
scopes: number
created: string
}
export type CreateOAuthAppRequest = {
name: string
max_scopes: number
redirect_uris: string[]
url?: string
description?: string
}
export type EditOAuthAppRequest = {
name?: string
max_scopes?: number
redirect_uris?: string[]
url?: string | null
description?: string | null
icon_url?: string
}
}
}
export namespace Projects {
@@ -318,6 +512,22 @@ export namespace Labrinth {
projects: Project[]
versions: Labrinth.Versions.v2.Version[]
}
export type BulkEditProjectRequest = {
categories?: string[]
add_categories?: string[]
remove_categories?: string[]
additional_categories?: string[]
add_additional_categories?: string[]
remove_additional_categories?: string[]
donation_urls?: DonationLink[]
add_donation_urls?: DonationLink[]
remove_donation_urls?: DonationLink[]
issues_url?: string | null
source_url?: string | null
wiki_url?: string | null
discord_url?: string | null
}
}
export namespace v3 {
@@ -882,6 +1092,36 @@ export namespace Labrinth {
short: string
name: string
}
export type LicenseText = {
title: string
body: string
}
}
}
export namespace Teams {
export namespace v2 {
export type AddTeamMemberRequest = {
user_id: string
role?: string
permissions?: number
organization_permissions?: number | null
payouts_split?: number
ordering?: number
}
export type EditTeamMemberRequest = {
permissions?: number
organization_permissions?: number | null
role?: string
payouts_split?: number
ordering?: number
}
export type TransferOwnershipRequest = {
user_id: string
}
}
}
@@ -1017,6 +1257,106 @@ export namespace Labrinth {
}
}
export namespace Reports {
export namespace v3 {
export type ItemType = 'project' | 'version' | 'user' | 'unknown'
export type Report = {
id: string
report_type: string
item_id: string
item_type: ItemType
reporter: string
body: string
created: string
closed: boolean
thread_id: string
}
export type CreateReportRequest = {
report_type: string
item_id: string
item_type: ItemType
body: string
uploaded_images?: string[]
}
export type EditReportRequest = {
body?: string
closed?: boolean
}
export type ListReportsParams = {
count?: number
offset?: number
all?: boolean
}
}
}
export namespace Notifications {
export namespace v2 {
export type NotificationAction = {
title: string
action_route: [string, string]
}
export type NotificationBody = {
type: string
project_id?: string
version_id?: string
report_id?: string
thread_id?: string
message_id?: string
invited_by?: string
organization_id?: string
team_id?: string
role?: string
old_status?: string
new_status?: string
[key: string]: unknown
}
export type Notification = {
id: string
user_id: string
type: string | null
title: string
text: string
link: string
read: boolean
created: string
actions: NotificationAction[]
body: NotificationBody
}
}
}
export namespace Payouts {
export namespace v3 {
export type RevenueData = {
time: number
revenue: string
creator_revenue: string
}
export type RevenueResponse = {
all_time: string
all_time_available: string
data: RevenueData[]
}
}
}
export namespace Limits {
export namespace v3 {
export type UserLimits = {
current: number
max: number
}
}
}
export namespace Collections {
export type CollectionStatus = 'listed' | 'unlisted' | 'private' | 'rejected' | 'unknown'
@@ -1267,4 +1607,52 @@ export namespace Labrinth {
}
}
}
export namespace Pats {
export namespace v2 {
export type PersonalAccessToken = {
id: string
name: string
access_token: string | null
scopes: number
user_id: string
created: string
expires: string
last_used: string | null
}
export type CreatePatRequest = {
scopes: number
name: string
expires: string
}
export type ModifyPatRequest = {
scopes?: number
name?: string
expires?: string
}
}
}
export namespace Sessions {
export namespace v2 {
export type Session = {
id: string
session: string | null
user_id: string
created: string
last_login: string
expires: string
refresh_expires: string
os: string | null
platform: string | null
user_agent: string
city: string | null
country: string | null
ip: string
current: boolean
}
}
}
}

View File

@@ -112,6 +112,49 @@ export class LabrinthUsersV2Module extends AbstractModule {
)
}
/**
* Get a user's notifications
*
* @param idOrUsername - The user's ID or username
* @returns Promise resolving to an array of the user's notifications
*
* @example
* ```typescript
* const notifications = await client.labrinth.users_v2.getNotifications('my_user')
* ```
*/
public async getNotifications(
idOrUsername: string,
): Promise<Labrinth.Notifications.v2.Notification[]> {
return this.client.request<Labrinth.Notifications.v2.Notification[]>(
`/user/${idOrUsername}/notifications`,
{
api: 'labrinth',
version: 2,
method: 'GET',
},
)
}
/**
* Get projects a user follows
*
* @param idOrUsername - The user's ID or username
* @returns Promise resolving to an array of followed projects
*
* @example
* ```typescript
* const projects = await client.labrinth.users_v2.getFollowedProjects('my_user')
* ```
*/
public async getFollowedProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {
return this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/follows`, {
api: 'labrinth',
version: 2,
method: 'GET',
})
}
/**
* Update a user
*