@modrinth/api-client 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +28 -0
- package/dist/index.js +3 -3
- package/dist/index.js.map +2 -2
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/core/abstract-module.ts", "../src/modules/archon/actions/v1.ts", "../src/modules/archon/backups/v1.ts", "../src/modules/archon/backups-queue/v1.ts", "../src/modules/archon/content/v1.ts", "../src/modules/archon/nodes/internal.ts", "../src/modules/archon/notices/v0.ts", "../src/modules/archon/options/v1.ts", "../src/modules/archon/properties/v1.ts", "../src/modules/archon/server-users/v1.ts", "../src/modules/archon/servers/internal.ts", "../src/modules/archon/servers/v0.ts", "../src/modules/archon/servers/v1.ts", "../src/modules/archon/transfers/internal.ts", "../src/modules/iso3166/index.ts", "../src/modules/kyros/content/v1.ts", "../src/utils/node-url.ts", "../src/modules/kyros/files/v0.ts", "../src/modules/kyros/logs/v1.ts", "../src/modules/kyros/upload-sessions/v1.ts", "../src/modules/labrinth/analytics/internal.ts", "../src/modules/labrinth/analytics/v3.ts", "../src/modules/labrinth/attribution/internal.ts", "../src/modules/labrinth/auth/internal.ts", "../src/modules/labrinth/auth/v2.ts", "../src/modules/labrinth/billing/internal.ts", "../src/modules/labrinth/collections.ts", "../src/modules/labrinth/content/v3.ts", "../src/modules/labrinth/external-projects/internal.ts", "../src/modules/labrinth/friends/v3.ts", "../src/modules/labrinth/geoip.ts", "../src/modules/labrinth/globals/internal.ts", "../src/modules/labrinth/images/v3.ts", "../src/modules/labrinth/limits/v3.ts", "../src/modules/labrinth/moderation/internal.ts", "../src/modules/labrinth/notifications/v2.ts", "../src/modules/labrinth/oauth/internal.ts", "../src/modules/labrinth/organizations/v3.ts", "../src/modules/labrinth/pats/v2.ts", "../src/modules/labrinth/payout/v3.ts", "../src/modules/labrinth/payouts/v3.ts", "../src/modules/labrinth/projects/v2.ts", "../src/types/errors.ts", "../src/core/errors.ts", "../src/modules/labrinth/projects/v3.ts", "../src/modules/labrinth/reports/v3.ts", "../src/modules/labrinth/server-ping/internal.ts", "../src/modules/labrinth/sessions/v2.ts", "../src/modules/labrinth/state/index.ts", "../src/modules/labrinth/tech-review/internal.ts", "../src/modules/labrinth/threads/v3.ts", "../src/modules/labrinth/users/v2.ts", "../src/modules/labrinth/users/v3.ts", "../src/modules/labrinth/versions/v2.ts", "../src/modules/labrinth/versions/v3.ts", "../src/modules/labrinth/affiliate/internal.ts", "../src/modules/labrinth/blocked-users/internal.ts", "../src/modules/labrinth/blocked-users/v3.ts", "../src/modules/labrinth/campaign/internal.ts", "../src/modules/labrinth/tags/v2.ts", "../src/modules/labrinth/teams/v2.ts", "../src/modules/labrinth/teams/v3.ts", "../src/modules/launcher-meta/v0.ts", "../src/modules/mclogs/insights/v1.ts", "../src/modules/mclogs/logs/v1.ts", "../src/modules/paper/v3.ts", "../src/modules/purpur/v2.ts", "../src/modules/shared-instances/instances/v1.ts", "../src/modules/shared-instances/invites/v1.ts", "../src/modules/shared-instances/moderation/v1.ts", "../src/modules/shared-instances/users/v1.ts", "../src/modules/index.ts", "../src/core/abstract-upload-client.ts", "../src/core/abstract-client.ts", "../src/core/abstract-feature.ts", "../src/core/abstract-sync.ts", "../src/core/abstract-websocket.ts", "../src/features/auth.ts", "../src/features/circuit-breaker.ts", "../src/features/node-auth.ts", "../src/features/panel-version.ts", "../src/features/retry.ts", "../src/features/verbose-logging.ts", "../src/modules/archon/types.ts", "../src/platform/generic.ts", "../src/utils/fetch.ts", "../src/platform/sync-generic.ts", "../src/utils/sse.ts", "../src/platform/websocket-generic.ts", "../src/platform/xhr-upload-client.ts", "../src/platform/nuxt.ts", "../src/platform/tauri.ts", "../src/state/node-auth.ts", "../src/utils/jwt-retry.ts", "../src/utils/pingtest.ts"],
|
|
4
|
-
"sourcesContent": ["import type { AbstractModrinthClient } from './abstract-client'\n\nexport abstract class AbstractModule {\n\tprotected client: AbstractModrinthClient\n\n\tpublic constructor(client: AbstractModrinthClient) {\n\t\tthis.client = client\n\t}\n\n\t/**\n\t * Get the module's name, used for error reporting & for module field generation.\n\t * @returns Module name\n\t */\n\tpublic abstract getModuleID(): string\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonActionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_actions_v1'\n\t}\n\n\t/**\n\t * Get server action log entries.\n\t * GET /v1/servers/:server_id/action-log\n\t */\n\tpublic async list(\n\t\tserverId: string,\n\t\toptions: Archon.Actions.v1.ListActionLogOptions = {},\n\t): Promise<Archon.Actions.v1.ActionLogResponse> {\n\t\tconst params: Record<string, string | number> = {}\n\t\tif (options.filter) params.filter = JSON.stringify(options.filter)\n\t\tif (options.limit !== undefined) params.limit = options.limit\n\t\tif (options.offset !== undefined) params.offset = options.offset\n\t\tif (options.order !== undefined) params.order = options.order\n\t\tif (options.min_datetime !== undefined) params.min_datetime = options.min_datetime\n\t\tif (options.max_datetime !== undefined) params.max_datetime = options.max_datetime\n\n\t\treturn this.client.request<Archon.Actions.v1.ActionLogResponse>(\n\t\t\t`/servers/${serverId}/action-log`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\n/**\n * @deprecated Use `client.archon.backups_queue_v1` (Backups Queue API) instead.\n */\nexport class ArchonBackupsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_backups_v1'\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.list` instead.\n\t */\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups */\n\tpublic async list(serverId: string, worldId: string): Promise<Archon.Backups.v1.Backup[]> {\n\t\treturn this.client.request<Archon.Backups.v1.Backup[]>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.list` instead.\n\t */\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async get(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t): Promise<Archon.Backups.v1.Backup> {\n\t\treturn this.client.request<Archon.Backups.v1.Backup>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.create` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups */\n\tpublic async create(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Backups.v1.BackupRequest,\n\t): Promise<Archon.Backups.v1.PostBackupResponse> {\n\t\treturn this.client.request<Archon.Backups.v1.PostBackupResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.restore` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/restore */\n\tpublic async restore(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}/restore`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.delete` for backup deletion, or\n\t * `client.archon.backups_queue_v1.cancelCreate` / `cancelRestore` for active operations.\n\t */\n\t/** DELETE /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async delete(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.retry` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/retry */\n\tpublic async retry(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}/retry`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Legacy backups only; no queue equivalent. Prefer renaming via other supported flows if available.\n\t */\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async rename(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t\trequest: Archon.Backups.v1.PatchBackup,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonBackupsQueueV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_backups_queue_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups-queue */\n\tpublic async list(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.BackupsQueue.v1.BackupsQueueResponse> {\n\t\treturn this.client.request<Archon.BackupsQueue.v1.BackupsQueueResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue */\n\tpublic async create(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.BackupsQueue.v1.BackupRequest,\n\t): Promise<Archon.BackupsQueue.v1.PostBackupQueueResponse> {\n\t\treturn this.client.request<Archon.BackupsQueue.v1.PostBackupQueueResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/ack */\n\tpublic async ackCreate(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/ack`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/cancel */\n\tpublic async cancelCreate(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/cancel`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/ack */\n\tpublic async ackRestore(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/ack`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/cancel */\n\tpublic async cancelRestore(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\toperationId: number,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/cancel`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** DELETE /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id */\n\tpublic async delete(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/delete-many */\n\tpublic async deleteMany(serverId: string, worldId: string, backupIds: string[]): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/delete-many`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: { backup_ids: backupIds } satisfies Archon.BackupsQueue.v1.DeleteManyBackupRequest,\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/restore */\n\tpublic async restore(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t\trequest: Archon.BackupsQueue.v1.BackupRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/restore`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/retry */\n\tpublic async retry(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/retry`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonContentV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_content_v1'\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/addons */\n\tpublic async getAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\toptions?: {\n\t\t\tfrom_modpack?: boolean\n\t\t\tdisabled?: boolean\n\t\t\taddons?: boolean\n\t\t\tupdates?: boolean\n\t\t},\n\t): Promise<Archon.Content.v1.Addons> {\n\t\tconst params = new URLSearchParams()\n\t\tif (options?.from_modpack !== undefined)\n\t\t\tparams.set('from_modpack', String(options.from_modpack))\n\t\tif (options?.disabled !== undefined) params.set('disabled', String(options.disabled))\n\t\tif (options?.addons !== undefined) params.set('addons', String(options.addons))\n\t\tif (options?.updates !== undefined) params.set('updates', String(options.updates))\n\t\tconst query = params.toString()\n\n\t\treturn this.client.request<Archon.Content.v1.Addons>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/addons${query ? `?${query}` : ''}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons */\n\tpublic async addAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.AddAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/install-many */\n\tpublic async addAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\taddons: Archon.Content.v1.AddAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/install-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: addons satisfies Archon.Content.v1.AddAddonsRequest,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/delete */\n\tpublic async deleteAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/delete`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/disable */\n\tpublic async disableAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/disable`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/enable */\n\tpublic async enableAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/enable`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/delete-many */\n\tpublic async deleteAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/delete-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/disable-many */\n\tpublic async disableAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/disable-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/enable-many */\n\tpublic async enableAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/enable-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content */\n\tpublic async installContent(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.InstallWorldContent,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/content`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/repair */\n\tpublic async repair(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/content/repair`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/unlink-modpack */\n\tpublic async unlinkModpack(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/unlink-modpack`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/addons/update?filename=... */\n\tpublic async getAddonUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tfilename: string,\n\t): Promise<Archon.Content.v1.Addon> {\n\t\treturn this.client.request<Archon.Content.v1.Addon>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/addons/update?filename=${encodeURIComponent(filename)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/update */\n\tpublic async updateAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.UpdateAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/update`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/update-many */\n\tpublic async updateAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\taddons: Archon.Content.v1.UpdateAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/update-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { addons },\n\t\t})\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/content/modpack/update */\n\tpublic async getModpackUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.ModpackFields> {\n\t\treturn this.client.request<Archon.Content.v1.ModpackFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/modpack/update`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/modpack/update */\n\tpublic async updateModpack(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/modpack/update`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/content/update-game-version?game_version=... */\n\tpublic async getUpdateGameVersionPreview(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tgameVersion: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<Archon.Content.v1.UpdateGameVersionPreview> {\n\t\treturn this.client.request<Archon.Content.v1.UpdateGameVersionPreview>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/update-game-version?game_version=${encodeURIComponent(gameVersion)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout: 1000 * 1000,\n\t\t\t\tsignal,\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/update-game-version?game_version=... */\n\tpublic async applyGameVersionUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tgameVersion: string,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/update-game-version?game_version=${encodeURIComponent(gameVersion)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonNodesInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_nodes_internal'\n\t}\n\n\t/**\n\t * Get node hostnames and region summary for admin tooling.\n\t * GET /_internal/nodes/overview\n\t */\n\tpublic async overview(): Promise<Archon.Nodes.Internal.Overview> {\n\t\treturn this.client.request<Archon.Nodes.Internal.Overview>('/nodes/overview', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonNoticesV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_notices_v0'\n\t}\n\n\t/**\n\t * Get all server notices.\n\t * GET /modrinth/v0/notices\n\t */\n\tpublic async list(): Promise<Archon.Notices.v0.ListedNotice[]> {\n\t\treturn this.client.request<Archon.Notices.v0.ListedNotice[]>('/notices', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a server notice.\n\t * POST /modrinth/v0/notices\n\t */\n\tpublic async create(\n\t\trequest: Archon.Notices.v0.Announce,\n\t): Promise<Archon.Notices.v0.PostNoticeResponseBody> {\n\t\treturn this.client.request<Archon.Notices.v0.PostNoticeResponseBody>('/notices', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Update a server notice.\n\t * PATCH /modrinth/v0/notices/:id\n\t */\n\tpublic async update(id: number, request: Archon.Notices.v0.AnnouncePatch): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a server notice.\n\t * DELETE /modrinth/v0/notices/:id\n\t */\n\tpublic async delete(id: number): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Assign a notice to a server or node.\n\t * PUT /modrinth/v0/notices/:id/assign?server=:serverId\n\t * PUT /modrinth/v0/notices/:id/assign?node=:nodeId\n\t */\n\tpublic async assign(id: number, target: Archon.Notices.v0.AssignmentTarget): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}/assign`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: this.assignmentTargetToParams(target),\n\t\t})\n\t}\n\n\t/**\n\t * Unassign a notice from a server or node.\n\t * PUT /modrinth/v0/notices/:id/unassign?server=:serverId\n\t * PUT /modrinth/v0/notices/:id/unassign?node=:nodeId\n\t */\n\tpublic async unassign(id: number, target: Archon.Notices.v0.AssignmentTarget): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}/unassign`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: this.assignmentTargetToParams(target),\n\t\t})\n\t}\n\n\tprivate assignmentTargetToParams(\n\t\ttarget: Archon.Notices.v0.AssignmentTarget,\n\t): Record<string, string> {\n\t\tif ('server' in target) {\n\t\t\treturn { server: target.server }\n\t\t}\n\n\t\treturn { node: target.node }\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonOptionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_options_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/options/startup */\n\tpublic async getStartup(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.RuntimeOptions> {\n\t\treturn this.client.request<Archon.Content.v1.RuntimeOptions>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/options/startup`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/options/startup */\n\tpublic async patchStartup(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbody: Archon.Content.v1.PatchRuntimeOptions,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/worlds/${worldId}/options/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonPropertiesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_properties_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/properties */\n\tpublic async getProperties(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.PropertiesFields> {\n\t\treturn this.client.request<Archon.Content.v1.PropertiesFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/properties`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/properties */\n\tpublic async patchProperties(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbody: Archon.Content.v1.PatchPropertiesFields,\n\t): Promise<Archon.Content.v1.PropertiesFields> {\n\t\treturn this.client.request<Archon.Content.v1.PropertiesFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/properties`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServerUsersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_server_users_v1'\n\t}\n\n\t/**\n\t * Get list of users with access to a server\n\t * GET /v1/servers/:server_id/users\n\t */\n\tpublic async list(serverId: string): Promise<Archon.ServerUsers.v1.ServerUser[]> {\n\t\treturn this.client.request<Archon.ServerUsers.v1.ServerUser[]>(`/servers/${serverId}/users`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Add a user to a server\n\t * POST /v1/servers/:server_id/users\n\t */\n\tpublic async add(\n\t\tserverId: string,\n\t\tuser: Archon.ServerUsers.v1.AddServerUserRequest,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: user,\n\t\t})\n\t}\n\n\t/**\n\t * Re-send an invite to a pending server user.\n\t * POST /v1/servers/:server_id/users/:user_id/reinvite\n\t */\n\tpublic async reinvite(\n\t\tserverId: string,\n\t\tuserId: string,\n\t): Promise<Archon.ServerUsers.v1.ReinviteResponse> {\n\t\treturn this.client.request<Archon.ServerUsers.v1.ReinviteResponse>(\n\t\t\t`/servers/${serverId}/users/${userId}/reinvite`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Remove a user from a server\n\t * DELETE /v1/servers/:server_id/users/:user_id\n\t */\n\tpublic async delete(serverId: string, userId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users/${userId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update a user's server role\n\t * PATCH /v1/servers/:server_id/users/:user_id\n\t */\n\tpublic async update(\n\t\tserverId: string,\n\t\tuserId: string,\n\t\trole: Archon.ServerUsers.v1.AssignableServerUserRole,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users/${userId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: JSON.stringify(role),\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_internal'\n\t}\n\n\t/**\n\t * Get the server assigned to a subdomain.\n\t * GET /_internal/servers/by-subdomain/:subdomain\n\t */\n\tpublic async getBySubdomain(subdomain: string): Promise<Archon.Servers.Internal.Lookup> {\n\t\treturn this.client.request<Archon.Servers.Internal.Lookup>(\n\t\t\t`/servers/by-subdomain/${encodeURIComponent(subdomain)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Archon } from '../types'\n\nexport class ArchonServersV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_v0'\n\t}\n\n\t/**\n\t * Get a specific server by ID\n\t * GET /modrinth/v0/servers/:id\n\t */\n\tpublic async get(serverId: string): Promise<Archon.Servers.v0.Server> {\n\t\treturn this.client.request<Archon.Servers.v0.Server>(`/servers/${serverId}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Get list of servers for the authenticated user\n\t * GET /modrinth/v0/servers\n\t */\n\tpublic async list(\n\t\toptions?: Archon.Servers.v0.GetServersOptions,\n\t): Promise<Archon.Servers.v0.ServerGetResponse> {\n\t\tconst params = new URLSearchParams()\n\t\tif (options?.limit) params.set('limit', options.limit.toString())\n\t\tif (options?.offset) params.set('offset', options.offset.toString())\n\n\t\tconst query = params.toString() ? `?${params.toString()}` : ''\n\n\t\treturn this.client.request<Archon.Servers.v0.ServerGetResponse>(`servers${query}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Check stock availability for a region\n\t * POST /modrinth/v0/stock?region=:region\n\t */\n\tpublic async checkStock(\n\t\tregion: string,\n\t\trequest: Archon.Servers.v0.StockRequest,\n\t): Promise<Archon.Servers.v0.StockResponse> {\n\t\treturn this.client.request<Archon.Servers.v0.StockResponse>(`/stock?region=${region}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Check stock availability (without region filter)\n\t * POST /modrinth/v0/stock\n\t */\n\tpublic async checkStockGlobal(\n\t\trequest: Archon.Servers.v0.StockRequest,\n\t): Promise<Archon.Servers.v0.StockResponse> {\n\t\treturn this.client.request<Archon.Servers.v0.StockResponse>('/stock', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get filesystem authentication credentials for a server\n\t * Returns URL and JWT token for accessing the server's filesystem via Kyros\n\t * GET /modrinth/v0/servers/:id/fs\n\t */\n\tpublic async getFilesystemAuth(serverId: string): Promise<Archon.Servers.v0.JWTAuth> {\n\t\treturn this.client.request<Archon.Servers.v0.JWTAuth>(`/servers/${serverId}/fs`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get WebSocket authentication credentials for a server\n\t * GET /modrinth/v0/servers/:id/ws\n\t */\n\tpublic async getWebSocketAuth(serverId: string): Promise<Archon.Websocket.v0.WSAuth> {\n\t\treturn this.client.request<Archon.Websocket.v0.WSAuth>(`/servers/${serverId}/ws`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Send a power action to a server (Start, Stop, Restart, Kill)\n\t * POST /modrinth/v0/servers/:id/power\n\t */\n\tpublic async power(\n\t\tserverId: string,\n\t\taction: 'Start' | 'Stop' | 'Restart' | 'Kill',\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/power`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { action },\n\t\t})\n\t}\n\n\t/**\n\t * Reinstall a server with a new loader or modpack\n\t * POST /modrinth/v0/servers/:id/reinstall\n\t */\n\tpublic async reinstall(\n\t\tserverId: string,\n\t\trequest: Archon.Servers.v0.ReinstallRequest,\n\t\thardReset: boolean = false,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/reinstall`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { hard: String(hardReset) },\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Get authentication credentials for .mrpack file upload\n\t * GET /modrinth/v0/servers/:id/reinstallFromMrpack\n\t */\n\tpublic async getReinstallMrpackAuth(\n\t\tserverId: string,\n\t): Promise<Archon.Servers.v0.MrpackReinstallAuth> {\n\t\treturn this.client.request<Archon.Servers.v0.MrpackReinstallAuth>(\n\t\t\t`/servers/${serverId}/reinstallFromMrpack`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'modrinth/v0',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Reinstall a server from a .mrpack file with progress tracking\n\t *\n\t * Two-step flow: fetches upload auth, then uploads the .mrpack file to the node.\n\t *\n\t * @param serverId - Server ID\n\t * @param file - .mrpack file to upload\n\t * @param hardReset - Whether to erase all server data\n\t * @param options - Optional progress callback\n\t * @returns Promise resolving to an UploadHandle with progress tracking and cancellation\n\t */\n\tpublic async reinstallFromMrpack(\n\t\tserverId: string,\n\t\tfile: File,\n\t\thardReset: boolean = false,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): Promise<UploadHandle<void>> {\n\t\tconst auth = await this.getReinstallMrpackAuth(serverId)\n\n\t\tconst formData = new FormData()\n\t\tformData.append('file', file)\n\n\t\treturn this.client.upload<void>('', {\n\t\t\tapi: `https://${auth.url}`,\n\t\t\tversion: 'reinstallMrpackMultiparted',\n\t\t\tformData,\n\t\t\tparams: { hard: String(hardReset) },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: false,\n\t\t})\n\t}\n\n\t/**\n\t * Update a server's name\n\t * POST /modrinth/v0/servers/:id/name\n\t */\n\tpublic async updateName(serverId: string, name: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/name`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Get allocations for a server\n\t * GET /modrinth/v0/servers/:id/allocations\n\t */\n\tpublic async getAllocations(serverId: string): Promise<Archon.Servers.v0.Allocation[]> {\n\t\treturn this.client.request<Archon.Servers.v0.Allocation[]>(`/servers/${serverId}/allocations`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Reserve a new allocation for a server\n\t * POST /modrinth/v0/servers/:id/allocations?name=...\n\t */\n\tpublic async reserveAllocation(\n\t\tserverId: string,\n\t\tname: string,\n\t): Promise<Archon.Servers.v0.Allocation> {\n\t\treturn this.client.request<Archon.Servers.v0.Allocation>(`/servers/${serverId}/allocations`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Update an allocation's name\n\t * PUT /modrinth/v0/servers/:id/allocations/:port?name=...\n\t */\n\tpublic async updateAllocation(serverId: string, port: number, name: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/allocations/${port}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'PUT',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Delete an allocation\n\t * DELETE /modrinth/v0/servers/:id/allocations/:port\n\t */\n\tpublic async deleteAllocation(serverId: string, port: number): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/allocations/${port}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'DELETE',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Check if a subdomain is available\n\t * GET /modrinth/v0/subdomains/:subdomain/isavailable\n\t */\n\tpublic async checkSubdomainAvailability(subdomain: string): Promise<{ available: boolean }> {\n\t\treturn this.client.request<{ available: boolean }>(`/subdomains/${subdomain}/isavailable`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Change a server's subdomain\n\t * POST /modrinth/v0/servers/:id/subdomain\n\t */\n\tpublic async changeSubdomain(serverId: string, subdomain: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/subdomain`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { subdomain },\n\t\t})\n\t}\n\n\t/**\n\t * Get startup configuration for a server\n\t * GET /modrinth/v0/servers/:id/startup\n\t */\n\tpublic async getStartupConfig(serverId: string): Promise<Archon.Servers.v0.StartupConfig> {\n\t\treturn this.client.request<Archon.Servers.v0.StartupConfig>(`/servers/${serverId}/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Update startup configuration for a server\n\t * POST /modrinth/v0/servers/:id/startup\n\t */\n\tpublic async updateStartupConfig(\n\t\tserverId: string,\n\t\tconfig: {\n\t\t\tinvocation: string | null\n\t\t\tjdk_version: string | null\n\t\t\tjdk_build: string | null\n\t\t},\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: config,\n\t\t})\n\t}\n\n\t/**\n\t * Dismiss a server notice\n\t * POST /modrinth/v0/servers/:id/notices/:noticeId/dismiss\n\t */\n\tpublic async dismissNotice(serverId: string, noticeId: number): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/notices/${noticeId}/dismiss`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_v1'\n\t}\n\n\t/**\n\t * Get list of servers for the authenticated user\n\t * GET /v1/servers\n\t */\n\tpublic async list(): Promise<Archon.Servers.v1.ServerFull[]> {\n\t\treturn this.client.request<Archon.Servers.v1.ServerFull[]>('/servers', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get full server details including worlds, backups, and content\n\t * GET /v1/servers/:server_id\n\t */\n\tpublic async get(serverId: string): Promise<Archon.Servers.v1.ServerFull> {\n\t\treturn this.client.request<Archon.Servers.v1.ServerFull>(`/servers/${serverId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get available regions\n\t * GET /v1/regions\n\t */\n\tpublic async getRegions(): Promise<Archon.Servers.v1.Region[]> {\n\t\treturn this.client.request<Archon.Servers.v1.Region[]>('/regions', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * End the intro flow for a server\n\t * DELETE /v1/servers/:id/flows/intro\n\t */\n\tpublic async endIntro(serverId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/flows/intro`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Reset a world to onboarding\n\t * POST /v1/servers/:id/worlds/:wid/onboard\n\t */\n\tpublic async resetToOnboarding(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/worlds/${worldId}/onboard`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonTransfersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_transfers_internal'\n\t}\n\n\t/**\n\t * Schedule transfers for specific servers.\n\t * POST /_internal/transfers/schedule/servers\n\t */\n\tpublic async scheduleServers(\n\t\trequest: Archon.Transfers.Internal.ScheduleServerTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.ScheduleTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.ScheduleTransfersResponse>(\n\t\t\t'/transfers/schedule/servers',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Schedule transfers for all servers on specific nodes.\n\t * POST /_internal/transfers/schedule/nodes\n\t */\n\tpublic async scheduleNodes(\n\t\trequest: Archon.Transfers.Internal.ScheduleNodeTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.ScheduleTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.ScheduleTransfersResponse>(\n\t\t\t'/transfers/schedule/nodes',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get transfer batch history.\n\t * GET /_internal/transfers/history\n\t */\n\tpublic async history(\n\t\toptions?: Archon.Transfers.Internal.TransferHistoryQuery,\n\t): Promise<Archon.Transfers.Internal.TransferHistoryResponse> {\n\t\tconst params: Record<string, number> = {}\n\t\tif (options?.page !== undefined) params.page = options.page\n\t\tif (options?.page_size !== undefined) params.page_size = options.page_size\n\n\t\treturn this.client.request<Archon.Transfers.Internal.TransferHistoryResponse>(\n\t\t\t'/transfers/history',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Cancel pending transfer batches.\n\t * POST /_internal/transfers/cancel\n\t */\n\tpublic async cancel(\n\t\trequest: Archon.Transfers.Internal.CancelTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.CancelTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.CancelTransfersResponse>(\n\t\t\t'/transfers/cancel',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { $fetch } from 'ofetch'\n\nimport { AbstractModule } from '../../core/abstract-module'\nimport type { ISO3166 } from './types'\n\nexport type { ISO3166 } from './types'\n\nconst ISO3166_REPO = 'https://raw.githubusercontent.com/ipregistry/iso3166/master'\n\n/**\n * Parse CSV string into array of objects\n * @param csv - CSV string to parse\n * @returns Array of objects with header keys mapped to row values\n */\nfunction parseCSV(csv: string): Record<string, string>[] {\n\tconst lines = csv\n\t\t.trim()\n\t\t.split('\\n')\n\t\t.filter((line) => line.trim() !== '')\n\n\tif (lines.length === 0) return []\n\n\tconst headerLine = lines[0]\n\tconst headers = (headerLine.startsWith('#') ? headerLine.slice(1) : headerLine).split(',')\n\n\treturn lines.slice(1).map((line) => {\n\t\tconst values = line.split(',')\n\t\tconst row: Record<string, string> = {}\n\n\t\theaders.forEach((header, index) => {\n\t\t\trow[header] = values[index] || ''\n\t\t})\n\n\t\treturn row\n\t})\n}\n\n/**\n * Module for fetching ISO 3166 country and subdivision data\n * Data from https://github.com/ipregistry/iso3166 (Licensed under CC BY-SA 4.0)\n * @platform Not for use in Tauri or Nuxt environments, only node.\n */\nexport class ISO3166Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'iso3166_data'\n\t}\n\n\t/**\n\t * Build ISO 3166 country and subdivision data from the ipregistry repository\n\t *\n\t * @returns Promise resolving to countries and subdivisions data\n\t *\n\t * @example\n\t * ```typescript\n\t * const data = await client.iso3166.data.build()\n\t * console.log(data.countries) // Array of country data\n\t * console.log(data.subdivisions['US']) // Array of US state data\n\t * ```\n\t */\n\tpublic async build(): Promise<ISO3166.State> {\n\t\ttry {\n\t\t\tconst [countriesCSV, subdivisionsCSV] = await Promise.all([\n\t\t\t\t$fetch<string>(`${ISO3166_REPO}/countries.csv`, {\n\t\t\t\t\t// @ts-expect-error supports text\n\t\t\t\t\tresponseType: 'text',\n\t\t\t\t}),\n\t\t\t\t$fetch<string>(`${ISO3166_REPO}/subdivisions.csv`, {\n\t\t\t\t\t// @ts-expect-error supports text\n\t\t\t\t\tresponseType: 'text',\n\t\t\t\t}),\n\t\t\t])\n\n\t\t\tconst countriesData = parseCSV(countriesCSV)\n\t\t\tconst subdivisionsData = parseCSV(subdivisionsCSV)\n\n\t\t\tconst countries: ISO3166.Country[] = countriesData.map((c) => ({\n\t\t\t\talpha2: c.country_code_alpha2,\n\t\t\t\talpha3: c.country_code_alpha3,\n\t\t\t\tnumeric: c.numeric_code,\n\t\t\t\tnameShort: c.name_short,\n\t\t\t\tnameLong: c.name_long,\n\t\t\t}))\n\n\t\t\t// Group subdivisions by country code\n\t\t\tconst subdivisions: Record<string, ISO3166.Subdivision[]> = subdivisionsData.reduce(\n\t\t\t\t(acc, sub) => {\n\t\t\t\t\tconst countryCode = sub.country_code_alpha2\n\n\t\t\t\t\tif (!countryCode || typeof countryCode !== 'string' || countryCode.trim() === '') {\n\t\t\t\t\t\treturn acc\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!acc[countryCode]) acc[countryCode] = []\n\n\t\t\t\t\tacc[countryCode].push({\n\t\t\t\t\t\tcode: sub['subdivision_code_iso3166-2'],\n\t\t\t\t\t\tname: sub.subdivision_name,\n\t\t\t\t\t\tlocalVariant: sub.localVariant || null,\n\t\t\t\t\t\tcategory: sub.category,\n\t\t\t\t\t\tparent: sub.parent_subdivision || null,\n\t\t\t\t\t\tlanguage: sub.language_code,\n\t\t\t\t\t})\n\n\t\t\t\t\treturn acc\n\t\t\t\t},\n\t\t\t\t{} as Record<string, ISO3166.Subdivision[]>,\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tcountries,\n\t\t\t\tsubdivisions,\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error('Error fetching ISO3166 data:', err)\n\t\t\treturn {\n\t\t\t\tcountries: [],\n\t\t\t\tsubdivisions: {},\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Archon } from '../../archon/types'\n\nexport class KyrosContentV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_content_v1'\n\t}\n\n\t/**\n\t * Upload addon files to a world via multipart form data\n\t *\n\t * @param worldId - World UUID\n\t * @param files - Files to upload as addons\n\t * @param options - Optional progress callback\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t * @deprecated Use `kyros.upload_sessions_v1` so cancellation can remove staged addon files before finalize.\n\t */\n\tpublic uploadAddonFile(\n\t\tworldId: string,\n\t\tfiles: (File | Blob)[],\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): UploadHandle<void> {\n\t\tconst formData = new FormData()\n\t\tfor (const file of files) {\n\t\t\tformData.append('file', file, file instanceof File ? file.name : 'file')\n\t\t}\n\n\t\treturn this.client.upload<void>(`/worlds/${worldId}/content/upload-addon-file`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tformData,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/** POST /v1/worlds/:world_id/content/upload-modpack-file */\n\tpublic uploadModpackFile(\n\t\tworldId: string,\n\t\tfile: File | Blob,\n\t\tproperties: Archon.Content.v1.PropertiesFields,\n\t\toptions?: {\n\t\t\tsoftOverride?: boolean\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): UploadHandle<void> {\n\t\tconst formData = new FormData()\n\t\tformData.append('file', file, file instanceof File ? file.name : 'file')\n\t\tformData.append('properties', JSON.stringify(properties))\n\n\t\treturn this.client.upload<void>(`/worlds/${worldId}/content/upload-modpack-file`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tformData,\n\t\t\tparams:\n\t\t\t\toptions?.softOverride !== undefined\n\t\t\t\t\t? { soft_override: String(options.softOverride) }\n\t\t\t\t\t: undefined,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "const NODE_FS_PATH_REGEX = /\\/modrinth\\/v\\d+\\/fs\\/?$/\nconst HTTP_SCHEME_REGEX = /^https?:\\/\\//i\nconst WS_SCHEME_REGEX = /^wss?:\\/\\//i\nconst HTTP_SECURE_SCHEME_REGEX = /^https:\\/\\//i\nconst HTTP_INSECURE_SCHEME_REGEX = /^http:\\/\\//i\n\nexport function getNodeBaseUrl(url: string): string {\n\tconst baseUrl = url.replace(NODE_FS_PATH_REGEX, '')\n\treturn HTTP_SCHEME_REGEX.test(baseUrl) ? baseUrl : `https://${baseUrl}`\n}\n\nexport function getNodeWebSocketUrl(url: string): string {\n\tif (WS_SCHEME_REGEX.test(url)) return url\n\tif (HTTP_SECURE_SCHEME_REGEX.test(url)) return url.replace(HTTP_SECURE_SCHEME_REGEX, 'wss://')\n\tif (HTTP_INSECURE_SCHEME_REGEX.test(url)) return url.replace(HTTP_INSECURE_SCHEME_REGEX, 'ws://')\n\n\treturn `wss://${url}`\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport { getNodeBaseUrl } from '../../../utils/node-url'\nimport type { Archon } from '../../archon/types'\nimport type { Kyros } from '../types'\n\ntype NodeFsAuth = Pick<Archon.Servers.v0.JWTAuth, 'url' | 'token'>\n\nexport class KyrosFilesV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_files_v0'\n\t}\n\n\tprivate getNodeBaseUrl(auth: NodeFsAuth): string {\n\t\treturn getNodeBaseUrl(auth.url)\n\t}\n\n\t/**\n\t * List directory contents with pagination\n\t *\n\t * @param path - Directory path (e.g., \"/\")\n\t * @param page - Page number (1-indexed)\n\t * @param pageSize - Items per page\n\t * @returns Directory listing with items and pagination info\n\t */\n\tpublic async listDirectory(\n\t\tpath: string,\n\t\tpage: number = 1,\n\t\tpageSize: number = 100,\n\t): Promise<Kyros.Files.v0.DirectoryResponse> {\n\t\treturn this.client.request<Kyros.Files.v0.DirectoryResponse>('/fs/list', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path, page, page_size: pageSize },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Create a file or directory\n\t *\n\t * @param path - Path for new item (e.g., \"/new-folder\")\n\t * @param type - Type of item to create\n\t */\n\tpublic async createFileOrFolder(path: string, type: 'file' | 'directory'): Promise<void> {\n\t\treturn this.client.request<void>('/fs/create', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { path, type },\n\t\t\theaders: { 'Content-Type': 'application/octet-stream' },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Download a file from a server's filesystem\n\t *\n\t * @param path - File path (e.g., \"/server-icon-original.png\")\n\t * @returns Promise resolving to file Blob\n\t */\n\tpublic async downloadFile(path: string): Promise<Blob> {\n\t\treturn this.client.request<Blob>('/fs/download', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Download a file using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - File path (e.g., \"/server-icon.png\")\n\t * @returns Promise resolving to file Blob\n\t */\n\tpublic async downloadFileWithAuth(auth: NodeFsAuth, path: string): Promise<Blob> {\n\t\treturn this.client.request<Blob>('/fs/download', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Upload a file to a server's filesystem with progress tracking\n\t *\n\t * @param path - Destination path (e.g., \"/server-icon.png\")\n\t * @param file - File to upload\n\t * @param options - Optional progress callback and feature overrides\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t * @deprecated Use `kyros.upload_sessions_v1` for bulk uploads so cancellation can remove staged files before finalize.\n\t */\n\tpublic uploadFile(\n\t\tpath: string,\n\t\tfile: File | Blob,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<void> {\n\t\treturn this.client.upload<void>('/fs/create', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tfile,\n\t\t\tparams: { path, type: 'file' },\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: options?.retry,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Upload a file using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - Destination path (e.g., \"/server-icon.png\")\n\t * @param file - File to upload\n\t * @param options - Optional progress callback and feature overrides\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t */\n\tpublic uploadFileWithAuth(\n\t\tauth: NodeFsAuth,\n\t\tpath: string,\n\t\tfile: File | Blob,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<void> {\n\t\treturn this.client.upload<void>('/fs/create', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tfile,\n\t\t\tparams: { path, type: 'file' },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: options?.retry,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Update file contents\n\t *\n\t * @param path - File path to update\n\t * @param content - New file content (string or Blob)\n\t */\n\tpublic async updateFile(path: string, content: string | Blob): Promise<void> {\n\t\tconst blob = typeof content === 'string' ? new Blob([content]) : content\n\n\t\treturn this.client.request<void>('/fs/update', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: { path },\n\t\t\tbody: blob,\n\t\t\theaders: { 'Content-Type': 'application/octet-stream' },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Move a file or folder to a new location\n\t *\n\t * @param sourcePath - Current path\n\t * @param destPath - New path\n\t */\n\tpublic async moveFileOrFolder(sourcePath: string, destPath: string): Promise<void> {\n\t\treturn this.client.request<void>('/fs/move', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: { source: sourcePath, destination: destPath },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Rename a file or folder (convenience wrapper around move)\n\t *\n\t * @param path - Current file/folder path\n\t * @param newName - New name (not full path)\n\t */\n\tpublic async renameFileOrFolder(path: string, newName: string): Promise<void> {\n\t\tconst newPath = path.split('/').slice(0, -1).join('/') + '/' + newName\n\t\treturn this.moveFileOrFolder(path, newPath)\n\t}\n\n\t/**\n\t * Delete a file or folder\n\t *\n\t * @param path - Path to delete\n\t * @param recursive - If true, delete directory contents recursively\n\t */\n\tpublic async deleteFileOrFolder(path: string, recursive: boolean): Promise<void> {\n\t\treturn this.client.request<void>('/fs/delete', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { path, recursive },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a file or folder using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - Path to delete\n\t * @param recursive - If true, delete directory contents recursively\n\t */\n\tpublic async deleteFileOrFolderWithAuth(\n\t\tauth: NodeFsAuth,\n\t\tpath: string,\n\t\trecursive: boolean,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/fs/delete', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { path, recursive },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Extract an archive file (zip, tar, etc.)\n\t *\n\t * Uses v1 API endpoint.\n\t *\n\t * @param path - Path to archive file\n\t * @param override - If true, overwrite existing files\n\t * @param dry - If true, perform dry run (returns conflicts without extracting)\n\t * @returns Extract result with modpack name and conflicting files\n\t */\n\tpublic async extractFile(\n\t\tpath: string,\n\t\toverride: boolean = true,\n\t\tdry: boolean = false,\n\t): Promise<Kyros.Files.v0.ExtractResult> {\n\t\treturn this.client.request<Kyros.Files.v0.ExtractResult>('/fs/unarchive', {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { src: path, trg: '/', override, dry },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Modify a filesystem operation (dismiss or cancel)\n\t *\n\t * Uses v1 API endpoint.\n\t *\n\t * @param opId - Operation ID (UUID)\n\t * @param action - Action to perform\n\t */\n\tpublic async modifyOperation(opId: string, action: 'dismiss' | 'cancel'): Promise<void> {\n\t\treturn this.client.request<void>(`/fs/ops/${action}`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { id: opId },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\n\nexport class KyrosLogsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_logs_v1'\n\t}\n\n\t/** POST /v1/logs/clear \u2014 clear the live logs buffer for the current server */\n\tpublic async clear(): Promise<void> {\n\t\treturn this.client.request<void>('/logs/clear', {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Kyros } from '../types'\n\nexport type UploadSessionFile = {\n\tfile: File | Blob\n\tfilename: string\n}\n\nfunction getUploadSessionPath(scope: Kyros.UploadSessions.v1.Scope, worldId: string) {\n\treturn `/worlds/${worldId}/${scope}/upload-session`\n}\n\nexport class KyrosUploadSessionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_upload_sessions_v1'\n\t}\n\n\tpublic async create(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\tgetUploadSessionPath(scope, worldId),\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async get(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t): Promise<Kyros.UploadSessions.v1.GetUploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.GetUploadSessionResponse>(\n\t\t\tgetUploadSessionPath(scope, worldId),\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic uploadFiles(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t\tfiles: UploadSessionFile[],\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\tconst formData = new FormData()\n\t\tfor (const { file, filename } of files) {\n\t\t\tformData.append('file', file, filename)\n\t\t}\n\n\t\treturn this.client.upload<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}/files`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tformData,\n\t\t\t\tonProgress: options?.onProgress,\n\t\t\t\tretry: options?.retry,\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async finalize(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}/finalize`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async cancel(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAnalyticsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_analytics_internal'\n\t}\n\n\t/**\n\t * Create an analytics event.\n\t * POST /_internal/analytics-event\n\t */\n\tpublic async createEvent(\n\t\tdata: Labrinth.Analytics.Internal.AnalyticsEventUpsert,\n\t): Promise<Labrinth.Analytics.v3.AnalyticsEvent> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent>('/analytics-event', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit an analytics event.\n\t * PATCH /_internal/analytics-event/{id}\n\t */\n\tpublic async editEvent(\n\t\tid: Labrinth.Analytics.v3.AnalyticsEventId,\n\t\tdata: Labrinth.Analytics.Internal.AnalyticsEventUpsert,\n\t): Promise<Labrinth.Analytics.v3.AnalyticsEvent> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent>(`/analytics-event/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete an analytics event.\n\t * DELETE /_internal/analytics-event/{id}\n\t */\n\tpublic async deleteEvent(id: Labrinth.Analytics.v3.AnalyticsEventId): Promise<void> {\n\t\treturn this.client.request<void>(`/analytics-event/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAnalyticsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_analytics_v3'\n\t}\n\n\t/**\n\t * Fetch analytics data for the authenticated user's accessible projects\n\t * and affiliate codes.\n\t *\n\t * @param data - Analytics request body defining time range and requested metrics\n\t * @returns Promise resolving to the analytics response, with time slices in `metrics`\n\t *\n\t * @example\n\t * ```typescript\n\t * const response = await client.labrinth.analytics_v3.fetch({\n\t * time_range: {\n\t * start: '2026-01-01T00:00:00Z',\n\t * end: '2026-02-01T00:00:00Z',\n\t * resolution: { slices: 31 },\n\t * },\n\t * project_ids: ['A1B2C3D4'],\n\t * return_metrics: {\n\t * project_views: { bucket_by: ['project_id'] },\n\t * },\n\t * })\n\t * const timeSlices = response.metrics\n\t * ```\n\t */\n\tpublic async fetch(\n\t\tdata: Labrinth.Analytics.v3.FetchRequest,\n\t): Promise<Labrinth.Analytics.v3.FetchResponse> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.FetchResponse>('/analytics', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\ttimeout: 100 * 1000,\n\t\t})\n\t}\n\n\t/**\n\t * Fetch available analytics filter facets for the authenticated user's\n\t * accessible projects.\n\t *\n\t * POST /v3/analytics/facets\n\t */\n\tpublic async fetchFacets(\n\t\tdata: Labrinth.Analytics.v3.FetchRequest,\n\t): Promise<Labrinth.Analytics.v3.FacetsResponse> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.FacetsResponse>('/analytics/facets', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\ttimeout: 100 * 1000,\n\t\t})\n\t}\n\n\t/**\n\t * Fetch all analytics events.\n\t * GET /v3/analytics-event\n\t */\n\tpublic async getEvents(): Promise<Labrinth.Analytics.v3.AnalyticsEvent[]> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent[]>('/analytics-event', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nconst BASE62_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\n\n/**\n * Decode a base62-encoded ID string into a number.\n * The backend serializes attribution group IDs as base62 strings in responses,\n * but the assign/update endpoints expect raw integer IDs in their request payloads.\n */\nfunction decodeBase62Id(id: string): number {\n\tlet value = 0\n\tfor (const char of id) {\n\t\tconst digit = BASE62_CHARS.indexOf(char)\n\t\tif (digit < 0) {\n\t\t\tthrow new Error(`Invalid base62 character \"${char}\" in id \"${id}\"`)\n\t\t}\n\t\tvalue = value * 62 + digit\n\t\tif (!Number.isSafeInteger(value)) {\n\t\t\tthrow new Error(`Base62 id \"${id}\" exceeds safe integer range`)\n\t\t}\n\t}\n\treturn value\n}\n\nexport class LabrinthAttributionInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_attribution_internal'\n\t}\n\n\t/**\n\t * List attribution groups for a project\n\t * GET /_internal/attribution/{project_id}\n\t */\n\tpublic async listProjectAttribution(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Attribution.Internal.AttributionGroup[]> {\n\t\treturn this.client.request<Labrinth.Attribution.Internal.AttributionGroup[]>(\n\t\t\t`/attribution/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update an attribution group's attribution payload.\n\t * PATCH /_internal/attribution/group/{group_id}\n\t *\n\t * @param groupId - The base62 attribution group id (as returned from listProjectAttribution).\n\t */\n\tpublic async updateGroup(\n\t\tgroupId: string,\n\t\tbody: Labrinth.Attribution.Internal.UpdateGroupRequest,\n\t): Promise<void> {\n\t\tconst numericId = decodeBase62Id(groupId)\n\t\treturn this.client.request<void>(`/attribution/group/${numericId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Delete attribution groups and all files inside them.\n\t * DELETE /_internal/attribution/group\n\t *\n\t * @param groupIds - The base62 attribution group ids (as returned from listProjectAttribution).\n\t */\n\tpublic async deleteGroups(groupIds: string[]): Promise<void> {\n\t\tconst body: Labrinth.Attribution.Internal.DeleteGroupsRequest = { groups: groupIds }\n\t\treturn this.client.request<void>('/attribution/group', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Delete all attribution groups and files for a project.\n\t * DELETE /_internal/attribution/all-groups\n\t */\n\tpublic async deleteAllGroups(projectId: string): Promise<void> {\n\t\tconst body: Labrinth.Attribution.Internal.DeleteAllGroupsRequest = {\n\t\t\tproject_id: projectId,\n\t\t}\n\t\treturn this.client.request<void>('/attribution/all-groups', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Reassign a file (by sha1) to another attribution group within the same project.\n\t * POST /_internal/attribution/assign\n\t *\n\t * @param body.target_group_id - The base62 id of the attribution group to assign the file to.\n\t */\n\tpublic async assignFileToGroup(body: {\n\t\tsha1: string\n\t\ttarget_group_id: string\n\t\tproject_id: string\n\t}): Promise<void> {\n\t\tconst wireBody: Labrinth.Attribution.Internal.AssignRequest = {\n\t\t\tsha1: body.sha1,\n\t\t\ttarget_group_id: decodeBase62Id(body.target_group_id),\n\t\t\tproject_id: body.project_id,\n\t\t}\n\t\treturn this.client.request<void>('/attribution/assign', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: wireBody,\n\t\t})\n\t}\n\n\t/**\n\t * Split a file (by sha1) out of its current attribution group into a new group.\n\t * POST /_internal/attribution/split\n\t */\n\tpublic async splitFile(body: Labrinth.Attribution.Internal.SplitRequest): Promise<void> {\n\t\treturn this.client.request<void>('/attribution/split', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Scan a file for attribution information.\n\t * POST /_internal/attribution/file/{file_id}/scan\n\t *\n\t * @param fileId - The file ID to scan.\n\t */\n\tpublic async scanFile(fileId: string): Promise<Labrinth.Attribution.Internal.FileScanResponse> {\n\t\treturn this.client.request<Labrinth.Attribution.Internal.FileScanResponse>(\n\t\t\t`/attribution/file/${fileId}/scan`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAuthInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_auth_internal'\n\t}\n\n\t/**\n\t * Check if the user is subscribed to the newsletter\n\t *\n\t * @returns Promise resolving to the subscription status\n\t */\n\tpublic async getNewsletterStatus(): Promise<Labrinth.Auth.Internal.SubscriptionStatus> {\n\t\treturn this.client.request<Labrinth.Auth.Internal.SubscriptionStatus>('/auth/email/subscribe', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Subscribe to the newsletter\n\t */\n\tpublic async subscribeNewsletter(): Promise<void> {\n\t\treturn this.client.request('/auth/email/subscribe', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Create a signed Discord community bot handoff URL\n\t */\n\tpublic async createDiscordCommunityLink(): Promise<Labrinth.Auth.Internal.DiscordCommunityLinkResponse> {\n\t\treturn this.client.request<Labrinth.Auth.Internal.DiscordCommunityLinkResponse>(\n\t\t\t'/auth/discord-community-link',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAuthV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_auth_v2'\n\t}\n\n\t/**\n\t * Log in with a password\n\t *\n\t * Returns a session token on success, or a flow ID if 2FA is required.\n\t *\n\t * @param data - Login credentials and captcha challenge\n\t * @returns Promise resolving to a login response with session or flow\n\t */\n\tpublic async login(data: Labrinth.Auth.v2.LoginRequest): Promise<Labrinth.Auth.v2.LoginResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.LoginResponse>(`/auth/login`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Complete a 2FA login flow\n\t *\n\t * @param data - The 2FA code and flow ID\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async login2FA(\n\t\tdata: Labrinth.Auth.v2.Login2FARequest,\n\t): Promise<Labrinth.Auth.v2.Login2FAResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Login2FAResponse>(`/auth/login/2fa`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Create a new account with a password\n\t *\n\t * @param data - Account creation data\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async createAccount(\n\t\tdata: Labrinth.Auth.v2.CreateAccountRequest,\n\t): Promise<Labrinth.Auth.v2.CreateAccountResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.CreateAccountResponse>(`/auth/create`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Validate email/password inputs for account creation without creating an account.\n\t *\n\t * @param data - Prospective account credentials\n\t */\n\tpublic async validateCreateAccount(\n\t\tdata: Labrinth.Auth.v2.ValidateCreateAccountRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/auth/create/validate`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Create a new account from an OAuth callback flow state\n\t *\n\t * @param data - OAuth account creation data\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async createOAuthAccount(\n\t\tdata: Labrinth.Auth.v2.CreateOAuthAccountRequest,\n\t): Promise<Labrinth.Auth.v2.CreateOAuthAccountResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.CreateOAuthAccountResponse>(`/auth/create/oauth`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Begin a password reset flow by sending a recovery email\n\t *\n\t * @param data - The username/email and captcha challenge\n\t */\n\tpublic async resetPasswordBegin(data: Labrinth.Auth.v2.ResetPasswordRequest): Promise<void> {\n\t\treturn this.client.request(`/auth/password/reset`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Change a user's password (via reset flow or with old password)\n\t *\n\t * @param data - The password change data\n\t */\n\tpublic async changePassword(data: Labrinth.Auth.v2.ChangePasswordRequest): Promise<void> {\n\t\treturn this.client.request(`/auth/password`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * List the current user's registered passkeys\n\t *\n\t * @returns A promise that resolves to a list of the user's registered passkeys\n\t */\n\tpublic async listPasskeys(): Promise<Labrinth.Auth.v2.Passkey[]> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Passkey[]>(`/auth/passkey`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Begin registering a new passkey, returning the WebAuthn creation options and a flow\n\t *\n\t * @returns A promise that resolves to the WebAuthn creation options and flow\n\t */\n\tpublic async registerPasskeyStart(): Promise<Labrinth.Auth.v2.PasskeyRegisterStartResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.PasskeyRegisterStartResponse>(\n\t\t\t`/auth/passkey/register/start`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Complete passkey registration with the created credential\n\t *\n\t * @param data The credential data and flow to complete registration with\n\t * @returns A promise that resolves to the newly registered passkey\n\t */\n\tpublic async registerPasskeyFinish(\n\t\tdata: Labrinth.Auth.v2.PasskeyRegisterFinishRequest,\n\t): Promise<Labrinth.Auth.v2.Passkey> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Passkey>(`/auth/passkey/register/finish`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Begin a passkey authentication flow, returning the WebAuthn request options and a flow\n\t *\n\t * @returns A promise that resolves to the WebAuthn request options and a flow\n\t */\n\tpublic async authenticatePasskeyStart(): Promise<Labrinth.Auth.v2.PasskeyAuthenticateStartResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.PasskeyAuthenticateStartResponse>(\n\t\t\t`/auth/passkey/start`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tskipAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Complete a passkey authentication flow, returning the new session\n\t *\n\t * @param data The credential data and flow to complete authentication with\n\t * @returns A promise that resolves to the new session\n\t */\n\tpublic async authenticatePasskeyFinish(\n\t\tdata: Labrinth.Auth.v2.PasskeyAuthenticateFinishRequest,\n\t): Promise<Labrinth.Sessions.v2.Session> {\n\t\treturn this.client.request<Labrinth.Sessions.v2.Session>(`/auth/passkey/finish`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Rename a passkey\n\t *\n\t * @param id The ID of the passkey to rename\n\t * @param data The new name for the passkey\n\t */\n\tpublic async renamePasskey(\n\t\tid: string,\n\t\tdata: Labrinth.Auth.v2.PasskeyRenameRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/auth/passkey/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a passkey\n\t *\n\t * @param id The ID of the passkey to delete\n\t */\n\tpublic async deletePasskey(id: string): Promise<void> {\n\t\treturn this.client.request(`/auth/passkey/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBillingInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_billing_internal'\n\t}\n\n\t/**\n\t * Get user's subscriptions\n\t * GET /_internal/billing/subscriptions\n\t */\n\tpublic async getSubscriptions(\n\t\tuserId?: string,\n\t): Promise<Labrinth.Billing.Internal.UserSubscription[]> {\n\t\tconst params = userId ? `?user_id=${userId}` : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.UserSubscription[]>(\n\t\t\t`/billing/subscriptions${params}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get available products for purchase\n\t * GET /_internal/billing/products\n\t */\n\tpublic async getProducts(): Promise<Labrinth.Billing.Internal.Product[]> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.Product[]>('/billing/products', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get Stripe customer information\n\t * GET /_internal/billing/customer\n\t */\n\tpublic async getCustomer(): Promise<unknown> {\n\t\treturn this.client.request<unknown>('/billing/customer', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Edit a subscription (change product, interval, cancel, etc.)\n\t * PATCH /_internal/billing/subscription/{id}\n\t */\n\tpublic async editSubscription(\n\t\tid: string,\n\t\tedit: Labrinth.Billing.Internal.EditSubscriptionRequest,\n\t\tdry?: boolean,\n\t): Promise<Labrinth.Billing.Internal.EditSubscriptionResponse | void> {\n\t\tconst params = dry ? '?dry=true' : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.EditSubscriptionResponse | void>(\n\t\t\t`/billing/subscription/${id}${params}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: edit,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get user's payment methods\n\t * GET /_internal/billing/payment_methods\n\t */\n\tpublic async getPaymentMethods(): Promise<unknown[]> {\n\t\treturn this.client.request<unknown[]>('/billing/payment_methods', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Initiate flow to add a new payment method\n\t * POST /_internal/billing/payment_method\n\t */\n\tpublic async addPaymentMethodFlow(): Promise<Labrinth.Billing.Internal.AddPaymentMethodFlowResponse> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.AddPaymentMethodFlowResponse>(\n\t\t\t'/billing/payment_method',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Edit a payment method (set as primary)\n\t * PATCH /_internal/billing/payment_method/{id}\n\t */\n\tpublic async editPaymentMethod(\n\t\tid: string,\n\t\tbody: Labrinth.Billing.Internal.EditPaymentMethodRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/payment_method/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a payment method\n\t * DELETE /_internal/billing/payment_method/{id}\n\t */\n\tpublic async removePaymentMethod(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/payment_method/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Get payment history (charges)\n\t * GET /_internal/billing/payments\n\t */\n\tpublic async getPayments(userId?: string): Promise<Labrinth.Billing.Internal.Charge[]> {\n\t\tconst params = userId ? `?user_id=${userId}` : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.Charge[]>(`/billing/payments${params}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Initiate a payment\n\t * POST /_internal/billing/payment\n\t */\n\tpublic async initiatePayment(\n\t\trequest: Labrinth.Billing.Internal.InitiatePaymentRequest,\n\t): Promise<Labrinth.Billing.Internal.InitiatePaymentResponse> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.InitiatePaymentResponse>(\n\t\t\t'/billing/payment',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Refund a charge (Admin only)\n\t * POST /_internal/billing/charge/{id}/refund\n\t */\n\tpublic async refundCharge(\n\t\tid: string,\n\t\trefund: Labrinth.Billing.Internal.RefundChargeRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/charge/${id}/refund`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: refund,\n\t\t})\n\t}\n\n\t/**\n\t * Credit subscriptions (Admin only)\n\t * POST /_internal/billing/credit\n\t */\n\tpublic async credit(request: Labrinth.Billing.Internal.CreditRequest): Promise<void> {\n\t\treturn this.client.request<void>('/billing/credit', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthCollectionsModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_collections'\n\t}\n\n\t/**\n\t * Get a collection by ID (v3)\n\t *\n\t * @param id - Collection ID\n\t * @returns Promise resolving to the collection data\n\t *\n\t * @example\n\t * ```typescript\n\t * const collection = await client.labrinth.collections.get('AANobbMI')\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Collections.Collection> {\n\t\treturn this.client.request<Labrinth.Collections.Collection>(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple collections by IDs (v3)\n\t *\n\t * @param ids - Array of collection IDs\n\t * @returns Promise resolving to array of collections\n\t *\n\t * @example\n\t * ```typescript\n\t * const collections = await client.labrinth.collections.getMultiple(['AANobbMI', 'BBNoobMI'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Collections.Collection[]> {\n\t\treturn this.client.request<Labrinth.Collections.Collection[]>(`/collections`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Edit a collection (v3)\n\t *\n\t * @param id - Collection ID\n\t * @param data - Collection update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.edit('AANobbMI', {\n\t * name: 'Updated name',\n\t * description: 'Updated description',\n\t * status: 'listed'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Collections.EditCollectionRequest): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a collection (v3)\n\t *\n\t * @param id - Collection ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.delete('AANobbMI')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Edit a collection icon (v3)\n\t *\n\t * @param id - Collection ID\n\t * @param icon - Icon file\n\t * @param ext - File extension (e.g., 'png', 'jpg')\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.editIcon('AANobbMI', iconFile, 'png')\n\t * ```\n\t */\n\tpublic async editIcon(id: string, icon: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}/icon?ext=${ext}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: icon,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a collection icon (v3)\n\t *\n\t * @param id - Collection ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.deleteIcon('AANobbMI')\n\t * ```\n\t */\n\tpublic async deleteIcon(id: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthContentV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_content_v3'\n\t}\n\n\tpublic async resolve(\n\t\trequest: Labrinth.Content.v3.ResolveContentRequest,\n\t): Promise<Labrinth.Content.v3.ResolveContentPlan> {\n\t\treturn this.client.request<Labrinth.Content.v3.ResolveContentPlan>('/content/resolve', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthExternalProjectsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_external_projects_internal'\n\t}\n\n\tpublic async search(\n\t\tdata: Labrinth.ExternalProjects.Internal.SearchRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject[]> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject[]>(\n\t\t\t'/moderation/external-license/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getBySha1(\n\t\tsha1: string,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t`/moderation/external-license/by-sha1/${sha1}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async update(\n\t\tid: number,\n\t\tdata: Labrinth.ExternalProjects.Internal.UpdateLicenseRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t`/moderation/external-license/${id}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async addFile(\n\t\tdata: Labrinth.ExternalProjects.Internal.AddFileRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t'/moderation/external-license/file',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthFriendsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_friends_v3'\n\t}\n\n\t/**\n\t * Get friends and pending friend requests for the authenticated user\n\t *\n\t * @returns Promise resolving to friend relationships\n\t */\n\tpublic async list(): Promise<Labrinth.Friends.v3.UserFriend[]> {\n\t\treturn this.client.request<Labrinth.Friends.v3.UserFriend[]>('/friends', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Send or accept a friend request\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async add(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/friend/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Remove a friend or pending friend request\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async remove(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/friend/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\n\nexport class LabrinthGeoIpModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_geoip'\n\t}\n\n\tpublic async getCountry(): Promise<string | undefined> {\n\t\tconst trace = await this.client.request<string>('/trace', {\n\t\t\tapi: 'https://api.modrinth.com',\n\t\t\tversion: 'cdn-cgi',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t\tconst country = trace\n\t\t\t.split('\\n')\n\t\t\t.find((line) => line.startsWith('loc='))\n\t\t\t?.slice(4)\n\t\t\t.toUpperCase()\n\n\t\treturn country?.match(/^[A-Z]{2}$/) ? country : undefined\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthGlobalsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_globals_internal'\n\t}\n\n\t/**\n\t * Get configured global non-secret variables for this backend instance\n\t *\n\t * @returns Promise resolving to the global configuration\n\t */\n\tpublic async get(): Promise<Labrinth.Globals.Internal.Globals> {\n\t\treturn this.client.request<Labrinth.Globals.Internal.Globals>(`/globals`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle } from '../../../types/upload'\nimport type { Labrinth } from '../types'\n\nfunction buildImageQueryParams(\n\text: Labrinth.Images.v3.ImageExtension,\n\ttarget: Labrinth.Images.v3.UploadImageParams,\n): Record<string, string> {\n\tconst params: Record<string, string> = {\n\t\text,\n\t\tcontext: target.context,\n\t}\n\tswitch (target.context) {\n\t\tcase 'project':\n\t\t\tparams.project_id = target.project_id\n\t\t\tbreak\n\t\tcase 'version':\n\t\t\tparams.version_id = target.version_id\n\t\t\tbreak\n\t\tcase 'thread_message':\n\t\t\tparams.thread_message_id = target.thread_message_id\n\t\t\tbreak\n\t\tcase 'report':\n\t\t\tif (target.report_id) params.report_id = target.report_id\n\t\t\tbreak\n\t}\n\treturn params\n}\n\nexport class LabrinthImagesV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_images_v3'\n\t}\n\n\tpublic uploadImage(\n\t\tfile: File | Blob,\n\t\text: Labrinth.Images.v3.ImageExtension,\n\t\ttarget: Labrinth.Images.v3.UploadImageParams,\n\t): UploadHandle<Labrinth.Images.v3.UploadedImage> {\n\t\treturn this.client.upload<Labrinth.Images.v3.UploadedImage>('/image', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tfile,\n\t\t\tparams: buildImageQueryParams(ext, target),\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthLimitsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_limits_v3'\n\t}\n\n\t/**\n\t * Get project creation limits for the authenticated user.\n\t */\n\tpublic async getProjectLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/projects', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get organization creation limits for the authenticated user.\n\t */\n\tpublic async getOrganizationLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/organizations', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get collection creation limits for the authenticated user.\n\t */\n\tpublic async getCollectionLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/collections', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthModerationInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_moderation_internal'\n\t}\n\n\tpublic async getProjects(\n\t\tparams: Labrinth.Moderation.Internal.ProjectsRequest = {},\n\t): Promise<Labrinth.Moderation.Internal.ProjectsResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ProjectsResponse>(\n\t\t\t'/moderation/projects',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getProjectIds(\n\t\tparams: Omit<Labrinth.Moderation.Internal.ProjectsRequest, 'count' | 'offset'> = {},\n\t): Promise<Labrinth.Moderation.Internal.ProjectIdsResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ProjectIdsResponse>(\n\t\t\t'/moderation/projects/ids',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async acquireLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockAcquireResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockAcquireResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async overrideLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockAcquireResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockAcquireResponse>(\n\t\t\t`/moderation/lock/${projectId}/override`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async releaseLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.ReleaseLockResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ReleaseLockResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async checkLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockStatusResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockStatusResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async setProjectJudgements(\n\t\tjudgements: Labrinth.Moderation.Internal.ProjectJudgements,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/project', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: judgements,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthNotificationsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_notifications_v2'\n\t}\n\n\t/**\n\t * Get all notifications for a user\n\t *\n\t * @param userId - The user's ID\n\t * @returns Promise resolving to the user's notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.notifications_v2.getUserNotifications('user123')\n\t * ```\n\t */\n\tpublic async getUserNotifications(\n\t\tuserId: string,\n\t): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/user/${userId}/notifications`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple notifications by their IDs\n\t *\n\t * @param ids - Array of notification IDs\n\t * @returns Promise resolving to an array of notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.notifications_v2.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/notifications?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Mark a single notification as read\n\t *\n\t * @param id - Notification ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.markAsRead('notif123')\n\t * ```\n\t */\n\tpublic async markAsRead(id: string): Promise<void> {\n\t\treturn this.client.request(`/notification/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t})\n\t}\n\n\t/**\n\t * Mark multiple notifications as read\n\t *\n\t * @param ids - Array of notification IDs to mark as read\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.markMultipleAsRead(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async markMultipleAsRead(ids: string[]): Promise<void> {\n\t\treturn this.client.request(`/notifications`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ids: JSON.stringify([...new Set(ids)]) },\n\t\t})\n\t}\n\n\t/**\n\t * Delete a single notification\n\t *\n\t * @param id - Notification ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.delete('notif123')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/notification/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Delete multiple notifications\n\t *\n\t * @param ids - Array of notification IDs to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.deleteMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async deleteMultiple(ids: string[]): Promise<void> {\n\t\treturn this.client.request(`/notifications`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { ids: JSON.stringify([...new Set(ids)]) },\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthOAuthInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_oauth_internal'\n\t}\n\n\t/**\n\t * Get a user's OAuth applications\n\t *\n\t * @param userId - The user's ID\n\t * @returns Promise resolving to an array of the user's OAuth clients\n\t */\n\tpublic async getUserApps(userId: string): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(\n\t\t\t`/user/${userId}/oauth_apps`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a single OAuth application by ID\n\t *\n\t * @param id - The OAuth client ID\n\t * @returns Promise resolving to the OAuth client\n\t */\n\tpublic async getApp(id: string): Promise<Labrinth.OAuth.Internal.OAuthClient> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClient>(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple OAuth applications by their IDs\n\t *\n\t * @param ids - Array of OAuth client IDs\n\t * @returns Promise resolving to an array of OAuth clients\n\t */\n\tpublic async getApps(ids: string[]): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {\n\t\tif (ids.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\t// bulk `/oauth/apps` is broken on backend, fetch by id instead\n\t\t// TODO: Remove this once the backend is fixed\n\t\tconst results = await Promise.all(ids.map((id) => this.getApp(id).catch(() => null)))\n\n\t\treturn results.filter((app): app is Labrinth.OAuth.Internal.OAuthClient => app !== null)\n\t}\n\n\t/**\n\t * Create a new OAuth application\n\t *\n\t * @param data - The OAuth app creation data\n\t * @returns Promise resolving to the created OAuth client with its client secret\n\t */\n\tpublic async createApp(\n\t\tdata: Labrinth.OAuth.Internal.CreateOAuthAppRequest,\n\t): Promise<Labrinth.OAuth.Internal.OAuthClientCreationResult> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientCreationResult>(`/oauth/app`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit an existing OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t * @param data - The fields to update\n\t */\n\tpublic async editApp(\n\t\tid: string,\n\t\tdata: Labrinth.OAuth.Internal.EditOAuthAppRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete an OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t */\n\tpublic async deleteApp(id: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update the icon for an OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t * @param file - The icon file\n\t * @param ext - The file extension (e.g. 'png', 'jpeg')\n\t */\n\tpublic async uploadAppIcon(id: string, file: File | Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Get the current user's OAuth authorizations\n\t *\n\t * @returns Promise resolving to an array of OAuth client authorizations\n\t */\n\tpublic async getAuthorizations(): Promise<Labrinth.OAuth.Internal.OAuthClientAuthorization[]> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientAuthorization[]>(\n\t\t\t`/oauth/authorizations`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Revoke an OAuth authorization for a client\n\t *\n\t * @param clientId - The OAuth client ID to revoke\n\t */\n\tpublic async revokeAuthorization(clientId: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/authorizations`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { client_id: clientId },\n\t\t})\n\t}\n\n\t/**\n\t * Initialize an OAuth authorization flow\n\t *\n\t * Returns either an OAuthClientAccessRequest (if user needs to approve)\n\t * or a redirect URL string (if already authorized).\n\t *\n\t * @param params - The OAuth query parameters\n\t * @returns Promise resolving to an access request object or redirect URL string\n\t */\n\tpublic async authorize(params: {\n\t\tclient_id: string\n\t\tredirect_uri: string\n\t\tscope: string\n\t\tstate?: string\n\t}): Promise<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string>(\n\t\t\t`/oauth/authorize`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams: params as Record<string, string>,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Accept an OAuth authorization request\n\t *\n\t * @param data - The flow ID to accept\n\t * @returns Promise resolving to a redirect URL string\n\t */\n\tpublic async accept(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {\n\t\treturn this.client.request<string>(`/oauth/accept`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Reject an OAuth authorization request\n\t *\n\t * @param data - The flow ID to reject\n\t * @returns Promise resolving to a redirect URL string\n\t */\n\tpublic async reject(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {\n\t\treturn this.client.request<string>(`/oauth/reject`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthOrganizationsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_organizations_v3'\n\t}\n\n\t/**\n\t * Get an organization by ID or slug\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @returns Promise resolving to the organization data\n\t *\n\t * @example\n\t * ```typescript\n\t * const org = await client.labrinth.organizations_v3.get('my-org')\n\t * ```\n\t */\n\tpublic async get(idOrSlug: string): Promise<Labrinth.Organizations.v3.Organization> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization>(\n\t\t\t`/organization/${idOrSlug}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get an organization's projects\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @returns Promise resolving to the organization's projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.organizations_v3.getProjects('my-org')\n\t * ```\n\t */\n\tpublic async getProjects(idOrSlug: string): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(\n\t\t\t`/organization/${idOrSlug}/projects`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple organizations by their IDs\n\t *\n\t * @param ids - Array of organization IDs\n\t * @returns Promise resolving to an array of organizations\n\t *\n\t * @example\n\t * ```typescript\n\t * const orgs = await client.labrinth.organizations_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Organizations.v3.Organization[]> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization[]>(\n\t\t\t`/organizations?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Add a project to an organization\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @param request - The project to add\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.organizations_v3.addProject('my-org', { project_id: 'AABBCCDD' })\n\t * ```\n\t */\n\tpublic async addProject(\n\t\tidOrSlug: string,\n\t\trequest: Labrinth.Organizations.v3.AddProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/organization/${idOrSlug}/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a project from an organization\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @param projectId - Project ID to remove\n\t * @param data - Request body containing the new_owner user ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.organizations_v3.removeProject('my-org', 'proj123', { new_owner: 'user456' })\n\t * ```\n\t */\n\tpublic async removeProject(\n\t\tidOrSlug: string,\n\t\tprojectId: string,\n\t\tdata: Labrinth.Organizations.v3.RemoveProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/organization/${idOrSlug}/projects/${projectId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthPatsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_pats_v2'\n\t}\n\n\t/**\n\t * Get all personal access tokens for the authenticated user\n\t *\n\t * @returns Promise resolving to an array of PATs\n\t */\n\tpublic async list(): Promise<Labrinth.Pats.v2.PersonalAccessToken[]> {\n\t\treturn this.client.request<Labrinth.Pats.v2.PersonalAccessToken[]>('/pat', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a new personal access token\n\t *\n\t * @param data - The PAT creation request data\n\t * @returns Promise resolving to the newly created PAT (includes access_token)\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Pats.v2.CreatePatRequest,\n\t): Promise<Labrinth.Pats.v2.PersonalAccessToken> {\n\t\treturn this.client.request<Labrinth.Pats.v2.PersonalAccessToken>('/pat', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Modify an existing personal access token\n\t *\n\t * @param id - The PAT ID\n\t * @param data - The fields to update\n\t */\n\tpublic async modify(id: string, data: Labrinth.Pats.v2.ModifyPatRequest): Promise<void> {\n\t\treturn this.client.request(`/pat/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a personal access token\n\t *\n\t * @param id - The PAT ID\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/pat/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Override, RawDecimal } from '../../../utils/types'\nimport type { Labrinth } from '../types'\n\ntype RawPayoutBalance = Override<\n\tLabrinth.Payout.v3.PayoutBalance,\n\t{\n\t\tavailable: RawDecimal\n\t\twithdrawn_lifetime: RawDecimal\n\t\twithdrawn_ytd: RawDecimal\n\t\tpending: RawDecimal\n\t\tdates: Record<string, RawDecimal>\n\t}\n>\n\ntype RawTransactionItem =\n\t| Override<\n\t\t\tExtract<Labrinth.Payout.v3.TransactionItem, { type: 'withdrawal' }>,\n\t\t\t{\n\t\t\t\tamount: RawDecimal\n\t\t\t\tfee: RawDecimal | null\n\t\t\t}\n\t >\n\t| Override<\n\t\t\tExtract<Labrinth.Payout.v3.TransactionItem, { type: 'payout_available' }>,\n\t\t\t{\n\t\t\t\tamount: RawDecimal\n\t\t\t}\n\t >\n\nexport class LabrinthPayoutV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_payout_v3'\n\t}\n\n\t/**\n\t * Get the authenticated user's payout balance\n\t *\n\t * @returns Promise resolving to the user's payout balance\n\t */\n\tpublic async getBalance(): Promise<Labrinth.Payout.v3.PayoutBalance> {\n\t\tconst balance = await this.client.request<RawPayoutBalance>('/payout/balance', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\n\t\treturn {\n\t\t\t...balance,\n\t\t\tavailable: Number(balance.available),\n\t\t\twithdrawn_lifetime: Number(balance.withdrawn_lifetime),\n\t\t\twithdrawn_ytd: Number(balance.withdrawn_ytd),\n\t\t\tpending: Number(balance.pending),\n\t\t\tdates: Object.fromEntries(\n\t\t\t\tObject.entries(balance.dates).map(([date, amount]) => [date, Number(amount)]),\n\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the authenticated user's transaction history (withdrawals and payouts)\n\t *\n\t * @returns Promise resolving to an array of transaction items\n\t */\n\tpublic async getHistory(): Promise<Labrinth.Payout.v3.TransactionItem[]> {\n\t\tconst history = await this.client.request<RawTransactionItem[]>('/payout/history', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\n\t\treturn history.map((transaction) => {\n\t\t\tif (transaction.type === 'withdrawal') {\n\t\t\t\treturn {\n\t\t\t\t\t...transaction,\n\t\t\t\t\tamount: Number(transaction.amount),\n\t\t\t\t\tfee: transaction.fee === null ? null : Number(transaction.fee),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...transaction,\n\t\t\t\tamount: Number(transaction.amount),\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Get available payout methods, optionally filtered by country\n\t *\n\t * @param country - Optional ISO country code to filter methods by supported countries\n\t * @returns Promise resolving to an array of payout methods\n\t */\n\tpublic async getMethods(country?: string): Promise<Labrinth.Payout.v3.PayoutMethod[]> {\n\t\treturn this.client.request<Labrinth.Payout.v3.PayoutMethod[]>('/payout/methods', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: country ? { country } : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Cancel a pending payout\n\t *\n\t * @param id - The payout ID to cancel\n\t */\n\tpublic async cancel(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/payout/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthPayoutsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_payouts_v3'\n\t}\n\n\t/**\n\t * Get platform revenue data.\n\t *\n\t * @param params - Optional start/end date filters\n\t * @returns Promise resolving to platform revenue data\n\t */\n\tpublic async getPlatformRevenue(params?: {\n\t\tstart?: string\n\t\tend?: string\n\t}): Promise<Labrinth.Payouts.v3.RevenueResponse> {\n\t\treturn this.client.request<Labrinth.Payouts.v3.RevenueResponse>('/payout/platform_revenue', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: params as Record<string, string>,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthProjectsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_projects_v2'\n\t}\n\n\t/**\n\t * Get a project by ID or slug\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @returns Promise resolving to the project data\n\t *\n\t * @example\n\t * ```typescript\n\t * const project = await client.labrinth.projects_v2.get('sodium')\n\t * console.log(project.title) // \"Sodium\"\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Projects.v2.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project>(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Check that a project slug or ID exists and return its canonical project ID.\n\t *\n\t * @param idOrSlug - Project ID or slug (e.g. `sodium` or `AANobbMI`)\n\t */\n\tpublic async check(idOrSlug: string): Promise<Labrinth.Projects.v2.ProjectCheckResponse> {\n\t\tconst encoded = encodeURIComponent(idOrSlug)\n\t\treturn this.client.request<Labrinth.Projects.v2.ProjectCheckResponse>(\n\t\t\t`/project/${encoded}/check`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple projects by IDs\n\t *\n\t * @param ids - Array of project IDs or slugs\n\t * @returns Promise resolving to array of projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.projects_v2.getMultiple(['sodium', 'lithium', 'phosphor'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Search projects\n\t *\n\t * @param params - Search parameters (query, facets, filters, etc.)\n\t * @returns Promise resolving to search results\n\t *\n\t * @example\n\t * ```typescript\n\t * const results = await client.labrinth.projects_v2.search({\n\t * query: 'optimization',\n\t * facets: [['categories:optimization'], ['project_type:mod']],\n\t * limit: 20\n\t * })\n\t * ```\n\t */\n\tpublic async search(\n\t\tparams: Labrinth.Projects.v2.ProjectSearchParams,\n\t): Promise<Labrinth.Projects.v2.SearchResult> {\n\t\treturn this.client.request<Labrinth.Projects.v2.SearchResult>(`/search`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: {\n\t\t\t\t...params,\n\t\t\t\tfacets: params.facets ? JSON.stringify(params.facets) : undefined,\n\t\t\t\tnew_filters: params.new_filters ?? undefined,\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Edit a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Project update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.edit('sodium', {\n\t * description: 'Updated description'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Partial<Labrinth.Projects.v2.Project>): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.delete('my-project')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Get dependencies for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to dependency info (projects and versions)\n\t *\n\t * @example\n\t * ```typescript\n\t * const deps = await client.labrinth.projects_v2.getDependencies('sodium')\n\t * console.log(deps.projects) // dependent projects\n\t * console.log(deps.versions) // dependent versions\n\t * ```\n\t */\n\tpublic async getDependencies(id: string): Promise<Labrinth.Projects.v2.DependencyInfo> {\n\t\treturn this.client.request<Labrinth.Projects.v2.DependencyInfo>(`/project/${id}/dependencies`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param options - Gallery image options\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.createGalleryImage('sodium', imageFile, {\n\t * featured: true,\n\t * title: 'Screenshot 1',\n\t * description: 'Main menu with Sodium enabled'\n\t * })\n\t * ```\n\t */\n\tpublic async createGalleryImage(\n\t\tid: string,\n\t\tfile: Blob,\n\t\toptions: {\n\t\t\text: string\n\t\t\tfeatured: boolean\n\t\t\ttitle?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\text: options.ext,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.title) params.title = options.title\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tparams,\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the existing gallery image to edit\n\t * @param options - Gallery image options to update\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.editGalleryImage('sodium', 'https://cdn.modrinth.com/...', {\n\t * featured: false,\n\t * title: 'Updated title'\n\t * })\n\t * ```\n\t */\n\tpublic async editGalleryImage(\n\t\tid: string,\n\t\turl: string,\n\t\toptions: {\n\t\t\tfeatured: boolean\n\t\t\ttitle?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\turl,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.title) params.title = options.title\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a gallery image from a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the gallery image to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.deleteGalleryImage('sodium', 'https://cdn.modrinth.com/...')\n\t * ```\n\t */\n\tpublic async deleteGalleryImage(id: string, url: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { url },\n\t\t})\n\t}\n\n\t/**\n\t * Get random projects\n\t *\n\t * @param count - Number of random projects to return\n\t * @returns Promise resolving to an array of random projects\n\t */\n\tpublic async getRandom(count: number): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>('/projects_random', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { count: String(count) },\n\t\t})\n\t}\n\n\t/**\n\t * Bulk edit multiple projects at once\n\t *\n\t * @param ids - Array of project IDs to edit\n\t * @param data - Fields to update across all specified projects\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.bulkEdit(['id1', 'id2'], {\n\t * issues_url: 'https://github.com/issues',\n\t * source_url: null,\n\t * })\n\t * ```\n\t */\n\tpublic async bulkEdit(\n\t\tids: string[],\n\t\tdata: Labrinth.Projects.v2.BulkEditProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "/**\n * Data for API errors\n */\nexport type ApiErrorData = {\n\t/**\n\t * HTTP status code (if available)\n\t */\n\tstatusCode?: number\n\n\t/**\n\t * Original error that was caught\n\t */\n\toriginalError?: Error\n\n\t/**\n\t * Response data from the API (if available)\n\t */\n\tresponseData?: unknown\n\n\t/**\n\t * Error context (e.g., module name, operation being performed)\n\t */\n\tcontext?: string\n}\n\n/**\n * Modrinth V1 error response format\n * Used by kyros + archon APIs\n */\nexport type ModrinthErrorResponse = {\n\t/**\n\t * Error code/identifier\n\t */\n\terror: string\n\n\t/**\n\t * Human-readable error description\n\t */\n\tdescription: string\n\n\t/**\n\t * Optional context about where the error occurred\n\t */\n\tcontext?: string\n}\n\n/**\n * Type guard to check if an object is a ModrinthErrorResponse\n */\nexport function isModrinthErrorResponse(obj: unknown): obj is ModrinthErrorResponse {\n\tif (typeof obj !== 'object' || obj === null) {\n\t\treturn false\n\t}\n\tconst record = obj as Record<string, unknown>\n\treturn typeof record.error === 'string' && typeof record.description === 'string'\n}\n", "import type { ApiErrorData, ModrinthErrorResponse } from '../types/errors'\nimport { isModrinthErrorResponse } from '../types/errors'\n\n/**\n * Base error class for all Modrinth API errors\n */\nexport class ModrinthApiError extends Error {\n\t/**\n\t * HTTP status code (if available)\n\t */\n\treadonly statusCode?: number\n\n\t/**\n\t * Original error that was caught\n\t */\n\treadonly originalError?: Error\n\n\t/**\n\t * Response data from the API (if available)\n\t */\n\treadonly responseData?: unknown\n\n\t/**\n\t * Error context (e.g., module name, operation being performed)\n\t */\n\treadonly context?: string\n\n\tconstructor(message: string, data?: ApiErrorData) {\n\t\tsuper(message)\n\t\tthis.name = 'ModrinthApiError'\n\n\t\tthis.statusCode = data?.statusCode\n\t\tthis.originalError = data?.originalError\n\t\tthis.responseData = data?.responseData\n\t\tthis.context = data?.context\n\n\t\t// Maintains proper stack trace for where our error was thrown (only available on V8)\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ModrinthApiError)\n\t\t}\n\t}\n\n\t/**\n\t * Create a ModrinthApiError from an unknown error\n\t */\n\tstatic fromUnknown(error: unknown, context?: string): ModrinthApiError {\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn error\n\t\t}\n\n\t\tif (error instanceof Error) {\n\t\t\treturn new ModrinthApiError(error.message, {\n\t\t\t\toriginalError: error,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\treturn new ModrinthApiError(String(error), { context })\n\t}\n}\n\n/**\n * Error class for Modrinth server errors (kyros/archon)\n * Extends ModrinthApiError with V1 error response parsing\n */\nexport class ModrinthServerError extends ModrinthApiError {\n\t/**\n\t * V1 error information (if available)\n\t */\n\treadonly v1Error?: ModrinthErrorResponse\n\n\tconstructor(message: string, data?: ApiErrorData & { v1Error?: ModrinthErrorResponse }) {\n\t\t// If we have a V1 error, format the message nicely\n\t\tlet errorMessage = message\n\t\tif (data?.v1Error) {\n\t\t\terrorMessage = `[${data.v1Error.error}] ${data.v1Error.description}`\n\t\t\tif (data.v1Error.context) {\n\t\t\t\terrorMessage = `${data.v1Error.context}: ${errorMessage}`\n\t\t\t}\n\t\t}\n\n\t\tsuper(errorMessage, data)\n\t\tthis.name = 'ModrinthServerError'\n\t\tthis.v1Error = data?.v1Error\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ModrinthServerError)\n\t\t}\n\t}\n\n\t/**\n\t * Create a ModrinthServerError from response data\n\t */\n\tstatic fromResponse(\n\t\tstatusCode: number,\n\t\tresponseData: unknown,\n\t\tcontext?: string,\n\t): ModrinthServerError {\n\t\tconst v1Error = isModrinthErrorResponse(responseData) ? responseData : undefined\n\n\t\tlet message = `HTTP ${statusCode}`\n\t\tif (v1Error) {\n\t\t\tmessage = v1Error.description\n\t\t} else if (typeof responseData === 'string') {\n\t\t\tmessage = responseData\n\t\t}\n\n\t\treturn new ModrinthServerError(message, {\n\t\t\tstatusCode,\n\t\t\tresponseData,\n\t\t\tcontext,\n\t\t\tv1Error,\n\t\t})\n\t}\n\n\t/**\n\t * Create a ModrinthServerError from an unknown error\n\t */\n\tstatic fromUnknown(error: unknown, context?: string): ModrinthServerError {\n\t\tif (error instanceof ModrinthServerError) {\n\t\t\treturn error\n\t\t}\n\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn new ModrinthServerError(error.message, {\n\t\t\t\tstatusCode: error.statusCode,\n\t\t\t\toriginalError: error.originalError,\n\t\t\t\tresponseData: error.responseData,\n\t\t\t\tcontext: context ?? error.context,\n\t\t\t})\n\t\t}\n\n\t\tif (error instanceof Error) {\n\t\t\treturn new ModrinthServerError(error.message, {\n\t\t\t\toriginalError: error,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\treturn new ModrinthServerError(String(error), { context })\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport { ModrinthApiError } from '../../../core/errors'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthProjectsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_projects_v3'\n\t}\n\n\t/**\n\t * Get a project by ID or slug (v3)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @returns Promise resolving to the v3 project data\n\t *\n\t * @example\n\t * ```typescript\n\t * const project = await client.labrinth.projects_v3.get('sodium')\n\t * console.log(project.project_types) // v3 field\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Projects.v3.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project>(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a project's dependencies (v3)\n\t *\n\t * Returns all projects and versions that are dependencies of this project's versions.\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to dependency data with projects and versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const deps = await client.labrinth.projects_v3.getDependencies('sodium')\n\t * console.log(deps.projects) // Array of project objects\n\t * console.log(deps.versions) // Array of version objects\n\t * ```\n\t */\n\tpublic async getDependencies(id: string): Promise<Labrinth.Projects.v3.ProjectDependencies> {\n\t\treturn this.client.request<Labrinth.Projects.v3.ProjectDependencies>(\n\t\t\t`/project/${id}/dependencies`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple projects by IDs (v3)\n\t *\n\t * @param ids - Array of project IDs or slugs\n\t * @returns Promise resolving to array of v3 projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.projects_v3.getMultiple(['sodium', 'lithium'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Search projects (v3)\n\t *\n\t * @param params - Search parameters\n\t * @returns Promise resolving to v3 search results\n\t */\n\tpublic async search(\n\t\tparams: Labrinth.Search.SearchParams,\n\t\toptions?: {\n\t\t\theaders?: Record<string, string>\n\t\t},\n\t): Promise<Labrinth.Search.v3.SearchResults> {\n\t\treturn this.client.request<Labrinth.Search.v3.SearchResults>(`/search`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\theaders: options?.headers,\n\t\t\tparams: {\n\t\t\t\t...params,\n\t\t\t\tfacets: params.facets ? JSON.stringify(params.facets) : undefined,\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Edit a project (v3)\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Project update data (v3 fields)\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.edit('sodium', {\n\t * environment: 'client_and_server'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Projects.v3.EditProjectRequest): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get the organization that owns a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to the organization data, or null if the project is not owned by an organization\n\t */\n\tpublic async getOrganization(id: string): Promise<Labrinth.Projects.v3.Organization | null> {\n\t\ttry {\n\t\t\treturn await this.client.request<Labrinth.Projects.v3.Organization>(\n\t\t\t\t`/project/${id}/organization`,\n\t\t\t\t{ api: 'labrinth', version: 3, method: 'GET' },\n\t\t\t)\n\t\t} catch (error) {\n\t\t\t// 404 means the project is not owned by an organization\n\t\t\tif (error instanceof ModrinthApiError && error.statusCode === 404) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get the team members of a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to an array of team members\n\t */\n\tpublic async getMembers(id: string): Promise<Labrinth.Projects.v3.TeamMember[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.TeamMember[]>(`/project/${id}/members`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\tpublic async createServerProject(\n\t\tdata: Labrinth.Projects.v3.CreateServerProjectRequest,\n\t): Promise<Labrinth.Projects.v3.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project>(`/project`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PUT',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteProject('my-project')\n\t * ```\n\t */\n\tpublic async deleteProject(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Change the icon of a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param ext - File extension (e.g., 'png', 'jpeg', 'gif', 'webp')\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.changeIcon('sodium', imageFile, 'png')\n\t * ```\n\t */\n\tpublic async changeIcon(id: string, file: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete the icon of a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteIcon('sodium')\n\t * ```\n\t */\n\tpublic async deleteIcon(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Create a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param options - Gallery image options\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.createGalleryImage('sodium', imageFile, {\n\t * featured: true,\n\t * name: 'Screenshot 1',\n\t * description: 'Main menu with Sodium enabled'\n\t * })\n\t * ```\n\t */\n\tpublic async createGalleryImage(\n\t\tid: string,\n\t\tfile: Blob,\n\t\toptions: {\n\t\t\text: string\n\t\t\tfeatured: boolean\n\t\t\tname?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\text: options.ext,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.name) params.name = options.name\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tparams,\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a gallery image from a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the gallery image to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteGalleryImage('sodium', 'https://cdn.modrinth.com/...')\n\t * ```\n\t */\n\tpublic async deleteGalleryImage(id: string, url: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { url },\n\t\t})\n\t}\n\n\t/**\n\t * Get content disclosures for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to the project's disclosures\n\t *\n\t * @example\n\t * ```typescript\n\t * const { disclosures } = await client.labrinth.projects_v3.getDisclosures('sodium')\n\t * ```\n\t */\n\tpublic async getDisclosures(id: string): Promise<Labrinth.Projects.v3.GetProjectDisclosures> {\n\t\treturn this.client.request<Labrinth.Projects.v3.GetProjectDisclosures>(\n\t\t\t`/project/${id}/disclosures`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Modify content disclosures for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Disclosures to set and types to remove\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.modifyDisclosures('sodium', {\n\t * set: [{ type: 'ai_content', uses: ['text'], note: 'Translations are AI-generated.' }],\n\t * remove: ['advertisements'],\n\t * })\n\t * ```\n\t */\n\tpublic async modifyDisclosures(\n\t\tid: string,\n\t\tdata: Labrinth.Projects.v3.ModifyProjectDisclosures,\n\t): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/disclosures`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthReportsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_reports_v3'\n\t}\n\n\t/**\n\t * Get a report by ID\n\t *\n\t * @param id - Report ID\n\t * @returns Promise resolving to the report data\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.reports_v3.get('abc123')\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Reports.v3.Report> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report>(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * List reports for the current user (or all reports if moderator)\n\t *\n\t * @param params - Optional query parameters for count, offset, and whether to show all reports\n\t * @returns Promise resolving to an array of reports\n\t *\n\t * @example\n\t * ```typescript\n\t * const reports = await client.labrinth.reports_v3.list({ count: 100 })\n\t * ```\n\t */\n\tpublic async list(\n\t\tparams?: Labrinth.Reports.v3.ListReportsParams,\n\t): Promise<Labrinth.Reports.v3.Report[]> {\n\t\tconst queryParams: Record<string, string> = {}\n\t\tif (params?.count != null) queryParams.count = String(params.count)\n\t\tif (params?.offset != null) queryParams.offset = String(params.offset)\n\t\tif (params?.all != null) queryParams.all = String(params.all)\n\n\t\treturn this.client.request<Labrinth.Reports.v3.Report[]>(`/report`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(queryParams).length > 0 ? queryParams : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple reports by IDs\n\t *\n\t * @param ids - Array of report IDs\n\t * @returns Promise resolving to an array of reports\n\t *\n\t * @example\n\t * ```typescript\n\t * const reports = await client.labrinth.reports_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Reports.v3.Report[]> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report[]>(\n\t\t\t`/reports?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Create a new report\n\t *\n\t * @param data - Report creation data\n\t * @returns Promise resolving to the created report\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.reports_v3.create({\n\t * report_type: 'spam',\n\t * item_id: 'project123',\n\t * item_type: 'project',\n\t * body: 'This project is spam',\n\t * })\n\t * ```\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Reports.v3.CreateReportRequest,\n\t): Promise<Labrinth.Reports.v3.Report> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report>(`/report`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a report\n\t *\n\t * @param id - Report ID\n\t * @param data - Report edit data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.reports_v3.edit('abc123', { closed: true })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Reports.v3.EditReportRequest): Promise<void> {\n\t\treturn this.client.request(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a report (moderator only)\n\t *\n\t * @param id - Report ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.reports_v3.delete('abc123')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthServerPingInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_server_ping_internal'\n\t}\n\n\t/**\n\t * Ping a Minecraft Java server\n\t * POST /_internal/server-ping/minecraft-java\n\t */\n\tpublic async pingMinecraftJava(\n\t\trequest: Labrinth.ServerPing.Internal.MinecraftJavaPingRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/server-ping/minecraft-java', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthSessionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_sessions_v2'\n\t}\n\n\t/**\n\t * List all sessions for the authenticated user\n\t *\n\t * @returns Promise resolving to an array of sessions\n\t */\n\tpublic async list(): Promise<Labrinth.Sessions.v2.Session[]> {\n\t\treturn this.client.request<Labrinth.Sessions.v2.Session[]>('/session/list', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Delete (revoke) a session\n\t *\n\t * @param id - The session ID\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/session/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthStateModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_state'\n\t}\n\n\t/**\n\t * Build the complete generated state by fetching from multiple endpoints\n\t *\n\t * @returns Promise resolving to the generated state containing categories, loaders, products, etc.\n\t *\n\t * @example\n\t * ```typescript\n\t * const state = await client.labrinth.state.build()\n\t * console.log(state.products) // Available billing products\n\t * ```\n\t */\n\tpublic async build(): Promise<Labrinth.State.GeneratedState> {\n\t\tconst errors: unknown[] = []\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tconst handleError = (err: any, defaultValue: any, endpoint: string) => {\n\t\t\tconsole.error('Error fetching state data:', err)\n\t\t\terrors.push({ endpoint, error: err })\n\t\t\treturn defaultValue\n\t\t}\n\n\t\t// TODO: as we add new modules, move these raw requests to actual\n\t\t// abstractions\n\t\tconst [\n\t\t\tcategories,\n\t\t\tloaders,\n\t\t\tgameVersions,\n\t\t\tdonationPlatforms,\n\t\t\treportTypes,\n\t\t\thomePageProjects,\n\t\t\thomePageSearch,\n\t\t\thomePageNotifs,\n\t\t\tproducts,\n\t\t\tmuralBankDetails,\n\t\t\tiso3166Data,\n\t\t\tpayoutMethods,\n\t\t\tglobals,\n\t\t] = await Promise.all([\n\t\t\t// Tag endpoints\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.Category[]>('/tag/category', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/category')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.Loader[]>('/tag/loader', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/loader')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.GameVersion[]>('/tag/game_version', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/game_version')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.DonationPlatform[]>('/tag/donation_platform', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/donation_platform')),\n\t\t\tthis.client\n\t\t\t\t.request<string[]>('/tag/report_type', { api: 'labrinth', version: 2, method: 'GET' })\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/report_type')),\n\n\t\t\t// Homepage data\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Projects.v2.Project[]>('/projects_random', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { count: '60' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/projects_random')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Search.v2.SearchResults>('/search', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { limit: '3', query: 'leave', index: 'relevance' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, {} as Labrinth.Search.v2.SearchResults, '/v2/search')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Search.v2.SearchResults>('/search', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { limit: '3', query: '', index: 'updated' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, {} as Labrinth.Search.v2.SearchResults, '/v2/search')),\n\n\t\t\t// Internal billing/mural endpoints\n\t\t\tthis.client.labrinth.billing_internal\n\t\t\t\t.getProducts()\n\t\t\t\t.catch((err) => handleError(err, [], '/_internal/billing/products')),\n\t\t\tthis.client\n\t\t\t\t.request<{ bankDetails: Record<string, { bankNames: string[] }> }>('/mural/bank-details', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 'internal',\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, null, '/_internal/mural/bank-details')),\n\n\t\t\t// ISO3166 country and subdivision data\n\t\t\tthis.client.iso3166.data\n\t\t\t\t.build()\n\t\t\t\t.catch((err) => handleError(err, { countries: [], subdivisions: {} }, 'iso3166/data')),\n\n\t\t\t// Payout methods for tremendous ID mapping\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.State.PayoutMethodInfo[]>('/payout/methods', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 3,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v3/payout/methods')),\n\n\t\t\t// Global configuration\n\t\t\tthis.client\n\t\t\t\t.request<{ tax_compliance_thresholds: Record<string, number> }>('/globals', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 'internal',\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, null, '/_internal/globals')),\n\t\t])\n\n\t\tconst tremendousIdMap = Object.fromEntries(\n\t\t\t(payoutMethods as Labrinth.State.PayoutMethodInfo[])\n\t\t\t\t.filter((m) => m.type === 'tremendous')\n\t\t\t\t.map((m) => [m.id, { name: m.name, image_url: m.image_logo_url }]),\n\t\t)\n\n\t\treturn {\n\t\t\tcategories,\n\t\t\tloaders,\n\t\t\tgameVersions,\n\t\t\tdonationPlatforms,\n\t\t\treportTypes,\n\t\t\thomePageProjects,\n\t\t\thomePageSearch,\n\t\t\thomePageNotifs,\n\t\t\tproducts,\n\t\t\t// Always emit a value: `undefined` is dropped by JSON.stringify, and consumers\n\t\t\t// import these keys by name from the generated state.\n\t\t\tmuralBankDetails: muralBankDetails?.bankDetails ?? {},\n\t\t\ttremendousIdMap,\n\t\t\tcountries: iso3166Data.countries,\n\t\t\tsubdivisions: iso3166Data.subdivisions,\n\t\t\ttaxComplianceThresholds: globals?.tax_compliance_thresholds ?? {},\n\t\t\terrors,\n\t\t}\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTechReviewInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_tech_review_internal'\n\t}\n\n\t/**\n\t * Search for projects awaiting technical review.\n\t *\n\t * Returns a flat list of file reports with associated project data, ownership\n\t * information, and moderation threads provided as lookup maps.\n\t *\n\t * @param params - Search parameters including pagination, filters, and sorting\n\t * @returns Response object containing reports array and lookup maps for projects, threads, and ownership\n\t *\n\t * @example\n\t * ```typescript\n\t * const response = await client.labrinth.tech_review_internal.searchProjects({\n\t * limit: 20,\n\t * page: 0,\n\t * sort_by: 'created_asc',\n\t * filter: {\n\t * project_type: ['mod', 'modpack']\n\t * }\n\t * })\n\t * // Access reports: response.reports\n\t * // Access project by ID: response.projects[projectId]\n\t * ```\n\t */\n\tpublic async searchProjects(\n\t\tparams: Labrinth.TechReview.Internal.SearchProjectsRequest,\n\t): Promise<Labrinth.TechReview.Internal.SearchResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.SearchResponse>(\n\t\t\t'/moderation/tech-review/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get detailed information about a specific file report.\n\t *\n\t * @param reportId - The Delphi report ID\n\t * @returns Full report with all issues and details\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.tech_review_internal.getReport('report-123')\n\t * console.log(report.file_name, report.issues.length)\n\t * ```\n\t */\n\tpublic async getReport(reportId: string): Promise<Labrinth.TechReview.Internal.FileReport> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.FileReport>(\n\t\t\t`/moderation/tech-review/report/${reportId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get detailed information about a specific issue.\n\t *\n\t * @param issueId - The issue ID\n\t * @returns Issue with all its details\n\t *\n\t * @example\n\t * ```typescript\n\t * const issue = await client.labrinth.tech_review_internal.getIssue('issue-123')\n\t * console.log(issue.issue_type, issue.status)\n\t * ```\n\t */\n\tpublic async getIssue(issueId: string): Promise<Labrinth.TechReview.Internal.FileIssue> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.FileIssue>(\n\t\t\t`/moderation/tech-review/issue/${issueId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update the status of a technical review issue detail.\n\t *\n\t * Allows moderators to mark an individual issue detail as safe (false positive) or unsafe (malicious).\n\t *\n\t * @param detailId - The ID of the issue detail to update\n\t * @param data - The verdict for the detail\n\t * @returns Promise that resolves when the update is complete\n\t */\n\tpublic async updateIssueDetail(\n\t\tdetailId: string,\n\t\tdata: Labrinth.TechReview.Internal.UpdateIssueDetailRequest,\n\t): Promise<void> {\n\t\treturn this.updateIssueDetails([{ detail_id: detailId, verdict: data.verdict }])\n\t}\n\n\tpublic async updateIssueDetails(\n\t\tdata: Labrinth.TechReview.Internal.UpdateIssueRequest[],\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/tech-review/issue-detail', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\tpublic async updateGlobalIssueDetails(\n\t\tdata: Labrinth.TechReview.Internal.UpdateGlobalIssueRequest[],\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/tech-review/global-issue-detail', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\tpublic async searchGlobalIssueDetails(\n\t\tparams: Labrinth.TechReview.Internal.SearchGlobalIssueDetailsRequest,\n\t): Promise<Labrinth.TechReview.Internal.SearchGlobalIssueDetailsResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.SearchGlobalIssueDetailsResponse>(\n\t\t\t'/moderation/tech-review/global-issue-detail/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getGlobalIssueDetail(\n\t\tparams: Labrinth.TechReview.Internal.GetGlobalIssueDetailRequest,\n\t): Promise<Labrinth.TechReview.Internal.GetGlobalIssueDetailResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.GetGlobalIssueDetailResponse>(\n\t\t\t'/moderation/tech-review/global-issue-detail/local-traces',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async submitProject(\n\t\tprojectId: string,\n\t\tdata: Labrinth.TechReview.Internal.SubmitProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/moderation/tech-review/submit/${projectId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get the project report and thread for a specific project.\n\t *\n\t * @param projectId - The project ID\n\t * @returns The project report (may be null if no reports exist) and the moderation thread\n\t */\n\tpublic async getProjectReport(\n\t\tprojectId: string,\n\t): Promise<Labrinth.TechReview.Internal.ProjectReportResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.ProjectReportResponse>(\n\t\t\t`/moderation/tech-review/project/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthThreadsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_threads_v3'\n\t}\n\n\t/**\n\t * Get a thread by ID (v3)\n\t *\n\t * @param id - Thread ID\n\t * @returns Promise resolving to the thread data\n\t *\n\t * @example\n\t * ```typescript\n\t * const thread = await client.labrinth.threads_v3.getThread('abc123')\n\t * console.log(thread.messages)\n\t * ```\n\t */\n\tpublic async getThread(id: string): Promise<Labrinth.Threads.v3.Thread> {\n\t\treturn this.client.request<Labrinth.Threads.v3.Thread>(`/thread/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple threads by IDs (v3)\n\t *\n\t * @param ids - Array of thread IDs\n\t * @returns Promise resolving to an array of threads\n\t *\n\t * @example\n\t * ```typescript\n\t * const threads = await client.labrinth.threads_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Threads.v3.Thread[]> {\n\t\treturn this.client.request<Labrinth.Threads.v3.Thread[]>(\n\t\t\t`/threads?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Send a message to a thread (v3)\n\t *\n\t * @param id - Thread ID\n\t * @param message - Message body to send\n\t * @returns Promise resolving when message is sent\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.threads_v3.sendMessage('abc123', {\n\t * body: { type: 'text', body: 'Hello!' }\n\t * })\n\t * ```\n\t */\n\tpublic async sendMessage(\n\t\tid: string,\n\t\tmessage: Labrinth.Threads.v3.SendMessageRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/thread/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: message,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a message from a thread (v3)\n\t *\n\t * @param messageId - Message ID\n\t * @returns Promise resolving when message is deleted\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.threads_v3.deleteMessage('msg123')\n\t * ```\n\t */\n\tpublic async deleteMessage(messageId: string): Promise<void> {\n\t\treturn this.client.request(`/message/${messageId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthUsersV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_users_v2'\n\t}\n\n\t/**\n\t * Get a user by ID or username\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to the user data\n\t *\n\t * @example\n\t * ```typescript\n\t * const user = await client.labrinth.users_v2.get('my_user')\n\t * ```\n\t */\n\tpublic async get(idOrUsername: string): Promise<Labrinth.Users.v2.User> {\n\t\treturn this.client.request<Labrinth.Users.v2.User>(`/user/${idOrUsername}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple users by their IDs\n\t *\n\t * @param ids - Array of user IDs\n\t * @returns Promise resolving to an array of users\n\t *\n\t * @example\n\t * ```typescript\n\t * const users = await client.labrinth.users_v2.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Users.v2.User[]> {\n\t\treturn this.client.request<Labrinth.Users.v2.User[]>(\n\t\t\t`/users?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's projects\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v2.getProjects('my_user')\n\t * ```\n\t */\n\tpublic async getProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a user's organizations\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's organizations\n\t *\n\t * @example\n\t * ```typescript\n\t * const orgs = await client.labrinth.users_v2.getOrganizations('my_user')\n\t * ```\n\t */\n\tpublic async getOrganizations(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Organizations.v3.Organization[]> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization[]>(\n\t\t\t`/user/${idOrUsername}/organizations`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's collections\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's collections\n\t *\n\t * @example\n\t * ```typescript\n\t * const collections = await client.labrinth.users_v2.getCollections('my_user')\n\t * ```\n\t */\n\tpublic async getCollections(idOrUsername: string): Promise<Labrinth.Collections.Collection[]> {\n\t\treturn this.client.request<Labrinth.Collections.Collection[]>(\n\t\t\t`/user/${idOrUsername}/collections`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's notifications\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.users_v2.getNotifications('my_user')\n\t * ```\n\t */\n\tpublic async getNotifications(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/user/${idOrUsername}/notifications`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get projects a user follows\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of followed projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v2.getFollowedProjects('my_user')\n\t * ```\n\t */\n\tpublic async getFollowedProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/follows`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Update a user\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @param data - Fields to update\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.users_v2.patch('my_user', { role: 'admin' })\n\t * ```\n\t */\n\tpublic async patch(\n\t\tidOrUsername: string,\n\t\tdata: Partial<Pick<Labrinth.Users.v2.User, 'badges' | 'bio' | 'role' | 'username'>>,\n\t): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Change a user's avatar.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @param file - Image file to upload\n\t * @param ext - File extension (e.g., 'png', 'jpeg', 'gif', 'webp')\n\t */\n\tpublic async changeIcon(idOrUsername: string, file: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a user's avatar.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t */\n\tpublic async deleteIcon(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthUsersV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_users_v3'\n\t}\n\n\t/**\n\t * Get the authenticated user.\n\t * GET /v3/user\n\t */\n\tpublic async getAuthenticated(): Promise<Labrinth.Users.v3.User> {\n\t\treturn this.client.request<Labrinth.Users.v3.User>('/user', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a user by ID or username\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to the user data\n\t *\n\t * GET /v3/user/{id}\n\t */\n\tpublic async get(idOrUsername: string): Promise<Labrinth.Users.v3.User> {\n\t\treturn this.client.request<Labrinth.Users.v3.User>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's account preferences. The authenticated user may access their\n\t * own preferences, while moderators may access another user's preferences.\n\t *\n\t * GET /v3/user/{id}/preferences\n\t */\n\tpublic async getPreferences(idOrUsername: string): Promise<Labrinth.Users.v3.UserPreferences> {\n\t\treturn this.client.request<Labrinth.Users.v3.UserPreferences>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/preferences`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update a user's account preferences and return the fully resolved result.\n\t *\n\t * PATCH /v3/user/{id}/preferences\n\t */\n\tpublic async patchPreferences(\n\t\tidOrUsername: string,\n\t\tpreferences: Labrinth.Users.v3.PartialUserPreferences,\n\t): Promise<Labrinth.Users.v3.UserPreferences> {\n\t\treturn this.client.request<Labrinth.Users.v3.UserPreferences>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/preferences`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: preferences,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Search users by username prefix.\n\t *\n\t * @param query - Username search query\n\t * @returns Promise resolving to compact user search results\n\t *\n\t * GET /v3/users/search?query=:query\n\t */\n\tpublic async search(query: string): Promise<Labrinth.Users.v3.SearchUser[]> {\n\t\treturn this.client.request<Labrinth.Users.v3.SearchUser[]>(\n\t\t\t`/users/search?query=${encodeURIComponent(query)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get all projects the authenticated user can access directly or through\n\t * their organizations.\n\t *\n\t * @param idOrUsername - User ID or username. Must be the authenticated user.\n\t *\n\t * GET /v3/user/{id}/all-projects\n\t */\n\tpublic async getAllProjects(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Users.v3.AllProjectsResponse> {\n\t\treturn this.client.request<Labrinth.Users.v3.AllProjectsResponse>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/all-projects`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthVersionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_versions_v2'\n\t}\n\n\t/**\n\t * Get versions for a project (v2)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @param options - Optional query parameters to filter versions\n\t * @returns Promise resolving to an array of v2 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v2.getProjectVersions('sodium')\n\t * const filteredVersions = await client.labrinth.versions_v2.getProjectVersions('sodium', {\n\t * game_versions: ['1.20.1'],\n\t * loaders: ['fabric'],\n\t * include_changelog: false\n\t * })\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getProjectVersions(\n\t\tid: string,\n\t\toptions?: Labrinth.Versions.v2.GetProjectVersionsParams,\n\t): Promise<Labrinth.Versions.v2.Version[]> {\n\t\tconst params: Record<string, string> = {}\n\t\tif (options?.game_versions?.length) {\n\t\t\tparams.game_versions = JSON.stringify(options.game_versions)\n\t\t}\n\t\tif (options?.loaders?.length) {\n\t\t\tparams.loaders = JSON.stringify(options.loaders)\n\t\t}\n\t\tif (options?.include_changelog === false) {\n\t\t\tparams.include_changelog = 'false'\n\t\t}\n\t\tif (options?.limit != null) {\n\t\t\tparams.limit = String(options.limit)\n\t\t}\n\t\tif (options?.offset != null) {\n\t\t\tparams.offset = String(options.offset)\n\t\t}\n\n\t\treturn this.client.request<Labrinth.Versions.v2.Version[]>(`/project/${id}/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific version by ID (v2)\n\t *\n\t * @param id - Version ID\n\t * @returns Promise resolving to the v2 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v2.getVersion('DXtmvS8i')\n\t * console.log(version.version_number)\n\t * ```\n\t */\n\tpublic async getVersion(id: string): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(`/version/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\tpublic async getVersionFromFileHash(\n\t\thash: string,\n\t\talgorithm: keyof Labrinth.Versions.v2.VersionFileHash,\n\t): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(`/version_file/${hash}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { algorithm },\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple versions by IDs (v2)\n\t *\n\t * @param ids - Array of version IDs\n\t * @returns Promise resolving to an array of v2 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v2.getVersions(['DXtmvS8i', 'abc123'])\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getVersions(ids: string[]): Promise<Labrinth.Versions.v2.Version[]> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version[]>(`/versions`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Get a version from a project by version ID or number (v2)\n\t *\n\t * @param projectId - Project ID or slug\n\t * @param versionId - Version ID or version number\n\t * @returns Promise resolving to the v2 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v2.getVersionFromIdOrNumber('sodium', 'DXtmvS8i')\n\t * const versionByNumber = await client.labrinth.versions_v2.getVersionFromIdOrNumber('sodium', '0.4.12')\n\t * ```\n\t */\n\tpublic async getVersionFromIdOrNumber(\n\t\tprojectId: string,\n\t\tversionId: string,\n\t): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(\n\t\t\t`/project/${projectId}/version/${versionId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Delete a version by ID (v2)\n\t *\n\t * @param versionId - Version ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.versions_v2.deleteVersion('DXtmvS8i')\n\t * ```\n\t */\n\tpublic async deleteVersion(versionId: string): Promise<void> {\n\t\treturn this.client.request(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle } from '../../../types/upload'\nimport type { Labrinth } from '../types'\n\nconst VERSION_UPLOAD_TIMEOUT_MS = 30 * 60 * 1000\n\nexport class LabrinthVersionsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_versions_v3'\n\t}\n\n\t/**\n\t * Get versions for a project (v3)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @param options - Optional query parameters to filter versions\n\t * @returns Promise resolving to an array of v3 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v3.getProjectVersions('sodium')\n\t * const filteredVersions = await client.labrinth.versions_v3.getProjectVersions('sodium', {\n\t * game_versions: ['1.20.1'],\n\t * loaders: ['fabric']\n\t * })\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getProjectVersions(\n\t\tid: string,\n\t\toptions?: Labrinth.Versions.v3.GetProjectVersionsParams,\n\t): Promise<Labrinth.Versions.v3.Version[]> {\n\t\tconst params: Record<string, string | boolean> = {}\n\t\tif (options?.game_versions?.length) {\n\t\t\tparams.game_versions = JSON.stringify(options.game_versions)\n\t\t}\n\t\tif (options?.loaders?.length) {\n\t\t\tparams.loaders = JSON.stringify(options.loaders)\n\t\t}\n\t\tif (options?.include_changelog === false) {\n\t\t\tparams.include_changelog = 'false'\n\t\t}\n\t\tif (options?.limit != null) {\n\t\t\tparams.limit = String(options.limit)\n\t\t}\n\t\tif (options?.offset != null) {\n\t\t\tparams.offset = String(options.offset)\n\t\t}\n\n\t\treturn this.client.request<Labrinth.Versions.v3.Version[]>(`/project/${id}/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: options?.apiVersion ?? 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific version by ID (v3)\n\t *\n\t * @param id - Version ID\n\t * @returns Promise resolving to the v3 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v3.getVersion('DXtmvS8i')\n\t * console.log(version.version_number)\n\t * ```\n\t */\n\tpublic async getVersion(id: string): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(`/version/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple versions by IDs (v3)\n\t *\n\t * @param ids - Array of version IDs\n\t * @returns Promise resolving to an array of v3 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v3.getVersions(['DXtmvS8i', 'abc123'])\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getVersions(ids: string[]): Promise<Labrinth.Versions.v3.Version[]> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version[]>(`/versions`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Get a version from a project by version ID or number (v3)\n\t *\n\t * @param projectId - Project ID or slug\n\t * @param versionId - Version ID or version number\n\t * @returns Promise resolving to the v3 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v3.getVersionFromIdOrNumber('sodium', 'DXtmvS8i')\n\t * const versionByNumber = await client.labrinth.versions_v3.getVersionFromIdOrNumber('sodium', '0.4.12')\n\t * ```\n\t */\n\tpublic async getVersionFromIdOrNumber(\n\t\tprojectId: string,\n\t\tversionId: string,\n\t): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(\n\t\t\t`/project/${projectId}/version/${versionId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Create a new version for a project (v3)\n\t *\n\t * Creates a new version on an existing project. At least one file must be\n\t * attached unless the version is created as a draft.\n\t *\n\t * @param data - JSON metadata payload for the version (must include file_parts)\n\t * @param files - Array of uploaded files, in the same order as `data.file_parts`\n\t *\n\t * @returns A promise resolving to the newly created version data\n\t *\n\t * @example\n\t * ```ts\n\t * const version = await client.labrinth.versions_v3.createVersion('sodium', {\n\t * name: 'v0.5.0',\n\t * version_number: '0.5.0',\n\t * version_type: 'release',\n\t * loaders: ['fabric'],\n\t * game_versions: ['1.20.1'],\n\t * project_id: 'sodium',\n\t * file_parts: ['primary']\n\t * }, [fileObject])\n\t * ```\n\t */\n\n\tpublic createVersion(\n\t\tdraftVersion: Labrinth.Versions.v3.DraftVersion,\n\t\tversionFiles: Labrinth.Versions.v3.DraftVersionFile[],\n\t\tprojectType: Labrinth.Projects.v2.ProjectType | null = null,\n\t): UploadHandle<Labrinth.Versions.v3.Version> {\n\t\tconst formData = new FormData()\n\n\t\tconst files = versionFiles.map((vf) => vf.file)\n\t\tconst fileTypes = versionFiles.map((vf) => vf.fileType || null)\n\n\t\tconst fileParts = files.map((file, i) => {\n\t\t\treturn `${file.name}-${i === 0 ? 'primary' : i}`\n\t\t})\n\n\t\tconst fileTypeMap = fileParts.reduce<Record<string, Labrinth.Versions.v3.FileType | null>>(\n\t\t\t(acc, key, i) => {\n\t\t\t\tacc[key] = fileTypes[i]\n\t\t\t\treturn acc\n\t\t\t},\n\t\t\t{},\n\t\t)\n\n\t\tconst data: Labrinth.Versions.v3.CreateVersionRequest = {\n\t\t\tproject_id: draftVersion.project_id,\n\t\t\tversion_number: draftVersion.version_number,\n\t\t\tname: draftVersion.name || draftVersion.version_number,\n\t\t\tchangelog: draftVersion.changelog,\n\t\t\tdependencies: draftVersion.dependencies || [],\n\t\t\tgame_versions: draftVersion.game_versions,\n\t\t\tversion_type: draftVersion.version_type,\n\t\t\tfeatured: !!draftVersion.featured,\n\t\t\tfile_parts: fileParts,\n\t\t\tfile_types: fileTypeMap,\n\t\t\tprimary_file: fileParts[0],\n\t\t\tenvironment: draftVersion.environment,\n\t\t\tloaders: draftVersion.loaders,\n\t\t}\n\n\t\tif (projectType === 'modpack') {\n\t\t\tdata.mrpack_loaders = draftVersion.loaders\n\t\t\tdata.loaders = ['mrpack']\n\t\t}\n\n\t\tformData.append('data', JSON.stringify(data))\n\n\t\tfiles.forEach((file, i) => {\n\t\t\tformData.append(fileParts[i], file, file.name)\n\t\t})\n\n\t\treturn this.client.upload<Labrinth.Versions.v3.Version>(`/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tformData,\n\t\t\ttimeout: VERSION_UPLOAD_TIMEOUT_MS,\n\t\t})\n\t}\n\n\t/**\n\t * Modify an existing version by ID (v3)\n\t *\n\t * Partially updates a version\u2019s metadata. Only JSON fields may be modified.\n\t * To update files, use the separate \"Add files to version\" endpoint.\n\t *\n\t * @param versionId - The version ID to update\n\t * @param data - PATCH metadata for this version (all fields optional)\n\t *\n\t * @returns A promise resolving to the updated version data\n\t *\n\t * @example\n\t * ```ts\n\t * const updated = await client.labrinth.versions_v3.modifyVersion('DXtmvS8i', {\n\t * name: 'v1.0.1',\n\t * changelog: 'Updated changelog',\n\t * featured: true,\n\t * status: 'listed'\n\t * })\n\t * ```\n\t */\n\n\tpublic async modifyVersion(\n\t\tversionId: string,\n\t\tdata: Labrinth.Versions.v3.ModifyVersionRequest,\n\t): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a version by ID (v3)\n\t *\n\t * @param versionId - Version ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.versions_v3.deleteVersion('DXtmvS8i')\n\t * ```\n\t */\n\tpublic async deleteVersion(versionId: string): Promise<void> {\n\t\treturn this.client.request(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\tpublic addFilesToVersion(\n\t\tversionId: string,\n\t\tversionFiles: Labrinth.Versions.v3.DraftVersionFile[],\n\t): UploadHandle<Labrinth.Versions.v3.Version> {\n\t\tconst formData = new FormData()\n\n\t\tconst files = versionFiles.map((vf) => vf.file)\n\t\tconst fileTypes = versionFiles.map((vf) => vf.fileType || null)\n\n\t\tconst fileParts = files.map((file, i) => `${file.name}-${i}`)\n\n\t\tconst fileTypeMap = fileParts.reduce<Record<string, Labrinth.Versions.v3.FileType | null>>(\n\t\t\t(acc, key, i) => {\n\t\t\t\tacc[key] = fileTypes[i]\n\t\t\t\treturn acc\n\t\t\t},\n\t\t\t{},\n\t\t)\n\n\t\tformData.append('data', JSON.stringify({ file_types: fileTypeMap }))\n\n\t\tfiles.forEach((file, i) => {\n\t\t\tformData.append(fileParts[i], file, file.name)\n\t\t})\n\n\t\treturn this.client.upload<Labrinth.Versions.v3.Version>(`/version/${versionId}/file`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tformData,\n\t\t\ttimeout: VERSION_UPLOAD_TIMEOUT_MS,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAffiliateInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_affiliate_internal'\n\t}\n\n\t/**\n\t * Get all affiliate codes for the authenticated user (or all if admin)\n\t * GET /_internal/affiliate\n\t */\n\tpublic async getAll(): Promise<Labrinth.Affiliate.Internal.AffiliateCode[]> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode[]>('/affiliate', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a new affiliate code\n\t * PUT /_internal/affiliate\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Affiliate.Internal.CreateRequest,\n\t): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>('/affiliate', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PUT',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific affiliate code by ID\n\t * GET /_internal/affiliate/{id}\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Delete an affiliate code\n\t * DELETE /_internal/affiliate/{id}\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update an affiliate code's source name\n\t * PATCH /_internal/affiliate/{id}\n\t */\n\tpublic async patch(id: string, data: Labrinth.Affiliate.Internal.PatchRequest): Promise<void> {\n\t\treturn this.client.request<void>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBlockedUsersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_blocked_users_internal'\n\t}\n\n\t/**\n\t * Check whether one user has blocked another.\n\t */\n\tpublic async getStatus(\n\t\tuserId: string,\n\t\ttargetId: string,\n\t): Promise<Labrinth.BlockedUsers.Internal.BlockStatus> {\n\t\treturn this.client.request<Labrinth.BlockedUsers.Internal.BlockStatus>(\n\t\t\t`/block/${encodeURIComponent(userId)}/${encodeURIComponent(targetId)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBlockedUsersV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_blocked_users_v3'\n\t}\n\n\t/**\n\t * List the users blocked by the authenticated user.\n\t */\n\tpublic async list(): Promise<Labrinth.BlockedUsers.v3.BlockedUserId[]> {\n\t\treturn this.client.request<Labrinth.BlockedUsers.v3.BlockedUserId[]>('/blocks', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Block a user.\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async block(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/block/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Unblock a user.\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async unblock(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/block/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthCampaignInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_campaign_internal'\n\t}\n\n\t/**\n\t * Get Pride 2026 campaign fundraising progress.\n\t * GET /_internal/campaign/pride-26\n\t */\n\tpublic async getPride26(): Promise<Labrinth.Campaign.Internal.CampaignInfo> {\n\t\treturn this.client.request<Labrinth.Campaign.Internal.CampaignInfo>('/campaign/pride-26', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTagsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_tags_v2'\n\t}\n\n\t/**\n\t * Get license text by SPDX identifier\n\t *\n\t * @param licenseId - SPDX license identifier (e.g., 'MIT', 'Apache-2.0')\n\t * @returns Promise resolving to the license title and body text\n\t *\n\t * @example\n\t * ```typescript\n\t * const license = await client.labrinth.tags_v2.getLicenseText('MIT')\n\t * console.log(license.title) // \"MIT License\"\n\t * console.log(license.body) // full license text\n\t * ```\n\t */\n\tpublic async getLicenseText(licenseId: string): Promise<Labrinth.Tags.v2.LicenseText> {\n\t\treturn this.client.request<Labrinth.Tags.v2.LicenseText>(`/tag/license/${licenseId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTeamsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_teams_v2'\n\t}\n\n\t/**\n\t * Add a member to a team\n\t *\n\t * @param teamId - Team ID\n\t * @param data - New member data including user_id\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.addMember('team123', { user_id: 'user456' })\n\t * ```\n\t */\n\tpublic async addMember(\n\t\tteamId: string,\n\t\tdata: Labrinth.Teams.v2.AddTeamMemberRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a team member\n\t *\n\t * @param teamId - Team ID\n\t * @param userId - User ID of the member to edit\n\t * @param data - Member update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.editMember('team123', 'user456', {\n\t * role: 'Developer',\n\t * permissions: 0b111,\n\t * })\n\t * ```\n\t */\n\tpublic async editMember(\n\t\tteamId: string,\n\t\tuserId: string,\n\t\tdata: Labrinth.Teams.v2.EditTeamMemberRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members/${userId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a member from a team\n\t *\n\t * @param teamId - Team ID\n\t * @param userId - User ID of the member to remove\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.removeMember('team123', 'user456')\n\t * ```\n\t */\n\tpublic async removeMember(teamId: string, userId: string): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members/${userId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Transfer team ownership to another member\n\t *\n\t * @param teamId - Team ID\n\t * @param data - Transfer data including the new owner's user_id\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.transferOwnership('team123', { user_id: 'user456' })\n\t * ```\n\t */\n\tpublic async transferOwnership(\n\t\tteamId: string,\n\t\tdata: Labrinth.Teams.v2.TransferOwnershipRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/owner`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTeamsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_teams_v3'\n\t}\n\n\t/**\n\t * Get multiple teams by their IDs\n\t *\n\t * @param ids - Array of team IDs\n\t * @returns Promise resolving to an array of team member arrays (one per team)\n\t *\n\t * @example\n\t * ```typescript\n\t * const teams = await client.labrinth.teams_v3.getMultiple(['team1', 'team2'])\n\t * // teams[0] = members of team1, teams[1] = members of team2\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.TeamMember[][]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.TeamMember[][]>(\n\t\t\t`/teams?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { LauncherMeta } from './types'\n\nexport type { LauncherMeta } from './types'\n\nconst LAUNCHER_META_BASE_URL = 'https://launcher-meta.modrinth.com'\n\nexport class LauncherMetaManifestV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'launchermeta_manifest_v0'\n\t}\n\n\t/**\n\t * Get the loader manifest for a given loader platform.\n\t *\n\t * launcher-meta refuses CORS preflights that ask for the `Content-Type`\n\t * header (returns 403), so we strip the default `Content-Type: application/json`\n\t * the abstract client sets \u2014 these are body-less GETs and don't need it.\n\t * Without this the browser preflight is rejected and the GET never fires.\n\t *\n\t * @param loader - Loader platform (fabric, forge, quilt, neo)\n\t */\n\tpublic async getManifest(\n\t\tloader: string,\n\t\tformatVersion = 0,\n\t): Promise<LauncherMeta.Manifest.v0.Manifest> {\n\t\treturn this.client.request<LauncherMeta.Manifest.v0.Manifest>('/manifest.json', {\n\t\t\tapi: LAUNCHER_META_BASE_URL,\n\t\t\tversion: `${loader}/v${formatVersion}`,\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t\theaders: { 'Content-Type': '' },\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Mclogs } from '../types'\n\nexport class MclogsInsightsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'mclogs_insights_v1'\n\t}\n\n\tpublic async analyse(content: string): Promise<Mclogs.Insights.v1.InsightsResponse> {\n\t\treturn this.client.request<Mclogs.Insights.v1.InsightsResponse>('/analyse', {\n\t\t\tapi: 'https://api.mclo.gs',\n\t\t\tversion: '1',\n\t\t\tmethod: 'POST',\n\t\t\tbody: new URLSearchParams({ content }),\n\t\t\theaders: { 'Content-Type': 'application/x-www-form-urlencoded' },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Mclogs } from '../types'\n\nexport class MclogsLogsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'mclogs_logs_v1'\n\t}\n\n\tpublic async create(content: string): Promise<Mclogs.Logs.v1.CreateResponse> {\n\t\treturn this.client.request<Mclogs.Logs.v1.CreateResponse>('/log', {\n\t\t\tapi: 'https://api.mclo.gs',\n\t\t\tversion: '1',\n\t\t\tmethod: 'POST',\n\t\t\tbody: new URLSearchParams({ content }),\n\t\t\theaders: { 'Content-Type': 'application/x-www-form-urlencoded' },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { Paper } from './types'\n\nexport type { Paper } from './types'\n\nconst PAPER_BASE_URL = 'https://fill.papermc.io'\n\nexport class PaperVersionsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'paper_versions_v3'\n\t}\n\n\t/**\n\t * Get the Paper project info including all supported Minecraft versions.\n\t */\n\tpublic async getProject(): Promise<Paper.Versions.v3.Project> {\n\t\treturn this.client.request<Paper.Versions.v3.Project>('/projects/paper', {\n\t\t\tapi: PAPER_BASE_URL,\n\t\t\tversion: 'v3',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get available Paper builds for a Minecraft version (includes channel per build).\n\t *\n\t * Fill (`fill.papermc.io`) returns a JSON array of builds at this path \u2014 not a `{ builds }`\n\t * wrapper like some other Paper API shapes \u2014 so we normalize to `VersionBuilds`.\n\t *\n\t * @param mcVersion - Minecraft version (e.g. \"1.21.4\")\n\t */\n\tpublic async getBuilds(mcVersion: string): Promise<Paper.Versions.v3.VersionBuilds> {\n\t\tconst builds = await this.client.request<Paper.Versions.v3.Build[]>(\n\t\t\t`/projects/paper/versions/${mcVersion}/builds`,\n\t\t\t{ api: PAPER_BASE_URL, version: 'v3', method: 'GET', skipAuth: true },\n\t\t)\n\t\treturn { builds }\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { Purpur } from './types'\n\nexport type { Purpur } from './types'\n\nconst PURPUR_BASE_URL = 'https://api.purpurmc.org'\n\nexport class PurpurVersionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'purpur_versions_v2'\n\t}\n\n\t/**\n\t * Get the Purpur project info including all supported Minecraft versions.\n\t */\n\tpublic async getProject(): Promise<Purpur.Versions.v2.Project> {\n\t\treturn this.client.request<Purpur.Versions.v2.Project>('/purpur', {\n\t\t\tapi: PURPUR_BASE_URL,\n\t\t\tversion: 'v2',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get available Purpur builds for a Minecraft version.\n\t *\n\t * @param mcVersion - Minecraft version (e.g. \"1.21.4\")\n\t */\n\tpublic async getBuilds(mcVersion: string): Promise<Purpur.Versions.v2.VersionBuilds> {\n\t\treturn this.client.request<Purpur.Versions.v2.VersionBuilds>(`/purpur/${mcVersion}`, {\n\t\t\tapi: PURPUR_BASE_URL,\n\t\t\tversion: 'v2',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesInstancesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_instances_v1'\n\t}\n\n\tpublic async get(instanceId: string): Promise<SharedInstances.Instances.v1.Instance> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.Instance>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getForUser(userId: string): Promise<string[]> {\n\t\treturn this.client.request<string[]>('/instances', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { user: userId },\n\t\t})\n\t}\n\n\tpublic async getUsers(instanceId: string): Promise<SharedInstances.Instances.v1.InstanceUsers> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceUsers>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/users`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getLatestVersion(\n\t\tinstanceId: string,\n\t): Promise<SharedInstances.Instances.v1.InstanceVersion> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceVersion>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/versions`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getVersion(\n\t\tinstanceId: string,\n\t\tversion: number,\n\t): Promise<SharedInstances.Instances.v1.InstanceVersion> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceVersion>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/versions/${version}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesInvitesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_invites_v1'\n\t}\n\n\tpublic async get(inviteId: string): Promise<SharedInstances.Invites.v1.Invite> {\n\t\treturn this.client.request<SharedInstances.Invites.v1.Invite>(\n\t\t\t`/invites/${encodeURIComponent(inviteId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tskipAuth: true,\n\t\t\t\tretry: false,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesModerationV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_moderation_v1'\n\t}\n\n\tpublic async blacklistUsers(\n\t\trequest: SharedInstances.Moderation.v1.BlacklistUserRequest,\n\t): Promise<void> {\n\t\treturn this.client.request('/moderation/blacklist', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\tpublic async unblacklistUsers(\n\t\trequest: SharedInstances.Moderation.v1.BlacklistUserRequest,\n\t): Promise<void> {\n\t\treturn this.client.request('/moderation/blacklist', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\tpublic async deleteFile(instanceId: string, version: number, fileName: string): Promise<void> {\n\t\treturn this.client.request(\n\t\t\t`/moderation/instances/${encodeURIComponent(instanceId)}/versions/${version}/files/${encodeURIComponent(fileName)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesUsersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_users_v1'\n\t}\n\n\tpublic async getBlacklistStatus(\n\t\tuserId: string,\n\t): Promise<SharedInstances.Users.v1.BlacklistStatus> {\n\t\treturn this.client.request<SharedInstances.Users.v1.BlacklistStatus>(\n\t\t\t`/blacklist/${encodeURIComponent(userId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import type { AbstractModrinthClient } from '../core/abstract-client'\nimport type { AbstractModule } from '../core/abstract-module'\nimport { ArchonActionsV1Module } from './archon/actions/v1'\nimport { ArchonBackupsV1Module } from './archon/backups/v1'\nimport { ArchonBackupsQueueV1Module } from './archon/backups-queue/v1'\nimport { ArchonContentV1Module } from './archon/content/v1'\nimport { ArchonNodesInternalModule } from './archon/nodes/internal'\nimport { ArchonNoticesV0Module } from './archon/notices/v0'\nimport { ArchonOptionsV1Module } from './archon/options/v1'\nimport { ArchonPropertiesV1Module } from './archon/properties/v1'\nimport { ArchonServerUsersV1Module } from './archon/server-users/v1'\nimport { ArchonServersInternalModule } from './archon/servers/internal'\nimport { ArchonServersV0Module } from './archon/servers/v0'\nimport { ArchonServersV1Module } from './archon/servers/v1'\nimport { ArchonTransfersInternalModule } from './archon/transfers/internal'\nimport { ISO3166Module } from './iso3166'\nimport { KyrosContentV1Module } from './kyros/content/v1'\nimport { KyrosFilesV0Module } from './kyros/files/v0'\nimport { KyrosLogsV1Module } from './kyros/logs/v1'\nimport { KyrosUploadSessionsV1Module } from './kyros/upload-sessions/v1'\nimport { LabrinthVersionsV2Module, LabrinthVersionsV3Module } from './labrinth'\nimport { LabrinthAffiliateInternalModule } from './labrinth/affiliate/internal'\nimport { LabrinthAnalyticsInternalModule } from './labrinth/analytics/internal'\nimport { LabrinthAnalyticsV3Module } from './labrinth/analytics/v3'\nimport { LabrinthAttributionInternalModule } from './labrinth/attribution/internal'\nimport { LabrinthAuthInternalModule } from './labrinth/auth/internal'\nimport { LabrinthAuthV2Module } from './labrinth/auth/v2'\nimport { LabrinthBillingInternalModule } from './labrinth/billing/internal'\nimport { LabrinthBlockedUsersInternalModule } from './labrinth/blocked-users/internal'\nimport { LabrinthBlockedUsersV3Module } from './labrinth/blocked-users/v3'\nimport { LabrinthCampaignInternalModule } from './labrinth/campaign/internal'\nimport { LabrinthCollectionsModule } from './labrinth/collections'\nimport { LabrinthContentV3Module } from './labrinth/content/v3'\nimport { LabrinthExternalProjectsInternalModule } from './labrinth/external-projects/internal'\nimport { LabrinthFriendsV3Module } from './labrinth/friends/v3'\nimport { LabrinthGeoIpModule } from './labrinth/geoip'\nimport { LabrinthGlobalsInternalModule } from './labrinth/globals/internal'\nimport { LabrinthImagesV3Module } from './labrinth/images/v3'\nimport { LabrinthLimitsV3Module } from './labrinth/limits/v3'\nimport { LabrinthModerationInternalModule } from './labrinth/moderation/internal'\nimport { LabrinthNotificationsV2Module } from './labrinth/notifications/v2'\nimport { LabrinthOAuthInternalModule } from './labrinth/oauth/internal'\nimport { LabrinthOrganizationsV3Module } from './labrinth/organizations/v3'\nimport { LabrinthPatsV2Module } from './labrinth/pats/v2'\nimport { LabrinthPayoutV3Module } from './labrinth/payout/v3'\nimport { LabrinthPayoutsV3Module } from './labrinth/payouts/v3'\nimport { LabrinthProjectsV2Module } from './labrinth/projects/v2'\nimport { LabrinthProjectsV3Module } from './labrinth/projects/v3'\nimport { LabrinthReportsV3Module } from './labrinth/reports/v3'\nimport { LabrinthServerPingInternalModule } from './labrinth/server-ping/internal'\nimport { LabrinthSessionsV2Module } from './labrinth/sessions/v2'\nimport { LabrinthStateModule } from './labrinth/state'\nimport { LabrinthTagsV2Module } from './labrinth/tags/v2'\nimport { LabrinthTeamsV2Module } from './labrinth/teams/v2'\nimport { LabrinthTeamsV3Module } from './labrinth/teams/v3'\nimport { LabrinthTechReviewInternalModule } from './labrinth/tech-review/internal'\nimport { LabrinthThreadsV3Module } from './labrinth/threads/v3'\nimport { LabrinthUsersV2Module } from './labrinth/users/v2'\nimport { LabrinthUsersV3Module } from './labrinth/users/v3'\nimport { LauncherMetaManifestV0Module } from './launcher-meta/v0'\nimport { MclogsInsightsV1Module } from './mclogs/insights/v1'\nimport { MclogsLogsV1Module } from './mclogs/logs/v1'\nimport { PaperVersionsV3Module } from './paper/v3'\nimport { PurpurVersionsV2Module } from './purpur/v2'\nimport { SharedInstancesInstancesV1Module } from './shared-instances/instances/v1'\nimport { SharedInstancesInvitesV1Module } from './shared-instances/invites/v1'\nimport { SharedInstancesModerationV1Module } from './shared-instances/moderation/v1'\nimport { SharedInstancesUsersV1Module } from './shared-instances/users/v1'\n\ntype ModuleConstructor = new (client: AbstractModrinthClient) => AbstractModule\n\n/**\n * To add a new module:\n * 1. Create your module class extending AbstractModule\n * 2. Add one line here: `<api>_<module>: YourModuleClass`\n *\n * TypeScript will automatically infer the client's field structure from this registry.\n *\n * TODO: Better way? Probably not\n */\nexport const MODULE_REGISTRY = {\n\tarchon_actions_v1: ArchonActionsV1Module,\n\tarchon_backups_queue_v1: ArchonBackupsQueueV1Module,\n\tarchon_backups_v1: ArchonBackupsV1Module,\n\tarchon_content_v1: ArchonContentV1Module,\n\tarchon_nodes_internal: ArchonNodesInternalModule,\n\tarchon_notices_v0: ArchonNoticesV0Module,\n\tarchon_options_v1: ArchonOptionsV1Module,\n\tarchon_properties_v1: ArchonPropertiesV1Module,\n\tarchon_server_users_v1: ArchonServerUsersV1Module,\n\tarchon_servers_internal: ArchonServersInternalModule,\n\tarchon_servers_v0: ArchonServersV0Module,\n\tarchon_servers_v1: ArchonServersV1Module,\n\tarchon_transfers_internal: ArchonTransfersInternalModule,\n\tiso3166_data: ISO3166Module,\n\tmclogs_insights_v1: MclogsInsightsV1Module,\n\tmclogs_logs_v1: MclogsLogsV1Module,\n\tlaunchermeta_manifest_v0: LauncherMetaManifestV0Module,\n\tkyros_content_v1: KyrosContentV1Module,\n\tkyros_files_v0: KyrosFilesV0Module,\n\tkyros_logs_v1: KyrosLogsV1Module,\n\tkyros_upload_sessions_v1: KyrosUploadSessionsV1Module,\n\tlabrinth_affiliate_internal: LabrinthAffiliateInternalModule,\n\tlabrinth_analytics_internal: LabrinthAnalyticsInternalModule,\n\tlabrinth_analytics_v3: LabrinthAnalyticsV3Module,\n\tlabrinth_auth_internal: LabrinthAuthInternalModule,\n\tlabrinth_auth_v2: LabrinthAuthV2Module,\n\tlabrinth_attribution_internal: LabrinthAttributionInternalModule,\n\tlabrinth_billing_internal: LabrinthBillingInternalModule,\n\tlabrinth_blocked_users_internal: LabrinthBlockedUsersInternalModule,\n\tlabrinth_blocked_users_v3: LabrinthBlockedUsersV3Module,\n\tlabrinth_campaign_internal: LabrinthCampaignInternalModule,\n\tlabrinth_collections: LabrinthCollectionsModule,\n\tlabrinth_content_v3: LabrinthContentV3Module,\n\tlabrinth_external_projects_internal: LabrinthExternalProjectsInternalModule,\n\tlabrinth_friends_v3: LabrinthFriendsV3Module,\n\tlabrinth_geoip: LabrinthGeoIpModule,\n\tlabrinth_globals_internal: LabrinthGlobalsInternalModule,\n\tlabrinth_images_v3: LabrinthImagesV3Module,\n\tlabrinth_moderation_internal: LabrinthModerationInternalModule,\n\tlabrinth_notifications_v2: LabrinthNotificationsV2Module,\n\tlabrinth_oauth_internal: LabrinthOAuthInternalModule,\n\tlabrinth_organizations_v3: LabrinthOrganizationsV3Module,\n\tlabrinth_pats_v2: LabrinthPatsV2Module,\n\tlabrinth_limits_v3: LabrinthLimitsV3Module,\n\tlabrinth_payout_v3: LabrinthPayoutV3Module,\n\tlabrinth_payouts_v3: LabrinthPayoutsV3Module,\n\tlabrinth_projects_v2: LabrinthProjectsV2Module,\n\tlabrinth_projects_v3: LabrinthProjectsV3Module,\n\tlabrinth_reports_v3: LabrinthReportsV3Module,\n\tlabrinth_server_ping_internal: LabrinthServerPingInternalModule,\n\tlabrinth_sessions_v2: LabrinthSessionsV2Module,\n\tlabrinth_state: LabrinthStateModule,\n\tlabrinth_tags_v2: LabrinthTagsV2Module,\n\tlabrinth_teams_v2: LabrinthTeamsV2Module,\n\tlabrinth_teams_v3: LabrinthTeamsV3Module,\n\tlabrinth_tech_review_internal: LabrinthTechReviewInternalModule,\n\tlabrinth_threads_v3: LabrinthThreadsV3Module,\n\tlabrinth_users_v2: LabrinthUsersV2Module,\n\tlabrinth_users_v3: LabrinthUsersV3Module,\n\tlabrinth_versions_v2: LabrinthVersionsV2Module,\n\tlabrinth_versions_v3: LabrinthVersionsV3Module,\n\tpaper_versions_v3: PaperVersionsV3Module,\n\tpurpur_versions_v2: PurpurVersionsV2Module,\n\tsharedinstances_invites_v1: SharedInstancesInvitesV1Module,\n\tsharedinstances_instances_v1: SharedInstancesInstancesV1Module,\n\tsharedinstances_moderation_v1: SharedInstancesModerationV1Module,\n\tsharedinstances_users_v1: SharedInstancesUsersV1Module,\n} as const satisfies Record<string, ModuleConstructor>\n\nexport type ModuleID = keyof typeof MODULE_REGISTRY\n\n/**\n * Parse a module ID into [api, moduleName] tuple\n *\n * @param id - Module ID in format `<api>_<module>` (e.g., 'labrinth_projects_v2')\n * @returns Tuple of [api, moduleName] (e.g., ['labrinth', 'projects_v2'])\n * @throws Error if module ID doesn't match expected format\n */\nexport function parseModuleID(id: string): [string, string] {\n\tconst parts = id.split('_')\n\tif (parts.length < 2) {\n\t\tthrow new Error(\n\t\t\t`Invalid module ID \"${id}\". Expected format: <api>_<module> (e.g., \"labrinth_projects_v2\")`,\n\t\t)\n\t}\n\tconst api = parts[0]\n\tconst moduleName = parts.slice(1).join('_')\n\treturn [api, moduleName]\n}\n\n/**\n * Build nested module structure from flat registry\n *\n * Transforms:\n * ```\n * { labrinth_projects_v2: Constructor, labrinth_users_v2: Constructor }\n * ```\n * Into:\n * ```\n * { labrinth: { projects_v2: Constructor, users_v2: Constructor } }\n * ```\n *\n * @returns Nested structure organized by API namespace\n */\nexport function buildModuleStructure(): Record<string, Record<string, ModuleConstructor>> {\n\tconst structure: Record<string, Record<string, ModuleConstructor>> = {}\n\n\tfor (const [id, constructor] of Object.entries(MODULE_REGISTRY)) {\n\t\tconst [api, moduleName] = parseModuleID(id)\n\n\t\tif (!structure[api]) {\n\t\t\tstructure[api] = {}\n\t\t}\n\n\t\tstructure[api][moduleName] = constructor\n\t}\n\n\treturn structure\n}\n\n/**\n * Extract API name from module ID\n * @example ParseAPI<'labrinth_projects_v2'> = 'labrinth'\n */\ntype ParseAPI<T extends string> = T extends `${infer API}_${string}` ? API : never\n\n/**\n * Extract module name for a given API\n * @example ParseModule<'labrinth_projects_v2', 'labrinth'> = 'projects_v2'\n */\ntype ParseModule<T extends string, API extends string> = T extends `${API}_${infer Module}`\n\t? Module\n\t: never\n\n/**\n * Group registry modules by API namespace\n *\n * Transforms flat registry into nested structure at the type level:\n * ```\n * { labrinth_projects_v2: ModuleClass } \u2192 { labrinth: { projects_v2: ModuleInstance } }\n * ```\n */\ntype GroupByAPI<Registry extends Record<string, ModuleConstructor>> = {\n\t[API in ParseAPI<keyof Registry & string>]: {\n\t\t[Module in ParseModule<keyof Registry & string, API>]: InstanceType<\n\t\t\tRegistry[`${API}_${Module}`]\n\t\t>\n\t}\n}\n\n/**\n * Inferred client module structure\n **/\nexport type InferredClientModules = GroupByAPI<typeof MODULE_REGISTRY>\n", "import type { UploadHandle, UploadRequestOptions } from '../types/upload'\n\n/**\n * Abstract base class defining upload capability\n *\n * All clients that support file uploads must extend this class.\n * Platform-specific implementations should provide the actual upload mechanism\n * (e.g., XHR for browser environments).\n *\n * Upload goes through the feature chain (auth, retry, circuit-breaker, etc.)\n * just like regular requests.\n */\nexport abstract class AbstractUploadClient {\n\t/**\n\t * Upload a file or FormData with progress tracking\n\t * @param path - API path (e.g., '/fs/create')\n\t * @param options - Upload options including file or formData, api, version\n\t * @returns UploadHandle with promise, onProgress chain, and cancel method\n\t */\n\tabstract upload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T>\n}\n", "import type { InferredClientModules } from '../modules'\nimport { buildModuleStructure } from '../modules'\nimport type { BaseUrlConfig, ClientConfig } from '../types/client'\nimport type { RequestContext, RequestOptions } from '../types/request'\nimport type { UploadMetadata, UploadProgress, UploadRequestOptions } from '../types/upload'\nimport type { AbstractFeature } from './abstract-feature'\nimport type { AbstractModule } from './abstract-module'\nimport type { AbstractSyncClient } from './abstract-sync'\nimport { AbstractUploadClient } from './abstract-upload-client'\nimport type { AbstractWebSocketClient } from './abstract-websocket'\nimport { ModrinthApiError, ModrinthServerError } from './errors'\n\ntype ArchonClientModules = Omit<InferredClientModules['archon'], 'backups_v1'> & {\n\t/** @deprecated Use `backups_queue_v1` for the Backups Queue API. */\n\tbackups_v1: InferredClientModules['archon']['backups_v1']\n}\n\n/**\n * Abstract base client for Modrinth APIs\n */\nexport abstract class AbstractModrinthClient extends AbstractUploadClient {\n\tprotected config: ClientConfig\n\tprotected features: AbstractFeature[]\n\n\t/**\n\t * Maps full module ID (e.g., 'labrinth_projects_v2') to instantiated module\n\t */\n\tprivate _moduleInstances: Map<string, AbstractModule> = new Map()\n\n\t/**\n\t * Maps API name (e.g., 'labrinth') to namespace object\n\t */\n\tprivate _moduleNamespaces: Map<string, Record<string, AbstractModule>> = new Map()\n\n\tpublic readonly labrinth!: InferredClientModules['labrinth']\n\tpublic readonly archon!: ArchonClientModules & {\n\t\tsockets: AbstractWebSocketClient\n\t\tsync: AbstractSyncClient\n\t}\n\tpublic readonly kyros!: InferredClientModules['kyros']\n\tpublic readonly iso3166!: InferredClientModules['iso3166']\n\tpublic readonly mclogs!: InferredClientModules['mclogs']\n\tpublic readonly launchermeta!: InferredClientModules['launchermeta']\n\tpublic readonly paper!: InferredClientModules['paper']\n\tpublic readonly purpur!: InferredClientModules['purpur']\n\tpublic readonly sharedinstances!: InferredClientModules['sharedinstances']\n\n\tconstructor(config: ClientConfig) {\n\t\tsuper()\n\t\tthis.config = {\n\t\t\ttimeout: 10000,\n\t\t\tlabrinthBaseUrl: 'https://api.modrinth.com',\n\t\t\tarchonBaseUrl: 'https://archon.modrinth.com',\n\t\t\tsharedInstancesBaseUrl: 'https://shared-instances.modrinth.com',\n\t\t\t...config,\n\t\t}\n\t\tthis.features = config.features ?? []\n\t\tthis.initializeModules()\n\t}\n\n\t/**\n\t * This creates the nested API structure (e.g., client.labrinth.projects_v2)\n\t * but doesn't instantiate modules until first access\n\t *\n\t * Module IDs in the registry are validated at runtime to ensure they match\n\t * what the module declares via getModuleID().\n\t */\n\tprivate initializeModules(): void {\n\t\tconst structure = buildModuleStructure()\n\n\t\tfor (const [api, modules] of Object.entries(structure)) {\n\t\t\tconst namespaceObj: Record<string, AbstractModule> = {}\n\n\t\t\t// Define lazy getters for each module\n\t\t\tfor (const [moduleName, ModuleConstructor] of Object.entries(modules)) {\n\t\t\t\tconst fullModuleId = `${api}_${moduleName}`\n\n\t\t\t\tObject.defineProperty(namespaceObj, moduleName, {\n\t\t\t\t\tget: () => {\n\t\t\t\t\t\t// Lazy instantiation\n\t\t\t\t\t\tif (!this._moduleInstances.has(fullModuleId)) {\n\t\t\t\t\t\t\tconst instance = new ModuleConstructor(this)\n\n\t\t\t\t\t\t\t// Validate the module ID matches what we expect\n\t\t\t\t\t\t\tconst declaredId = instance.getModuleID()\n\t\t\t\t\t\t\tif (declaredId !== fullModuleId) {\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Module ID mismatch: registry expects \"${fullModuleId}\" but module declares \"${declaredId}\"`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._moduleInstances.set(fullModuleId, instance)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn this._moduleInstances.get(fullModuleId)!\n\t\t\t\t\t},\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Assign namespace to client (e.g., this.labrinth = namespaceObj)\n\t\t\t// defineProperty bypasses readonly restriction\n\t\t\tObject.defineProperty(this, api, {\n\t\t\t\tvalue: namespaceObj,\n\t\t\t\twritable: false,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: false,\n\t\t\t})\n\n\t\t\tthis._moduleNamespaces.set(api, namespaceObj)\n\t\t}\n\t}\n\n\t/**\n\t * Make a request to the API\n\t *\n\t * @param path - API path (e.g., '/project/sodium')\n\t * @param options - Request options\n\t * @returns Promise resolving to the response data\n\t * @throws {ModrinthApiError} When the request fails or features throw errors\n\t */\n\tasync request<T>(path: string, options: RequestOptions): Promise<T> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\n\t\tconst defaultHeaders = await this.buildDefaultHeaders()\n\n\t\t// Merge options with defaults\n\t\tconst mergedOptions: RequestOptions = {\n\t\t\tmethod: 'GET',\n\t\t\ttimeout: this.config.timeout,\n\t\t\t...options,\n\t\t\theaders: {\n\t\t\t\t...defaultHeaders,\n\t\t\t\t...options.headers,\n\t\t\t},\n\t\t}\n\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\tconst headers = mergedOptions.headers\n\t\tif (headers && 'Content-Type' in headers && headers['Content-Type'] === '') {\n\t\t\tdelete headers['Content-Type']\n\t\t}\n\n\t\tconst context = this.buildContext(url, path, mergedOptions)\n\n\t\ttry {\n\t\t\tconst result = await this.executeFeatureChain<T>(context)\n\n\t\t\tawait this.config.hooks?.onResponse?.(result, context)\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\n\t\t\tthrow apiError\n\t\t}\n\t}\n\n\tasync stream(path: string, options: RequestOptions): Promise<ReadableStream<Uint8Array>> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\t\tconst defaultHeaders = await this.buildDefaultHeaders()\n\t\tconst mergedOptions: RequestOptions = {\n\t\t\tmethod: 'GET',\n\t\t\tretry: false,\n\t\t\tcircuitBreaker: false,\n\t\t\t...options,\n\t\t\theaders: {\n\t\t\t\t...defaultHeaders,\n\t\t\t\tAccept: 'text/event-stream',\n\t\t\t\t...options.headers,\n\t\t\t},\n\t\t}\n\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\tconst context = this.buildContext(url, path, mergedOptions)\n\n\t\ttry {\n\t\t\treturn await this.executeFeatureChain<ReadableStream<Uint8Array>>(context, () =>\n\t\t\t\tthis.executeStreamRequest(context.url, context.options),\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\n\t\t\tthrow apiError\n\t\t}\n\t}\n\n\t/**\n\t * Execute the feature chain and the actual request\n\t *\n\t * Features are executed in order, with each feature calling next() to continue.\n\t * The last \"feature\" in the chain is the actual request execution.\n\t */\n\tprotected async executeFeatureChain<T>(\n\t\tcontext: RequestContext,\n\t\texecuteTerminal: () => Promise<T> = () => this.executeRequest<T>(context.url, context.options),\n\t): Promise<T> {\n\t\t// Filter to only features that should apply\n\t\tconst applicableFeatures = this.features.filter((feature) => feature.shouldApply(context))\n\n\t\t// Build the feature chain\n\t\t// We work backwards from the actual request, wrapping each feature around the previous\n\t\tlet index = applicableFeatures.length\n\n\t\tconst next = async (): Promise<T> => {\n\t\t\tindex--\n\n\t\t\tif (index >= 0) {\n\t\t\t\t// Execute the next feature in the chain\n\t\t\t\tconst feature = applicableFeatures[index]\n\t\t\t\treturn feature.execute(next, context)\n\t\t\t} else {\n\t\t\t\t// We've reached the end of the chain, execute the actual request\n\t\t\t\tawait this.config.hooks?.onRequest?.(context)\n\t\t\t\treturn executeTerminal()\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\t/**\n\t * Execute the feature chain for an upload\n\t *\n\t * Similar to executeFeatureChain but calls executeXHRUpload at the end.\n\t * This allows features (auth, retry, etc.) to wrap the upload execution.\n\t */\n\tprotected async executeUploadFeatureChain<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T> {\n\t\tconst applicableFeatures = this.features.filter((feature) => feature.shouldApply(context))\n\n\t\tlet index = applicableFeatures.length\n\n\t\tconst next = async (): Promise<T> => {\n\t\t\tindex--\n\n\t\t\tif (index >= 0) {\n\t\t\t\treturn applicableFeatures[index].execute(next, context)\n\t\t\t} else {\n\t\t\t\tawait this.config.hooks?.onRequest?.(context)\n\t\t\t\treturn this.executeXHRUpload<T>(context, progressCallbacks, abortController)\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\t/**\n\t * Build the full URL for a request\n\t */\n\tprotected buildUrl(path: string, baseUrl: string, version: number | 'internal' | string): string {\n\t\t// Remove trailing slash from base URL\n\t\tconst base = baseUrl.replace(/\\/$/, '')\n\n\t\t// Build version path\n\t\tlet versionPath = ''\n\t\tif (version === 'internal') {\n\t\t\tversionPath = '/_internal'\n\t\t} else if (typeof version === 'number') {\n\t\t\tversionPath = `/v${version}`\n\t\t} else if (typeof version === 'string') {\n\t\t\t// Custom version string (e.g., 'v0', 'modrinth/v0')\n\t\t\tversionPath = `/${version}`\n\t\t}\n\n\t\tconst cleanPath = path.startsWith('/') ? path : `/${path}`\n\n\t\treturn `${base}${versionPath}${cleanPath}`\n\t}\n\n\tprotected resolveBaseUrl(baseUrl: BaseUrlConfig): string {\n\t\treturn typeof baseUrl === 'function' ? baseUrl() : baseUrl\n\t}\n\n\t/**\n\t * Build the request context\n\t */\n\tprotected buildContext(url: string, path: string, options: RequestOptions): RequestContext {\n\t\treturn {\n\t\t\turl,\n\t\t\tpath,\n\t\t\toptions,\n\t\t\tattempt: 1,\n\t\t\tstartTime: Date.now(),\n\t\t}\n\t}\n\n\t/**\n\t * Build context for an upload request\n\t *\n\t * Sets metadata.isUpload = true so features can detect uploads.\n\t * Supports both single file uploads and FormData uploads.\n\t */\n\tprotected buildUploadContext(\n\t\turl: string,\n\t\tpath: string,\n\t\toptions: UploadRequestOptions,\n\t): RequestContext {\n\t\tlet metadata: UploadMetadata\n\t\tlet body: File | Blob | FormData\n\n\t\tif ('formData' in options && options.formData) {\n\t\t\tmetadata = {\n\t\t\t\tisUpload: true,\n\t\t\t\tformData: options.formData,\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t}\n\t\t\tbody = options.formData\n\t\t} else if ('file' in options && options.file) {\n\t\t\tmetadata = {\n\t\t\t\tisUpload: true,\n\t\t\t\tfile: options.file,\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t}\n\t\t\tbody = options.file\n\t\t} else {\n\t\t\tthrow new Error('Upload options must include either file or formData')\n\t\t}\n\n\t\treturn {\n\t\t\turl,\n\t\t\tpath,\n\t\t\toptions: {\n\t\t\t\t...options,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody,\n\t\t\t},\n\t\t\tattempt: 1,\n\t\t\tstartTime: Date.now(),\n\t\t\tmetadata,\n\t\t}\n\t}\n\n\t/**\n\t * Build default headers for all requests\n\t *\n\t * Subclasses can override this to add platform-specific headers\n\t * (e.g., Nuxt rate limit key)\n\t */\n\tprotected async buildDefaultHeaders(): Promise<Record<string, string>> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t...this.config.headers,\n\t\t}\n\n\t\tconst userAgent = await this.resolveUserAgent()\n\t\tif (userAgent) {\n\t\t\theaders['User-Agent'] = userAgent\n\t\t}\n\n\t\treturn headers\n\t}\n\n\tprivate async resolveUserAgent(): Promise<string | undefined> {\n\t\tconst userAgent = this.config.userAgent\n\t\treturn typeof userAgent === 'function' ? await userAgent() : userAgent\n\t}\n\n\tprotected attachArchonSentryCaptureHeader(options: RequestOptions): void {\n\t\tif (options.api !== 'archon' || !options.headers || !this.shouldCaptureArchonRequests()) {\n\t\t\treturn\n\t\t}\n\n\t\toptions.headers['modrinth-sentry-capture'] = '1'\n\t}\n\n\tprivate shouldCaptureArchonRequests(): boolean {\n\t\tconst archonSentryCapture = this.config.archonSentryCapture\n\t\treturn typeof archonSentryCapture === 'function'\n\t\t\t? archonSentryCapture()\n\t\t\t: archonSentryCapture === true\n\t}\n\n\t/**\n\t * Execute the actual HTTP request\n\t *\n\t * This must be implemented by platform-specific clients.\n\t *\n\t * @param url - Full URL to request\n\t * @param options - Request options\n\t * @returns Promise resolving to the response data\n\t * @throws {Error} Platform-specific errors that will be normalized by normalizeError()\n\t */\n\tprotected abstract executeRequest<T>(url: string, options: RequestOptions): Promise<T>\n\n\tprotected abstract executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>>\n\n\t/**\n\t * Execute the actual XHR upload\n\t *\n\t * This must be implemented by platform clients that support uploads.\n\t * Called at the end of the upload feature chain.\n\t *\n\t * @param context - Request context with upload metadata\n\t * @param progressCallbacks - Callbacks to invoke on progress events\n\t * @param abortController - Controller for cancellation\n\t * @returns Promise resolving to the response data\n\t */\n\tprotected abstract executeXHRUpload<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T>\n\n\t/**\n\t * Normalize an error into a ModrinthApiError\n\t *\n\t * Platform implementations should override this to handle platform-specific errors\n\t * (e.g., FetchError from ofetch, Tauri HTTP errors)\n\t */\n\tprotected normalizeError(error: unknown, context?: RequestContext): ModrinthApiError {\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn error\n\t\t}\n\n\t\treturn ModrinthApiError.fromUnknown(error, context?.path)\n\t}\n\n\t/**\n\t * Helper to create a normalized error from extracted status code and response data\n\t */\n\tprotected createNormalizedError(\n\t\terror: Error,\n\t\tstatusCode: number | undefined,\n\t\tresponseData: unknown,\n\t): ModrinthApiError {\n\t\tif (statusCode && responseData) {\n\t\t\treturn ModrinthServerError.fromResponse(statusCode, responseData)\n\t\t}\n\n\t\treturn new ModrinthApiError(error.message, {\n\t\t\tstatusCode,\n\t\t\toriginalError: error,\n\t\t\tresponseData,\n\t\t})\n\t}\n\n\t/**\n\t * Add a feature to this client\n\t *\n\t * Features are executed in the order they are added.\n\t *\n\t * @example\n\t * ```typescript\n\t * const client = new GenericModrinthClient()\n\t * client.addFeature(new AuthFeature({ token: async () => getOAuthToken() }))\n\t * client.addFeature(new RetryFeature({ maxAttempts: 3 }))\n\t * ```\n\t */\n\taddFeature(feature: AbstractFeature): this {\n\t\tthis.features.push(feature)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a feature from this client\n\t *\n\t * @example\n\t * ```typescript\n\t * const retryFeature = new RetryFeature({ maxAttempts: 3 })\n\t * client.addFeature(retryFeature)\n\t * // Later, remove it\n\t * client.removeFeature(retryFeature)\n\t * ```\n\t */\n\tremoveFeature(feature: AbstractFeature): this {\n\t\tconst index = this.features.indexOf(feature)\n\t\tif (index !== -1) {\n\t\t\tthis.features.splice(index, 1)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get all features on this client\n\t */\n\tgetFeatures(): AbstractFeature[] {\n\t\treturn [...this.features]\n\t}\n}\n", "import type { RequestContext } from '../types/request'\n\n/**\n * Base configuration for features\n */\nexport interface FeatureConfig {\n\t/**\n\t * Optional name for this feature (for debugging)\n\t */\n\tname?: string\n\n\t/**\n\t * Whether this feature is enabled\n\t * @default true\n\t */\n\tenabled?: boolean\n}\n\n/**\n * Abstract base class for request features\n *\n * Features are composable middleware that can intercept and modify requests.\n * They are executed in a chain, with each feature calling next() to continue the chain.\n */\nexport abstract class AbstractFeature {\n\tprotected config: FeatureConfig\n\n\tconstructor(config?: FeatureConfig) {\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\t...config,\n\t\t}\n\t}\n\n\t/**\n\t * Execute the feature logic\n\t *\n\t * @param next - Function to call the next feature in the chain (or the actual request)\n\t * @param context - Full request context\n\t * @returns Promise resolving to the response data\n\t *\n\t * @example\n\t * ```typescript\n\t * async execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t * // Do something before request\n\t * console.log('Before request:', context.url)\n\t *\n\t * try {\n\t * const result = await next()\n\t *\n\t * // Do something after successful request\n\t * console.log('Request succeeded')\n\t *\n\t * return result\n\t * } catch (error) {\n\t * // Handle errors\n\t * console.error('Request failed:', error)\n\t * throw error\n\t * }\n\t * }\n\t * ```\n\t */\n\tabstract execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T>\n\n\t/**\n\t * Determine if this feature should apply to the given request\n\t *\n\t * By default, features apply if they are enabled.\n\t * Override this to add custom logic (e.g., only apply to GET requests).\n\t *\n\t * @param context - Request context\n\t * @returns true if the feature should execute, false to skip\n\t */\n\tshouldApply(_context: RequestContext): boolean {\n\t\treturn this.config.enabled !== false\n\t}\n\n\t/**\n\t * Get the name of this feature (for debugging)\n\t */\n\tget name(): string {\n\t\treturn this.config.name ?? this.constructor.name\n\t}\n\n\t/**\n\t * Check if this feature is enabled\n\t */\n\tget enabled(): boolean {\n\t\treturn this.config.enabled !== false\n\t}\n}\n", "import type mitt from 'mitt'\n\nimport type { Archon } from '../modules/archon/types'\nimport type { RequestOptions } from '../types/request'\n\nexport type SyncEventType = Archon.Sync.v1.SyncEvent['type']\n\nexport type SyncEventOfType<E extends SyncEventType> = Extract<\n\tArchon.Sync.v1.SyncEvent,\n\t{ type: E }\n>\n\nexport type SyncEventHandler<E extends Archon.Sync.v1.SyncEvent = Archon.Sync.v1.SyncEvent> = (\n\tevent: E,\n) => void\n\nexport type SyncStatusState =\n\t| 'idle'\n\t| 'connecting'\n\t| 'connected'\n\t| 'reconnecting'\n\t| 'disconnected'\n\t| 'error'\n\nexport type SyncStatus = {\n\tstate: SyncStatusState\n\tconnected: boolean\n\treconnecting: boolean\n\treconnectAttempts: number\n\tretryDelay: number\n\tlastEventId?: string\n\terror?: unknown\n}\n\nexport type SyncStatusHandler = (status: SyncStatus) => void\n\nexport type SyncConnectOptions = {\n\tintent?: Archon.Sync.v1.SyncIntent\n\tforce?: boolean\n}\n\nexport type SyncConnection = {\n\tserverId: string\n\tintent: Archon.Sync.v1.SyncIntent\n\tcontroller?: AbortController\n\treconnectAttempts: number\n\treconnectTimer?: ReturnType<typeof setTimeout>\n\treconnectResolve?: () => void\n\tretryDelay: number\n\tlastEventId?: string\n\tstopped: boolean\n\tstatus: SyncStatusState\n\terror?: unknown\n}\n\nexport type SyncEmitterEvents = Record<string, unknown>\n\nexport abstract class AbstractSyncClient {\n\tprotected connections = new Map<string, SyncConnection>()\n\tprotected abstract emitter: ReturnType<typeof mitt<SyncEmitterEvents>>\n\n\tconstructor(\n\t\tprotected client: {\n\t\t\tstream: (path: string, options: RequestOptions) => Promise<ReadableStream<Uint8Array>>\n\t\t},\n\t) {}\n\n\tabstract safeConnectServer(serverId: string, options?: SyncConnectOptions): Promise<void>\n\n\tabstract disconnect(serverId: string): void\n\n\tabstract disconnectAll(): void\n\n\ton<E extends SyncEventType>(\n\t\tserverId: string,\n\t\teventType: E,\n\t\thandler: SyncEventHandler<SyncEventOfType<E>>,\n\t): () => void {\n\t\tconst eventKey = this.getEventKey(serverId, eventType)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tonAny(serverId: string, handler: SyncEventHandler): () => void {\n\t\tconst eventKey = this.getAnyEventKey(serverId)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tonStatus(serverId: string, handler: SyncStatusHandler): () => void {\n\t\tconst eventKey = this.getStatusEventKey(serverId)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tgetStatus(serverId: string): SyncStatus | null {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return null\n\n\t\treturn this.connectionToStatus(connection)\n\t}\n\n\tprotected emitSyncEvent(serverId: string, event: Archon.Sync.v1.SyncEvent): void {\n\t\tthis.emitter.emit(this.getEventKey(serverId, event.type), event)\n\t\tthis.emitter.emit(this.getAnyEventKey(serverId), event)\n\t}\n\n\tprotected updateStatus(\n\t\tconnection: SyncConnection,\n\t\tstatus: SyncStatusState,\n\t\terror?: unknown,\n\t): void {\n\t\tconnection.status = status\n\t\tconnection.error = error\n\t\tthis.emitter.emit(\n\t\t\tthis.getStatusEventKey(connection.serverId),\n\t\t\tthis.connectionToStatus(connection),\n\t\t)\n\t}\n\n\tprotected clearListeners(serverId: string): void {\n\t\tthis.emitter.all.forEach((_handlers, type) => {\n\t\t\tif (type.toString().startsWith(`${serverId}:`)) {\n\t\t\t\tthis.emitter.all.delete(type)\n\t\t\t}\n\t\t})\n\t}\n\n\tprotected connectionToStatus(connection: SyncConnection): SyncStatus {\n\t\treturn {\n\t\t\tstate: connection.status,\n\t\t\tconnected: connection.status === 'connected',\n\t\t\treconnecting: connection.status === 'reconnecting',\n\t\t\treconnectAttempts: connection.reconnectAttempts,\n\t\t\tretryDelay: connection.retryDelay,\n\t\t\tlastEventId: connection.lastEventId,\n\t\t\terror: connection.error,\n\t\t}\n\t}\n\n\tprivate getEventKey(serverId: string, eventType: string): string {\n\t\treturn `${serverId}:${eventType}`\n\t}\n\n\tprivate getAnyEventKey(serverId: string): string {\n\t\treturn `${serverId}:*`\n\t}\n\n\tprivate getStatusEventKey(serverId: string): string {\n\t\treturn `${serverId}:__status`\n\t}\n}\n", "import type mitt from 'mitt'\n\nimport type { Archon } from '../modules/archon/types'\n\nexport type WebSocketEventHandler<\n\tE extends Archon.Websocket.v0.WSEvent = Archon.Websocket.v0.WSEvent,\n> = (event: E) => void\n\nexport interface WebSocketConnection {\n\tserverId: string\n\tsocket: WebSocket\n\tauthenticated: boolean\n\treconnectAttempts: number\n\treconnectTimer?: ReturnType<typeof setTimeout>\n\tisReconnecting: boolean\n}\n\nexport interface WebSocketStatus {\n\tconnected: boolean\n\treconnecting: boolean\n\treconnectAttempts: number\n}\n\ntype WSEventMap = {\n\t[K in Archon.Websocket.v0.WSEvent as `${string}:${K['event']}`]: K\n}\n\nexport abstract class AbstractWebSocketClient {\n\tprotected connections = new Map<string, WebSocketConnection>()\n\tprotected abstract emitter: ReturnType<typeof mitt<WSEventMap>>\n\n\tprotected readonly MAX_RECONNECT_ATTEMPTS = 10\n\tprotected readonly RECONNECT_BASE_DELAY = 1000\n\tprotected readonly RECONNECT_MAX_DELAY = 30000\n\tprotected readonly AUTHENTICATION_TIMEOUT = 30000\n\n\tconstructor(\n\t\tprotected client: {\n\t\t\tarchon: {\n\t\t\t\tservers_v0: {\n\t\t\t\t\tgetWebSocketAuth: (serverId: string) => Promise<Archon.Websocket.v0.WSAuth>\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t) {}\n\n\tabstract connect(serverId: string, auth: Archon.Websocket.v0.WSAuth): Promise<void>\n\n\tabstract disconnect(serverId: string): void\n\n\tabstract disconnectAll(): void\n\n\tabstract send(serverId: string, message: Archon.Websocket.v0.WSOutgoingMessage): void\n\n\tasync safeConnect(serverId: string, options?: { force?: boolean }): Promise<void> {\n\t\tconst status = this.getStatus(serverId)\n\n\t\tif (status?.connected && !options?.force) {\n\t\t\treturn\n\t\t}\n\n\t\tif (status && !status.connected && !options?.force) {\n\t\t\tawait this.waitForAuthentication(serverId)\n\t\t\treturn\n\t\t}\n\n\t\tif (options?.force && status) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\n\t\tconst auth = await this.client.archon.servers_v0.getWebSocketAuth(serverId)\n\t\tawait this.connect(serverId, auth)\n\t}\n\n\tprotected async waitForAuthentication(serverId: string): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tlet unsubscribe = () => {}\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tunsubscribe()\n\t\t\t\treject(new Error(`WebSocket authentication timed out for server ${serverId}`))\n\t\t\t}, this.AUTHENTICATION_TIMEOUT)\n\n\t\t\tunsubscribe = this.on(serverId, 'auth-ok', () => {\n\t\t\t\tclearTimeout(timeout)\n\t\t\t\tunsubscribe()\n\t\t\t\tresolve()\n\t\t\t})\n\n\t\t\tif (this.getStatus(serverId)?.connected) {\n\t\t\t\tclearTimeout(timeout)\n\t\t\t\tunsubscribe()\n\t\t\t\tresolve()\n\t\t\t}\n\t\t})\n\t}\n\n\ton<E extends Archon.Websocket.v0.WSEventType>(\n\t\tserverId: string,\n\t\teventType: E,\n\t\thandler: WebSocketEventHandler<Extract<Archon.Websocket.v0.WSEvent, { event: E }>>,\n\t): () => void {\n\t\tconst eventKey = `${serverId}:${eventType}` as keyof WSEventMap\n\n\t\tthis.emitter.on(eventKey, handler as () => void)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, handler as () => void)\n\t\t}\n\t}\n\n\tgetStatus(serverId: string): WebSocketStatus | null {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return null\n\n\t\treturn {\n\t\t\tconnected: connection.socket.readyState === WebSocket.OPEN && connection.authenticated,\n\t\t\treconnecting: connection.isReconnecting,\n\t\t\treconnectAttempts: connection.reconnectAttempts,\n\t\t}\n\t}\n\n\tprotected getReconnectDelay(attempt: number): number {\n\t\tconst delay = Math.min(\n\t\t\tthis.RECONNECT_BASE_DELAY * Math.pow(2, attempt),\n\t\t\tthis.RECONNECT_MAX_DELAY,\n\t\t)\n\t\treturn delay + Math.random() * 1000\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Authentication feature configuration\n */\nexport interface AuthConfig extends FeatureConfig {\n\t/**\n\t * Authentication token\n\t * - string: static token\n\t * - function: async function that returns token (useful for dynamic tokens)\n\t */\n\ttoken: string | (() => Promise<string | undefined>)\n\n\t/**\n\t * Token prefix (e.g., 'Bearer', 'Token')\n\t * @default 'Bearer'\n\t */\n\ttokenPrefix?: string\n\n\t/**\n\t * Custom header name for the token\n\t * @default 'Authorization'\n\t */\n\theaderName?: string\n}\n\n/**\n * Authentication feature\n *\n * Automatically injects authentication tokens into request headers.\n * Supports both static tokens and dynamic token providers.\n *\n * @example\n * ```typescript\n * const auth = new AuthFeature({\n * token: async () => process.env.MODRINTH_TOKEN\n * })\n * ```\n */\nexport class AuthFeature extends AbstractFeature {\n\tdeclare protected config: AuthConfig\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst token = await this.getToken()\n\n\t\tif (token) {\n\t\t\tconst headerName = this.config.headerName ?? 'Authorization'\n\t\t\tconst tokenPrefix = this.config.tokenPrefix ?? 'Bearer'\n\t\t\tconst headerValue = tokenPrefix ? `${tokenPrefix} ${token}` : token\n\n\t\t\tcontext.options.headers = {\n\t\t\t\t...context.options.headers,\n\t\t\t\t[headerName]: headerValue,\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.skipAuth) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Skip if Authorization header is already explicitly set\n\t\tconst headerName = this.config.headerName ?? 'Authorization'\n\t\tif (context.options.headers?.[headerName]) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Get the authentication token\n\t *\n\t * Handles both static tokens and async token providers\n\t */\n\tprivate async getToken(): Promise<string | undefined> {\n\t\tconst { token } = this.config\n\n\t\tif (typeof token === 'function') {\n\t\t\treturn await token()\n\t\t}\n\n\t\treturn token\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Circuit breaker state\n */\nexport type CircuitBreakerState = {\n\t/**\n\t * Number of consecutive failures\n\t */\n\tfailures: number\n\n\t/**\n\t * Timestamp of last failure\n\t */\n\tlastFailure: number\n}\n\n/**\n * Circuit breaker storage interface\n */\nexport interface CircuitBreakerStorage {\n\t/**\n\t * Get circuit breaker state for a key\n\t */\n\tget(key: string): CircuitBreakerState | undefined\n\n\t/**\n\t * Set circuit breaker state for a key\n\t */\n\tset(key: string, state: CircuitBreakerState): void\n\n\t/**\n\t * Clear circuit breaker state for a key\n\t */\n\tclear?(key: string): void\n}\n\n/**\n * Circuit breaker feature configuration\n */\nexport interface CircuitBreakerConfig extends FeatureConfig {\n\t/**\n\t * Maximum number of consecutive failures before opening circuit\n\t * @default 3\n\t */\n\tmaxFailures?: number\n\n\t/**\n\t * Time in milliseconds before circuit resets after opening\n\t * @default 30000\n\t */\n\tresetTimeout?: number\n\n\t/**\n\t * HTTP status codes that count as failures\n\t * @default [500, 502, 503, 504]\n\t */\n\tfailureStatusCodes?: number[]\n\n\t/**\n\t * Storage implementation for circuit state\n\t * If not provided, uses in-memory Map\n\t */\n\tstorage?: CircuitBreakerStorage\n\n\t/**\n\t * Function to generate circuit key from request context\n\t * By default, uses the base path (without query params)\n\t */\n\tgetCircuitKey?: (url: string, method: string) => string\n}\n\n/**\n * In-memory storage for circuit breaker state\n */\nexport class InMemoryCircuitBreakerStorage implements CircuitBreakerStorage {\n\tprivate state = new Map<string, CircuitBreakerState>()\n\n\tget(key: string): CircuitBreakerState | undefined {\n\t\treturn this.state.get(key)\n\t}\n\n\tset(key: string, state: CircuitBreakerState): void {\n\t\tthis.state.set(key, state)\n\t}\n\n\tclear(key: string): void {\n\t\tthis.state.delete(key)\n\t}\n}\n\n/**\n * Circuit breaker feature\n *\n * Prevents requests to failing endpoints by \"opening the circuit\" after\n * a threshold of consecutive failures. The circuit automatically resets\n * after a timeout period.\n *\n * This implements the circuit breaker pattern to prevent cascading failures\n * and give failing services time to recover.\n *\n * @example\n * ```typescript\n * const circuitBreaker = new CircuitBreakerFeature({\n * maxFailures: 3,\n * resetTimeout: 30000, // 30 seconds\n * failureStatusCodes: [500, 502, 503, 504]\n * })\n * ```\n */\nexport class CircuitBreakerFeature extends AbstractFeature {\n\tdeclare protected config: Required<CircuitBreakerConfig>\n\tprivate storage: CircuitBreakerStorage\n\n\tconstructor(config?: CircuitBreakerConfig) {\n\t\tsuper(config)\n\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\tname: 'circuit-breaker',\n\t\t\tmaxFailures: 3,\n\t\t\tresetTimeout: 30000,\n\t\t\tfailureStatusCodes: [500, 502, 503, 504],\n\t\t\t...config,\n\t\t} as Required<CircuitBreakerConfig>\n\n\t\t// Use provided storage or default to in-memory\n\t\tthis.storage = config?.storage ?? new InMemoryCircuitBreakerStorage()\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst circuitKey = this.getCircuitKey(context)\n\n\t\tif (this.isCircuitOpen(circuitKey)) {\n\t\t\tthrow new ModrinthApiError('Circuit breaker open - too many recent failures', {\n\t\t\t\tstatusCode: 503,\n\t\t\t\tcontext: context.path,\n\t\t\t})\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await next()\n\n\t\t\tthis.recordSuccess(circuitKey)\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tif (this.isFailureError(error)) {\n\t\t\t\tthis.recordFailure(circuitKey)\n\t\t\t}\n\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.circuitBreaker === false) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Get the circuit key for a request\n\t *\n\t * By default, uses the path and method to identify unique circuits\n\t */\n\tprivate getCircuitKey(context: RequestContext): string {\n\t\tif (this.config.getCircuitKey) {\n\t\t\treturn this.config.getCircuitKey(context.url, context.options.method ?? 'GET')\n\t\t}\n\n\t\t// Default: use method + path (without query params)\n\t\tconst method = context.options.method ?? 'GET'\n\t\tconst pathWithoutQuery = context.path.split('?')[0]\n\n\t\treturn `${method}_${pathWithoutQuery}`\n\t}\n\n\t/**\n\t * Check if the circuit is open for a given key\n\t */\n\tprivate isCircuitOpen(key: string): boolean {\n\t\tconst state = this.storage.get(key)\n\n\t\tif (!state) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst timeSinceLastFailure = now - state.lastFailure\n\n\t\tif (timeSinceLastFailure > this.config.resetTimeout) {\n\t\t\tthis.storage.clear?.(key)\n\t\t\treturn false\n\t\t}\n\n\t\treturn state.failures >= this.config.maxFailures\n\t}\n\n\t/**\n\t * Record a successful request\n\t */\n\tprivate recordSuccess(key: string): void {\n\t\tthis.storage.clear?.(key)\n\t}\n\n\t/**\n\t * Record a failed request\n\t */\n\tprivate recordFailure(key: string): void {\n\t\tconst now = Date.now()\n\t\tconst state = this.storage.get(key)\n\n\t\tif (!state) {\n\t\t\t// First failure\n\t\t\tthis.storage.set(key, {\n\t\t\t\tfailures: 1,\n\t\t\t\tlastFailure: now,\n\t\t\t})\n\t\t} else {\n\t\t\t// Subsequent failure\n\t\t\tthis.storage.set(key, {\n\t\t\t\tfailures: state.failures + 1,\n\t\t\t\tlastFailure: now,\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Determine if an error should count as a circuit failure\n\t */\n\tprivate isFailureError(error: unknown): boolean {\n\t\tif (error instanceof ModrinthApiError && error.statusCode) {\n\t\t\treturn this.config.failureStatusCodes.includes(error.statusCode)\n\t\t}\n\n\t\treturn false\n\t}\n\n\t/**\n\t * Get current circuit state for debugging\n\t *\n\t * @example\n\t * ```typescript\n\t * const state = circuitBreaker.getCircuitState('GET_/v2/project/sodium')\n\t * console.log(`Failures: ${state?.failures}, Last failure: ${state?.lastFailure}`)\n\t * ```\n\t */\n\tgetCircuitState(key: string): CircuitBreakerState | undefined {\n\t\treturn this.storage.get(key)\n\t}\n\n\t/**\n\t * Manually reset a circuit\n\t *\n\t * @example\n\t * ```typescript\n\t * // Reset circuit after manual intervention\n\t * circuitBreaker.resetCircuit('GET_/v2/project/sodium')\n\t * ```\n\t */\n\tresetCircuit(key: string): void {\n\t\tthis.storage.clear?.(key)\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\nimport { getNodeBaseUrl } from '../utils/node-url'\n\n/**\n * Node authentication credentials\n */\nexport interface NodeAuth {\n\t/** Node instance URL (e.g., \"node-xyz.modrinth.com/modrinth/v0/fs\") */\n\turl: string\n\t/** Base URL without path suffix (e.g., \"node-xyz.modrinth.com\") \u2014 used when available */\n\tbaseUrl?: string\n\t/** JWT token */\n\ttoken: string\n}\n\nexport interface NodeAuthConfig extends FeatureConfig {\n\t/**\n\t * Get current node auth. Returns null if not authenticated.\n\t */\n\tgetAuth: () => NodeAuth | null\n\n\t/**\n\t * Refresh the node authentication token.\n\t */\n\trefreshAuth: () => Promise<void>\n}\n\n/**\n * Handles authentication for Kyros node fs requests:\n * - Automatically injects Authorization header\n * - Builds the correct URL from node instance\n * - Handles 401 errors by refreshing and retrying (max 3 times)\n *\n * Only applies to requests with `useNodeAuth: true` in options.\n *\n * @example\n * ```typescript\n * const nodeAuth = new NodeAuthFeature({\n * getAuth: () => nodeAuthState.getAuth?.() ?? null,\n * refreshAuth: async () => {\n * if (nodeAuthState.refreshAuth) {\n * await nodeAuthState.refreshAuth()\n * }\n * },\n * })\n * client.addFeature(nodeAuth)\n * ```\n */\nexport class NodeAuthFeature extends AbstractFeature {\n\tdeclare protected config: NodeAuthConfig\n\tprivate refreshPromise: Promise<void> | null = null\n\n\tshouldApply(context: RequestContext): boolean {\n\t\treturn context.options.useNodeAuth === true && this.config.enabled !== false\n\t}\n\n\tprivate async refreshAuthWithLock(): Promise<void> {\n\t\tif (this.refreshPromise) {\n\t\t\treturn this.refreshPromise\n\t\t}\n\t\tthis.refreshPromise = this.config.refreshAuth().finally(() => {\n\t\t\tthis.refreshPromise = null\n\t\t})\n\t\treturn this.refreshPromise\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst maxRetries = 3\n\t\tlet retryCount = 0\n\n\t\tlet auth = this.config.getAuth()\n\t\tif (!auth || this.isTokenExpired(auth.token)) {\n\t\t\tawait this.refreshAuthWithLock()\n\t\t\tauth = this.config.getAuth()\n\t\t}\n\t\tif (!auth) {\n\t\t\tthrow new Error('Failed to obtain node authentication')\n\t\t}\n\n\t\tthis.applyAuth(context, auth)\n\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\treturn await next()\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof ModrinthApiError && error.statusCode === 401) {\n\t\t\t\t\tretryCount++\n\t\t\t\t\tif (retryCount >= maxRetries) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Node authentication failed after ${maxRetries} retries. Please re-authenticate.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this.refreshAuthWithLock()\n\t\t\t\t\tauth = this.config.getAuth()\n\t\t\t\t\tif (!auth) {\n\t\t\t\t\t\tthrow new Error('Failed to refresh node authentication')\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.applyAuth(context, auth)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate applyAuth(context: RequestContext, auth: NodeAuth): void {\n\t\tconst baseUrl = getNodeBaseUrl(auth.url)\n\t\tcontext.url = this.buildUrl(context.path, baseUrl, context.options.version)\n\n\t\tcontext.options.headers = {\n\t\t\t...context.options.headers,\n\t\t\tAuthorization: `Bearer ${auth.token}`,\n\t\t}\n\n\t\tcontext.options.skipAuth = true\n\t}\n\n\tprivate buildUrl(path: string, baseUrl: string, version: number | 'internal' | string): string {\n\t\tconst base = baseUrl.replace(/\\/$/, '')\n\t\tlet versionPath = ''\n\t\tif (version === 'internal') {\n\t\t\tversionPath = '/_internal'\n\t\t} else if (typeof version === 'number') {\n\t\t\tversionPath = `/v${version}`\n\t\t} else if (typeof version === 'string') {\n\t\t\tversionPath = `/${version}`\n\t\t}\n\t\tconst cleanPath = path.startsWith('/') ? path : `/${path}`\n\t\treturn `${base}${versionPath}${cleanPath}`\n\t}\n\n\t/**\n\t * Check if a JWT token is expired or about to expire\n\t * Refreshes proactively if expiring within next 10 seconds\n\t */\n\tprivate isTokenExpired(token: string): boolean {\n\t\ttry {\n\t\t\tconst payload = JSON.parse(atob(token.split('.')[1]))\n\t\t\tif (!payload.exp) return false\n\t\t\t// refresh if expiring within 10 seconds\n\t\t\tconst expiresAt = payload.exp * 1000\n\t\t\treturn Date.now() >= expiresAt - 10000\n\t\t} catch {\n\t\t\t// cant decode, assume valid and let server decide\n\t\t\treturn false\n\t\t}\n\t}\n}\n", "import { AbstractFeature } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\nexport const PANEL_VERSION = 1\n\nexport class PanelVersionFeature extends AbstractFeature {\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tcontext.options.headers = {\n\t\t\t...context.options.headers,\n\t\t\t'X-Panel-Version': String(PANEL_VERSION),\n\t\t}\n\t\treturn next()\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\treturn context.options.api === 'labrinth' || context.options.api === 'archon'\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Backoff strategy for retries\n */\nexport type BackoffStrategy = 'exponential' | 'linear' | 'constant'\n\n/**\n * Retry feature configuration\n */\nexport interface RetryConfig extends FeatureConfig {\n\t/**\n\t * Maximum number of retry attempts\n\t * @default 3\n\t */\n\tmaxAttempts?: number\n\n\t/**\n\t * Backoff strategy to use\n\t * @default 'exponential'\n\t */\n\tbackoffStrategy?: BackoffStrategy\n\n\t/**\n\t * Initial delay in milliseconds before first retry\n\t * @default 1000\n\t */\n\tinitialDelay?: number\n\n\t/**\n\t * Maximum delay in milliseconds between retries\n\t * @default 15000\n\t */\n\tmaxDelay?: number\n\n\t/**\n\t * HTTP status codes that should trigger a retry\n\t * @default [408, 429, 500, 502, 503, 504]\n\t */\n\tretryableStatusCodes?: number[]\n\n\t/**\n\t * Whether to retry on network errors (connection refused, timeout, etc.)\n\t * @default true\n\t */\n\tretryOnNetworkError?: boolean\n\n\t/**\n\t * Custom function to determine if an error should be retried\n\t */\n\tshouldRetry?: (error: unknown, attempt: number) => boolean\n}\n\n/**\n * Retry feature\n *\n * Automatically retries failed requests with configurable backoff strategy.\n * Only retries errors that are likely to succeed on retry (e.g., timeout, 5xx errors).\n *\n * @example\n * ```typescript\n * const retry = new RetryFeature({\n * maxAttempts: 3,\n * backoffStrategy: 'exponential',\n * initialDelay: 1000,\n * maxDelay: 15000\n * })\n * ```\n */\nexport class RetryFeature extends AbstractFeature {\n\tdeclare protected config: Required<RetryConfig>\n\n\tconstructor(config?: RetryConfig) {\n\t\tsuper(config)\n\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\tname: 'retry',\n\t\t\tmaxAttempts: 3,\n\t\t\tbackoffStrategy: 'exponential',\n\t\t\tinitialDelay: 1000,\n\t\t\tmaxDelay: 15000,\n\t\t\tretryableStatusCodes: [408, 429, 500, 502, 503, 504],\n\t\t\tretryOnNetworkError: true,\n\t\t\t...config,\n\t\t} as Required<RetryConfig>\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tlet lastError: Error | null = null\n\t\tconst maxAttempts = this.getMaxAttempts(context)\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\tcontext.attempt = attempt\n\n\t\t\ttry {\n\t\t\t\tconst result = await next()\n\t\t\t\treturn result\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error as Error\n\n\t\t\t\tconst shouldRetry = this.shouldRetryError(error, attempt, maxAttempts)\n\n\t\t\t\tif (!shouldRetry || attempt >= maxAttempts) {\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\n\t\t\t\tconst delay = this.calculateDelay(attempt)\n\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[${this.name}] Retrying request to ${context.path} (attempt ${attempt + 1}/${maxAttempts}) after ${delay}ms`,\n\t\t\t\t)\n\n\t\t\t\tawait this.sleep(delay)\n\t\t\t}\n\t\t}\n\n\t\t// This shouldn't be reached, but TypeScript requires it\n\t\tthrow lastError ?? new Error('Max retry attempts reached')\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.retry === false) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Determine if an error should be retried\n\t */\n\tprivate shouldRetryError(error: unknown, attempt: number, _maxAttempts: number): boolean {\n\t\tif (this.config.shouldRetry) {\n\t\t\treturn this.config.shouldRetry(error, attempt)\n\t\t}\n\n\t\tif (this.config.retryOnNetworkError && this.isNetworkError(error)) {\n\t\t\treturn true\n\t\t}\n\n\t\tif (error instanceof ModrinthApiError && error.statusCode) {\n\t\t\treturn this.config.retryableStatusCodes.includes(error.statusCode)\n\t\t}\n\n\t\treturn false\n\t}\n\n\t/**\n\t * Check if an error is a network error\n\t */\n\tprivate isNetworkError(error: unknown): boolean {\n\t\t// Common network error indicators\n\t\tconst networkErrorPatterns = [\n\t\t\t/network/i,\n\t\t\t/timeout/i,\n\t\t\t/ECONNREFUSED/i,\n\t\t\t/ENOTFOUND/i,\n\t\t\t/ETIMEDOUT/i,\n\t\t\t/ECONNRESET/i,\n\t\t]\n\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\treturn networkErrorPatterns.some((pattern) => pattern.test(errorMessage))\n\t}\n\n\t/**\n\t * Get max attempts for this request\n\t */\n\tprivate getMaxAttempts(context: RequestContext): number {\n\t\tif (typeof context.options.retry === 'number') {\n\t\t\treturn context.options.retry\n\t\t}\n\n\t\treturn this.config.maxAttempts\n\t}\n\n\t/**\n\t * Calculate delay before next retry based on backoff strategy\n\t */\n\tprivate calculateDelay(attempt: number): number {\n\t\tconst { backoffStrategy, initialDelay, maxDelay } = this.config\n\n\t\tlet delay: number\n\n\t\tswitch (backoffStrategy) {\n\t\t\tcase 'exponential':\n\t\t\t\t// Exponential: delay = initialDelay * 2^(attempt-1)\n\t\t\t\tdelay = initialDelay * Math.pow(2, attempt - 1)\n\t\t\t\tbreak\n\n\t\t\tcase 'linear':\n\t\t\t\t// Linear: delay = initialDelay * attempt\n\t\t\t\tdelay = initialDelay * attempt\n\t\t\t\tbreak\n\n\t\t\tcase 'constant':\n\t\t\t\t// Constant: delay = initialDelay\n\t\t\t\tdelay = initialDelay\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tdelay = initialDelay\n\t\t}\n\n\t\t// Add jitter (random 0-1000ms) to prevent thundering herd\n\t\tdelay += Math.random() * 1000\n\n\t\treturn Math.min(delay, maxDelay)\n\t}\n\n\t/**\n\t * Sleep for a given duration\n\t */\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\nexport type VerboseLoggingConfig = FeatureConfig\n\nexport class VerboseLoggingFeature extends AbstractFeature {\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst method = context.options.method ?? 'GET'\n\t\tconst api = context.options.api\n\t\tconst version = context.options.version\n\t\tconst prefix = `[${method}] [${api}_v${version}]`\n\n\t\tconsole.debug(`${prefix} ${context.url} SENT`)\n\n\t\ttry {\n\t\t\tconst result = await next()\n\t\t\ttry {\n\t\t\t\tconst size = result ? JSON.stringify(result).length : 0\n\t\t\t\tconsole.debug(`${prefix} ${context.url} RECEIVED ${size} bytes`)\n\t\t\t} catch {\n\t\t\t\t// ignore size calc fail\n\t\t\t\tconsole.debug(`${prefix} ${context.url} RECEIVED`)\n\t\t\t}\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst details = formatErrorDetails(error)\n\t\t\tconsole.debug(`${prefix} ${context.url} FAILED${details ? ` \u2014 ${details}` : ''}`)\n\t\t\tthrow error\n\t\t}\n\t}\n}\n\nfunction formatErrorDetails(error: unknown): string {\n\tif (!error || typeof error !== 'object') {\n\t\treturn typeof error === 'string' ? error : ''\n\t}\n\n\tconst err = error as {\n\t\tstatus?: number\n\t\tstatusCode?: number\n\t\tstatusText?: string\n\t\tmessage?: string\n\t\tdata?: unknown\n\t\tresponseData?: unknown\n\t\toriginalError?: unknown\n\t\tresponse?: { status?: number; statusText?: string; _data?: unknown }\n\t}\n\n\tconst status = err.status ?? err.statusCode ?? err.response?.status\n\tconst statusText = err.statusText ?? err.response?.statusText\n\tconst data = err.responseData ?? err.data ?? err.response?._data\n\n\tconst parts: string[] = []\n\tif (status !== undefined) {\n\t\tparts.push(statusText ? `${status} ${statusText}` : String(status))\n\t}\n\tif (data !== undefined) {\n\t\tparts.push(`body: ${safeStringify(data)}`)\n\t} else if (err.message) {\n\t\tparts.push(err.message)\n\t}\n\treturn parts.join(' ')\n}\n\nfunction safeStringify(value: unknown): string {\n\tif (typeof value === 'string') return value\n\ttry {\n\t\treturn JSON.stringify(value)\n\t} catch {\n\t\treturn String(value)\n\t}\n}\n", "import type { Labrinth } from '../labrinth/types'\n\nexport namespace Archon {\n\texport namespace Nodes {\n\t\texport namespace Internal {\n\t\t\texport type Node = {\n\t\t\t\tid: string\n\t\t\t\thostname: string\n\t\t\t\tregion: string\n\t\t\t\tcreated_at: string | null\n\t\t\t\tlocked: boolean\n\t\t\t}\n\n\t\t\texport type Server = {\n\t\t\t\tid: string\n\t\t\t\tavailable: boolean\n\t\t\t}\n\n\t\t\texport type NodeFull = Node & {\n\t\t\t\tservers: Server[]\n\t\t\t}\n\n\t\t\texport type Overview = {\n\t\t\t\tnode_hostnames: string[]\n\t\t\t\tregions: Region[]\n\t\t\t\ttotal_servers_active: number\n\t\t\t}\n\n\t\t\texport type Region = {\n\t\t\t\tdisplay_name: string\n\t\t\t\tcountry_code: string\n\t\t\t\tkey: string\n\t\t\t\tserver_count: number\n\t\t\t\tnode_count: number\n\t\t\t}\n\n\t\t\texport type RegionWithStatistics = {\n\t\t\t\tregion: Region\n\t\t\t\tactive_servers: string[]\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Notices {\n\t\texport namespace v0 {\n\t\t\texport type Notice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\ttitle: string | null\n\t\t\t\tmessage: string\n\t\t\t\tlevel: string\n\t\t\t\tannounced: string\n\t\t\t}\n\n\t\t\texport type ListedNotice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\tmessage: string\n\t\t\t\ttitle: string | null\n\t\t\t\tlevel: string\n\t\t\t\tannounce_at: string\n\t\t\t\texpires: string | null\n\t\t\t\tassigned: Assignment[]\n\t\t\t\tdismissed_by: Dismisser[]\n\t\t\t}\n\n\t\t\texport type Dismisser = {\n\t\t\t\tserver: string\n\t\t\t\tdismissed_on: string\n\t\t\t}\n\n\t\t\texport type Assignment = {\n\t\t\t\tkind: string\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type AssignmentTarget = { server: string } | { node: string }\n\n\t\t\texport type Announce = {\n\t\t\t\tmessage: string\n\t\t\t\ttitle?: string | null\n\t\t\t\tlevel: string\n\t\t\t\tdismissable: boolean\n\t\t\t\tannounce_at: string\n\t\t\t\texpires?: string | null\n\t\t\t}\n\n\t\t\texport type AnnouncePatch = {\n\t\t\t\tmessage?: string\n\t\t\t\ttitle?: string | null\n\t\t\t\tlevel?: string\n\t\t\t\tdismissable?: boolean\n\t\t\t\tannounce_at?: string\n\t\t\t\texpires?: string | null\n\t\t\t}\n\n\t\t\texport type PostNoticeResponseBody = {\n\t\t\t\tid: number\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Actions {\n\t\texport namespace v1 {\n\t\t\texport type SortOrder = 'asc' | 'desc'\n\n\t\t\texport type ActionName =\n\t\t\t\t| 'server_created'\n\t\t\t\t| 'changed_server_name'\n\t\t\t\t| 'changed_server_subdomain'\n\t\t\t\t| 'server_reallocated'\n\t\t\t\t| 'server_plan_changed'\n\t\t\t\t| 'user_invited'\n\t\t\t\t| 'user_invite_revoked'\n\t\t\t\t| 'user_permission_modified'\n\t\t\t\t| 'user_removed'\n\t\t\t\t| 'addon_added'\n\t\t\t\t| 'addon_uploaded'\n\t\t\t\t| 'addon_disabled'\n\t\t\t\t| 'addon_enabled'\n\t\t\t\t| 'addon_deleted'\n\t\t\t\t| 'addon_updated'\n\t\t\t\t| 'modpack_changed'\n\t\t\t\t| 'modpack_unlinked'\n\t\t\t\t| 'server_repaired'\n\t\t\t\t| 'server_reset'\n\t\t\t\t| 'server_started'\n\t\t\t\t| 'server_stopped'\n\t\t\t\t| 'server_restarted'\n\t\t\t\t| 'server_killed'\n\t\t\t\t| 'port_allocation_added'\n\t\t\t\t| 'port_allocation_removed'\n\t\t\t\t| 'loader_version_edited'\n\t\t\t\t| 'game_version_edited'\n\t\t\t\t| 'server_properties_modified'\n\t\t\t\t| 'file_uploaded'\n\t\t\t\t| 'file_deleted'\n\t\t\t\t| 'file_renamed'\n\t\t\t\t| 'file_edited'\n\t\t\t\t| 'sftp_login'\n\t\t\t\t| 'console_command_executed'\n\t\t\t\t| 'console_cleared'\n\t\t\t\t| 'backup_created'\n\t\t\t\t| 'backup_renamed'\n\t\t\t\t| 'backup_restored'\n\t\t\t\t| 'backup_deleted'\n\t\t\t\t| 'startup_command_modified'\n\t\t\t\t| 'java_runtime_modified'\n\t\t\t\t| 'java_version_modified'\n\n\t\t\texport type Action = {\n\t\t\t\taction: ActionName | string\n\t\t\t\tmetadata?: unknown\n\t\t\t}\n\n\t\t\texport type UserPermissionsActionMetadata = {\n\t\t\t\tuser_id: string\n\t\t\t\tpermissions?: ServerUsers.v1.UserScope | null\n\t\t\t}\n\n\t\t\texport type ActionUser =\n\t\t\t\t| {\n\t\t\t\t\t\ttype: 'user'\n\t\t\t\t\t\tuser_id: string\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\ttype: 'support'\n\t\t\t\t\t\tuser_id?: string | null\n\t\t\t\t }\n\n\t\t\texport type ActionEntry = {\n\t\t\t\tactor: ActionUser\n\t\t\t\taction: Action\n\t\t\t\tserver_id: string\n\t\t\t\tworld_id?: string | null\n\t\t\t\ttimestamp: string\n\t\t\t}\n\n\t\t\texport type UserResp = {\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type AddonResp = {\n\t\t\t\ttitle: string\n\t\t\t\tslug?: string | null\n\t\t\t\ticon_url?: string | null\n\t\t\t\tversion?: string | null\n\t\t\t}\n\n\t\t\texport type VersionResp = {\n\t\t\t\tname: string\n\t\t\t\tversion_number?: string | null\n\t\t\t}\n\n\t\t\texport type ActionLogResponse = {\n\t\t\t\tnext_offset?: number | null\n\t\t\t\tdata: ActionEntry[]\n\t\t\t\tusers: Record<string, UserResp>\n\t\t\t\taddons: Record<string, AddonResp>\n\t\t\t\tversions: Record<string, VersionResp>\n\t\t\t}\n\n\t\t\texport type ActionLogFilter = {\n\t\t\t\tusers?: string[]\n\t\t\t\tworlds?: Array<string | null>\n\t\t\t\tactions?: ActionName[]\n\t\t\t}\n\n\t\t\texport type ListActionLogOptions = {\n\t\t\t\tfilter?: ActionLogFilter\n\t\t\t\tlimit?: number\n\t\t\t\toffset?: number\n\t\t\t\torder?: SortOrder\n\t\t\t\tmin_datetime?: string\n\t\t\t\tmax_datetime?: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Transfers {\n\t\texport namespace Internal {\n\t\t\texport type ProvisionOptions = {\n\t\t\t\tregion?: string | null\n\t\t\t\tnode_tags: string[]\n\t\t\t}\n\n\t\t\texport type ScheduleServerTransfersRequest = {\n\t\t\t\tserver_ids: string[]\n\t\t\t\tscheduled_at?: string | null\n\t\t\t\ttarget_region?: string | null\n\t\t\t\tnode_tags?: string[]\n\t\t\t\treason?: string | null\n\t\t\t}\n\n\t\t\texport type ScheduleNodeTransfersRequest = {\n\t\t\t\tnode_hostnames: string[]\n\t\t\t\tscheduled_at?: string | null\n\t\t\t\ttarget_region?: string | null\n\t\t\t\tnode_tags?: string[]\n\t\t\t\treason?: string | null\n\t\t\t\tcordon_nodes?: boolean\n\t\t\t\ttag_nodes?: string | null\n\t\t\t}\n\n\t\t\texport type ScheduleTransfersResponse = {\n\t\t\t\tbatch_id: number\n\t\t\t\tscheduled_count: number\n\t\t\t}\n\n\t\t\texport type CancelTransfersRequest = {\n\t\t\t\tbatch_ids: number[]\n\t\t\t}\n\n\t\t\texport type CancelTransfersResponse = {\n\t\t\t\tcancelled_count: number\n\t\t\t}\n\n\t\t\texport type TransferLogBatchEntry = {\n\t\t\t\tid: number\n\t\t\t\tcreated_by: string\n\t\t\t\tcreated_at: string\n\t\t\t\treason?: string | null\n\t\t\t\tscheduled_at: string\n\t\t\t\tcancelled: boolean\n\t\t\t\tlog_count: number\n\t\t\t\tprovision_options: ProvisionOptions\n\t\t\t}\n\n\t\t\texport type TransferHistoryQuery = {\n\t\t\t\tpage?: number\n\t\t\t\tpage_size?: number\n\t\t\t}\n\n\t\t\texport type TransferHistoryResponse = {\n\t\t\t\tbatches: TransferLogBatchEntry[]\n\t\t\t\ttotal: number\n\t\t\t\tpage: number\n\t\t\t\tpage_size: number\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Content {\n\t\texport namespace v1 {\n\t\t\texport type AddonKind = 'mod' | 'plugin' | 'datapack' | 'shader' | 'resourcepack'\n\n\t\t\texport type ContentOwnerType = 'user' | 'organization'\n\n\t\t\texport type ContentOwner = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\ttype: ContentOwnerType\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type AddonVersion = {\n\t\t\t\tid: string\n\t\t\t\tname: string | null\n\t\t\t\tenvironment?: Labrinth.Projects.v3.Environment | null\n\t\t\t}\n\n\t\t\texport type AddonStatus =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'installed'\n\t\t\t\t| {\n\t\t\t\t\t\tfailed: {\n\t\t\t\t\t\t\terror: string\n\t\t\t\t\t\t}\n\t\t\t\t }\n\n\t\t\texport type Addon = {\n\t\t\t\tid: string\n\t\t\t\tfilename: string\n\t\t\t\tfilesize: number\n\t\t\t\tbtime?: string\n\t\t\t\tdisabled: boolean\n\t\t\t\tkind: AddonKind\n\t\t\t\tfrom_modpack: boolean\n\t\t\t\tstatus: AddonStatus\n\t\t\t\tpack_client_retained: boolean\n\t\t\t\tpack_client_depends: boolean\n\t\t\t\thas_update: string | null\n\t\t\t\tname: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tversion: AddonVersion | null\n\t\t\t\towner: ContentOwner | null\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type Addons = {\n\t\t\t\tmodloader: string | null\n\t\t\t\tmodloader_version: string | null\n\t\t\t\tgame_version: string | null\n\t\t\t\tmodpack: ModpackFields | null\n\t\t\t\tinstalling?: 'loader' | 'modpack'\n\t\t\t\terror?: {\n\t\t\t\t\tmessage: string\n\t\t\t\t}\n\t\t\t\taddons: Addon[] | null\n\t\t\t}\n\n\t\t\texport type AddAddonRequest = {\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id?: string\n\t\t\t\tkind?: AddonKind\n\t\t\t}\n\n\t\t\texport type AddAddonsRequest = AddAddonRequest[]\n\n\t\t\texport type RemoveAddonRequest = {\n\t\t\t\tkind: AddonKind\n\t\t\t\tfilename: string\n\t\t\t}\n\n\t\t\texport type UpdateAddonRequest = {\n\t\t\t\tfilename: string\n\t\t\t\tversion_id?: string | null\n\t\t\t}\n\n\t\t\texport type Modloader =\n\t\t\t\t| 'forge'\n\t\t\t\t| 'neo_forge'\n\t\t\t\t| 'fabric'\n\t\t\t\t| 'quilt'\n\t\t\t\t| 'paper'\n\t\t\t\t| 'purpur'\n\t\t\t\t| 'vanilla'\n\n\t\t\texport type ModpackSpecModrinth = {\n\t\t\t\tplatform: 'modrinth'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type ModpackSpecLocalFile = {\n\t\t\t\tplatform: 'local_file'\n\t\t\t\tfilename: string\n\t\t\t\tname: string\n\t\t\t\tdescription: string | null\n\t\t\t}\n\n\t\t\texport type ModpackSpec = ModpackSpecModrinth | ModpackSpecLocalFile\n\n\t\t\texport type ModpackOwner = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\ttype: 'user' | 'organization'\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type ModpackFields = {\n\t\t\t\tspec: ModpackSpec\n\t\t\t\thas_update: string | null\n\t\t\t\ttitle: string | null\n\t\t\t\tdescription: string | null\n\t\t\t\ticon_url: string | null\n\t\t\t\towner: ModpackOwner | null\n\t\t\t\tversion_number: string | null\n\t\t\t\tdate_published: string | null\n\t\t\t\tdownloads: number | null\n\t\t\t\tfollowers: number | null\n\t\t\t}\n\n\t\t\texport type KnownPropertiesFields = {\n\t\t\t\tallow_cheats?: string | null\n\t\t\t\tallow_flight?: string | null\n\t\t\t\tdifficulty?: string | null\n\t\t\t\tenforce_whitelist?: string | null\n\t\t\t\tforce_gamemode?: string | null\n\t\t\t\tgamemode?: string | null\n\t\t\t\tgenerate_structures?: string | null\n\t\t\t\tgenerator_settings?: string | null\n\t\t\t\thardcore?: string | null\n\t\t\t\tlevel_seed?: string | null\n\t\t\t\tlevel_type?: string | null\n\t\t\t\tmax_players?: string | null\n\t\t\t\tmax_tick_time?: string | null\n\t\t\t\tmotd?: string | null\n\t\t\t\tpause_when_empty_seconds?: string | null\n\t\t\t\tplayer_idle_timeout?: string | null\n\t\t\t\trequire_resource_pack?: string | null\n\t\t\t\tresource_pack?: string | null\n\t\t\t\tresource_pack_id?: string | null\n\t\t\t\tresource_pack_sha1?: string | null\n\t\t\t\tsimulation_distance?: string | null\n\t\t\t\tspawn_protection?: string | null\n\t\t\t\tsync_chunk_writes?: string | null\n\t\t\t\tview_distance?: string | null\n\t\t\t\twhite_list?: string | null\n\t\t\t}\n\n\t\t\texport type PropertiesFields = {\n\t\t\t\tknown: KnownPropertiesFields\n\t\t\t\tcustom?: Record<string, string>\n\t\t\t}\n\n\t\t\texport type PatchPropertiesFields = {\n\t\t\t\tknown?: KnownPropertiesFields\n\t\t\t\tcustom?: Record<string, string | null>\n\t\t\t}\n\n\t\t\texport type JreVendor = 'temurin' | 'corretto' | 'graal'\n\n\t\t\texport type RuntimeOptions = {\n\t\t\t\tjava_version: number | null\n\t\t\t\tjre_vendor: JreVendor | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t\tstartup_command: string | null\n\t\t\t}\n\n\t\t\texport type PatchRuntimeOptions = {\n\t\t\t\tjava_version?: number | null\n\t\t\t\tjre_vendor?: JreVendor | null\n\t\t\t\tstartup_command?: string | null\n\t\t\t}\n\n\t\t\texport type InstallWorldContent =\n\t\t\t\t| {\n\t\t\t\t\t\tcontent_variant: 'modpack'\n\t\t\t\t\t\tspec: ModpackSpec\n\t\t\t\t\t\tsoft_override: boolean\n\t\t\t\t\t\tproperties?: PropertiesFields | null\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tcontent_variant: 'bare'\n\t\t\t\t\t\tloader: Modloader\n\t\t\t\t\t\tversion: string\n\t\t\t\t\t\tgame_version?: string\n\t\t\t\t\t\tsoft_override: boolean\n\t\t\t\t\t\tproperties?: PropertiesFields | null\n\t\t\t\t }\n\n\t\t\texport type AddonDiffVersion = {\n\t\t\t\tid: string\n\t\t\t\tversion_number: string\n\t\t\t}\n\n\t\t\texport type AddonDiffProject = {\n\t\t\t\tid: string\n\t\t\t\ttitle: string\n\t\t\t\ticon_url: string | null\n\t\t\t\tslug: string\n\t\t\t}\n\n\t\t\texport type AddonBaseDiffInfo = {\n\t\t\t\tcurrent_version: AddonDiffVersion | null\n\t\t\t\tnew_version: AddonDiffVersion | null\n\t\t\t\tfile_name: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tproject: AddonDiffProject | null\n\t\t\t}\n\n\t\t\texport type AddonDiffAdded = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'added'\n\t\t\t\tnew_version_id: string\n\t\t\t}\n\n\t\t\texport type AddonDiffRemoved = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'removed'\n\t\t\t}\n\n\t\t\texport type AddonDiffUpdated = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'updated'\n\t\t\t\tcurrent_version_id: string\n\t\t\t\tnew_version_id: string\n\t\t\t}\n\n\t\t\texport type AddonDiff = AddonDiffAdded | AddonDiffRemoved | AddonDiffUpdated\n\n\t\t\texport type UpdateGameVersionPreview = {\n\t\t\t\taddon_changes: AddonDiff[]\n\t\t\t\tnew_game_version: string\n\t\t\t\tnew_loader_version: string\n\t\t\t\thas_unknown_content: boolean\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace ServerUsers {\n\t\texport namespace v1 {\n\t\t\texport type ServerUserRole = 'Owner' | 'Editor' | 'Viewer' | 'Unknown'\n\n\t\t\texport type AssignableServerUserRole = Exclude<ServerUserRole, 'Owner' | 'Unknown'>\n\n\t\t\texport const UserScope = {\n\t\t\t\tNONE: '',\n\t\t\t\tSERVER_ADMIN: 'SERVER_ADMIN',\n\t\t\t\tBASE_READ: 'BASE_READ',\n\t\t\t\tPOWER_ACTIONS: 'POWER_ACTIONS',\n\t\t\t\tEXEC_COMMANDS: 'EXEC_COMMANDS',\n\t\t\t\tFILES_WRITE: 'FILES_WRITE',\n\t\t\t\tSETUP: 'SETUP',\n\t\t\t\tBACKUPS: 'BACKUPS',\n\t\t\t\tADVANCED: 'ADVANCED',\n\t\t\t\tRESET_SERVER: 'RESET_SERVER',\n\t\t\t\tMANAGE_USERS: 'MANAGE_USERS',\n\t\t\t\tSUPPORT_AGENT: 'SUPPORT_AGENT',\n\t\t\t\tINFRA_MANAGER: 'INFRA_MANAGER',\n\t\t\t\tINFRA_MANAGER_READ: 'INFRA_MANAGER_READ',\n\t\t\t\tINFRA_SERVERS_XFER: 'INFRA_SERVERS_XFER',\n\t\t\t\tINFRA_USERS: 'INFRA_USERS',\n\t\t\t} as const\n\n\t\t\texport type UserScope = string | number\n\n\t\t\texport type UserResp = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type ServerUser = {\n\t\t\t\tuser: UserResp\n\t\t\t\tadded_on?: string | null\n\t\t\t\tlast_invite_sent?: string | null\n\t\t\t\tpermissions: UserScope\n\t\t\t}\n\n\t\t\texport type AddServerUserRequest = {\n\t\t\t\tserver_id?: string | null\n\t\t\t\tuser_id: string\n\t\t\t\tadded_on?: string | null\n\t\t\t\trole: ServerUserRole\n\t\t\t}\n\n\t\t\texport type ReinviteResponse = {\n\t\t\t\tsent: boolean\n\t\t\t\tcooldown_seconds: number | null\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Servers {\n\t\texport namespace Internal {\n\t\t\texport type Lookup = {\n\t\t\t\tid: string\n\t\t\t}\n\t\t}\n\n\t\texport namespace v0 {\n\t\t\texport type ServerGetResponse = {\n\t\t\t\tservers: Server[]\n\t\t\t\tpagination: Pagination\n\t\t\t\tusers: Record<string, ServerOwner>\n\t\t\t}\n\n\t\t\texport type Pagination = {\n\t\t\t\tcurrent_page: number\n\t\t\t\tpage_size: number\n\t\t\t\ttotal_pages: number\n\t\t\t\ttotal_items: number\n\t\t\t}\n\n\t\t\texport type ServerOwner = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type Status = 'installing' | 'broken' | 'available' | 'suspended'\n\n\t\t\texport type SuspensionReason =\n\t\t\t\t| 'moderated'\n\t\t\t\t| 'paymentfailed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'upgrading'\n\t\t\t\t| 'other'\n\n\t\t\texport type Loader =\n\t\t\t\t| 'Forge'\n\t\t\t\t| 'NeoForge'\n\t\t\t\t| 'Fabric'\n\t\t\t\t| 'Quilt'\n\t\t\t\t| 'Purpur'\n\t\t\t\t| 'Spigot'\n\t\t\t\t| 'Vanilla'\n\t\t\t\t| 'Paper'\n\n\t\t\texport type Game = 'Minecraft'\n\n\t\t\texport type UpstreamKind = 'modpack' | 'none'\n\n\t\t\texport type Server = {\n\t\t\t\tserver_id: string\n\t\t\t\tname: string\n\t\t\t\towner_id: string\n\t\t\t\tnet: Net\n\t\t\t\tgame: Game\n\t\t\t\tbackup_quota: number\n\t\t\t\tused_backup_quota: number\n\t\t\t\tstatus: Status\n\t\t\t\tsuspension_reason: SuspensionReason | null\n\t\t\t\tloader: Loader | null\n\t\t\t\tloader_version: string | null\n\t\t\t\tmc_version: string | null\n\t\t\t\tupstream: Upstream | null\n\t\t\t\tsftp_username: string\n\t\t\t\tsftp_password: string\n\t\t\t\tsftp_host: string\n\t\t\t\tdatacenter: string\n\t\t\t\tnotices: Notice[]\n\t\t\t\tnode: NodeInfo | null\n\t\t\t\tflows: Flows\n\t\t\t\tis_medal: boolean\n\t\t\t\tcurrent_user_permissions: UserScope\n\n\t\t\t\tmedal_expires?: string\n\t\t\t}\n\n\t\t\texport type UserScope = number\n\n\t\t\texport type Net = {\n\t\t\t\tip: string | null\n\t\t\t\tport: number\n\t\t\t\tdomain: string\n\t\t\t}\n\n\t\t\texport type Upstream = {\n\t\t\t\tkind: UpstreamKind\n\t\t\t\tversion_id: string\n\t\t\t\tproject_id: string\n\t\t\t}\n\n\t\t\texport type Notice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\ttitle: string\n\t\t\t\tmessage: string\n\t\t\t\tlevel: string\n\t\t\t\tannounced: string\n\t\t\t}\n\n\t\t\texport type NodeInfo = {\n\t\t\t\ttoken: string\n\t\t\t\tinstance: string\n\t\t\t}\n\n\t\t\texport type Flows = {\n\t\t\t\tintro: boolean\n\t\t\t}\n\n\t\t\texport type GetServersOptions = {\n\t\t\t\tlimit?: number\n\t\t\t\toffset?: number\n\t\t\t}\n\n\t\t\texport type StockRequest = {\n\t\t\t\tcpu?: number\n\t\t\t\tmemory_mb?: number\n\t\t\t\tswap_mb?: number\n\t\t\t\tstorage_mb?: number\n\t\t\t}\n\n\t\t\texport type StockResponse = {\n\t\t\t\tavailable: number\n\t\t\t}\n\n\t\t\texport type JWTAuth = {\n\t\t\t\turl: string // e.g., \"node-xyz.modrinth.com/modrinth/v0/fs\"\n\t\t\t\ttoken: string // JWT token for filesystem access\n\t\t\t}\n\n\t\t\texport type ReinstallLoaderRequest = {\n\t\t\t\tloader: string\n\t\t\t\tloader_version?: string\n\t\t\t\tgame_version?: string\n\t\t\t}\n\n\t\t\texport type ReinstallModpackRequest = {\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id?: string\n\t\t\t}\n\n\t\t\texport type ReinstallRequest = ReinstallLoaderRequest | ReinstallModpackRequest\n\n\t\t\texport type MrpackReinstallAuth = {\n\t\t\t\turl: string\n\t\t\t\ttoken: string\n\t\t\t}\n\n\t\t\texport type Allocation = {\n\t\t\t\tport: number\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type StartupConfig = {\n\t\t\t\tinvocation: string\n\t\t\t\toriginal_invocation: string\n\t\t\t\tjdk_version: 'lts8' | 'lts11' | 'lts17' | 'lts21'\n\t\t\t\tjdk_build: 'corretto' | 'temurin' | 'graal'\n\t\t\t}\n\t\t}\n\n\t\texport namespace v1 {\n\t\t\texport type ServerFull = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tsubdomain: string\n\t\t\t\tspecs: ServerResources\n\t\t\t\tsftp_username: string\n\t\t\t\tsftp_password: string\n\t\t\t\ttags: string[]\n\t\t\t\tlocation: ServerLocation\n\t\t\t\tworlds: WorldFull[]\n\t\t\t}\n\n\t\t\texport type ServerResources = {\n\t\t\t\tcpu: number\n\t\t\t\tmemory_mb: number\n\t\t\t\tstorage_mb: number\n\t\t\t\tswap_mb: number\n\t\t\t}\n\n\t\t\texport type ServerLocation =\n\t\t\t\t| {\n\t\t\t\t\t\tstatus: 'assigned'\n\t\t\t\t\t\tlocation_metadata: {\n\t\t\t\t\t\t\tregion: string\n\t\t\t\t\t\t\tregion_should_be_user_displayed: boolean\n\t\t\t\t\t\t\thostname: string\n\t\t\t\t\t\t\tis_decommissioned_node: boolean\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tstatus: 'unassigned'\n\t\t\t\t }\n\n\t\t\texport type WorldFull = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tis_active: boolean\n\t\t\t\t/**\n\t\t\t\t * @deprecated Prefer `client.archon.backups_queue_v1.list()` for queue-aware backup state.\n\t\t\t\t */\n\t\t\t\tbackups: Archon.Backups.v1.Backup[]\n\t\t\t\tcontent: WorldContentInfo | null\n\t\t\t\treadiness: WorldReadiness\n\t\t\t}\n\n\t\t\texport type WorldReadiness = {\n\t\t\t\tdata_synchronized_fetched: boolean\n\t\t\t}\n\n\t\t\texport type WorldContentInfo = {\n\t\t\t\tmodloader: string\n\t\t\t\tmodloader_version: string\n\t\t\t\tgame_version: string\n\t\t\t\tjava_version: number | null\n\t\t\t\tinvocation: string | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t}\n\n\t\t\texport type Region = {\n\t\t\t\tshortcode: string\n\t\t\t\tcountry_code: string\n\t\t\t\tdisplay_name: string\n\t\t\t\tlat: number\n\t\t\t\tlon: number\n\t\t\t\tzone: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Backups {\n\t\t/**\n\t\t * @deprecated Use {@link Archon.BackupsQueue.v1} and `client.archon.backups_queue_v1` instead.\n\t\t */\n\t\texport namespace v1 {\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupState = 'ongoing' | 'done' | 'failed' | 'cancelled' | 'unchanged'\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupTask = 'file' | 'create' | 'restore'\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupTaskProgress = {\n\t\t\t\tprogress: number // 0.0 to 1.0\n\t\t\t\tstate: BackupState\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupQueueBackup} instead. */\n\t\t\texport type Backup = {\n\t\t\t\tid: string\n\t\t\t\tphysical_id: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tautomated: boolean\n\t\t\t\tstatus: BackupStatus\n\t\t\t\tinterrupted: boolean\n\t\t\t\tongoing: boolean\n\t\t\t\tlocked: boolean\n\t\t\t\ttask?: {\n\t\t\t\t\tfile?: BackupTaskProgress\n\t\t\t\t\tcreate?: BackupTaskProgress\n\t\t\t\t\trestore?: BackupTaskProgress\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupRequest} instead. */\n\t\t\texport type BackupRequest = {\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type PatchBackup = {\n\t\t\t\tname?: string\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.PostBackupQueueResponse} instead. */\n\t\t\texport type PostBackupResponse = {\n\t\t\t\tid: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace BackupsQueue {\n\t\texport namespace v1 {\n\t\t\texport type BackupQueueOperationType = 'create' | 'restore'\n\n\t\t\texport type BackupQueueState =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'completed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'failed'\n\t\t\t\t| 'timed_out'\n\n\t\t\texport type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'\n\n\t\t\texport type BackupRequest = {\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type PostBackupQueueResponse = {\n\t\t\t\tid: string\n\t\t\t}\n\n\t\t\texport type UserInfo = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url: string | null\n\t\t\t}\n\n\t\t\texport type DeleteManyBackupRequest = {\n\t\t\t\tbackup_ids: string[]\n\t\t\t}\n\n\t\t\texport type ActiveOperation = {\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_type: BackupQueueOperationType\n\t\t\t\toperation_id: number | null\n\t\t\t\thas_parent: boolean\n\t\t\t\tscheduled_for: string\n\t\t\t\tstarted_at: string | null\n\t\t\t\tsynthetic_legacy: boolean\n\t\t\t\tuser_info: UserInfo | null\n\t\t\t}\n\n\t\t\texport type BackupQueueOperation = {\n\t\t\t\toperation_type: BackupQueueOperationType\n\t\t\t\toperation_id: number | null\n\t\t\t\tstate: BackupQueueState\n\t\t\t\tscheduled_for: string\n\t\t\t\tstarted_at: string | null\n\t\t\t\tcompleted_at: string | null\n\t\t\t\thas_parent: boolean\n\t\t\t\terror: string | null\n\t\t\t\tshould_prompt: boolean\n\t\t\t\tsynthetic_legacy: boolean\n\t\t\t\tuser_info: UserInfo | null\n\t\t\t}\n\n\t\t\texport type BackupQueueBackup = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tstatus: BackupStatus\n\t\t\t\tlocked: boolean\n\t\t\t\tautomated: boolean\n\t\t\t\thistory: BackupQueueOperation[]\n\t\t\t}\n\n\t\t\texport type BackupsQueueResponse = {\n\t\t\t\tactive_operations: ActiveOperation[]\n\t\t\t\tbackups: BackupQueueBackup[]\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Sync {\n\t\texport namespace v1 {\n\t\t\texport type SyncCategory = 'backup' | 'users' | 'server' | 'protocol' | 'world'\n\t\t\texport type SyncIntent = 'all' | SyncCategory | SyncCategory[]\n\t\t\texport type BackupOperationStatus = 'completed' | 'cancelled' | 'failed' | 'timed-out'\n\t\t\texport type ServerNetworkPort = { port: number; name: string }\n\n\t\t\texport type ProtocolResetEvent = { type: 'protocol.reset' }\n\t\t\texport type ProtocolInvalidEvent = { type: 'protocol.invalid' }\n\t\t\texport type ProtocolErrorEvent = { type: 'protocol.error'; error: string }\n\n\t\t\texport type BackupNewEvent = { type: 'backup.new'; id: string }\n\t\t\texport type BackupPatchEvent = {\n\t\t\t\ttype: 'backup.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\tname: string\n\t\t\t}\n\t\t\texport type BackupDeleteEvent = {\n\t\t\t\ttype: 'backup.delete'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t}\n\t\t\texport type BackupOperationStartEvent = {\n\t\t\t\ttype:\n\t\t\t\t\t| 'backup.operation.create.init'\n\t\t\t\t\t| 'backup.operation.create.start'\n\t\t\t\t\t| 'backup.operation.restore.init'\n\t\t\t\t\t| 'backup.operation.restore.start'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_id: number\n\t\t\t}\n\t\t\texport type BackupOperationDoneEvent = {\n\t\t\t\ttype: 'backup.operation.create.done' | 'backup.operation.restore.done'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_id: number\n\t\t\t\tstatus: BackupOperationStatus\n\t\t\t}\n\n\t\t\texport type ServerPatchEvent = {\n\t\t\t\ttype: 'server.patch'\n\t\t\t\tname: string\n\t\t\t\tsubdomain: string\n\t\t\t}\n\t\t\texport type ServerNetworkPatchEvent = {\n\t\t\t\ttype: 'server.network.patch'\n\t\t\t\tports: ServerNetworkPort[]\n\t\t\t}\n\t\t\texport type ServerTransferEvent = {\n\t\t\t\ttype: 'server.transfer.start' | 'server.transfer.done'\n\t\t\t\ttarget_node: string\n\t\t\t}\n\n\t\t\texport type UsersPatchEvent = { type: 'users.patch' }\n\n\t\t\texport type WorldPatchEvent = {\n\t\t\t\ttype: 'world.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tname: string\n\t\t\t}\n\t\t\texport type WorldStartupPatchEvent = {\n\t\t\t\ttype: 'world.startup.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tjava_version: number | null\n\t\t\t\tinvocation: string | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t}\n\t\t\texport type WorldContentAddonPatchEvent = {\n\t\t\t\ttype: 'world.content.addon.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tspecs: Archon.Content.v1.Addon[]\n\t\t\t}\n\t\t\texport type WorldContentBaseUpdateEvent = {\n\t\t\t\ttype: 'world.content.base.update'\n\t\t\t\tworld_id: string\n\t\t\t\tspec: Archon.Content.v1.Addons\n\t\t\t}\n\t\t\texport type WorldContentPlatform =\n\t\t\t\t| 'forge'\n\t\t\t\t| 'neoforge'\n\t\t\t\t| 'fabric'\n\t\t\t\t| 'quilt'\n\t\t\t\t| 'paper'\n\t\t\t\t| 'purpur'\n\t\t\t\t| 'vanilla'\n\t\t\texport type WorldContentPlatformData = {\n\t\t\t\tplatform: WorldContentPlatform\n\t\t\t\tgame_version: string\n\t\t\t\tplatform_version: string | null\n\t\t\t}\n\t\t\texport type WorldContentModpackSource =\n\t\t\t\t| 'CurseForge'\n\t\t\t\t| {\n\t\t\t\t\t\tModrinth: {\n\t\t\t\t\t\t\tversion_id: string\n\t\t\t\t\t\t\tproject_id: string\n\t\t\t\t\t\t\tmrpack_sha1: string | null\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tLocalMrPackFile: {\n\t\t\t\t\t\t\tpath: string\n\t\t\t\t\t\t\tname: string\n\t\t\t\t\t\t\tdescription: string | null\n\t\t\t\t\t\t\tversion_name: string | null\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\texport type WorldContentModpack = {\n\t\t\t\tspec: WorldContentModpackSource\n\t\t\t\tdownloads: number | null\n\t\t\t\tfollowers: number | null\n\t\t\t\ticon_url: string | null\n\t\t\t\towner: Archon.Content.v1.ContentOwner | null\n\t\t\t\ttitle: string | null\n\t\t\t\tdescription: string | null\n\t\t\t\tversion_number: string | null\n\t\t\t\tdate_published: string | null\n\t\t\t\tenvironment: Labrinth.Projects.v3.Environment | null\n\t\t\t\thas_update: string | null\n\t\t\t}\n\t\t\texport type WorldContentItem = {\n\t\t\t\tparent_directory: string\n\t\t\t\tfile_sha1: string | null\n\t\t\t\tfilename: string\n\t\t\t\tbtime?: string\n\t\t\t\tfrom_modpack: boolean\n\t\t\t\tversion_id: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tpack_client_retained: boolean\n\t\t\t\tpack_client_depends: boolean\n\t\t\t\tstatus: Archon.Content.v1.AddonStatus\n\t\t\t\tfilesize: number | null\n\t\t\t\tname: string | null\n\t\t\t\tversion: Archon.Content.v1.AddonVersion | null\n\t\t\t\towner: Archon.Content.v1.ContentOwner | null\n\t\t\t\thas_update: string | null\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\t\t\texport type WorldContentUpdateEvent = {\n\t\t\t\ttype: 'world.content.update'\n\t\t\t\tworld_id: string\n\t\t\t\tplatform_data: WorldContentPlatformData | null\n\t\t\t\tlinked_modpack: WorldContentModpack | null\n\t\t\t\tinstalling?: 'loader' | 'modpack'\n\t\t\t\terror?: {\n\t\t\t\t\tmessage: string\n\t\t\t\t}\n\t\t\t\tcontent: WorldContentItem[]\n\t\t\t}\n\n\t\t\texport type SyncEvent =\n\t\t\t\t| ProtocolResetEvent\n\t\t\t\t| ProtocolInvalidEvent\n\t\t\t\t| ProtocolErrorEvent\n\t\t\t\t| BackupNewEvent\n\t\t\t\t| BackupPatchEvent\n\t\t\t\t| BackupDeleteEvent\n\t\t\t\t| BackupOperationStartEvent\n\t\t\t\t| BackupOperationDoneEvent\n\t\t\t\t| ServerPatchEvent\n\t\t\t\t| ServerNetworkPatchEvent\n\t\t\t\t| ServerTransferEvent\n\t\t\t\t| UsersPatchEvent\n\t\t\t\t| WorldPatchEvent\n\t\t\t\t| WorldStartupPatchEvent\n\t\t\t\t| WorldContentAddonPatchEvent\n\t\t\t\t| WorldContentBaseUpdateEvent\n\t\t\t\t| WorldContentUpdateEvent\n\t\t}\n\t}\n\n\texport namespace Websocket {\n\t\texport namespace v0 {\n\t\t\texport type WSAuth = {\n\t\t\t\turl: string\n\t\t\t\ttoken: string\n\t\t\t}\n\n\t\t\texport type BackupState =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'done'\n\t\t\t\t| 'failed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'unchanged'\n\t\t\t\t| 'damaged'\n\t\t\texport type BackupTask = 'file' | 'create' | 'restore'\n\n\t\t\texport type WSBackupProgressEvent = {\n\t\t\t\tevent: 'backup-progress'\n\t\t\t\tid: string\n\t\t\t\ttask: BackupTask\n\t\t\t\tstate: BackupState\n\t\t\t\tprogress: number\n\t\t\t\tstart_time?: number | null\n\t\t\t\tfinish_time?: number | null\n\t\t\t}\n\n\t\t\texport type WSLogEvent = {\n\t\t\t\tevent: 'log'\n\t\t\t\tstream: 'stdout' | 'stderr'\n\t\t\t\tmessage: string\n\t\t\t}\n\n\t\t\texport type WSLog4jEvent = {\n\t\t\t\tevent: 'log4j'\n\t\t\t\tlogger_name?: string\n\t\t\t\tlevel?: string\n\t\t\t\tthread_name?: string\n\t\t\t\ttimestamp_millis?: number\n\t\t\t\tmessage?: string\n\t\t\t\tthrowable?: string\n\t\t\t}\n\n\t\t\texport type WSStatsEvent = {\n\t\t\t\tevent: 'stats'\n\t\t\t\tcpu_percent: number\n\t\t\t\tram_usage_bytes: number\n\t\t\t\tram_total_bytes: number\n\t\t\t\tstorage_usage_bytes: number\n\t\t\t\tstorage_total_bytes: number\n\t\t\t\tnet_tx_bytes: number\n\t\t\t\tnet_rx_bytes: number\n\t\t\t}\n\n\t\t\texport type PowerState = 'running' | 'stopped' | 'starting' | 'stopping' | 'crashed'\n\n\t\t\texport type WSPowerStateEvent = {\n\t\t\t\tevent: 'power-state'\n\t\t\t\tstate: PowerState\n\t\t\t\toom_killed?: boolean\n\t\t\t\texit_code?: number\n\t\t\t}\n\n\t\t\texport type WSAuthExpiringEvent = {\n\t\t\t\tevent: 'auth-expiring'\n\t\t\t}\n\n\t\t\texport type WSAuthIncorrectEvent = {\n\t\t\t\tevent: 'auth-incorrect'\n\t\t\t}\n\n\t\t\texport type WSAuthOkEvent = {\n\t\t\t\tevent: 'auth-ok'\n\t\t\t}\n\n\t\t\texport type WSInstallationResultEvent =\n\t\t\t\t| WSInstallationResultOkEvent\n\t\t\t\t| WSInstallationResultErrEvent\n\n\t\t\texport type WSInstallationResultOkEvent = {\n\t\t\t\tevent: 'installation-result'\n\t\t\t\tresult: 'ok'\n\t\t\t}\n\n\t\t\texport type WSInstallationResultErrEvent = {\n\t\t\t\tevent: 'installation-result'\n\t\t\t\tresult: 'err'\n\t\t\t\treason?: string\n\t\t\t}\n\n\t\t\texport type WSUptimeEvent = {\n\t\t\t\tevent: 'uptime'\n\t\t\t\tuptime: number\n\t\t\t}\n\n\t\t\texport type WSNewModEvent = {\n\t\t\t\tevent: 'new-mod'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type InstallProgressFileKey = {\n\t\t\t\ttype: 'file'\n\t\t\t\tinstall_type: 'install' | 'update'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t\tparent_directory: string\n\t\t\t\tsource_filename: string | null\n\t\t\t\ttarget_filename?: string | null\n\t\t\t}\n\n\t\t\texport type InstallProgressModrinthModpackKey = {\n\t\t\t\ttype: 'modrinth_modpack'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type InstallProgressLocalModpackKey = {\n\t\t\t\ttype: 'local_modpack'\n\t\t\t\tfilename: string\n\t\t\t}\n\n\t\t\texport type InstallProgressPlatformKey = {\n\t\t\t\ttype: 'platform'\n\t\t\t\tplatform: 'forge' | 'neoforge' | 'fabric' | 'quilt' | 'paper' | 'purpur' | 'vanilla'\n\t\t\t\tplatform_version: string\n\t\t\t\tgame_version: string\n\t\t\t}\n\n\t\t\texport type InstallProgressKey =\n\t\t\t\t| InstallProgressFileKey\n\t\t\t\t| InstallProgressModrinthModpackKey\n\t\t\t\t| InstallProgressLocalModpackKey\n\t\t\t\t| InstallProgressPlatformKey\n\n\t\t\texport type InstallProgressItem = {\n\t\t\t\tworld_id: string\n\t\t\t\tkey: InstallProgressKey\n\t\t\t\tid: string\n\t\t\t\tprogress: number | null\n\t\t\t\terror: string | null\n\t\t\t}\n\n\t\t\texport type WSInstallProgressEvent = {\n\t\t\t\tevent: 'install-progress'\n\t\t\t\titems: InstallProgressItem[]\n\t\t\t}\n\n\t\t\texport type FilesystemOpKind = 'unarchive'\n\n\t\t\texport type FilesystemOpState =\n\t\t\t\t| 'queued'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'done'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'failure-corrupted'\n\t\t\t\t| 'failure-invalid-path'\n\n\t\t\texport type FilesystemOperation = {\n\t\t\t\top: FilesystemOpKind\n\t\t\t\tid: string\n\t\t\t\tprogress: number\n\t\t\t\tbytes_processed: number\n\t\t\t\tfiles_processed: number\n\t\t\t\tstate: FilesystemOpState\n\t\t\t\tmime: string\n\t\t\t\tcurrent_file?: string\n\t\t\t\tinvalid_path?: string\n\t\t\t\tsrc: string\n\t\t\t\tstarted: string\n\t\t\t}\n\n\t\t\texport type QueuedFilesystemOp = {\n\t\t\t\top: FilesystemOpKind\n\t\t\t\tsrc: string\n\t\t\t}\n\n\t\t\texport type WSFilesystemOpsEvent = {\n\t\t\t\tevent: 'filesystem-ops'\n\t\t\t\tall: FilesystemOperation[]\n\t\t\t}\n\n\t\t\texport type ReadinessState =\n\t\t\t\t| 'deprovisioned'\n\t\t\t\t| 'waiting_active_world'\n\t\t\t\t| 'waiting_world_spec_details_for_progress'\n\t\t\t\t| 'pulling_world_data'\n\t\t\t\t| 'migration_zfs'\n\t\t\t\t| 'sync_content'\n\t\t\t\t| 'container_readying'\n\t\t\t\t| 'ready'\n\n\t\t\texport type FlattenedPowerState = 'not_ready' | 'starting' | 'running' | 'stopping' | 'idle'\n\n\t\t\texport type SyncInstallPhase = 'Analyzing' | 'InstallingPack' | 'InstallingLoader' | 'Addons'\n\n\t\t\texport type SyncContentProgress = {\n\t\t\t\tstarted_at: string\n\t\t\t\tphase: SyncInstallPhase\n\t\t\t\tpercent: number\n\t\t\t}\n\n\t\t\texport type SyncContentError = {\n\t\t\t\tstep: string\n\t\t\t\tdescription: string\n\t\t\t}\n\n\t\t\texport type WSStateEvent = {\n\t\t\t\tevent: 'state'\n\t\t\t\tdebug: string\n\t\t\t\tpower_variant: FlattenedPowerState\n\t\t\t\texit_code?: number | null\n\t\t\t\twas_oom?: boolean\n\t\t\t\ttarget: 'start' | 'stop' | 'restart' | null\n\t\t\t\tuptime: number\n\t\t\t\tprogress: SyncContentProgress | null\n\t\t\t\tcontent_error: SyncContentError | null\n\t\t\t}\n\n\t\t\t// Outgoing messages (client -> server)\n\t\t\texport type WSOutgoingMessage = WSAuthMessage | WSCommandMessage\n\n\t\t\texport type WSAuthMessage = {\n\t\t\t\tevent: 'auth'\n\t\t\t\tjwt: string\n\t\t\t}\n\n\t\t\texport type WSCommandMessage = {\n\t\t\t\tevent: 'command'\n\t\t\t\tcmd: string\n\t\t\t}\n\n\t\t\texport type WSEvent =\n\t\t\t\t| WSBackupProgressEvent\n\t\t\t\t| WSLogEvent\n\t\t\t\t| WSLog4jEvent\n\t\t\t\t| WSStatsEvent\n\t\t\t\t| WSPowerStateEvent\n\t\t\t\t| WSStateEvent\n\t\t\t\t| WSAuthExpiringEvent\n\t\t\t\t| WSAuthIncorrectEvent\n\t\t\t\t| WSAuthOkEvent\n\t\t\t\t| WSInstallationResultEvent\n\t\t\t\t| WSUptimeEvent\n\t\t\t\t| WSNewModEvent\n\t\t\t\t| WSInstallProgressEvent\n\t\t\t\t| WSFilesystemOpsEvent\n\n\t\t\texport type WSEventType = WSEvent['event']\n\t\t}\n\t}\n}\n", "import { $fetch, FetchError } from 'ofetch'\n\nimport { ModrinthApiError } from '../core/errors'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Generic platform client using ofetch\n *\n * This client works in any JavaScript environment (Node.js, browser, workers, etc).\n *\n * @example\n * ```typescript\n * const client = new GenericModrinthClient({\n * userAgent: 'my-app/1.0.0',\n * features: [\n * new AuthFeature({ token: async () => getOAuthToken() }),\n * new RetryFeature({ maxAttempts: 3 })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class GenericModrinthClient extends XHRUploadClient {\n\tconstructor(config: ClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\tconst response = await $fetch<T>(url, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: options.body as BodyInit,\n\t\t\t\tparams: options.params as Record<string, string>,\n\t\t\t\ttimeout: options.timeout,\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\treturn response\n\t\t} catch (error) {\n\t\t\t// ofetch throws FetchError for HTTP errors\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst response = await fetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new ModrinthApiError('Streaming response has no readable body', {\n\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof FetchError) {\n\t\t\treturn this.createNormalizedError(error, error.response?.status, error.data)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n}\n", "import type { RequestOptions } from '../types/request'\n\nexport function appendRequestParams(url: string, params?: RequestOptions['params']): string {\n\tif (!params) return url\n\n\tconst filteredParams: Record<string, string> = {}\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined && value !== null) {\n\t\t\tfilteredParams[key] = String(value)\n\t\t}\n\t}\n\n\tconst queryString = new URLSearchParams(filteredParams).toString()\n\tif (!queryString) return url\n\n\treturn `${url}${url.includes('?') ? '&' : '?'}${queryString}`\n}\n\nexport function toFetchBody(body: unknown): BodyInit | null | undefined {\n\tif (!body) return undefined\n\n\tif (\n\t\ttypeof body === 'object' &&\n\t\t!(body instanceof FormData) &&\n\t\t!(body instanceof URLSearchParams) &&\n\t\t!(body instanceof Blob) &&\n\t\t!(body instanceof ArrayBuffer) &&\n\t\t!ArrayBuffer.isView(body as ArrayBufferView)\n\t) {\n\t\treturn JSON.stringify(body)\n\t}\n\n\treturn body as BodyInit\n}\n\nexport async function parseResponseErrorData(response: Response): Promise<unknown> {\n\tconst contentType = response.headers.get('content-type')?.toLowerCase() ?? ''\n\n\ttry {\n\t\tif (contentType.includes('application/json') || contentType.includes('+json')) {\n\t\t\treturn await response.json()\n\t\t}\n\n\t\tconst text = await response.text()\n\t\tif (!text) return undefined\n\n\t\ttry {\n\t\t\treturn JSON.parse(text)\n\t\t} catch {\n\t\t\treturn text\n\t\t}\n\t} catch {\n\t\treturn undefined\n\t}\n}\n", "import mitt from 'mitt'\n\nimport {\n\tAbstractSyncClient,\n\ttype SyncConnection,\n\ttype SyncConnectOptions,\n\ttype SyncEmitterEvents,\n} from '../core/abstract-sync'\nimport type { Archon } from '../modules/archon/types'\nimport { type ParsedSseItem, parseSyncEventData, SseParser } from '../utils/sse'\n\ntype StreamReadResult = 'closed' | 'protocol-reconnect'\n\nconst DEFAULT_RETRY_DELAY = 1000\nconst MAX_RECONNECT_DELAY = 30000\nconst JITTER_MS = 1000\n\nexport class GenericSyncClient extends AbstractSyncClient {\n\tprotected emitter = mitt<SyncEmitterEvents>()\n\n\tasync safeConnectServer(serverId: string, options: SyncConnectOptions = {}): Promise<void> {\n\t\tconst existing = this.connections.get(serverId)\n\t\tif (existing && !options.force && !existing.stopped && existing.status !== 'disconnected') {\n\t\t\treturn\n\t\t}\n\n\t\tif (existing) {\n\t\t\tthis.closeConnection(serverId)\n\t\t}\n\n\t\tconst connection: SyncConnection = {\n\t\t\tserverId,\n\t\t\tintent: options.intent ?? 'all',\n\t\t\treconnectAttempts: 0,\n\t\t\tretryDelay: DEFAULT_RETRY_DELAY,\n\t\t\tstopped: false,\n\t\t\tstatus: 'idle',\n\t\t}\n\n\t\tthis.connections.set(serverId, connection)\n\t\tvoid this.runConnection(connection)\n\t}\n\n\tdisconnect(serverId: string): void {\n\t\tthis.closeConnection(serverId)\n\t\tthis.clearListeners(serverId)\n\t}\n\n\tdisconnectAll(): void {\n\t\tfor (const serverId of this.connections.keys()) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n\n\tprivate async runConnection(connection: SyncConnection): Promise<void> {\n\t\twhile (!connection.stopped) {\n\t\t\tconst hadConnected = connection.status === 'connected'\n\t\t\tthis.updateStatus(connection, hadConnected ? 'reconnecting' : 'connecting')\n\n\t\t\tconst controller = new AbortController()\n\t\t\tconnection.controller = controller\n\n\t\t\ttry {\n\t\t\t\tconst stream = await this.client.stream('/sync', {\n\t\t\t\t\tapi: 'archon',\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tscope: `server:${connection.serverId}`,\n\t\t\t\t\t\tintent: this.intentToParam(connection.intent),\n\t\t\t\t\t},\n\t\t\t\t\theaders: connection.lastEventId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t'Last-Event-Id': connection.lastEventId,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\tretry: false,\n\t\t\t\t\tcircuitBreaker: false,\n\t\t\t\t})\n\n\t\t\t\tif (connection.stopped) return\n\n\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\tthis.updateStatus(connection, 'connected')\n\n\t\t\t\tconst result = await this.consumeStream(connection, stream)\n\t\t\t\tconnection.controller = undefined\n\t\t\t\tif (connection.stopped) return\n\n\t\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tawait this.waitForReconnect(connection)\n\t\t\t} catch (error) {\n\t\t\t\tconnection.controller = undefined\n\t\t\t\tif (connection.stopped || this.isAbortError(error)) return\n\n\t\t\t\tconnection.reconnectAttempts++\n\t\t\t\tthis.updateStatus(connection, 'error', error)\n\t\t\t\tconsole.warn(`[Sync] Connection failed for server ${connection.serverId}:`, error)\n\t\t\t\tawait this.waitForReconnect(connection)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async consumeStream(\n\t\tconnection: SyncConnection,\n\t\tstream: ReadableStream<Uint8Array>,\n\t): Promise<StreamReadResult> {\n\t\tconst reader = stream.getReader()\n\t\tconst decoder = new TextDecoder()\n\t\tconst parser = new SseParser()\n\n\t\ttry {\n\t\t\twhile (!connection.stopped) {\n\t\t\t\tconst { done, value } = await reader.read()\n\t\t\t\tif (done) break\n\n\t\t\t\tconst chunk = decoder.decode(value, { stream: true })\n\t\t\t\tconst result = this.processParsedItems(connection, parser.feed(chunk))\n\t\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\t\tawait reader.cancel()\n\t\t\t\t\tconnection.controller?.abort()\n\t\t\t\t\treturn result\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst finalChunk = decoder.decode()\n\t\t\tconst finalItems = finalChunk ? parser.feed(finalChunk) : []\n\t\t\tconst result = this.processParsedItems(connection, [...finalItems, ...parser.end()])\n\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\tawait reader.cancel()\n\t\t\t\tconnection.controller?.abort()\n\t\t\t\treturn result\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock()\n\t\t}\n\n\t\treturn 'closed'\n\t}\n\n\tprivate processParsedItems(connection: SyncConnection, items: ParsedSseItem[]): StreamReadResult {\n\t\tfor (const item of items) {\n\t\t\tif (item.kind === 'retry') {\n\t\t\t\tconnection.retryDelay = Math.min(item.retry, MAX_RECONNECT_DELAY)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.updateLastEventId(connection, item.id)\n\n\t\t\tconst event = parseSyncEventData(item.data)\n\t\t\tif (!event) {\n\t\t\t\tconsole.warn('[Sync] Dropping malformed SSE payload:', {\n\t\t\t\t\tserverId: connection.serverId,\n\t\t\t\t\tevent: item.event,\n\t\t\t\t\tdata: item.data,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.emitSyncEvent(connection.serverId, event)\n\n\t\t\tif (event.type === 'protocol.reset' || event.type === 'protocol.invalid') {\n\t\t\t\tconnection.lastEventId = undefined\n\t\t\t\treturn 'protocol-reconnect'\n\t\t\t}\n\t\t}\n\n\t\treturn 'closed'\n\t}\n\n\tprivate async waitForReconnect(connection: SyncConnection): Promise<void> {\n\t\tif (connection.stopped) return\n\n\t\tthis.updateStatus(connection, 'reconnecting')\n\t\tconst delay = this.getReconnectDelay(connection)\n\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconnection.reconnectResolve = resolve\n\t\t\tconnection.reconnectTimer = setTimeout(() => {\n\t\t\t\tconnection.reconnectTimer = undefined\n\t\t\t\tconnection.reconnectResolve = undefined\n\t\t\t\tresolve()\n\t\t\t}, delay)\n\t\t})\n\t}\n\n\tprivate closeConnection(serverId: string): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tconnection.stopped = true\n\t\tconnection.controller?.abort()\n\n\t\tif (connection.reconnectTimer) {\n\t\t\tclearTimeout(connection.reconnectTimer)\n\t\t\tconnection.reconnectTimer = undefined\n\t\t}\n\t\tconnection.reconnectResolve?.()\n\t\tconnection.reconnectResolve = undefined\n\n\t\tthis.updateStatus(connection, 'disconnected')\n\t\tthis.connections.delete(serverId)\n\t}\n\n\tprivate getReconnectDelay(connection: SyncConnection): number {\n\t\tconst exponentialDelay =\n\t\t\tconnection.retryDelay * Math.pow(2, Math.max(connection.reconnectAttempts - 1, 0))\n\t\treturn Math.min(exponentialDelay, MAX_RECONNECT_DELAY) + Math.random() * JITTER_MS\n\t}\n\n\tprivate updateLastEventId(connection: SyncConnection, id: string | undefined): void {\n\t\tif (id === undefined) return\n\t\tconnection.lastEventId = id || undefined\n\t}\n\n\tprivate intentToParam(intent: Archon.Sync.v1.SyncIntent): string {\n\t\treturn Array.isArray(intent) ? intent.join(',') : intent\n\t}\n\n\tprivate isAbortError(error: unknown): boolean {\n\t\tif (!(error instanceof Error)) return false\n\t\treturn error.name === 'AbortError' || error.message.toLowerCase().includes('abort')\n\t}\n}\n", "import type { Archon } from '../modules/archon/types'\n\nexport type ParsedSseEvent = {\n\tkind: 'event'\n\tid?: string\n\tevent?: string\n\tdata: string\n}\n\nexport type ParsedSseRetry = {\n\tkind: 'retry'\n\tretry: number\n}\n\nexport type ParsedSseItem = ParsedSseEvent | ParsedSseRetry\n\nexport class SseParser {\n\tprivate buffer = ''\n\tprivate eventName = ''\n\tprivate data = ''\n\tprivate id: string | undefined\n\n\tfeed(chunk: string): ParsedSseItem[] {\n\t\tthis.buffer += chunk\n\t\tconst items: ParsedSseItem[] = []\n\n\t\twhile (true) {\n\t\t\tconst lineEnd = this.findLineEnd()\n\t\t\tif (!lineEnd) break\n\n\t\t\tconst { line, length } = lineEnd\n\t\t\tthis.buffer = this.buffer.slice(length)\n\t\t\tthis.processLine(line, items)\n\t\t}\n\n\t\treturn items\n\t}\n\n\tend(): ParsedSseItem[] {\n\t\tconst items: ParsedSseItem[] = []\n\n\t\tif (this.buffer.length > 0) {\n\t\t\tthis.processLine(this.buffer.endsWith('\\r') ? this.buffer.slice(0, -1) : this.buffer, items)\n\t\t\tthis.buffer = ''\n\t\t}\n\n\t\tthis.dispatch(items)\n\t\treturn items\n\t}\n\n\tprivate findLineEnd(): { line: string; length: number } | null {\n\t\tconst lf = this.buffer.indexOf('\\n')\n\t\tconst cr = this.buffer.indexOf('\\r')\n\n\t\tif (lf === -1 && cr === -1) return null\n\n\t\tif (cr !== -1 && (lf === -1 || cr < lf)) {\n\t\t\tif (cr === this.buffer.length - 1) return null\n\t\t\tconst length = this.buffer[cr + 1] === '\\n' ? cr + 2 : cr + 1\n\t\t\treturn {\n\t\t\t\tline: this.buffer.slice(0, cr),\n\t\t\t\tlength,\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tline: this.buffer.slice(0, lf),\n\t\t\tlength: lf + 1,\n\t\t}\n\t}\n\n\tprivate processLine(line: string, items: ParsedSseItem[]): void {\n\t\tif (line === '') {\n\t\t\tthis.dispatch(items)\n\t\t\treturn\n\t\t}\n\n\t\tif (line.startsWith(':')) return\n\n\t\tconst colon = line.indexOf(':')\n\t\tconst field = colon === -1 ? line : line.slice(0, colon)\n\t\tlet value = colon === -1 ? '' : line.slice(colon + 1)\n\t\tif (value.startsWith(' ')) value = value.slice(1)\n\n\t\tswitch (field) {\n\t\t\tcase 'event':\n\t\t\t\tthis.eventName = value\n\t\t\t\tbreak\n\t\t\tcase 'data':\n\t\t\t\tthis.data += `${value}\\n`\n\t\t\t\tbreak\n\t\t\tcase 'id':\n\t\t\t\tthis.id = value\n\t\t\t\tbreak\n\t\t\tcase 'retry': {\n\t\t\t\tconst retry = Number(value)\n\t\t\t\tif (Number.isInteger(retry) && retry >= 0) {\n\t\t\t\t\titems.push({ kind: 'retry', retry })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate dispatch(items: ParsedSseItem[]): void {\n\t\tif (!this.data) {\n\t\t\tthis.eventName = ''\n\t\t\tthis.id = undefined\n\t\t\treturn\n\t\t}\n\n\t\titems.push({\n\t\t\tkind: 'event',\n\t\t\tid: this.id,\n\t\t\tevent: this.eventName || undefined,\n\t\t\tdata: this.data.endsWith('\\n') ? this.data.slice(0, -1) : this.data,\n\t\t})\n\n\t\tthis.eventName = ''\n\t\tthis.data = ''\n\t\tthis.id = undefined\n\t}\n}\n\nexport function parseSyncEventData(data: string): Archon.Sync.v1.SyncEvent | null {\n\tlet parsed: unknown\n\n\ttry {\n\t\tparsed = JSON.parse(data)\n\t} catch {\n\t\treturn null\n\t}\n\n\tif (!parsed || typeof parsed !== 'object') return null\n\tconst event = parsed as { type?: unknown }\n\tif (typeof event.type !== 'string') return null\n\n\treturn parsed as Archon.Sync.v1.SyncEvent\n}\n", "import mitt from 'mitt'\n\nimport { AbstractWebSocketClient, type WebSocketConnection } from '../core/abstract-websocket'\nimport type { Archon } from '../modules/archon/types'\nimport { getNodeWebSocketUrl } from '../utils/node-url'\n\ntype WSEventMap = {\n\t[K in Archon.Websocket.v0.WSEvent as `${string}:${K['event']}`]: K\n}\n\nconst NORMAL_CLOSURE = 1000\n\nexport class GenericWebSocketClient extends AbstractWebSocketClient {\n\tprotected emitter = mitt<WSEventMap>()\n\n\tasync connect(serverId: string, auth: Archon.Websocket.v0.WSAuth): Promise<void> {\n\t\tif (this.connections.has(serverId)) {\n\t\t\tthis.closeConnection(serverId)\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet settled = false\n\t\t\tlet authenticationTimeout: ReturnType<typeof setTimeout> | null = null\n\t\t\tconst resolveConnection = () => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tif (authenticationTimeout) clearTimeout(authenticationTimeout)\n\t\t\t\tresolve()\n\t\t\t}\n\t\t\tconst rejectConnection = (error: unknown) => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tif (authenticationTimeout) clearTimeout(authenticationTimeout)\n\t\t\t\treject(error)\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst ws = new WebSocket(getNodeWebSocketUrl(auth.url))\n\n\t\t\t\tconst connection: WebSocketConnection = {\n\t\t\t\t\tserverId,\n\t\t\t\t\tsocket: ws,\n\t\t\t\t\tauthenticated: false,\n\t\t\t\t\treconnectAttempts: 0,\n\t\t\t\t\treconnectTimer: undefined,\n\t\t\t\t\tisReconnecting: false,\n\t\t\t\t}\n\n\t\t\t\tthis.connections.set(serverId, connection)\n\t\t\t\tauthenticationTimeout = setTimeout(() => {\n\t\t\t\t\trejectConnection(new Error(`WebSocket authentication timed out for server ${serverId}`))\n\t\t\t\t\tif (this.connections.get(serverId) === connection) this.closeConnection(serverId)\n\t\t\t\t}, this.AUTHENTICATION_TIMEOUT)\n\n\t\t\t\tws.onopen = () => {\n\t\t\t\t\tws.send(JSON.stringify({ event: 'auth', jwt: auth.token }))\n\n\t\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\t\tconnection.isReconnecting = false\n\t\t\t\t}\n\n\t\t\t\tws.onmessage = (messageEvent) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(messageEvent.data) as Archon.Websocket.v0.WSEvent\n\t\t\t\t\t\tif (data.event === 'auth-ok') {\n\t\t\t\t\t\t\tconnection.authenticated = true\n\t\t\t\t\t\t} else if (data.event === 'auth-incorrect') {\n\t\t\t\t\t\t\tconnection.authenticated = false\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst eventKey = `${serverId}:${data.event}` as keyof WSEventMap\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t\tthis.emitter.emit(eventKey, data as any)\n\n\t\t\t\t\t\tif (data.event === 'auth-ok') resolveConnection()\n\n\t\t\t\t\t\tif (data.event === 'auth-expiring' || data.event === 'auth-incorrect') {\n\t\t\t\t\t\t\tthis.handleAuthExpiring(serverId).catch(console.error)\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error('[WebSocket] Failed to parse message:', error)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tws.onclose = (event) => {\n\t\t\t\t\tconnection.authenticated = false\n\t\t\t\t\tconsole.debug(`[WebSocket] Closed for server ${serverId}:`, {\n\t\t\t\t\t\tcode: event.code,\n\t\t\t\t\t\treason: event.reason,\n\t\t\t\t\t\twasClean: event.wasClean,\n\t\t\t\t\t})\n\t\t\t\t\trejectConnection(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`WebSocket closed before authentication for server ${serverId} (code: ${event.code})`,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tif (event.code !== NORMAL_CLOSURE) {\n\t\t\t\t\t\tthis.scheduleReconnect(serverId, auth)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tws.onerror = (event) => {\n\t\t\t\t\tconst url = ws.url\n\t\t\t\t\tconst readyState = ws.readyState\n\t\t\t\t\tconsole.error(`[WebSocket] Error for server ${serverId}:`, {\n\t\t\t\t\t\turl,\n\t\t\t\t\t\treadyState,\n\t\t\t\t\t\treadyStateLabel: ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'][readyState],\n\t\t\t\t\t\ttype: (event as Event).type,\n\t\t\t\t\t})\n\t\t\t\t\trejectConnection(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`WebSocket connection failed for server ${serverId} (readyState: ${readyState})`,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\trejectConnection(error)\n\t\t\t}\n\t\t})\n\t}\n\n\tdisconnect(serverId: string): void {\n\t\tthis.closeConnection(serverId)\n\n\t\tthis.emitter.all.forEach((_handlers, type) => {\n\t\t\tif (type.toString().startsWith(`${serverId}:`)) {\n\t\t\t\tthis.emitter.all.delete(type)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate closeConnection(serverId: string): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tif (connection.reconnectTimer) {\n\t\t\tclearTimeout(connection.reconnectTimer)\n\t\t\tconnection.reconnectTimer = undefined\n\t\t}\n\n\t\tif (\n\t\t\tconnection.socket.readyState === WebSocket.OPEN ||\n\t\t\tconnection.socket.readyState === WebSocket.CONNECTING\n\t\t) {\n\t\t\tconnection.socket.close(NORMAL_CLOSURE, 'Client disconnecting')\n\t\t}\n\n\t\tthis.connections.delete(serverId)\n\t}\n\n\tdisconnectAll(): void {\n\t\tfor (const serverId of this.connections.keys()) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n\n\tsend(serverId: string, message: Archon.Websocket.v0.WSOutgoingMessage): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection || connection.socket.readyState !== WebSocket.OPEN) {\n\t\t\tconsole.warn(`Cannot send message: WebSocket not connected for server ${serverId}`)\n\t\t\treturn\n\t\t}\n\t\tconnection.socket.send(JSON.stringify(message))\n\t}\n\n\tprivate scheduleReconnect(serverId: string, auth: Archon.Websocket.v0.WSAuth): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tif (connection.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {\n\t\t\tthis.disconnect(serverId)\n\t\t\treturn\n\t\t}\n\n\t\tconnection.isReconnecting = true\n\t\tconnection.reconnectAttempts++\n\n\t\tconst delay = this.getReconnectDelay(connection.reconnectAttempts)\n\n\t\tconnection.reconnectTimer = setTimeout(() => {\n\t\t\tthis.connect(serverId, auth).catch((error) => {\n\t\t\t\tconsole.error(`[WebSocket] Reconnection failed for server ${serverId}:`, error)\n\t\t\t})\n\t\t}, delay)\n\t}\n\n\tprivate async handleAuthExpiring(serverId: string): Promise<void> {\n\t\ttry {\n\t\t\tconst newAuth = await this.client.archon.servers_v0.getWebSocketAuth(serverId)\n\n\t\t\tconst connection = this.connections.get(serverId)\n\t\t\tif (connection && connection.socket.readyState === WebSocket.OPEN) {\n\t\t\t\tconnection.socket.send(JSON.stringify({ event: 'auth', jwt: newAuth.token }))\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`[WebSocket] Failed to refresh auth for server ${serverId}:`, error)\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n}\n", "import { AbstractModrinthClient } from '../core/abstract-client'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\nimport type {\n\tUploadHandle,\n\tUploadMetadata,\n\tUploadProgress,\n\tUploadRequestOptions,\n} from '../types/upload'\n\n/**\n * Abstract client with XHR-based upload implementation\n *\n * Platform-specific clients should extend this instead of AbstractModrinthClient\n * to inherit the XHR upload implementation.\n */\nexport abstract class XHRUploadClient extends AbstractModrinthClient {\n\tupload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\n\t\tconst progressCallbacks: Array<(p: UploadProgress) => void> = []\n\t\tif (options.onProgress) {\n\t\t\tprogressCallbacks.push(options.onProgress)\n\t\t}\n\t\tconst abortController = new AbortController()\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener('abort', () => abortController.abort())\n\t\t}\n\n\t\tlet context: RequestContext | undefined\n\t\tconst handle: UploadHandle<T> = {\n\t\t\tpromise: (async () => {\n\t\t\t\tconst isFormData = 'formData' in options && options.formData instanceof FormData\n\t\t\t\tconst baseHeaders = await this.buildDefaultHeaders()\n\t\t\t\tif (isFormData) {\n\t\t\t\t\tdelete baseHeaders['Content-Type']\n\t\t\t\t} else {\n\t\t\t\t\tbaseHeaders['Content-Type'] = 'application/octet-stream'\n\t\t\t\t}\n\n\t\t\t\tconst mergedOptions: UploadRequestOptions = {\n\t\t\t\t\tretry: false,\n\t\t\t\t\t...options,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t...baseHeaders,\n\t\t\t\t\t\t...options.headers,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\t\t\tconst uploadContext = this.buildUploadContext(url, path, mergedOptions)\n\t\t\t\tcontext = uploadContext\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\tthrow new ModrinthApiError('Upload cancelled')\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.executeUploadFeatureChain<T>(\n\t\t\t\t\tuploadContext,\n\t\t\t\t\tprogressCallbacks,\n\t\t\t\t\tabortController,\n\t\t\t\t)\n\t\t\t\tawait this.config.hooks?.onResponse?.(result, uploadContext)\n\t\t\t\treturn result\n\t\t\t})().catch(async (error) => {\n\t\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\t\tif (context) {\n\t\t\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\t\t\t\t}\n\t\t\t\tthrow apiError\n\t\t\t}),\n\t\t\tonProgress: (callback) => {\n\t\t\t\tprogressCallbacks.push(callback)\n\t\t\t\treturn handle\n\t\t\t},\n\t\t\tcancel: () => abortController.abort(),\n\t\t}\n\n\t\treturn handle\n\t}\n\n\tprotected executeXHRUpload<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T> {\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst xhr = new XMLHttpRequest()\n\t\t\tconst metadata = context.metadata as UploadMetadata\n\n\t\t\txhr.upload.addEventListener('progress', (e) => {\n\t\t\t\tif (e.lengthComputable) {\n\t\t\t\t\tconst progress: UploadProgress = {\n\t\t\t\t\t\tloaded: e.loaded,\n\t\t\t\t\t\ttotal: e.total,\n\t\t\t\t\t\tprogress: e.loaded / e.total,\n\t\t\t\t\t}\n\t\t\t\t\tprogressCallbacks.forEach((cb) => cb(progress))\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txhr.addEventListener('load', () => {\n\t\t\t\tif (xhr.status >= 200 && xhr.status < 300) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresolve(xhr.response ? JSON.parse(xhr.response) : (undefined as T))\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tresolve(undefined as T)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treject(this.createUploadError(xhr))\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txhr.addEventListener('error', () => reject(new ModrinthApiError('Upload failed')))\n\t\t\txhr.addEventListener('abort', () => reject(new ModrinthApiError('Upload cancelled')))\n\t\t\txhr.addEventListener('timeout', () => reject(new ModrinthApiError('Upload timed out')))\n\n\t\t\tif (context.options.timeout !== undefined) {\n\t\t\t\txhr.timeout = context.options.timeout\n\t\t\t}\n\n\t\t\t// build URL with params (unlike $fetch, XHR doesn't handle params automatically)\n\t\t\tlet url = context.url\n\t\t\tif (context.options.params) {\n\t\t\t\tconst queryString = new URLSearchParams(\n\t\t\t\t\tObject.entries(context.options.params).map(([k, v]) => [k, String(v)]),\n\t\t\t\t).toString()\n\t\t\t\turl += (url.includes('?') ? '&' : '?') + queryString\n\t\t\t}\n\n\t\t\txhr.open('POST', url)\n\n\t\t\t// apply headers from context (features may have modified them)\n\t\t\tfor (const [key, value] of Object.entries(context.options.headers ?? {})) {\n\t\t\t\txhr.setRequestHeader(key, value)\n\t\t\t}\n\n\t\t\t// Send either FormData or file depending on what was provided\n\t\t\tconst data = 'formData' in metadata ? metadata.formData : metadata.file\n\t\t\txhr.send(data)\n\t\t\tabortController.signal.addEventListener('abort', () => xhr.abort())\n\t\t})\n\t}\n\n\tprotected createUploadError(xhr: XMLHttpRequest): ModrinthApiError {\n\t\tlet responseData: unknown\n\t\ttry {\n\t\t\tresponseData = xhr.response ? JSON.parse(xhr.response) : undefined\n\t\t} catch {\n\t\t\tresponseData = xhr.responseText\n\t\t}\n\t\treturn this.createNormalizedError(\n\t\t\tnew Error(`Upload failed with status ${xhr.status}`),\n\t\t\txhr.status,\n\t\t\tresponseData,\n\t\t)\n\t}\n}\n", "import { FetchError } from 'ofetch'\n\nimport { ModrinthApiError } from '../core/errors'\nimport type { CircuitBreakerState, CircuitBreakerStorage } from '../features/circuit-breaker'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport type { UploadHandle, UploadRequestOptions } from '../types/upload'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Circuit breaker storage using Nuxt's useState\n *\n * This provides cross-request persistence in SSR while also working in client-side.\n * State is shared between requests in the same Nuxt context.\n *\n * Note: useState must be called during initialization (in setup context) and cached,\n * as it won't work during async operations when the Nuxt context may be lost.\n */\nexport class NuxtCircuitBreakerStorage implements CircuitBreakerStorage {\n\tprivate state: Map<string, CircuitBreakerState>\n\n\tconstructor() {\n\t\t// @ts-expect-error - useState is provided by Nuxt runtime\n\t\tconst stateRef = useState<Map<string, CircuitBreakerState>>(\n\t\t\t'circuit-breaker-state',\n\t\t\t() => new Map(),\n\t\t)\n\t\tthis.state = stateRef.value\n\t}\n\n\tget(key: string): CircuitBreakerState | undefined {\n\t\treturn this.state.get(key)\n\t}\n\n\tset(key: string, state: CircuitBreakerState): void {\n\t\tthis.state.set(key, state)\n\t}\n\n\tclear(key: string): void {\n\t\tthis.state.delete(key)\n\t}\n}\n\n/**\n * Nuxt-specific configuration\n */\nexport interface NuxtClientConfig extends ClientConfig {\n\t// TODO: do we want to provide this for tauri+base as well? its not used on app\n\t/**\n\t * Rate limit key for server-side requests.\n\t * This is injected as x-ratelimit-key header on server-side.\n\t * Can be a string (for env var) or async function (for CF Secrets Store).\n\t */\n\trateLimitKey?: string | (() => Promise<string | undefined>)\n}\n\n/**\n * Nuxt platform client using Nuxt's $fetch\n *\n * This client is optimized for Nuxt applications and handles SSR/CSR automatically.\n *\n * Note: upload() is only available in browser context (CSR). It will throw during SSR.\n *\n * @example\n * ```typescript\n * // In a Nuxt composable\n * const config = useRuntimeConfig()\n *\n * const client = new NuxtModrinthClient({\n * userAgent: 'my-nuxt-app/1.0.0',\n * rateLimitKey: import.meta.server ? config.rateLimitKey : undefined,\n * features: [\n * new AuthFeature({\n * token: async () => getOAuthToken()\n * }),\n * new CircuitBreakerFeature({\n * storage: new NuxtCircuitBreakerStorage()\n * })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class NuxtModrinthClient extends XHRUploadClient {\n\tdeclare protected config: NuxtClientConfig\n\tprivate rateLimitKeyResolved: string | undefined\n\tprivate rateLimitKeyPromise: Promise<string | undefined> | undefined\n\n\tconstructor(config: NuxtClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\t/**\n\t * Resolve the rate limit key, handling both string and async function values.\n\t * Results are cached for subsequent calls.\n\t */\n\tprivate async resolveRateLimitKey(): Promise<string | undefined> {\n\t\tif (this.rateLimitKeyResolved !== undefined) {\n\t\t\treturn this.rateLimitKeyResolved\n\t\t}\n\n\t\tconst key = this.config.rateLimitKey\n\t\tif (typeof key === 'string') {\n\t\t\tthis.rateLimitKeyResolved = key\n\t\t} else if (typeof key === 'function') {\n\t\t\tif (!this.rateLimitKeyPromise) {\n\t\t\t\tthis.rateLimitKeyPromise = key()\n\t\t\t}\n\t\t\tthis.rateLimitKeyResolved = await this.rateLimitKeyPromise\n\t\t}\n\n\t\treturn this.rateLimitKeyResolved\n\t}\n\n\t/**\n\t * Override request to resolve rate limit key before calling super.\n\t * This allows async fetching of the key from CF Secrets Store.\n\t */\n\tasync request<T>(path: string, options: RequestOptions): Promise<T> {\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server) {\n\t\t\tawait this.resolveRateLimitKey()\n\t\t}\n\t\treturn super.request(path, options)\n\t}\n\n\t/**\n\t * Upload a file with progress tracking\n\t *\n\t * Note: This method is only available in browser context (CSR).\n\t * Calling during SSR will throw an error.\n\t */\n\tupload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T> {\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server) {\n\t\t\tthrow new ModrinthApiError('upload() is not supported during SSR')\n\t\t}\n\t\treturn super.upload(path, options)\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\t// @ts-expect-error - $fetch is provided by Nuxt\n\t\t\tconst response = await $fetch<T>(url, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: options.body,\n\t\t\t\tparams: options.params,\n\t\t\t\ttimeout: options.timeout,\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\t\t\tcache: import.meta.server ? undefined : 'no-store',\n\t\t\t})\n\n\t\t\treturn response\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst response = await fetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\t\t\tcache: import.meta.server ? undefined : 'no-store',\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new ModrinthApiError('Streaming response has no readable body', {\n\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof FetchError) {\n\t\t\treturn this.createNormalizedError(error, error.response?.status, error.data)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n\n\tprotected async buildDefaultHeaders(): Promise<Record<string, string>> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t...(await super.buildDefaultHeaders()),\n\t\t}\n\n\t\t// Use the resolved key (populated by resolveRateLimitKey in request())\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server && this.rateLimitKeyResolved) {\n\t\t\theaders['x-ratelimit-key'] = this.rateLimitKeyResolved\n\t\t}\n\n\t\treturn headers\n\t}\n}\n", "import type { ModrinthApiError } from '../core/errors'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Tauri-specific configuration\n * TODO: extend into interface if needed.\n */\nexport type TauriClientConfig = ClientConfig\n\n/**\n * Extended error type with HTTP response metadata\n */\ninterface HttpError extends Error {\n\tstatusCode?: number\n\tresponseData?: unknown\n}\n\n/**\n * Tauri platform client using Tauri v2 HTTP plugin\n *\n * Extends XHRUploadClient to provide upload with progress tracking.\n *\n * @example\n * ```typescript\n * import { getVersion } from '@tauri-apps/api/app'\n *\n * const client = new TauriModrinthClient({\n * userAgent: async () => `modrinth/theseus/${await getVersion()} (support@modrinth.com)`,\n * features: [\n * new AuthFeature({ token: async () => getOAuthToken() })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class TauriModrinthClient extends XHRUploadClient {\n\tdeclare protected config: TauriClientConfig\n\n\tconstructor(config: TauriClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\t// Dynamically import Tauri HTTP plugin\n\t\t\t// This allows the package to be used in non-Tauri environments\n\t\t\tconst { fetch: tauriFetch } = await import('@tauri-apps/plugin-http')\n\n\t\t\tconst body = toFetchBody(options.body)\n\t\t\tconst fullUrl = appendRequestParams(url, options.params)\n\n\t\t\tconst response = await tauriFetch(fullUrl, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet responseData: unknown\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json()\n\t\t\t\t} catch {\n\t\t\t\t\tresponseData = undefined\n\t\t\t\t}\n\n\t\t\t\tconst error = new Error(`HTTP ${response.status}: ${response.statusText}`) as HttpError\n\n\t\t\t\terror.statusCode = response.status\n\t\t\t\terror.responseData = responseData\n\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\t// Handle binary downloads (e.g. kyros fs files) before JSON parsing.\n\t\t\tconst contentType = response.headers.get('content-type')?.toLowerCase() ?? ''\n\t\t\tif (fullUrl.includes('/fs/download')) {\n\t\t\t\treturn (await response.blob()) as T\n\t\t\t}\n\t\t\tif (\n\t\t\t\tcontentType.startsWith('image/') ||\n\t\t\t\tcontentType.startsWith('audio/') ||\n\t\t\t\tcontentType.startsWith('video/') ||\n\t\t\t\tcontentType.includes('application/octet-stream')\n\t\t\t) {\n\t\t\t\treturn (await response.blob()) as T\n\t\t\t}\n\n\t\t\tif (response.status === 204 || response.status === 205) {\n\t\t\t\treturn undefined as T\n\t\t\t}\n\n\t\t\tif (contentType.includes('application/json') || contentType.includes('+json')) {\n\t\t\t\treturn (await response.json()) as T\n\t\t\t}\n\n\t\t\tconst text = await response.text()\n\t\t\tif (!text) {\n\t\t\t\treturn undefined as T\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(text) as T\n\t\t\t} catch {\n\t\t\t\treturn text as T\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst { fetch: tauriFetch } = await import('@tauri-apps/plugin-http')\n\t\t\tconst response = await tauriFetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error('Streaming response has no readable body'),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tundefined,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof Error) {\n\t\t\tconst httpError = error as HttpError\n\t\t\tconst statusCode = httpError.statusCode\n\t\t\tconst responseData = httpError.responseData\n\n\t\t\treturn this.createNormalizedError(error, statusCode, responseData)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n}\n", "import type { NodeAuth } from '../features/node-auth'\n\n/**\n * Global node auth state.\n * Set by server management pages, read by NodeAuthFeature.\n */\nexport const nodeAuthState = {\n\tgetAuth: null as (() => NodeAuth | null) | null,\n\trefreshAuth: null as (() => Promise<void>) | null,\n}\n\n/**\n * Configure the node auth state. Call this when entering server management.\n *\n * @param getAuth - Function that returns current auth or null\n * @param refreshAuth - Function to refresh the auth token\n *\n * @example\n * ```typescript\n * // In server management page setup\n * setNodeAuthState(\n * () => fsAuth.value,\n * refreshFsAuth,\n * )\n * ```\n */\nexport function setNodeAuthState(getAuth: () => NodeAuth | null, refreshAuth: () => Promise<void>) {\n\tnodeAuthState.getAuth = getAuth\n\tnodeAuthState.refreshAuth = refreshAuth\n}\n\n/**\n * Clear the node auth state. Call this when leaving server management.\n *\n * @example\n * ```typescript\n * onUnmounted(() => {\n * clearNodeAuthState()\n * })\n * ```\n */\nexport function clearNodeAuthState() {\n\tnodeAuthState.getAuth = null\n\tnodeAuthState.refreshAuth = null\n}\n", "import { ModrinthApiError } from '../core/errors'\n\n/**\n * Wrap a function with JWT retry logic.\n * On 401, calls refreshToken() and retries once.\n */\nexport async function withJWTRetry<T>(\n\tfn: () => Promise<T>,\n\trefreshToken: () => Promise<void>,\n): Promise<T> {\n\ttry {\n\t\treturn await fn()\n\t} catch (error) {\n\t\tif (error instanceof ModrinthApiError && error.statusCode === 401) {\n\t\t\tawait refreshToken()\n\t\t\treturn await fn()\n\t\t}\n\t\tthrow error\n\t}\n}\n", "export interface WebSocketPingOptions {\n\tcount?: number\n\tintervalMs?: number\n\tsettleDelayMs?: number\n\ttimeoutMs?: number\n\tsignal?: AbortSignal\n}\n\nexport async function pingWebSocketUrl(\n\turl: string,\n\toptions: WebSocketPingOptions = {},\n): Promise<number> {\n\tconst count = options.count ?? 5\n\tconst intervalMs = options.intervalMs ?? 200\n\tconst settleDelayMs = options.settleDelayMs ?? 1000\n\tconst timeoutMs = options.timeoutMs ?? count * intervalMs + settleDelayMs + 1000\n\n\tif (options.signal?.aborted) return -1\n\n\treturn await new Promise<number>((resolve) => {\n\t\tconst samples: number[] = []\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>()\n\t\tlet socket: WebSocket | undefined\n\t\tlet settled = false\n\n\t\tconst setTrackedTimeout = (callback: () => void, ms: number) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer)\n\t\t\t\tcallback()\n\t\t\t}, ms)\n\t\t\ttimers.add(timer)\n\t\t\treturn timer\n\t\t}\n\n\t\tconst cleanup = () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer)\n\t\t\ttimers.clear()\n\t\t\toptions.signal?.removeEventListener('abort', abort)\n\n\t\t\tif (\n\t\t\t\tsocket &&\n\t\t\t\t(socket.readyState === WebSocket.CONNECTING || socket.readyState === WebSocket.OPEN)\n\t\t\t) {\n\t\t\t\tsocket.close()\n\t\t\t}\n\t\t}\n\n\t\tconst finish = (ping: number) => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tcleanup()\n\t\t\tresolve(ping)\n\t\t}\n\n\t\tconst abort = () => finish(-1)\n\t\toptions.signal?.addEventListener('abort', abort, { once: true })\n\n\t\ttry {\n\t\t\tsocket = new WebSocket(url)\n\t\t} catch {\n\t\t\tfinish(-1)\n\t\t\treturn\n\t\t}\n\n\t\tsetTrackedTimeout(() => finish(-1), timeoutMs)\n\n\t\tsocket.onopen = () => {\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tsetTrackedTimeout(() => {\n\t\t\t\t\tif (socket?.readyState === WebSocket.OPEN) {\n\t\t\t\t\t\tsocket.send(String(performance.now()))\n\t\t\t\t\t}\n\t\t\t\t}, i * intervalMs)\n\t\t\t}\n\n\t\t\tsetTrackedTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tconst ping =\n\t\t\t\t\t\tsamples.length > 0\n\t\t\t\t\t\t\t? Math.round([...samples].sort((a, b) => a - b)[Math.floor(samples.length / 2)])\n\t\t\t\t\t\t\t: -1\n\t\t\t\t\tfinish(ping)\n\t\t\t\t},\n\t\t\t\tcount * intervalMs + settleDelayMs,\n\t\t\t)\n\t\t}\n\n\t\tsocket.onmessage = (event) => {\n\t\t\tsamples.push(performance.now() - Number(event.data))\n\t\t}\n\n\t\tsocket.onerror = () => finish(-1)\n\t\tsocket.onclose = () => {\n\t\t\tif (!settled && samples.length === 0) finish(-1)\n\t\t}\n\t})\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { AbstractModrinthClient } from './abstract-client'\n\nexport abstract class AbstractModule {\n\tprotected client: AbstractModrinthClient\n\n\tpublic constructor(client: AbstractModrinthClient) {\n\t\tthis.client = client\n\t}\n\n\t/**\n\t * Get the module's name, used for error reporting & for module field generation.\n\t * @returns Module name\n\t */\n\tpublic abstract getModuleID(): string\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonActionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_actions_v1'\n\t}\n\n\t/**\n\t * Get server action log entries.\n\t * GET /v1/servers/:server_id/action-log\n\t */\n\tpublic async list(\n\t\tserverId: string,\n\t\toptions: Archon.Actions.v1.ListActionLogOptions = {},\n\t): Promise<Archon.Actions.v1.ActionLogResponse> {\n\t\tconst params: Record<string, string | number> = {}\n\t\tif (options.filter) params.filter = JSON.stringify(options.filter)\n\t\tif (options.limit !== undefined) params.limit = options.limit\n\t\tif (options.offset !== undefined) params.offset = options.offset\n\t\tif (options.order !== undefined) params.order = options.order\n\t\tif (options.min_datetime !== undefined) params.min_datetime = options.min_datetime\n\t\tif (options.max_datetime !== undefined) params.max_datetime = options.max_datetime\n\n\t\treturn this.client.request<Archon.Actions.v1.ActionLogResponse>(\n\t\t\t`/servers/${serverId}/action-log`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\n/**\n * @deprecated Use `client.archon.backups_queue_v1` (Backups Queue API) instead.\n */\nexport class ArchonBackupsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_backups_v1'\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.list` instead.\n\t */\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups */\n\tpublic async list(serverId: string, worldId: string): Promise<Archon.Backups.v1.Backup[]> {\n\t\treturn this.client.request<Archon.Backups.v1.Backup[]>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.list` instead.\n\t */\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async get(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t): Promise<Archon.Backups.v1.Backup> {\n\t\treturn this.client.request<Archon.Backups.v1.Backup>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.create` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups */\n\tpublic async create(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Backups.v1.BackupRequest,\n\t): Promise<Archon.Backups.v1.PostBackupResponse> {\n\t\treturn this.client.request<Archon.Backups.v1.PostBackupResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.restore` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/restore */\n\tpublic async restore(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}/restore`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.delete` for backup deletion, or\n\t * `client.archon.backups_queue_v1.cancelCreate` / `cancelRestore` for active operations.\n\t */\n\t/** DELETE /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async delete(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * @deprecated Use `client.archon.backups_queue_v1.retry` instead.\n\t */\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups/:backup_id/retry */\n\tpublic async retry(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups/${backupId}/retry`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * @deprecated Legacy backups only; no queue equivalent. Prefer renaming via other supported flows if available.\n\t */\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/backups/:backup_id */\n\tpublic async rename(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t\trequest: Archon.Backups.v1.PatchBackup,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/backups/${backupId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonBackupsQueueV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_backups_queue_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/backups-queue */\n\tpublic async list(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.BackupsQueue.v1.BackupsQueueResponse> {\n\t\treturn this.client.request<Archon.BackupsQueue.v1.BackupsQueueResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue`,\n\t\t\t{ api: 'archon', version: 1, method: 'GET' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue */\n\tpublic async create(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.BackupsQueue.v1.BackupRequest,\n\t): Promise<Archon.BackupsQueue.v1.PostBackupQueueResponse> {\n\t\treturn this.client.request<Archon.BackupsQueue.v1.PostBackupQueueResponse>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/ack */\n\tpublic async ackCreate(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/ack`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/create/:operation_id/cancel */\n\tpublic async cancelCreate(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/create/${operationId}/cancel`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/ack */\n\tpublic async ackRestore(serverId: string, worldId: string, operationId: number): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/ack`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/history/restore/:operation_id/cancel */\n\tpublic async cancelRestore(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\toperationId: number,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/history/restore/${operationId}/cancel`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n\n\t/** DELETE /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id */\n\tpublic async delete(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/delete-many */\n\tpublic async deleteMany(serverId: string, worldId: string, backupIds: string[]): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/delete-many`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: { backup_ids: backupIds } satisfies Archon.BackupsQueue.v1.DeleteManyBackupRequest,\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/restore */\n\tpublic async restore(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbackupId: string,\n\t\trequest: Archon.BackupsQueue.v1.BackupRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/restore`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST', body: request },\n\t\t)\n\t}\n\n\t/** POST /v1/servers/:server_id/worlds/:world_id/backups-queue/:backup_id/retry */\n\tpublic async retry(serverId: string, worldId: string, backupId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/backups-queue/${backupId}/retry`,\n\t\t\t{ api: 'archon', version: 1, method: 'POST' },\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonContentV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_content_v1'\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/addons */\n\tpublic async getAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\toptions?: {\n\t\t\tfrom_modpack?: boolean\n\t\t\tdisabled?: boolean\n\t\t\taddons?: boolean\n\t\t\tupdates?: boolean\n\t\t},\n\t): Promise<Archon.Content.v1.Addons> {\n\t\tconst params = new URLSearchParams()\n\t\tif (options?.from_modpack !== undefined)\n\t\t\tparams.set('from_modpack', String(options.from_modpack))\n\t\tif (options?.disabled !== undefined) params.set('disabled', String(options.disabled))\n\t\tif (options?.addons !== undefined) params.set('addons', String(options.addons))\n\t\tif (options?.updates !== undefined) params.set('updates', String(options.updates))\n\t\tconst query = params.toString()\n\n\t\treturn this.client.request<Archon.Content.v1.Addons>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/addons${query ? `?${query}` : ''}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons */\n\tpublic async addAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.AddAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/install-many */\n\tpublic async addAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\taddons: Archon.Content.v1.AddAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/install-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: addons satisfies Archon.Content.v1.AddAddonsRequest,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/delete */\n\tpublic async deleteAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/delete`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/disable */\n\tpublic async disableAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/disable`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/enable */\n\tpublic async enableAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.RemoveAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/enable`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/delete-many */\n\tpublic async deleteAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/delete-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/disable-many */\n\tpublic async disableAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/disable-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/enable-many */\n\tpublic async enableAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\titems: Archon.Content.v1.RemoveAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/enable-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { items },\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content */\n\tpublic async installContent(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.InstallWorldContent,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/content`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/repair */\n\tpublic async repair(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/content/repair`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/unlink-modpack */\n\tpublic async unlinkModpack(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/unlink-modpack`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/addons/update?filename=... */\n\tpublic async getAddonUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tfilename: string,\n\t): Promise<Archon.Content.v1.Addon> {\n\t\treturn this.client.request<Archon.Content.v1.Addon>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/addons/update?filename=${encodeURIComponent(filename)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/update */\n\tpublic async updateAddon(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\trequest: Archon.Content.v1.UpdateAddonRequest,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/update`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/addons/update-many */\n\tpublic async updateAddons(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\taddons: Archon.Content.v1.UpdateAddonRequest[],\n\t): Promise<void> {\n\t\tawait this.client.request<void>(`/servers/${serverId}/worlds/${worldId}/addons/update-many`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: { addons },\n\t\t})\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/content/modpack/update */\n\tpublic async getModpackUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.ModpackFields> {\n\t\treturn this.client.request<Archon.Content.v1.ModpackFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/modpack/update`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/modpack/update */\n\tpublic async updateModpack(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/modpack/update`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** GET /v1/:server_id/worlds/:world_id/content/update-game-version?game_version=... */\n\tpublic async getUpdateGameVersionPreview(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tgameVersion: string,\n\t\tsignal?: AbortSignal,\n\t): Promise<Archon.Content.v1.UpdateGameVersionPreview> {\n\t\treturn this.client.request<Archon.Content.v1.UpdateGameVersionPreview>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/update-game-version?game_version=${encodeURIComponent(gameVersion)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\ttimeout: 1000 * 1000,\n\t\t\t\tsignal,\n\t\t\t},\n\t\t)\n\t}\n\n\t/** POST /v1/:server_id/worlds/:world_id/content/update-game-version?game_version=... */\n\tpublic async applyGameVersionUpdate(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tgameVersion: string,\n\t): Promise<void> {\n\t\tawait this.client.request<void>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/content/update-game-version?game_version=${encodeURIComponent(gameVersion)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonNodesInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_nodes_internal'\n\t}\n\n\t/**\n\t * Get node hostnames and region summary for admin tooling.\n\t * GET /_internal/nodes/overview\n\t */\n\tpublic async overview(): Promise<Archon.Nodes.Internal.Overview> {\n\t\treturn this.client.request<Archon.Nodes.Internal.Overview>('/nodes/overview', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonNoticesV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_notices_v0'\n\t}\n\n\t/**\n\t * Get all server notices.\n\t * GET /modrinth/v0/notices\n\t */\n\tpublic async list(): Promise<Archon.Notices.v0.ListedNotice[]> {\n\t\treturn this.client.request<Archon.Notices.v0.ListedNotice[]>('/notices', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a server notice.\n\t * POST /modrinth/v0/notices\n\t */\n\tpublic async create(\n\t\trequest: Archon.Notices.v0.Announce,\n\t): Promise<Archon.Notices.v0.PostNoticeResponseBody> {\n\t\treturn this.client.request<Archon.Notices.v0.PostNoticeResponseBody>('/notices', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Update a server notice.\n\t * PATCH /modrinth/v0/notices/:id\n\t */\n\tpublic async update(id: number, request: Archon.Notices.v0.AnnouncePatch): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a server notice.\n\t * DELETE /modrinth/v0/notices/:id\n\t */\n\tpublic async delete(id: number): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Assign a notice to a server or node.\n\t * PUT /modrinth/v0/notices/:id/assign?server=:serverId\n\t * PUT /modrinth/v0/notices/:id/assign?node=:nodeId\n\t */\n\tpublic async assign(id: number, target: Archon.Notices.v0.AssignmentTarget): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}/assign`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: this.assignmentTargetToParams(target),\n\t\t})\n\t}\n\n\t/**\n\t * Unassign a notice from a server or node.\n\t * PUT /modrinth/v0/notices/:id/unassign?server=:serverId\n\t * PUT /modrinth/v0/notices/:id/unassign?node=:nodeId\n\t */\n\tpublic async unassign(id: number, target: Archon.Notices.v0.AssignmentTarget): Promise<void> {\n\t\tawait this.client.request(`/notices/${id}/unassign`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: this.assignmentTargetToParams(target),\n\t\t})\n\t}\n\n\tprivate assignmentTargetToParams(\n\t\ttarget: Archon.Notices.v0.AssignmentTarget,\n\t): Record<string, string> {\n\t\tif ('server' in target) {\n\t\t\treturn { server: target.server }\n\t\t}\n\n\t\treturn { node: target.node }\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonOptionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_options_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/options/startup */\n\tpublic async getStartup(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.RuntimeOptions> {\n\t\treturn this.client.request<Archon.Content.v1.RuntimeOptions>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/options/startup`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/options/startup */\n\tpublic async patchStartup(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbody: Archon.Content.v1.PatchRuntimeOptions,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/worlds/${worldId}/options/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonPropertiesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_properties_v1'\n\t}\n\n\t/** GET /v1/servers/:server_id/worlds/:world_id/properties */\n\tpublic async getProperties(\n\t\tserverId: string,\n\t\tworldId: string,\n\t): Promise<Archon.Content.v1.PropertiesFields> {\n\t\treturn this.client.request<Archon.Content.v1.PropertiesFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/properties`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/** PATCH /v1/servers/:server_id/worlds/:world_id/properties */\n\tpublic async patchProperties(\n\t\tserverId: string,\n\t\tworldId: string,\n\t\tbody: Archon.Content.v1.PatchPropertiesFields,\n\t): Promise<Archon.Content.v1.PropertiesFields> {\n\t\treturn this.client.request<Archon.Content.v1.PropertiesFields>(\n\t\t\t`/servers/${serverId}/worlds/${worldId}/properties`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServerUsersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_server_users_v1'\n\t}\n\n\t/**\n\t * Get list of users with access to a server\n\t * GET /v1/servers/:server_id/users\n\t */\n\tpublic async list(serverId: string): Promise<Archon.ServerUsers.v1.ServerUser[]> {\n\t\treturn this.client.request<Archon.ServerUsers.v1.ServerUser[]>(`/servers/${serverId}/users`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Add a user to a server\n\t * POST /v1/servers/:server_id/users\n\t */\n\tpublic async add(\n\t\tserverId: string,\n\t\tuser: Archon.ServerUsers.v1.AddServerUserRequest,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: user,\n\t\t})\n\t}\n\n\t/**\n\t * Re-send an invite to a pending server user.\n\t * POST /v1/servers/:server_id/users/:user_id/reinvite\n\t */\n\tpublic async reinvite(\n\t\tserverId: string,\n\t\tuserId: string,\n\t): Promise<Archon.ServerUsers.v1.ReinviteResponse> {\n\t\treturn this.client.request<Archon.ServerUsers.v1.ReinviteResponse>(\n\t\t\t`/servers/${serverId}/users/${userId}/reinvite`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Remove a user from a server\n\t * DELETE /v1/servers/:server_id/users/:user_id\n\t */\n\tpublic async delete(serverId: string, userId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users/${userId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update a user's server role\n\t * PATCH /v1/servers/:server_id/users/:user_id\n\t */\n\tpublic async update(\n\t\tserverId: string,\n\t\tuserId: string,\n\t\trole: Archon.ServerUsers.v1.AssignableServerUserRole,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/users/${userId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: JSON.stringify(role),\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_internal'\n\t}\n\n\t/**\n\t * Get the server assigned to a subdomain.\n\t * GET /_internal/servers/by-subdomain/:subdomain\n\t */\n\tpublic async getBySubdomain(subdomain: string): Promise<Archon.Servers.Internal.Lookup> {\n\t\treturn this.client.request<Archon.Servers.Internal.Lookup>(\n\t\t\t`/servers/by-subdomain/${encodeURIComponent(subdomain)}`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Archon } from '../types'\n\nexport class ArchonServersV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_v0'\n\t}\n\n\t/**\n\t * Get a specific server by ID\n\t * GET /modrinth/v0/servers/:id\n\t */\n\tpublic async get(serverId: string): Promise<Archon.Servers.v0.Server> {\n\t\treturn this.client.request<Archon.Servers.v0.Server>(`/servers/${serverId}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Get list of servers for the authenticated user\n\t * GET /modrinth/v0/servers\n\t */\n\tpublic async list(\n\t\toptions?: Archon.Servers.v0.GetServersOptions,\n\t): Promise<Archon.Servers.v0.ServerGetResponse> {\n\t\tconst params = new URLSearchParams()\n\t\tif (options?.limit) params.set('limit', options.limit.toString())\n\t\tif (options?.offset) params.set('offset', options.offset.toString())\n\n\t\tconst query = params.toString() ? `?${params.toString()}` : ''\n\n\t\treturn this.client.request<Archon.Servers.v0.ServerGetResponse>(`servers${query}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Check stock availability for a region\n\t * POST /modrinth/v0/stock?region=:region\n\t */\n\tpublic async checkStock(\n\t\tregion: string,\n\t\trequest: Archon.Servers.v0.StockRequest,\n\t): Promise<Archon.Servers.v0.StockResponse> {\n\t\treturn this.client.request<Archon.Servers.v0.StockResponse>(`/stock?region=${region}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Check stock availability (without region filter)\n\t * POST /modrinth/v0/stock\n\t */\n\tpublic async checkStockGlobal(\n\t\trequest: Archon.Servers.v0.StockRequest,\n\t): Promise<Archon.Servers.v0.StockResponse> {\n\t\treturn this.client.request<Archon.Servers.v0.StockResponse>('/stock', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get filesystem authentication credentials for a server\n\t * Returns URL and JWT token for accessing the server's filesystem via Kyros\n\t * GET /modrinth/v0/servers/:id/fs\n\t */\n\tpublic async getFilesystemAuth(serverId: string): Promise<Archon.Servers.v0.JWTAuth> {\n\t\treturn this.client.request<Archon.Servers.v0.JWTAuth>(`/servers/${serverId}/fs`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get WebSocket authentication credentials for a server\n\t * GET /modrinth/v0/servers/:id/ws\n\t */\n\tpublic async getWebSocketAuth(serverId: string): Promise<Archon.Websocket.v0.WSAuth> {\n\t\treturn this.client.request<Archon.Websocket.v0.WSAuth>(`/servers/${serverId}/ws`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Send a power action to a server (Start, Stop, Restart, Kill)\n\t * POST /modrinth/v0/servers/:id/power\n\t */\n\tpublic async power(\n\t\tserverId: string,\n\t\taction: 'Start' | 'Stop' | 'Restart' | 'Kill',\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/power`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { action },\n\t\t})\n\t}\n\n\t/**\n\t * Reinstall a server with a new loader or modpack\n\t * POST /modrinth/v0/servers/:id/reinstall\n\t */\n\tpublic async reinstall(\n\t\tserverId: string,\n\t\trequest: Archon.Servers.v0.ReinstallRequest,\n\t\thardReset: boolean = false,\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/reinstall`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { hard: String(hardReset) },\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Get authentication credentials for .mrpack file upload\n\t * GET /modrinth/v0/servers/:id/reinstallFromMrpack\n\t */\n\tpublic async getReinstallMrpackAuth(\n\t\tserverId: string,\n\t): Promise<Archon.Servers.v0.MrpackReinstallAuth> {\n\t\treturn this.client.request<Archon.Servers.v0.MrpackReinstallAuth>(\n\t\t\t`/servers/${serverId}/reinstallFromMrpack`,\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'modrinth/v0',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Reinstall a server from a .mrpack file with progress tracking\n\t *\n\t * Two-step flow: fetches upload auth, then uploads the .mrpack file to the node.\n\t *\n\t * @param serverId - Server ID\n\t * @param file - .mrpack file to upload\n\t * @param hardReset - Whether to erase all server data\n\t * @param options - Optional progress callback\n\t * @returns Promise resolving to an UploadHandle with progress tracking and cancellation\n\t */\n\tpublic async reinstallFromMrpack(\n\t\tserverId: string,\n\t\tfile: File,\n\t\thardReset: boolean = false,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): Promise<UploadHandle<void>> {\n\t\tconst auth = await this.getReinstallMrpackAuth(serverId)\n\n\t\tconst formData = new FormData()\n\t\tformData.append('file', file)\n\n\t\treturn this.client.upload<void>('', {\n\t\t\tapi: `https://${auth.url}`,\n\t\t\tversion: 'reinstallMrpackMultiparted',\n\t\t\tformData,\n\t\t\tparams: { hard: String(hardReset) },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: false,\n\t\t})\n\t}\n\n\t/**\n\t * Update a server's name\n\t * POST /modrinth/v0/servers/:id/name\n\t */\n\tpublic async updateName(serverId: string, name: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/name`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Get allocations for a server\n\t * GET /modrinth/v0/servers/:id/allocations\n\t */\n\tpublic async getAllocations(serverId: string): Promise<Archon.Servers.v0.Allocation[]> {\n\t\treturn this.client.request<Archon.Servers.v0.Allocation[]>(`/servers/${serverId}/allocations`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Reserve a new allocation for a server\n\t * POST /modrinth/v0/servers/:id/allocations?name=...\n\t */\n\tpublic async reserveAllocation(\n\t\tserverId: string,\n\t\tname: string,\n\t): Promise<Archon.Servers.v0.Allocation> {\n\t\treturn this.client.request<Archon.Servers.v0.Allocation>(`/servers/${serverId}/allocations`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Update an allocation's name\n\t * PUT /modrinth/v0/servers/:id/allocations/:port?name=...\n\t */\n\tpublic async updateAllocation(serverId: string, port: number, name: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/allocations/${port}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'PUT',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tparams: { name },\n\t\t})\n\t}\n\n\t/**\n\t * Delete an allocation\n\t * DELETE /modrinth/v0/servers/:id/allocations/:port\n\t */\n\tpublic async deleteAllocation(serverId: string, port: number): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/allocations/${port}`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'DELETE',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Check if a subdomain is available\n\t * GET /modrinth/v0/subdomains/:subdomain/isavailable\n\t */\n\tpublic async checkSubdomainAvailability(subdomain: string): Promise<{ available: boolean }> {\n\t\treturn this.client.request<{ available: boolean }>(`/subdomains/${subdomain}/isavailable`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Change a server's subdomain\n\t * POST /modrinth/v0/servers/:id/subdomain\n\t */\n\tpublic async changeSubdomain(serverId: string, subdomain: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/subdomain`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: { subdomain },\n\t\t})\n\t}\n\n\t/**\n\t * Get startup configuration for a server\n\t * GET /modrinth/v0/servers/:id/startup\n\t */\n\tpublic async getStartupConfig(serverId: string): Promise<Archon.Servers.v0.StartupConfig> {\n\t\treturn this.client.request<Archon.Servers.v0.StartupConfig>(`/servers/${serverId}/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'GET',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n\n\t/**\n\t * Update startup configuration for a server\n\t * POST /modrinth/v0/servers/:id/startup\n\t */\n\tpublic async updateStartupConfig(\n\t\tserverId: string,\n\t\tconfig: {\n\t\t\tinvocation: string | null\n\t\t\tjdk_version: string | null\n\t\t\tjdk_build: string | null\n\t\t},\n\t): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/startup`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tbody: config,\n\t\t})\n\t}\n\n\t/**\n\t * Dismiss a server notice\n\t * POST /modrinth/v0/servers/:id/notices/:noticeId/dismiss\n\t */\n\tpublic async dismissNotice(serverId: string, noticeId: number): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/notices/${noticeId}/dismiss`, {\n\t\t\tapi: 'archon',\n\t\t\tmethod: 'POST',\n\t\t\tversion: 'modrinth/v0',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonServersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_servers_v1'\n\t}\n\n\t/**\n\t * Get list of servers for the authenticated user\n\t * GET /v1/servers\n\t */\n\tpublic async list(): Promise<Archon.Servers.v1.ServerFull[]> {\n\t\treturn this.client.request<Archon.Servers.v1.ServerFull[]>('/servers', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get full server details including worlds, backups, and content\n\t * GET /v1/servers/:server_id\n\t */\n\tpublic async get(serverId: string): Promise<Archon.Servers.v1.ServerFull> {\n\t\treturn this.client.request<Archon.Servers.v1.ServerFull>(`/servers/${serverId}`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get available regions\n\t * GET /v1/regions\n\t */\n\tpublic async getRegions(): Promise<Archon.Servers.v1.Region[]> {\n\t\treturn this.client.request<Archon.Servers.v1.Region[]>('/regions', {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * End the intro flow for a server\n\t * DELETE /v1/servers/:id/flows/intro\n\t */\n\tpublic async endIntro(serverId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/flows/intro`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Reset a world to onboarding\n\t * POST /v1/servers/:id/worlds/:wid/onboard\n\t */\n\tpublic async resetToOnboarding(serverId: string, worldId: string): Promise<void> {\n\t\tawait this.client.request(`/servers/${serverId}/worlds/${worldId}/onboard`, {\n\t\t\tapi: 'archon',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Archon } from '../types'\n\nexport class ArchonTransfersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'archon_transfers_internal'\n\t}\n\n\t/**\n\t * Schedule transfers for specific servers.\n\t * POST /_internal/transfers/schedule/servers\n\t */\n\tpublic async scheduleServers(\n\t\trequest: Archon.Transfers.Internal.ScheduleServerTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.ScheduleTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.ScheduleTransfersResponse>(\n\t\t\t'/transfers/schedule/servers',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Schedule transfers for all servers on specific nodes.\n\t * POST /_internal/transfers/schedule/nodes\n\t */\n\tpublic async scheduleNodes(\n\t\trequest: Archon.Transfers.Internal.ScheduleNodeTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.ScheduleTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.ScheduleTransfersResponse>(\n\t\t\t'/transfers/schedule/nodes',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get transfer batch history.\n\t * GET /_internal/transfers/history\n\t */\n\tpublic async history(\n\t\toptions?: Archon.Transfers.Internal.TransferHistoryQuery,\n\t): Promise<Archon.Transfers.Internal.TransferHistoryResponse> {\n\t\tconst params: Record<string, number> = {}\n\t\tif (options?.page !== undefined) params.page = options.page\n\t\tif (options?.page_size !== undefined) params.page_size = options.page_size\n\n\t\treturn this.client.request<Archon.Transfers.Internal.TransferHistoryResponse>(\n\t\t\t'/transfers/history',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Cancel pending transfer batches.\n\t * POST /_internal/transfers/cancel\n\t */\n\tpublic async cancel(\n\t\trequest: Archon.Transfers.Internal.CancelTransfersRequest,\n\t): Promise<Archon.Transfers.Internal.CancelTransfersResponse> {\n\t\treturn this.client.request<Archon.Transfers.Internal.CancelTransfersResponse>(\n\t\t\t'/transfers/cancel',\n\t\t\t{\n\t\t\t\tapi: 'archon',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { $fetch } from 'ofetch'\n\nimport { AbstractModule } from '../../core/abstract-module'\nimport type { ISO3166 } from './types'\n\nexport type { ISO3166 } from './types'\n\nconst ISO3166_REPO = 'https://raw.githubusercontent.com/ipregistry/iso3166/master'\n\n/**\n * Parse CSV string into array of objects\n * @param csv - CSV string to parse\n * @returns Array of objects with header keys mapped to row values\n */\nfunction parseCSV(csv: string): Record<string, string>[] {\n\tconst lines = csv\n\t\t.trim()\n\t\t.split('\\n')\n\t\t.filter((line) => line.trim() !== '')\n\n\tif (lines.length === 0) return []\n\n\tconst headerLine = lines[0]\n\tconst headers = (headerLine.startsWith('#') ? headerLine.slice(1) : headerLine).split(',')\n\n\treturn lines.slice(1).map((line) => {\n\t\tconst values = line.split(',')\n\t\tconst row: Record<string, string> = {}\n\n\t\theaders.forEach((header, index) => {\n\t\t\trow[header] = values[index] || ''\n\t\t})\n\n\t\treturn row\n\t})\n}\n\n/**\n * Module for fetching ISO 3166 country and subdivision data\n * Data from https://github.com/ipregistry/iso3166 (Licensed under CC BY-SA 4.0)\n * @platform Not for use in Tauri or Nuxt environments, only node.\n */\nexport class ISO3166Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'iso3166_data'\n\t}\n\n\t/**\n\t * Build ISO 3166 country and subdivision data from the ipregistry repository\n\t *\n\t * @returns Promise resolving to countries and subdivisions data\n\t *\n\t * @example\n\t * ```typescript\n\t * const data = await client.iso3166.data.build()\n\t * console.log(data.countries) // Array of country data\n\t * console.log(data.subdivisions['US']) // Array of US state data\n\t * ```\n\t */\n\tpublic async build(): Promise<ISO3166.State> {\n\t\ttry {\n\t\t\tconst [countriesCSV, subdivisionsCSV] = await Promise.all([\n\t\t\t\t$fetch<string>(`${ISO3166_REPO}/countries.csv`, {\n\t\t\t\t\t// @ts-expect-error supports text\n\t\t\t\t\tresponseType: 'text',\n\t\t\t\t}),\n\t\t\t\t$fetch<string>(`${ISO3166_REPO}/subdivisions.csv`, {\n\t\t\t\t\t// @ts-expect-error supports text\n\t\t\t\t\tresponseType: 'text',\n\t\t\t\t}),\n\t\t\t])\n\n\t\t\tconst countriesData = parseCSV(countriesCSV)\n\t\t\tconst subdivisionsData = parseCSV(subdivisionsCSV)\n\n\t\t\tconst countries: ISO3166.Country[] = countriesData.map((c) => ({\n\t\t\t\talpha2: c.country_code_alpha2,\n\t\t\t\talpha3: c.country_code_alpha3,\n\t\t\t\tnumeric: c.numeric_code,\n\t\t\t\tnameShort: c.name_short,\n\t\t\t\tnameLong: c.name_long,\n\t\t\t}))\n\n\t\t\t// Group subdivisions by country code\n\t\t\tconst subdivisions: Record<string, ISO3166.Subdivision[]> = subdivisionsData.reduce(\n\t\t\t\t(acc, sub) => {\n\t\t\t\t\tconst countryCode = sub.country_code_alpha2\n\n\t\t\t\t\tif (!countryCode || typeof countryCode !== 'string' || countryCode.trim() === '') {\n\t\t\t\t\t\treturn acc\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!acc[countryCode]) acc[countryCode] = []\n\n\t\t\t\t\tacc[countryCode].push({\n\t\t\t\t\t\tcode: sub['subdivision_code_iso3166-2'],\n\t\t\t\t\t\tname: sub.subdivision_name,\n\t\t\t\t\t\tlocalVariant: sub.localVariant || null,\n\t\t\t\t\t\tcategory: sub.category,\n\t\t\t\t\t\tparent: sub.parent_subdivision || null,\n\t\t\t\t\t\tlanguage: sub.language_code,\n\t\t\t\t\t})\n\n\t\t\t\t\treturn acc\n\t\t\t\t},\n\t\t\t\t{} as Record<string, ISO3166.Subdivision[]>,\n\t\t\t)\n\n\t\t\treturn {\n\t\t\t\tcountries,\n\t\t\t\tsubdivisions,\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconsole.error('Error fetching ISO3166 data:', err)\n\t\t\treturn {\n\t\t\t\tcountries: [],\n\t\t\t\tsubdivisions: {},\n\t\t\t}\n\t\t}\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Archon } from '../../archon/types'\n\nexport class KyrosContentV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_content_v1'\n\t}\n\n\t/**\n\t * Upload addon files to a world via multipart form data\n\t *\n\t * @param worldId - World UUID\n\t * @param files - Files to upload as addons\n\t * @param options - Optional progress callback\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t * @deprecated Use `kyros.upload_sessions_v1` so cancellation can remove staged addon files before finalize.\n\t */\n\tpublic uploadAddonFile(\n\t\tworldId: string,\n\t\tfiles: (File | Blob)[],\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): UploadHandle<void> {\n\t\tconst formData = new FormData()\n\t\tfor (const file of files) {\n\t\t\tformData.append('file', file, file instanceof File ? file.name : 'file')\n\t\t}\n\n\t\treturn this.client.upload<void>(`/worlds/${worldId}/content/upload-addon-file`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tformData,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/** POST /v1/worlds/:world_id/content/upload-modpack-file */\n\tpublic uploadModpackFile(\n\t\tworldId: string,\n\t\tfile: File | Blob,\n\t\tproperties: Archon.Content.v1.PropertiesFields,\n\t\toptions?: {\n\t\t\tsoftOverride?: boolean\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t},\n\t): UploadHandle<void> {\n\t\tconst formData = new FormData()\n\t\tformData.append('file', file, file instanceof File ? file.name : 'file')\n\t\tformData.append('properties', JSON.stringify(properties))\n\n\t\treturn this.client.upload<void>(`/worlds/${worldId}/content/upload-modpack-file`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tformData,\n\t\t\tparams:\n\t\t\t\toptions?.softOverride !== undefined\n\t\t\t\t\t? { soft_override: String(options.softOverride) }\n\t\t\t\t\t: undefined,\n\t\t\tonProgress: options?.onProgress,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "const NODE_FS_PATH_REGEX = /\\/modrinth\\/v\\d+\\/fs\\/?$/\nconst HTTP_SCHEME_REGEX = /^https?:\\/\\//i\nconst WS_SCHEME_REGEX = /^wss?:\\/\\//i\nconst HTTP_SECURE_SCHEME_REGEX = /^https:\\/\\//i\nconst HTTP_INSECURE_SCHEME_REGEX = /^http:\\/\\//i\n\nexport function getNodeBaseUrl(url: string): string {\n\tconst baseUrl = url.replace(NODE_FS_PATH_REGEX, '')\n\treturn HTTP_SCHEME_REGEX.test(baseUrl) ? baseUrl : `https://${baseUrl}`\n}\n\nexport function getNodeWebSocketUrl(url: string): string {\n\tif (WS_SCHEME_REGEX.test(url)) return url\n\tif (HTTP_SECURE_SCHEME_REGEX.test(url)) return url.replace(HTTP_SECURE_SCHEME_REGEX, 'wss://')\n\tif (HTTP_INSECURE_SCHEME_REGEX.test(url)) return url.replace(HTTP_INSECURE_SCHEME_REGEX, 'ws://')\n\n\treturn `wss://${url}`\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport { getNodeBaseUrl } from '../../../utils/node-url'\nimport type { Archon } from '../../archon/types'\nimport type { Kyros } from '../types'\n\ntype NodeFsAuth = Pick<Archon.Servers.v0.JWTAuth, 'url' | 'token'>\n\nexport class KyrosFilesV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_files_v0'\n\t}\n\n\tprivate getNodeBaseUrl(auth: NodeFsAuth): string {\n\t\treturn getNodeBaseUrl(auth.url)\n\t}\n\n\t/**\n\t * List directory contents with pagination\n\t *\n\t * @param path - Directory path (e.g., \"/\")\n\t * @param page - Page number (1-indexed)\n\t * @param pageSize - Items per page\n\t * @returns Directory listing with items and pagination info\n\t */\n\tpublic async listDirectory(\n\t\tpath: string,\n\t\tpage: number = 1,\n\t\tpageSize: number = 100,\n\t): Promise<Kyros.Files.v0.DirectoryResponse> {\n\t\treturn this.client.request<Kyros.Files.v0.DirectoryResponse>('/fs/list', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path, page, page_size: pageSize },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Create a file or directory\n\t *\n\t * @param path - Path for new item (e.g., \"/new-folder\")\n\t * @param type - Type of item to create\n\t */\n\tpublic async createFileOrFolder(path: string, type: 'file' | 'directory'): Promise<void> {\n\t\treturn this.client.request<void>('/fs/create', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { path, type },\n\t\t\theaders: { 'Content-Type': 'application/octet-stream' },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Download a file from a server's filesystem\n\t *\n\t * @param path - File path (e.g., \"/server-icon-original.png\")\n\t * @returns Promise resolving to file Blob\n\t */\n\tpublic async downloadFile(path: string): Promise<Blob> {\n\t\treturn this.client.request<Blob>('/fs/download', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Download a file using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - File path (e.g., \"/server-icon.png\")\n\t * @returns Promise resolving to file Blob\n\t */\n\tpublic async downloadFileWithAuth(auth: NodeFsAuth, path: string): Promise<Blob> {\n\t\treturn this.client.request<Blob>('/fs/download', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'GET',\n\t\t\tparams: { path },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Upload a file to a server's filesystem with progress tracking\n\t *\n\t * @param path - Destination path (e.g., \"/server-icon.png\")\n\t * @param file - File to upload\n\t * @param options - Optional progress callback and feature overrides\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t * @deprecated Use `kyros.upload_sessions_v1` for bulk uploads so cancellation can remove staged files before finalize.\n\t */\n\tpublic uploadFile(\n\t\tpath: string,\n\t\tfile: File | Blob,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<void> {\n\t\treturn this.client.upload<void>('/fs/create', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tfile,\n\t\t\tparams: { path, type: 'file' },\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: options?.retry,\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Upload a file using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - Destination path (e.g., \"/server-icon.png\")\n\t * @param file - File to upload\n\t * @param options - Optional progress callback and feature overrides\n\t * @returns UploadHandle with promise, onProgress, and cancel\n\t */\n\tpublic uploadFileWithAuth(\n\t\tauth: NodeFsAuth,\n\t\tpath: string,\n\t\tfile: File | Blob,\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<void> {\n\t\treturn this.client.upload<void>('/fs/create', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tfile,\n\t\t\tparams: { path, type: 'file' },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tonProgress: options?.onProgress,\n\t\t\tretry: options?.retry,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Update file contents\n\t *\n\t * @param path - File path to update\n\t * @param content - New file content (string or Blob)\n\t */\n\tpublic async updateFile(path: string, content: string | Blob): Promise<void> {\n\t\tconst blob = typeof content === 'string' ? new Blob([content]) : content\n\n\t\treturn this.client.request<void>('/fs/update', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'PUT',\n\t\t\tparams: { path },\n\t\t\tbody: blob,\n\t\t\theaders: { 'Content-Type': 'application/octet-stream' },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Move a file or folder to a new location\n\t *\n\t * @param sourcePath - Current path\n\t * @param destPath - New path\n\t */\n\tpublic async moveFileOrFolder(sourcePath: string, destPath: string): Promise<void> {\n\t\treturn this.client.request<void>('/fs/move', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'POST',\n\t\t\tbody: { source: sourcePath, destination: destPath },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Rename a file or folder (convenience wrapper around move)\n\t *\n\t * @param path - Current file/folder path\n\t * @param newName - New name (not full path)\n\t */\n\tpublic async renameFileOrFolder(path: string, newName: string): Promise<void> {\n\t\tconst newPath = path.split('/').slice(0, -1).join('/') + '/' + newName\n\t\treturn this.moveFileOrFolder(path, newPath)\n\t}\n\n\t/**\n\t * Delete a file or folder\n\t *\n\t * @param path - Path to delete\n\t * @param recursive - If true, delete directory contents recursively\n\t */\n\tpublic async deleteFileOrFolder(path: string, recursive: boolean): Promise<void> {\n\t\treturn this.client.request<void>('/fs/delete', {\n\t\t\tapi: '',\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { path, recursive },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a file or folder using explicit filesystem auth credentials.\n\t *\n\t * @param auth - Filesystem auth (url + token) from Archon\n\t * @param path - Path to delete\n\t * @param recursive - If true, delete directory contents recursively\n\t */\n\tpublic async deleteFileOrFolderWithAuth(\n\t\tauth: NodeFsAuth,\n\t\tpath: string,\n\t\trecursive: boolean,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/fs/delete', {\n\t\t\tapi: this.getNodeBaseUrl(auth),\n\t\t\tversion: 'modrinth/v0',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { path, recursive },\n\t\t\theaders: { Authorization: `Bearer ${auth.token}` },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Extract an archive file (zip, tar, etc.)\n\t *\n\t * Uses v1 API endpoint.\n\t *\n\t * @param path - Path to archive file\n\t * @param override - If true, overwrite existing files\n\t * @param dry - If true, perform dry run (returns conflicts without extracting)\n\t * @returns Extract result with modpack name and conflicting files\n\t */\n\tpublic async extractFile(\n\t\tpath: string,\n\t\toverride: boolean = true,\n\t\tdry: boolean = false,\n\t): Promise<Kyros.Files.v0.ExtractResult> {\n\t\treturn this.client.request<Kyros.Files.v0.ExtractResult>('/fs/unarchive', {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { src: path, trg: '/', override, dry },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Modify a filesystem operation (dismiss or cancel)\n\t *\n\t * Uses v1 API endpoint.\n\t *\n\t * @param opId - Operation ID (UUID)\n\t * @param action - Action to perform\n\t */\n\tpublic async modifyOperation(opId: string, action: 'dismiss' | 'cancel'): Promise<void> {\n\t\treturn this.client.request<void>(`/fs/ops/${action}`, {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tparams: { id: opId },\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\n\nexport class KyrosLogsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_logs_v1'\n\t}\n\n\t/** POST /v1/logs/clear \u2014 clear the live logs buffer for the current server */\n\tpublic async clear(): Promise<void> {\n\t\treturn this.client.request<void>('/logs/clear', {\n\t\t\tapi: '',\n\t\t\tversion: 'v1',\n\t\t\tmethod: 'POST',\n\t\t\tuseNodeAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle, UploadProgress } from '../../../types/upload'\nimport type { Kyros } from '../types'\n\nexport type UploadSessionFile = {\n\tfile: File | Blob\n\tfilename: string\n}\n\nfunction getUploadSessionPath(scope: Kyros.UploadSessions.v1.Scope, worldId: string) {\n\treturn `/worlds/${worldId}/${scope}/upload-session`\n}\n\nexport class KyrosUploadSessionsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'kyros_upload_sessions_v1'\n\t}\n\n\tpublic async create(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\tgetUploadSessionPath(scope, worldId),\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async get(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t): Promise<Kyros.UploadSessions.v1.GetUploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.GetUploadSessionResponse>(\n\t\t\tgetUploadSessionPath(scope, worldId),\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic uploadFiles(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t\tfiles: UploadSessionFile[],\n\t\toptions?: {\n\t\t\tonProgress?: (progress: UploadProgress) => void\n\t\t\tretry?: boolean | number\n\t\t},\n\t): UploadHandle<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\tconst formData = new FormData()\n\t\tfor (const { file, filename } of files) {\n\t\t\tformData.append('file', file, filename)\n\t\t}\n\n\t\treturn this.client.upload<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}/files`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tformData,\n\t\t\t\tonProgress: options?.onProgress,\n\t\t\t\tretry: options?.retry,\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async finalize(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}/finalize`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async cancel(\n\t\tscope: Kyros.UploadSessions.v1.Scope,\n\t\tworldId: string,\n\t\tuploadId: string,\n\t): Promise<Kyros.UploadSessions.v1.UploadSessionResponse> {\n\t\treturn this.client.request<Kyros.UploadSessions.v1.UploadSessionResponse>(\n\t\t\t`${getUploadSessionPath(scope, worldId)}/${uploadId}`,\n\t\t\t{\n\t\t\t\tapi: '',\n\t\t\t\tversion: 'v1',\n\t\t\t\tmethod: 'DELETE',\n\t\t\t\tuseNodeAuth: true,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAnalyticsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_analytics_internal'\n\t}\n\n\t/**\n\t * Create an analytics event.\n\t * POST /_internal/analytics-event\n\t */\n\tpublic async createEvent(\n\t\tdata: Labrinth.Analytics.Internal.AnalyticsEventUpsert,\n\t): Promise<Labrinth.Analytics.v3.AnalyticsEvent> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent>('/analytics-event', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit an analytics event.\n\t * PATCH /_internal/analytics-event/{id}\n\t */\n\tpublic async editEvent(\n\t\tid: Labrinth.Analytics.v3.AnalyticsEventId,\n\t\tdata: Labrinth.Analytics.Internal.AnalyticsEventUpsert,\n\t): Promise<Labrinth.Analytics.v3.AnalyticsEvent> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent>(`/analytics-event/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete an analytics event.\n\t * DELETE /_internal/analytics-event/{id}\n\t */\n\tpublic async deleteEvent(id: Labrinth.Analytics.v3.AnalyticsEventId): Promise<void> {\n\t\treturn this.client.request<void>(`/analytics-event/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAnalyticsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_analytics_v3'\n\t}\n\n\t/**\n\t * Fetch analytics data for the authenticated user's accessible projects\n\t * and affiliate codes.\n\t *\n\t * @param data - Analytics request body defining time range and requested metrics\n\t * @returns Promise resolving to the analytics response, with time slices in `metrics`\n\t *\n\t * @example\n\t * ```typescript\n\t * const response = await client.labrinth.analytics_v3.fetch({\n\t * time_range: {\n\t * start: '2026-01-01T00:00:00Z',\n\t * end: '2026-02-01T00:00:00Z',\n\t * resolution: { slices: 31 },\n\t * },\n\t * project_ids: ['A1B2C3D4'],\n\t * return_metrics: {\n\t * project_views: { bucket_by: ['project_id'] },\n\t * },\n\t * })\n\t * const timeSlices = response.metrics\n\t * ```\n\t */\n\tpublic async fetch(\n\t\tdata: Labrinth.Analytics.v3.FetchRequest,\n\t): Promise<Labrinth.Analytics.v3.FetchResponse> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.FetchResponse>('/analytics', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\ttimeout: 100 * 1000,\n\t\t})\n\t}\n\n\t/**\n\t * Fetch available analytics filter facets for the authenticated user's\n\t * accessible projects.\n\t *\n\t * POST /v3/analytics/facets\n\t */\n\tpublic async fetchFacets(\n\t\tdata: Labrinth.Analytics.v3.FetchRequest,\n\t): Promise<Labrinth.Analytics.v3.FacetsResponse> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.FacetsResponse>('/analytics/facets', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\ttimeout: 100 * 1000,\n\t\t})\n\t}\n\n\t/**\n\t * Fetch all analytics events.\n\t * GET /v3/analytics-event\n\t */\n\tpublic async getEvents(): Promise<Labrinth.Analytics.v3.AnalyticsEvent[]> {\n\t\treturn this.client.request<Labrinth.Analytics.v3.AnalyticsEvent[]>('/analytics-event', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nconst BASE62_CHARS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'\n\n/**\n * Decode a base62-encoded ID string into a number.\n * The backend serializes attribution group IDs as base62 strings in responses,\n * but the assign/update endpoints expect raw integer IDs in their request payloads.\n */\nfunction decodeBase62Id(id: string): number {\n\tlet value = 0\n\tfor (const char of id) {\n\t\tconst digit = BASE62_CHARS.indexOf(char)\n\t\tif (digit < 0) {\n\t\t\tthrow new Error(`Invalid base62 character \"${char}\" in id \"${id}\"`)\n\t\t}\n\t\tvalue = value * 62 + digit\n\t\tif (!Number.isSafeInteger(value)) {\n\t\t\tthrow new Error(`Base62 id \"${id}\" exceeds safe integer range`)\n\t\t}\n\t}\n\treturn value\n}\n\nexport class LabrinthAttributionInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_attribution_internal'\n\t}\n\n\t/**\n\t * List attribution groups for a project\n\t * GET /_internal/attribution/{project_id}\n\t */\n\tpublic async listProjectAttribution(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Attribution.Internal.AttributionGroup[]> {\n\t\treturn this.client.request<Labrinth.Attribution.Internal.AttributionGroup[]>(\n\t\t\t`/attribution/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update an attribution group's attribution payload.\n\t * PATCH /_internal/attribution/group/{group_id}\n\t *\n\t * @param groupId - The base62 attribution group id (as returned from listProjectAttribution).\n\t */\n\tpublic async updateGroup(\n\t\tgroupId: string,\n\t\tbody: Labrinth.Attribution.Internal.UpdateGroupRequest,\n\t): Promise<void> {\n\t\tconst numericId = decodeBase62Id(groupId)\n\t\treturn this.client.request<void>(`/attribution/group/${numericId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Delete attribution groups and all files inside them.\n\t * DELETE /_internal/attribution/group\n\t *\n\t * @param groupIds - The base62 attribution group ids (as returned from listProjectAttribution).\n\t */\n\tpublic async deleteGroups(groupIds: string[]): Promise<void> {\n\t\tconst body: Labrinth.Attribution.Internal.DeleteGroupsRequest = { groups: groupIds }\n\t\treturn this.client.request<void>('/attribution/group', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Delete all attribution groups and files for a project.\n\t * DELETE /_internal/attribution/all-groups\n\t */\n\tpublic async deleteAllGroups(projectId: string): Promise<void> {\n\t\tconst body: Labrinth.Attribution.Internal.DeleteAllGroupsRequest = {\n\t\t\tproject_id: projectId,\n\t\t}\n\t\treturn this.client.request<void>('/attribution/all-groups', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Reassign a file (by sha1) to another attribution group within the same project.\n\t * POST /_internal/attribution/assign\n\t *\n\t * @param body.target_group_id - The base62 id of the attribution group to assign the file to.\n\t */\n\tpublic async assignFileToGroup(body: {\n\t\tsha1: string\n\t\ttarget_group_id: string\n\t\tproject_id: string\n\t}): Promise<void> {\n\t\tconst wireBody: Labrinth.Attribution.Internal.AssignRequest = {\n\t\t\tsha1: body.sha1,\n\t\t\ttarget_group_id: decodeBase62Id(body.target_group_id),\n\t\t\tproject_id: body.project_id,\n\t\t}\n\t\treturn this.client.request<void>('/attribution/assign', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: wireBody,\n\t\t})\n\t}\n\n\t/**\n\t * Split a file (by sha1) out of its current attribution group into a new group.\n\t * POST /_internal/attribution/split\n\t */\n\tpublic async splitFile(body: Labrinth.Attribution.Internal.SplitRequest): Promise<void> {\n\t\treturn this.client.request<void>('/attribution/split', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Scan a file for attribution information.\n\t * POST /_internal/attribution/file/{file_id}/scan\n\t *\n\t * @param fileId - The file ID to scan.\n\t */\n\tpublic async scanFile(fileId: string): Promise<Labrinth.Attribution.Internal.FileScanResponse> {\n\t\treturn this.client.request<Labrinth.Attribution.Internal.FileScanResponse>(\n\t\t\t`/attribution/file/${fileId}/scan`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAuthInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_auth_internal'\n\t}\n\n\t/**\n\t * Check if the user is subscribed to the newsletter\n\t *\n\t * @returns Promise resolving to the subscription status\n\t */\n\tpublic async getNewsletterStatus(): Promise<Labrinth.Auth.Internal.SubscriptionStatus> {\n\t\treturn this.client.request<Labrinth.Auth.Internal.SubscriptionStatus>('/auth/email/subscribe', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Subscribe to the newsletter\n\t */\n\tpublic async subscribeNewsletter(): Promise<void> {\n\t\treturn this.client.request('/auth/email/subscribe', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Create a signed Discord community bot handoff URL\n\t */\n\tpublic async createDiscordCommunityLink(): Promise<Labrinth.Auth.Internal.DiscordCommunityLinkResponse> {\n\t\treturn this.client.request<Labrinth.Auth.Internal.DiscordCommunityLinkResponse>(\n\t\t\t'/auth/discord-community-link',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAuthV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_auth_v2'\n\t}\n\n\t/**\n\t * Log in with a password\n\t *\n\t * Returns a session token on success, or a flow ID if 2FA is required.\n\t *\n\t * @param data - Login credentials and captcha challenge\n\t * @returns Promise resolving to a login response with session or flow\n\t */\n\tpublic async login(data: Labrinth.Auth.v2.LoginRequest): Promise<Labrinth.Auth.v2.LoginResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.LoginResponse>(`/auth/login`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Complete a 2FA login flow\n\t *\n\t * @param data - The 2FA code and flow ID\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async login2FA(\n\t\tdata: Labrinth.Auth.v2.Login2FARequest,\n\t): Promise<Labrinth.Auth.v2.Login2FAResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Login2FAResponse>(`/auth/login/2fa`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Create a new account with a password\n\t *\n\t * @param data - Account creation data\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async createAccount(\n\t\tdata: Labrinth.Auth.v2.CreateAccountRequest,\n\t): Promise<Labrinth.Auth.v2.CreateAccountResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.CreateAccountResponse>(`/auth/create`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Validate email/password inputs for account creation without creating an account.\n\t *\n\t * @param data - Prospective account credentials\n\t */\n\tpublic async validateCreateAccount(\n\t\tdata: Labrinth.Auth.v2.ValidateCreateAccountRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/auth/create/validate`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Create a new account from an OAuth callback flow state\n\t *\n\t * @param data - OAuth account creation data\n\t * @returns Promise resolving to a session response\n\t */\n\tpublic async createOAuthAccount(\n\t\tdata: Labrinth.Auth.v2.CreateOAuthAccountRequest,\n\t): Promise<Labrinth.Auth.v2.CreateOAuthAccountResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.CreateOAuthAccountResponse>(`/auth/create/oauth`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Begin a password reset flow by sending a recovery email\n\t *\n\t * @param data - The username/email and captcha challenge\n\t */\n\tpublic async resetPasswordBegin(data: Labrinth.Auth.v2.ResetPasswordRequest): Promise<void> {\n\t\treturn this.client.request(`/auth/password/reset`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Change a user's password (via reset flow or with old password)\n\t *\n\t * @param data - The password change data\n\t */\n\tpublic async changePassword(data: Labrinth.Auth.v2.ChangePasswordRequest): Promise<void> {\n\t\treturn this.client.request(`/auth/password`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * List the current user's registered passkeys\n\t *\n\t * @returns A promise that resolves to a list of the user's registered passkeys\n\t */\n\tpublic async listPasskeys(): Promise<Labrinth.Auth.v2.Passkey[]> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Passkey[]>(`/auth/passkey`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Begin registering a new passkey, returning the WebAuthn creation options and a flow\n\t *\n\t * @returns A promise that resolves to the WebAuthn creation options and flow\n\t */\n\tpublic async registerPasskeyStart(): Promise<Labrinth.Auth.v2.PasskeyRegisterStartResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.PasskeyRegisterStartResponse>(\n\t\t\t`/auth/passkey/register/start`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Complete passkey registration with the created credential\n\t *\n\t * @param data The credential data and flow to complete registration with\n\t * @returns A promise that resolves to the newly registered passkey\n\t */\n\tpublic async registerPasskeyFinish(\n\t\tdata: Labrinth.Auth.v2.PasskeyRegisterFinishRequest,\n\t): Promise<Labrinth.Auth.v2.Passkey> {\n\t\treturn this.client.request<Labrinth.Auth.v2.Passkey>(`/auth/passkey/register/finish`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Begin a passkey authentication flow, returning the WebAuthn request options and a flow\n\t *\n\t * @returns A promise that resolves to the WebAuthn request options and a flow\n\t */\n\tpublic async authenticatePasskeyStart(): Promise<Labrinth.Auth.v2.PasskeyAuthenticateStartResponse> {\n\t\treturn this.client.request<Labrinth.Auth.v2.PasskeyAuthenticateStartResponse>(\n\t\t\t`/auth/passkey/start`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tskipAuth: true,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Complete a passkey authentication flow, returning the new session\n\t *\n\t * @param data The credential data and flow to complete authentication with\n\t * @returns A promise that resolves to the new session\n\t */\n\tpublic async authenticatePasskeyFinish(\n\t\tdata: Labrinth.Auth.v2.PasskeyAuthenticateFinishRequest,\n\t): Promise<Labrinth.Sessions.v2.Session> {\n\t\treturn this.client.request<Labrinth.Sessions.v2.Session>(`/auth/passkey/finish`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Rename a passkey\n\t *\n\t * @param id The ID of the passkey to rename\n\t * @param data The new name for the passkey\n\t */\n\tpublic async renamePasskey(\n\t\tid: string,\n\t\tdata: Labrinth.Auth.v2.PasskeyRenameRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/auth/passkey/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a passkey\n\t *\n\t * @param id The ID of the passkey to delete\n\t */\n\tpublic async deletePasskey(id: string): Promise<void> {\n\t\treturn this.client.request(`/auth/passkey/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBillingInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_billing_internal'\n\t}\n\n\t/**\n\t * Get user's subscriptions\n\t * GET /_internal/billing/subscriptions\n\t */\n\tpublic async getSubscriptions(\n\t\tuserId?: string,\n\t): Promise<Labrinth.Billing.Internal.UserSubscription[]> {\n\t\tconst params = userId ? `?user_id=${userId}` : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.UserSubscription[]>(\n\t\t\t`/billing/subscriptions${params}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get available products for purchase\n\t * GET /_internal/billing/products\n\t */\n\tpublic async getProducts(): Promise<Labrinth.Billing.Internal.Product[]> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.Product[]>('/billing/products', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get Stripe customer information\n\t * GET /_internal/billing/customer\n\t */\n\tpublic async getCustomer(): Promise<unknown> {\n\t\treturn this.client.request<unknown>('/billing/customer', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Edit a subscription (change product, interval, cancel, etc.)\n\t * PATCH /_internal/billing/subscription/{id}\n\t */\n\tpublic async editSubscription(\n\t\tid: string,\n\t\tedit: Labrinth.Billing.Internal.EditSubscriptionRequest,\n\t\tdry?: boolean,\n\t): Promise<Labrinth.Billing.Internal.EditSubscriptionResponse | void> {\n\t\tconst params = dry ? '?dry=true' : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.EditSubscriptionResponse | void>(\n\t\t\t`/billing/subscription/${id}${params}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: edit,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get user's payment methods\n\t * GET /_internal/billing/payment_methods\n\t */\n\tpublic async getPaymentMethods(): Promise<unknown[]> {\n\t\treturn this.client.request<unknown[]>('/billing/payment_methods', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Initiate flow to add a new payment method\n\t * POST /_internal/billing/payment_method\n\t */\n\tpublic async addPaymentMethodFlow(): Promise<Labrinth.Billing.Internal.AddPaymentMethodFlowResponse> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.AddPaymentMethodFlowResponse>(\n\t\t\t'/billing/payment_method',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Edit a payment method (set as primary)\n\t * PATCH /_internal/billing/payment_method/{id}\n\t */\n\tpublic async editPaymentMethod(\n\t\tid: string,\n\t\tbody: Labrinth.Billing.Internal.EditPaymentMethodRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/payment_method/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a payment method\n\t * DELETE /_internal/billing/payment_method/{id}\n\t */\n\tpublic async removePaymentMethod(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/payment_method/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Get payment history (charges)\n\t * GET /_internal/billing/payments\n\t */\n\tpublic async getPayments(userId?: string): Promise<Labrinth.Billing.Internal.Charge[]> {\n\t\tconst params = userId ? `?user_id=${userId}` : ''\n\n\t\treturn this.client.request<Labrinth.Billing.Internal.Charge[]>(`/billing/payments${params}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Initiate a payment\n\t * POST /_internal/billing/payment\n\t */\n\tpublic async initiatePayment(\n\t\trequest: Labrinth.Billing.Internal.InitiatePaymentRequest,\n\t): Promise<Labrinth.Billing.Internal.InitiatePaymentResponse> {\n\t\treturn this.client.request<Labrinth.Billing.Internal.InitiatePaymentResponse>(\n\t\t\t'/billing/payment',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: request,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Refund a charge (Admin only)\n\t * POST /_internal/billing/charge/{id}/refund\n\t */\n\tpublic async refundCharge(\n\t\tid: string,\n\t\trefund: Labrinth.Billing.Internal.RefundChargeRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/billing/charge/${id}/refund`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: refund,\n\t\t})\n\t}\n\n\t/**\n\t * Credit subscriptions (Admin only)\n\t * POST /_internal/billing/credit\n\t */\n\tpublic async credit(request: Labrinth.Billing.Internal.CreditRequest): Promise<void> {\n\t\treturn this.client.request<void>('/billing/credit', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthCollectionsModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_collections'\n\t}\n\n\t/**\n\t * Get a collection by ID (v3)\n\t *\n\t * @param id - Collection ID\n\t * @returns Promise resolving to the collection data\n\t *\n\t * @example\n\t * ```typescript\n\t * const collection = await client.labrinth.collections.get('AANobbMI')\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Collections.Collection> {\n\t\treturn this.client.request<Labrinth.Collections.Collection>(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple collections by IDs (v3)\n\t *\n\t * @param ids - Array of collection IDs\n\t * @returns Promise resolving to array of collections\n\t *\n\t * @example\n\t * ```typescript\n\t * const collections = await client.labrinth.collections.getMultiple(['AANobbMI', 'BBNoobMI'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Collections.Collection[]> {\n\t\treturn this.client.request<Labrinth.Collections.Collection[]>(`/collections`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Edit a collection (v3)\n\t *\n\t * @param id - Collection ID\n\t * @param data - Collection update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.edit('AANobbMI', {\n\t * name: 'Updated name',\n\t * description: 'Updated description',\n\t * status: 'listed'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Collections.EditCollectionRequest): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a collection (v3)\n\t *\n\t * @param id - Collection ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.delete('AANobbMI')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Edit a collection icon (v3)\n\t *\n\t * @param id - Collection ID\n\t * @param icon - Icon file\n\t * @param ext - File extension (e.g., 'png', 'jpg')\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.editIcon('AANobbMI', iconFile, 'png')\n\t * ```\n\t */\n\tpublic async editIcon(id: string, icon: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}/icon?ext=${ext}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: icon,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a collection icon (v3)\n\t *\n\t * @param id - Collection ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.collections.deleteIcon('AANobbMI')\n\t * ```\n\t */\n\tpublic async deleteIcon(id: string): Promise<void> {\n\t\treturn this.client.request(`/collection/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthContentV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_content_v3'\n\t}\n\n\tpublic async resolve(\n\t\trequest: Labrinth.Content.v3.ResolveContentRequest,\n\t): Promise<Labrinth.Content.v3.ResolveContentPlan> {\n\t\treturn this.client.request<Labrinth.Content.v3.ResolveContentPlan>('/content/resolve', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthExternalProjectsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_external_projects_internal'\n\t}\n\n\tpublic async search(\n\t\tdata: Labrinth.ExternalProjects.Internal.SearchRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject[]> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject[]>(\n\t\t\t'/moderation/external-license/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getBySha1(\n\t\tsha1: string,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t`/moderation/external-license/by-sha1/${sha1}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async update(\n\t\tid: number,\n\t\tdata: Labrinth.ExternalProjects.Internal.UpdateLicenseRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t`/moderation/external-license/${id}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async addFile(\n\t\tdata: Labrinth.ExternalProjects.Internal.AddFileRequest,\n\t): Promise<Labrinth.ExternalProjects.Internal.ExternalProject> {\n\t\treturn this.client.request<Labrinth.ExternalProjects.Internal.ExternalProject>(\n\t\t\t'/moderation/external-license/file',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: data,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthFriendsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_friends_v3'\n\t}\n\n\t/**\n\t * Get friends and pending friend requests for the authenticated user\n\t *\n\t * @returns Promise resolving to friend relationships\n\t */\n\tpublic async list(): Promise<Labrinth.Friends.v3.UserFriend[]> {\n\t\treturn this.client.request<Labrinth.Friends.v3.UserFriend[]>('/friends', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Send or accept a friend request\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async add(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/friend/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Remove a friend or pending friend request\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async remove(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/friend/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\n\nexport class LabrinthGeoIpModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_geoip'\n\t}\n\n\tpublic async getCountry(): Promise<string | undefined> {\n\t\tconst trace = await this.client.request<string>('/trace', {\n\t\t\tapi: 'https://api.modrinth.com',\n\t\t\tversion: 'cdn-cgi',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t\tconst country = trace\n\t\t\t.split('\\n')\n\t\t\t.find((line) => line.startsWith('loc='))\n\t\t\t?.slice(4)\n\t\t\t.toUpperCase()\n\n\t\treturn country?.match(/^[A-Z]{2}$/) ? country : undefined\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthGlobalsInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_globals_internal'\n\t}\n\n\t/**\n\t * Get configured global non-secret variables for this backend instance\n\t *\n\t * @returns Promise resolving to the global configuration\n\t */\n\tpublic async get(): Promise<Labrinth.Globals.Internal.Globals> {\n\t\treturn this.client.request<Labrinth.Globals.Internal.Globals>(`/globals`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle } from '../../../types/upload'\nimport type { Labrinth } from '../types'\n\nfunction buildImageQueryParams(\n\text: Labrinth.Images.v3.ImageExtension,\n\ttarget: Labrinth.Images.v3.UploadImageParams,\n): Record<string, string> {\n\tconst params: Record<string, string> = {\n\t\text,\n\t\tcontext: target.context,\n\t}\n\tswitch (target.context) {\n\t\tcase 'project':\n\t\t\tparams.project_id = target.project_id\n\t\t\tbreak\n\t\tcase 'version':\n\t\t\tparams.version_id = target.version_id\n\t\t\tbreak\n\t\tcase 'thread_message':\n\t\t\tparams.thread_message_id = target.thread_message_id\n\t\t\tbreak\n\t\tcase 'report':\n\t\t\tif (target.report_id) params.report_id = target.report_id\n\t\t\tbreak\n\t}\n\treturn params\n}\n\nexport class LabrinthImagesV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_images_v3'\n\t}\n\n\tpublic uploadImage(\n\t\tfile: File | Blob,\n\t\text: Labrinth.Images.v3.ImageExtension,\n\t\ttarget: Labrinth.Images.v3.UploadImageParams,\n\t): UploadHandle<Labrinth.Images.v3.UploadedImage> {\n\t\treturn this.client.upload<Labrinth.Images.v3.UploadedImage>('/image', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tfile,\n\t\t\tparams: buildImageQueryParams(ext, target),\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthLimitsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_limits_v3'\n\t}\n\n\t/**\n\t * Get project creation limits for the authenticated user.\n\t */\n\tpublic async getProjectLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/projects', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get organization creation limits for the authenticated user.\n\t */\n\tpublic async getOrganizationLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/organizations', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get collection creation limits for the authenticated user.\n\t */\n\tpublic async getCollectionLimits(): Promise<Labrinth.Limits.v3.UserLimits> {\n\t\treturn this.client.request<Labrinth.Limits.v3.UserLimits>('/limits/collections', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthModerationInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_moderation_internal'\n\t}\n\n\tpublic async getProjects(\n\t\tparams: Labrinth.Moderation.Internal.ProjectsRequest = {},\n\t): Promise<Labrinth.Moderation.Internal.ProjectsResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ProjectsResponse>(\n\t\t\t'/moderation/projects',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getProjectIds(\n\t\tparams: Omit<Labrinth.Moderation.Internal.ProjectsRequest, 'count' | 'offset'> = {},\n\t): Promise<Labrinth.Moderation.Internal.ProjectIdsResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ProjectIdsResponse>(\n\t\t\t'/moderation/projects/ids',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async acquireLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockAcquireResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockAcquireResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async overrideLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockAcquireResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockAcquireResponse>(\n\t\t\t`/moderation/lock/${projectId}/override`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async releaseLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.ReleaseLockResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.ReleaseLockResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async checkLock(\n\t\tprojectId: string,\n\t): Promise<Labrinth.Moderation.Internal.LockStatusResponse> {\n\t\treturn this.client.request<Labrinth.Moderation.Internal.LockStatusResponse>(\n\t\t\t`/moderation/lock/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async setProjectJudgements(\n\t\tjudgements: Labrinth.Moderation.Internal.ProjectJudgements,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/project', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: judgements,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthNotificationsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_notifications_v2'\n\t}\n\n\t/**\n\t * Get all notifications for a user\n\t *\n\t * @param userId - The user's ID\n\t * @returns Promise resolving to the user's notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.notifications_v2.getUserNotifications('user123')\n\t * ```\n\t */\n\tpublic async getUserNotifications(\n\t\tuserId: string,\n\t): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/user/${userId}/notifications`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple notifications by their IDs\n\t *\n\t * @param ids - Array of notification IDs\n\t * @returns Promise resolving to an array of notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.notifications_v2.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/notifications?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Mark a single notification as read\n\t *\n\t * @param id - Notification ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.markAsRead('notif123')\n\t * ```\n\t */\n\tpublic async markAsRead(id: string): Promise<void> {\n\t\treturn this.client.request(`/notification/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t})\n\t}\n\n\t/**\n\t * Mark multiple notifications as read\n\t *\n\t * @param ids - Array of notification IDs to mark as read\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.markMultipleAsRead(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async markMultipleAsRead(ids: string[]): Promise<void> {\n\t\treturn this.client.request(`/notifications`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ids: JSON.stringify([...new Set(ids)]) },\n\t\t})\n\t}\n\n\t/**\n\t * Delete a single notification\n\t *\n\t * @param id - Notification ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.delete('notif123')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/notification/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Delete multiple notifications\n\t *\n\t * @param ids - Array of notification IDs to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.notifications_v2.deleteMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async deleteMultiple(ids: string[]): Promise<void> {\n\t\treturn this.client.request(`/notifications`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { ids: JSON.stringify([...new Set(ids)]) },\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthOAuthInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_oauth_internal'\n\t}\n\n\t/**\n\t * Get a user's OAuth applications\n\t *\n\t * @param userId - The user's ID\n\t * @returns Promise resolving to an array of the user's OAuth clients\n\t */\n\tpublic async getUserApps(userId: string): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClient[]>(\n\t\t\t`/user/${userId}/oauth_apps`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a single OAuth application by ID\n\t *\n\t * @param id - The OAuth client ID\n\t * @returns Promise resolving to the OAuth client\n\t */\n\tpublic async getApp(id: string): Promise<Labrinth.OAuth.Internal.OAuthClient> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClient>(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple OAuth applications by their IDs\n\t *\n\t * @param ids - Array of OAuth client IDs\n\t * @returns Promise resolving to an array of OAuth clients\n\t */\n\tpublic async getApps(ids: string[]): Promise<Labrinth.OAuth.Internal.OAuthClient[]> {\n\t\tif (ids.length === 0) {\n\t\t\treturn []\n\t\t}\n\n\t\t// bulk `/oauth/apps` is broken on backend, fetch by id instead\n\t\t// TODO: Remove this once the backend is fixed\n\t\tconst results = await Promise.all(ids.map((id) => this.getApp(id).catch(() => null)))\n\n\t\treturn results.filter((app): app is Labrinth.OAuth.Internal.OAuthClient => app !== null)\n\t}\n\n\t/**\n\t * Create a new OAuth application\n\t *\n\t * @param data - The OAuth app creation data\n\t * @returns Promise resolving to the created OAuth client with its client secret\n\t */\n\tpublic async createApp(\n\t\tdata: Labrinth.OAuth.Internal.CreateOAuthAppRequest,\n\t): Promise<Labrinth.OAuth.Internal.OAuthClientCreationResult> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientCreationResult>(`/oauth/app`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit an existing OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t * @param data - The fields to update\n\t */\n\tpublic async editApp(\n\t\tid: string,\n\t\tdata: Labrinth.OAuth.Internal.EditOAuthAppRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete an OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t */\n\tpublic async deleteApp(id: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update the icon for an OAuth application\n\t *\n\t * @param id - The OAuth client ID\n\t * @param file - The icon file\n\t * @param ext - The file extension (e.g. 'png', 'jpeg')\n\t */\n\tpublic async uploadAppIcon(id: string, file: File | Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/app/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Get the current user's OAuth authorizations\n\t *\n\t * @returns Promise resolving to an array of OAuth client authorizations\n\t */\n\tpublic async getAuthorizations(): Promise<Labrinth.OAuth.Internal.OAuthClientAuthorization[]> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientAuthorization[]>(\n\t\t\t`/oauth/authorizations`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Revoke an OAuth authorization for a client\n\t *\n\t * @param clientId - The OAuth client ID to revoke\n\t */\n\tpublic async revokeAuthorization(clientId: string): Promise<void> {\n\t\treturn this.client.request(`/oauth/authorizations`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { client_id: clientId },\n\t\t})\n\t}\n\n\t/**\n\t * Initialize an OAuth authorization flow\n\t *\n\t * Returns either an OAuthClientAccessRequest (if user needs to approve)\n\t * or a redirect URL string (if already authorized).\n\t *\n\t * @param params - The OAuth query parameters\n\t * @returns Promise resolving to an access request object or redirect URL string\n\t */\n\tpublic async authorize(params: {\n\t\tclient_id: string\n\t\tredirect_uri: string\n\t\tscope: string\n\t\tstate?: string\n\t}): Promise<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string> {\n\t\treturn this.client.request<Labrinth.OAuth.Internal.OAuthClientAccessRequest | string>(\n\t\t\t`/oauth/authorize`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t\tparams: params as Record<string, string>,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Accept an OAuth authorization request\n\t *\n\t * @param data - The flow ID to accept\n\t * @returns Promise resolving to a redirect URL string\n\t */\n\tpublic async accept(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {\n\t\treturn this.client.request<string>(`/oauth/accept`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Reject an OAuth authorization request\n\t *\n\t * @param data - The flow ID to reject\n\t * @returns Promise resolving to a redirect URL string\n\t */\n\tpublic async reject(data: Labrinth.OAuth.Internal.AcceptRejectRequest): Promise<string> {\n\t\treturn this.client.request<string>(`/oauth/reject`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthOrganizationsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_organizations_v3'\n\t}\n\n\t/**\n\t * Get an organization by ID or slug\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @returns Promise resolving to the organization data\n\t *\n\t * @example\n\t * ```typescript\n\t * const org = await client.labrinth.organizations_v3.get('my-org')\n\t * ```\n\t */\n\tpublic async get(idOrSlug: string): Promise<Labrinth.Organizations.v3.Organization> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization>(\n\t\t\t`/organization/${idOrSlug}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get an organization's projects\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @returns Promise resolving to the organization's projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.organizations_v3.getProjects('my-org')\n\t * ```\n\t */\n\tpublic async getProjects(idOrSlug: string): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(\n\t\t\t`/organization/${idOrSlug}/projects`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple organizations by their IDs\n\t *\n\t * @param ids - Array of organization IDs\n\t * @returns Promise resolving to an array of organizations\n\t *\n\t * @example\n\t * ```typescript\n\t * const orgs = await client.labrinth.organizations_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Organizations.v3.Organization[]> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization[]>(\n\t\t\t`/organizations?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Add a project to an organization\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @param request - The project to add\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.organizations_v3.addProject('my-org', { project_id: 'AABBCCDD' })\n\t * ```\n\t */\n\tpublic async addProject(\n\t\tidOrSlug: string,\n\t\trequest: Labrinth.Organizations.v3.AddProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/organization/${idOrSlug}/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a project from an organization\n\t *\n\t * @param idOrSlug - Organization ID or slug\n\t * @param projectId - Project ID to remove\n\t * @param data - Request body containing the new_owner user ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.organizations_v3.removeProject('my-org', 'proj123', { new_owner: 'user456' })\n\t * ```\n\t */\n\tpublic async removeProject(\n\t\tidOrSlug: string,\n\t\tprojectId: string,\n\t\tdata: Labrinth.Organizations.v3.RemoveProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/organization/${idOrSlug}/projects/${projectId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthPatsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_pats_v2'\n\t}\n\n\t/**\n\t * Get all personal access tokens for the authenticated user\n\t *\n\t * @returns Promise resolving to an array of PATs\n\t */\n\tpublic async list(): Promise<Labrinth.Pats.v2.PersonalAccessToken[]> {\n\t\treturn this.client.request<Labrinth.Pats.v2.PersonalAccessToken[]>('/pat', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a new personal access token\n\t *\n\t * @param data - The PAT creation request data\n\t * @returns Promise resolving to the newly created PAT (includes access_token)\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Pats.v2.CreatePatRequest,\n\t): Promise<Labrinth.Pats.v2.PersonalAccessToken> {\n\t\treturn this.client.request<Labrinth.Pats.v2.PersonalAccessToken>('/pat', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Modify an existing personal access token\n\t *\n\t * @param id - The PAT ID\n\t * @param data - The fields to update\n\t */\n\tpublic async modify(id: string, data: Labrinth.Pats.v2.ModifyPatRequest): Promise<void> {\n\t\treturn this.client.request(`/pat/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a personal access token\n\t *\n\t * @param id - The PAT ID\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/pat/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Override, RawDecimal } from '../../../utils/types'\nimport type { Labrinth } from '../types'\n\ntype RawPayoutBalance = Override<\n\tLabrinth.Payout.v3.PayoutBalance,\n\t{\n\t\tavailable: RawDecimal\n\t\twithdrawn_lifetime: RawDecimal\n\t\twithdrawn_ytd: RawDecimal\n\t\tpending: RawDecimal\n\t\tdates: Record<string, RawDecimal>\n\t}\n>\n\ntype RawTransactionItem =\n\t| Override<\n\t\t\tExtract<Labrinth.Payout.v3.TransactionItem, { type: 'withdrawal' }>,\n\t\t\t{\n\t\t\t\tamount: RawDecimal\n\t\t\t\tfee: RawDecimal | null\n\t\t\t}\n\t >\n\t| Override<\n\t\t\tExtract<Labrinth.Payout.v3.TransactionItem, { type: 'payout_available' }>,\n\t\t\t{\n\t\t\t\tamount: RawDecimal\n\t\t\t}\n\t >\n\nexport class LabrinthPayoutV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_payout_v3'\n\t}\n\n\t/**\n\t * Get the authenticated user's payout balance\n\t *\n\t * @returns Promise resolving to the user's payout balance\n\t */\n\tpublic async getBalance(): Promise<Labrinth.Payout.v3.PayoutBalance> {\n\t\tconst balance = await this.client.request<RawPayoutBalance>('/payout/balance', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\n\t\treturn {\n\t\t\t...balance,\n\t\t\tavailable: Number(balance.available),\n\t\t\twithdrawn_lifetime: Number(balance.withdrawn_lifetime),\n\t\t\twithdrawn_ytd: Number(balance.withdrawn_ytd),\n\t\t\tpending: Number(balance.pending),\n\t\t\tdates: Object.fromEntries(\n\t\t\t\tObject.entries(balance.dates).map(([date, amount]) => [date, Number(amount)]),\n\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Get the authenticated user's transaction history (withdrawals and payouts)\n\t *\n\t * @returns Promise resolving to an array of transaction items\n\t */\n\tpublic async getHistory(): Promise<Labrinth.Payout.v3.TransactionItem[]> {\n\t\tconst history = await this.client.request<RawTransactionItem[]>('/payout/history', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\n\t\treturn history.map((transaction) => {\n\t\t\tif (transaction.type === 'withdrawal') {\n\t\t\t\treturn {\n\t\t\t\t\t...transaction,\n\t\t\t\t\tamount: Number(transaction.amount),\n\t\t\t\t\tfee: transaction.fee === null ? null : Number(transaction.fee),\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\t...transaction,\n\t\t\t\tamount: Number(transaction.amount),\n\t\t\t}\n\t\t})\n\t}\n\n\t/**\n\t * Get available payout methods, optionally filtered by country\n\t *\n\t * @param country - Optional ISO country code to filter methods by supported countries\n\t * @returns Promise resolving to an array of payout methods\n\t */\n\tpublic async getMethods(country?: string): Promise<Labrinth.Payout.v3.PayoutMethod[]> {\n\t\treturn this.client.request<Labrinth.Payout.v3.PayoutMethod[]>('/payout/methods', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: country ? { country } : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Cancel a pending payout\n\t *\n\t * @param id - The payout ID to cancel\n\t */\n\tpublic async cancel(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/payout/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module.js'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthPayoutsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_payouts_v3'\n\t}\n\n\t/**\n\t * Get platform revenue data.\n\t *\n\t * @param params - Optional start/end date filters\n\t * @returns Promise resolving to platform revenue data\n\t */\n\tpublic async getPlatformRevenue(params?: {\n\t\tstart?: string\n\t\tend?: string\n\t}): Promise<Labrinth.Payouts.v3.RevenueResponse> {\n\t\treturn this.client.request<Labrinth.Payouts.v3.RevenueResponse>('/payout/platform_revenue', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: params as Record<string, string>,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthProjectsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_projects_v2'\n\t}\n\n\t/**\n\t * Get a project by ID or slug\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @returns Promise resolving to the project data\n\t *\n\t * @example\n\t * ```typescript\n\t * const project = await client.labrinth.projects_v2.get('sodium')\n\t * console.log(project.title) // \"Sodium\"\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Projects.v2.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project>(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Check that a project slug or ID exists and return its canonical project ID.\n\t *\n\t * @param idOrSlug - Project ID or slug (e.g. `sodium` or `AANobbMI`)\n\t */\n\tpublic async check(idOrSlug: string): Promise<Labrinth.Projects.v2.ProjectCheckResponse> {\n\t\tconst encoded = encodeURIComponent(idOrSlug)\n\t\treturn this.client.request<Labrinth.Projects.v2.ProjectCheckResponse>(\n\t\t\t`/project/${encoded}/check`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple projects by IDs\n\t *\n\t * @param ids - Array of project IDs or slugs\n\t * @returns Promise resolving to array of projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.projects_v2.getMultiple(['sodium', 'lithium', 'phosphor'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Search projects\n\t *\n\t * @param params - Search parameters (query, facets, filters, etc.)\n\t * @returns Promise resolving to search results\n\t *\n\t * @example\n\t * ```typescript\n\t * const results = await client.labrinth.projects_v2.search({\n\t * query: 'optimization',\n\t * facets: [['categories:optimization'], ['project_type:mod']],\n\t * limit: 20\n\t * })\n\t * ```\n\t */\n\tpublic async search(\n\t\tparams: Labrinth.Projects.v2.ProjectSearchParams,\n\t): Promise<Labrinth.Projects.v2.SearchResult> {\n\t\treturn this.client.request<Labrinth.Projects.v2.SearchResult>(`/search`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: {\n\t\t\t\t...params,\n\t\t\t\tfacets: params.facets ? JSON.stringify(params.facets) : undefined,\n\t\t\t\tnew_filters: params.new_filters ?? undefined,\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Edit a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Project update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.edit('sodium', {\n\t * description: 'Updated description'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Partial<Labrinth.Projects.v2.Project>): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.delete('my-project')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Get dependencies for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to dependency info (projects and versions)\n\t *\n\t * @example\n\t * ```typescript\n\t * const deps = await client.labrinth.projects_v2.getDependencies('sodium')\n\t * console.log(deps.projects) // dependent projects\n\t * console.log(deps.versions) // dependent versions\n\t * ```\n\t */\n\tpublic async getDependencies(id: string): Promise<Labrinth.Projects.v2.DependencyInfo> {\n\t\treturn this.client.request<Labrinth.Projects.v2.DependencyInfo>(`/project/${id}/dependencies`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param options - Gallery image options\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.createGalleryImage('sodium', imageFile, {\n\t * featured: true,\n\t * title: 'Screenshot 1',\n\t * description: 'Main menu with Sodium enabled'\n\t * })\n\t * ```\n\t */\n\tpublic async createGalleryImage(\n\t\tid: string,\n\t\tfile: Blob,\n\t\toptions: {\n\t\t\text: string\n\t\t\tfeatured: boolean\n\t\t\ttitle?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\text: options.ext,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.title) params.title = options.title\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tparams,\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the existing gallery image to edit\n\t * @param options - Gallery image options to update\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.editGalleryImage('sodium', 'https://cdn.modrinth.com/...', {\n\t * featured: false,\n\t * title: 'Updated title'\n\t * })\n\t * ```\n\t */\n\tpublic async editGalleryImage(\n\t\tid: string,\n\t\turl: string,\n\t\toptions: {\n\t\t\tfeatured: boolean\n\t\t\ttitle?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\turl,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.title) params.title = options.title\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a gallery image from a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the gallery image to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.deleteGalleryImage('sodium', 'https://cdn.modrinth.com/...')\n\t * ```\n\t */\n\tpublic async deleteGalleryImage(id: string, url: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { url },\n\t\t})\n\t}\n\n\t/**\n\t * Get random projects\n\t *\n\t * @param count - Number of random projects to return\n\t * @returns Promise resolving to an array of random projects\n\t */\n\tpublic async getRandom(count: number): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>('/projects_random', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { count: String(count) },\n\t\t})\n\t}\n\n\t/**\n\t * Bulk edit multiple projects at once\n\t *\n\t * @param ids - Array of project IDs to edit\n\t * @param data - Fields to update across all specified projects\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v2.bulkEdit(['id1', 'id2'], {\n\t * issues_url: 'https://github.com/issues',\n\t * source_url: null,\n\t * })\n\t * ```\n\t */\n\tpublic async bulkEdit(\n\t\tids: string[],\n\t\tdata: Labrinth.Projects.v2.BulkEditProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "/**\n * Data for API errors\n */\nexport type ApiErrorData = {\n\t/**\n\t * HTTP status code (if available)\n\t */\n\tstatusCode?: number\n\n\t/**\n\t * Original error that was caught\n\t */\n\toriginalError?: Error\n\n\t/**\n\t * Response data from the API (if available)\n\t */\n\tresponseData?: unknown\n\n\t/**\n\t * Error context (e.g., module name, operation being performed)\n\t */\n\tcontext?: string\n}\n\n/**\n * Modrinth V1 error response format\n * Used by kyros + archon APIs\n */\nexport type ModrinthErrorResponse = {\n\t/**\n\t * Error code/identifier\n\t */\n\terror: string\n\n\t/**\n\t * Human-readable error description\n\t */\n\tdescription: string\n\n\t/**\n\t * Optional context about where the error occurred\n\t */\n\tcontext?: string\n}\n\n/**\n * Type guard to check if an object is a ModrinthErrorResponse\n */\nexport function isModrinthErrorResponse(obj: unknown): obj is ModrinthErrorResponse {\n\tif (typeof obj !== 'object' || obj === null) {\n\t\treturn false\n\t}\n\tconst record = obj as Record<string, unknown>\n\treturn typeof record.error === 'string' && typeof record.description === 'string'\n}\n", "import type { ApiErrorData, ModrinthErrorResponse } from '../types/errors'\nimport { isModrinthErrorResponse } from '../types/errors'\n\n/**\n * Base error class for all Modrinth API errors\n */\nexport class ModrinthApiError extends Error {\n\t/**\n\t * HTTP status code (if available)\n\t */\n\treadonly statusCode?: number\n\n\t/**\n\t * Original error that was caught\n\t */\n\treadonly originalError?: Error\n\n\t/**\n\t * Response data from the API (if available)\n\t */\n\treadonly responseData?: unknown\n\n\t/**\n\t * Error context (e.g., module name, operation being performed)\n\t */\n\treadonly context?: string\n\n\tconstructor(message: string, data?: ApiErrorData) {\n\t\tsuper(message)\n\t\tthis.name = 'ModrinthApiError'\n\n\t\tthis.statusCode = data?.statusCode\n\t\tthis.originalError = data?.originalError\n\t\tthis.responseData = data?.responseData\n\t\tthis.context = data?.context\n\n\t\t// Maintains proper stack trace for where our error was thrown (only available on V8)\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ModrinthApiError)\n\t\t}\n\t}\n\n\t/**\n\t * Create a ModrinthApiError from an unknown error\n\t */\n\tstatic fromUnknown(error: unknown, context?: string): ModrinthApiError {\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn error\n\t\t}\n\n\t\tif (error instanceof Error) {\n\t\t\treturn new ModrinthApiError(error.message, {\n\t\t\t\toriginalError: error,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\treturn new ModrinthApiError(String(error), { context })\n\t}\n}\n\n/**\n * Error class for Modrinth server errors (kyros/archon)\n * Extends ModrinthApiError with V1 error response parsing\n */\nexport class ModrinthServerError extends ModrinthApiError {\n\t/**\n\t * V1 error information (if available)\n\t */\n\treadonly v1Error?: ModrinthErrorResponse\n\n\tconstructor(message: string, data?: ApiErrorData & { v1Error?: ModrinthErrorResponse }) {\n\t\t// If we have a V1 error, format the message nicely\n\t\tlet errorMessage = message\n\t\tif (data?.v1Error) {\n\t\t\terrorMessage = `[${data.v1Error.error}] ${data.v1Error.description}`\n\t\t\tif (data.v1Error.context) {\n\t\t\t\terrorMessage = `${data.v1Error.context}: ${errorMessage}`\n\t\t\t}\n\t\t}\n\n\t\tsuper(errorMessage, data)\n\t\tthis.name = 'ModrinthServerError'\n\t\tthis.v1Error = data?.v1Error\n\n\t\tif (Error.captureStackTrace) {\n\t\t\tError.captureStackTrace(this, ModrinthServerError)\n\t\t}\n\t}\n\n\t/**\n\t * Create a ModrinthServerError from response data\n\t */\n\tstatic fromResponse(\n\t\tstatusCode: number,\n\t\tresponseData: unknown,\n\t\tcontext?: string,\n\t): ModrinthServerError {\n\t\tconst v1Error = isModrinthErrorResponse(responseData) ? responseData : undefined\n\n\t\tlet message = `HTTP ${statusCode}`\n\t\tif (v1Error) {\n\t\t\tmessage = v1Error.description\n\t\t} else if (typeof responseData === 'string') {\n\t\t\tmessage = responseData\n\t\t}\n\n\t\treturn new ModrinthServerError(message, {\n\t\t\tstatusCode,\n\t\t\tresponseData,\n\t\t\tcontext,\n\t\t\tv1Error,\n\t\t})\n\t}\n\n\t/**\n\t * Create a ModrinthServerError from an unknown error\n\t */\n\tstatic fromUnknown(error: unknown, context?: string): ModrinthServerError {\n\t\tif (error instanceof ModrinthServerError) {\n\t\t\treturn error\n\t\t}\n\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn new ModrinthServerError(error.message, {\n\t\t\t\tstatusCode: error.statusCode,\n\t\t\t\toriginalError: error.originalError,\n\t\t\t\tresponseData: error.responseData,\n\t\t\t\tcontext: context ?? error.context,\n\t\t\t})\n\t\t}\n\n\t\tif (error instanceof Error) {\n\t\t\treturn new ModrinthServerError(error.message, {\n\t\t\t\toriginalError: error,\n\t\t\t\tcontext,\n\t\t\t})\n\t\t}\n\n\t\treturn new ModrinthServerError(String(error), { context })\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport { ModrinthApiError } from '../../../core/errors'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthProjectsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_projects_v3'\n\t}\n\n\t/**\n\t * Get a project by ID or slug (v3)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @returns Promise resolving to the v3 project data\n\t *\n\t * @example\n\t * ```typescript\n\t * const project = await client.labrinth.projects_v3.get('sodium')\n\t * console.log(project.project_types) // v3 field\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Projects.v3.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project>(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a project's dependencies (v3)\n\t *\n\t * Returns all projects and versions that are dependencies of this project's versions.\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to dependency data with projects and versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const deps = await client.labrinth.projects_v3.getDependencies('sodium')\n\t * console.log(deps.projects) // Array of project objects\n\t * console.log(deps.versions) // Array of version objects\n\t * ```\n\t */\n\tpublic async getDependencies(id: string): Promise<Labrinth.Projects.v3.ProjectDependencies> {\n\t\treturn this.client.request<Labrinth.Projects.v3.ProjectDependencies>(\n\t\t\t`/project/${id}/dependencies`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get multiple projects by IDs (v3)\n\t *\n\t * @param ids - Array of project IDs or slugs\n\t * @returns Promise resolving to array of v3 projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.projects_v3.getMultiple(['sodium', 'lithium'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(`/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Search projects (v3)\n\t *\n\t * @param params - Search parameters\n\t * @returns Promise resolving to v3 search results\n\t */\n\tpublic async search(\n\t\tparams: Labrinth.Search.SearchParams,\n\t\toptions?: {\n\t\t\theaders?: Record<string, string>\n\t\t},\n\t): Promise<Labrinth.Search.v3.SearchResults> {\n\t\treturn this.client.request<Labrinth.Search.v3.SearchResults>(`/search`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\theaders: options?.headers,\n\t\t\tparams: {\n\t\t\t\t...params,\n\t\t\t\tfacets: params.facets ? JSON.stringify(params.facets) : undefined,\n\t\t\t},\n\t\t})\n\t}\n\n\t/**\n\t * Edit a project (v3)\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Project update data (v3 fields)\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.edit('sodium', {\n\t * environment: 'client_and_server'\n\t * })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Projects.v3.EditProjectRequest): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get the organization that owns a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to the organization data, or null if the project is not owned by an organization\n\t */\n\tpublic async getOrganization(id: string): Promise<Labrinth.Projects.v3.Organization | null> {\n\t\ttry {\n\t\t\treturn await this.client.request<Labrinth.Projects.v3.Organization>(\n\t\t\t\t`/project/${id}/organization`,\n\t\t\t\t{ api: 'labrinth', version: 3, method: 'GET' },\n\t\t\t)\n\t\t} catch (error) {\n\t\t\t// 404 means the project is not owned by an organization\n\t\t\tif (error instanceof ModrinthApiError && error.statusCode === 404) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t/**\n\t * Get the team members of a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to an array of team members\n\t */\n\tpublic async getMembers(id: string): Promise<Labrinth.Projects.v3.TeamMember[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.TeamMember[]>(`/project/${id}/members`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\tpublic async createServerProject(\n\t\tdata: Labrinth.Projects.v3.CreateServerProjectRequest,\n\t): Promise<Labrinth.Projects.v3.Project> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project>(`/project`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PUT',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteProject('my-project')\n\t * ```\n\t */\n\tpublic async deleteProject(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Change the icon of a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param ext - File extension (e.g., 'png', 'jpeg', 'gif', 'webp')\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.changeIcon('sodium', imageFile, 'png')\n\t * ```\n\t */\n\tpublic async changeIcon(id: string, file: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete the icon of a project\n\t *\n\t * @param id - Project ID or slug\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteIcon('sodium')\n\t * ```\n\t */\n\tpublic async deleteIcon(id: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Create a gallery image for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param file - Image file to upload\n\t * @param options - Gallery image options\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.createGalleryImage('sodium', imageFile, {\n\t * featured: true,\n\t * name: 'Screenshot 1',\n\t * description: 'Main menu with Sodium enabled'\n\t * })\n\t * ```\n\t */\n\tpublic async createGalleryImage(\n\t\tid: string,\n\t\tfile: Blob,\n\t\toptions: {\n\t\t\text: string\n\t\t\tfeatured: boolean\n\t\t\tname?: string\n\t\t\tdescription?: string\n\t\t\tordering?: number\n\t\t},\n\t): Promise<void> {\n\t\tconst params: Record<string, string> = {\n\t\t\text: options.ext,\n\t\t\tfeatured: String(options.featured),\n\t\t}\n\t\tif (options.name) params.name = options.name\n\t\tif (options.description) params.description = options.description\n\t\tif (options.ordering !== undefined) params.ordering = String(options.ordering)\n\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tparams,\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a gallery image from a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param url - URL of the gallery image to delete\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.deleteGalleryImage('sodium', 'https://cdn.modrinth.com/...')\n\t * ```\n\t */\n\tpublic async deleteGalleryImage(id: string, url: string): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/gallery`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t\tparams: { url },\n\t\t})\n\t}\n\n\t/**\n\t * Get content disclosures for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @returns Promise resolving to the project's disclosures\n\t *\n\t * @example\n\t * ```typescript\n\t * const { disclosures } = await client.labrinth.projects_v3.getDisclosures('sodium')\n\t * ```\n\t */\n\tpublic async getDisclosures(id: string): Promise<Labrinth.Projects.v3.GetProjectDisclosures> {\n\t\treturn this.client.request<Labrinth.Projects.v3.GetProjectDisclosures>(\n\t\t\t`/project/${id}/disclosures`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Modify content disclosures for a project\n\t *\n\t * @param id - Project ID or slug\n\t * @param data - Disclosures to set and types to remove\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.projects_v3.modifyDisclosures('sodium', {\n\t * set: [{ type: 'ai_content', uses: ['text'], note: 'Translations are AI-generated.' }],\n\t * remove: ['advertisements'],\n\t * })\n\t * ```\n\t */\n\tpublic async modifyDisclosures(\n\t\tid: string,\n\t\tdata: Labrinth.Projects.v3.ModifyProjectDisclosures,\n\t): Promise<void> {\n\t\treturn this.client.request(`/project/${id}/disclosures`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthReportsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_reports_v3'\n\t}\n\n\t/**\n\t * Get a report by ID\n\t *\n\t * @param id - Report ID\n\t * @returns Promise resolving to the report data\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.reports_v3.get('abc123')\n\t * ```\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Reports.v3.Report> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report>(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * List reports for the current user (or all reports if moderator)\n\t *\n\t * @param params - Optional query parameters for count, offset, and whether to show all reports\n\t * @returns Promise resolving to an array of reports\n\t *\n\t * @example\n\t * ```typescript\n\t * const reports = await client.labrinth.reports_v3.list({ count: 100 })\n\t * ```\n\t */\n\tpublic async list(\n\t\tparams?: Labrinth.Reports.v3.ListReportsParams,\n\t): Promise<Labrinth.Reports.v3.Report[]> {\n\t\tconst queryParams: Record<string, string> = {}\n\t\tif (params?.count != null) queryParams.count = String(params.count)\n\t\tif (params?.offset != null) queryParams.offset = String(params.offset)\n\t\tif (params?.all != null) queryParams.all = String(params.all)\n\n\t\treturn this.client.request<Labrinth.Reports.v3.Report[]>(`/report`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(queryParams).length > 0 ? queryParams : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple reports by IDs\n\t *\n\t * @param ids - Array of report IDs\n\t * @returns Promise resolving to an array of reports\n\t *\n\t * @example\n\t * ```typescript\n\t * const reports = await client.labrinth.reports_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Reports.v3.Report[]> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report[]>(\n\t\t\t`/reports?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Create a new report\n\t *\n\t * @param data - Report creation data\n\t * @returns Promise resolving to the created report\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.reports_v3.create({\n\t * report_type: 'spam',\n\t * item_id: 'project123',\n\t * item_type: 'project',\n\t * body: 'This project is spam',\n\t * })\n\t * ```\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Reports.v3.CreateReportRequest,\n\t): Promise<Labrinth.Reports.v3.Report> {\n\t\treturn this.client.request<Labrinth.Reports.v3.Report>(`/report`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a report\n\t *\n\t * @param id - Report ID\n\t * @param data - Report edit data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.reports_v3.edit('abc123', { closed: true })\n\t * ```\n\t */\n\tpublic async edit(id: string, data: Labrinth.Reports.v3.EditReportRequest): Promise<void> {\n\t\treturn this.client.request(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a report (moderator only)\n\t *\n\t * @param id - Report ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.reports_v3.delete('abc123')\n\t * ```\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/report/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthServerPingInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_server_ping_internal'\n\t}\n\n\t/**\n\t * Ping a Minecraft Java server\n\t * POST /_internal/server-ping/minecraft-java\n\t */\n\tpublic async pingMinecraftJava(\n\t\trequest: Labrinth.ServerPing.Internal.MinecraftJavaPingRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/server-ping/minecraft-java', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthSessionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_sessions_v2'\n\t}\n\n\t/**\n\t * List all sessions for the authenticated user\n\t *\n\t * @returns Promise resolving to an array of sessions\n\t */\n\tpublic async list(): Promise<Labrinth.Sessions.v2.Session[]> {\n\t\treturn this.client.request<Labrinth.Sessions.v2.Session[]>('/session/list', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Delete (revoke) a session\n\t *\n\t * @param id - The session ID\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request(`/session/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthStateModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_state'\n\t}\n\n\t/**\n\t * Build the complete generated state by fetching from multiple endpoints\n\t *\n\t * @returns Promise resolving to the generated state containing categories, loaders, products, etc.\n\t *\n\t * @example\n\t * ```typescript\n\t * const state = await client.labrinth.state.build()\n\t * console.log(state.products) // Available billing products\n\t * ```\n\t */\n\tpublic async build(): Promise<Labrinth.State.GeneratedState> {\n\t\tconst errors: unknown[] = []\n\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\tconst handleError = (err: any, defaultValue: any, endpoint: string) => {\n\t\t\tconsole.error('Error fetching state data:', err)\n\t\t\terrors.push({ endpoint, error: err })\n\t\t\treturn defaultValue\n\t\t}\n\n\t\t// TODO: as we add new modules, move these raw requests to actual\n\t\t// abstractions\n\t\tconst [\n\t\t\tcategories,\n\t\t\tloaders,\n\t\t\tgameVersions,\n\t\t\tdonationPlatforms,\n\t\t\treportTypes,\n\t\t\thomePageProjects,\n\t\t\thomePageSearch,\n\t\t\thomePageNotifs,\n\t\t\tproducts,\n\t\t\tmuralBankDetails,\n\t\t\tiso3166Data,\n\t\t\tpayoutMethods,\n\t\t\tglobals,\n\t\t] = await Promise.all([\n\t\t\t// Tag endpoints\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.Category[]>('/tag/category', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/category')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.Loader[]>('/tag/loader', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/loader')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.GameVersion[]>('/tag/game_version', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/game_version')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Tags.v2.DonationPlatform[]>('/tag/donation_platform', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/donation_platform')),\n\t\t\tthis.client\n\t\t\t\t.request<string[]>('/tag/report_type', { api: 'labrinth', version: 2, method: 'GET' })\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/tag/report_type')),\n\n\t\t\t// Homepage data\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Projects.v2.Project[]>('/projects_random', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { count: '60' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v2/projects_random')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Search.v2.SearchResults>('/search', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { limit: '3', query: 'leave', index: 'relevance' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, {} as Labrinth.Search.v2.SearchResults, '/v2/search')),\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.Search.v2.SearchResults>('/search', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 2,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: { limit: '3', query: '', index: 'updated' },\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, {} as Labrinth.Search.v2.SearchResults, '/v2/search')),\n\n\t\t\t// Internal billing/mural endpoints\n\t\t\tthis.client.labrinth.billing_internal\n\t\t\t\t.getProducts()\n\t\t\t\t.catch((err) => handleError(err, [], '/_internal/billing/products')),\n\t\t\tthis.client\n\t\t\t\t.request<{ bankDetails: Record<string, { bankNames: string[] }> }>('/mural/bank-details', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 'internal',\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, null, '/_internal/mural/bank-details')),\n\n\t\t\t// ISO3166 country and subdivision data\n\t\t\tthis.client.iso3166.data\n\t\t\t\t.build()\n\t\t\t\t.catch((err) => handleError(err, { countries: [], subdivisions: {} }, 'iso3166/data')),\n\n\t\t\t// Payout methods for tremendous ID mapping\n\t\t\tthis.client\n\t\t\t\t.request<Labrinth.State.PayoutMethodInfo[]>('/payout/methods', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 3,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, [], '/v3/payout/methods')),\n\n\t\t\t// Global configuration\n\t\t\tthis.client\n\t\t\t\t.request<{ tax_compliance_thresholds: Record<string, number> }>('/globals', {\n\t\t\t\t\tapi: 'labrinth',\n\t\t\t\t\tversion: 'internal',\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t})\n\t\t\t\t.catch((err) => handleError(err, null, '/_internal/globals')),\n\t\t])\n\n\t\tconst tremendousIdMap = Object.fromEntries(\n\t\t\t(payoutMethods as Labrinth.State.PayoutMethodInfo[])\n\t\t\t\t.filter((m) => m.type === 'tremendous')\n\t\t\t\t.map((m) => [m.id, { name: m.name, image_url: m.image_logo_url }]),\n\t\t)\n\n\t\treturn {\n\t\t\tcategories,\n\t\t\tloaders,\n\t\t\tgameVersions,\n\t\t\tdonationPlatforms,\n\t\t\treportTypes,\n\t\t\thomePageProjects,\n\t\t\thomePageSearch,\n\t\t\thomePageNotifs,\n\t\t\tproducts,\n\t\t\t// Always emit a value: `undefined` is dropped by JSON.stringify, and consumers\n\t\t\t// import these keys by name from the generated state.\n\t\t\tmuralBankDetails: muralBankDetails?.bankDetails ?? {},\n\t\t\ttremendousIdMap,\n\t\t\tcountries: iso3166Data.countries,\n\t\t\tsubdivisions: iso3166Data.subdivisions,\n\t\t\ttaxComplianceThresholds: globals?.tax_compliance_thresholds ?? {},\n\t\t\terrors,\n\t\t}\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTechReviewInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_tech_review_internal'\n\t}\n\n\t/**\n\t * Search for projects awaiting technical review.\n\t *\n\t * Returns a flat list of file reports with associated project data, ownership\n\t * information, and moderation threads provided as lookup maps.\n\t *\n\t * @param params - Search parameters including pagination, filters, and sorting\n\t * @returns Response object containing reports array and lookup maps for projects, threads, and ownership\n\t *\n\t * @example\n\t * ```typescript\n\t * const response = await client.labrinth.tech_review_internal.searchProjects({\n\t * limit: 20,\n\t * page: 0,\n\t * sort_by: 'created_asc',\n\t * filter: {\n\t * project_type: ['mod', 'modpack']\n\t * }\n\t * })\n\t * // Access reports: response.reports\n\t * // Access project by ID: response.projects[projectId]\n\t * ```\n\t */\n\tpublic async searchProjects(\n\t\tparams: Labrinth.TechReview.Internal.SearchProjectsRequest,\n\t): Promise<Labrinth.TechReview.Internal.SearchResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.SearchResponse>(\n\t\t\t'/moderation/tech-review/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get detailed information about a specific file report.\n\t *\n\t * @param reportId - The Delphi report ID\n\t * @returns Full report with all issues and details\n\t *\n\t * @example\n\t * ```typescript\n\t * const report = await client.labrinth.tech_review_internal.getReport('report-123')\n\t * console.log(report.file_name, report.issues.length)\n\t * ```\n\t */\n\tpublic async getReport(reportId: string): Promise<Labrinth.TechReview.Internal.FileReport> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.FileReport>(\n\t\t\t`/moderation/tech-review/report/${reportId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get detailed information about a specific issue.\n\t *\n\t * @param issueId - The issue ID\n\t * @returns Issue with all its details\n\t *\n\t * @example\n\t * ```typescript\n\t * const issue = await client.labrinth.tech_review_internal.getIssue('issue-123')\n\t * console.log(issue.issue_type, issue.status)\n\t * ```\n\t */\n\tpublic async getIssue(issueId: string): Promise<Labrinth.TechReview.Internal.FileIssue> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.FileIssue>(\n\t\t\t`/moderation/tech-review/issue/${issueId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update the status of a technical review issue detail.\n\t *\n\t * Allows moderators to mark an individual issue detail as safe (false positive) or unsafe (malicious).\n\t *\n\t * @param detailId - The ID of the issue detail to update\n\t * @param data - The verdict for the detail\n\t * @returns Promise that resolves when the update is complete\n\t */\n\tpublic async updateIssueDetail(\n\t\tdetailId: string,\n\t\tdata: Labrinth.TechReview.Internal.UpdateIssueDetailRequest,\n\t): Promise<void> {\n\t\treturn this.updateIssueDetails([{ detail_id: detailId, verdict: data.verdict }])\n\t}\n\n\tpublic async updateIssueDetails(\n\t\tdata: Labrinth.TechReview.Internal.UpdateIssueRequest[],\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/tech-review/issue-detail', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\tpublic async updateGlobalIssueDetails(\n\t\tdata: Labrinth.TechReview.Internal.UpdateGlobalIssueRequest[],\n\t): Promise<void> {\n\t\treturn this.client.request<void>('/moderation/tech-review/global-issue-detail', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\tpublic async searchGlobalIssueDetails(\n\t\tparams: Labrinth.TechReview.Internal.SearchGlobalIssueDetailsRequest,\n\t): Promise<Labrinth.TechReview.Internal.SearchGlobalIssueDetailsResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.SearchGlobalIssueDetailsResponse>(\n\t\t\t'/moderation/tech-review/global-issue-detail/search',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getGlobalIssueDetail(\n\t\tparams: Labrinth.TechReview.Internal.GetGlobalIssueDetailRequest,\n\t): Promise<Labrinth.TechReview.Internal.GetGlobalIssueDetailResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.GetGlobalIssueDetailResponse>(\n\t\t\t'/moderation/tech-review/global-issue-detail/local-traces',\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody: params,\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async submitProject(\n\t\tprojectId: string,\n\t\tdata: Labrinth.TechReview.Internal.SubmitProjectRequest,\n\t): Promise<void> {\n\t\treturn this.client.request<void>(`/moderation/tech-review/submit/${projectId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get the project report and thread for a specific project.\n\t *\n\t * @param projectId - The project ID\n\t * @returns The project report (may be null if no reports exist) and the moderation thread\n\t */\n\tpublic async getProjectReport(\n\t\tprojectId: string,\n\t): Promise<Labrinth.TechReview.Internal.ProjectReportResponse> {\n\t\treturn this.client.request<Labrinth.TechReview.Internal.ProjectReportResponse>(\n\t\t\t`/moderation/tech-review/project/${projectId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthThreadsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_threads_v3'\n\t}\n\n\t/**\n\t * Get a thread by ID (v3)\n\t *\n\t * @param id - Thread ID\n\t * @returns Promise resolving to the thread data\n\t *\n\t * @example\n\t * ```typescript\n\t * const thread = await client.labrinth.threads_v3.getThread('abc123')\n\t * console.log(thread.messages)\n\t * ```\n\t */\n\tpublic async getThread(id: string): Promise<Labrinth.Threads.v3.Thread> {\n\t\treturn this.client.request<Labrinth.Threads.v3.Thread>(`/thread/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple threads by IDs (v3)\n\t *\n\t * @param ids - Array of thread IDs\n\t * @returns Promise resolving to an array of threads\n\t *\n\t * @example\n\t * ```typescript\n\t * const threads = await client.labrinth.threads_v3.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Threads.v3.Thread[]> {\n\t\treturn this.client.request<Labrinth.Threads.v3.Thread[]>(\n\t\t\t`/threads?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Send a message to a thread (v3)\n\t *\n\t * @param id - Thread ID\n\t * @param message - Message body to send\n\t * @returns Promise resolving when message is sent\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.threads_v3.sendMessage('abc123', {\n\t * body: { type: 'text', body: 'Hello!' }\n\t * })\n\t * ```\n\t */\n\tpublic async sendMessage(\n\t\tid: string,\n\t\tmessage: Labrinth.Threads.v3.SendMessageRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/thread/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t\tbody: message,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a message from a thread (v3)\n\t *\n\t * @param messageId - Message ID\n\t * @returns Promise resolving when message is deleted\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.threads_v3.deleteMessage('msg123')\n\t * ```\n\t */\n\tpublic async deleteMessage(messageId: string): Promise<void> {\n\t\treturn this.client.request(`/message/${messageId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthUsersV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_users_v2'\n\t}\n\n\t/**\n\t * Get a user by ID or username\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to the user data\n\t *\n\t * @example\n\t * ```typescript\n\t * const user = await client.labrinth.users_v2.get('my_user')\n\t * ```\n\t */\n\tpublic async get(idOrUsername: string): Promise<Labrinth.Users.v2.User> {\n\t\treturn this.client.request<Labrinth.Users.v2.User>(`/user/${idOrUsername}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple users by their IDs\n\t *\n\t * @param ids - Array of user IDs\n\t * @returns Promise resolving to an array of users\n\t *\n\t * @example\n\t * ```typescript\n\t * const users = await client.labrinth.users_v2.getMultiple(['id1', 'id2'])\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Users.v2.User[]> {\n\t\treturn this.client.request<Labrinth.Users.v2.User[]>(\n\t\t\t`/users?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's projects\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v2.getProjects('my_user')\n\t * ```\n\t */\n\tpublic async getProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/projects`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a user's organizations\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's organizations\n\t *\n\t * @example\n\t * ```typescript\n\t * const orgs = await client.labrinth.users_v2.getOrganizations('my_user')\n\t * ```\n\t */\n\tpublic async getOrganizations(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Organizations.v3.Organization[]> {\n\t\treturn this.client.request<Labrinth.Organizations.v3.Organization[]>(\n\t\t\t`/user/${idOrUsername}/organizations`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's collections\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's collections\n\t *\n\t * @example\n\t * ```typescript\n\t * const collections = await client.labrinth.users_v2.getCollections('my_user')\n\t * ```\n\t */\n\tpublic async getCollections(idOrUsername: string): Promise<Labrinth.Collections.Collection[]> {\n\t\treturn this.client.request<Labrinth.Collections.Collection[]>(\n\t\t\t`/user/${idOrUsername}/collections`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's notifications\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's notifications\n\t *\n\t * @example\n\t * ```typescript\n\t * const notifications = await client.labrinth.users_v2.getNotifications('my_user')\n\t * ```\n\t */\n\tpublic async getNotifications(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Notifications.v2.Notification[]> {\n\t\treturn this.client.request<Labrinth.Notifications.v2.Notification[]>(\n\t\t\t`/user/${idOrUsername}/notifications`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get projects a user follows\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of followed projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v2.getFollowedProjects('my_user')\n\t * ```\n\t */\n\tpublic async getFollowedProjects(idOrUsername: string): Promise<Labrinth.Projects.v2.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v2.Project[]>(`/user/${idOrUsername}/follows`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Update a user\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @param data - Fields to update\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.users_v2.patch('my_user', { role: 'admin' })\n\t * ```\n\t */\n\tpublic async patch(\n\t\tidOrUsername: string,\n\t\tdata: Partial<Pick<Labrinth.Users.v2.User, 'badges' | 'bio' | 'role' | 'username'>>,\n\t): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Change a user's avatar.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @param file - Image file to upload\n\t * @param ext - File extension (e.g., 'png', 'jpeg', 'gif', 'webp')\n\t */\n\tpublic async changeIcon(idOrUsername: string, file: Blob, ext: string): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tparams: { ext },\n\t\t\tbody: file,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a user's avatar.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t */\n\tpublic async deleteIcon(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/user/${idOrUsername}/icon`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthUsersV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_users_v3'\n\t}\n\n\t/**\n\t * Get the authenticated user.\n\t * GET /v3/user\n\t */\n\tpublic async getAuthenticated(): Promise<Labrinth.Users.v3.User> {\n\t\treturn this.client.request<Labrinth.Users.v3.User>('/user', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get a user by ID or username\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to the user data\n\t *\n\t * GET /v3/user/{id}\n\t */\n\tpublic async get(idOrUsername: string): Promise<Labrinth.Users.v3.User> {\n\t\treturn this.client.request<Labrinth.Users.v3.User>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's account preferences. The authenticated user may access their\n\t * own preferences, while moderators may access another user's preferences.\n\t *\n\t * GET /v3/user/{id}/preferences\n\t */\n\tpublic async getPreferences(idOrUsername: string): Promise<Labrinth.Users.v3.UserPreferences> {\n\t\treturn this.client.request<Labrinth.Users.v3.UserPreferences>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/preferences`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Update a user's account preferences and return the fully resolved result.\n\t *\n\t * PATCH /v3/user/{id}/preferences\n\t */\n\tpublic async patchPreferences(\n\t\tidOrUsername: string,\n\t\tpreferences: Labrinth.Users.v3.PartialUserPreferences,\n\t): Promise<Labrinth.Users.v3.UserPreferences> {\n\t\treturn this.client.request<Labrinth.Users.v3.UserPreferences>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/preferences`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'PATCH',\n\t\t\t\tbody: preferences,\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Search users by username prefix.\n\t *\n\t * @param query - Username search query\n\t * @returns Promise resolving to compact user search results\n\t *\n\t * GET /v3/users/search?query=:query\n\t */\n\tpublic async search(query: string): Promise<Labrinth.Users.v3.SearchUser[]> {\n\t\treturn this.client.request<Labrinth.Users.v3.SearchUser[]>(\n\t\t\t`/users/search?query=${encodeURIComponent(query)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get a user's projects.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of the user's projects\n\t *\n\t * GET /v3/user/{id}/projects\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v3.getProjects('my_user')\n\t * ```\n\t */\n\tpublic async getProjects(idOrUsername: string): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/projects`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get projects a user follows.\n\t *\n\t * @param idOrUsername - The user's ID or username\n\t * @returns Promise resolving to an array of followed projects\n\t *\n\t * GET /v3/user/{id}/follows\n\t *\n\t * @example\n\t * ```typescript\n\t * const projects = await client.labrinth.users_v3.getFollowedProjects('my_user')\n\t * ```\n\t */\n\tpublic async getFollowedProjects(idOrUsername: string): Promise<Labrinth.Projects.v3.Project[]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.Project[]>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/follows`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Get all projects the authenticated user can access directly or through\n\t * their organizations.\n\t *\n\t * @param idOrUsername - User ID or username. Must be the authenticated user.\n\t *\n\t * GET /v3/user/{id}/all-projects\n\t */\n\tpublic async getAllProjects(\n\t\tidOrUsername: string,\n\t): Promise<Labrinth.Users.v3.AllProjectsResponse> {\n\t\treturn this.client.request<Labrinth.Users.v3.AllProjectsResponse>(\n\t\t\t`/user/${encodeURIComponent(idOrUsername)}/all-projects`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthVersionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_versions_v2'\n\t}\n\n\t/**\n\t * Get versions for a project (v2)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @param options - Optional query parameters to filter versions\n\t * @returns Promise resolving to an array of v2 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v2.getProjectVersions('sodium')\n\t * const filteredVersions = await client.labrinth.versions_v2.getProjectVersions('sodium', {\n\t * game_versions: ['1.20.1'],\n\t * loaders: ['fabric'],\n\t * include_changelog: false\n\t * })\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getProjectVersions(\n\t\tid: string,\n\t\toptions?: Labrinth.Versions.v2.GetProjectVersionsParams,\n\t): Promise<Labrinth.Versions.v2.Version[]> {\n\t\tconst params: Record<string, string> = {}\n\t\tif (options?.game_versions?.length) {\n\t\t\tparams.game_versions = JSON.stringify(options.game_versions)\n\t\t}\n\t\tif (options?.loaders?.length) {\n\t\t\tparams.loaders = JSON.stringify(options.loaders)\n\t\t}\n\t\tif (options?.include_changelog === false) {\n\t\t\tparams.include_changelog = 'false'\n\t\t}\n\t\tif (options?.limit != null) {\n\t\t\tparams.limit = String(options.limit)\n\t\t}\n\t\tif (options?.offset != null) {\n\t\t\tparams.offset = String(options.offset)\n\t\t}\n\n\t\treturn this.client.request<Labrinth.Versions.v2.Version[]>(`/project/${id}/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific version by ID (v2)\n\t *\n\t * @param id - Version ID\n\t * @returns Promise resolving to the v2 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v2.getVersion('DXtmvS8i')\n\t * console.log(version.version_number)\n\t * ```\n\t */\n\tpublic async getVersion(id: string): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(`/version/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\tpublic async getVersionFromFileHash(\n\t\thash: string,\n\t\talgorithm: keyof Labrinth.Versions.v2.VersionFileHash,\n\t): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(`/version_file/${hash}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { algorithm },\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple versions by IDs (v2)\n\t *\n\t * @param ids - Array of version IDs\n\t * @returns Promise resolving to an array of v2 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v2.getVersions(['DXtmvS8i', 'abc123'])\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getVersions(ids: string[]): Promise<Labrinth.Versions.v2.Version[]> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version[]>(`/versions`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Get a version from a project by version ID or number (v2)\n\t *\n\t * @param projectId - Project ID or slug\n\t * @param versionId - Version ID or version number\n\t * @returns Promise resolving to the v2 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v2.getVersionFromIdOrNumber('sodium', 'DXtmvS8i')\n\t * const versionByNumber = await client.labrinth.versions_v2.getVersionFromIdOrNumber('sodium', '0.4.12')\n\t * ```\n\t */\n\tpublic async getVersionFromIdOrNumber(\n\t\tprojectId: string,\n\t\tversionId: string,\n\t): Promise<Labrinth.Versions.v2.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v2.Version>(\n\t\t\t`/project/${projectId}/version/${versionId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 2,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Delete a version by ID (v2)\n\t *\n\t * @param versionId - Version ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.versions_v2.deleteVersion('DXtmvS8i')\n\t * ```\n\t */\n\tpublic async deleteVersion(versionId: string): Promise<void> {\n\t\treturn this.client.request(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { UploadHandle } from '../../../types/upload'\nimport type { Labrinth } from '../types'\n\nconst VERSION_UPLOAD_TIMEOUT_MS = 30 * 60 * 1000\n\nexport class LabrinthVersionsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_versions_v3'\n\t}\n\n\t/**\n\t * Get versions for a project (v3)\n\t *\n\t * @param id - Project ID or slug (e.g., 'sodium' or 'AANobbMI')\n\t * @param options - Optional query parameters to filter versions\n\t * @returns Promise resolving to an array of v3 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v3.getProjectVersions('sodium')\n\t * const filteredVersions = await client.labrinth.versions_v3.getProjectVersions('sodium', {\n\t * game_versions: ['1.20.1'],\n\t * loaders: ['fabric']\n\t * })\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getProjectVersions(\n\t\tid: string,\n\t\toptions?: Labrinth.Versions.v3.GetProjectVersionsParams,\n\t): Promise<Labrinth.Versions.v3.Version[]> {\n\t\tconst params: Record<string, string | boolean> = {}\n\t\tif (options?.game_versions?.length) {\n\t\t\tparams.game_versions = JSON.stringify(options.game_versions)\n\t\t}\n\t\tif (options?.loaders?.length) {\n\t\t\tparams.loaders = JSON.stringify(options.loaders)\n\t\t}\n\t\tif (options?.include_changelog === false) {\n\t\t\tparams.include_changelog = 'false'\n\t\t}\n\t\tif (options?.limit != null) {\n\t\t\tparams.limit = String(options.limit)\n\t\t}\n\t\tif (options?.offset != null) {\n\t\t\tparams.offset = String(options.offset)\n\t\t}\n\n\t\treturn this.client.request<Labrinth.Versions.v3.Version[]>(`/project/${id}/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: options?.apiVersion ?? 2,\n\t\t\tmethod: 'GET',\n\t\t\tparams: Object.keys(params).length > 0 ? params : undefined,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific version by ID (v3)\n\t *\n\t * @param id - Version ID\n\t * @returns Promise resolving to the v3 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v3.getVersion('DXtmvS8i')\n\t * console.log(version.version_number)\n\t * ```\n\t */\n\tpublic async getVersion(id: string): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(`/version/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Get multiple versions by IDs (v3)\n\t *\n\t * @param ids - Array of version IDs\n\t * @returns Promise resolving to an array of v3 versions\n\t *\n\t * @example\n\t * ```typescript\n\t * const versions = await client.labrinth.versions_v3.getVersions(['DXtmvS8i', 'abc123'])\n\t * console.log(versions[0].version_number)\n\t * ```\n\t */\n\tpublic async getVersions(ids: string[]): Promise<Labrinth.Versions.v3.Version[]> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version[]>(`/versions`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { ids: JSON.stringify(ids) },\n\t\t})\n\t}\n\n\t/**\n\t * Get a version from a project by version ID or number (v3)\n\t *\n\t * @param projectId - Project ID or slug\n\t * @param versionId - Version ID or version number\n\t * @returns Promise resolving to the v3 version data\n\t *\n\t * @example\n\t * ```typescript\n\t * const version = await client.labrinth.versions_v3.getVersionFromIdOrNumber('sodium', 'DXtmvS8i')\n\t * const versionByNumber = await client.labrinth.versions_v3.getVersionFromIdOrNumber('sodium', '0.4.12')\n\t * ```\n\t */\n\tpublic async getVersionFromIdOrNumber(\n\t\tprojectId: string,\n\t\tversionId: string,\n\t): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(\n\t\t\t`/project/${projectId}/version/${versionId}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\t/**\n\t * Create a new version for a project (v3)\n\t *\n\t * Creates a new version on an existing project. At least one file must be\n\t * attached unless the version is created as a draft.\n\t *\n\t * @param data - JSON metadata payload for the version (must include file_parts)\n\t * @param files - Array of uploaded files, in the same order as `data.file_parts`\n\t *\n\t * @returns A promise resolving to the newly created version data\n\t *\n\t * @example\n\t * ```ts\n\t * const version = await client.labrinth.versions_v3.createVersion('sodium', {\n\t * name: 'v0.5.0',\n\t * version_number: '0.5.0',\n\t * version_type: 'release',\n\t * loaders: ['fabric'],\n\t * game_versions: ['1.20.1'],\n\t * project_id: 'sodium',\n\t * file_parts: ['primary']\n\t * }, [fileObject])\n\t * ```\n\t */\n\n\tpublic createVersion(\n\t\tdraftVersion: Labrinth.Versions.v3.DraftVersion,\n\t\tversionFiles: Labrinth.Versions.v3.DraftVersionFile[],\n\t\tprojectType: Labrinth.Projects.v2.ProjectType | null = null,\n\t): UploadHandle<Labrinth.Versions.v3.Version> {\n\t\tconst formData = new FormData()\n\n\t\tconst files = versionFiles.map((vf) => vf.file)\n\t\tconst fileTypes = versionFiles.map((vf) => vf.fileType || null)\n\n\t\tconst fileParts = files.map((file, i) => {\n\t\t\treturn `${file.name}-${i === 0 ? 'primary' : i}`\n\t\t})\n\n\t\tconst fileTypeMap = fileParts.reduce<Record<string, Labrinth.Versions.v3.FileType | null>>(\n\t\t\t(acc, key, i) => {\n\t\t\t\tacc[key] = fileTypes[i]\n\t\t\t\treturn acc\n\t\t\t},\n\t\t\t{},\n\t\t)\n\n\t\tconst data: Labrinth.Versions.v3.CreateVersionRequest = {\n\t\t\tproject_id: draftVersion.project_id,\n\t\t\tversion_number: draftVersion.version_number,\n\t\t\tname: draftVersion.name || draftVersion.version_number,\n\t\t\tchangelog: draftVersion.changelog,\n\t\t\tdependencies: draftVersion.dependencies || [],\n\t\t\tgame_versions: draftVersion.game_versions,\n\t\t\tversion_type: draftVersion.version_type,\n\t\t\tfeatured: !!draftVersion.featured,\n\t\t\tfile_parts: fileParts,\n\t\t\tfile_types: fileTypeMap,\n\t\t\tprimary_file: fileParts[0],\n\t\t\tenvironment: draftVersion.environment,\n\t\t\tloaders: draftVersion.loaders,\n\t\t}\n\n\t\tif (projectType === 'modpack') {\n\t\t\tdata.mrpack_loaders = draftVersion.loaders\n\t\t\tdata.loaders = ['mrpack']\n\t\t}\n\n\t\tformData.append('data', JSON.stringify(data))\n\n\t\tfiles.forEach((file, i) => {\n\t\t\tformData.append(fileParts[i], file, file.name)\n\t\t})\n\n\t\treturn this.client.upload<Labrinth.Versions.v3.Version>(`/version`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tformData,\n\t\t\ttimeout: VERSION_UPLOAD_TIMEOUT_MS,\n\t\t})\n\t}\n\n\t/**\n\t * Modify an existing version by ID (v3)\n\t *\n\t * Partially updates a version\u2019s metadata. Only JSON fields may be modified.\n\t * To update files, use the separate \"Add files to version\" endpoint.\n\t *\n\t * @param versionId - The version ID to update\n\t * @param data - PATCH metadata for this version (all fields optional)\n\t *\n\t * @returns A promise resolving to the updated version data\n\t *\n\t * @example\n\t * ```ts\n\t * const updated = await client.labrinth.versions_v3.modifyVersion('DXtmvS8i', {\n\t * name: 'v1.0.1',\n\t * changelog: 'Updated changelog',\n\t * featured: true,\n\t * status: 'listed'\n\t * })\n\t * ```\n\t */\n\n\tpublic async modifyVersion(\n\t\tversionId: string,\n\t\tdata: Labrinth.Versions.v3.ModifyVersionRequest,\n\t): Promise<Labrinth.Versions.v3.Version> {\n\t\treturn this.client.request<Labrinth.Versions.v3.Version>(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Delete a version by ID (v3)\n\t *\n\t * @param versionId - Version ID\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.versions_v3.deleteVersion('DXtmvS8i')\n\t * ```\n\t */\n\tpublic async deleteVersion(versionId: string): Promise<void> {\n\t\treturn this.client.request(`/version/${versionId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\tpublic addFilesToVersion(\n\t\tversionId: string,\n\t\tversionFiles: Labrinth.Versions.v3.DraftVersionFile[],\n\t): UploadHandle<Labrinth.Versions.v3.Version> {\n\t\tconst formData = new FormData()\n\n\t\tconst files = versionFiles.map((vf) => vf.file)\n\t\tconst fileTypes = versionFiles.map((vf) => vf.fileType || null)\n\n\t\tconst fileParts = files.map((file, i) => `${file.name}-${i}`)\n\n\t\tconst fileTypeMap = fileParts.reduce<Record<string, Labrinth.Versions.v3.FileType | null>>(\n\t\t\t(acc, key, i) => {\n\t\t\t\tacc[key] = fileTypes[i]\n\t\t\t\treturn acc\n\t\t\t},\n\t\t\t{},\n\t\t)\n\n\t\tformData.append('data', JSON.stringify({ file_types: fileTypeMap }))\n\n\t\tfiles.forEach((file, i) => {\n\t\t\tformData.append(fileParts[i], file, file.name)\n\t\t})\n\n\t\treturn this.client.upload<Labrinth.Versions.v3.Version>(`/version/${versionId}/file`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tformData,\n\t\t\ttimeout: VERSION_UPLOAD_TIMEOUT_MS,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthAffiliateInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_affiliate_internal'\n\t}\n\n\t/**\n\t * Get all affiliate codes for the authenticated user (or all if admin)\n\t * GET /_internal/affiliate\n\t */\n\tpublic async getAll(): Promise<Labrinth.Affiliate.Internal.AffiliateCode[]> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode[]>('/affiliate', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Create a new affiliate code\n\t * PUT /_internal/affiliate\n\t */\n\tpublic async create(\n\t\tdata: Labrinth.Affiliate.Internal.CreateRequest,\n\t): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>('/affiliate', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PUT',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Get a specific affiliate code by ID\n\t * GET /_internal/affiliate/{id}\n\t */\n\tpublic async get(id: string): Promise<Labrinth.Affiliate.Internal.AffiliateCode> {\n\t\treturn this.client.request<Labrinth.Affiliate.Internal.AffiliateCode>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Delete an affiliate code\n\t * DELETE /_internal/affiliate/{id}\n\t */\n\tpublic async delete(id: string): Promise<void> {\n\t\treturn this.client.request<void>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Update an affiliate code's source name\n\t * PATCH /_internal/affiliate/{id}\n\t */\n\tpublic async patch(id: string, data: Labrinth.Affiliate.Internal.PatchRequest): Promise<void> {\n\t\treturn this.client.request<void>(`/affiliate/${id}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBlockedUsersInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_blocked_users_internal'\n\t}\n\n\t/**\n\t * Check whether one user has blocked another.\n\t */\n\tpublic async getStatus(\n\t\tuserId: string,\n\t\ttargetId: string,\n\t): Promise<Labrinth.BlockedUsers.Internal.BlockStatus> {\n\t\treturn this.client.request<Labrinth.BlockedUsers.Internal.BlockStatus>(\n\t\t\t`/block/${encodeURIComponent(userId)}/${encodeURIComponent(targetId)}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 'internal',\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthBlockedUsersV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_blocked_users_v3'\n\t}\n\n\t/**\n\t * List the users blocked by the authenticated user.\n\t */\n\tpublic async list(): Promise<Labrinth.BlockedUsers.v3.BlockedUserId[]> {\n\t\treturn this.client.request<Labrinth.BlockedUsers.v3.BlockedUserId[]>('/blocks', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n\n\t/**\n\t * Block a user.\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async block(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/block/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'POST',\n\t\t})\n\t}\n\n\t/**\n\t * Unblock a user.\n\t *\n\t * @param idOrUsername - The target user's ID or username\n\t */\n\tpublic async unblock(idOrUsername: string): Promise<void> {\n\t\treturn this.client.request(`/block/${encodeURIComponent(idOrUsername)}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 3,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthCampaignInternalModule extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_campaign_internal'\n\t}\n\n\t/**\n\t * Get Pride 2026 campaign fundraising progress.\n\t * GET /_internal/campaign/pride-26\n\t */\n\tpublic async getPride26(): Promise<Labrinth.Campaign.Internal.CampaignInfo> {\n\t\treturn this.client.request<Labrinth.Campaign.Internal.CampaignInfo>('/campaign/pride-26', {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 'internal',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTagsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_tags_v2'\n\t}\n\n\t/**\n\t * Get license text by SPDX identifier\n\t *\n\t * @param licenseId - SPDX license identifier (e.g., 'MIT', 'Apache-2.0')\n\t * @returns Promise resolving to the license title and body text\n\t *\n\t * @example\n\t * ```typescript\n\t * const license = await client.labrinth.tags_v2.getLicenseText('MIT')\n\t * console.log(license.title) // \"MIT License\"\n\t * console.log(license.body) // full license text\n\t * ```\n\t */\n\tpublic async getLicenseText(licenseId: string): Promise<Labrinth.Tags.v2.LicenseText> {\n\t\treturn this.client.request<Labrinth.Tags.v2.LicenseText>(`/tag/license/${licenseId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'GET',\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTeamsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_teams_v2'\n\t}\n\n\t/**\n\t * Add a member to a team\n\t *\n\t * @param teamId - Team ID\n\t * @param data - New member data including user_id\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.addMember('team123', { user_id: 'user456' })\n\t * ```\n\t */\n\tpublic async addMember(\n\t\tteamId: string,\n\t\tdata: Labrinth.Teams.v2.AddTeamMemberRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'POST',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Edit a team member\n\t *\n\t * @param teamId - Team ID\n\t * @param userId - User ID of the member to edit\n\t * @param data - Member update data\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.editMember('team123', 'user456', {\n\t * role: 'Developer',\n\t * permissions: 0b111,\n\t * })\n\t * ```\n\t */\n\tpublic async editMember(\n\t\tteamId: string,\n\t\tuserId: string,\n\t\tdata: Labrinth.Teams.v2.EditTeamMemberRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members/${userId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n\n\t/**\n\t * Remove a member from a team\n\t *\n\t * @param teamId - Team ID\n\t * @param userId - User ID of the member to remove\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.removeMember('team123', 'user456')\n\t * ```\n\t */\n\tpublic async removeMember(teamId: string, userId: string): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/members/${userId}`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'DELETE',\n\t\t})\n\t}\n\n\t/**\n\t * Transfer team ownership to another member\n\t *\n\t * @param teamId - Team ID\n\t * @param data - Transfer data including the new owner's user_id\n\t *\n\t * @example\n\t * ```typescript\n\t * await client.labrinth.teams_v2.transferOwnership('team123', { user_id: 'user456' })\n\t * ```\n\t */\n\tpublic async transferOwnership(\n\t\tteamId: string,\n\t\tdata: Labrinth.Teams.v2.TransferOwnershipRequest,\n\t): Promise<void> {\n\t\treturn this.client.request(`/team/${teamId}/owner`, {\n\t\t\tapi: 'labrinth',\n\t\t\tversion: 2,\n\t\t\tmethod: 'PATCH',\n\t\t\tbody: data,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Labrinth } from '../types'\n\nexport class LabrinthTeamsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'labrinth_teams_v3'\n\t}\n\n\t/**\n\t * Get multiple teams by their IDs\n\t *\n\t * @param ids - Array of team IDs\n\t * @returns Promise resolving to an array of team member arrays (one per team)\n\t *\n\t * @example\n\t * ```typescript\n\t * const teams = await client.labrinth.teams_v3.getMultiple(['team1', 'team2'])\n\t * // teams[0] = members of team1, teams[1] = members of team2\n\t * ```\n\t */\n\tpublic async getMultiple(ids: string[]): Promise<Labrinth.Projects.v3.TeamMember[][]> {\n\t\treturn this.client.request<Labrinth.Projects.v3.TeamMember[][]>(\n\t\t\t`/teams?ids=${encodeURIComponent(JSON.stringify(ids))}`,\n\t\t\t{\n\t\t\t\tapi: 'labrinth',\n\t\t\t\tversion: 3,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { LauncherMeta } from './types'\n\nexport type { LauncherMeta } from './types'\n\nconst LAUNCHER_META_BASE_URL = 'https://launcher-meta.modrinth.com'\n\nexport class LauncherMetaManifestV0Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'launchermeta_manifest_v0'\n\t}\n\n\t/**\n\t * Get the loader manifest for a given loader platform.\n\t *\n\t * launcher-meta refuses CORS preflights that ask for the `Content-Type`\n\t * header (returns 403), so we strip the default `Content-Type: application/json`\n\t * the abstract client sets \u2014 these are body-less GETs and don't need it.\n\t * Without this the browser preflight is rejected and the GET never fires.\n\t *\n\t * @param loader - Loader platform (fabric, forge, quilt, neo)\n\t */\n\tpublic async getManifest(\n\t\tloader: string,\n\t\tformatVersion = 0,\n\t): Promise<LauncherMeta.Manifest.v0.Manifest> {\n\t\treturn this.client.request<LauncherMeta.Manifest.v0.Manifest>('/manifest.json', {\n\t\t\tapi: LAUNCHER_META_BASE_URL,\n\t\t\tversion: `${loader}/v${formatVersion}`,\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t\theaders: { 'Content-Type': '' },\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Mclogs } from '../types'\n\nexport class MclogsInsightsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'mclogs_insights_v1'\n\t}\n\n\tpublic async analyse(content: string): Promise<Mclogs.Insights.v1.InsightsResponse> {\n\t\treturn this.client.request<Mclogs.Insights.v1.InsightsResponse>('/analyse', {\n\t\t\tapi: 'https://api.mclo.gs',\n\t\t\tversion: '1',\n\t\t\tmethod: 'POST',\n\t\t\tbody: new URLSearchParams({ content }),\n\t\t\theaders: { 'Content-Type': 'application/x-www-form-urlencoded' },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { Mclogs } from '../types'\n\nexport class MclogsLogsV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'mclogs_logs_v1'\n\t}\n\n\tpublic async create(content: string): Promise<Mclogs.Logs.v1.CreateResponse> {\n\t\treturn this.client.request<Mclogs.Logs.v1.CreateResponse>('/log', {\n\t\t\tapi: 'https://api.mclo.gs',\n\t\t\tversion: '1',\n\t\t\tmethod: 'POST',\n\t\t\tbody: new URLSearchParams({ content }),\n\t\t\theaders: { 'Content-Type': 'application/x-www-form-urlencoded' },\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { Paper } from './types'\n\nexport type { Paper } from './types'\n\nconst PAPER_BASE_URL = 'https://fill.papermc.io'\n\nexport class PaperVersionsV3Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'paper_versions_v3'\n\t}\n\n\t/**\n\t * Get the Paper project info including all supported Minecraft versions.\n\t */\n\tpublic async getProject(): Promise<Paper.Versions.v3.Project> {\n\t\treturn this.client.request<Paper.Versions.v3.Project>('/projects/paper', {\n\t\t\tapi: PAPER_BASE_URL,\n\t\t\tversion: 'v3',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get available Paper builds for a Minecraft version (includes channel per build).\n\t *\n\t * Fill (`fill.papermc.io`) returns a JSON array of builds at this path \u2014 not a `{ builds }`\n\t * wrapper like some other Paper API shapes \u2014 so we normalize to `VersionBuilds`.\n\t *\n\t * @param mcVersion - Minecraft version (e.g. \"1.21.4\")\n\t */\n\tpublic async getBuilds(mcVersion: string): Promise<Paper.Versions.v3.VersionBuilds> {\n\t\tconst builds = await this.client.request<Paper.Versions.v3.Build[]>(\n\t\t\t`/projects/paper/versions/${mcVersion}/builds`,\n\t\t\t{ api: PAPER_BASE_URL, version: 'v3', method: 'GET', skipAuth: true },\n\t\t)\n\t\treturn { builds }\n\t}\n}\n", "import { AbstractModule } from '../../core/abstract-module'\nimport type { Purpur } from './types'\n\nexport type { Purpur } from './types'\n\nconst PURPUR_BASE_URL = 'https://api.purpurmc.org'\n\nexport class PurpurVersionsV2Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'purpur_versions_v2'\n\t}\n\n\t/**\n\t * Get the Purpur project info including all supported Minecraft versions.\n\t */\n\tpublic async getProject(): Promise<Purpur.Versions.v2.Project> {\n\t\treturn this.client.request<Purpur.Versions.v2.Project>('/purpur', {\n\t\t\tapi: PURPUR_BASE_URL,\n\t\t\tversion: 'v2',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n\n\t/**\n\t * Get available Purpur builds for a Minecraft version.\n\t *\n\t * @param mcVersion - Minecraft version (e.g. \"1.21.4\")\n\t */\n\tpublic async getBuilds(mcVersion: string): Promise<Purpur.Versions.v2.VersionBuilds> {\n\t\treturn this.client.request<Purpur.Versions.v2.VersionBuilds>(`/purpur/${mcVersion}`, {\n\t\t\tapi: PURPUR_BASE_URL,\n\t\t\tversion: 'v2',\n\t\t\tmethod: 'GET',\n\t\t\tskipAuth: true,\n\t\t})\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesInstancesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_instances_v1'\n\t}\n\n\tpublic async get(instanceId: string): Promise<SharedInstances.Instances.v1.Instance> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.Instance>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getForUser(userId: string): Promise<string[]> {\n\t\treturn this.client.request<string[]>('/instances', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'GET',\n\t\t\tparams: { user: userId },\n\t\t})\n\t}\n\n\tpublic async getUsers(instanceId: string): Promise<SharedInstances.Instances.v1.InstanceUsers> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceUsers>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/users`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getLatestVersion(\n\t\tinstanceId: string,\n\t): Promise<SharedInstances.Instances.v1.InstanceVersion> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceVersion>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/versions`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n\n\tpublic async getVersion(\n\t\tinstanceId: string,\n\t\tversion: number,\n\t): Promise<SharedInstances.Instances.v1.InstanceVersion> {\n\t\treturn this.client.request<SharedInstances.Instances.v1.InstanceVersion>(\n\t\t\t`/instances/${encodeURIComponent(instanceId)}/versions/${version}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesInvitesV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_invites_v1'\n\t}\n\n\tpublic async get(inviteId: string): Promise<SharedInstances.Invites.v1.Invite> {\n\t\treturn this.client.request<SharedInstances.Invites.v1.Invite>(\n\t\t\t`/invites/${encodeURIComponent(inviteId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t\tskipAuth: true,\n\t\t\t\tretry: false,\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesModerationV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_moderation_v1'\n\t}\n\n\tpublic async blacklistUsers(\n\t\trequest: SharedInstances.Moderation.v1.BlacklistUserRequest,\n\t): Promise<void> {\n\t\treturn this.client.request('/moderation/blacklist', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'POST',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\tpublic async unblacklistUsers(\n\t\trequest: SharedInstances.Moderation.v1.BlacklistUserRequest,\n\t): Promise<void> {\n\t\treturn this.client.request('/moderation/blacklist', {\n\t\t\tapi: 'sharedinstances',\n\t\t\tversion: 1,\n\t\t\tmethod: 'DELETE',\n\t\t\tbody: request,\n\t\t})\n\t}\n\n\tpublic async deleteFile(instanceId: string, version: number, fileName: string): Promise<void> {\n\t\treturn this.client.request(\n\t\t\t`/moderation/instances/${encodeURIComponent(instanceId)}/versions/${version}/files/${encodeURIComponent(fileName)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'DELETE',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import { AbstractModule } from '../../../core/abstract-module'\nimport type { SharedInstances } from '../types'\n\nexport class SharedInstancesUsersV1Module extends AbstractModule {\n\tpublic getModuleID(): string {\n\t\treturn 'sharedinstances_users_v1'\n\t}\n\n\tpublic async getBlacklistStatus(\n\t\tuserId: string,\n\t): Promise<SharedInstances.Users.v1.BlacklistStatus> {\n\t\treturn this.client.request<SharedInstances.Users.v1.BlacklistStatus>(\n\t\t\t`/blacklist/${encodeURIComponent(userId)}`,\n\t\t\t{\n\t\t\t\tapi: 'sharedinstances',\n\t\t\t\tversion: 1,\n\t\t\t\tmethod: 'GET',\n\t\t\t},\n\t\t)\n\t}\n}\n", "import type { AbstractModrinthClient } from '../core/abstract-client'\nimport type { AbstractModule } from '../core/abstract-module'\nimport { ArchonActionsV1Module } from './archon/actions/v1'\nimport { ArchonBackupsV1Module } from './archon/backups/v1'\nimport { ArchonBackupsQueueV1Module } from './archon/backups-queue/v1'\nimport { ArchonContentV1Module } from './archon/content/v1'\nimport { ArchonNodesInternalModule } from './archon/nodes/internal'\nimport { ArchonNoticesV0Module } from './archon/notices/v0'\nimport { ArchonOptionsV1Module } from './archon/options/v1'\nimport { ArchonPropertiesV1Module } from './archon/properties/v1'\nimport { ArchonServerUsersV1Module } from './archon/server-users/v1'\nimport { ArchonServersInternalModule } from './archon/servers/internal'\nimport { ArchonServersV0Module } from './archon/servers/v0'\nimport { ArchonServersV1Module } from './archon/servers/v1'\nimport { ArchonTransfersInternalModule } from './archon/transfers/internal'\nimport { ISO3166Module } from './iso3166'\nimport { KyrosContentV1Module } from './kyros/content/v1'\nimport { KyrosFilesV0Module } from './kyros/files/v0'\nimport { KyrosLogsV1Module } from './kyros/logs/v1'\nimport { KyrosUploadSessionsV1Module } from './kyros/upload-sessions/v1'\nimport { LabrinthVersionsV2Module, LabrinthVersionsV3Module } from './labrinth'\nimport { LabrinthAffiliateInternalModule } from './labrinth/affiliate/internal'\nimport { LabrinthAnalyticsInternalModule } from './labrinth/analytics/internal'\nimport { LabrinthAnalyticsV3Module } from './labrinth/analytics/v3'\nimport { LabrinthAttributionInternalModule } from './labrinth/attribution/internal'\nimport { LabrinthAuthInternalModule } from './labrinth/auth/internal'\nimport { LabrinthAuthV2Module } from './labrinth/auth/v2'\nimport { LabrinthBillingInternalModule } from './labrinth/billing/internal'\nimport { LabrinthBlockedUsersInternalModule } from './labrinth/blocked-users/internal'\nimport { LabrinthBlockedUsersV3Module } from './labrinth/blocked-users/v3'\nimport { LabrinthCampaignInternalModule } from './labrinth/campaign/internal'\nimport { LabrinthCollectionsModule } from './labrinth/collections'\nimport { LabrinthContentV3Module } from './labrinth/content/v3'\nimport { LabrinthExternalProjectsInternalModule } from './labrinth/external-projects/internal'\nimport { LabrinthFriendsV3Module } from './labrinth/friends/v3'\nimport { LabrinthGeoIpModule } from './labrinth/geoip'\nimport { LabrinthGlobalsInternalModule } from './labrinth/globals/internal'\nimport { LabrinthImagesV3Module } from './labrinth/images/v3'\nimport { LabrinthLimitsV3Module } from './labrinth/limits/v3'\nimport { LabrinthModerationInternalModule } from './labrinth/moderation/internal'\nimport { LabrinthNotificationsV2Module } from './labrinth/notifications/v2'\nimport { LabrinthOAuthInternalModule } from './labrinth/oauth/internal'\nimport { LabrinthOrganizationsV3Module } from './labrinth/organizations/v3'\nimport { LabrinthPatsV2Module } from './labrinth/pats/v2'\nimport { LabrinthPayoutV3Module } from './labrinth/payout/v3'\nimport { LabrinthPayoutsV3Module } from './labrinth/payouts/v3'\nimport { LabrinthProjectsV2Module } from './labrinth/projects/v2'\nimport { LabrinthProjectsV3Module } from './labrinth/projects/v3'\nimport { LabrinthReportsV3Module } from './labrinth/reports/v3'\nimport { LabrinthServerPingInternalModule } from './labrinth/server-ping/internal'\nimport { LabrinthSessionsV2Module } from './labrinth/sessions/v2'\nimport { LabrinthStateModule } from './labrinth/state'\nimport { LabrinthTagsV2Module } from './labrinth/tags/v2'\nimport { LabrinthTeamsV2Module } from './labrinth/teams/v2'\nimport { LabrinthTeamsV3Module } from './labrinth/teams/v3'\nimport { LabrinthTechReviewInternalModule } from './labrinth/tech-review/internal'\nimport { LabrinthThreadsV3Module } from './labrinth/threads/v3'\nimport { LabrinthUsersV2Module } from './labrinth/users/v2'\nimport { LabrinthUsersV3Module } from './labrinth/users/v3'\nimport { LauncherMetaManifestV0Module } from './launcher-meta/v0'\nimport { MclogsInsightsV1Module } from './mclogs/insights/v1'\nimport { MclogsLogsV1Module } from './mclogs/logs/v1'\nimport { PaperVersionsV3Module } from './paper/v3'\nimport { PurpurVersionsV2Module } from './purpur/v2'\nimport { SharedInstancesInstancesV1Module } from './shared-instances/instances/v1'\nimport { SharedInstancesInvitesV1Module } from './shared-instances/invites/v1'\nimport { SharedInstancesModerationV1Module } from './shared-instances/moderation/v1'\nimport { SharedInstancesUsersV1Module } from './shared-instances/users/v1'\n\ntype ModuleConstructor = new (client: AbstractModrinthClient) => AbstractModule\n\n/**\n * To add a new module:\n * 1. Create your module class extending AbstractModule\n * 2. Add one line here: `<api>_<module>: YourModuleClass`\n *\n * TypeScript will automatically infer the client's field structure from this registry.\n *\n * TODO: Better way? Probably not\n */\nexport const MODULE_REGISTRY = {\n\tarchon_actions_v1: ArchonActionsV1Module,\n\tarchon_backups_queue_v1: ArchonBackupsQueueV1Module,\n\tarchon_backups_v1: ArchonBackupsV1Module,\n\tarchon_content_v1: ArchonContentV1Module,\n\tarchon_nodes_internal: ArchonNodesInternalModule,\n\tarchon_notices_v0: ArchonNoticesV0Module,\n\tarchon_options_v1: ArchonOptionsV1Module,\n\tarchon_properties_v1: ArchonPropertiesV1Module,\n\tarchon_server_users_v1: ArchonServerUsersV1Module,\n\tarchon_servers_internal: ArchonServersInternalModule,\n\tarchon_servers_v0: ArchonServersV0Module,\n\tarchon_servers_v1: ArchonServersV1Module,\n\tarchon_transfers_internal: ArchonTransfersInternalModule,\n\tiso3166_data: ISO3166Module,\n\tmclogs_insights_v1: MclogsInsightsV1Module,\n\tmclogs_logs_v1: MclogsLogsV1Module,\n\tlaunchermeta_manifest_v0: LauncherMetaManifestV0Module,\n\tkyros_content_v1: KyrosContentV1Module,\n\tkyros_files_v0: KyrosFilesV0Module,\n\tkyros_logs_v1: KyrosLogsV1Module,\n\tkyros_upload_sessions_v1: KyrosUploadSessionsV1Module,\n\tlabrinth_affiliate_internal: LabrinthAffiliateInternalModule,\n\tlabrinth_analytics_internal: LabrinthAnalyticsInternalModule,\n\tlabrinth_analytics_v3: LabrinthAnalyticsV3Module,\n\tlabrinth_auth_internal: LabrinthAuthInternalModule,\n\tlabrinth_auth_v2: LabrinthAuthV2Module,\n\tlabrinth_attribution_internal: LabrinthAttributionInternalModule,\n\tlabrinth_billing_internal: LabrinthBillingInternalModule,\n\tlabrinth_blocked_users_internal: LabrinthBlockedUsersInternalModule,\n\tlabrinth_blocked_users_v3: LabrinthBlockedUsersV3Module,\n\tlabrinth_campaign_internal: LabrinthCampaignInternalModule,\n\tlabrinth_collections: LabrinthCollectionsModule,\n\tlabrinth_content_v3: LabrinthContentV3Module,\n\tlabrinth_external_projects_internal: LabrinthExternalProjectsInternalModule,\n\tlabrinth_friends_v3: LabrinthFriendsV3Module,\n\tlabrinth_geoip: LabrinthGeoIpModule,\n\tlabrinth_globals_internal: LabrinthGlobalsInternalModule,\n\tlabrinth_images_v3: LabrinthImagesV3Module,\n\tlabrinth_moderation_internal: LabrinthModerationInternalModule,\n\tlabrinth_notifications_v2: LabrinthNotificationsV2Module,\n\tlabrinth_oauth_internal: LabrinthOAuthInternalModule,\n\tlabrinth_organizations_v3: LabrinthOrganizationsV3Module,\n\tlabrinth_pats_v2: LabrinthPatsV2Module,\n\tlabrinth_limits_v3: LabrinthLimitsV3Module,\n\tlabrinth_payout_v3: LabrinthPayoutV3Module,\n\tlabrinth_payouts_v3: LabrinthPayoutsV3Module,\n\tlabrinth_projects_v2: LabrinthProjectsV2Module,\n\tlabrinth_projects_v3: LabrinthProjectsV3Module,\n\tlabrinth_reports_v3: LabrinthReportsV3Module,\n\tlabrinth_server_ping_internal: LabrinthServerPingInternalModule,\n\tlabrinth_sessions_v2: LabrinthSessionsV2Module,\n\tlabrinth_state: LabrinthStateModule,\n\tlabrinth_tags_v2: LabrinthTagsV2Module,\n\tlabrinth_teams_v2: LabrinthTeamsV2Module,\n\tlabrinth_teams_v3: LabrinthTeamsV3Module,\n\tlabrinth_tech_review_internal: LabrinthTechReviewInternalModule,\n\tlabrinth_threads_v3: LabrinthThreadsV3Module,\n\tlabrinth_users_v2: LabrinthUsersV2Module,\n\tlabrinth_users_v3: LabrinthUsersV3Module,\n\tlabrinth_versions_v2: LabrinthVersionsV2Module,\n\tlabrinth_versions_v3: LabrinthVersionsV3Module,\n\tpaper_versions_v3: PaperVersionsV3Module,\n\tpurpur_versions_v2: PurpurVersionsV2Module,\n\tsharedinstances_invites_v1: SharedInstancesInvitesV1Module,\n\tsharedinstances_instances_v1: SharedInstancesInstancesV1Module,\n\tsharedinstances_moderation_v1: SharedInstancesModerationV1Module,\n\tsharedinstances_users_v1: SharedInstancesUsersV1Module,\n} as const satisfies Record<string, ModuleConstructor>\n\nexport type ModuleID = keyof typeof MODULE_REGISTRY\n\n/**\n * Parse a module ID into [api, moduleName] tuple\n *\n * @param id - Module ID in format `<api>_<module>` (e.g., 'labrinth_projects_v2')\n * @returns Tuple of [api, moduleName] (e.g., ['labrinth', 'projects_v2'])\n * @throws Error if module ID doesn't match expected format\n */\nexport function parseModuleID(id: string): [string, string] {\n\tconst parts = id.split('_')\n\tif (parts.length < 2) {\n\t\tthrow new Error(\n\t\t\t`Invalid module ID \"${id}\". Expected format: <api>_<module> (e.g., \"labrinth_projects_v2\")`,\n\t\t)\n\t}\n\tconst api = parts[0]\n\tconst moduleName = parts.slice(1).join('_')\n\treturn [api, moduleName]\n}\n\n/**\n * Build nested module structure from flat registry\n *\n * Transforms:\n * ```\n * { labrinth_projects_v2: Constructor, labrinth_users_v2: Constructor }\n * ```\n * Into:\n * ```\n * { labrinth: { projects_v2: Constructor, users_v2: Constructor } }\n * ```\n *\n * @returns Nested structure organized by API namespace\n */\nexport function buildModuleStructure(): Record<string, Record<string, ModuleConstructor>> {\n\tconst structure: Record<string, Record<string, ModuleConstructor>> = {}\n\n\tfor (const [id, constructor] of Object.entries(MODULE_REGISTRY)) {\n\t\tconst [api, moduleName] = parseModuleID(id)\n\n\t\tif (!structure[api]) {\n\t\t\tstructure[api] = {}\n\t\t}\n\n\t\tstructure[api][moduleName] = constructor\n\t}\n\n\treturn structure\n}\n\n/**\n * Extract API name from module ID\n * @example ParseAPI<'labrinth_projects_v2'> = 'labrinth'\n */\ntype ParseAPI<T extends string> = T extends `${infer API}_${string}` ? API : never\n\n/**\n * Extract module name for a given API\n * @example ParseModule<'labrinth_projects_v2', 'labrinth'> = 'projects_v2'\n */\ntype ParseModule<T extends string, API extends string> = T extends `${API}_${infer Module}`\n\t? Module\n\t: never\n\n/**\n * Group registry modules by API namespace\n *\n * Transforms flat registry into nested structure at the type level:\n * ```\n * { labrinth_projects_v2: ModuleClass } \u2192 { labrinth: { projects_v2: ModuleInstance } }\n * ```\n */\ntype GroupByAPI<Registry extends Record<string, ModuleConstructor>> = {\n\t[API in ParseAPI<keyof Registry & string>]: {\n\t\t[Module in ParseModule<keyof Registry & string, API>]: InstanceType<\n\t\t\tRegistry[`${API}_${Module}`]\n\t\t>\n\t}\n}\n\n/**\n * Inferred client module structure\n **/\nexport type InferredClientModules = GroupByAPI<typeof MODULE_REGISTRY>\n", "import type { UploadHandle, UploadRequestOptions } from '../types/upload'\n\n/**\n * Abstract base class defining upload capability\n *\n * All clients that support file uploads must extend this class.\n * Platform-specific implementations should provide the actual upload mechanism\n * (e.g., XHR for browser environments).\n *\n * Upload goes through the feature chain (auth, retry, circuit-breaker, etc.)\n * just like regular requests.\n */\nexport abstract class AbstractUploadClient {\n\t/**\n\t * Upload a file or FormData with progress tracking\n\t * @param path - API path (e.g., '/fs/create')\n\t * @param options - Upload options including file or formData, api, version\n\t * @returns UploadHandle with promise, onProgress chain, and cancel method\n\t */\n\tabstract upload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T>\n}\n", "import type { InferredClientModules } from '../modules'\nimport { buildModuleStructure } from '../modules'\nimport type { BaseUrlConfig, ClientConfig } from '../types/client'\nimport type { RequestContext, RequestOptions } from '../types/request'\nimport type { UploadMetadata, UploadProgress, UploadRequestOptions } from '../types/upload'\nimport type { AbstractFeature } from './abstract-feature'\nimport type { AbstractModule } from './abstract-module'\nimport type { AbstractSyncClient } from './abstract-sync'\nimport { AbstractUploadClient } from './abstract-upload-client'\nimport type { AbstractWebSocketClient } from './abstract-websocket'\nimport { ModrinthApiError, ModrinthServerError } from './errors'\n\ntype ArchonClientModules = Omit<InferredClientModules['archon'], 'backups_v1'> & {\n\t/** @deprecated Use `backups_queue_v1` for the Backups Queue API. */\n\tbackups_v1: InferredClientModules['archon']['backups_v1']\n}\n\n/**\n * Abstract base client for Modrinth APIs\n */\nexport abstract class AbstractModrinthClient extends AbstractUploadClient {\n\tprotected config: ClientConfig\n\tprotected features: AbstractFeature[]\n\n\t/**\n\t * Maps full module ID (e.g., 'labrinth_projects_v2') to instantiated module\n\t */\n\tprivate _moduleInstances: Map<string, AbstractModule> = new Map()\n\n\t/**\n\t * Maps API name (e.g., 'labrinth') to namespace object\n\t */\n\tprivate _moduleNamespaces: Map<string, Record<string, AbstractModule>> = new Map()\n\n\tpublic readonly labrinth!: InferredClientModules['labrinth']\n\tpublic readonly archon!: ArchonClientModules & {\n\t\tsockets: AbstractWebSocketClient\n\t\tsync: AbstractSyncClient\n\t}\n\tpublic readonly kyros!: InferredClientModules['kyros']\n\tpublic readonly iso3166!: InferredClientModules['iso3166']\n\tpublic readonly mclogs!: InferredClientModules['mclogs']\n\tpublic readonly launchermeta!: InferredClientModules['launchermeta']\n\tpublic readonly paper!: InferredClientModules['paper']\n\tpublic readonly purpur!: InferredClientModules['purpur']\n\tpublic readonly sharedinstances!: InferredClientModules['sharedinstances']\n\n\tconstructor(config: ClientConfig) {\n\t\tsuper()\n\t\tthis.config = {\n\t\t\ttimeout: 10000,\n\t\t\tlabrinthBaseUrl: 'https://api.modrinth.com',\n\t\t\tarchonBaseUrl: 'https://archon.modrinth.com',\n\t\t\tsharedInstancesBaseUrl: 'https://shared-instances.modrinth.com',\n\t\t\t...config,\n\t\t}\n\t\tthis.features = config.features ?? []\n\t\tthis.initializeModules()\n\t}\n\n\t/**\n\t * This creates the nested API structure (e.g., client.labrinth.projects_v2)\n\t * but doesn't instantiate modules until first access\n\t *\n\t * Module IDs in the registry are validated at runtime to ensure they match\n\t * what the module declares via getModuleID().\n\t */\n\tprivate initializeModules(): void {\n\t\tconst structure = buildModuleStructure()\n\n\t\tfor (const [api, modules] of Object.entries(structure)) {\n\t\t\tconst namespaceObj: Record<string, AbstractModule> = {}\n\n\t\t\t// Define lazy getters for each module\n\t\t\tfor (const [moduleName, ModuleConstructor] of Object.entries(modules)) {\n\t\t\t\tconst fullModuleId = `${api}_${moduleName}`\n\n\t\t\t\tObject.defineProperty(namespaceObj, moduleName, {\n\t\t\t\t\tget: () => {\n\t\t\t\t\t\t// Lazy instantiation\n\t\t\t\t\t\tif (!this._moduleInstances.has(fullModuleId)) {\n\t\t\t\t\t\t\tconst instance = new ModuleConstructor(this)\n\n\t\t\t\t\t\t\t// Validate the module ID matches what we expect\n\t\t\t\t\t\t\tconst declaredId = instance.getModuleID()\n\t\t\t\t\t\t\tif (declaredId !== fullModuleId) {\n\t\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t\t`Module ID mismatch: registry expects \"${fullModuleId}\" but module declares \"${declaredId}\"`,\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis._moduleInstances.set(fullModuleId, instance)\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn this._moduleInstances.get(fullModuleId)!\n\t\t\t\t\t},\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\tconfigurable: false,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\t// Assign namespace to client (e.g., this.labrinth = namespaceObj)\n\t\t\t// defineProperty bypasses readonly restriction\n\t\t\tObject.defineProperty(this, api, {\n\t\t\t\tvalue: namespaceObj,\n\t\t\t\twritable: false,\n\t\t\t\tenumerable: true,\n\t\t\t\tconfigurable: false,\n\t\t\t})\n\n\t\t\tthis._moduleNamespaces.set(api, namespaceObj)\n\t\t}\n\t}\n\n\t/**\n\t * Make a request to the API\n\t *\n\t * @param path - API path (e.g., '/project/sodium')\n\t * @param options - Request options\n\t * @returns Promise resolving to the response data\n\t * @throws {ModrinthApiError} When the request fails or features throw errors\n\t */\n\tasync request<T>(path: string, options: RequestOptions): Promise<T> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\n\t\tconst defaultHeaders = await this.buildDefaultHeaders()\n\n\t\t// Merge options with defaults\n\t\tconst mergedOptions: RequestOptions = {\n\t\t\tmethod: 'GET',\n\t\t\ttimeout: this.config.timeout,\n\t\t\t...options,\n\t\t\theaders: {\n\t\t\t\t...defaultHeaders,\n\t\t\t\t...options.headers,\n\t\t\t},\n\t\t}\n\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\tconst headers = mergedOptions.headers\n\t\tif (headers && 'Content-Type' in headers && headers['Content-Type'] === '') {\n\t\t\tdelete headers['Content-Type']\n\t\t}\n\n\t\tconst context = this.buildContext(url, path, mergedOptions)\n\n\t\ttry {\n\t\t\tconst result = await this.executeFeatureChain<T>(context)\n\n\t\t\tawait this.config.hooks?.onResponse?.(result, context)\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\n\t\t\tthrow apiError\n\t\t}\n\t}\n\n\tasync stream(path: string, options: RequestOptions): Promise<ReadableStream<Uint8Array>> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\t\tconst defaultHeaders = await this.buildDefaultHeaders()\n\t\tconst mergedOptions: RequestOptions = {\n\t\t\tmethod: 'GET',\n\t\t\tretry: false,\n\t\t\tcircuitBreaker: false,\n\t\t\t...options,\n\t\t\theaders: {\n\t\t\t\t...defaultHeaders,\n\t\t\t\tAccept: 'text/event-stream',\n\t\t\t\t...options.headers,\n\t\t\t},\n\t\t}\n\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\tconst context = this.buildContext(url, path, mergedOptions)\n\n\t\ttry {\n\t\t\treturn await this.executeFeatureChain<ReadableStream<Uint8Array>>(context, () =>\n\t\t\t\tthis.executeStreamRequest(context.url, context.options),\n\t\t\t)\n\t\t} catch (error) {\n\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\n\t\t\tthrow apiError\n\t\t}\n\t}\n\n\t/**\n\t * Execute the feature chain and the actual request\n\t *\n\t * Features are executed in order, with each feature calling next() to continue.\n\t * The last \"feature\" in the chain is the actual request execution.\n\t */\n\tprotected async executeFeatureChain<T>(\n\t\tcontext: RequestContext,\n\t\texecuteTerminal: () => Promise<T> = () => this.executeRequest<T>(context.url, context.options),\n\t): Promise<T> {\n\t\t// Filter to only features that should apply\n\t\tconst applicableFeatures = this.features.filter((feature) => feature.shouldApply(context))\n\n\t\t// Build the feature chain\n\t\t// We work backwards from the actual request, wrapping each feature around the previous\n\t\tlet index = applicableFeatures.length\n\n\t\tconst next = async (): Promise<T> => {\n\t\t\tindex--\n\n\t\t\tif (index >= 0) {\n\t\t\t\t// Execute the next feature in the chain\n\t\t\t\tconst feature = applicableFeatures[index]\n\t\t\t\treturn feature.execute(next, context)\n\t\t\t} else {\n\t\t\t\t// We've reached the end of the chain, execute the actual request\n\t\t\t\tawait this.config.hooks?.onRequest?.(context)\n\t\t\t\treturn executeTerminal()\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\t/**\n\t * Execute the feature chain for an upload\n\t *\n\t * Similar to executeFeatureChain but calls executeXHRUpload at the end.\n\t * This allows features (auth, retry, etc.) to wrap the upload execution.\n\t */\n\tprotected async executeUploadFeatureChain<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T> {\n\t\tconst applicableFeatures = this.features.filter((feature) => feature.shouldApply(context))\n\n\t\tlet index = applicableFeatures.length\n\n\t\tconst next = async (): Promise<T> => {\n\t\t\tindex--\n\n\t\t\tif (index >= 0) {\n\t\t\t\treturn applicableFeatures[index].execute(next, context)\n\t\t\t} else {\n\t\t\t\tawait this.config.hooks?.onRequest?.(context)\n\t\t\t\treturn this.executeXHRUpload<T>(context, progressCallbacks, abortController)\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\t/**\n\t * Build the full URL for a request\n\t */\n\tprotected buildUrl(path: string, baseUrl: string, version: number | 'internal' | string): string {\n\t\t// Remove trailing slash from base URL\n\t\tconst base = baseUrl.replace(/\\/$/, '')\n\n\t\t// Build version path\n\t\tlet versionPath = ''\n\t\tif (version === 'internal') {\n\t\t\tversionPath = '/_internal'\n\t\t} else if (typeof version === 'number') {\n\t\t\tversionPath = `/v${version}`\n\t\t} else if (typeof version === 'string') {\n\t\t\t// Custom version string (e.g., 'v0', 'modrinth/v0')\n\t\t\tversionPath = `/${version}`\n\t\t}\n\n\t\tconst cleanPath = path.startsWith('/') ? path : `/${path}`\n\n\t\treturn `${base}${versionPath}${cleanPath}`\n\t}\n\n\tprotected resolveBaseUrl(baseUrl: BaseUrlConfig): string {\n\t\treturn typeof baseUrl === 'function' ? baseUrl() : baseUrl\n\t}\n\n\t/**\n\t * Build the request context\n\t */\n\tprotected buildContext(url: string, path: string, options: RequestOptions): RequestContext {\n\t\treturn {\n\t\t\turl,\n\t\t\tpath,\n\t\t\toptions,\n\t\t\tattempt: 1,\n\t\t\tstartTime: Date.now(),\n\t\t}\n\t}\n\n\t/**\n\t * Build context for an upload request\n\t *\n\t * Sets metadata.isUpload = true so features can detect uploads.\n\t * Supports both single file uploads and FormData uploads.\n\t */\n\tprotected buildUploadContext(\n\t\turl: string,\n\t\tpath: string,\n\t\toptions: UploadRequestOptions,\n\t): RequestContext {\n\t\tlet metadata: UploadMetadata\n\t\tlet body: File | Blob | FormData\n\n\t\tif ('formData' in options && options.formData) {\n\t\t\tmetadata = {\n\t\t\t\tisUpload: true,\n\t\t\t\tformData: options.formData,\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t}\n\t\t\tbody = options.formData\n\t\t} else if ('file' in options && options.file) {\n\t\t\tmetadata = {\n\t\t\t\tisUpload: true,\n\t\t\t\tfile: options.file,\n\t\t\t\tonProgress: options.onProgress,\n\t\t\t}\n\t\t\tbody = options.file\n\t\t} else {\n\t\t\tthrow new Error('Upload options must include either file or formData')\n\t\t}\n\n\t\treturn {\n\t\t\turl,\n\t\t\tpath,\n\t\t\toptions: {\n\t\t\t\t...options,\n\t\t\t\tmethod: 'POST',\n\t\t\t\tbody,\n\t\t\t},\n\t\t\tattempt: 1,\n\t\t\tstartTime: Date.now(),\n\t\t\tmetadata,\n\t\t}\n\t}\n\n\t/**\n\t * Build default headers for all requests\n\t *\n\t * Subclasses can override this to add platform-specific headers\n\t * (e.g., Nuxt rate limit key)\n\t */\n\tprotected async buildDefaultHeaders(): Promise<Record<string, string>> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t'Content-Type': 'application/json',\n\t\t\t...this.config.headers,\n\t\t}\n\n\t\tconst userAgent = await this.resolveUserAgent()\n\t\tif (userAgent) {\n\t\t\theaders['User-Agent'] = userAgent\n\t\t}\n\n\t\treturn headers\n\t}\n\n\tprivate async resolveUserAgent(): Promise<string | undefined> {\n\t\tconst userAgent = this.config.userAgent\n\t\treturn typeof userAgent === 'function' ? await userAgent() : userAgent\n\t}\n\n\tprotected attachArchonSentryCaptureHeader(options: RequestOptions): void {\n\t\tif (options.api !== 'archon' || !options.headers || !this.shouldCaptureArchonRequests()) {\n\t\t\treturn\n\t\t}\n\n\t\toptions.headers['modrinth-sentry-capture'] = '1'\n\t}\n\n\tprivate shouldCaptureArchonRequests(): boolean {\n\t\tconst archonSentryCapture = this.config.archonSentryCapture\n\t\treturn typeof archonSentryCapture === 'function'\n\t\t\t? archonSentryCapture()\n\t\t\t: archonSentryCapture === true\n\t}\n\n\t/**\n\t * Execute the actual HTTP request\n\t *\n\t * This must be implemented by platform-specific clients.\n\t *\n\t * @param url - Full URL to request\n\t * @param options - Request options\n\t * @returns Promise resolving to the response data\n\t * @throws {Error} Platform-specific errors that will be normalized by normalizeError()\n\t */\n\tprotected abstract executeRequest<T>(url: string, options: RequestOptions): Promise<T>\n\n\tprotected abstract executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>>\n\n\t/**\n\t * Execute the actual XHR upload\n\t *\n\t * This must be implemented by platform clients that support uploads.\n\t * Called at the end of the upload feature chain.\n\t *\n\t * @param context - Request context with upload metadata\n\t * @param progressCallbacks - Callbacks to invoke on progress events\n\t * @param abortController - Controller for cancellation\n\t * @returns Promise resolving to the response data\n\t */\n\tprotected abstract executeXHRUpload<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T>\n\n\t/**\n\t * Normalize an error into a ModrinthApiError\n\t *\n\t * Platform implementations should override this to handle platform-specific errors\n\t * (e.g., FetchError from ofetch, Tauri HTTP errors)\n\t */\n\tprotected normalizeError(error: unknown, context?: RequestContext): ModrinthApiError {\n\t\tif (error instanceof ModrinthApiError) {\n\t\t\treturn error\n\t\t}\n\n\t\treturn ModrinthApiError.fromUnknown(error, context?.path)\n\t}\n\n\t/**\n\t * Helper to create a normalized error from extracted status code and response data\n\t */\n\tprotected createNormalizedError(\n\t\terror: Error,\n\t\tstatusCode: number | undefined,\n\t\tresponseData: unknown,\n\t): ModrinthApiError {\n\t\tif (statusCode && responseData) {\n\t\t\treturn ModrinthServerError.fromResponse(statusCode, responseData)\n\t\t}\n\n\t\treturn new ModrinthApiError(error.message, {\n\t\t\tstatusCode,\n\t\t\toriginalError: error,\n\t\t\tresponseData,\n\t\t})\n\t}\n\n\t/**\n\t * Add a feature to this client\n\t *\n\t * Features are executed in the order they are added.\n\t *\n\t * @example\n\t * ```typescript\n\t * const client = new GenericModrinthClient()\n\t * client.addFeature(new AuthFeature({ token: async () => getOAuthToken() }))\n\t * client.addFeature(new RetryFeature({ maxAttempts: 3 }))\n\t * ```\n\t */\n\taddFeature(feature: AbstractFeature): this {\n\t\tthis.features.push(feature)\n\t\treturn this\n\t}\n\n\t/**\n\t * Remove a feature from this client\n\t *\n\t * @example\n\t * ```typescript\n\t * const retryFeature = new RetryFeature({ maxAttempts: 3 })\n\t * client.addFeature(retryFeature)\n\t * // Later, remove it\n\t * client.removeFeature(retryFeature)\n\t * ```\n\t */\n\tremoveFeature(feature: AbstractFeature): this {\n\t\tconst index = this.features.indexOf(feature)\n\t\tif (index !== -1) {\n\t\t\tthis.features.splice(index, 1)\n\t\t}\n\t\treturn this\n\t}\n\n\t/**\n\t * Get all features on this client\n\t */\n\tgetFeatures(): AbstractFeature[] {\n\t\treturn [...this.features]\n\t}\n}\n", "import type { RequestContext } from '../types/request'\n\n/**\n * Base configuration for features\n */\nexport interface FeatureConfig {\n\t/**\n\t * Optional name for this feature (for debugging)\n\t */\n\tname?: string\n\n\t/**\n\t * Whether this feature is enabled\n\t * @default true\n\t */\n\tenabled?: boolean\n}\n\n/**\n * Abstract base class for request features\n *\n * Features are composable middleware that can intercept and modify requests.\n * They are executed in a chain, with each feature calling next() to continue the chain.\n */\nexport abstract class AbstractFeature {\n\tprotected config: FeatureConfig\n\n\tconstructor(config?: FeatureConfig) {\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\t...config,\n\t\t}\n\t}\n\n\t/**\n\t * Execute the feature logic\n\t *\n\t * @param next - Function to call the next feature in the chain (or the actual request)\n\t * @param context - Full request context\n\t * @returns Promise resolving to the response data\n\t *\n\t * @example\n\t * ```typescript\n\t * async execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t * // Do something before request\n\t * console.log('Before request:', context.url)\n\t *\n\t * try {\n\t * const result = await next()\n\t *\n\t * // Do something after successful request\n\t * console.log('Request succeeded')\n\t *\n\t * return result\n\t * } catch (error) {\n\t * // Handle errors\n\t * console.error('Request failed:', error)\n\t * throw error\n\t * }\n\t * }\n\t * ```\n\t */\n\tabstract execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T>\n\n\t/**\n\t * Determine if this feature should apply to the given request\n\t *\n\t * By default, features apply if they are enabled.\n\t * Override this to add custom logic (e.g., only apply to GET requests).\n\t *\n\t * @param context - Request context\n\t * @returns true if the feature should execute, false to skip\n\t */\n\tshouldApply(_context: RequestContext): boolean {\n\t\treturn this.config.enabled !== false\n\t}\n\n\t/**\n\t * Get the name of this feature (for debugging)\n\t */\n\tget name(): string {\n\t\treturn this.config.name ?? this.constructor.name\n\t}\n\n\t/**\n\t * Check if this feature is enabled\n\t */\n\tget enabled(): boolean {\n\t\treturn this.config.enabled !== false\n\t}\n}\n", "import type mitt from 'mitt'\n\nimport type { Archon } from '../modules/archon/types'\nimport type { RequestOptions } from '../types/request'\n\nexport type SyncEventType = Archon.Sync.v1.SyncEvent['type']\n\nexport type SyncEventOfType<E extends SyncEventType> = Extract<\n\tArchon.Sync.v1.SyncEvent,\n\t{ type: E }\n>\n\nexport type SyncEventHandler<E extends Archon.Sync.v1.SyncEvent = Archon.Sync.v1.SyncEvent> = (\n\tevent: E,\n) => void\n\nexport type SyncStatusState =\n\t| 'idle'\n\t| 'connecting'\n\t| 'connected'\n\t| 'reconnecting'\n\t| 'disconnected'\n\t| 'error'\n\nexport type SyncStatus = {\n\tstate: SyncStatusState\n\tconnected: boolean\n\treconnecting: boolean\n\treconnectAttempts: number\n\tretryDelay: number\n\tlastEventId?: string\n\terror?: unknown\n}\n\nexport type SyncStatusHandler = (status: SyncStatus) => void\n\nexport type SyncConnectOptions = {\n\tintent?: Archon.Sync.v1.SyncIntent\n\tforce?: boolean\n}\n\nexport type SyncConnection = {\n\tserverId: string\n\tintent: Archon.Sync.v1.SyncIntent\n\tcontroller?: AbortController\n\treconnectAttempts: number\n\treconnectTimer?: ReturnType<typeof setTimeout>\n\treconnectResolve?: () => void\n\tretryDelay: number\n\tlastEventId?: string\n\tstopped: boolean\n\tstatus: SyncStatusState\n\terror?: unknown\n}\n\nexport type SyncEmitterEvents = Record<string, unknown>\n\nexport abstract class AbstractSyncClient {\n\tprotected connections = new Map<string, SyncConnection>()\n\tprotected abstract emitter: ReturnType<typeof mitt<SyncEmitterEvents>>\n\n\tconstructor(\n\t\tprotected client: {\n\t\t\tstream: (path: string, options: RequestOptions) => Promise<ReadableStream<Uint8Array>>\n\t\t},\n\t) {}\n\n\tabstract safeConnectServer(serverId: string, options?: SyncConnectOptions): Promise<void>\n\n\tabstract disconnect(serverId: string): void\n\n\tabstract disconnectAll(): void\n\n\ton<E extends SyncEventType>(\n\t\tserverId: string,\n\t\teventType: E,\n\t\thandler: SyncEventHandler<SyncEventOfType<E>>,\n\t): () => void {\n\t\tconst eventKey = this.getEventKey(serverId, eventType)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tonAny(serverId: string, handler: SyncEventHandler): () => void {\n\t\tconst eventKey = this.getAnyEventKey(serverId)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tonStatus(serverId: string, handler: SyncStatusHandler): () => void {\n\t\tconst eventKey = this.getStatusEventKey(serverId)\n\t\tconst wrapped = handler as (event: unknown) => void\n\n\t\tthis.emitter.on(eventKey, wrapped)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, wrapped)\n\t\t}\n\t}\n\n\tgetStatus(serverId: string): SyncStatus | null {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return null\n\n\t\treturn this.connectionToStatus(connection)\n\t}\n\n\tprotected emitSyncEvent(serverId: string, event: Archon.Sync.v1.SyncEvent): void {\n\t\tthis.emitter.emit(this.getEventKey(serverId, event.type), event)\n\t\tthis.emitter.emit(this.getAnyEventKey(serverId), event)\n\t}\n\n\tprotected updateStatus(\n\t\tconnection: SyncConnection,\n\t\tstatus: SyncStatusState,\n\t\terror?: unknown,\n\t): void {\n\t\tconnection.status = status\n\t\tconnection.error = error\n\t\tthis.emitter.emit(\n\t\t\tthis.getStatusEventKey(connection.serverId),\n\t\t\tthis.connectionToStatus(connection),\n\t\t)\n\t}\n\n\tprotected clearListeners(serverId: string): void {\n\t\tthis.emitter.all.forEach((_handlers, type) => {\n\t\t\tif (type.toString().startsWith(`${serverId}:`)) {\n\t\t\t\tthis.emitter.all.delete(type)\n\t\t\t}\n\t\t})\n\t}\n\n\tprotected connectionToStatus(connection: SyncConnection): SyncStatus {\n\t\treturn {\n\t\t\tstate: connection.status,\n\t\t\tconnected: connection.status === 'connected',\n\t\t\treconnecting: connection.status === 'reconnecting',\n\t\t\treconnectAttempts: connection.reconnectAttempts,\n\t\t\tretryDelay: connection.retryDelay,\n\t\t\tlastEventId: connection.lastEventId,\n\t\t\terror: connection.error,\n\t\t}\n\t}\n\n\tprivate getEventKey(serverId: string, eventType: string): string {\n\t\treturn `${serverId}:${eventType}`\n\t}\n\n\tprivate getAnyEventKey(serverId: string): string {\n\t\treturn `${serverId}:*`\n\t}\n\n\tprivate getStatusEventKey(serverId: string): string {\n\t\treturn `${serverId}:__status`\n\t}\n}\n", "import type mitt from 'mitt'\n\nimport type { Archon } from '../modules/archon/types'\n\nexport type WebSocketEventHandler<\n\tE extends Archon.Websocket.v0.WSEvent = Archon.Websocket.v0.WSEvent,\n> = (event: E) => void\n\nexport interface WebSocketConnection {\n\tserverId: string\n\tsocket: WebSocket\n\tauthenticated: boolean\n\treconnectAttempts: number\n\treconnectTimer?: ReturnType<typeof setTimeout>\n\tisReconnecting: boolean\n}\n\nexport interface WebSocketStatus {\n\tconnected: boolean\n\treconnecting: boolean\n\treconnectAttempts: number\n}\n\ntype WSEventMap = {\n\t[K in Archon.Websocket.v0.WSEvent as `${string}:${K['event']}`]: K\n}\n\nexport abstract class AbstractWebSocketClient {\n\tprotected connections = new Map<string, WebSocketConnection>()\n\tprotected abstract emitter: ReturnType<typeof mitt<WSEventMap>>\n\n\tprotected readonly MAX_RECONNECT_ATTEMPTS = 10\n\tprotected readonly RECONNECT_BASE_DELAY = 1000\n\tprotected readonly RECONNECT_MAX_DELAY = 30000\n\tprotected readonly AUTHENTICATION_TIMEOUT = 30000\n\n\tconstructor(\n\t\tprotected client: {\n\t\t\tarchon: {\n\t\t\t\tservers_v0: {\n\t\t\t\t\tgetWebSocketAuth: (serverId: string) => Promise<Archon.Websocket.v0.WSAuth>\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t) {}\n\n\tabstract connect(serverId: string, auth: Archon.Websocket.v0.WSAuth): Promise<void>\n\n\tabstract disconnect(serverId: string): void\n\n\tabstract disconnectAll(): void\n\n\tabstract send(serverId: string, message: Archon.Websocket.v0.WSOutgoingMessage): void\n\n\tasync safeConnect(serverId: string, options?: { force?: boolean }): Promise<void> {\n\t\tconst status = this.getStatus(serverId)\n\n\t\tif (status?.connected && !options?.force) {\n\t\t\treturn\n\t\t}\n\n\t\tif (status && !status.connected && !options?.force) {\n\t\t\tawait this.waitForAuthentication(serverId)\n\t\t\treturn\n\t\t}\n\n\t\tif (options?.force && status) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\n\t\tconst auth = await this.client.archon.servers_v0.getWebSocketAuth(serverId)\n\t\tawait this.connect(serverId, auth)\n\t}\n\n\tprotected async waitForAuthentication(serverId: string): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tlet unsubscribe = () => {}\n\t\t\tconst timeout = setTimeout(() => {\n\t\t\t\tunsubscribe()\n\t\t\t\treject(new Error(`WebSocket authentication timed out for server ${serverId}`))\n\t\t\t}, this.AUTHENTICATION_TIMEOUT)\n\n\t\t\tunsubscribe = this.on(serverId, 'auth-ok', () => {\n\t\t\t\tclearTimeout(timeout)\n\t\t\t\tunsubscribe()\n\t\t\t\tresolve()\n\t\t\t})\n\n\t\t\tif (this.getStatus(serverId)?.connected) {\n\t\t\t\tclearTimeout(timeout)\n\t\t\t\tunsubscribe()\n\t\t\t\tresolve()\n\t\t\t}\n\t\t})\n\t}\n\n\ton<E extends Archon.Websocket.v0.WSEventType>(\n\t\tserverId: string,\n\t\teventType: E,\n\t\thandler: WebSocketEventHandler<Extract<Archon.Websocket.v0.WSEvent, { event: E }>>,\n\t): () => void {\n\t\tconst eventKey = `${serverId}:${eventType}` as keyof WSEventMap\n\n\t\tthis.emitter.on(eventKey, handler as () => void)\n\n\t\treturn () => {\n\t\t\tthis.emitter.off(eventKey, handler as () => void)\n\t\t}\n\t}\n\n\tgetStatus(serverId: string): WebSocketStatus | null {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return null\n\n\t\treturn {\n\t\t\tconnected: connection.socket.readyState === WebSocket.OPEN && connection.authenticated,\n\t\t\treconnecting: connection.isReconnecting,\n\t\t\treconnectAttempts: connection.reconnectAttempts,\n\t\t}\n\t}\n\n\tprotected getReconnectDelay(attempt: number): number {\n\t\tconst delay = Math.min(\n\t\t\tthis.RECONNECT_BASE_DELAY * Math.pow(2, attempt),\n\t\t\tthis.RECONNECT_MAX_DELAY,\n\t\t)\n\t\treturn delay + Math.random() * 1000\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Authentication feature configuration\n */\nexport interface AuthConfig extends FeatureConfig {\n\t/**\n\t * Authentication token\n\t * - string: static token\n\t * - function: async function that returns token (useful for dynamic tokens)\n\t */\n\ttoken: string | (() => Promise<string | undefined>)\n\n\t/**\n\t * Token prefix (e.g., 'Bearer', 'Token')\n\t * @default 'Bearer'\n\t */\n\ttokenPrefix?: string\n\n\t/**\n\t * Custom header name for the token\n\t * @default 'Authorization'\n\t */\n\theaderName?: string\n}\n\n/**\n * Authentication feature\n *\n * Automatically injects authentication tokens into request headers.\n * Supports both static tokens and dynamic token providers.\n *\n * @example\n * ```typescript\n * const auth = new AuthFeature({\n * token: async () => process.env.MODRINTH_TOKEN\n * })\n * ```\n */\nexport class AuthFeature extends AbstractFeature {\n\tdeclare protected config: AuthConfig\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst token = await this.getToken()\n\n\t\tif (token) {\n\t\t\tconst headerName = this.config.headerName ?? 'Authorization'\n\t\t\tconst tokenPrefix = this.config.tokenPrefix ?? 'Bearer'\n\t\t\tconst headerValue = tokenPrefix ? `${tokenPrefix} ${token}` : token\n\n\t\t\tcontext.options.headers = {\n\t\t\t\t...context.options.headers,\n\t\t\t\t[headerName]: headerValue,\n\t\t\t}\n\t\t}\n\n\t\treturn next()\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.skipAuth) {\n\t\t\treturn false\n\t\t}\n\n\t\t// Skip if Authorization header is already explicitly set\n\t\tconst headerName = this.config.headerName ?? 'Authorization'\n\t\tif (context.options.headers?.[headerName]) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Get the authentication token\n\t *\n\t * Handles both static tokens and async token providers\n\t */\n\tprivate async getToken(): Promise<string | undefined> {\n\t\tconst { token } = this.config\n\n\t\tif (typeof token === 'function') {\n\t\t\treturn await token()\n\t\t}\n\n\t\treturn token\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Circuit breaker state\n */\nexport type CircuitBreakerState = {\n\t/**\n\t * Number of consecutive failures\n\t */\n\tfailures: number\n\n\t/**\n\t * Timestamp of last failure\n\t */\n\tlastFailure: number\n}\n\n/**\n * Circuit breaker storage interface\n */\nexport interface CircuitBreakerStorage {\n\t/**\n\t * Get circuit breaker state for a key\n\t */\n\tget(key: string): CircuitBreakerState | undefined\n\n\t/**\n\t * Set circuit breaker state for a key\n\t */\n\tset(key: string, state: CircuitBreakerState): void\n\n\t/**\n\t * Clear circuit breaker state for a key\n\t */\n\tclear?(key: string): void\n}\n\n/**\n * Circuit breaker feature configuration\n */\nexport interface CircuitBreakerConfig extends FeatureConfig {\n\t/**\n\t * Maximum number of consecutive failures before opening circuit\n\t * @default 3\n\t */\n\tmaxFailures?: number\n\n\t/**\n\t * Time in milliseconds before circuit resets after opening\n\t * @default 30000\n\t */\n\tresetTimeout?: number\n\n\t/**\n\t * HTTP status codes that count as failures\n\t * @default [500, 502, 503, 504]\n\t */\n\tfailureStatusCodes?: number[]\n\n\t/**\n\t * Storage implementation for circuit state\n\t * If not provided, uses in-memory Map\n\t */\n\tstorage?: CircuitBreakerStorage\n\n\t/**\n\t * Function to generate circuit key from request context\n\t * By default, uses the base path (without query params)\n\t */\n\tgetCircuitKey?: (url: string, method: string) => string\n}\n\n/**\n * In-memory storage for circuit breaker state\n */\nexport class InMemoryCircuitBreakerStorage implements CircuitBreakerStorage {\n\tprivate state = new Map<string, CircuitBreakerState>()\n\n\tget(key: string): CircuitBreakerState | undefined {\n\t\treturn this.state.get(key)\n\t}\n\n\tset(key: string, state: CircuitBreakerState): void {\n\t\tthis.state.set(key, state)\n\t}\n\n\tclear(key: string): void {\n\t\tthis.state.delete(key)\n\t}\n}\n\n/**\n * Circuit breaker feature\n *\n * Prevents requests to failing endpoints by \"opening the circuit\" after\n * a threshold of consecutive failures. The circuit automatically resets\n * after a timeout period.\n *\n * This implements the circuit breaker pattern to prevent cascading failures\n * and give failing services time to recover.\n *\n * @example\n * ```typescript\n * const circuitBreaker = new CircuitBreakerFeature({\n * maxFailures: 3,\n * resetTimeout: 30000, // 30 seconds\n * failureStatusCodes: [500, 502, 503, 504]\n * })\n * ```\n */\nexport class CircuitBreakerFeature extends AbstractFeature {\n\tdeclare protected config: Required<CircuitBreakerConfig>\n\tprivate storage: CircuitBreakerStorage\n\n\tconstructor(config?: CircuitBreakerConfig) {\n\t\tsuper(config)\n\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\tname: 'circuit-breaker',\n\t\t\tmaxFailures: 3,\n\t\t\tresetTimeout: 30000,\n\t\t\tfailureStatusCodes: [500, 502, 503, 504],\n\t\t\t...config,\n\t\t} as Required<CircuitBreakerConfig>\n\n\t\t// Use provided storage or default to in-memory\n\t\tthis.storage = config?.storage ?? new InMemoryCircuitBreakerStorage()\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst circuitKey = this.getCircuitKey(context)\n\n\t\tif (this.isCircuitOpen(circuitKey)) {\n\t\t\tthrow new ModrinthApiError('Circuit breaker open - too many recent failures', {\n\t\t\t\tstatusCode: 503,\n\t\t\t\tcontext: context.path,\n\t\t\t})\n\t\t}\n\n\t\ttry {\n\t\t\tconst result = await next()\n\n\t\t\tthis.recordSuccess(circuitKey)\n\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tif (this.isFailureError(error)) {\n\t\t\t\tthis.recordFailure(circuitKey)\n\t\t\t}\n\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.circuitBreaker === false) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Get the circuit key for a request\n\t *\n\t * By default, uses the path and method to identify unique circuits\n\t */\n\tprivate getCircuitKey(context: RequestContext): string {\n\t\tif (this.config.getCircuitKey) {\n\t\t\treturn this.config.getCircuitKey(context.url, context.options.method ?? 'GET')\n\t\t}\n\n\t\t// Default: use method + path (without query params)\n\t\tconst method = context.options.method ?? 'GET'\n\t\tconst pathWithoutQuery = context.path.split('?')[0]\n\n\t\treturn `${method}_${pathWithoutQuery}`\n\t}\n\n\t/**\n\t * Check if the circuit is open for a given key\n\t */\n\tprivate isCircuitOpen(key: string): boolean {\n\t\tconst state = this.storage.get(key)\n\n\t\tif (!state) {\n\t\t\treturn false\n\t\t}\n\n\t\tconst now = Date.now()\n\t\tconst timeSinceLastFailure = now - state.lastFailure\n\n\t\tif (timeSinceLastFailure > this.config.resetTimeout) {\n\t\t\tthis.storage.clear?.(key)\n\t\t\treturn false\n\t\t}\n\n\t\treturn state.failures >= this.config.maxFailures\n\t}\n\n\t/**\n\t * Record a successful request\n\t */\n\tprivate recordSuccess(key: string): void {\n\t\tthis.storage.clear?.(key)\n\t}\n\n\t/**\n\t * Record a failed request\n\t */\n\tprivate recordFailure(key: string): void {\n\t\tconst now = Date.now()\n\t\tconst state = this.storage.get(key)\n\n\t\tif (!state) {\n\t\t\t// First failure\n\t\t\tthis.storage.set(key, {\n\t\t\t\tfailures: 1,\n\t\t\t\tlastFailure: now,\n\t\t\t})\n\t\t} else {\n\t\t\t// Subsequent failure\n\t\t\tthis.storage.set(key, {\n\t\t\t\tfailures: state.failures + 1,\n\t\t\t\tlastFailure: now,\n\t\t\t})\n\t\t}\n\t}\n\n\t/**\n\t * Determine if an error should count as a circuit failure\n\t */\n\tprivate isFailureError(error: unknown): boolean {\n\t\tif (error instanceof ModrinthApiError && error.statusCode) {\n\t\t\treturn this.config.failureStatusCodes.includes(error.statusCode)\n\t\t}\n\n\t\treturn false\n\t}\n\n\t/**\n\t * Get current circuit state for debugging\n\t *\n\t * @example\n\t * ```typescript\n\t * const state = circuitBreaker.getCircuitState('GET_/v2/project/sodium')\n\t * console.log(`Failures: ${state?.failures}, Last failure: ${state?.lastFailure}`)\n\t * ```\n\t */\n\tgetCircuitState(key: string): CircuitBreakerState | undefined {\n\t\treturn this.storage.get(key)\n\t}\n\n\t/**\n\t * Manually reset a circuit\n\t *\n\t * @example\n\t * ```typescript\n\t * // Reset circuit after manual intervention\n\t * circuitBreaker.resetCircuit('GET_/v2/project/sodium')\n\t * ```\n\t */\n\tresetCircuit(key: string): void {\n\t\tthis.storage.clear?.(key)\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\nimport { getNodeBaseUrl } from '../utils/node-url'\n\n/**\n * Node authentication credentials\n */\nexport interface NodeAuth {\n\t/** Node instance URL (e.g., \"node-xyz.modrinth.com/modrinth/v0/fs\") */\n\turl: string\n\t/** Base URL without path suffix (e.g., \"node-xyz.modrinth.com\") \u2014 used when available */\n\tbaseUrl?: string\n\t/** JWT token */\n\ttoken: string\n}\n\nexport interface NodeAuthConfig extends FeatureConfig {\n\t/**\n\t * Get current node auth. Returns null if not authenticated.\n\t */\n\tgetAuth: () => NodeAuth | null\n\n\t/**\n\t * Refresh the node authentication token.\n\t */\n\trefreshAuth: () => Promise<void>\n}\n\n/**\n * Handles authentication for Kyros node fs requests:\n * - Automatically injects Authorization header\n * - Builds the correct URL from node instance\n * - Handles 401 errors by refreshing and retrying (max 3 times)\n *\n * Only applies to requests with `useNodeAuth: true` in options.\n *\n * @example\n * ```typescript\n * const nodeAuth = new NodeAuthFeature({\n * getAuth: () => nodeAuthState.getAuth?.() ?? null,\n * refreshAuth: async () => {\n * if (nodeAuthState.refreshAuth) {\n * await nodeAuthState.refreshAuth()\n * }\n * },\n * })\n * client.addFeature(nodeAuth)\n * ```\n */\nexport class NodeAuthFeature extends AbstractFeature {\n\tdeclare protected config: NodeAuthConfig\n\tprivate refreshPromise: Promise<void> | null = null\n\n\tshouldApply(context: RequestContext): boolean {\n\t\treturn context.options.useNodeAuth === true && this.config.enabled !== false\n\t}\n\n\tprivate async refreshAuthWithLock(): Promise<void> {\n\t\tif (this.refreshPromise) {\n\t\t\treturn this.refreshPromise\n\t\t}\n\t\tthis.refreshPromise = this.config.refreshAuth().finally(() => {\n\t\t\tthis.refreshPromise = null\n\t\t})\n\t\treturn this.refreshPromise\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst maxRetries = 3\n\t\tlet retryCount = 0\n\n\t\tlet auth = this.config.getAuth()\n\t\tif (!auth || this.isTokenExpired(auth.token)) {\n\t\t\tawait this.refreshAuthWithLock()\n\t\t\tauth = this.config.getAuth()\n\t\t}\n\t\tif (!auth) {\n\t\t\tthrow new Error('Failed to obtain node authentication')\n\t\t}\n\n\t\tthis.applyAuth(context, auth)\n\n\t\twhile (true) {\n\t\t\ttry {\n\t\t\t\treturn await next()\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof ModrinthApiError && error.statusCode === 401) {\n\t\t\t\t\tretryCount++\n\t\t\t\t\tif (retryCount >= maxRetries) {\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t`Node authentication failed after ${maxRetries} retries. Please re-authenticate.`,\n\t\t\t\t\t\t)\n\t\t\t\t\t}\n\n\t\t\t\t\tawait this.refreshAuthWithLock()\n\t\t\t\t\tauth = this.config.getAuth()\n\t\t\t\t\tif (!auth) {\n\t\t\t\t\t\tthrow new Error('Failed to refresh node authentication')\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.applyAuth(context, auth)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate applyAuth(context: RequestContext, auth: NodeAuth): void {\n\t\tconst baseUrl = getNodeBaseUrl(auth.url)\n\t\tcontext.url = this.buildUrl(context.path, baseUrl, context.options.version)\n\n\t\tcontext.options.headers = {\n\t\t\t...context.options.headers,\n\t\t\tAuthorization: `Bearer ${auth.token}`,\n\t\t}\n\n\t\tcontext.options.skipAuth = true\n\t}\n\n\tprivate buildUrl(path: string, baseUrl: string, version: number | 'internal' | string): string {\n\t\tconst base = baseUrl.replace(/\\/$/, '')\n\t\tlet versionPath = ''\n\t\tif (version === 'internal') {\n\t\t\tversionPath = '/_internal'\n\t\t} else if (typeof version === 'number') {\n\t\t\tversionPath = `/v${version}`\n\t\t} else if (typeof version === 'string') {\n\t\t\tversionPath = `/${version}`\n\t\t}\n\t\tconst cleanPath = path.startsWith('/') ? path : `/${path}`\n\t\treturn `${base}${versionPath}${cleanPath}`\n\t}\n\n\t/**\n\t * Check if a JWT token is expired or about to expire\n\t * Refreshes proactively if expiring within next 10 seconds\n\t */\n\tprivate isTokenExpired(token: string): boolean {\n\t\ttry {\n\t\t\tconst payload = JSON.parse(atob(token.split('.')[1]))\n\t\t\tif (!payload.exp) return false\n\t\t\t// refresh if expiring within 10 seconds\n\t\t\tconst expiresAt = payload.exp * 1000\n\t\t\treturn Date.now() >= expiresAt - 10000\n\t\t} catch {\n\t\t\t// cant decode, assume valid and let server decide\n\t\t\treturn false\n\t\t}\n\t}\n}\n", "import { AbstractFeature } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\nexport const PANEL_VERSION = 1\n\nexport class PanelVersionFeature extends AbstractFeature {\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tcontext.options.headers = {\n\t\t\t...context.options.headers,\n\t\t\t'X-Panel-Version': String(PANEL_VERSION),\n\t\t}\n\t\treturn next()\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\treturn context.options.api === 'labrinth' || context.options.api === 'archon'\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\n\n/**\n * Backoff strategy for retries\n */\nexport type BackoffStrategy = 'exponential' | 'linear' | 'constant'\n\n/**\n * Retry feature configuration\n */\nexport interface RetryConfig extends FeatureConfig {\n\t/**\n\t * Maximum number of retry attempts\n\t * @default 3\n\t */\n\tmaxAttempts?: number\n\n\t/**\n\t * Backoff strategy to use\n\t * @default 'exponential'\n\t */\n\tbackoffStrategy?: BackoffStrategy\n\n\t/**\n\t * Initial delay in milliseconds before first retry\n\t * @default 1000\n\t */\n\tinitialDelay?: number\n\n\t/**\n\t * Maximum delay in milliseconds between retries\n\t * @default 15000\n\t */\n\tmaxDelay?: number\n\n\t/**\n\t * HTTP status codes that should trigger a retry\n\t * @default [408, 429, 500, 502, 503, 504]\n\t */\n\tretryableStatusCodes?: number[]\n\n\t/**\n\t * Whether to retry on network errors (connection refused, timeout, etc.)\n\t * @default true\n\t */\n\tretryOnNetworkError?: boolean\n\n\t/**\n\t * Custom function to determine if an error should be retried\n\t */\n\tshouldRetry?: (error: unknown, attempt: number) => boolean\n}\n\n/**\n * Retry feature\n *\n * Automatically retries failed requests with configurable backoff strategy.\n * Only retries errors that are likely to succeed on retry (e.g., timeout, 5xx errors).\n *\n * @example\n * ```typescript\n * const retry = new RetryFeature({\n * maxAttempts: 3,\n * backoffStrategy: 'exponential',\n * initialDelay: 1000,\n * maxDelay: 15000\n * })\n * ```\n */\nexport class RetryFeature extends AbstractFeature {\n\tdeclare protected config: Required<RetryConfig>\n\n\tconstructor(config?: RetryConfig) {\n\t\tsuper(config)\n\n\t\tthis.config = {\n\t\t\tenabled: true,\n\t\t\tname: 'retry',\n\t\t\tmaxAttempts: 3,\n\t\t\tbackoffStrategy: 'exponential',\n\t\t\tinitialDelay: 1000,\n\t\t\tmaxDelay: 15000,\n\t\t\tretryableStatusCodes: [408, 429, 500, 502, 503, 504],\n\t\t\tretryOnNetworkError: true,\n\t\t\t...config,\n\t\t} as Required<RetryConfig>\n\t}\n\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tlet lastError: Error | null = null\n\t\tconst maxAttempts = this.getMaxAttempts(context)\n\n\t\tfor (let attempt = 1; attempt <= maxAttempts; attempt++) {\n\t\t\tcontext.attempt = attempt\n\n\t\t\ttry {\n\t\t\t\tconst result = await next()\n\t\t\t\treturn result\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error as Error\n\n\t\t\t\tconst shouldRetry = this.shouldRetryError(error, attempt, maxAttempts)\n\n\t\t\t\tif (!shouldRetry || attempt >= maxAttempts) {\n\t\t\t\t\tthrow error\n\t\t\t\t}\n\n\t\t\t\tconst delay = this.calculateDelay(attempt)\n\n\t\t\t\tconsole.warn(\n\t\t\t\t\t`[${this.name}] Retrying request to ${context.path} (attempt ${attempt + 1}/${maxAttempts}) after ${delay}ms`,\n\t\t\t\t)\n\n\t\t\t\tawait this.sleep(delay)\n\t\t\t}\n\t\t}\n\n\t\t// This shouldn't be reached, but TypeScript requires it\n\t\tthrow lastError ?? new Error('Max retry attempts reached')\n\t}\n\n\tshouldApply(context: RequestContext): boolean {\n\t\tif (context.options.retry === false) {\n\t\t\treturn false\n\t\t}\n\n\t\treturn super.shouldApply(context)\n\t}\n\n\t/**\n\t * Determine if an error should be retried\n\t */\n\tprivate shouldRetryError(error: unknown, attempt: number, _maxAttempts: number): boolean {\n\t\tif (this.config.shouldRetry) {\n\t\t\treturn this.config.shouldRetry(error, attempt)\n\t\t}\n\n\t\tif (this.config.retryOnNetworkError && this.isNetworkError(error)) {\n\t\t\treturn true\n\t\t}\n\n\t\tif (error instanceof ModrinthApiError && error.statusCode) {\n\t\t\treturn this.config.retryableStatusCodes.includes(error.statusCode)\n\t\t}\n\n\t\treturn false\n\t}\n\n\t/**\n\t * Check if an error is a network error\n\t */\n\tprivate isNetworkError(error: unknown): boolean {\n\t\t// Common network error indicators\n\t\tconst networkErrorPatterns = [\n\t\t\t/network/i,\n\t\t\t/timeout/i,\n\t\t\t/ECONNREFUSED/i,\n\t\t\t/ENOTFOUND/i,\n\t\t\t/ETIMEDOUT/i,\n\t\t\t/ECONNRESET/i,\n\t\t]\n\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error)\n\t\treturn networkErrorPatterns.some((pattern) => pattern.test(errorMessage))\n\t}\n\n\t/**\n\t * Get max attempts for this request\n\t */\n\tprivate getMaxAttempts(context: RequestContext): number {\n\t\tif (typeof context.options.retry === 'number') {\n\t\t\treturn context.options.retry\n\t\t}\n\n\t\treturn this.config.maxAttempts\n\t}\n\n\t/**\n\t * Calculate delay before next retry based on backoff strategy\n\t */\n\tprivate calculateDelay(attempt: number): number {\n\t\tconst { backoffStrategy, initialDelay, maxDelay } = this.config\n\n\t\tlet delay: number\n\n\t\tswitch (backoffStrategy) {\n\t\t\tcase 'exponential':\n\t\t\t\t// Exponential: delay = initialDelay * 2^(attempt-1)\n\t\t\t\tdelay = initialDelay * Math.pow(2, attempt - 1)\n\t\t\t\tbreak\n\n\t\t\tcase 'linear':\n\t\t\t\t// Linear: delay = initialDelay * attempt\n\t\t\t\tdelay = initialDelay * attempt\n\t\t\t\tbreak\n\n\t\t\tcase 'constant':\n\t\t\t\t// Constant: delay = initialDelay\n\t\t\t\tdelay = initialDelay\n\t\t\t\tbreak\n\n\t\t\tdefault:\n\t\t\t\tdelay = initialDelay\n\t\t}\n\n\t\t// Add jitter (random 0-1000ms) to prevent thundering herd\n\t\tdelay += Math.random() * 1000\n\n\t\treturn Math.min(delay, maxDelay)\n\t}\n\n\t/**\n\t * Sleep for a given duration\n\t */\n\tprivate sleep(ms: number): Promise<void> {\n\t\treturn new Promise((resolve) => setTimeout(resolve, ms))\n\t}\n}\n", "import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature'\nimport type { RequestContext } from '../types/request'\n\nexport type VerboseLoggingConfig = FeatureConfig\n\nexport class VerboseLoggingFeature extends AbstractFeature {\n\tasync execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {\n\t\tconst method = context.options.method ?? 'GET'\n\t\tconst api = context.options.api\n\t\tconst version = context.options.version\n\t\tconst prefix = `[${method}] [${api}_v${version}]`\n\n\t\tconsole.debug(`${prefix} ${context.url} SENT`)\n\n\t\ttry {\n\t\t\tconst result = await next()\n\t\t\ttry {\n\t\t\t\tconst size = result ? JSON.stringify(result).length : 0\n\t\t\t\tconsole.debug(`${prefix} ${context.url} RECEIVED ${size} bytes`)\n\t\t\t} catch {\n\t\t\t\t// ignore size calc fail\n\t\t\t\tconsole.debug(`${prefix} ${context.url} RECEIVED`)\n\t\t\t}\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tconst details = formatErrorDetails(error)\n\t\t\tconsole.debug(`${prefix} ${context.url} FAILED${details ? ` \u2014 ${details}` : ''}`)\n\t\t\tthrow error\n\t\t}\n\t}\n}\n\nfunction formatErrorDetails(error: unknown): string {\n\tif (!error || typeof error !== 'object') {\n\t\treturn typeof error === 'string' ? error : ''\n\t}\n\n\tconst err = error as {\n\t\tstatus?: number\n\t\tstatusCode?: number\n\t\tstatusText?: string\n\t\tmessage?: string\n\t\tdata?: unknown\n\t\tresponseData?: unknown\n\t\toriginalError?: unknown\n\t\tresponse?: { status?: number; statusText?: string; _data?: unknown }\n\t}\n\n\tconst status = err.status ?? err.statusCode ?? err.response?.status\n\tconst statusText = err.statusText ?? err.response?.statusText\n\tconst data = err.responseData ?? err.data ?? err.response?._data\n\n\tconst parts: string[] = []\n\tif (status !== undefined) {\n\t\tparts.push(statusText ? `${status} ${statusText}` : String(status))\n\t}\n\tif (data !== undefined) {\n\t\tparts.push(`body: ${safeStringify(data)}`)\n\t} else if (err.message) {\n\t\tparts.push(err.message)\n\t}\n\treturn parts.join(' ')\n}\n\nfunction safeStringify(value: unknown): string {\n\tif (typeof value === 'string') return value\n\ttry {\n\t\treturn JSON.stringify(value)\n\t} catch {\n\t\treturn String(value)\n\t}\n}\n", "import type { Labrinth } from '../labrinth/types'\n\nexport namespace Archon {\n\texport namespace Nodes {\n\t\texport namespace Internal {\n\t\t\texport type Node = {\n\t\t\t\tid: string\n\t\t\t\thostname: string\n\t\t\t\tregion: string\n\t\t\t\tcreated_at: string | null\n\t\t\t\tlocked: boolean\n\t\t\t}\n\n\t\t\texport type Server = {\n\t\t\t\tid: string\n\t\t\t\tavailable: boolean\n\t\t\t}\n\n\t\t\texport type NodeFull = Node & {\n\t\t\t\tservers: Server[]\n\t\t\t}\n\n\t\t\texport type Overview = {\n\t\t\t\tnode_hostnames: string[]\n\t\t\t\tregions: Region[]\n\t\t\t\ttotal_servers_active: number\n\t\t\t}\n\n\t\t\texport type Region = {\n\t\t\t\tdisplay_name: string\n\t\t\t\tcountry_code: string\n\t\t\t\tkey: string\n\t\t\t\tserver_count: number\n\t\t\t\tnode_count: number\n\t\t\t}\n\n\t\t\texport type RegionWithStatistics = {\n\t\t\t\tregion: Region\n\t\t\t\tactive_servers: string[]\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Notices {\n\t\texport namespace v0 {\n\t\t\texport type Notice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\ttitle: string | null\n\t\t\t\tmessage: string\n\t\t\t\tlevel: string\n\t\t\t\tannounced: string\n\t\t\t}\n\n\t\t\texport type ListedNotice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\tmessage: string\n\t\t\t\ttitle: string | null\n\t\t\t\tlevel: string\n\t\t\t\tannounce_at: string\n\t\t\t\texpires: string | null\n\t\t\t\tassigned: Assignment[]\n\t\t\t\tdismissed_by: Dismisser[]\n\t\t\t}\n\n\t\t\texport type Dismisser = {\n\t\t\t\tserver: string\n\t\t\t\tdismissed_on: string\n\t\t\t}\n\n\t\t\texport type Assignment = {\n\t\t\t\tkind: string\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type AssignmentTarget = { server: string } | { node: string }\n\n\t\t\texport type Announce = {\n\t\t\t\tmessage: string\n\t\t\t\ttitle?: string | null\n\t\t\t\tlevel: string\n\t\t\t\tdismissable: boolean\n\t\t\t\tannounce_at: string\n\t\t\t\texpires?: string | null\n\t\t\t}\n\n\t\t\texport type AnnouncePatch = {\n\t\t\t\tmessage?: string\n\t\t\t\ttitle?: string | null\n\t\t\t\tlevel?: string\n\t\t\t\tdismissable?: boolean\n\t\t\t\tannounce_at?: string\n\t\t\t\texpires?: string | null\n\t\t\t}\n\n\t\t\texport type PostNoticeResponseBody = {\n\t\t\t\tid: number\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Actions {\n\t\texport namespace v1 {\n\t\t\texport type SortOrder = 'asc' | 'desc'\n\n\t\t\texport type ActionName =\n\t\t\t\t| 'server_created'\n\t\t\t\t| 'changed_server_name'\n\t\t\t\t| 'changed_server_subdomain'\n\t\t\t\t| 'server_reallocated'\n\t\t\t\t| 'server_plan_changed'\n\t\t\t\t| 'user_invited'\n\t\t\t\t| 'user_invite_revoked'\n\t\t\t\t| 'user_permission_modified'\n\t\t\t\t| 'user_removed'\n\t\t\t\t| 'addon_added'\n\t\t\t\t| 'addon_uploaded'\n\t\t\t\t| 'addon_disabled'\n\t\t\t\t| 'addon_enabled'\n\t\t\t\t| 'addon_deleted'\n\t\t\t\t| 'addon_updated'\n\t\t\t\t| 'modpack_changed'\n\t\t\t\t| 'modpack_unlinked'\n\t\t\t\t| 'server_repaired'\n\t\t\t\t| 'server_reset'\n\t\t\t\t| 'server_started'\n\t\t\t\t| 'server_stopped'\n\t\t\t\t| 'server_restarted'\n\t\t\t\t| 'server_killed'\n\t\t\t\t| 'port_allocation_added'\n\t\t\t\t| 'port_allocation_removed'\n\t\t\t\t| 'loader_version_edited'\n\t\t\t\t| 'game_version_edited'\n\t\t\t\t| 'server_properties_modified'\n\t\t\t\t| 'file_uploaded'\n\t\t\t\t| 'file_deleted'\n\t\t\t\t| 'file_renamed'\n\t\t\t\t| 'file_edited'\n\t\t\t\t| 'sftp_login'\n\t\t\t\t| 'console_command_executed'\n\t\t\t\t| 'console_cleared'\n\t\t\t\t| 'backup_created'\n\t\t\t\t| 'backup_renamed'\n\t\t\t\t| 'backup_restored'\n\t\t\t\t| 'backup_deleted'\n\t\t\t\t| 'startup_command_modified'\n\t\t\t\t| 'java_runtime_modified'\n\t\t\t\t| 'java_version_modified'\n\n\t\t\texport type Action = {\n\t\t\t\taction: ActionName | string\n\t\t\t\tmetadata?: unknown\n\t\t\t}\n\n\t\t\texport type UserPermissionsActionMetadata = {\n\t\t\t\tuser_id: string\n\t\t\t\tpermissions?: ServerUsers.v1.UserScope | null\n\t\t\t}\n\n\t\t\texport type ActionUser =\n\t\t\t\t| {\n\t\t\t\t\t\ttype: 'user'\n\t\t\t\t\t\tuser_id: string\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\ttype: 'support'\n\t\t\t\t\t\tuser_id?: string | null\n\t\t\t\t }\n\n\t\t\texport type ActionEntry = {\n\t\t\t\tactor: ActionUser\n\t\t\t\taction: Action\n\t\t\t\tserver_id: string\n\t\t\t\tworld_id?: string | null\n\t\t\t\ttimestamp: string\n\t\t\t}\n\n\t\t\texport type UserResp = {\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type AddonResp = {\n\t\t\t\ttitle: string\n\t\t\t\tslug?: string | null\n\t\t\t\ticon_url?: string | null\n\t\t\t\tversion?: string | null\n\t\t\t}\n\n\t\t\texport type VersionResp = {\n\t\t\t\tname: string\n\t\t\t\tversion_number?: string | null\n\t\t\t}\n\n\t\t\texport type ActionLogResponse = {\n\t\t\t\tnext_offset?: number | null\n\t\t\t\tdata: ActionEntry[]\n\t\t\t\tusers: Record<string, UserResp>\n\t\t\t\taddons: Record<string, AddonResp>\n\t\t\t\tversions: Record<string, VersionResp>\n\t\t\t}\n\n\t\t\texport type ActionLogFilter = {\n\t\t\t\tusers?: string[]\n\t\t\t\tworlds?: Array<string | null>\n\t\t\t\tactions?: ActionName[]\n\t\t\t}\n\n\t\t\texport type ListActionLogOptions = {\n\t\t\t\tfilter?: ActionLogFilter\n\t\t\t\tlimit?: number\n\t\t\t\toffset?: number\n\t\t\t\torder?: SortOrder\n\t\t\t\tmin_datetime?: string\n\t\t\t\tmax_datetime?: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Transfers {\n\t\texport namespace Internal {\n\t\t\texport type ProvisionOptions = {\n\t\t\t\tregion?: string | null\n\t\t\t\tnode_tags: string[]\n\t\t\t}\n\n\t\t\texport type ScheduleServerTransfersRequest = {\n\t\t\t\tserver_ids: string[]\n\t\t\t\tscheduled_at?: string | null\n\t\t\t\ttarget_region?: string | null\n\t\t\t\tnode_tags?: string[]\n\t\t\t\treason?: string | null\n\t\t\t}\n\n\t\t\texport type ScheduleNodeTransfersRequest = {\n\t\t\t\tnode_hostnames: string[]\n\t\t\t\tscheduled_at?: string | null\n\t\t\t\ttarget_region?: string | null\n\t\t\t\tnode_tags?: string[]\n\t\t\t\treason?: string | null\n\t\t\t\tcordon_nodes?: boolean\n\t\t\t\ttag_nodes?: string | null\n\t\t\t}\n\n\t\t\texport type ScheduleTransfersResponse = {\n\t\t\t\tbatch_id: number\n\t\t\t\tscheduled_count: number\n\t\t\t}\n\n\t\t\texport type CancelTransfersRequest = {\n\t\t\t\tbatch_ids: number[]\n\t\t\t}\n\n\t\t\texport type CancelTransfersResponse = {\n\t\t\t\tcancelled_count: number\n\t\t\t}\n\n\t\t\texport type TransferLogBatchEntry = {\n\t\t\t\tid: number\n\t\t\t\tcreated_by: string\n\t\t\t\tcreated_at: string\n\t\t\t\treason?: string | null\n\t\t\t\tscheduled_at: string\n\t\t\t\tcancelled: boolean\n\t\t\t\tlog_count: number\n\t\t\t\tprovision_options: ProvisionOptions\n\t\t\t}\n\n\t\t\texport type TransferHistoryQuery = {\n\t\t\t\tpage?: number\n\t\t\t\tpage_size?: number\n\t\t\t}\n\n\t\t\texport type TransferHistoryResponse = {\n\t\t\t\tbatches: TransferLogBatchEntry[]\n\t\t\t\ttotal: number\n\t\t\t\tpage: number\n\t\t\t\tpage_size: number\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Content {\n\t\texport namespace v1 {\n\t\t\texport type AddonKind = 'mod' | 'plugin' | 'datapack' | 'shader' | 'resourcepack'\n\n\t\t\texport type ContentOwnerType = 'user' | 'organization'\n\n\t\t\texport type ContentOwner = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\ttype: ContentOwnerType\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type AddonVersion = {\n\t\t\t\tid: string\n\t\t\t\tname: string | null\n\t\t\t\tenvironment?: Labrinth.Projects.v3.Environment | null\n\t\t\t}\n\n\t\t\texport type AddonStatus =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'installed'\n\t\t\t\t| {\n\t\t\t\t\t\tfailed: {\n\t\t\t\t\t\t\terror: string\n\t\t\t\t\t\t}\n\t\t\t\t }\n\n\t\t\texport type Addon = {\n\t\t\t\tid: string\n\t\t\t\tfilename: string\n\t\t\t\tfilesize: number\n\t\t\t\tbtime?: string\n\t\t\t\tdisabled: boolean\n\t\t\t\tkind: AddonKind\n\t\t\t\tfrom_modpack: boolean\n\t\t\t\tstatus: AddonStatus\n\t\t\t\tpack_client_retained: boolean\n\t\t\t\tpack_client_depends: boolean\n\t\t\t\thas_update: string | null\n\t\t\t\tname: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tversion: AddonVersion | null\n\t\t\t\towner: ContentOwner | null\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type Addons = {\n\t\t\t\tmodloader: string | null\n\t\t\t\tmodloader_version: string | null\n\t\t\t\tgame_version: string | null\n\t\t\t\tmodpack: ModpackFields | null\n\t\t\t\tinstalling?: 'loader' | 'modpack'\n\t\t\t\terror?: {\n\t\t\t\t\tmessage: string\n\t\t\t\t}\n\t\t\t\taddons: Addon[] | null\n\t\t\t}\n\n\t\t\texport type AddAddonRequest = {\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id?: string\n\t\t\t\tkind?: AddonKind\n\t\t\t}\n\n\t\t\texport type AddAddonsRequest = AddAddonRequest[]\n\n\t\t\texport type RemoveAddonRequest = {\n\t\t\t\tkind: AddonKind\n\t\t\t\tfilename: string\n\t\t\t}\n\n\t\t\texport type UpdateAddonRequest = {\n\t\t\t\tfilename: string\n\t\t\t\tversion_id?: string | null\n\t\t\t}\n\n\t\t\texport type Modloader =\n\t\t\t\t| 'forge'\n\t\t\t\t| 'neo_forge'\n\t\t\t\t| 'fabric'\n\t\t\t\t| 'quilt'\n\t\t\t\t| 'paper'\n\t\t\t\t| 'purpur'\n\t\t\t\t| 'vanilla'\n\n\t\t\texport type ModpackSpecModrinth = {\n\t\t\t\tplatform: 'modrinth'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type ModpackSpecLocalFile = {\n\t\t\t\tplatform: 'local_file'\n\t\t\t\tfilename: string\n\t\t\t\tname: string\n\t\t\t\tdescription: string | null\n\t\t\t}\n\n\t\t\texport type ModpackSpec = ModpackSpecModrinth | ModpackSpecLocalFile\n\n\t\t\texport type ModpackOwner = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\ttype: 'user' | 'organization'\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\n\t\t\texport type ModpackFields = {\n\t\t\t\tspec: ModpackSpec\n\t\t\t\thas_update: string | null\n\t\t\t\ttitle: string | null\n\t\t\t\tdescription: string | null\n\t\t\t\ticon_url: string | null\n\t\t\t\towner: ModpackOwner | null\n\t\t\t\tversion_number: string | null\n\t\t\t\tdate_published: string | null\n\t\t\t\tdownloads: number | null\n\t\t\t\tfollowers: number | null\n\t\t\t}\n\n\t\t\texport type KnownPropertiesFields = {\n\t\t\t\tallow_cheats?: string | null\n\t\t\t\tallow_flight?: string | null\n\t\t\t\tdifficulty?: string | null\n\t\t\t\tenforce_whitelist?: string | null\n\t\t\t\tforce_gamemode?: string | null\n\t\t\t\tgamemode?: string | null\n\t\t\t\tgenerate_structures?: string | null\n\t\t\t\tgenerator_settings?: string | null\n\t\t\t\thardcore?: string | null\n\t\t\t\tlevel_seed?: string | null\n\t\t\t\tlevel_type?: string | null\n\t\t\t\tmax_players?: string | null\n\t\t\t\tmax_tick_time?: string | null\n\t\t\t\tmotd?: string | null\n\t\t\t\tpause_when_empty_seconds?: string | null\n\t\t\t\tplayer_idle_timeout?: string | null\n\t\t\t\trequire_resource_pack?: string | null\n\t\t\t\tresource_pack?: string | null\n\t\t\t\tresource_pack_id?: string | null\n\t\t\t\tresource_pack_sha1?: string | null\n\t\t\t\tsimulation_distance?: string | null\n\t\t\t\tspawn_protection?: string | null\n\t\t\t\tsync_chunk_writes?: string | null\n\t\t\t\tview_distance?: string | null\n\t\t\t\twhite_list?: string | null\n\t\t\t}\n\n\t\t\texport type PropertiesFields = {\n\t\t\t\tknown: KnownPropertiesFields\n\t\t\t\tcustom?: Record<string, string>\n\t\t\t}\n\n\t\t\texport type PatchPropertiesFields = {\n\t\t\t\tknown?: KnownPropertiesFields\n\t\t\t\tcustom?: Record<string, string | null>\n\t\t\t}\n\n\t\t\texport type JreVendor = 'temurin' | 'corretto' | 'graal'\n\n\t\t\texport type RuntimeOptions = {\n\t\t\t\tjava_version: number | null\n\t\t\t\tjre_vendor: JreVendor | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t\tstartup_command: string | null\n\t\t\t}\n\n\t\t\texport type PatchRuntimeOptions = {\n\t\t\t\tjava_version?: number | null\n\t\t\t\tjre_vendor?: JreVendor | null\n\t\t\t\tstartup_command?: string | null\n\t\t\t}\n\n\t\t\texport type InstallWorldContent =\n\t\t\t\t| {\n\t\t\t\t\t\tcontent_variant: 'modpack'\n\t\t\t\t\t\tspec: ModpackSpec\n\t\t\t\t\t\tsoft_override: boolean\n\t\t\t\t\t\tproperties?: PropertiesFields | null\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tcontent_variant: 'bare'\n\t\t\t\t\t\tloader: Modloader\n\t\t\t\t\t\tversion: string\n\t\t\t\t\t\tgame_version?: string\n\t\t\t\t\t\tsoft_override: boolean\n\t\t\t\t\t\tproperties?: PropertiesFields | null\n\t\t\t\t }\n\n\t\t\texport type AddonDiffVersion = {\n\t\t\t\tid: string\n\t\t\t\tversion_number: string\n\t\t\t}\n\n\t\t\texport type AddonDiffProject = {\n\t\t\t\tid: string\n\t\t\t\ttitle: string\n\t\t\t\ticon_url: string | null\n\t\t\t\tslug: string\n\t\t\t}\n\n\t\t\texport type AddonBaseDiffInfo = {\n\t\t\t\tcurrent_version: AddonDiffVersion | null\n\t\t\t\tnew_version: AddonDiffVersion | null\n\t\t\t\tfile_name: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tproject: AddonDiffProject | null\n\t\t\t}\n\n\t\t\texport type AddonDiffAdded = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'added'\n\t\t\t\tnew_version_id: string\n\t\t\t}\n\n\t\t\texport type AddonDiffRemoved = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'removed'\n\t\t\t}\n\n\t\t\texport type AddonDiffUpdated = AddonBaseDiffInfo & {\n\t\t\t\ttype: 'updated'\n\t\t\t\tcurrent_version_id: string\n\t\t\t\tnew_version_id: string\n\t\t\t}\n\n\t\t\texport type AddonDiff = AddonDiffAdded | AddonDiffRemoved | AddonDiffUpdated\n\n\t\t\texport type UpdateGameVersionPreview = {\n\t\t\t\taddon_changes: AddonDiff[]\n\t\t\t\tnew_game_version: string\n\t\t\t\tnew_loader_version: string\n\t\t\t\thas_unknown_content: boolean\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace ServerUsers {\n\t\texport namespace v1 {\n\t\t\texport type ServerUserRole = 'Owner' | 'Editor' | 'Viewer' | 'Unknown'\n\n\t\t\texport type AssignableServerUserRole = Exclude<ServerUserRole, 'Owner' | 'Unknown'>\n\n\t\t\texport const UserScope = {\n\t\t\t\tNONE: '',\n\t\t\t\tSERVER_ADMIN: 'SERVER_ADMIN',\n\t\t\t\tBASE_READ: 'BASE_READ',\n\t\t\t\tPOWER_ACTIONS: 'POWER_ACTIONS',\n\t\t\t\tEXEC_COMMANDS: 'EXEC_COMMANDS',\n\t\t\t\tFILES_WRITE: 'FILES_WRITE',\n\t\t\t\tSETUP: 'SETUP',\n\t\t\t\tBACKUPS: 'BACKUPS',\n\t\t\t\tADVANCED: 'ADVANCED',\n\t\t\t\tRESET_SERVER: 'RESET_SERVER',\n\t\t\t\tMANAGE_USERS: 'MANAGE_USERS',\n\t\t\t\tSUPPORT_AGENT: 'SUPPORT_AGENT',\n\t\t\t\tINFRA_MANAGER: 'INFRA_MANAGER',\n\t\t\t\tINFRA_MANAGER_READ: 'INFRA_MANAGER_READ',\n\t\t\t\tINFRA_SERVERS_XFER: 'INFRA_SERVERS_XFER',\n\t\t\t\tINFRA_USERS: 'INFRA_USERS',\n\t\t\t} as const\n\n\t\t\texport type UserScope = string | number\n\n\t\t\texport type UserResp = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type ServerUser = {\n\t\t\t\tuser: UserResp\n\t\t\t\tadded_on?: string | null\n\t\t\t\tlast_invite_sent?: string | null\n\t\t\t\tpermissions: UserScope\n\t\t\t}\n\n\t\t\texport type AddServerUserRequest = {\n\t\t\t\tserver_id?: string | null\n\t\t\t\tuser_id: string\n\t\t\t\tadded_on?: string | null\n\t\t\t\trole: ServerUserRole\n\t\t\t}\n\n\t\t\texport type ReinviteResponse = {\n\t\t\t\tsent: boolean\n\t\t\t\tcooldown_seconds: number | null\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Servers {\n\t\texport namespace Internal {\n\t\t\texport type Lookup = {\n\t\t\t\tid: string\n\t\t\t}\n\t\t}\n\n\t\texport namespace v0 {\n\t\t\texport type ServerGetResponse = {\n\t\t\t\tservers: Server[]\n\t\t\t\tpagination: Pagination\n\t\t\t\tusers: Record<string, ServerOwner>\n\t\t\t}\n\n\t\t\texport type Pagination = {\n\t\t\t\tcurrent_page: number\n\t\t\t\tpage_size: number\n\t\t\t\ttotal_pages: number\n\t\t\t\ttotal_items: number\n\t\t\t}\n\n\t\t\texport type ServerOwner = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url?: string | null\n\t\t\t}\n\n\t\t\texport type Status = 'installing' | 'broken' | 'available' | 'suspended'\n\n\t\t\texport type SuspensionReason =\n\t\t\t\t| 'moderated'\n\t\t\t\t| 'paymentfailed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'upgrading'\n\t\t\t\t| 'other'\n\n\t\t\texport type Loader =\n\t\t\t\t| 'Forge'\n\t\t\t\t| 'NeoForge'\n\t\t\t\t| 'Fabric'\n\t\t\t\t| 'Quilt'\n\t\t\t\t| 'Purpur'\n\t\t\t\t| 'Spigot'\n\t\t\t\t| 'Vanilla'\n\t\t\t\t| 'Paper'\n\n\t\t\texport type Game = 'Minecraft'\n\n\t\t\texport type UpstreamKind = 'modpack' | 'none'\n\n\t\t\texport type Server = {\n\t\t\t\tserver_id: string\n\t\t\t\tname: string\n\t\t\t\towner_id: string\n\t\t\t\tnet: Net\n\t\t\t\tgame: Game\n\t\t\t\tbackup_quota: number\n\t\t\t\tused_backup_quota: number\n\t\t\t\tstatus: Status\n\t\t\t\tsuspension_reason: SuspensionReason | null\n\t\t\t\tloader: Loader | null\n\t\t\t\tloader_version: string | null\n\t\t\t\tmc_version: string | null\n\t\t\t\tupstream: Upstream | null\n\t\t\t\tsftp_username: string\n\t\t\t\tsftp_password: string\n\t\t\t\tsftp_host: string\n\t\t\t\tdatacenter: string\n\t\t\t\tnotices: Notice[]\n\t\t\t\tnode: NodeInfo | null\n\t\t\t\tflows: Flows\n\t\t\t\tis_medal: boolean\n\t\t\t\tcurrent_user_permissions: UserScope\n\n\t\t\t\tmedal_expires?: string\n\t\t\t}\n\n\t\t\texport type UserScope = number\n\n\t\t\texport type Net = {\n\t\t\t\tip: string | null\n\t\t\t\tport: number\n\t\t\t\tdomain: string\n\t\t\t}\n\n\t\t\texport type Upstream = {\n\t\t\t\tkind: UpstreamKind\n\t\t\t\tversion_id: string\n\t\t\t\tproject_id: string\n\t\t\t}\n\n\t\t\texport type Notice = {\n\t\t\t\tid: number\n\t\t\t\tdismissable: boolean\n\t\t\t\ttitle: string\n\t\t\t\tmessage: string\n\t\t\t\tlevel: string\n\t\t\t\tannounced: string\n\t\t\t}\n\n\t\t\texport type NodeInfo = {\n\t\t\t\ttoken: string\n\t\t\t\tinstance: string\n\t\t\t}\n\n\t\t\texport type Flows = {\n\t\t\t\tintro: boolean\n\t\t\t}\n\n\t\t\texport type GetServersOptions = {\n\t\t\t\tlimit?: number\n\t\t\t\toffset?: number\n\t\t\t}\n\n\t\t\texport type StockRequest = {\n\t\t\t\tcpu?: number\n\t\t\t\tmemory_mb?: number\n\t\t\t\tswap_mb?: number\n\t\t\t\tstorage_mb?: number\n\t\t\t}\n\n\t\t\texport type StockResponse = {\n\t\t\t\tavailable: number\n\t\t\t}\n\n\t\t\texport type JWTAuth = {\n\t\t\t\turl: string // e.g., \"node-xyz.modrinth.com/modrinth/v0/fs\"\n\t\t\t\ttoken: string // JWT token for filesystem access\n\t\t\t}\n\n\t\t\texport type ReinstallLoaderRequest = {\n\t\t\t\tloader: string\n\t\t\t\tloader_version?: string\n\t\t\t\tgame_version?: string\n\t\t\t}\n\n\t\t\texport type ReinstallModpackRequest = {\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id?: string\n\t\t\t}\n\n\t\t\texport type ReinstallRequest = ReinstallLoaderRequest | ReinstallModpackRequest\n\n\t\t\texport type MrpackReinstallAuth = {\n\t\t\t\turl: string\n\t\t\t\ttoken: string\n\t\t\t}\n\n\t\t\texport type Allocation = {\n\t\t\t\tport: number\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type StartupConfig = {\n\t\t\t\tinvocation: string\n\t\t\t\toriginal_invocation: string\n\t\t\t\tjdk_version: 'lts8' | 'lts11' | 'lts17' | 'lts21'\n\t\t\t\tjdk_build: 'corretto' | 'temurin' | 'graal'\n\t\t\t}\n\t\t}\n\n\t\texport namespace v1 {\n\t\t\texport type ServerFull = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tsubdomain: string\n\t\t\t\tspecs: ServerResources\n\t\t\t\tsftp_username: string\n\t\t\t\tsftp_password: string\n\t\t\t\ttags: string[]\n\t\t\t\tlocation: ServerLocation\n\t\t\t\tworlds: WorldFull[]\n\t\t\t}\n\n\t\t\texport type ServerResources = {\n\t\t\t\tcpu: number\n\t\t\t\tmemory_mb: number\n\t\t\t\tstorage_mb: number\n\t\t\t\tswap_mb: number\n\t\t\t}\n\n\t\t\texport type ServerLocation =\n\t\t\t\t| {\n\t\t\t\t\t\tstatus: 'assigned'\n\t\t\t\t\t\tlocation_metadata: {\n\t\t\t\t\t\t\tregion: string\n\t\t\t\t\t\t\tregion_should_be_user_displayed: boolean\n\t\t\t\t\t\t\thostname: string\n\t\t\t\t\t\t\tis_decommissioned_node: boolean\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tstatus: 'unassigned'\n\t\t\t\t }\n\n\t\t\texport type WorldFull = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tis_active: boolean\n\t\t\t\t/**\n\t\t\t\t * @deprecated Prefer `client.archon.backups_queue_v1.list()` for queue-aware backup state.\n\t\t\t\t */\n\t\t\t\tbackups: Archon.Backups.v1.Backup[]\n\t\t\t\tcontent: WorldContentInfo | null\n\t\t\t\treadiness: WorldReadiness\n\t\t\t}\n\n\t\t\texport type WorldReadiness = {\n\t\t\t\tdata_synchronized_fetched: boolean\n\t\t\t}\n\n\t\t\texport type WorldContentInfo = {\n\t\t\t\tmodloader: string\n\t\t\t\tmodloader_version: string\n\t\t\t\tgame_version: string\n\t\t\t\tjava_version: number | null\n\t\t\t\tinvocation: string | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t}\n\n\t\t\texport type Region = {\n\t\t\t\tshortcode: string\n\t\t\t\tcountry_code: string\n\t\t\t\tdisplay_name: string\n\t\t\t\tlat: number\n\t\t\t\tlon: number\n\t\t\t\tzone: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Backups {\n\t\t/**\n\t\t * @deprecated Use {@link Archon.BackupsQueue.v1} and `client.archon.backups_queue_v1` instead.\n\t\t */\n\t\texport namespace v1 {\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupState = 'ongoing' | 'done' | 'failed' | 'cancelled' | 'unchanged'\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupTask = 'file' | 'create' | 'restore'\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type BackupTaskProgress = {\n\t\t\t\tprogress: number // 0.0 to 1.0\n\t\t\t\tstate: BackupState\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupQueueBackup} instead. */\n\t\t\texport type Backup = {\n\t\t\t\tid: string\n\t\t\t\tphysical_id: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tautomated: boolean\n\t\t\t\tstatus: BackupStatus\n\t\t\t\tinterrupted: boolean\n\t\t\t\tongoing: boolean\n\t\t\t\tlocked: boolean\n\t\t\t\ttask?: {\n\t\t\t\t\tfile?: BackupTaskProgress\n\t\t\t\t\tcreate?: BackupTaskProgress\n\t\t\t\t\trestore?: BackupTaskProgress\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.BackupRequest} instead. */\n\t\t\texport type BackupRequest = {\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1} instead. */\n\t\t\texport type PatchBackup = {\n\t\t\t\tname?: string\n\t\t\t}\n\n\t\t\t/** @deprecated Use {@link Archon.BackupsQueue.v1.PostBackupQueueResponse} instead. */\n\t\t\texport type PostBackupResponse = {\n\t\t\t\tid: string\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace BackupsQueue {\n\t\texport namespace v1 {\n\t\t\texport type BackupQueueOperationType = 'create' | 'restore'\n\n\t\t\texport type BackupQueueState =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'completed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'failed'\n\t\t\t\t| 'timed_out'\n\n\t\t\texport type BackupStatus = 'pending' | 'in_progress' | 'timed_out' | 'error' | 'done'\n\n\t\t\texport type BackupRequest = {\n\t\t\t\tname: string\n\t\t\t}\n\n\t\t\texport type PostBackupQueueResponse = {\n\t\t\t\tid: string\n\t\t\t}\n\n\t\t\texport type UserInfo = {\n\t\t\t\tid: string\n\t\t\t\tusername: string\n\t\t\t\tavatar_url: string | null\n\t\t\t}\n\n\t\t\texport type DeleteManyBackupRequest = {\n\t\t\t\tbackup_ids: string[]\n\t\t\t}\n\n\t\t\texport type ActiveOperation = {\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_type: BackupQueueOperationType\n\t\t\t\toperation_id: number | null\n\t\t\t\thas_parent: boolean\n\t\t\t\tscheduled_for: string\n\t\t\t\tstarted_at: string | null\n\t\t\t\tsynthetic_legacy: boolean\n\t\t\t\tuser_info: UserInfo | null\n\t\t\t}\n\n\t\t\texport type BackupQueueOperation = {\n\t\t\t\toperation_type: BackupQueueOperationType\n\t\t\t\toperation_id: number | null\n\t\t\t\tstate: BackupQueueState\n\t\t\t\tscheduled_for: string\n\t\t\t\tstarted_at: string | null\n\t\t\t\tcompleted_at: string | null\n\t\t\t\thas_parent: boolean\n\t\t\t\terror: string | null\n\t\t\t\tshould_prompt: boolean\n\t\t\t\tsynthetic_legacy: boolean\n\t\t\t\tuser_info: UserInfo | null\n\t\t\t}\n\n\t\t\texport type BackupQueueBackup = {\n\t\t\t\tid: string\n\t\t\t\tname: string\n\t\t\t\tcreated_at: string\n\t\t\t\tstatus: BackupStatus\n\t\t\t\tlocked: boolean\n\t\t\t\tautomated: boolean\n\t\t\t\thistory: BackupQueueOperation[]\n\t\t\t}\n\n\t\t\texport type BackupsQueueResponse = {\n\t\t\t\tactive_operations: ActiveOperation[]\n\t\t\t\tbackups: BackupQueueBackup[]\n\t\t\t}\n\t\t}\n\t}\n\n\texport namespace Sync {\n\t\texport namespace v1 {\n\t\t\texport type SyncCategory = 'backup' | 'users' | 'server' | 'protocol' | 'world'\n\t\t\texport type SyncIntent = 'all' | SyncCategory | SyncCategory[]\n\t\t\texport type BackupOperationStatus = 'completed' | 'cancelled' | 'failed' | 'timed-out'\n\t\t\texport type ServerNetworkPort = { port: number; name: string }\n\n\t\t\texport type ProtocolResetEvent = { type: 'protocol.reset' }\n\t\t\texport type ProtocolInvalidEvent = { type: 'protocol.invalid' }\n\t\t\texport type ProtocolErrorEvent = { type: 'protocol.error'; error: string }\n\n\t\t\texport type BackupNewEvent = { type: 'backup.new'; id: string }\n\t\t\texport type BackupPatchEvent = {\n\t\t\t\ttype: 'backup.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\tname: string\n\t\t\t}\n\t\t\texport type BackupDeleteEvent = {\n\t\t\t\ttype: 'backup.delete'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t}\n\t\t\texport type BackupOperationStartEvent = {\n\t\t\t\ttype:\n\t\t\t\t\t| 'backup.operation.create.init'\n\t\t\t\t\t| 'backup.operation.create.start'\n\t\t\t\t\t| 'backup.operation.restore.init'\n\t\t\t\t\t| 'backup.operation.restore.start'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_id: number\n\t\t\t}\n\t\t\texport type BackupOperationDoneEvent = {\n\t\t\t\ttype: 'backup.operation.create.done' | 'backup.operation.restore.done'\n\t\t\t\tworld_id: string\n\t\t\t\tbackup_id: string\n\t\t\t\toperation_id: number\n\t\t\t\tstatus: BackupOperationStatus\n\t\t\t}\n\n\t\t\texport type ServerPatchEvent = {\n\t\t\t\ttype: 'server.patch'\n\t\t\t\tname: string\n\t\t\t\tsubdomain: string\n\t\t\t}\n\t\t\texport type ServerNetworkPatchEvent = {\n\t\t\t\ttype: 'server.network.patch'\n\t\t\t\tports: ServerNetworkPort[]\n\t\t\t}\n\t\t\texport type ServerTransferEvent = {\n\t\t\t\ttype: 'server.transfer.start' | 'server.transfer.done'\n\t\t\t\ttarget_node: string\n\t\t\t}\n\n\t\t\texport type UsersPatchEvent = { type: 'users.patch' }\n\n\t\t\texport type WorldPatchEvent = {\n\t\t\t\ttype: 'world.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tname: string\n\t\t\t}\n\t\t\texport type WorldStartupPatchEvent = {\n\t\t\t\ttype: 'world.startup.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tjava_version: number | null\n\t\t\t\tinvocation: string | null\n\t\t\t\toriginal_invocation: string | null\n\t\t\t}\n\t\t\texport type WorldContentAddonPatchEvent = {\n\t\t\t\ttype: 'world.content.addon.patch'\n\t\t\t\tworld_id: string\n\t\t\t\tspecs: Archon.Content.v1.Addon[]\n\t\t\t}\n\t\t\texport type WorldContentBaseUpdateEvent = {\n\t\t\t\ttype: 'world.content.base.update'\n\t\t\t\tworld_id: string\n\t\t\t\tspec: Archon.Content.v1.Addons\n\t\t\t}\n\t\t\texport type WorldContentPlatform =\n\t\t\t\t| 'forge'\n\t\t\t\t| 'neoforge'\n\t\t\t\t| 'fabric'\n\t\t\t\t| 'quilt'\n\t\t\t\t| 'paper'\n\t\t\t\t| 'purpur'\n\t\t\t\t| 'vanilla'\n\t\t\texport type WorldContentPlatformData = {\n\t\t\t\tplatform: WorldContentPlatform\n\t\t\t\tgame_version: string\n\t\t\t\tplatform_version: string | null\n\t\t\t}\n\t\t\texport type WorldContentModpackSource =\n\t\t\t\t| 'CurseForge'\n\t\t\t\t| {\n\t\t\t\t\t\tModrinth: {\n\t\t\t\t\t\t\tversion_id: string\n\t\t\t\t\t\t\tproject_id: string\n\t\t\t\t\t\t\tmrpack_sha1: string | null\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\t\t| {\n\t\t\t\t\t\tLocalMrPackFile: {\n\t\t\t\t\t\t\tpath: string\n\t\t\t\t\t\t\tname: string\n\t\t\t\t\t\t\tdescription: string | null\n\t\t\t\t\t\t\tversion_name: string | null\n\t\t\t\t\t\t}\n\t\t\t\t }\n\t\t\texport type WorldContentModpack = {\n\t\t\t\tspec: WorldContentModpackSource\n\t\t\t\tdownloads: number | null\n\t\t\t\tfollowers: number | null\n\t\t\t\ticon_url: string | null\n\t\t\t\towner: Archon.Content.v1.ContentOwner | null\n\t\t\t\ttitle: string | null\n\t\t\t\tdescription: string | null\n\t\t\t\tversion_number: string | null\n\t\t\t\tdate_published: string | null\n\t\t\t\tenvironment: Labrinth.Projects.v3.Environment | null\n\t\t\t\thas_update: string | null\n\t\t\t}\n\t\t\texport type WorldContentItem = {\n\t\t\t\tparent_directory: string\n\t\t\t\tfile_sha1: string | null\n\t\t\t\tfilename: string\n\t\t\t\tbtime?: string\n\t\t\t\tfrom_modpack: boolean\n\t\t\t\tversion_id: string | null\n\t\t\t\tproject_id: string | null\n\t\t\t\tpack_client_retained: boolean\n\t\t\t\tpack_client_depends: boolean\n\t\t\t\tstatus: Archon.Content.v1.AddonStatus\n\t\t\t\tfilesize: number | null\n\t\t\t\tname: string | null\n\t\t\t\tversion: Archon.Content.v1.AddonVersion | null\n\t\t\t\towner: Archon.Content.v1.ContentOwner | null\n\t\t\t\thas_update: string | null\n\t\t\t\ticon_url: string | null\n\t\t\t}\n\t\t\texport type WorldContentUpdateEvent = {\n\t\t\t\ttype: 'world.content.update'\n\t\t\t\tworld_id: string\n\t\t\t\tplatform_data: WorldContentPlatformData | null\n\t\t\t\tlinked_modpack: WorldContentModpack | null\n\t\t\t\tinstalling?: 'loader' | 'modpack'\n\t\t\t\terror?: {\n\t\t\t\t\tmessage: string\n\t\t\t\t}\n\t\t\t\tcontent: WorldContentItem[]\n\t\t\t}\n\n\t\t\texport type SyncEvent =\n\t\t\t\t| ProtocolResetEvent\n\t\t\t\t| ProtocolInvalidEvent\n\t\t\t\t| ProtocolErrorEvent\n\t\t\t\t| BackupNewEvent\n\t\t\t\t| BackupPatchEvent\n\t\t\t\t| BackupDeleteEvent\n\t\t\t\t| BackupOperationStartEvent\n\t\t\t\t| BackupOperationDoneEvent\n\t\t\t\t| ServerPatchEvent\n\t\t\t\t| ServerNetworkPatchEvent\n\t\t\t\t| ServerTransferEvent\n\t\t\t\t| UsersPatchEvent\n\t\t\t\t| WorldPatchEvent\n\t\t\t\t| WorldStartupPatchEvent\n\t\t\t\t| WorldContentAddonPatchEvent\n\t\t\t\t| WorldContentBaseUpdateEvent\n\t\t\t\t| WorldContentUpdateEvent\n\t\t}\n\t}\n\n\texport namespace Websocket {\n\t\texport namespace v0 {\n\t\t\texport type WSAuth = {\n\t\t\t\turl: string\n\t\t\t\ttoken: string\n\t\t\t}\n\n\t\t\texport type BackupState =\n\t\t\t\t| 'pending'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'done'\n\t\t\t\t| 'failed'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'unchanged'\n\t\t\t\t| 'damaged'\n\t\t\texport type BackupTask = 'file' | 'create' | 'restore'\n\n\t\t\texport type WSBackupProgressEvent = {\n\t\t\t\tevent: 'backup-progress'\n\t\t\t\tid: string\n\t\t\t\ttask: BackupTask\n\t\t\t\tstate: BackupState\n\t\t\t\tprogress: number\n\t\t\t\tstart_time?: number | null\n\t\t\t\tfinish_time?: number | null\n\t\t\t}\n\n\t\t\texport type WSLogEvent = {\n\t\t\t\tevent: 'log'\n\t\t\t\tstream: 'stdout' | 'stderr'\n\t\t\t\tmessage: string\n\t\t\t}\n\n\t\t\texport type WSLog4jEvent = {\n\t\t\t\tevent: 'log4j'\n\t\t\t\tlogger_name?: string\n\t\t\t\tlevel?: string\n\t\t\t\tthread_name?: string\n\t\t\t\ttimestamp_millis?: number\n\t\t\t\tmessage?: string\n\t\t\t\tthrowable?: string\n\t\t\t}\n\n\t\t\texport type WSStatsEvent = {\n\t\t\t\tevent: 'stats'\n\t\t\t\tcpu_percent: number\n\t\t\t\tram_usage_bytes: number\n\t\t\t\tram_total_bytes: number\n\t\t\t\tstorage_usage_bytes: number\n\t\t\t\tstorage_total_bytes: number\n\t\t\t\tnet_tx_bytes: number\n\t\t\t\tnet_rx_bytes: number\n\t\t\t}\n\n\t\t\texport type PowerState = 'running' | 'stopped' | 'starting' | 'stopping' | 'crashed'\n\n\t\t\texport type WSPowerStateEvent = {\n\t\t\t\tevent: 'power-state'\n\t\t\t\tstate: PowerState\n\t\t\t\toom_killed?: boolean\n\t\t\t\texit_code?: number\n\t\t\t}\n\n\t\t\texport type WSAuthExpiringEvent = {\n\t\t\t\tevent: 'auth-expiring'\n\t\t\t}\n\n\t\t\texport type WSAuthIncorrectEvent = {\n\t\t\t\tevent: 'auth-incorrect'\n\t\t\t}\n\n\t\t\texport type WSAuthOkEvent = {\n\t\t\t\tevent: 'auth-ok'\n\t\t\t}\n\n\t\t\texport type WSInstallationResultEvent =\n\t\t\t\t| WSInstallationResultOkEvent\n\t\t\t\t| WSInstallationResultErrEvent\n\n\t\t\texport type WSInstallationResultOkEvent = {\n\t\t\t\tevent: 'installation-result'\n\t\t\t\tresult: 'ok'\n\t\t\t}\n\n\t\t\texport type WSInstallationResultErrEvent = {\n\t\t\t\tevent: 'installation-result'\n\t\t\t\tresult: 'err'\n\t\t\t\treason?: string\n\t\t\t}\n\n\t\t\texport type WSUptimeEvent = {\n\t\t\t\tevent: 'uptime'\n\t\t\t\tuptime: number\n\t\t\t}\n\n\t\t\texport type WSNewModEvent = {\n\t\t\t\tevent: 'new-mod'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type InstallProgressFileKey = {\n\t\t\t\ttype: 'file'\n\t\t\t\tinstall_type: 'install' | 'update'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t\tparent_directory: string\n\t\t\t\tsource_filename: string | null\n\t\t\t\ttarget_filename?: string | null\n\t\t\t}\n\n\t\t\texport type InstallProgressModrinthModpackKey = {\n\t\t\t\ttype: 'modrinth_modpack'\n\t\t\t\tproject_id: string\n\t\t\t\tversion_id: string\n\t\t\t}\n\n\t\t\texport type InstallProgressLocalModpackKey = {\n\t\t\t\ttype: 'local_modpack'\n\t\t\t\tfilename: string\n\t\t\t}\n\n\t\t\texport type InstallProgressPlatformKey = {\n\t\t\t\ttype: 'platform'\n\t\t\t\tplatform: 'forge' | 'neoforge' | 'fabric' | 'quilt' | 'paper' | 'purpur' | 'vanilla'\n\t\t\t\tplatform_version: string\n\t\t\t\tgame_version: string\n\t\t\t}\n\n\t\t\texport type InstallProgressKey =\n\t\t\t\t| InstallProgressFileKey\n\t\t\t\t| InstallProgressModrinthModpackKey\n\t\t\t\t| InstallProgressLocalModpackKey\n\t\t\t\t| InstallProgressPlatformKey\n\n\t\t\texport type InstallProgressItem = {\n\t\t\t\tworld_id: string\n\t\t\t\tkey: InstallProgressKey\n\t\t\t\tid: string\n\t\t\t\tprogress: number | null\n\t\t\t\terror: string | null\n\t\t\t}\n\n\t\t\texport type WSInstallProgressEvent = {\n\t\t\t\tevent: 'install-progress'\n\t\t\t\titems: InstallProgressItem[]\n\t\t\t}\n\n\t\t\texport type FilesystemOpKind = 'unarchive'\n\n\t\t\texport type FilesystemOpState =\n\t\t\t\t| 'queued'\n\t\t\t\t| 'ongoing'\n\t\t\t\t| 'done'\n\t\t\t\t| 'cancelled'\n\t\t\t\t| 'failure-corrupted'\n\t\t\t\t| 'failure-invalid-path'\n\n\t\t\texport type FilesystemOperation = {\n\t\t\t\top: FilesystemOpKind\n\t\t\t\tid: string\n\t\t\t\tprogress: number\n\t\t\t\tbytes_processed: number\n\t\t\t\tfiles_processed: number\n\t\t\t\tstate: FilesystemOpState\n\t\t\t\tmime: string\n\t\t\t\tcurrent_file?: string\n\t\t\t\tinvalid_path?: string\n\t\t\t\tsrc: string\n\t\t\t\tstarted: string\n\t\t\t}\n\n\t\t\texport type QueuedFilesystemOp = {\n\t\t\t\top: FilesystemOpKind\n\t\t\t\tsrc: string\n\t\t\t}\n\n\t\t\texport type WSFilesystemOpsEvent = {\n\t\t\t\tevent: 'filesystem-ops'\n\t\t\t\tall: FilesystemOperation[]\n\t\t\t}\n\n\t\t\texport type ReadinessState =\n\t\t\t\t| 'deprovisioned'\n\t\t\t\t| 'waiting_active_world'\n\t\t\t\t| 'waiting_world_spec_details_for_progress'\n\t\t\t\t| 'pulling_world_data'\n\t\t\t\t| 'migration_zfs'\n\t\t\t\t| 'sync_content'\n\t\t\t\t| 'container_readying'\n\t\t\t\t| 'ready'\n\n\t\t\texport type FlattenedPowerState = 'not_ready' | 'starting' | 'running' | 'stopping' | 'idle'\n\n\t\t\texport type SyncInstallPhase = 'Analyzing' | 'InstallingPack' | 'InstallingLoader' | 'Addons'\n\n\t\t\texport type SyncContentProgress = {\n\t\t\t\tstarted_at: string\n\t\t\t\tphase: SyncInstallPhase\n\t\t\t\tpercent: number\n\t\t\t}\n\n\t\t\texport type SyncContentError = {\n\t\t\t\tstep: string\n\t\t\t\tdescription: string\n\t\t\t}\n\n\t\t\texport type WSStateEvent = {\n\t\t\t\tevent: 'state'\n\t\t\t\tdebug: string\n\t\t\t\tpower_variant: FlattenedPowerState\n\t\t\t\texit_code?: number | null\n\t\t\t\twas_oom?: boolean\n\t\t\t\ttarget: 'start' | 'stop' | 'restart' | null\n\t\t\t\tuptime: number\n\t\t\t\tprogress: SyncContentProgress | null\n\t\t\t\tcontent_error: SyncContentError | null\n\t\t\t}\n\n\t\t\t// Outgoing messages (client -> server)\n\t\t\texport type WSOutgoingMessage = WSAuthMessage | WSCommandMessage\n\n\t\t\texport type WSAuthMessage = {\n\t\t\t\tevent: 'auth'\n\t\t\t\tjwt: string\n\t\t\t}\n\n\t\t\texport type WSCommandMessage = {\n\t\t\t\tevent: 'command'\n\t\t\t\tcmd: string\n\t\t\t}\n\n\t\t\texport type WSEvent =\n\t\t\t\t| WSBackupProgressEvent\n\t\t\t\t| WSLogEvent\n\t\t\t\t| WSLog4jEvent\n\t\t\t\t| WSStatsEvent\n\t\t\t\t| WSPowerStateEvent\n\t\t\t\t| WSStateEvent\n\t\t\t\t| WSAuthExpiringEvent\n\t\t\t\t| WSAuthIncorrectEvent\n\t\t\t\t| WSAuthOkEvent\n\t\t\t\t| WSInstallationResultEvent\n\t\t\t\t| WSUptimeEvent\n\t\t\t\t| WSNewModEvent\n\t\t\t\t| WSInstallProgressEvent\n\t\t\t\t| WSFilesystemOpsEvent\n\n\t\t\texport type WSEventType = WSEvent['event']\n\t\t}\n\t}\n}\n", "import { $fetch, FetchError } from 'ofetch'\n\nimport { ModrinthApiError } from '../core/errors'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Generic platform client using ofetch\n *\n * This client works in any JavaScript environment (Node.js, browser, workers, etc).\n *\n * @example\n * ```typescript\n * const client = new GenericModrinthClient({\n * userAgent: 'my-app/1.0.0',\n * features: [\n * new AuthFeature({ token: async () => getOAuthToken() }),\n * new RetryFeature({ maxAttempts: 3 })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class GenericModrinthClient extends XHRUploadClient {\n\tconstructor(config: ClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\tconst response = await $fetch<T>(url, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: options.body as BodyInit,\n\t\t\t\tparams: options.params as Record<string, string>,\n\t\t\t\ttimeout: options.timeout,\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\treturn response\n\t\t} catch (error) {\n\t\t\t// ofetch throws FetchError for HTTP errors\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst response = await fetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new ModrinthApiError('Streaming response has no readable body', {\n\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof FetchError) {\n\t\t\treturn this.createNormalizedError(error, error.response?.status, error.data)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n}\n", "import type { RequestOptions } from '../types/request'\n\nexport function appendRequestParams(url: string, params?: RequestOptions['params']): string {\n\tif (!params) return url\n\n\tconst filteredParams: Record<string, string> = {}\n\tfor (const [key, value] of Object.entries(params)) {\n\t\tif (value !== undefined && value !== null) {\n\t\t\tfilteredParams[key] = String(value)\n\t\t}\n\t}\n\n\tconst queryString = new URLSearchParams(filteredParams).toString()\n\tif (!queryString) return url\n\n\treturn `${url}${url.includes('?') ? '&' : '?'}${queryString}`\n}\n\nexport function toFetchBody(body: unknown): BodyInit | null | undefined {\n\tif (!body) return undefined\n\n\tif (\n\t\ttypeof body === 'object' &&\n\t\t!(body instanceof FormData) &&\n\t\t!(body instanceof URLSearchParams) &&\n\t\t!(body instanceof Blob) &&\n\t\t!(body instanceof ArrayBuffer) &&\n\t\t!ArrayBuffer.isView(body as ArrayBufferView)\n\t) {\n\t\treturn JSON.stringify(body)\n\t}\n\n\treturn body as BodyInit\n}\n\nexport async function parseResponseErrorData(response: Response): Promise<unknown> {\n\tconst contentType = response.headers.get('content-type')?.toLowerCase() ?? ''\n\n\ttry {\n\t\tif (contentType.includes('application/json') || contentType.includes('+json')) {\n\t\t\treturn await response.json()\n\t\t}\n\n\t\tconst text = await response.text()\n\t\tif (!text) return undefined\n\n\t\ttry {\n\t\t\treturn JSON.parse(text)\n\t\t} catch {\n\t\t\treturn text\n\t\t}\n\t} catch {\n\t\treturn undefined\n\t}\n}\n", "import mitt from 'mitt'\n\nimport {\n\tAbstractSyncClient,\n\ttype SyncConnection,\n\ttype SyncConnectOptions,\n\ttype SyncEmitterEvents,\n} from '../core/abstract-sync'\nimport type { Archon } from '../modules/archon/types'\nimport { type ParsedSseItem, parseSyncEventData, SseParser } from '../utils/sse'\n\ntype StreamReadResult = 'closed' | 'protocol-reconnect'\n\nconst DEFAULT_RETRY_DELAY = 1000\nconst MAX_RECONNECT_DELAY = 30000\nconst JITTER_MS = 1000\n\nexport class GenericSyncClient extends AbstractSyncClient {\n\tprotected emitter = mitt<SyncEmitterEvents>()\n\n\tasync safeConnectServer(serverId: string, options: SyncConnectOptions = {}): Promise<void> {\n\t\tconst existing = this.connections.get(serverId)\n\t\tif (existing && !options.force && !existing.stopped && existing.status !== 'disconnected') {\n\t\t\treturn\n\t\t}\n\n\t\tif (existing) {\n\t\t\tthis.closeConnection(serverId)\n\t\t}\n\n\t\tconst connection: SyncConnection = {\n\t\t\tserverId,\n\t\t\tintent: options.intent ?? 'all',\n\t\t\treconnectAttempts: 0,\n\t\t\tretryDelay: DEFAULT_RETRY_DELAY,\n\t\t\tstopped: false,\n\t\t\tstatus: 'idle',\n\t\t}\n\n\t\tthis.connections.set(serverId, connection)\n\t\tvoid this.runConnection(connection)\n\t}\n\n\tdisconnect(serverId: string): void {\n\t\tthis.closeConnection(serverId)\n\t\tthis.clearListeners(serverId)\n\t}\n\n\tdisconnectAll(): void {\n\t\tfor (const serverId of this.connections.keys()) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n\n\tprivate async runConnection(connection: SyncConnection): Promise<void> {\n\t\twhile (!connection.stopped) {\n\t\t\tconst hadConnected = connection.status === 'connected'\n\t\t\tthis.updateStatus(connection, hadConnected ? 'reconnecting' : 'connecting')\n\n\t\t\tconst controller = new AbortController()\n\t\t\tconnection.controller = controller\n\n\t\t\ttry {\n\t\t\t\tconst stream = await this.client.stream('/sync', {\n\t\t\t\t\tapi: 'archon',\n\t\t\t\t\tversion: 1,\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\tparams: {\n\t\t\t\t\t\tscope: `server:${connection.serverId}`,\n\t\t\t\t\t\tintent: this.intentToParam(connection.intent),\n\t\t\t\t\t},\n\t\t\t\t\theaders: connection.lastEventId\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t'Last-Event-Id': connection.lastEventId,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined,\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\tretry: false,\n\t\t\t\t\tcircuitBreaker: false,\n\t\t\t\t})\n\n\t\t\t\tif (connection.stopped) return\n\n\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\tthis.updateStatus(connection, 'connected')\n\n\t\t\t\tconst result = await this.consumeStream(connection, stream)\n\t\t\t\tconnection.controller = undefined\n\t\t\t\tif (connection.stopped) return\n\n\t\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\n\t\t\t\tawait this.waitForReconnect(connection)\n\t\t\t} catch (error) {\n\t\t\t\tconnection.controller = undefined\n\t\t\t\tif (connection.stopped || this.isAbortError(error)) return\n\n\t\t\t\tconnection.reconnectAttempts++\n\t\t\t\tthis.updateStatus(connection, 'error', error)\n\t\t\t\tconsole.warn(`[Sync] Connection failed for server ${connection.serverId}:`, error)\n\t\t\t\tawait this.waitForReconnect(connection)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async consumeStream(\n\t\tconnection: SyncConnection,\n\t\tstream: ReadableStream<Uint8Array>,\n\t): Promise<StreamReadResult> {\n\t\tconst reader = stream.getReader()\n\t\tconst decoder = new TextDecoder()\n\t\tconst parser = new SseParser()\n\n\t\ttry {\n\t\t\twhile (!connection.stopped) {\n\t\t\t\tconst { done, value } = await reader.read()\n\t\t\t\tif (done) break\n\n\t\t\t\tconst chunk = decoder.decode(value, { stream: true })\n\t\t\t\tconst result = this.processParsedItems(connection, parser.feed(chunk))\n\t\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\t\tawait reader.cancel()\n\t\t\t\t\tconnection.controller?.abort()\n\t\t\t\t\treturn result\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst finalChunk = decoder.decode()\n\t\t\tconst finalItems = finalChunk ? parser.feed(finalChunk) : []\n\t\t\tconst result = this.processParsedItems(connection, [...finalItems, ...parser.end()])\n\t\t\tif (result === 'protocol-reconnect') {\n\t\t\t\tawait reader.cancel()\n\t\t\t\tconnection.controller?.abort()\n\t\t\t\treturn result\n\t\t\t}\n\t\t} finally {\n\t\t\treader.releaseLock()\n\t\t}\n\n\t\treturn 'closed'\n\t}\n\n\tprivate processParsedItems(connection: SyncConnection, items: ParsedSseItem[]): StreamReadResult {\n\t\tfor (const item of items) {\n\t\t\tif (item.kind === 'retry') {\n\t\t\t\tconnection.retryDelay = Math.min(item.retry, MAX_RECONNECT_DELAY)\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.updateLastEventId(connection, item.id)\n\n\t\t\tconst event = parseSyncEventData(item.data)\n\t\t\tif (!event) {\n\t\t\t\tconsole.warn('[Sync] Dropping malformed SSE payload:', {\n\t\t\t\t\tserverId: connection.serverId,\n\t\t\t\t\tevent: item.event,\n\t\t\t\t\tdata: item.data,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tthis.emitSyncEvent(connection.serverId, event)\n\n\t\t\tif (event.type === 'protocol.reset' || event.type === 'protocol.invalid') {\n\t\t\t\tconnection.lastEventId = undefined\n\t\t\t\treturn 'protocol-reconnect'\n\t\t\t}\n\t\t}\n\n\t\treturn 'closed'\n\t}\n\n\tprivate async waitForReconnect(connection: SyncConnection): Promise<void> {\n\t\tif (connection.stopped) return\n\n\t\tthis.updateStatus(connection, 'reconnecting')\n\t\tconst delay = this.getReconnectDelay(connection)\n\n\t\tawait new Promise<void>((resolve) => {\n\t\t\tconnection.reconnectResolve = resolve\n\t\t\tconnection.reconnectTimer = setTimeout(() => {\n\t\t\t\tconnection.reconnectTimer = undefined\n\t\t\t\tconnection.reconnectResolve = undefined\n\t\t\t\tresolve()\n\t\t\t}, delay)\n\t\t})\n\t}\n\n\tprivate closeConnection(serverId: string): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tconnection.stopped = true\n\t\tconnection.controller?.abort()\n\n\t\tif (connection.reconnectTimer) {\n\t\t\tclearTimeout(connection.reconnectTimer)\n\t\t\tconnection.reconnectTimer = undefined\n\t\t}\n\t\tconnection.reconnectResolve?.()\n\t\tconnection.reconnectResolve = undefined\n\n\t\tthis.updateStatus(connection, 'disconnected')\n\t\tthis.connections.delete(serverId)\n\t}\n\n\tprivate getReconnectDelay(connection: SyncConnection): number {\n\t\tconst exponentialDelay =\n\t\t\tconnection.retryDelay * Math.pow(2, Math.max(connection.reconnectAttempts - 1, 0))\n\t\treturn Math.min(exponentialDelay, MAX_RECONNECT_DELAY) + Math.random() * JITTER_MS\n\t}\n\n\tprivate updateLastEventId(connection: SyncConnection, id: string | undefined): void {\n\t\tif (id === undefined) return\n\t\tconnection.lastEventId = id || undefined\n\t}\n\n\tprivate intentToParam(intent: Archon.Sync.v1.SyncIntent): string {\n\t\treturn Array.isArray(intent) ? intent.join(',') : intent\n\t}\n\n\tprivate isAbortError(error: unknown): boolean {\n\t\tif (!(error instanceof Error)) return false\n\t\treturn error.name === 'AbortError' || error.message.toLowerCase().includes('abort')\n\t}\n}\n", "import type { Archon } from '../modules/archon/types'\n\nexport type ParsedSseEvent = {\n\tkind: 'event'\n\tid?: string\n\tevent?: string\n\tdata: string\n}\n\nexport type ParsedSseRetry = {\n\tkind: 'retry'\n\tretry: number\n}\n\nexport type ParsedSseItem = ParsedSseEvent | ParsedSseRetry\n\nexport class SseParser {\n\tprivate buffer = ''\n\tprivate eventName = ''\n\tprivate data = ''\n\tprivate id: string | undefined\n\n\tfeed(chunk: string): ParsedSseItem[] {\n\t\tthis.buffer += chunk\n\t\tconst items: ParsedSseItem[] = []\n\n\t\twhile (true) {\n\t\t\tconst lineEnd = this.findLineEnd()\n\t\t\tif (!lineEnd) break\n\n\t\t\tconst { line, length } = lineEnd\n\t\t\tthis.buffer = this.buffer.slice(length)\n\t\t\tthis.processLine(line, items)\n\t\t}\n\n\t\treturn items\n\t}\n\n\tend(): ParsedSseItem[] {\n\t\tconst items: ParsedSseItem[] = []\n\n\t\tif (this.buffer.length > 0) {\n\t\t\tthis.processLine(this.buffer.endsWith('\\r') ? this.buffer.slice(0, -1) : this.buffer, items)\n\t\t\tthis.buffer = ''\n\t\t}\n\n\t\tthis.dispatch(items)\n\t\treturn items\n\t}\n\n\tprivate findLineEnd(): { line: string; length: number } | null {\n\t\tconst lf = this.buffer.indexOf('\\n')\n\t\tconst cr = this.buffer.indexOf('\\r')\n\n\t\tif (lf === -1 && cr === -1) return null\n\n\t\tif (cr !== -1 && (lf === -1 || cr < lf)) {\n\t\t\tif (cr === this.buffer.length - 1) return null\n\t\t\tconst length = this.buffer[cr + 1] === '\\n' ? cr + 2 : cr + 1\n\t\t\treturn {\n\t\t\t\tline: this.buffer.slice(0, cr),\n\t\t\t\tlength,\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tline: this.buffer.slice(0, lf),\n\t\t\tlength: lf + 1,\n\t\t}\n\t}\n\n\tprivate processLine(line: string, items: ParsedSseItem[]): void {\n\t\tif (line === '') {\n\t\t\tthis.dispatch(items)\n\t\t\treturn\n\t\t}\n\n\t\tif (line.startsWith(':')) return\n\n\t\tconst colon = line.indexOf(':')\n\t\tconst field = colon === -1 ? line : line.slice(0, colon)\n\t\tlet value = colon === -1 ? '' : line.slice(colon + 1)\n\t\tif (value.startsWith(' ')) value = value.slice(1)\n\n\t\tswitch (field) {\n\t\t\tcase 'event':\n\t\t\t\tthis.eventName = value\n\t\t\t\tbreak\n\t\t\tcase 'data':\n\t\t\t\tthis.data += `${value}\\n`\n\t\t\t\tbreak\n\t\t\tcase 'id':\n\t\t\t\tthis.id = value\n\t\t\t\tbreak\n\t\t\tcase 'retry': {\n\t\t\t\tconst retry = Number(value)\n\t\t\t\tif (Number.isInteger(retry) && retry >= 0) {\n\t\t\t\t\titems.push({ kind: 'retry', retry })\n\t\t\t\t}\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate dispatch(items: ParsedSseItem[]): void {\n\t\tif (!this.data) {\n\t\t\tthis.eventName = ''\n\t\t\tthis.id = undefined\n\t\t\treturn\n\t\t}\n\n\t\titems.push({\n\t\t\tkind: 'event',\n\t\t\tid: this.id,\n\t\t\tevent: this.eventName || undefined,\n\t\t\tdata: this.data.endsWith('\\n') ? this.data.slice(0, -1) : this.data,\n\t\t})\n\n\t\tthis.eventName = ''\n\t\tthis.data = ''\n\t\tthis.id = undefined\n\t}\n}\n\nexport function parseSyncEventData(data: string): Archon.Sync.v1.SyncEvent | null {\n\tlet parsed: unknown\n\n\ttry {\n\t\tparsed = JSON.parse(data)\n\t} catch {\n\t\treturn null\n\t}\n\n\tif (!parsed || typeof parsed !== 'object') return null\n\tconst event = parsed as { type?: unknown }\n\tif (typeof event.type !== 'string') return null\n\n\treturn parsed as Archon.Sync.v1.SyncEvent\n}\n", "import mitt from 'mitt'\n\nimport { AbstractWebSocketClient, type WebSocketConnection } from '../core/abstract-websocket'\nimport type { Archon } from '../modules/archon/types'\nimport { getNodeWebSocketUrl } from '../utils/node-url'\n\ntype WSEventMap = {\n\t[K in Archon.Websocket.v0.WSEvent as `${string}:${K['event']}`]: K\n}\n\nconst NORMAL_CLOSURE = 1000\n\nexport class GenericWebSocketClient extends AbstractWebSocketClient {\n\tprotected emitter = mitt<WSEventMap>()\n\n\tasync connect(serverId: string, auth: Archon.Websocket.v0.WSAuth): Promise<void> {\n\t\tif (this.connections.has(serverId)) {\n\t\t\tthis.closeConnection(serverId)\n\t\t}\n\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tlet settled = false\n\t\t\tlet authenticationTimeout: ReturnType<typeof setTimeout> | null = null\n\t\t\tconst resolveConnection = () => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tif (authenticationTimeout) clearTimeout(authenticationTimeout)\n\t\t\t\tresolve()\n\t\t\t}\n\t\t\tconst rejectConnection = (error: unknown) => {\n\t\t\t\tif (settled) return\n\t\t\t\tsettled = true\n\t\t\t\tif (authenticationTimeout) clearTimeout(authenticationTimeout)\n\t\t\t\treject(error)\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst ws = new WebSocket(getNodeWebSocketUrl(auth.url))\n\n\t\t\t\tconst connection: WebSocketConnection = {\n\t\t\t\t\tserverId,\n\t\t\t\t\tsocket: ws,\n\t\t\t\t\tauthenticated: false,\n\t\t\t\t\treconnectAttempts: 0,\n\t\t\t\t\treconnectTimer: undefined,\n\t\t\t\t\tisReconnecting: false,\n\t\t\t\t}\n\n\t\t\t\tthis.connections.set(serverId, connection)\n\t\t\t\tauthenticationTimeout = setTimeout(() => {\n\t\t\t\t\trejectConnection(new Error(`WebSocket authentication timed out for server ${serverId}`))\n\t\t\t\t\tif (this.connections.get(serverId) === connection) this.closeConnection(serverId)\n\t\t\t\t}, this.AUTHENTICATION_TIMEOUT)\n\n\t\t\t\tws.onopen = () => {\n\t\t\t\t\tws.send(JSON.stringify({ event: 'auth', jwt: auth.token }))\n\n\t\t\t\t\tconnection.reconnectAttempts = 0\n\t\t\t\t\tconnection.isReconnecting = false\n\t\t\t\t}\n\n\t\t\t\tws.onmessage = (messageEvent) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst data = JSON.parse(messageEvent.data) as Archon.Websocket.v0.WSEvent\n\t\t\t\t\t\tif (data.event === 'auth-ok') {\n\t\t\t\t\t\t\tconnection.authenticated = true\n\t\t\t\t\t\t} else if (data.event === 'auth-incorrect') {\n\t\t\t\t\t\t\tconnection.authenticated = false\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst eventKey = `${serverId}:${data.event}` as keyof WSEventMap\n\t\t\t\t\t\t// eslint-disable-next-line @typescript-eslint/no-explicit-any\n\t\t\t\t\t\tthis.emitter.emit(eventKey, data as any)\n\n\t\t\t\t\t\tif (data.event === 'auth-ok') resolveConnection()\n\n\t\t\t\t\t\tif (data.event === 'auth-expiring' || data.event === 'auth-incorrect') {\n\t\t\t\t\t\t\tthis.handleAuthExpiring(serverId).catch(console.error)\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch (error) {\n\t\t\t\t\t\tconsole.error('[WebSocket] Failed to parse message:', error)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tws.onclose = (event) => {\n\t\t\t\t\tconnection.authenticated = false\n\t\t\t\t\tconsole.debug(`[WebSocket] Closed for server ${serverId}:`, {\n\t\t\t\t\t\tcode: event.code,\n\t\t\t\t\t\treason: event.reason,\n\t\t\t\t\t\twasClean: event.wasClean,\n\t\t\t\t\t})\n\t\t\t\t\trejectConnection(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`WebSocket closed before authentication for server ${serverId} (code: ${event.code})`,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t\tif (event.code !== NORMAL_CLOSURE) {\n\t\t\t\t\t\tthis.scheduleReconnect(serverId, auth)\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tws.onerror = (event) => {\n\t\t\t\t\tconst url = ws.url\n\t\t\t\t\tconst readyState = ws.readyState\n\t\t\t\t\tconsole.error(`[WebSocket] Error for server ${serverId}:`, {\n\t\t\t\t\t\turl,\n\t\t\t\t\t\treadyState,\n\t\t\t\t\t\treadyStateLabel: ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED'][readyState],\n\t\t\t\t\t\ttype: (event as Event).type,\n\t\t\t\t\t})\n\t\t\t\t\trejectConnection(\n\t\t\t\t\t\tnew Error(\n\t\t\t\t\t\t\t`WebSocket connection failed for server ${serverId} (readyState: ${readyState})`,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\trejectConnection(error)\n\t\t\t}\n\t\t})\n\t}\n\n\tdisconnect(serverId: string): void {\n\t\tthis.closeConnection(serverId)\n\n\t\tthis.emitter.all.forEach((_handlers, type) => {\n\t\t\tif (type.toString().startsWith(`${serverId}:`)) {\n\t\t\t\tthis.emitter.all.delete(type)\n\t\t\t}\n\t\t})\n\t}\n\n\tprivate closeConnection(serverId: string): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tif (connection.reconnectTimer) {\n\t\t\tclearTimeout(connection.reconnectTimer)\n\t\t\tconnection.reconnectTimer = undefined\n\t\t}\n\n\t\tif (\n\t\t\tconnection.socket.readyState === WebSocket.OPEN ||\n\t\t\tconnection.socket.readyState === WebSocket.CONNECTING\n\t\t) {\n\t\t\tconnection.socket.close(NORMAL_CLOSURE, 'Client disconnecting')\n\t\t}\n\n\t\tthis.connections.delete(serverId)\n\t}\n\n\tdisconnectAll(): void {\n\t\tfor (const serverId of this.connections.keys()) {\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n\n\tsend(serverId: string, message: Archon.Websocket.v0.WSOutgoingMessage): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection || connection.socket.readyState !== WebSocket.OPEN) {\n\t\t\tconsole.warn(`Cannot send message: WebSocket not connected for server ${serverId}`)\n\t\t\treturn\n\t\t}\n\t\tconnection.socket.send(JSON.stringify(message))\n\t}\n\n\tprivate scheduleReconnect(serverId: string, auth: Archon.Websocket.v0.WSAuth): void {\n\t\tconst connection = this.connections.get(serverId)\n\t\tif (!connection) return\n\n\t\tif (connection.reconnectAttempts >= this.MAX_RECONNECT_ATTEMPTS) {\n\t\t\tthis.disconnect(serverId)\n\t\t\treturn\n\t\t}\n\n\t\tconnection.isReconnecting = true\n\t\tconnection.reconnectAttempts++\n\n\t\tconst delay = this.getReconnectDelay(connection.reconnectAttempts)\n\n\t\tconnection.reconnectTimer = setTimeout(() => {\n\t\t\tthis.connect(serverId, auth).catch((error) => {\n\t\t\t\tconsole.error(`[WebSocket] Reconnection failed for server ${serverId}:`, error)\n\t\t\t})\n\t\t}, delay)\n\t}\n\n\tprivate async handleAuthExpiring(serverId: string): Promise<void> {\n\t\ttry {\n\t\t\tconst newAuth = await this.client.archon.servers_v0.getWebSocketAuth(serverId)\n\n\t\t\tconst connection = this.connections.get(serverId)\n\t\t\tif (connection && connection.socket.readyState === WebSocket.OPEN) {\n\t\t\t\tconnection.socket.send(JSON.stringify({ event: 'auth', jwt: newAuth.token }))\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconsole.error(`[WebSocket] Failed to refresh auth for server ${serverId}:`, error)\n\t\t\tthis.disconnect(serverId)\n\t\t}\n\t}\n}\n", "import { AbstractModrinthClient } from '../core/abstract-client'\nimport { ModrinthApiError } from '../core/errors'\nimport type { RequestContext } from '../types/request'\nimport type {\n\tUploadHandle,\n\tUploadMetadata,\n\tUploadProgress,\n\tUploadRequestOptions,\n} from '../types/upload'\n\n/**\n * Abstract client with XHR-based upload implementation\n *\n * Platform-specific clients should extend this instead of AbstractModrinthClient\n * to inherit the XHR upload implementation.\n */\nexport abstract class XHRUploadClient extends AbstractModrinthClient {\n\tupload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T> {\n\t\tlet baseUrl: string\n\t\tif (options.api === 'labrinth') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.labrinthBaseUrl!)\n\t\t} else if (options.api === 'archon') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.archonBaseUrl!)\n\t\t} else if (options.api === 'sharedinstances') {\n\t\t\tbaseUrl = this.resolveBaseUrl(this.config.sharedInstancesBaseUrl!)\n\t\t} else {\n\t\t\tbaseUrl = options.api\n\t\t}\n\n\t\tconst url = this.buildUrl(path, baseUrl, options.version)\n\n\t\tconst progressCallbacks: Array<(p: UploadProgress) => void> = []\n\t\tif (options.onProgress) {\n\t\t\tprogressCallbacks.push(options.onProgress)\n\t\t}\n\t\tconst abortController = new AbortController()\n\n\t\tif (options.signal) {\n\t\t\toptions.signal.addEventListener('abort', () => abortController.abort())\n\t\t}\n\n\t\tlet context: RequestContext | undefined\n\t\tconst handle: UploadHandle<T> = {\n\t\t\tpromise: (async () => {\n\t\t\t\tconst isFormData = 'formData' in options && options.formData instanceof FormData\n\t\t\t\tconst baseHeaders = await this.buildDefaultHeaders()\n\t\t\t\tif (isFormData) {\n\t\t\t\t\tdelete baseHeaders['Content-Type']\n\t\t\t\t} else {\n\t\t\t\t\tbaseHeaders['Content-Type'] = 'application/octet-stream'\n\t\t\t\t}\n\n\t\t\t\tconst mergedOptions: UploadRequestOptions = {\n\t\t\t\t\tretry: false,\n\t\t\t\t\t...options,\n\t\t\t\t\theaders: {\n\t\t\t\t\t\t...baseHeaders,\n\t\t\t\t\t\t...options.headers,\n\t\t\t\t\t},\n\t\t\t\t}\n\t\t\t\tthis.attachArchonSentryCaptureHeader(mergedOptions)\n\n\t\t\t\tconst uploadContext = this.buildUploadContext(url, path, mergedOptions)\n\t\t\t\tcontext = uploadContext\n\t\t\t\tif (abortController.signal.aborted) {\n\t\t\t\t\tthrow new ModrinthApiError('Upload cancelled')\n\t\t\t\t}\n\n\t\t\t\tconst result = await this.executeUploadFeatureChain<T>(\n\t\t\t\t\tuploadContext,\n\t\t\t\t\tprogressCallbacks,\n\t\t\t\t\tabortController,\n\t\t\t\t)\n\t\t\t\tawait this.config.hooks?.onResponse?.(result, uploadContext)\n\t\t\t\treturn result\n\t\t\t})().catch(async (error) => {\n\t\t\t\tconst apiError = this.normalizeError(error, context)\n\t\t\t\tif (context) {\n\t\t\t\t\tawait this.config.hooks?.onError?.(apiError, context)\n\t\t\t\t}\n\t\t\t\tthrow apiError\n\t\t\t}),\n\t\t\tonProgress: (callback) => {\n\t\t\t\tprogressCallbacks.push(callback)\n\t\t\t\treturn handle\n\t\t\t},\n\t\t\tcancel: () => abortController.abort(),\n\t\t}\n\n\t\treturn handle\n\t}\n\n\tprotected executeXHRUpload<T>(\n\t\tcontext: RequestContext,\n\t\tprogressCallbacks: Array<(p: UploadProgress) => void>,\n\t\tabortController: AbortController,\n\t): Promise<T> {\n\t\treturn new Promise<T>((resolve, reject) => {\n\t\t\tconst xhr = new XMLHttpRequest()\n\t\t\tconst metadata = context.metadata as UploadMetadata\n\n\t\t\txhr.upload.addEventListener('progress', (e) => {\n\t\t\t\tif (e.lengthComputable) {\n\t\t\t\t\tconst progress: UploadProgress = {\n\t\t\t\t\t\tloaded: e.loaded,\n\t\t\t\t\t\ttotal: e.total,\n\t\t\t\t\t\tprogress: e.loaded / e.total,\n\t\t\t\t\t}\n\t\t\t\t\tprogressCallbacks.forEach((cb) => cb(progress))\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txhr.addEventListener('load', () => {\n\t\t\t\tif (xhr.status >= 200 && xhr.status < 300) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresolve(xhr.response ? JSON.parse(xhr.response) : (undefined as T))\n\t\t\t\t\t} catch {\n\t\t\t\t\t\tresolve(undefined as T)\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treject(this.createUploadError(xhr))\n\t\t\t\t}\n\t\t\t})\n\n\t\t\txhr.addEventListener('error', () => reject(new ModrinthApiError('Upload failed')))\n\t\t\txhr.addEventListener('abort', () => reject(new ModrinthApiError('Upload cancelled')))\n\t\t\txhr.addEventListener('timeout', () => reject(new ModrinthApiError('Upload timed out')))\n\n\t\t\tif (context.options.timeout !== undefined) {\n\t\t\t\txhr.timeout = context.options.timeout\n\t\t\t}\n\n\t\t\t// build URL with params (unlike $fetch, XHR doesn't handle params automatically)\n\t\t\tlet url = context.url\n\t\t\tif (context.options.params) {\n\t\t\t\tconst queryString = new URLSearchParams(\n\t\t\t\t\tObject.entries(context.options.params).map(([k, v]) => [k, String(v)]),\n\t\t\t\t).toString()\n\t\t\t\turl += (url.includes('?') ? '&' : '?') + queryString\n\t\t\t}\n\n\t\t\txhr.open('POST', url)\n\n\t\t\t// apply headers from context (features may have modified them)\n\t\t\tfor (const [key, value] of Object.entries(context.options.headers ?? {})) {\n\t\t\t\txhr.setRequestHeader(key, value)\n\t\t\t}\n\n\t\t\t// Send either FormData or file depending on what was provided\n\t\t\tconst data = 'formData' in metadata ? metadata.formData : metadata.file\n\t\t\txhr.send(data)\n\t\t\tabortController.signal.addEventListener('abort', () => xhr.abort())\n\t\t})\n\t}\n\n\tprotected createUploadError(xhr: XMLHttpRequest): ModrinthApiError {\n\t\tlet responseData: unknown\n\t\ttry {\n\t\t\tresponseData = xhr.response ? JSON.parse(xhr.response) : undefined\n\t\t} catch {\n\t\t\tresponseData = xhr.responseText\n\t\t}\n\t\treturn this.createNormalizedError(\n\t\t\tnew Error(`Upload failed with status ${xhr.status}`),\n\t\t\txhr.status,\n\t\t\tresponseData,\n\t\t)\n\t}\n}\n", "import { FetchError } from 'ofetch'\n\nimport { ModrinthApiError } from '../core/errors'\nimport type { CircuitBreakerState, CircuitBreakerStorage } from '../features/circuit-breaker'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport type { UploadHandle, UploadRequestOptions } from '../types/upload'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Circuit breaker storage using Nuxt's useState\n *\n * This provides cross-request persistence in SSR while also working in client-side.\n * State is shared between requests in the same Nuxt context.\n *\n * Note: useState must be called during initialization (in setup context) and cached,\n * as it won't work during async operations when the Nuxt context may be lost.\n */\nexport class NuxtCircuitBreakerStorage implements CircuitBreakerStorage {\n\tprivate state: Map<string, CircuitBreakerState>\n\n\tconstructor() {\n\t\t// @ts-expect-error - useState is provided by Nuxt runtime\n\t\tconst stateRef = useState<Map<string, CircuitBreakerState>>(\n\t\t\t'circuit-breaker-state',\n\t\t\t() => new Map(),\n\t\t)\n\t\tthis.state = stateRef.value\n\t}\n\n\tget(key: string): CircuitBreakerState | undefined {\n\t\treturn this.state.get(key)\n\t}\n\n\tset(key: string, state: CircuitBreakerState): void {\n\t\tthis.state.set(key, state)\n\t}\n\n\tclear(key: string): void {\n\t\tthis.state.delete(key)\n\t}\n}\n\n/**\n * Nuxt-specific configuration\n */\nexport interface NuxtClientConfig extends ClientConfig {\n\t// TODO: do we want to provide this for tauri+base as well? its not used on app\n\t/**\n\t * Rate limit key for server-side requests.\n\t * This is injected as x-ratelimit-key header on server-side.\n\t * Can be a string (for env var) or async function (for CF Secrets Store).\n\t */\n\trateLimitKey?: string | (() => Promise<string | undefined>)\n}\n\n/**\n * Nuxt platform client using Nuxt's $fetch\n *\n * This client is optimized for Nuxt applications and handles SSR/CSR automatically.\n *\n * Note: upload() is only available in browser context (CSR). It will throw during SSR.\n *\n * @example\n * ```typescript\n * // In a Nuxt composable\n * const config = useRuntimeConfig()\n *\n * const client = new NuxtModrinthClient({\n * userAgent: 'my-nuxt-app/1.0.0',\n * rateLimitKey: import.meta.server ? config.rateLimitKey : undefined,\n * features: [\n * new AuthFeature({\n * token: async () => getOAuthToken()\n * }),\n * new CircuitBreakerFeature({\n * storage: new NuxtCircuitBreakerStorage()\n * })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class NuxtModrinthClient extends XHRUploadClient {\n\tdeclare protected config: NuxtClientConfig\n\tprivate rateLimitKeyResolved: string | undefined\n\tprivate rateLimitKeyPromise: Promise<string | undefined> | undefined\n\n\tconstructor(config: NuxtClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\t/**\n\t * Resolve the rate limit key, handling both string and async function values.\n\t * Results are cached for subsequent calls.\n\t */\n\tprivate async resolveRateLimitKey(): Promise<string | undefined> {\n\t\tif (this.rateLimitKeyResolved !== undefined) {\n\t\t\treturn this.rateLimitKeyResolved\n\t\t}\n\n\t\tconst key = this.config.rateLimitKey\n\t\tif (typeof key === 'string') {\n\t\t\tthis.rateLimitKeyResolved = key\n\t\t} else if (typeof key === 'function') {\n\t\t\tif (!this.rateLimitKeyPromise) {\n\t\t\t\tthis.rateLimitKeyPromise = key()\n\t\t\t}\n\t\t\tthis.rateLimitKeyResolved = await this.rateLimitKeyPromise\n\t\t}\n\n\t\treturn this.rateLimitKeyResolved\n\t}\n\n\t/**\n\t * Override request to resolve rate limit key before calling super.\n\t * This allows async fetching of the key from CF Secrets Store.\n\t */\n\tasync request<T>(path: string, options: RequestOptions): Promise<T> {\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server) {\n\t\t\tawait this.resolveRateLimitKey()\n\t\t}\n\t\treturn super.request(path, options)\n\t}\n\n\t/**\n\t * Upload a file with progress tracking\n\t *\n\t * Note: This method is only available in browser context (CSR).\n\t * Calling during SSR will throw an error.\n\t */\n\tupload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T> {\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server) {\n\t\t\tthrow new ModrinthApiError('upload() is not supported during SSR')\n\t\t}\n\t\treturn super.upload(path, options)\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\t// @ts-expect-error - $fetch is provided by Nuxt\n\t\t\tconst response = await $fetch<T>(url, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: options.body,\n\t\t\t\tparams: options.params,\n\t\t\t\ttimeout: options.timeout,\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\t\t\tcache: import.meta.server ? undefined : 'no-store',\n\t\t\t})\n\n\t\t\treturn response\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst response = await fetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\t\t\tcache: import.meta.server ? undefined : 'no-store',\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow new ModrinthApiError('Streaming response has no readable body', {\n\t\t\t\t\tstatusCode: response.status,\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof FetchError) {\n\t\t\treturn this.createNormalizedError(error, error.response?.status, error.data)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n\n\tprotected async buildDefaultHeaders(): Promise<Record<string, string>> {\n\t\tconst headers: Record<string, string> = {\n\t\t\t...(await super.buildDefaultHeaders()),\n\t\t}\n\n\t\t// Use the resolved key (populated by resolveRateLimitKey in request())\n\t\t// @ts-expect-error - import.meta is provided by Nuxt\n\t\tif (import.meta.server && this.rateLimitKeyResolved) {\n\t\t\theaders['x-ratelimit-key'] = this.rateLimitKeyResolved\n\t\t}\n\n\t\treturn headers\n\t}\n}\n", "import type { ModrinthApiError } from '../core/errors'\nimport type { ClientConfig } from '../types/client'\nimport type { RequestOptions } from '../types/request'\nimport { appendRequestParams, parseResponseErrorData, toFetchBody } from '../utils/fetch'\nimport { GenericSyncClient } from './sync-generic'\nimport { GenericWebSocketClient } from './websocket-generic'\nimport { XHRUploadClient } from './xhr-upload-client'\n\n/**\n * Tauri-specific configuration\n * TODO: extend into interface if needed.\n */\nexport type TauriClientConfig = ClientConfig\n\n/**\n * Extended error type with HTTP response metadata\n */\ninterface HttpError extends Error {\n\tstatusCode?: number\n\tresponseData?: unknown\n}\n\n/**\n * Tauri platform client using Tauri v2 HTTP plugin\n *\n * Extends XHRUploadClient to provide upload with progress tracking.\n *\n * @example\n * ```typescript\n * import { getVersion } from '@tauri-apps/api/app'\n *\n * const client = new TauriModrinthClient({\n * userAgent: async () => `modrinth/theseus/${await getVersion()} (support@modrinth.com)`,\n * features: [\n * new AuthFeature({ token: async () => getOAuthToken() })\n * ]\n * })\n *\n * const project = await client.request('/project/sodium', { api: 'labrinth', version: 2 })\n * ```\n */\nexport class TauriModrinthClient extends XHRUploadClient {\n\tdeclare protected config: TauriClientConfig\n\n\tconstructor(config: TauriClientConfig) {\n\t\tsuper(config)\n\n\t\tObject.defineProperty(this.archon, 'sockets', {\n\t\t\tvalue: new GenericWebSocketClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t\tObject.defineProperty(this.archon, 'sync', {\n\t\t\tvalue: new GenericSyncClient(this),\n\t\t\twritable: false,\n\t\t\tenumerable: true,\n\t\t\tconfigurable: false,\n\t\t})\n\t}\n\n\tprotected async executeRequest<T>(url: string, options: RequestOptions): Promise<T> {\n\t\ttry {\n\t\t\t// Dynamically import Tauri HTTP plugin\n\t\t\t// This allows the package to be used in non-Tauri environments\n\t\t\tconst { fetch: tauriFetch } = await import('@tauri-apps/plugin-http')\n\n\t\t\tconst body = toFetchBody(options.body)\n\t\t\tconst fullUrl = appendRequestParams(url, options.params)\n\n\t\t\tconst response = await tauriFetch(fullUrl, {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tlet responseData: unknown\n\t\t\t\ttry {\n\t\t\t\t\tresponseData = await response.json()\n\t\t\t\t} catch {\n\t\t\t\t\tresponseData = undefined\n\t\t\t\t}\n\n\t\t\t\tconst error = new Error(`HTTP ${response.status}: ${response.statusText}`) as HttpError\n\n\t\t\t\terror.statusCode = response.status\n\t\t\t\terror.responseData = responseData\n\n\t\t\t\tthrow error\n\t\t\t}\n\n\t\t\t// Handle binary downloads (e.g. kyros fs files) before JSON parsing.\n\t\t\tconst contentType = response.headers.get('content-type')?.toLowerCase() ?? ''\n\t\t\tif (fullUrl.includes('/fs/download')) {\n\t\t\t\treturn (await response.blob()) as T\n\t\t\t}\n\t\t\tif (\n\t\t\t\tcontentType.startsWith('image/') ||\n\t\t\t\tcontentType.startsWith('audio/') ||\n\t\t\t\tcontentType.startsWith('video/') ||\n\t\t\t\tcontentType.includes('application/octet-stream')\n\t\t\t) {\n\t\t\t\treturn (await response.blob()) as T\n\t\t\t}\n\n\t\t\tif (response.status === 204 || response.status === 205) {\n\t\t\t\treturn undefined as T\n\t\t\t}\n\n\t\t\tif (contentType.includes('application/json') || contentType.includes('+json')) {\n\t\t\t\treturn (await response.json()) as T\n\t\t\t}\n\n\t\t\tconst text = await response.text()\n\t\t\tif (!text) {\n\t\t\t\treturn undefined as T\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(text) as T\n\t\t\t} catch {\n\t\t\t\treturn text as T\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected async executeStreamRequest(\n\t\turl: string,\n\t\toptions: RequestOptions,\n\t): Promise<ReadableStream<Uint8Array>> {\n\t\ttry {\n\t\t\tconst { fetch: tauriFetch } = await import('@tauri-apps/plugin-http')\n\t\t\tconst response = await tauriFetch(appendRequestParams(url, options.params), {\n\t\t\t\tmethod: options.method ?? 'GET',\n\t\t\t\theaders: options.headers,\n\t\t\t\tbody: toFetchBody(options.body),\n\t\t\t\tsignal: options.signal,\n\t\t\t})\n\n\t\t\tif (!response.ok) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error(`HTTP ${response.status}: ${response.statusText}`),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tawait parseResponseErrorData(response),\n\t\t\t\t)\n\t\t\t}\n\n\t\t\tif (!response.body) {\n\t\t\t\tthrow this.createNormalizedError(\n\t\t\t\t\tnew Error('Streaming response has no readable body'),\n\t\t\t\t\tresponse.status,\n\t\t\t\t\tundefined,\n\t\t\t\t)\n\t\t\t}\n\n\t\t\treturn response.body\n\t\t} catch (error) {\n\t\t\tthrow this.normalizeError(error)\n\t\t}\n\t}\n\n\tprotected normalizeError(error: unknown): ModrinthApiError {\n\t\tif (error instanceof Error) {\n\t\t\tconst httpError = error as HttpError\n\t\t\tconst statusCode = httpError.statusCode\n\t\t\tconst responseData = httpError.responseData\n\n\t\t\treturn this.createNormalizedError(error, statusCode, responseData)\n\t\t}\n\n\t\treturn super.normalizeError(error)\n\t}\n}\n", "import type { NodeAuth } from '../features/node-auth'\n\n/**\n * Global node auth state.\n * Set by server management pages, read by NodeAuthFeature.\n */\nexport const nodeAuthState = {\n\tgetAuth: null as (() => NodeAuth | null) | null,\n\trefreshAuth: null as (() => Promise<void>) | null,\n}\n\n/**\n * Configure the node auth state. Call this when entering server management.\n *\n * @param getAuth - Function that returns current auth or null\n * @param refreshAuth - Function to refresh the auth token\n *\n * @example\n * ```typescript\n * // In server management page setup\n * setNodeAuthState(\n * () => fsAuth.value,\n * refreshFsAuth,\n * )\n * ```\n */\nexport function setNodeAuthState(getAuth: () => NodeAuth | null, refreshAuth: () => Promise<void>) {\n\tnodeAuthState.getAuth = getAuth\n\tnodeAuthState.refreshAuth = refreshAuth\n}\n\n/**\n * Clear the node auth state. Call this when leaving server management.\n *\n * @example\n * ```typescript\n * onUnmounted(() => {\n * clearNodeAuthState()\n * })\n * ```\n */\nexport function clearNodeAuthState() {\n\tnodeAuthState.getAuth = null\n\tnodeAuthState.refreshAuth = null\n}\n", "import { ModrinthApiError } from '../core/errors'\n\n/**\n * Wrap a function with JWT retry logic.\n * On 401, calls refreshToken() and retries once.\n */\nexport async function withJWTRetry<T>(\n\tfn: () => Promise<T>,\n\trefreshToken: () => Promise<void>,\n): Promise<T> {\n\ttry {\n\t\treturn await fn()\n\t} catch (error) {\n\t\tif (error instanceof ModrinthApiError && error.statusCode === 401) {\n\t\t\tawait refreshToken()\n\t\t\treturn await fn()\n\t\t}\n\t\tthrow error\n\t}\n}\n", "export interface WebSocketPingOptions {\n\tcount?: number\n\tintervalMs?: number\n\tsettleDelayMs?: number\n\ttimeoutMs?: number\n\tsignal?: AbortSignal\n}\n\nexport async function pingWebSocketUrl(\n\turl: string,\n\toptions: WebSocketPingOptions = {},\n): Promise<number> {\n\tconst count = options.count ?? 5\n\tconst intervalMs = options.intervalMs ?? 200\n\tconst settleDelayMs = options.settleDelayMs ?? 1000\n\tconst timeoutMs = options.timeoutMs ?? count * intervalMs + settleDelayMs + 1000\n\n\tif (options.signal?.aborted) return -1\n\n\treturn await new Promise<number>((resolve) => {\n\t\tconst samples: number[] = []\n\t\tconst timers = new Set<ReturnType<typeof setTimeout>>()\n\t\tlet socket: WebSocket | undefined\n\t\tlet settled = false\n\n\t\tconst setTrackedTimeout = (callback: () => void, ms: number) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\ttimers.delete(timer)\n\t\t\t\tcallback()\n\t\t\t}, ms)\n\t\t\ttimers.add(timer)\n\t\t\treturn timer\n\t\t}\n\n\t\tconst cleanup = () => {\n\t\t\tfor (const timer of timers) clearTimeout(timer)\n\t\t\ttimers.clear()\n\t\t\toptions.signal?.removeEventListener('abort', abort)\n\n\t\t\tif (\n\t\t\t\tsocket &&\n\t\t\t\t(socket.readyState === WebSocket.CONNECTING || socket.readyState === WebSocket.OPEN)\n\t\t\t) {\n\t\t\t\tsocket.close()\n\t\t\t}\n\t\t}\n\n\t\tconst finish = (ping: number) => {\n\t\t\tif (settled) return\n\t\t\tsettled = true\n\t\t\tcleanup()\n\t\t\tresolve(ping)\n\t\t}\n\n\t\tconst abort = () => finish(-1)\n\t\toptions.signal?.addEventListener('abort', abort, { once: true })\n\n\t\ttry {\n\t\t\tsocket = new WebSocket(url)\n\t\t} catch {\n\t\t\tfinish(-1)\n\t\t\treturn\n\t\t}\n\n\t\tsetTrackedTimeout(() => finish(-1), timeoutMs)\n\n\t\tsocket.onopen = () => {\n\t\t\tfor (let i = 0; i < count; i++) {\n\t\t\t\tsetTrackedTimeout(() => {\n\t\t\t\t\tif (socket?.readyState === WebSocket.OPEN) {\n\t\t\t\t\t\tsocket.send(String(performance.now()))\n\t\t\t\t\t}\n\t\t\t\t}, i * intervalMs)\n\t\t\t}\n\n\t\t\tsetTrackedTimeout(\n\t\t\t\t() => {\n\t\t\t\t\tconst ping =\n\t\t\t\t\t\tsamples.length > 0\n\t\t\t\t\t\t\t? Math.round([...samples].sort((a, b) => a - b)[Math.floor(samples.length / 2)])\n\t\t\t\t\t\t\t: -1\n\t\t\t\t\tfinish(ping)\n\t\t\t\t},\n\t\t\t\tcount * intervalMs + settleDelayMs,\n\t\t\t)\n\t\t}\n\n\t\tsocket.onmessage = (event) => {\n\t\t\tsamples.push(performance.now() - Number(event.data))\n\t\t}\n\n\t\tsocket.onerror = () => finish(-1)\n\t\tsocket.onclose = () => {\n\t\t\tif (!settled && samples.length === 0) finish(-1)\n\t\t}\n\t})\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["AbstractModule", "client", "ArchonActionsV1Module", "AbstractModule", "serverId", "options", "params", "ArchonBackupsV1Module", "AbstractModule", "serverId", "worldId", "backupId", "request", "ArchonBackupsQueueV1Module", "AbstractModule", "serverId", "worldId", "request", "operationId", "backupId", "backupIds", "ArchonContentV1Module", "AbstractModule", "serverId", "worldId", "options", "params", "query", "request", "addons", "items", "filename", "gameVersion", "signal", "ArchonNodesInternalModule", "AbstractModule", "ArchonNoticesV0Module", "AbstractModule", "request", "id", "target", "ArchonOptionsV1Module", "AbstractModule", "serverId", "worldId", "body", "ArchonPropertiesV1Module", "AbstractModule", "serverId", "worldId", "body", "ArchonServerUsersV1Module", "AbstractModule", "serverId", "user", "userId", "role", "ArchonServersInternalModule", "AbstractModule", "subdomain", "ArchonServersV0Module", "AbstractModule", "serverId", "options", "params", "query", "region", "request", "action", "hardReset", "file", "auth", "formData", "name", "port", "subdomain", "config", "noticeId", "ArchonServersV1Module", "AbstractModule", "serverId", "worldId", "ArchonTransfersInternalModule", "AbstractModule", "request", "options", "params", "$fetch", "ISO3166_REPO", "parseCSV", "csv", "lines", "line", "headerLine", "headers", "values", "row", "header", "index", "ISO3166Module", "AbstractModule", "countriesCSV", "subdivisionsCSV", "$fetch", "countriesData", "subdivisionsData", "countries", "subdivisions", "acc", "sub", "countryCode", "err", "KyrosContentV1Module", "AbstractModule", "worldId", "files", "options", "formData", "file", "properties", "NODE_FS_PATH_REGEX", "HTTP_SCHEME_REGEX", "WS_SCHEME_REGEX", "HTTP_SECURE_SCHEME_REGEX", "HTTP_INSECURE_SCHEME_REGEX", "getNodeBaseUrl", "url", "baseUrl", "getNodeWebSocketUrl", "KyrosFilesV0Module", "AbstractModule", "auth", "getNodeBaseUrl", "path", "page", "pageSize", "type", "file", "options", "content", "blob", "sourcePath", "destPath", "newName", "newPath", "recursive", "override", "dry", "opId", "action", "KyrosLogsV1Module", "AbstractModule", "getUploadSessionPath", "scope", "worldId", "KyrosUploadSessionsV1Module", "AbstractModule", "uploadId", "files", "options", "formData", "file", "filename", "LabrinthAnalyticsInternalModule", "AbstractModule", "data", "id", "LabrinthAnalyticsV3Module", "AbstractModule", "data", "BASE62_CHARS", "decodeBase62Id", "id", "value", "char", "digit", "LabrinthAttributionInternalModule", "AbstractModule", "projectId", "groupId", "body", "numericId", "groupIds", "wireBody", "fileId", "LabrinthAuthInternalModule", "AbstractModule", "LabrinthAuthV2Module", "AbstractModule", "data", "id", "LabrinthBillingInternalModule", "AbstractModule", "userId", "params", "id", "edit", "dry", "body", "request", "refund", "LabrinthCollectionsModule", "AbstractModule", "id", "ids", "data", "icon", "ext", "LabrinthContentV3Module", "AbstractModule", "request", "LabrinthExternalProjectsInternalModule", "AbstractModule", "data", "sha1", "id", "LabrinthFriendsV3Module", "AbstractModule", "idOrUsername", "LabrinthGeoIpModule", "AbstractModule", "country", "line", "LabrinthGlobalsInternalModule", "AbstractModule", "buildImageQueryParams", "ext", "target", "params", "LabrinthImagesV3Module", "AbstractModule", "file", "LabrinthLimitsV3Module", "AbstractModule", "LabrinthModerationInternalModule", "AbstractModule", "params", "projectId", "judgements", "LabrinthNotificationsV2Module", "AbstractModule", "userId", "ids", "id", "LabrinthOAuthInternalModule", "AbstractModule", "userId", "id", "ids", "app", "data", "file", "ext", "clientId", "params", "LabrinthOrganizationsV3Module", "AbstractModule", "idOrSlug", "ids", "request", "projectId", "data", "LabrinthPatsV2Module", "AbstractModule", "data", "id", "LabrinthPayoutV3Module", "AbstractModule", "balance", "date", "amount", "transaction", "country", "id", "LabrinthPayoutsV3Module", "AbstractModule", "params", "LabrinthProjectsV2Module", "AbstractModule", "id", "idOrSlug", "encoded", "ids", "params", "data", "file", "options", "url", "count", "isModrinthErrorResponse", "obj", "record", "ModrinthApiError", "_ModrinthApiError", "message", "data", "error", "context", "ModrinthServerError", "_ModrinthServerError", "errorMessage", "statusCode", "responseData", "v1Error", "isModrinthErrorResponse", "LabrinthProjectsV3Module", "AbstractModule", "id", "ids", "params", "options", "data", "error", "ModrinthApiError", "file", "ext", "url", "LabrinthReportsV3Module", "AbstractModule", "id", "params", "queryParams", "ids", "data", "LabrinthServerPingInternalModule", "AbstractModule", "request", "LabrinthSessionsV2Module", "AbstractModule", "id", "LabrinthStateModule", "AbstractModule", "errors", "handleError", "err", "defaultValue", "endpoint", "categories", "loaders", "gameVersions", "donationPlatforms", "reportTypes", "homePageProjects", "homePageSearch", "homePageNotifs", "products", "muralBankDetails", "iso3166Data", "payoutMethods", "globals", "tremendousIdMap", "m", "LabrinthTechReviewInternalModule", "AbstractModule", "params", "reportId", "issueId", "detailId", "data", "projectId", "LabrinthThreadsV3Module", "AbstractModule", "id", "ids", "message", "messageId", "LabrinthUsersV2Module", "AbstractModule", "idOrUsername", "ids", "data", "file", "ext", "LabrinthUsersV3Module", "AbstractModule", "idOrUsername", "preferences", "query", "LabrinthVersionsV2Module", "AbstractModule", "id", "options", "params", "hash", "algorithm", "ids", "projectId", "versionId", "VERSION_UPLOAD_TIMEOUT_MS", "LabrinthVersionsV3Module", "AbstractModule", "id", "options", "params", "ids", "projectId", "versionId", "draftVersion", "versionFiles", "projectType", "formData", "files", "vf", "fileTypes", "fileParts", "file", "i", "fileTypeMap", "acc", "key", "data", "LabrinthAffiliateInternalModule", "AbstractModule", "data", "id", "LabrinthBlockedUsersInternalModule", "AbstractModule", "userId", "targetId", "LabrinthBlockedUsersV3Module", "AbstractModule", "idOrUsername", "LabrinthCampaignInternalModule", "AbstractModule", "LabrinthTagsV2Module", "AbstractModule", "licenseId", "LabrinthTeamsV2Module", "AbstractModule", "teamId", "data", "userId", "LabrinthTeamsV3Module", "AbstractModule", "ids", "LAUNCHER_META_BASE_URL", "LauncherMetaManifestV0Module", "AbstractModule", "loader", "formatVersion", "MclogsInsightsV1Module", "AbstractModule", "content", "MclogsLogsV1Module", "AbstractModule", "content", "PAPER_BASE_URL", "PaperVersionsV3Module", "AbstractModule", "mcVersion", "PURPUR_BASE_URL", "PurpurVersionsV2Module", "AbstractModule", "mcVersion", "SharedInstancesInstancesV1Module", "AbstractModule", "instanceId", "userId", "version", "SharedInstancesInvitesV1Module", "AbstractModule", "inviteId", "SharedInstancesModerationV1Module", "AbstractModule", "request", "instanceId", "version", "fileName", "SharedInstancesUsersV1Module", "AbstractModule", "userId", "MODULE_REGISTRY", "ArchonActionsV1Module", "ArchonBackupsQueueV1Module", "ArchonBackupsV1Module", "ArchonContentV1Module", "ArchonNodesInternalModule", "ArchonNoticesV0Module", "ArchonOptionsV1Module", "ArchonPropertiesV1Module", "ArchonServerUsersV1Module", "ArchonServersInternalModule", "ArchonServersV0Module", "ArchonServersV1Module", "ArchonTransfersInternalModule", "ISO3166Module", "MclogsInsightsV1Module", "MclogsLogsV1Module", "LauncherMetaManifestV0Module", "KyrosContentV1Module", "KyrosFilesV0Module", "KyrosLogsV1Module", "KyrosUploadSessionsV1Module", "LabrinthAffiliateInternalModule", "LabrinthAnalyticsInternalModule", "LabrinthAnalyticsV3Module", "LabrinthAuthInternalModule", "LabrinthAuthV2Module", "LabrinthAttributionInternalModule", "LabrinthBillingInternalModule", "LabrinthBlockedUsersInternalModule", "LabrinthBlockedUsersV3Module", "LabrinthCampaignInternalModule", "LabrinthCollectionsModule", "LabrinthContentV3Module", "LabrinthExternalProjectsInternalModule", "LabrinthFriendsV3Module", "LabrinthGeoIpModule", "LabrinthGlobalsInternalModule", "LabrinthImagesV3Module", "LabrinthModerationInternalModule", "LabrinthNotificationsV2Module", "LabrinthOAuthInternalModule", "LabrinthOrganizationsV3Module", "LabrinthPatsV2Module", "LabrinthLimitsV3Module", "LabrinthPayoutV3Module", "LabrinthPayoutsV3Module", "LabrinthProjectsV2Module", "LabrinthProjectsV3Module", "LabrinthReportsV3Module", "LabrinthServerPingInternalModule", "LabrinthSessionsV2Module", "LabrinthStateModule", "LabrinthTagsV2Module", "LabrinthTeamsV2Module", "LabrinthTeamsV3Module", "LabrinthTechReviewInternalModule", "LabrinthThreadsV3Module", "LabrinthUsersV2Module", "LabrinthUsersV3Module", "LabrinthVersionsV2Module", "LabrinthVersionsV3Module", "PaperVersionsV3Module", "PurpurVersionsV2Module", "SharedInstancesInvitesV1Module", "SharedInstancesInstancesV1Module", "SharedInstancesModerationV1Module", "SharedInstancesUsersV1Module", "parseModuleID", "id", "parts", "api", "moduleName", "buildModuleStructure", "structure", "constructor", "AbstractUploadClient", "AbstractModrinthClient", "AbstractUploadClient", "config", "structure", "buildModuleStructure", "api", "modules", "namespaceObj", "moduleName", "ModuleConstructor", "fullModuleId", "instance", "declaredId", "path", "options", "baseUrl", "url", "defaultHeaders", "mergedOptions", "headers", "context", "result", "error", "apiError", "executeTerminal", "applicableFeatures", "feature", "index", "next", "progressCallbacks", "abortController", "version", "base", "versionPath", "cleanPath", "metadata", "body", "userAgent", "archonSentryCapture", "ModrinthApiError", "statusCode", "responseData", "ModrinthServerError", "AbstractFeature", "config", "_context", "AbstractSyncClient", "client", "serverId", "eventType", "handler", "eventKey", "wrapped", "connection", "event", "status", "error", "_handlers", "type", "AbstractWebSocketClient", "client", "serverId", "options", "status", "auth", "resolve", "reject", "unsubscribe", "timeout", "eventType", "handler", "eventKey", "connection", "attempt", "AuthFeature", "AbstractFeature", "next", "context", "token", "headerName", "tokenPrefix", "headerValue", "InMemoryCircuitBreakerStorage", "key", "state", "CircuitBreakerFeature", "AbstractFeature", "config", "next", "context", "circuitKey", "ModrinthApiError", "result", "error", "method", "pathWithoutQuery", "now", "NodeAuthFeature", "AbstractFeature", "context", "next", "retryCount", "auth", "error", "ModrinthApiError", "baseUrl", "getNodeBaseUrl", "path", "version", "base", "versionPath", "cleanPath", "token", "payload", "expiresAt", "PANEL_VERSION", "PanelVersionFeature", "AbstractFeature", "next", "context", "RetryFeature", "AbstractFeature", "config", "next", "context", "lastError", "maxAttempts", "attempt", "error", "delay", "_maxAttempts", "ModrinthApiError", "networkErrorPatterns", "errorMessage", "pattern", "backoffStrategy", "initialDelay", "maxDelay", "ms", "resolve", "VerboseLoggingFeature", "AbstractFeature", "next", "context", "method", "api", "version", "prefix", "result", "size", "error", "details", "formatErrorDetails", "err", "status", "statusText", "data", "parts", "safeStringify", "value", "Archon", "ServerUsers", "v1", "$fetch", "FetchError", "appendRequestParams", "url", "params", "filteredParams", "key", "value", "queryString", "toFetchBody", "body", "parseResponseErrorData", "response", "contentType", "text", "mitt", "SseParser", "chunk", "items", "lineEnd", "line", "length", "lf", "cr", "colon", "field", "value", "retry", "parseSyncEventData", "data", "parsed", "DEFAULT_RETRY_DELAY", "MAX_RECONNECT_DELAY", "JITTER_MS", "GenericSyncClient", "AbstractSyncClient", "mitt", "serverId", "options", "existing", "connection", "hadConnected", "controller", "stream", "result", "error", "reader", "decoder", "parser", "SseParser", "done", "value", "chunk", "finalChunk", "finalItems", "items", "item", "event", "parseSyncEventData", "delay", "resolve", "exponentialDelay", "id", "intent", "mitt", "NORMAL_CLOSURE", "GenericWebSocketClient", "AbstractWebSocketClient", "mitt", "serverId", "auth", "resolve", "reject", "settled", "authenticationTimeout", "resolveConnection", "rejectConnection", "error", "ws", "getNodeWebSocketUrl", "connection", "messageEvent", "data", "eventKey", "event", "url", "readyState", "_handlers", "type", "message", "delay", "newAuth", "XHRUploadClient", "AbstractModrinthClient", "path", "options", "baseUrl", "url", "progressCallbacks", "abortController", "context", "handle", "isFormData", "baseHeaders", "mergedOptions", "uploadContext", "ModrinthApiError", "result", "error", "apiError", "callback", "resolve", "reject", "xhr", "metadata", "e", "progress", "cb", "queryString", "k", "v", "key", "value", "data", "responseData", "GenericModrinthClient", "XHRUploadClient", "config", "GenericWebSocketClient", "GenericSyncClient", "url", "options", "$fetch", "error", "response", "appendRequestParams", "toFetchBody", "parseResponseErrorData", "ModrinthApiError", "FetchError", "FetchError", "NuxtCircuitBreakerStorage", "stateRef", "key", "state", "NuxtModrinthClient", "XHRUploadClient", "config", "GenericWebSocketClient", "GenericSyncClient", "path", "options", "ModrinthApiError", "url", "error", "response", "appendRequestParams", "toFetchBody", "parseResponseErrorData", "FetchError", "headers", "TauriModrinthClient", "XHRUploadClient", "config", "GenericWebSocketClient", "GenericSyncClient", "url", "options", "tauriFetch", "body", "toFetchBody", "fullUrl", "appendRequestParams", "response", "responseData", "error", "contentType", "text", "parseResponseErrorData", "httpError", "statusCode", "nodeAuthState", "setNodeAuthState", "getAuth", "refreshAuth", "clearNodeAuthState", "withJWTRetry", "fn", "refreshToken", "error", "ModrinthApiError", "pingWebSocketUrl", "url", "options", "count", "intervalMs", "settleDelayMs", "timeoutMs", "resolve", "samples", "timers", "socket", "settled", "setTrackedTimeout", "callback", "ms", "timer", "cleanup", "abort", "finish", "ping", "i", "a", "b", "event"]
|
|
7
7
|
}
|