@modrinth/api-client 0.30.0 → 0.32.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 +7103 -28
- package/dist/index.js +1 -0
- package/dist/index.js.map +7 -0
- package/package.json +4 -2
- package/dist/core/abstract-client.d.ts +0 -163
- package/dist/core/abstract-feature.d.ts +0 -72
- package/dist/core/abstract-module.d.ts +0 -10
- package/dist/core/abstract-sync.d.ts +0 -61
- package/dist/core/abstract-upload-client.d.ts +0 -20
- package/dist/core/abstract-websocket.d.ts +0 -52
- package/dist/core/errors.d.ts +0 -48
- package/dist/features/auth.d.ts +0 -47
- package/dist/features/circuit-breaker.d.ts +0 -139
- package/dist/features/node-auth.d.ts +0 -58
- package/dist/features/panel-version.d.ts +0 -7
- package/dist/features/retry.d.ts +0 -87
- package/dist/features/verbose-logging.d.ts +0 -6
- package/dist/modules/archon/actions/v1.d.ts +0 -10
- package/dist/modules/archon/backups/v1.d.ts +0 -44
- package/dist/modules/archon/backups-queue/v1.d.ts +0 -25
- package/dist/modules/archon/content/v1.d.ts +0 -48
- package/dist/modules/archon/index.d.ts +0 -8
- package/dist/modules/archon/nodes/internal.d.ts +0 -10
- package/dist/modules/archon/notices/v0.d.ts +0 -38
- package/dist/modules/archon/options/v1.d.ts +0 -9
- package/dist/modules/archon/properties/v1.d.ts +0 -9
- package/dist/modules/archon/server-users/v1.d.ts +0 -30
- package/dist/modules/archon/servers/v0.d.ts +0 -122
- package/dist/modules/archon/servers/v1.d.ts +0 -30
- package/dist/modules/archon/transfers/internal.d.ts +0 -25
- package/dist/modules/archon/types.d.ts +0 -941
- package/dist/modules/index.d.ts +0 -181
- package/dist/modules/iso3166/index.d.ts +0 -24
- package/dist/modules/iso3166/types.d.ts +0 -21
- package/dist/modules/kyros/content/v1.d.ts +0 -23
- package/dist/modules/kyros/files/v0.d.ts +0 -123
- package/dist/modules/kyros/logs/v1.d.ts +0 -6
- package/dist/modules/kyros/types.d.ts +0 -44
- package/dist/modules/kyros/upload-sessions/v1.d.ts +0 -18
- package/dist/modules/labrinth/affiliate/internal.d.ts +0 -30
- package/dist/modules/labrinth/analytics/v3.d.ts +0 -56
- package/dist/modules/labrinth/attribution/internal.d.ts +0 -47
- package/dist/modules/labrinth/auth/internal.d.ts +0 -19
- package/dist/modules/labrinth/auth/v2.d.ts +0 -98
- package/dist/modules/labrinth/billing/internal.d.ts +0 -65
- package/dist/modules/labrinth/campaign/internal.d.ts +0 -10
- package/dist/modules/labrinth/collections.d.ts +0 -80
- package/dist/modules/labrinth/content/v3.d.ts +0 -6
- package/dist/modules/labrinth/external-projects/internal.d.ts +0 -9
- package/dist/modules/labrinth/friends/v3.d.ts +0 -23
- package/dist/modules/labrinth/globals/internal.d.ts +0 -11
- package/dist/modules/labrinth/images/v3.d.ts +0 -7
- package/dist/modules/labrinth/index.d.ts +0 -31
- package/dist/modules/labrinth/limits/v3.d.ts +0 -17
- package/dist/modules/labrinth/moderation/internal.d.ts +0 -12
- package/dist/modules/labrinth/notifications/v2.d.ts +0 -73
- package/dist/modules/labrinth/oauth/internal.d.ts +0 -97
- package/dist/modules/labrinth/organizations/v3.d.ts +0 -66
- package/dist/modules/labrinth/pats/v2.d.ts +0 -31
- package/dist/modules/labrinth/payout/v3.d.ts +0 -30
- package/dist/modules/labrinth/payouts/v3.d.ts +0 -15
- package/dist/modules/labrinth/projects/v2.d.ts +0 -169
- package/dist/modules/labrinth/projects/v3.d.ts +0 -110
- package/dist/modules/labrinth/reports/v3.d.ts +0 -81
- package/dist/modules/labrinth/server-ping/internal.d.ts +0 -10
- package/dist/modules/labrinth/sessions/v2.d.ts +0 -17
- package/dist/modules/labrinth/state/index.d.ts +0 -17
- package/dist/modules/labrinth/tags/v2.d.ts +0 -19
- package/dist/modules/labrinth/teams/v2.d.ts +0 -57
- package/dist/modules/labrinth/teams/v3.d.ts +0 -18
- package/dist/modules/labrinth/tech-review/internal.d.ts +0 -77
- package/dist/modules/labrinth/threads/v3.d.ts +0 -57
- package/dist/modules/labrinth/types.d.ts +0 -2118
- package/dist/modules/labrinth/users/v2.d.ts +0 -101
- package/dist/modules/labrinth/users/v3.d.ts +0 -37
- package/dist/modules/labrinth/versions/v2.d.ts +0 -75
- package/dist/modules/labrinth/versions/v3.d.ts +0 -123
- package/dist/modules/launcher-meta/types.d.ts +0 -25
- package/dist/modules/launcher-meta/v0.d.ts +0 -17
- package/dist/modules/mclogs/insights/v1.d.ts +0 -6
- package/dist/modules/mclogs/logs/v1.d.ts +0 -6
- package/dist/modules/mclogs/types.d.ts +0 -60
- package/dist/modules/paper/types.d.ts +0 -22
- package/dist/modules/paper/v3.d.ts +0 -19
- package/dist/modules/purpur/types.d.ts +0 -15
- package/dist/modules/purpur/v2.d.ts +0 -16
- package/dist/modules/types.d.ts +0 -8
- package/dist/platform/generic.d.ts +0 -28
- package/dist/platform/nuxt.d.ts +0 -88
- package/dist/platform/sync-generic.d.ts +0 -16
- package/dist/platform/tauri.d.ts +0 -35
- package/dist/platform/websocket-generic.d.ts +0 -16
- package/dist/platform/xhr-upload-client.d.ts +0 -15
- package/dist/state/node-auth.d.ts +0 -36
- package/dist/types/client.d.ts +0 -70
- package/dist/types/errors.d.ts +0 -43
- package/dist/types/index.d.ts +0 -10
- package/dist/types/request.d.ts +0 -124
- package/dist/types/upload.d.ts +0 -92
- package/dist/utils/fetch.d.ts +0 -4
- package/dist/utils/jwt-retry.d.ts +0 -5
- package/dist/utils/node-url.d.ts +0 -2
- package/dist/utils/pingtest.d.ts +0 -8
- package/dist/utils/sse.d.ts +0 -24
- 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.
|
|
3
|
+
"version": "0.32.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
|
|
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 {};
|
package/dist/core/errors.d.ts
DELETED
|
@@ -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
|
-
}
|
package/dist/features/auth.d.ts
DELETED
|
@@ -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
|
-
}
|