@modrinth/api-client 0.31.0 → 0.33.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.
Files changed (105) hide show
  1. package/dist/index.d.ts +7104 -28
  2. package/dist/index.js +2 -1
  3. package/dist/index.js.map +7 -0
  4. package/package.json +4 -2
  5. package/dist/core/abstract-client.d.ts +0 -163
  6. package/dist/core/abstract-feature.d.ts +0 -72
  7. package/dist/core/abstract-module.d.ts +0 -10
  8. package/dist/core/abstract-sync.d.ts +0 -61
  9. package/dist/core/abstract-upload-client.d.ts +0 -20
  10. package/dist/core/abstract-websocket.d.ts +0 -52
  11. package/dist/core/errors.d.ts +0 -48
  12. package/dist/features/auth.d.ts +0 -47
  13. package/dist/features/circuit-breaker.d.ts +0 -139
  14. package/dist/features/node-auth.d.ts +0 -58
  15. package/dist/features/panel-version.d.ts +0 -7
  16. package/dist/features/retry.d.ts +0 -87
  17. package/dist/features/verbose-logging.d.ts +0 -6
  18. package/dist/modules/archon/actions/v1.d.ts +0 -10
  19. package/dist/modules/archon/backups/v1.d.ts +0 -44
  20. package/dist/modules/archon/backups-queue/v1.d.ts +0 -25
  21. package/dist/modules/archon/content/v1.d.ts +0 -48
  22. package/dist/modules/archon/index.d.ts +0 -8
  23. package/dist/modules/archon/nodes/internal.d.ts +0 -10
  24. package/dist/modules/archon/notices/v0.d.ts +0 -38
  25. package/dist/modules/archon/options/v1.d.ts +0 -9
  26. package/dist/modules/archon/properties/v1.d.ts +0 -9
  27. package/dist/modules/archon/server-users/v1.d.ts +0 -30
  28. package/dist/modules/archon/servers/v0.d.ts +0 -122
  29. package/dist/modules/archon/servers/v1.d.ts +0 -30
  30. package/dist/modules/archon/transfers/internal.d.ts +0 -25
  31. package/dist/modules/archon/types.d.ts +0 -941
  32. package/dist/modules/index.d.ts +0 -181
  33. package/dist/modules/iso3166/index.d.ts +0 -24
  34. package/dist/modules/iso3166/types.d.ts +0 -21
  35. package/dist/modules/kyros/content/v1.d.ts +0 -23
  36. package/dist/modules/kyros/files/v0.d.ts +0 -123
  37. package/dist/modules/kyros/logs/v1.d.ts +0 -6
  38. package/dist/modules/kyros/types.d.ts +0 -44
  39. package/dist/modules/kyros/upload-sessions/v1.d.ts +0 -18
  40. package/dist/modules/labrinth/affiliate/internal.d.ts +0 -30
  41. package/dist/modules/labrinth/analytics/v3.d.ts +0 -56
  42. package/dist/modules/labrinth/attribution/internal.d.ts +0 -47
  43. package/dist/modules/labrinth/auth/internal.d.ts +0 -19
  44. package/dist/modules/labrinth/auth/v2.d.ts +0 -98
  45. package/dist/modules/labrinth/billing/internal.d.ts +0 -65
  46. package/dist/modules/labrinth/campaign/internal.d.ts +0 -10
  47. package/dist/modules/labrinth/collections.d.ts +0 -80
  48. package/dist/modules/labrinth/content/v3.d.ts +0 -6
  49. package/dist/modules/labrinth/external-projects/internal.d.ts +0 -9
  50. package/dist/modules/labrinth/friends/v3.d.ts +0 -23
  51. package/dist/modules/labrinth/globals/internal.d.ts +0 -11
  52. package/dist/modules/labrinth/images/v3.d.ts +0 -7
  53. package/dist/modules/labrinth/index.d.ts +0 -31
  54. package/dist/modules/labrinth/limits/v3.d.ts +0 -17
  55. package/dist/modules/labrinth/moderation/internal.d.ts +0 -12
  56. package/dist/modules/labrinth/notifications/v2.d.ts +0 -73
  57. package/dist/modules/labrinth/oauth/internal.d.ts +0 -97
  58. package/dist/modules/labrinth/organizations/v3.d.ts +0 -66
  59. package/dist/modules/labrinth/pats/v2.d.ts +0 -31
  60. package/dist/modules/labrinth/payout/v3.d.ts +0 -30
  61. package/dist/modules/labrinth/payouts/v3.d.ts +0 -15
  62. package/dist/modules/labrinth/projects/v2.d.ts +0 -169
  63. package/dist/modules/labrinth/projects/v3.d.ts +0 -110
  64. package/dist/modules/labrinth/reports/v3.d.ts +0 -81
  65. package/dist/modules/labrinth/server-ping/internal.d.ts +0 -10
  66. package/dist/modules/labrinth/sessions/v2.d.ts +0 -17
  67. package/dist/modules/labrinth/state/index.d.ts +0 -17
  68. package/dist/modules/labrinth/tags/v2.d.ts +0 -19
  69. package/dist/modules/labrinth/teams/v2.d.ts +0 -57
  70. package/dist/modules/labrinth/teams/v3.d.ts +0 -18
  71. package/dist/modules/labrinth/tech-review/internal.d.ts +0 -77
  72. package/dist/modules/labrinth/threads/v3.d.ts +0 -57
  73. package/dist/modules/labrinth/types.d.ts +0 -2119
  74. package/dist/modules/labrinth/users/v2.d.ts +0 -101
  75. package/dist/modules/labrinth/users/v3.d.ts +0 -37
  76. package/dist/modules/labrinth/versions/v2.d.ts +0 -75
  77. package/dist/modules/labrinth/versions/v3.d.ts +0 -123
  78. package/dist/modules/launcher-meta/types.d.ts +0 -25
  79. package/dist/modules/launcher-meta/v0.d.ts +0 -17
  80. package/dist/modules/mclogs/insights/v1.d.ts +0 -6
  81. package/dist/modules/mclogs/logs/v1.d.ts +0 -6
  82. package/dist/modules/mclogs/types.d.ts +0 -60
  83. package/dist/modules/paper/types.d.ts +0 -22
  84. package/dist/modules/paper/v3.d.ts +0 -19
  85. package/dist/modules/purpur/types.d.ts +0 -15
  86. package/dist/modules/purpur/v2.d.ts +0 -16
  87. package/dist/modules/types.d.ts +0 -8
  88. package/dist/platform/generic.d.ts +0 -28
  89. package/dist/platform/nuxt.d.ts +0 -88
  90. package/dist/platform/sync-generic.d.ts +0 -16
  91. package/dist/platform/tauri.d.ts +0 -35
  92. package/dist/platform/websocket-generic.d.ts +0 -16
  93. package/dist/platform/xhr-upload-client.d.ts +0 -15
  94. package/dist/state/node-auth.d.ts +0 -36
  95. package/dist/types/client.d.ts +0 -70
  96. package/dist/types/errors.d.ts +0 -43
  97. package/dist/types/index.d.ts +0 -10
  98. package/dist/types/request.d.ts +0 -124
  99. package/dist/types/upload.d.ts +0 -92
  100. package/dist/utils/fetch.d.ts +0 -4
  101. package/dist/utils/jwt-retry.d.ts +0 -5
  102. package/dist/utils/node-url.d.ts +0 -2
  103. package/dist/utils/pingtest.d.ts +0 -8
  104. package/dist/utils/sse.d.ts +0 -24
  105. package/dist/utils/types.d.ts +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modrinth/api-client",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "An API client for Modrinth's API for use in nuxt, tauri and plain node/browser environments.",
5
5
  "license": "LGPL-3.0-only",
6
6
  "type": "module",
@@ -37,9 +37,11 @@
37
37
  "ofetch": "^1.4.1"
38
38
  },
39
39
  "devDependencies": {
40
+ "@microsoft/api-extractor": "^7.58.9",
40
41
  "@tauri-apps/plugin-http": "^2.0.0",
41
42
  "esbuild": "0.27.2",
42
43
  "typescript": "^5.9.3",
44
+ "unplugin-dts": "^1.0.3",
43
45
  "@modrinth/tooling-config": "0.0.0"
44
46
  },
45
47
  "peerDependencies": {
@@ -52,7 +54,7 @@
52
54
  },
53
55
  "scripts": {
54
56
  "clean": "node --eval \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
55
- "build": "pnpm run clean && esbuild src/index.ts --bundle --format=esm --platform=neutral --target=es2020 --minify --legal-comments=none --outfile=dist/index.js --external:ofetch --external:mitt --external:@tauri-apps/plugin-http && tsc -p tsconfig.build.json",
57
+ "build": "pnpm run clean && node esbuild.config.mjs",
56
58
  "lint": "eslint . && prettier --check .",
57
59
  "fix": "eslint . --fix && prettier --write ."
58
60
  }
@@ -1,163 +0,0 @@
1
- import type { InferredClientModules } from '../modules';
2
- import type { BaseUrlConfig, ClientConfig } from '../types/client';
3
- import type { RequestContext, RequestOptions } from '../types/request';
4
- import type { UploadProgress, UploadRequestOptions } from '../types/upload';
5
- import type { AbstractFeature } from './abstract-feature';
6
- import type { AbstractSyncClient } from './abstract-sync';
7
- import { AbstractUploadClient } from './abstract-upload-client';
8
- import type { AbstractWebSocketClient } from './abstract-websocket';
9
- import { ModrinthApiError } from './errors';
10
- type ArchonClientModules = Omit<InferredClientModules['archon'], 'backups_v1'> & {
11
- /** @deprecated Use `backups_queue_v1` for the Backups Queue API. */
12
- backups_v1: InferredClientModules['archon']['backups_v1'];
13
- };
14
- /**
15
- * Abstract base client for Modrinth APIs
16
- */
17
- export declare abstract class AbstractModrinthClient extends AbstractUploadClient {
18
- protected config: ClientConfig;
19
- protected features: AbstractFeature[];
20
- /**
21
- * Maps full module ID (e.g., 'labrinth_projects_v2') to instantiated module
22
- */
23
- private _moduleInstances;
24
- /**
25
- * Maps API name (e.g., 'labrinth') to namespace object
26
- */
27
- private _moduleNamespaces;
28
- readonly labrinth: InferredClientModules['labrinth'];
29
- readonly archon: ArchonClientModules & {
30
- sockets: AbstractWebSocketClient;
31
- sync: AbstractSyncClient;
32
- };
33
- readonly kyros: InferredClientModules['kyros'];
34
- readonly iso3166: InferredClientModules['iso3166'];
35
- readonly mclogs: InferredClientModules['mclogs'];
36
- readonly launchermeta: InferredClientModules['launchermeta'];
37
- readonly paper: InferredClientModules['paper'];
38
- readonly purpur: InferredClientModules['purpur'];
39
- constructor(config: ClientConfig);
40
- /**
41
- * This creates the nested API structure (e.g., client.labrinth.projects_v2)
42
- * but doesn't instantiate modules until first access
43
- *
44
- * Module IDs in the registry are validated at runtime to ensure they match
45
- * what the module declares via getModuleID().
46
- */
47
- private initializeModules;
48
- /**
49
- * Make a request to the API
50
- *
51
- * @param path - API path (e.g., '/project/sodium')
52
- * @param options - Request options
53
- * @returns Promise resolving to the response data
54
- * @throws {ModrinthApiError} When the request fails or features throw errors
55
- */
56
- request<T>(path: string, options: RequestOptions): Promise<T>;
57
- stream(path: string, options: RequestOptions): Promise<ReadableStream<Uint8Array>>;
58
- /**
59
- * Execute the feature chain and the actual request
60
- *
61
- * Features are executed in order, with each feature calling next() to continue.
62
- * The last "feature" in the chain is the actual request execution.
63
- */
64
- protected executeFeatureChain<T>(context: RequestContext, executeTerminal?: () => Promise<T>): Promise<T>;
65
- /**
66
- * Execute the feature chain for an upload
67
- *
68
- * Similar to executeFeatureChain but calls executeXHRUpload at the end.
69
- * This allows features (auth, retry, etc.) to wrap the upload execution.
70
- */
71
- protected executeUploadFeatureChain<T>(context: RequestContext, progressCallbacks: Array<(p: UploadProgress) => void>, abortController: AbortController): Promise<T>;
72
- /**
73
- * Build the full URL for a request
74
- */
75
- protected buildUrl(path: string, baseUrl: string, version: number | 'internal' | string): string;
76
- protected resolveBaseUrl(baseUrl: BaseUrlConfig): string;
77
- /**
78
- * Build the request context
79
- */
80
- protected buildContext(url: string, path: string, options: RequestOptions): RequestContext;
81
- /**
82
- * Build context for an upload request
83
- *
84
- * Sets metadata.isUpload = true so features can detect uploads.
85
- * Supports both single file uploads and FormData uploads.
86
- */
87
- protected buildUploadContext(url: string, path: string, options: UploadRequestOptions): RequestContext;
88
- /**
89
- * Build default headers for all requests
90
- *
91
- * Subclasses can override this to add platform-specific headers
92
- * (e.g., Nuxt rate limit key)
93
- */
94
- protected buildDefaultHeaders(): Promise<Record<string, string>>;
95
- private resolveUserAgent;
96
- protected attachArchonSentryCaptureHeader(options: RequestOptions): void;
97
- private shouldCaptureArchonRequests;
98
- /**
99
- * Execute the actual HTTP request
100
- *
101
- * This must be implemented by platform-specific clients.
102
- *
103
- * @param url - Full URL to request
104
- * @param options - Request options
105
- * @returns Promise resolving to the response data
106
- * @throws {Error} Platform-specific errors that will be normalized by normalizeError()
107
- */
108
- protected abstract executeRequest<T>(url: string, options: RequestOptions): Promise<T>;
109
- protected abstract executeStreamRequest(url: string, options: RequestOptions): Promise<ReadableStream<Uint8Array>>;
110
- /**
111
- * Execute the actual XHR upload
112
- *
113
- * This must be implemented by platform clients that support uploads.
114
- * Called at the end of the upload feature chain.
115
- *
116
- * @param context - Request context with upload metadata
117
- * @param progressCallbacks - Callbacks to invoke on progress events
118
- * @param abortController - Controller for cancellation
119
- * @returns Promise resolving to the response data
120
- */
121
- protected abstract executeXHRUpload<T>(context: RequestContext, progressCallbacks: Array<(p: UploadProgress) => void>, abortController: AbortController): Promise<T>;
122
- /**
123
- * Normalize an error into a ModrinthApiError
124
- *
125
- * Platform implementations should override this to handle platform-specific errors
126
- * (e.g., FetchError from ofetch, Tauri HTTP errors)
127
- */
128
- protected normalizeError(error: unknown, context?: RequestContext): ModrinthApiError;
129
- /**
130
- * Helper to create a normalized error from extracted status code and response data
131
- */
132
- protected createNormalizedError(error: Error, statusCode: number | undefined, responseData: unknown): ModrinthApiError;
133
- /**
134
- * Add a feature to this client
135
- *
136
- * Features are executed in the order they are added.
137
- *
138
- * @example
139
- * ```typescript
140
- * const client = new GenericModrinthClient()
141
- * client.addFeature(new AuthFeature({ token: async () => getOAuthToken() }))
142
- * client.addFeature(new RetryFeature({ maxAttempts: 3 }))
143
- * ```
144
- */
145
- addFeature(feature: AbstractFeature): this;
146
- /**
147
- * Remove a feature from this client
148
- *
149
- * @example
150
- * ```typescript
151
- * const retryFeature = new RetryFeature({ maxAttempts: 3 })
152
- * client.addFeature(retryFeature)
153
- * // Later, remove it
154
- * client.removeFeature(retryFeature)
155
- * ```
156
- */
157
- removeFeature(feature: AbstractFeature): this;
158
- /**
159
- * Get all features on this client
160
- */
161
- getFeatures(): AbstractFeature[];
162
- }
163
- export {};
@@ -1,72 +0,0 @@
1
- import type { RequestContext } from '../types/request';
2
- /**
3
- * Base configuration for features
4
- */
5
- export interface FeatureConfig {
6
- /**
7
- * Optional name for this feature (for debugging)
8
- */
9
- name?: string;
10
- /**
11
- * Whether this feature is enabled
12
- * @default true
13
- */
14
- enabled?: boolean;
15
- }
16
- /**
17
- * Abstract base class for request features
18
- *
19
- * Features are composable middleware that can intercept and modify requests.
20
- * They are executed in a chain, with each feature calling next() to continue the chain.
21
- */
22
- export declare abstract class AbstractFeature {
23
- protected config: FeatureConfig;
24
- constructor(config?: FeatureConfig);
25
- /**
26
- * Execute the feature logic
27
- *
28
- * @param next - Function to call the next feature in the chain (or the actual request)
29
- * @param context - Full request context
30
- * @returns Promise resolving to the response data
31
- *
32
- * @example
33
- * ```typescript
34
- * async execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T> {
35
- * // Do something before request
36
- * console.log('Before request:', context.url)
37
- *
38
- * try {
39
- * const result = await next()
40
- *
41
- * // Do something after successful request
42
- * console.log('Request succeeded')
43
- *
44
- * return result
45
- * } catch (error) {
46
- * // Handle errors
47
- * console.error('Request failed:', error)
48
- * throw error
49
- * }
50
- * }
51
- * ```
52
- */
53
- abstract execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T>;
54
- /**
55
- * Determine if this feature should apply to the given request
56
- *
57
- * By default, features apply if they are enabled.
58
- * Override this to add custom logic (e.g., only apply to GET requests).
59
- *
60
- * @param context - Request context
61
- * @returns true if the feature should execute, false to skip
62
- */
63
- shouldApply(_context: RequestContext): boolean;
64
- /**
65
- * Get the name of this feature (for debugging)
66
- */
67
- get name(): string;
68
- /**
69
- * Check if this feature is enabled
70
- */
71
- get enabled(): boolean;
72
- }
@@ -1,10 +0,0 @@
1
- import type { AbstractModrinthClient } from './abstract-client';
2
- export declare abstract class AbstractModule {
3
- protected client: AbstractModrinthClient;
4
- constructor(client: AbstractModrinthClient);
5
- /**
6
- * Get the module's name, used for error reporting & for module field generation.
7
- * @returns Module name
8
- */
9
- abstract getModuleID(): string;
10
- }
@@ -1,61 +0,0 @@
1
- import type mitt from 'mitt';
2
- import type { Archon } from '../modules/archon/types';
3
- import type { RequestOptions } from '../types/request';
4
- export type SyncEventType = Archon.Sync.v1.SyncEvent['type'];
5
- export type SyncEventOfType<E extends SyncEventType> = Extract<Archon.Sync.v1.SyncEvent, {
6
- type: E;
7
- }>;
8
- export type SyncEventHandler<E extends Archon.Sync.v1.SyncEvent = Archon.Sync.v1.SyncEvent> = (event: E) => void;
9
- export type SyncStatusState = 'idle' | 'connecting' | 'connected' | 'reconnecting' | 'disconnected' | 'error';
10
- export type SyncStatus = {
11
- state: SyncStatusState;
12
- connected: boolean;
13
- reconnecting: boolean;
14
- reconnectAttempts: number;
15
- retryDelay: number;
16
- lastEventId?: string;
17
- error?: unknown;
18
- };
19
- export type SyncStatusHandler = (status: SyncStatus) => void;
20
- export type SyncConnectOptions = {
21
- intent?: Archon.Sync.v1.SyncIntent;
22
- force?: boolean;
23
- };
24
- export type SyncConnection = {
25
- serverId: string;
26
- intent: Archon.Sync.v1.SyncIntent;
27
- controller?: AbortController;
28
- reconnectAttempts: number;
29
- reconnectTimer?: ReturnType<typeof setTimeout>;
30
- reconnectResolve?: () => void;
31
- retryDelay: number;
32
- lastEventId?: string;
33
- stopped: boolean;
34
- status: SyncStatusState;
35
- error?: unknown;
36
- };
37
- export type SyncEmitterEvents = Record<string, unknown>;
38
- export declare abstract class AbstractSyncClient {
39
- protected client: {
40
- stream: (path: string, options: RequestOptions) => Promise<ReadableStream<Uint8Array>>;
41
- };
42
- protected connections: Map<string, SyncConnection>;
43
- protected abstract emitter: ReturnType<typeof mitt<SyncEmitterEvents>>;
44
- constructor(client: {
45
- stream: (path: string, options: RequestOptions) => Promise<ReadableStream<Uint8Array>>;
46
- });
47
- abstract safeConnectServer(serverId: string, options?: SyncConnectOptions): Promise<void>;
48
- abstract disconnect(serverId: string): void;
49
- abstract disconnectAll(): void;
50
- on<E extends SyncEventType>(serverId: string, eventType: E, handler: SyncEventHandler<SyncEventOfType<E>>): () => void;
51
- onAny(serverId: string, handler: SyncEventHandler): () => void;
52
- onStatus(serverId: string, handler: SyncStatusHandler): () => void;
53
- getStatus(serverId: string): SyncStatus | null;
54
- protected emitSyncEvent(serverId: string, event: Archon.Sync.v1.SyncEvent): void;
55
- protected updateStatus(connection: SyncConnection, status: SyncStatusState, error?: unknown): void;
56
- protected clearListeners(serverId: string): void;
57
- protected connectionToStatus(connection: SyncConnection): SyncStatus;
58
- private getEventKey;
59
- private getAnyEventKey;
60
- private getStatusEventKey;
61
- }
@@ -1,20 +0,0 @@
1
- import type { UploadHandle, UploadRequestOptions } from '../types/upload';
2
- /**
3
- * Abstract base class defining upload capability
4
- *
5
- * All clients that support file uploads must extend this class.
6
- * Platform-specific implementations should provide the actual upload mechanism
7
- * (e.g., XHR for browser environments).
8
- *
9
- * Upload goes through the feature chain (auth, retry, circuit-breaker, etc.)
10
- * just like regular requests.
11
- */
12
- export declare abstract class AbstractUploadClient {
13
- /**
14
- * Upload a file or FormData with progress tracking
15
- * @param path - API path (e.g., '/fs/create')
16
- * @param options - Upload options including file or formData, api, version
17
- * @returns UploadHandle with promise, onProgress chain, and cancel method
18
- */
19
- abstract upload<T = void>(path: string, options: UploadRequestOptions): UploadHandle<T>;
20
- }
@@ -1,52 +0,0 @@
1
- import type mitt from 'mitt';
2
- import type { Archon } from '../modules/archon/types';
3
- export type WebSocketEventHandler<E extends Archon.Websocket.v0.WSEvent = Archon.Websocket.v0.WSEvent> = (event: E) => void;
4
- export interface WebSocketConnection {
5
- serverId: string;
6
- socket: WebSocket;
7
- reconnectAttempts: number;
8
- reconnectTimer?: ReturnType<typeof setTimeout>;
9
- isReconnecting: boolean;
10
- }
11
- export interface WebSocketStatus {
12
- connected: boolean;
13
- reconnecting: boolean;
14
- reconnectAttempts: number;
15
- }
16
- type WSEventMap = {
17
- [K in Archon.Websocket.v0.WSEvent as `${string}:${K['event']}`]: K;
18
- };
19
- export declare abstract class AbstractWebSocketClient {
20
- protected client: {
21
- archon: {
22
- servers_v0: {
23
- getWebSocketAuth: (serverId: string) => Promise<Archon.Websocket.v0.WSAuth>;
24
- };
25
- };
26
- };
27
- protected connections: Map<string, WebSocketConnection>;
28
- protected abstract emitter: ReturnType<typeof mitt<WSEventMap>>;
29
- protected readonly MAX_RECONNECT_ATTEMPTS = 10;
30
- protected readonly RECONNECT_BASE_DELAY = 1000;
31
- protected readonly RECONNECT_MAX_DELAY = 30000;
32
- constructor(client: {
33
- archon: {
34
- servers_v0: {
35
- getWebSocketAuth: (serverId: string) => Promise<Archon.Websocket.v0.WSAuth>;
36
- };
37
- };
38
- });
39
- abstract connect(serverId: string, auth: Archon.Websocket.v0.WSAuth): Promise<void>;
40
- abstract disconnect(serverId: string): void;
41
- abstract disconnectAll(): void;
42
- abstract send(serverId: string, message: Archon.Websocket.v0.WSOutgoingMessage): void;
43
- safeConnect(serverId: string, options?: {
44
- force?: boolean;
45
- }): Promise<void>;
46
- on<E extends Archon.Websocket.v0.WSEventType>(serverId: string, eventType: E, handler: WebSocketEventHandler<Extract<Archon.Websocket.v0.WSEvent, {
47
- event: E;
48
- }>>): () => void;
49
- getStatus(serverId: string): WebSocketStatus | null;
50
- protected getReconnectDelay(attempt: number): number;
51
- }
52
- export {};
@@ -1,48 +0,0 @@
1
- import type { ApiErrorData, ModrinthErrorResponse } from '../types/errors';
2
- /**
3
- * Base error class for all Modrinth API errors
4
- */
5
- export declare class ModrinthApiError extends Error {
6
- /**
7
- * HTTP status code (if available)
8
- */
9
- readonly statusCode?: number;
10
- /**
11
- * Original error that was caught
12
- */
13
- readonly originalError?: Error;
14
- /**
15
- * Response data from the API (if available)
16
- */
17
- readonly responseData?: unknown;
18
- /**
19
- * Error context (e.g., module name, operation being performed)
20
- */
21
- readonly context?: string;
22
- constructor(message: string, data?: ApiErrorData);
23
- /**
24
- * Create a ModrinthApiError from an unknown error
25
- */
26
- static fromUnknown(error: unknown, context?: string): ModrinthApiError;
27
- }
28
- /**
29
- * Error class for Modrinth server errors (kyros/archon)
30
- * Extends ModrinthApiError with V1 error response parsing
31
- */
32
- export declare class ModrinthServerError extends ModrinthApiError {
33
- /**
34
- * V1 error information (if available)
35
- */
36
- readonly v1Error?: ModrinthErrorResponse;
37
- constructor(message: string, data?: ApiErrorData & {
38
- v1Error?: ModrinthErrorResponse;
39
- });
40
- /**
41
- * Create a ModrinthServerError from response data
42
- */
43
- static fromResponse(statusCode: number, responseData: unknown, context?: string): ModrinthServerError;
44
- /**
45
- * Create a ModrinthServerError from an unknown error
46
- */
47
- static fromUnknown(error: unknown, context?: string): ModrinthServerError;
48
- }
@@ -1,47 +0,0 @@
1
- import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature';
2
- import type { RequestContext } from '../types/request';
3
- /**
4
- * Authentication feature configuration
5
- */
6
- export interface AuthConfig extends FeatureConfig {
7
- /**
8
- * Authentication token
9
- * - string: static token
10
- * - function: async function that returns token (useful for dynamic tokens)
11
- */
12
- token: string | (() => Promise<string | undefined>);
13
- /**
14
- * Token prefix (e.g., 'Bearer', 'Token')
15
- * @default 'Bearer'
16
- */
17
- tokenPrefix?: string;
18
- /**
19
- * Custom header name for the token
20
- * @default 'Authorization'
21
- */
22
- headerName?: string;
23
- }
24
- /**
25
- * Authentication feature
26
- *
27
- * Automatically injects authentication tokens into request headers.
28
- * Supports both static tokens and dynamic token providers.
29
- *
30
- * @example
31
- * ```typescript
32
- * const auth = new AuthFeature({
33
- * token: async () => process.env.MODRINTH_TOKEN
34
- * })
35
- * ```
36
- */
37
- export declare class AuthFeature extends AbstractFeature {
38
- protected config: AuthConfig;
39
- execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T>;
40
- shouldApply(context: RequestContext): boolean;
41
- /**
42
- * Get the authentication token
43
- *
44
- * Handles both static tokens and async token providers
45
- */
46
- private getToken;
47
- }
@@ -1,139 +0,0 @@
1
- import { AbstractFeature, type FeatureConfig } from '../core/abstract-feature';
2
- import type { RequestContext } from '../types/request';
3
- /**
4
- * Circuit breaker state
5
- */
6
- export type CircuitBreakerState = {
7
- /**
8
- * Number of consecutive failures
9
- */
10
- failures: number;
11
- /**
12
- * Timestamp of last failure
13
- */
14
- lastFailure: number;
15
- };
16
- /**
17
- * Circuit breaker storage interface
18
- */
19
- export interface CircuitBreakerStorage {
20
- /**
21
- * Get circuit breaker state for a key
22
- */
23
- get(key: string): CircuitBreakerState | undefined;
24
- /**
25
- * Set circuit breaker state for a key
26
- */
27
- set(key: string, state: CircuitBreakerState): void;
28
- /**
29
- * Clear circuit breaker state for a key
30
- */
31
- clear?(key: string): void;
32
- }
33
- /**
34
- * Circuit breaker feature configuration
35
- */
36
- export interface CircuitBreakerConfig extends FeatureConfig {
37
- /**
38
- * Maximum number of consecutive failures before opening circuit
39
- * @default 3
40
- */
41
- maxFailures?: number;
42
- /**
43
- * Time in milliseconds before circuit resets after opening
44
- * @default 30000
45
- */
46
- resetTimeout?: number;
47
- /**
48
- * HTTP status codes that count as failures
49
- * @default [500, 502, 503, 504]
50
- */
51
- failureStatusCodes?: number[];
52
- /**
53
- * Storage implementation for circuit state
54
- * If not provided, uses in-memory Map
55
- */
56
- storage?: CircuitBreakerStorage;
57
- /**
58
- * Function to generate circuit key from request context
59
- * By default, uses the base path (without query params)
60
- */
61
- getCircuitKey?: (url: string, method: string) => string;
62
- }
63
- /**
64
- * In-memory storage for circuit breaker state
65
- */
66
- export declare class InMemoryCircuitBreakerStorage implements CircuitBreakerStorage {
67
- private state;
68
- get(key: string): CircuitBreakerState | undefined;
69
- set(key: string, state: CircuitBreakerState): void;
70
- clear(key: string): void;
71
- }
72
- /**
73
- * Circuit breaker feature
74
- *
75
- * Prevents requests to failing endpoints by "opening the circuit" after
76
- * a threshold of consecutive failures. The circuit automatically resets
77
- * after a timeout period.
78
- *
79
- * This implements the circuit breaker pattern to prevent cascading failures
80
- * and give failing services time to recover.
81
- *
82
- * @example
83
- * ```typescript
84
- * const circuitBreaker = new CircuitBreakerFeature({
85
- * maxFailures: 3,
86
- * resetTimeout: 30000, // 30 seconds
87
- * failureStatusCodes: [500, 502, 503, 504]
88
- * })
89
- * ```
90
- */
91
- export declare class CircuitBreakerFeature extends AbstractFeature {
92
- protected config: Required<CircuitBreakerConfig>;
93
- private storage;
94
- constructor(config?: CircuitBreakerConfig);
95
- execute<T>(next: () => Promise<T>, context: RequestContext): Promise<T>;
96
- shouldApply(context: RequestContext): boolean;
97
- /**
98
- * Get the circuit key for a request
99
- *
100
- * By default, uses the path and method to identify unique circuits
101
- */
102
- private getCircuitKey;
103
- /**
104
- * Check if the circuit is open for a given key
105
- */
106
- private isCircuitOpen;
107
- /**
108
- * Record a successful request
109
- */
110
- private recordSuccess;
111
- /**
112
- * Record a failed request
113
- */
114
- private recordFailure;
115
- /**
116
- * Determine if an error should count as a circuit failure
117
- */
118
- private isFailureError;
119
- /**
120
- * Get current circuit state for debugging
121
- *
122
- * @example
123
- * ```typescript
124
- * const state = circuitBreaker.getCircuitState('GET_/v2/project/sodium')
125
- * console.log(`Failures: ${state?.failures}, Last failure: ${state?.lastFailure}`)
126
- * ```
127
- */
128
- getCircuitState(key: string): CircuitBreakerState | undefined;
129
- /**
130
- * Manually reset a circuit
131
- *
132
- * @example
133
- * ```typescript
134
- * // Reset circuit after manual intervention
135
- * circuitBreaker.resetCircuit('GET_/v2/project/sodium')
136
- * ```
137
- */
138
- resetCircuit(key: string): void;
139
- }