@frp-bridge/core 0.0.3 → 0.0.4
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 +1288 -756
- package/dist/index.js +258 -0
- package/package.json +7 -11
- package/dist/index.d.mts +0 -1216
- package/dist/index.mjs +0 -8
package/dist/index.d.mts
DELETED
|
@@ -1,1216 +0,0 @@
|
|
|
1
|
-
import { NodeRegisterPayload, NodeHeartbeatPayload, NodeInfo as NodeInfo$1, NodeListQuery, NodeListResponse, NodeStatistics, TunnelSyncPayload, ProxyConfig, ClientConfig, ServerConfig, RpcRequest as RpcRequest$1 } from '@frp-bridge/types';
|
|
2
|
-
import { EventEmitter } from 'node:events';
|
|
3
|
-
|
|
4
|
-
type Awaitable<T> = T | Promise<T>;
|
|
5
|
-
type RuntimeMode = 'client' | 'server';
|
|
6
|
-
type RuntimeStatus = 'idle' | 'starting' | 'running' | 'stopping' | 'error';
|
|
7
|
-
interface RuntimeContext {
|
|
8
|
-
id: string;
|
|
9
|
-
mode: RuntimeMode;
|
|
10
|
-
workDir: string;
|
|
11
|
-
platform: string;
|
|
12
|
-
clock?: () => number;
|
|
13
|
-
logger?: RuntimeLogger;
|
|
14
|
-
}
|
|
15
|
-
interface RuntimeLogger {
|
|
16
|
-
debug: (message: string, context?: Record<string, unknown>) => void;
|
|
17
|
-
info: (message: string, context?: Record<string, unknown>) => void;
|
|
18
|
-
warn: (message: string, context?: Record<string, unknown>) => void;
|
|
19
|
-
error: (message: string, context?: Record<string, unknown>) => void;
|
|
20
|
-
}
|
|
21
|
-
interface RuntimeState {
|
|
22
|
-
status: RuntimeStatus;
|
|
23
|
-
version: number;
|
|
24
|
-
lastAppliedAt?: number;
|
|
25
|
-
lastError?: RuntimeError;
|
|
26
|
-
}
|
|
27
|
-
interface CommandMetadata {
|
|
28
|
-
requestId?: string;
|
|
29
|
-
correlationId?: string;
|
|
30
|
-
author?: string;
|
|
31
|
-
issuedAt?: number;
|
|
32
|
-
}
|
|
33
|
-
interface RuntimeCommand<TPayload = unknown> {
|
|
34
|
-
name: string;
|
|
35
|
-
payload: TPayload;
|
|
36
|
-
metadata?: CommandMetadata;
|
|
37
|
-
}
|
|
38
|
-
interface CommandResult<TResult = unknown> {
|
|
39
|
-
status: CommandStatus;
|
|
40
|
-
version?: number;
|
|
41
|
-
events?: RuntimeEvent[];
|
|
42
|
-
result?: TResult;
|
|
43
|
-
error?: RuntimeError;
|
|
44
|
-
snapshot?: ConfigSnapshot;
|
|
45
|
-
}
|
|
46
|
-
type CommandStatus = 'success' | 'failed' | 'pending';
|
|
47
|
-
interface RuntimeQuery<TPayload = unknown> {
|
|
48
|
-
name: string;
|
|
49
|
-
payload?: TPayload;
|
|
50
|
-
}
|
|
51
|
-
interface QueryResult<TResult = unknown> {
|
|
52
|
-
result: TResult;
|
|
53
|
-
version: number;
|
|
54
|
-
}
|
|
55
|
-
interface RuntimeEvent<TPayload = unknown> {
|
|
56
|
-
type: string;
|
|
57
|
-
timestamp: number;
|
|
58
|
-
version?: number;
|
|
59
|
-
payload?: TPayload;
|
|
60
|
-
}
|
|
61
|
-
interface RuntimeError {
|
|
62
|
-
code: RuntimeErrorCode;
|
|
63
|
-
message: string;
|
|
64
|
-
details?: Record<string, unknown>;
|
|
65
|
-
}
|
|
66
|
-
type RuntimeErrorCode = 'VALIDATION_ERROR' | 'RUNTIME_ERROR' | 'SYSTEM_ERROR' | 'PORT_CONFLICT' | 'RPC_NOT_AVAILABLE' | 'RPC_ERROR';
|
|
67
|
-
interface ConfigSnapshot {
|
|
68
|
-
version: number;
|
|
69
|
-
checksum: string;
|
|
70
|
-
appliedAt: number;
|
|
71
|
-
author?: string;
|
|
72
|
-
summary?: string;
|
|
73
|
-
}
|
|
74
|
-
interface SnapshotStorage {
|
|
75
|
-
save: (snapshot: ConfigSnapshot) => Awaitable<void>;
|
|
76
|
-
load: (version: number) => Awaitable<ConfigSnapshot | undefined>;
|
|
77
|
-
list: () => Awaitable<ConfigSnapshot[]>;
|
|
78
|
-
}
|
|
79
|
-
interface CommandHandlerContext {
|
|
80
|
-
context: RuntimeContext;
|
|
81
|
-
state: RuntimeState;
|
|
82
|
-
emit: (events: RuntimeEvent[]) => void;
|
|
83
|
-
requestVersionBump: () => number;
|
|
84
|
-
}
|
|
85
|
-
type CommandHandler<TPayload = unknown, TResult = unknown> = (command: RuntimeCommand<TPayload>, ctx: CommandHandlerContext) => Awaitable<CommandResult<TResult>>;
|
|
86
|
-
type QueryHandler<TPayload = unknown, TResult = unknown> = (query: RuntimeQuery<TPayload>, ctx: RuntimeContext) => Awaitable<QueryResult<TResult>>;
|
|
87
|
-
interface RuntimeAdapters {
|
|
88
|
-
storage?: SnapshotStorage;
|
|
89
|
-
commands?: Record<string, CommandHandler>;
|
|
90
|
-
queries?: Record<string, QueryHandler>;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
declare class FrpRuntime {
|
|
94
|
-
private readonly context;
|
|
95
|
-
private readonly storage?;
|
|
96
|
-
private readonly commandHandlers;
|
|
97
|
-
private readonly queryHandlers;
|
|
98
|
-
private eventBuffer;
|
|
99
|
-
private commandQueue;
|
|
100
|
-
private state;
|
|
101
|
-
constructor(context: RuntimeContext, adapters?: RuntimeAdapters);
|
|
102
|
-
registerCommand(name: string, handler: CommandHandler): void;
|
|
103
|
-
registerQuery(name: string, handler: QueryHandler): void;
|
|
104
|
-
execute<TPayload, TResult = unknown>(command: RuntimeCommand<TPayload>): Promise<CommandResult<TResult>>;
|
|
105
|
-
query<TPayload, TResult = unknown>(query: RuntimeQuery<TPayload>): Promise<QueryResult<TResult>>;
|
|
106
|
-
snapshot(): RuntimeState;
|
|
107
|
-
drainEvents(): RuntimeEvent[];
|
|
108
|
-
private runCommand;
|
|
109
|
-
private pushEvents;
|
|
110
|
-
private bumpVersion;
|
|
111
|
-
private persistSnapshot;
|
|
112
|
-
private normalizeError;
|
|
113
|
-
private buildError;
|
|
114
|
-
private now;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Client-side node information collector
|
|
119
|
-
* Gathers system information and reports to server via heartbeat
|
|
120
|
-
*/
|
|
121
|
-
|
|
122
|
-
interface ClientCollectorOptions {
|
|
123
|
-
/** Node ID (set by server after registration) */
|
|
124
|
-
nodeId?: string;
|
|
125
|
-
/** Heartbeat interval in milliseconds (default: 30000) */
|
|
126
|
-
heartbeatInterval?: number;
|
|
127
|
-
/** Logger instance */
|
|
128
|
-
logger?: {
|
|
129
|
-
debug?: (msg: string, data?: unknown) => void;
|
|
130
|
-
info?: (msg: string, data?: unknown) => void;
|
|
131
|
-
error?: (msg: string, error?: unknown) => void;
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Collects node information on client side
|
|
136
|
-
* Used in client mode to send system info and heartbeat to server
|
|
137
|
-
*/
|
|
138
|
-
declare class ClientNodeCollector {
|
|
139
|
-
private nodeId?;
|
|
140
|
-
private heartbeatInterval;
|
|
141
|
-
private logger;
|
|
142
|
-
private heartbeatTimer?;
|
|
143
|
-
constructor(options?: ClientCollectorOptions);
|
|
144
|
-
/** Set node ID after server registration */
|
|
145
|
-
setNodeId(nodeId: string): void;
|
|
146
|
-
/** Collect current node information */
|
|
147
|
-
collectNodeInfo(): Partial<NodeRegisterPayload>;
|
|
148
|
-
/** Collect heartbeat payload */
|
|
149
|
-
collectHeartbeat(): Partial<NodeHeartbeatPayload>;
|
|
150
|
-
/**
|
|
151
|
-
* Start periodic heartbeat collection
|
|
152
|
-
* Callback will be called at each interval with heartbeat payload
|
|
153
|
-
*/
|
|
154
|
-
startHeartbeat(callback: (payload: Partial<NodeHeartbeatPayload>) => void, interval?: number): void;
|
|
155
|
-
/** Stop periodic heartbeat collection */
|
|
156
|
-
stopHeartbeat(): void;
|
|
157
|
-
/** Check if heartbeat is running */
|
|
158
|
-
isHeartbeatRunning(): boolean;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Node Manager for server-side node management
|
|
163
|
-
* Handles node registration, heartbeat, tunnel registry, and queries
|
|
164
|
-
*/
|
|
165
|
-
|
|
166
|
-
interface NodeManagerOptions {
|
|
167
|
-
heartbeatTimeout?: number;
|
|
168
|
-
logger?: Partial<RuntimeLogger>;
|
|
169
|
-
}
|
|
170
|
-
interface NodeStorage {
|
|
171
|
-
save: (node: NodeInfo$1) => Promise<void> | void;
|
|
172
|
-
delete: (id: string) => Promise<void> | void;
|
|
173
|
-
load: (id: string) => Promise<NodeInfo$1 | undefined> | NodeInfo$1 | undefined;
|
|
174
|
-
list: () => Promise<NodeInfo$1[]> | NodeInfo$1[];
|
|
175
|
-
}
|
|
176
|
-
type NodeEvent = 'node:registered' | 'node:heartbeat' | 'node:unregistered' | 'node:statusChanged' | 'tunnel:synced';
|
|
177
|
-
/**
|
|
178
|
-
* Manages nodes in server mode
|
|
179
|
-
* Stores node info, handles heartbeat, manages global tunnel registry, emits events
|
|
180
|
-
*/
|
|
181
|
-
declare class NodeManager extends EventEmitter {
|
|
182
|
-
private context;
|
|
183
|
-
private nodes;
|
|
184
|
-
private heartbeatTimers;
|
|
185
|
-
private tunnelRegistry;
|
|
186
|
-
private storage?;
|
|
187
|
-
private heartbeatTimeout;
|
|
188
|
-
private readonly log;
|
|
189
|
-
constructor(context: RuntimeContext, options?: NodeManagerOptions, storage?: NodeStorage);
|
|
190
|
-
initialize(): Promise<void>;
|
|
191
|
-
/** Register a new node (called when client connects) */
|
|
192
|
-
registerNode(payload: NodeRegisterPayload): Promise<NodeInfo$1>;
|
|
193
|
-
/** Update node heartbeat and status */
|
|
194
|
-
updateHeartbeat(payload: NodeHeartbeatPayload): Promise<void>;
|
|
195
|
-
/** Unregister a node (called when client disconnects) */
|
|
196
|
-
unregisterNode(nodeId: string): Promise<void>;
|
|
197
|
-
/** Get node by id */
|
|
198
|
-
getNode(id: string): Promise<NodeInfo$1 | undefined>;
|
|
199
|
-
/** List nodes with pagination and filtering */
|
|
200
|
-
listNodes(query?: NodeListQuery): Promise<NodeListResponse>;
|
|
201
|
-
/** Get node statistics */
|
|
202
|
-
getStatistics(): Promise<NodeStatistics>;
|
|
203
|
-
/** Check if node exists */
|
|
204
|
-
hasNode(id: string): boolean;
|
|
205
|
-
/** Get all online nodes */
|
|
206
|
-
getOnlineNodes(): NodeInfo$1[];
|
|
207
|
-
/** Get all offline nodes */
|
|
208
|
-
getOfflineNodes(): NodeInfo$1[];
|
|
209
|
-
/** Get nodes by status */
|
|
210
|
-
getNodesByStatus(status: NodeInfo$1['status']): NodeInfo$1[];
|
|
211
|
-
/** Setup heartbeat timer for a node */
|
|
212
|
-
private setupHeartbeatTimer;
|
|
213
|
-
/** Clear heartbeat timer for a node */
|
|
214
|
-
private clearHeartbeatTimer;
|
|
215
|
-
/** Handle heartbeat timeout */
|
|
216
|
-
private handleHeartbeatTimeout;
|
|
217
|
-
/** Sync tunnels for a node (called when node connects or updates tunnels) */
|
|
218
|
-
syncTunnels(payload: TunnelSyncPayload): Promise<void>;
|
|
219
|
-
/** Get tunnels for a specific node */
|
|
220
|
-
getNodeTunnels(nodeId: string): ProxyConfig[];
|
|
221
|
-
/** Get all tunnels across all nodes */
|
|
222
|
-
getAllTunnels(): Map<string, ProxyConfig[]>;
|
|
223
|
-
/** Check if a remotePort is in use across all nodes (for conflict detection) */
|
|
224
|
-
isRemotePortInUse(remotePort: number, excludeNodeId?: string): {
|
|
225
|
-
inUse: boolean;
|
|
226
|
-
nodeId?: string;
|
|
227
|
-
tunnelName?: string;
|
|
228
|
-
};
|
|
229
|
-
/** Clear tunnels for a node (called when node disconnects) */
|
|
230
|
-
private clearNodeTunnels;
|
|
231
|
-
/** Update dispose method to clear tunnels */
|
|
232
|
-
dispose(): Promise<void>;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
/**
|
|
236
|
-
* File-based node storage implementation
|
|
237
|
-
* Persists node information to disk
|
|
238
|
-
*/
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Stores nodes in JSON files
|
|
242
|
-
* Directory structure:
|
|
243
|
-
* ~/.frp-bridge/runtime/nodes/
|
|
244
|
-
* ├── nodes.json (index of all nodes)
|
|
245
|
-
* └── node-{id}.json (individual node data)
|
|
246
|
-
*/
|
|
247
|
-
declare class FileNodeStorage implements NodeStorage {
|
|
248
|
-
private storagePath;
|
|
249
|
-
private indexPath;
|
|
250
|
-
private nodeDir;
|
|
251
|
-
constructor(storagePath: string);
|
|
252
|
-
/** Save or update a node */
|
|
253
|
-
save(node: NodeInfo$1): Promise<void>;
|
|
254
|
-
/** Delete a node */
|
|
255
|
-
delete(id: string): Promise<void>;
|
|
256
|
-
/** Load a single node */
|
|
257
|
-
load(id: string): Promise<NodeInfo$1 | undefined>;
|
|
258
|
-
/** Load all nodes */
|
|
259
|
-
list(): Promise<NodeInfo$1[]>;
|
|
260
|
-
/** Update the index of node IDs */
|
|
261
|
-
private updateIndex;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/**
|
|
265
|
-
* 配置合并方法 - core 包内部使用
|
|
266
|
-
* 将预设配置和用户配置合并成最终的 frp 配置
|
|
267
|
-
*/
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* 预设配置接口
|
|
271
|
-
*/
|
|
272
|
-
interface PresetConfig {
|
|
273
|
-
frps?: FrpsPresetConfig;
|
|
274
|
-
frpc?: FrpcPresetConfig;
|
|
275
|
-
}
|
|
276
|
-
interface FrpsPresetConfig {
|
|
277
|
-
bindPort?: number;
|
|
278
|
-
vhostHTTPPort?: number;
|
|
279
|
-
vhostHTTPSPort?: number;
|
|
280
|
-
domain?: string;
|
|
281
|
-
dashboardPort?: number;
|
|
282
|
-
dashboardUser?: string;
|
|
283
|
-
dashboardPassword?: string;
|
|
284
|
-
authToken?: string;
|
|
285
|
-
subdomainHost?: string;
|
|
286
|
-
}
|
|
287
|
-
interface FrpcPresetConfig {
|
|
288
|
-
serverAddr?: string;
|
|
289
|
-
serverPort?: number;
|
|
290
|
-
authToken?: string;
|
|
291
|
-
user?: string;
|
|
292
|
-
heartbeatInterval?: number;
|
|
293
|
-
}
|
|
294
|
-
/**
|
|
295
|
-
* 默认预设配置
|
|
296
|
-
*/
|
|
297
|
-
declare const DEFAULT_PRESET_CONFIG: PresetConfig;
|
|
298
|
-
/**
|
|
299
|
-
* 合并预设配置和用户配置,生成最终的 TOML 配置
|
|
300
|
-
*/
|
|
301
|
-
declare function mergeConfigs(presetConfig: PresetConfig, userConfig: string, type: 'frps' | 'frpc'): string;
|
|
302
|
-
/**
|
|
303
|
-
* 从 tunnels 数组生成并保存 FRP 配置文件
|
|
304
|
-
*/
|
|
305
|
-
declare function saveFrpConfigFile(configPath: string, tunnels: ProxyConfig[], presetConfig: PresetConfig, type: 'frps' | 'frpc'): void;
|
|
306
|
-
/**
|
|
307
|
-
* 将配置对象转换为 TOML 格式
|
|
308
|
-
*/
|
|
309
|
-
declare function configToToml(config: Record<string, any>): string;
|
|
310
|
-
/**
|
|
311
|
-
* 验证预设配置
|
|
312
|
-
*/
|
|
313
|
-
declare function validatePresetConfig(config: PresetConfig, type: 'frps' | 'frpc'): {
|
|
314
|
-
valid: boolean;
|
|
315
|
-
errors: string[];
|
|
316
|
-
};
|
|
317
|
-
|
|
318
|
-
/**
|
|
319
|
-
* FRP process management utilities
|
|
320
|
-
*
|
|
321
|
-
* This class serves as a facade that delegates to specialized components:
|
|
322
|
-
* - ProcessController: Process lifecycle management
|
|
323
|
-
* - ConfigurationStore: Configuration file operations
|
|
324
|
-
* - TunnelManager: Tunnel/proxy management
|
|
325
|
-
* - NodeManager: Node information management
|
|
326
|
-
* - BinaryManager: Binary file management
|
|
327
|
-
*/
|
|
328
|
-
|
|
329
|
-
interface FrpProcessManagerOptions {
|
|
330
|
-
/** Working directory for FRP files */
|
|
331
|
-
workDir?: string;
|
|
332
|
-
/** Path to config file (overrides default) */
|
|
333
|
-
configPath?: string;
|
|
334
|
-
/** FRP version (defaults to latest) */
|
|
335
|
-
version?: string;
|
|
336
|
-
/** Mode: client or server */
|
|
337
|
-
mode: 'client' | 'server';
|
|
338
|
-
/** Optional logger */
|
|
339
|
-
logger?: RuntimeLogger;
|
|
340
|
-
}
|
|
341
|
-
interface NodeInfo {
|
|
342
|
-
/** Node ID */
|
|
343
|
-
id: string;
|
|
344
|
-
/** Node name */
|
|
345
|
-
name: string;
|
|
346
|
-
/** Server address */
|
|
347
|
-
serverAddr: string;
|
|
348
|
-
/** Server port */
|
|
349
|
-
serverPort?: number;
|
|
350
|
-
/** Authentication token */
|
|
351
|
-
token?: string;
|
|
352
|
-
/** Additional config */
|
|
353
|
-
config?: Partial<ClientConfig | ServerConfig>;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Manages FRP client/server lifecycle, config, and tunnels
|
|
357
|
-
*
|
|
358
|
-
* This class now serves as a facade that delegates to specialized components:
|
|
359
|
-
* - ProcessController: Process lifecycle management
|
|
360
|
-
* - ConfigurationStore: Configuration file operations
|
|
361
|
-
* - TunnelManager: Tunnel/proxy management
|
|
362
|
-
* - NodeManager: Node information management
|
|
363
|
-
* - BinaryManager: Binary file management
|
|
364
|
-
*/
|
|
365
|
-
declare class FrpProcessManager extends EventEmitter {
|
|
366
|
-
private readonly workDir;
|
|
367
|
-
private readonly mode;
|
|
368
|
-
private readonly specifiedVersion?;
|
|
369
|
-
private readonly logger;
|
|
370
|
-
private readonly configPath;
|
|
371
|
-
private readonly processController;
|
|
372
|
-
private readonly configStore;
|
|
373
|
-
private readonly binaryManager;
|
|
374
|
-
private readonly presetConfigManager;
|
|
375
|
-
private tunnelManager;
|
|
376
|
-
private nodeManager;
|
|
377
|
-
private process;
|
|
378
|
-
private uptime;
|
|
379
|
-
private isManualStop;
|
|
380
|
-
constructor(options: FrpProcessManagerOptions);
|
|
381
|
-
/** Ensure version is fetched and binary path is set */
|
|
382
|
-
private ensureVersion;
|
|
383
|
-
/** Download FRP binary for current platform */
|
|
384
|
-
downloadFrpBinary(): Promise<void>;
|
|
385
|
-
/** Update FRP binary to latest version */
|
|
386
|
-
updateFrpBinary(newVersion?: string): Promise<void>;
|
|
387
|
-
/** Check if binary exists */
|
|
388
|
-
hasBinary(): boolean;
|
|
389
|
-
/** Get current configuration */
|
|
390
|
-
getConfig(): Promise<ClientConfig | ServerConfig | null>;
|
|
391
|
-
/** Update configuration */
|
|
392
|
-
updateConfig(config: Partial<ClientConfig | ServerConfig>): Promise<void>;
|
|
393
|
-
/** Backup configuration */
|
|
394
|
-
backupConfig(): Promise<string>;
|
|
395
|
-
/** Return the absolute config file path */
|
|
396
|
-
getConfigPath(): string;
|
|
397
|
-
/** Read raw config file contents */
|
|
398
|
-
getConfigRaw(): string | null;
|
|
399
|
-
/** Overwrite config file with provided content */
|
|
400
|
-
updateConfigRaw(content: string): void;
|
|
401
|
-
/** Start FRP process */
|
|
402
|
-
start(): Promise<void>;
|
|
403
|
-
/** Stop FRP process */
|
|
404
|
-
stop(): Promise<void>;
|
|
405
|
-
/** Check if process is running */
|
|
406
|
-
isRunning(): boolean;
|
|
407
|
-
/** Add node (for client mode) */
|
|
408
|
-
addNode(node: NodeInfo): Promise<void>;
|
|
409
|
-
/** Get node info */
|
|
410
|
-
getNode(): Promise<NodeInfo | null>;
|
|
411
|
-
/** Update node info */
|
|
412
|
-
updateNode(node: Partial<NodeInfo>): Promise<void>;
|
|
413
|
-
/** Remove node */
|
|
414
|
-
removeNode(): Promise<void>;
|
|
415
|
-
/** Add tunnel (proxy) */
|
|
416
|
-
addTunnel(proxy: ProxyConfig): Promise<void>;
|
|
417
|
-
/** Get tunnel by name */
|
|
418
|
-
getTunnel(name: string): Promise<ProxyConfig | null>;
|
|
419
|
-
/** Update tunnel */
|
|
420
|
-
updateTunnel(name: string, proxy: Partial<ProxyConfig>): Promise<void>;
|
|
421
|
-
/** Remove tunnel */
|
|
422
|
-
removeTunnel(name: string): Promise<void>;
|
|
423
|
-
/** List all tunnels */
|
|
424
|
-
listTunnels(): Promise<ProxyConfig[]>;
|
|
425
|
-
/**
|
|
426
|
-
* 生成 FRP 配置文件(合并预设配置和用户 tunnels)
|
|
427
|
-
* @param force 是否强制重新生成
|
|
428
|
-
*/
|
|
429
|
-
generateConfig(force?: boolean): Promise<void>;
|
|
430
|
-
/**
|
|
431
|
-
* 获取预设配置
|
|
432
|
-
*/
|
|
433
|
-
getPresetConfig(): PresetConfig;
|
|
434
|
-
/**
|
|
435
|
-
* 保存预设配置
|
|
436
|
-
*/
|
|
437
|
-
savePresetConfig(config: Record<string, any>): void;
|
|
438
|
-
/**
|
|
439
|
-
* Query current process status
|
|
440
|
-
*/
|
|
441
|
-
queryProcess(): {
|
|
442
|
-
pid: number | undefined;
|
|
443
|
-
uptime: number;
|
|
444
|
-
};
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* RPC 消息类型定义
|
|
449
|
-
* 提供类型安全的消息结构和类型守卫
|
|
450
|
-
*/
|
|
451
|
-
/**
|
|
452
|
-
* RPC 消息类型枚举
|
|
453
|
-
*/
|
|
454
|
-
declare enum RpcMessageType {
|
|
455
|
-
REGISTER = "register",
|
|
456
|
-
COMMAND = "command",
|
|
457
|
-
RESPONSE = "response",
|
|
458
|
-
PING = "ping",
|
|
459
|
-
PONG = "pong"
|
|
460
|
-
}
|
|
461
|
-
/**
|
|
462
|
-
* 节点注册消息
|
|
463
|
-
*/
|
|
464
|
-
interface RegisterMessage {
|
|
465
|
-
type: RpcMessageType.REGISTER;
|
|
466
|
-
nodeId: string;
|
|
467
|
-
payload: Record<string, unknown>;
|
|
468
|
-
}
|
|
469
|
-
/**
|
|
470
|
-
* RPC 请求
|
|
471
|
-
*/
|
|
472
|
-
interface RpcRequest {
|
|
473
|
-
id: string;
|
|
474
|
-
method: string;
|
|
475
|
-
params: Record<string, unknown>;
|
|
476
|
-
timeout?: number;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* RPC 响应状态
|
|
480
|
-
*/
|
|
481
|
-
type RpcResponseStatus = 'success' | 'error';
|
|
482
|
-
/**
|
|
483
|
-
* RPC 响应
|
|
484
|
-
*/
|
|
485
|
-
interface RpcResponse {
|
|
486
|
-
id: string;
|
|
487
|
-
status: RpcResponseStatus;
|
|
488
|
-
result?: unknown;
|
|
489
|
-
error?: {
|
|
490
|
-
code: string;
|
|
491
|
-
message: string;
|
|
492
|
-
};
|
|
493
|
-
}
|
|
494
|
-
/**
|
|
495
|
-
* Ping 消息
|
|
496
|
-
*/
|
|
497
|
-
interface PingMessage {
|
|
498
|
-
type: RpcMessageType.PING;
|
|
499
|
-
timestamp: number;
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Pong 消息
|
|
503
|
-
*/
|
|
504
|
-
interface PongMessage {
|
|
505
|
-
type: RpcMessageType.PONG;
|
|
506
|
-
timestamp: number;
|
|
507
|
-
}
|
|
508
|
-
/**
|
|
509
|
-
* 所有 RPC 消息类型
|
|
510
|
-
*/
|
|
511
|
-
type RpcMessage = RegisterMessage | RpcRequest | RpcResponse | PingMessage | PongMessage;
|
|
512
|
-
/**
|
|
513
|
-
* Event-based RPC message type (matching document spec)
|
|
514
|
-
*/
|
|
515
|
-
interface EventRpcMessage {
|
|
516
|
-
type: 'command' | 'event';
|
|
517
|
-
action: string;
|
|
518
|
-
payload: unknown;
|
|
519
|
-
id?: string;
|
|
520
|
-
targetNodeId?: string;
|
|
521
|
-
}
|
|
522
|
-
/**
|
|
523
|
-
* Command message (frps -> frpc)
|
|
524
|
-
*/
|
|
525
|
-
interface CommandRpcMessage extends EventRpcMessage {
|
|
526
|
-
type: 'command';
|
|
527
|
-
id: string;
|
|
528
|
-
}
|
|
529
|
-
/**
|
|
530
|
-
* Event message (frpc -> frps)
|
|
531
|
-
*/
|
|
532
|
-
interface EventRpcMessageEvent extends EventRpcMessage {
|
|
533
|
-
type: 'event';
|
|
534
|
-
id?: string;
|
|
535
|
-
}
|
|
536
|
-
/**
|
|
537
|
-
* Tunnel add payload
|
|
538
|
-
*/
|
|
539
|
-
interface TunnelAddPayload {
|
|
540
|
-
name: string;
|
|
541
|
-
type: 'tcp' | 'http' | 'https' | 'stcp' | 'sudp' | 'xtcp';
|
|
542
|
-
localPort: number;
|
|
543
|
-
remotePort?: number;
|
|
544
|
-
customDomains?: string[];
|
|
545
|
-
subdomain?: string;
|
|
546
|
-
nodeId?: string;
|
|
547
|
-
[key: string]: unknown;
|
|
548
|
-
}
|
|
549
|
-
/**
|
|
550
|
-
* Tunnel delete payload
|
|
551
|
-
*/
|
|
552
|
-
interface TunnelDeletePayload {
|
|
553
|
-
name: string;
|
|
554
|
-
nodeId?: string;
|
|
555
|
-
}
|
|
556
|
-
/**
|
|
557
|
-
* Tunnel response payload
|
|
558
|
-
*/
|
|
559
|
-
interface TunnelResponsePayload {
|
|
560
|
-
success: boolean;
|
|
561
|
-
error?: string;
|
|
562
|
-
tunnel?: TunnelAddPayload;
|
|
563
|
-
}
|
|
564
|
-
/**
|
|
565
|
-
* Node delete payload
|
|
566
|
-
*/
|
|
567
|
-
interface NodeDeletePayload {
|
|
568
|
-
name: string;
|
|
569
|
-
}
|
|
570
|
-
/**
|
|
571
|
-
* Node response payload
|
|
572
|
-
*/
|
|
573
|
-
interface NodeResponsePayload {
|
|
574
|
-
success: boolean;
|
|
575
|
-
error?: string;
|
|
576
|
-
deletedNode?: string;
|
|
577
|
-
}
|
|
578
|
-
/**
|
|
579
|
-
* All message types including event-based
|
|
580
|
-
*/
|
|
581
|
-
type AllRpcMessage = RpcMessage | EventRpcMessage;
|
|
582
|
-
/**
|
|
583
|
-
* 类型守卫:检查是否为注册消息
|
|
584
|
-
*/
|
|
585
|
-
declare function isRegisterMessage(msg: unknown): msg is RegisterMessage;
|
|
586
|
-
/**
|
|
587
|
-
* 类型守卫:检查是否为 RPC 请求
|
|
588
|
-
*/
|
|
589
|
-
declare function isRpcRequest(msg: unknown): msg is RpcRequest;
|
|
590
|
-
/**
|
|
591
|
-
* 类型守卫:检查是否为 RPC 响应
|
|
592
|
-
*/
|
|
593
|
-
declare function isRpcResponse(msg: unknown): msg is RpcResponse;
|
|
594
|
-
/**
|
|
595
|
-
* 类型守卫:检查是否为 Ping 消息
|
|
596
|
-
*/
|
|
597
|
-
declare function isPingMessage(msg: unknown): msg is PingMessage;
|
|
598
|
-
/**
|
|
599
|
-
* 类型守卫:检查是否为 Pong 消息
|
|
600
|
-
*/
|
|
601
|
-
declare function isPongMessage(msg: unknown): msg is PongMessage;
|
|
602
|
-
/**
|
|
603
|
-
* 类型守卫:检查是否为 Event-based RPC 消息
|
|
604
|
-
*/
|
|
605
|
-
declare function isEventRpcMessage(msg: unknown): msg is EventRpcMessage;
|
|
606
|
-
/**
|
|
607
|
-
* 类型守卫:检查是否为 Command 消息
|
|
608
|
-
*/
|
|
609
|
-
declare function isCommandMessage(msg: unknown): msg is CommandRpcMessage;
|
|
610
|
-
/**
|
|
611
|
-
* 类型守卫:检查是否为 Event 消息
|
|
612
|
-
*/
|
|
613
|
-
declare function isEventMessage(msg: unknown): msg is EventRpcMessageEvent;
|
|
614
|
-
/**
|
|
615
|
-
* 类型守卫:检查是否为 TunnelAddPayload
|
|
616
|
-
*/
|
|
617
|
-
declare function isTunnelAddPayload(data: unknown): data is TunnelAddPayload;
|
|
618
|
-
/**
|
|
619
|
-
* 类型守卫:检查是否为 TunnelDeletePayload
|
|
620
|
-
*/
|
|
621
|
-
declare function isTunnelDeletePayload(data: unknown): data is TunnelDeletePayload;
|
|
622
|
-
/**
|
|
623
|
-
* 类型守卫:检查是否为 NodeDeletePayload
|
|
624
|
-
*/
|
|
625
|
-
declare function isNodeDeletePayload(data: unknown): data is NodeDeletePayload;
|
|
626
|
-
|
|
627
|
-
/**
|
|
628
|
-
* RPC 中间件系统
|
|
629
|
-
* 提供可扩展的请求处理管道
|
|
630
|
-
*/
|
|
631
|
-
|
|
632
|
-
/**
|
|
633
|
-
* 中间件上下文
|
|
634
|
-
*/
|
|
635
|
-
interface MiddlewareContext {
|
|
636
|
-
request: RpcRequest;
|
|
637
|
-
response: Partial<RpcResponse>;
|
|
638
|
-
startTime: number;
|
|
639
|
-
}
|
|
640
|
-
/**
|
|
641
|
-
* 中间件函数类型
|
|
642
|
-
*/
|
|
643
|
-
type MiddlewareFn = (context: MiddlewareContext, next: () => Promise<void>) => Promise<void>;
|
|
644
|
-
/**
|
|
645
|
-
* 中间件选项
|
|
646
|
-
*/
|
|
647
|
-
interface MiddlewareOptions {
|
|
648
|
-
preHooks?: MiddlewareFn[];
|
|
649
|
-
postHooks?: MiddlewareFn[];
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* 日志中间件
|
|
653
|
-
*/
|
|
654
|
-
declare function loggingMiddleware(logger?: {
|
|
655
|
-
info?: (msg: string, data?: unknown) => void;
|
|
656
|
-
warn?: (msg: string, data?: unknown) => void;
|
|
657
|
-
error?: (msg: string, data?: unknown) => void;
|
|
658
|
-
}): MiddlewareFn;
|
|
659
|
-
/**
|
|
660
|
-
* 认证中间件
|
|
661
|
-
*/
|
|
662
|
-
declare function authMiddleware(validateToken: (token: string | undefined) => boolean | Promise<boolean>): MiddlewareFn;
|
|
663
|
-
/**
|
|
664
|
-
* 超时中间件
|
|
665
|
-
*/
|
|
666
|
-
declare function timeoutMiddleware(timeoutMs: number): MiddlewareFn;
|
|
667
|
-
/**
|
|
668
|
-
* 错误处理中间件
|
|
669
|
-
*/
|
|
670
|
-
declare function errorHandlerMiddleware(logger?: {
|
|
671
|
-
error?: (msg: string, data?: unknown) => void;
|
|
672
|
-
}): MiddlewareFn;
|
|
673
|
-
/**
|
|
674
|
-
* 中间件管道
|
|
675
|
-
*/
|
|
676
|
-
declare class MiddlewarePipeline {
|
|
677
|
-
private middlewares;
|
|
678
|
-
/**
|
|
679
|
-
* 添加中间件
|
|
680
|
-
*/
|
|
681
|
-
use(middleware: MiddlewareFn): this;
|
|
682
|
-
/**
|
|
683
|
-
* 执行中间件管道
|
|
684
|
-
*/
|
|
685
|
-
execute(request: RpcRequest, handler: () => Promise<unknown>): Promise<Partial<RpcResponse>>;
|
|
686
|
-
/**
|
|
687
|
-
* 执行处理器
|
|
688
|
-
*/
|
|
689
|
-
private executeHandler;
|
|
690
|
-
/**
|
|
691
|
-
* 清空中间件
|
|
692
|
-
*/
|
|
693
|
-
clear(): void;
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
/**
|
|
697
|
-
* RPC 重连策略
|
|
698
|
-
* 提供可配置的重连机制,包括指数退避
|
|
699
|
-
*/
|
|
700
|
-
/**
|
|
701
|
-
* 重连策略接口
|
|
702
|
-
*/
|
|
703
|
-
interface ReconnectStrategy {
|
|
704
|
-
/**
|
|
705
|
-
* 判断是否应该重连
|
|
706
|
-
*/
|
|
707
|
-
shouldReconnect: (attempt: number) => boolean;
|
|
708
|
-
/**
|
|
709
|
-
* 获取重连延迟时间(毫秒)
|
|
710
|
-
*/
|
|
711
|
-
getDelay: (attempt: number) => number;
|
|
712
|
-
/**
|
|
713
|
-
* 达到最大重连次数时的回调
|
|
714
|
-
*/
|
|
715
|
-
onMaxAttemptsReached: () => void;
|
|
716
|
-
}
|
|
717
|
-
/**
|
|
718
|
-
* 指数退避重连策略
|
|
719
|
-
*/
|
|
720
|
-
declare class ExponentialBackoffStrategy implements ReconnectStrategy {
|
|
721
|
-
private maxAttempts;
|
|
722
|
-
private baseDelay;
|
|
723
|
-
private maxDelay;
|
|
724
|
-
private logger?;
|
|
725
|
-
constructor(maxAttempts?: number, baseDelay?: number, maxDelay?: number, logger?: {
|
|
726
|
-
error?: (msg: string, data?: unknown) => void;
|
|
727
|
-
} | undefined);
|
|
728
|
-
shouldReconnect(attempt: number): boolean;
|
|
729
|
-
getDelay(attempt: number): number;
|
|
730
|
-
onMaxAttemptsReached(): void;
|
|
731
|
-
}
|
|
732
|
-
/**
|
|
733
|
-
* 固定间隔重连策略
|
|
734
|
-
*/
|
|
735
|
-
declare class FixedIntervalStrategy implements ReconnectStrategy {
|
|
736
|
-
private maxAttempts;
|
|
737
|
-
private interval;
|
|
738
|
-
private logger?;
|
|
739
|
-
constructor(maxAttempts?: number, interval?: number, logger?: {
|
|
740
|
-
error?: (msg: string, data?: unknown) => void;
|
|
741
|
-
} | undefined);
|
|
742
|
-
shouldReconnect(attempt: number): boolean;
|
|
743
|
-
getDelay(): number;
|
|
744
|
-
onMaxAttemptsReached(): void;
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
* 线性增长重连策略
|
|
748
|
-
*/
|
|
749
|
-
declare class LinearBackoffStrategy implements ReconnectStrategy {
|
|
750
|
-
private maxAttempts;
|
|
751
|
-
private baseDelay;
|
|
752
|
-
private increment;
|
|
753
|
-
private maxDelay;
|
|
754
|
-
private logger?;
|
|
755
|
-
constructor(maxAttempts?: number, baseDelay?: number, increment?: number, maxDelay?: number, logger?: {
|
|
756
|
-
error?: (msg: string, data?: unknown) => void;
|
|
757
|
-
} | undefined);
|
|
758
|
-
shouldReconnect(attempt: number): boolean;
|
|
759
|
-
getDelay(attempt: number): number;
|
|
760
|
-
onMaxAttemptsReached(): void;
|
|
761
|
-
}
|
|
762
|
-
/**
|
|
763
|
-
* 无限重连策略(永不停止)
|
|
764
|
-
*/
|
|
765
|
-
declare class InfiniteReconnectStrategy implements ReconnectStrategy {
|
|
766
|
-
private baseDelay;
|
|
767
|
-
private maxDelay;
|
|
768
|
-
constructor(baseDelay?: number, maxDelay?: number);
|
|
769
|
-
shouldReconnect(): boolean;
|
|
770
|
-
getDelay(attempt: number): number;
|
|
771
|
-
onMaxAttemptsReached(): void;
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
interface RpcClientOptions {
|
|
775
|
-
url: string;
|
|
776
|
-
nodeId: string;
|
|
777
|
-
getRegisterPayload: () => Promise<NodeInfo$1> | NodeInfo$1;
|
|
778
|
-
handleRequest: (req: RpcRequest$1) => Promise<unknown>;
|
|
779
|
-
handleCommand?: (command: CommandRpcMessage) => Promise<unknown>;
|
|
780
|
-
reconnectStrategy?: ReconnectStrategy;
|
|
781
|
-
logger?: Partial<RuntimeLogger>;
|
|
782
|
-
}
|
|
783
|
-
declare class RpcClient {
|
|
784
|
-
private readonly options;
|
|
785
|
-
private ws;
|
|
786
|
-
private reconnectTimer?;
|
|
787
|
-
private reconnectAttempt;
|
|
788
|
-
private readonly reconnectStrategy;
|
|
789
|
-
private connectionState;
|
|
790
|
-
private readonly log;
|
|
791
|
-
constructor(options: RpcClientOptions);
|
|
792
|
-
connect(): Promise<void>;
|
|
793
|
-
disconnect(): void;
|
|
794
|
-
/**
|
|
795
|
-
* Get current connection state
|
|
796
|
-
*/
|
|
797
|
-
getConnectionState(): 'connecting' | 'connected' | 'disconnected';
|
|
798
|
-
/**
|
|
799
|
-
* Check if connected
|
|
800
|
-
*/
|
|
801
|
-
isConnected(): boolean;
|
|
802
|
-
/**
|
|
803
|
-
* Send an event message to server (matching document spec)
|
|
804
|
-
*/
|
|
805
|
-
sendEvent(event: EventRpcMessageEvent): boolean;
|
|
806
|
-
private createConnection;
|
|
807
|
-
private handleMessage;
|
|
808
|
-
/**
|
|
809
|
-
* Handle event-based command messages from server (matching document spec)
|
|
810
|
-
*/
|
|
811
|
-
private handleCommandEvent;
|
|
812
|
-
private handleRpcRequest;
|
|
813
|
-
private send;
|
|
814
|
-
private scheduleReconnect;
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
/**
|
|
818
|
-
* Command status for tracking
|
|
819
|
-
*/
|
|
820
|
-
interface RpcCommandStatus {
|
|
821
|
-
commandId: string;
|
|
822
|
-
nodeId: string;
|
|
823
|
-
action: string;
|
|
824
|
-
status: 'pending' | 'completed' | 'failed';
|
|
825
|
-
result?: unknown;
|
|
826
|
-
error?: string;
|
|
827
|
-
timestamp: number;
|
|
828
|
-
}
|
|
829
|
-
interface RpcServerOptions {
|
|
830
|
-
port: number;
|
|
831
|
-
heartbeatInterval?: number;
|
|
832
|
-
validateToken?: (token: string | undefined, nodeId: string | undefined) => boolean | Promise<boolean>;
|
|
833
|
-
authorize?: (nodeId: string, method: string) => boolean | Promise<boolean>;
|
|
834
|
-
onRegister?: (nodeId: string, payload: NodeInfo$1) => void | Promise<void>;
|
|
835
|
-
onEvent?: (nodeId: string, event: EventRpcMessage) => void | Promise<void>;
|
|
836
|
-
commandTimeout?: number;
|
|
837
|
-
logger?: Partial<RuntimeLogger>;
|
|
838
|
-
}
|
|
839
|
-
declare class RpcServer {
|
|
840
|
-
private readonly options;
|
|
841
|
-
private readonly clients;
|
|
842
|
-
private readonly pendingRequests;
|
|
843
|
-
private readonly commandStatuses;
|
|
844
|
-
private readonly wsToNode;
|
|
845
|
-
private heartbeatTimer?;
|
|
846
|
-
private server?;
|
|
847
|
-
private readonly defaultCommandTimeout;
|
|
848
|
-
private readonly log;
|
|
849
|
-
constructor(options: RpcServerOptions);
|
|
850
|
-
start(): void;
|
|
851
|
-
stop(): void;
|
|
852
|
-
rpcCall(nodeId: string, method: string, params: Record<string, unknown>, timeout?: number): Promise<unknown>;
|
|
853
|
-
/**
|
|
854
|
-
* Send event-based message to a specific node (matching document spec)
|
|
855
|
-
*/
|
|
856
|
-
sendToNode(nodeId: string, message: EventRpcMessage): boolean;
|
|
857
|
-
/**
|
|
858
|
-
* Broadcast event-based message to all connected nodes
|
|
859
|
-
*/
|
|
860
|
-
broadcast(message: EventRpcMessage): void;
|
|
861
|
-
/**
|
|
862
|
-
* Get list of all online node IDs
|
|
863
|
-
*/
|
|
864
|
-
getOnlineNodes(): string[];
|
|
865
|
-
/**
|
|
866
|
-
* Check if a specific node is online
|
|
867
|
-
*/
|
|
868
|
-
isNodeOnline(nodeId: string): boolean;
|
|
869
|
-
/**
|
|
870
|
-
* Get the count of online nodes
|
|
871
|
-
*/
|
|
872
|
-
getOnlineNodeCount(): number;
|
|
873
|
-
/**
|
|
874
|
-
* Get command status by ID
|
|
875
|
-
*/
|
|
876
|
-
getRpcCommandStatus(commandId: string): RpcCommandStatus | undefined;
|
|
877
|
-
/**
|
|
878
|
-
* Get all command statuses
|
|
879
|
-
*/
|
|
880
|
-
getAllRpcCommandStatuses(): RpcCommandStatus[];
|
|
881
|
-
/**
|
|
882
|
-
* Clear completed/failed command statuses older than specified milliseconds
|
|
883
|
-
*/
|
|
884
|
-
clearOldStatuses(maxAge?: number): void;
|
|
885
|
-
private handleMessage;
|
|
886
|
-
/**
|
|
887
|
-
* Handle event-based messages from clients
|
|
888
|
-
*/
|
|
889
|
-
private handleEventMessage;
|
|
890
|
-
private handleRegister;
|
|
891
|
-
private handleRpcResponse;
|
|
892
|
-
private handleClose;
|
|
893
|
-
private startHeartbeat;
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
interface FrpBridgeRuntimeOptions {
|
|
897
|
-
id?: string;
|
|
898
|
-
mode?: RuntimeMode;
|
|
899
|
-
logger?: RuntimeLogger;
|
|
900
|
-
clock?: () => number;
|
|
901
|
-
platform?: string;
|
|
902
|
-
workDir?: string;
|
|
903
|
-
}
|
|
904
|
-
interface FrpBridgeProcessOptions extends Partial<Omit<FrpProcessManagerOptions, 'mode'>> {
|
|
905
|
-
mode?: 'client' | 'server';
|
|
906
|
-
}
|
|
907
|
-
interface FrpBridgeRpcOptions {
|
|
908
|
-
serverPort?: number;
|
|
909
|
-
serverHeartbeatInterval?: number;
|
|
910
|
-
serverValidateToken?: (token: string | undefined, nodeId: string | undefined) => boolean | Promise<boolean>;
|
|
911
|
-
serverAuthorize?: (nodeId: string, method: string) => boolean | Promise<boolean>;
|
|
912
|
-
serverOnRegister?: (nodeId: string, payload: NodeInfo$1) => void | Promise<void>;
|
|
913
|
-
serverOnEvent?: (nodeId: string, event: EventRpcMessage) => void | Promise<void>;
|
|
914
|
-
serverCommandTimeout?: number;
|
|
915
|
-
clientUrl?: string;
|
|
916
|
-
clientNodeId?: string;
|
|
917
|
-
clientToken?: string;
|
|
918
|
-
clientReconnectInterval?: number;
|
|
919
|
-
getRegisterPayload?: () => Promise<NodeInfo$1> | NodeInfo$1;
|
|
920
|
-
handleRequest?: (req: RpcRequest$1) => Promise<unknown>;
|
|
921
|
-
}
|
|
922
|
-
|
|
923
|
-
interface FrpBridgeOptions {
|
|
924
|
-
mode: 'client' | 'server';
|
|
925
|
-
workDir?: string;
|
|
926
|
-
configPath?: string;
|
|
927
|
-
runtime?: FrpBridgeRuntimeOptions;
|
|
928
|
-
process?: FrpBridgeProcessOptions;
|
|
929
|
-
rpc?: FrpBridgeRpcOptions;
|
|
930
|
-
storage?: SnapshotStorage;
|
|
931
|
-
commands?: Record<string, CommandHandler>;
|
|
932
|
-
queries?: Record<string, QueryHandler>;
|
|
933
|
-
eventSink?: (event: RuntimeEvent) => void;
|
|
934
|
-
}
|
|
935
|
-
/**
|
|
936
|
-
* FrpBridge - Main facade class for managing FRP bridge operations.
|
|
937
|
-
*
|
|
938
|
-
* This class serves as a facade that coordinates multiple components:
|
|
939
|
-
* - Runtime management (command/query execution)
|
|
940
|
-
* - Process management (FRP process lifecycle)
|
|
941
|
-
* - Node management (server mode only)
|
|
942
|
-
* - RPC communication
|
|
943
|
-
*
|
|
944
|
-
* Design patterns used:
|
|
945
|
-
* - Facade Pattern: Simplifies interface to complex subsystems
|
|
946
|
-
* - Dependency Injection: All dependencies injected via constructor
|
|
947
|
-
* - Factory Pattern: Handlers created via factory functions
|
|
948
|
-
*/
|
|
949
|
-
declare class FrpBridge {
|
|
950
|
-
private readonly runtime;
|
|
951
|
-
private readonly process;
|
|
952
|
-
private readonly mode;
|
|
953
|
-
private readonly eventSink?;
|
|
954
|
-
private readonly nodeManager?;
|
|
955
|
-
private readonly clientCollector?;
|
|
956
|
-
private readonly rpcServer?;
|
|
957
|
-
private readonly rpcClient?;
|
|
958
|
-
constructor(options: FrpBridgeOptions);
|
|
959
|
-
/**
|
|
960
|
-
* Execute a command
|
|
961
|
-
*/
|
|
962
|
-
execute<TPayload, TResult = unknown>(command: RuntimeCommand<TPayload>): Promise<CommandResult<TResult>>;
|
|
963
|
-
/**
|
|
964
|
-
* Execute a query
|
|
965
|
-
*/
|
|
966
|
-
query<TPayload, TResult = unknown>(query: RuntimeQuery<TPayload>): Promise<QueryResult<TResult>>;
|
|
967
|
-
/**
|
|
968
|
-
* Get current runtime state snapshot
|
|
969
|
-
*/
|
|
970
|
-
snapshot(): RuntimeState;
|
|
971
|
-
/**
|
|
972
|
-
* Drain and return all pending events
|
|
973
|
-
*/
|
|
974
|
-
drainEvents(): RuntimeEvent[];
|
|
975
|
-
getProcessManager(): FrpProcessManager;
|
|
976
|
-
getRuntime(): FrpRuntime;
|
|
977
|
-
getNodeManager(): NodeManager | undefined;
|
|
978
|
-
getClientCollector(): ClientNodeCollector | undefined;
|
|
979
|
-
getRpcServer(): RpcServer | undefined;
|
|
980
|
-
getRpcClient(): RpcClient | undefined;
|
|
981
|
-
/**
|
|
982
|
-
* Initialize all async components
|
|
983
|
-
*/
|
|
984
|
-
initialize(): Promise<void>;
|
|
985
|
-
/**
|
|
986
|
-
* Cleanup and dispose all resources
|
|
987
|
-
*/
|
|
988
|
-
dispose(): Promise<void>;
|
|
989
|
-
/**
|
|
990
|
-
* Forward runtime events to external event sink
|
|
991
|
-
*/
|
|
992
|
-
private forwardEvents;
|
|
993
|
-
}
|
|
994
|
-
|
|
995
|
-
/**
|
|
996
|
-
* Core constants
|
|
997
|
-
*/
|
|
998
|
-
/** GitHub repository owner */
|
|
999
|
-
declare const GITHUB_OWNER = "fatedier";
|
|
1000
|
-
/** GitHub repository name */
|
|
1001
|
-
declare const GITHUB_REPO = "frp";
|
|
1002
|
-
/** Platform-specific binary names */
|
|
1003
|
-
declare const BINARY_NAMES: {
|
|
1004
|
-
readonly client: "frpc.exe" | "frpc";
|
|
1005
|
-
readonly server: "frps.exe" | "frps";
|
|
1006
|
-
};
|
|
1007
|
-
/** Platform architecture mapping */
|
|
1008
|
-
declare const ARCH_MAP: Record<string, string>;
|
|
1009
|
-
/** Platform OS mapping */
|
|
1010
|
-
declare const OS_MAP: Record<string, string>;
|
|
1011
|
-
|
|
1012
|
-
/**
|
|
1013
|
-
* Base error class for all FRP Bridge errors
|
|
1014
|
-
* Provides consistent error structure and handling
|
|
1015
|
-
*/
|
|
1016
|
-
declare abstract class FrpBridgeErrorBase extends Error {
|
|
1017
|
-
/**
|
|
1018
|
-
* Error code for programmatic error handling
|
|
1019
|
-
*/
|
|
1020
|
-
abstract readonly code: string;
|
|
1021
|
-
/**
|
|
1022
|
-
* HTTP status code (optional, for API responses)
|
|
1023
|
-
*/
|
|
1024
|
-
readonly statusCode?: number;
|
|
1025
|
-
/**
|
|
1026
|
-
* Additional error details
|
|
1027
|
-
*/
|
|
1028
|
-
readonly details?: unknown;
|
|
1029
|
-
constructor(message: string, details?: unknown);
|
|
1030
|
-
/**
|
|
1031
|
-
* Convert error to plain object for serialization
|
|
1032
|
-
*/
|
|
1033
|
-
toJSON(): {
|
|
1034
|
-
code: string;
|
|
1035
|
-
message: string;
|
|
1036
|
-
statusCode?: number;
|
|
1037
|
-
details?: unknown;
|
|
1038
|
-
};
|
|
1039
|
-
}
|
|
1040
|
-
/**
|
|
1041
|
-
* Generic error for uncategorized errors
|
|
1042
|
-
*/
|
|
1043
|
-
declare class GenericError extends FrpBridgeErrorBase {
|
|
1044
|
-
readonly code: string;
|
|
1045
|
-
constructor(message: string, code: string, details?: unknown);
|
|
1046
|
-
}
|
|
1047
|
-
|
|
1048
|
-
/**
|
|
1049
|
-
* Categorized error classes for FRP Bridge
|
|
1050
|
-
* Each error extends FrpBridgeErrorBase directly
|
|
1051
|
-
*/
|
|
1052
|
-
|
|
1053
|
-
/**
|
|
1054
|
-
* Configuration errors (400 Bad Request)
|
|
1055
|
-
*/
|
|
1056
|
-
declare class ConfigNotFoundError extends FrpBridgeErrorBase {
|
|
1057
|
-
readonly code = "CONFIG_NOT_FOUND";
|
|
1058
|
-
readonly statusCode = 400;
|
|
1059
|
-
}
|
|
1060
|
-
declare class ConfigInvalidError extends FrpBridgeErrorBase {
|
|
1061
|
-
readonly code = "CONFIG_INVALID";
|
|
1062
|
-
readonly statusCode = 400;
|
|
1063
|
-
}
|
|
1064
|
-
/**
|
|
1065
|
-
* Process errors
|
|
1066
|
-
*/
|
|
1067
|
-
declare class ProcessNotRunningError extends FrpBridgeErrorBase {
|
|
1068
|
-
readonly code = "PROCESS_NOT_RUNNING";
|
|
1069
|
-
readonly statusCode = 409;
|
|
1070
|
-
}
|
|
1071
|
-
declare class ProcessAlreadyRunningError extends FrpBridgeErrorBase {
|
|
1072
|
-
readonly code = "PROCESS_ALREADY_RUNNING";
|
|
1073
|
-
readonly statusCode = 409;
|
|
1074
|
-
}
|
|
1075
|
-
declare class ProcessStartFailedError extends FrpBridgeErrorBase {
|
|
1076
|
-
readonly code = "PROCESS_START_FAILED";
|
|
1077
|
-
readonly statusCode = 500;
|
|
1078
|
-
}
|
|
1079
|
-
/**
|
|
1080
|
-
* Binary errors (500 Internal Server Error)
|
|
1081
|
-
*/
|
|
1082
|
-
declare class BinaryNotFoundError extends FrpBridgeErrorBase {
|
|
1083
|
-
readonly code = "BINARY_NOT_FOUND";
|
|
1084
|
-
readonly statusCode = 500;
|
|
1085
|
-
}
|
|
1086
|
-
declare class DownloadFailedError extends FrpBridgeErrorBase {
|
|
1087
|
-
readonly code = "DOWNLOAD_FAILED";
|
|
1088
|
-
readonly statusCode = 500;
|
|
1089
|
-
}
|
|
1090
|
-
declare class ExtractionFailedError extends FrpBridgeErrorBase {
|
|
1091
|
-
readonly code = "EXTRACTION_FAILED";
|
|
1092
|
-
readonly statusCode = 500;
|
|
1093
|
-
}
|
|
1094
|
-
/**
|
|
1095
|
-
* Network/Version errors (503 Service Unavailable)
|
|
1096
|
-
*/
|
|
1097
|
-
declare class VersionFetchError extends FrpBridgeErrorBase {
|
|
1098
|
-
readonly code = "VERSION_FETCH_FAILED";
|
|
1099
|
-
readonly statusCode = 503;
|
|
1100
|
-
}
|
|
1101
|
-
/**
|
|
1102
|
-
* Validation errors (400 Bad Request)
|
|
1103
|
-
*/
|
|
1104
|
-
declare class ValidationError extends FrpBridgeErrorBase {
|
|
1105
|
-
readonly code = "VALIDATION_ERROR";
|
|
1106
|
-
readonly statusCode = 400;
|
|
1107
|
-
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Mode/State errors (409 Conflict)
|
|
1110
|
-
*/
|
|
1111
|
-
declare class ModeError extends FrpBridgeErrorBase {
|
|
1112
|
-
readonly code = "MODE_ERROR";
|
|
1113
|
-
readonly statusCode = 409;
|
|
1114
|
-
}
|
|
1115
|
-
/**
|
|
1116
|
-
* Resource not found (404 Not Found)
|
|
1117
|
-
*/
|
|
1118
|
-
declare class NotFoundError extends FrpBridgeErrorBase {
|
|
1119
|
-
readonly code = "NOT_FOUND";
|
|
1120
|
-
readonly statusCode = 404;
|
|
1121
|
-
}
|
|
1122
|
-
/**
|
|
1123
|
-
* Platform errors (500 Internal Server Error)
|
|
1124
|
-
*/
|
|
1125
|
-
declare class PlatformError extends FrpBridgeErrorBase {
|
|
1126
|
-
readonly code = "UNSUPPORTED_PLATFORM";
|
|
1127
|
-
readonly statusCode = 500;
|
|
1128
|
-
}
|
|
1129
|
-
|
|
1130
|
-
declare class FileSnapshotStorage implements SnapshotStorage {
|
|
1131
|
-
private readonly directory;
|
|
1132
|
-
constructor(directory: string);
|
|
1133
|
-
save(snapshot: ConfigSnapshot): Promise<void>;
|
|
1134
|
-
load(version: number): Promise<ConfigSnapshot | undefined>;
|
|
1135
|
-
list(): Promise<ConfigSnapshot[]>;
|
|
1136
|
-
private buildPath;
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
/**
|
|
1140
|
-
* Unified TOML parsing and serialization module
|
|
1141
|
-
* Wraps smol-toml with consistent error handling
|
|
1142
|
-
*/
|
|
1143
|
-
interface ParseOptions {
|
|
1144
|
-
/**
|
|
1145
|
-
* Parse integers as BigInt
|
|
1146
|
-
*/
|
|
1147
|
-
integersAsBigInt?: boolean | 'asNeeded';
|
|
1148
|
-
}
|
|
1149
|
-
interface StringifyOptions {
|
|
1150
|
-
/**
|
|
1151
|
-
* Serialize numbers as floats
|
|
1152
|
-
*/
|
|
1153
|
-
numbersAsFloat?: boolean;
|
|
1154
|
-
}
|
|
1155
|
-
/**
|
|
1156
|
-
* Parse TOML string to JavaScript object
|
|
1157
|
-
* @param content - TOML string content
|
|
1158
|
-
* @param options - Parse options
|
|
1159
|
-
* @returns Parsed JavaScript object
|
|
1160
|
-
* @throws {Error} If TOML is invalid
|
|
1161
|
-
*/
|
|
1162
|
-
declare function parse<T = Record<string, any>>(content: string, options?: ParseOptions): T;
|
|
1163
|
-
/**
|
|
1164
|
-
* Serialize JavaScript object to TOML string
|
|
1165
|
-
* @param obj - JavaScript object to serialize
|
|
1166
|
-
* @param options - Stringify options
|
|
1167
|
-
* @returns TOML string
|
|
1168
|
-
* @throws {Error} If object contains unserializable values
|
|
1169
|
-
*/
|
|
1170
|
-
declare function stringify(obj: Record<string, any>, options?: StringifyOptions): string;
|
|
1171
|
-
/**
|
|
1172
|
-
* Check if a string is valid TOML
|
|
1173
|
-
* @param content - String content to check
|
|
1174
|
-
* @returns true if valid TOML, false otherwise
|
|
1175
|
-
*/
|
|
1176
|
-
declare function isValidToml(content: string): boolean;
|
|
1177
|
-
/**
|
|
1178
|
-
* Parse TOML file content safely (returns null on error)
|
|
1179
|
-
* @param content - TOML string content
|
|
1180
|
-
* @returns Parsed object or null if parsing fails
|
|
1181
|
-
*/
|
|
1182
|
-
declare function safeParse<T = Record<string, any>>(content: string): T | null;
|
|
1183
|
-
|
|
1184
|
-
/**
|
|
1185
|
-
* Utility functions
|
|
1186
|
-
*/
|
|
1187
|
-
/** Get latest FRP version from GitHub releases */
|
|
1188
|
-
declare function getLatestVersion(): Promise<string>;
|
|
1189
|
-
/** Get platform identifier for FRP release */
|
|
1190
|
-
declare function getPlatform(): string;
|
|
1191
|
-
/** Get GitHub release download URL */
|
|
1192
|
-
declare function getDownloadUrl(version: string, platform: string): string;
|
|
1193
|
-
/** Download file from URL */
|
|
1194
|
-
declare function downloadFile(url: string, dest: string): Promise<void>;
|
|
1195
|
-
/** Execute command */
|
|
1196
|
-
declare function executeCommand(command: string): Promise<{
|
|
1197
|
-
stdout: string;
|
|
1198
|
-
stderr: string;
|
|
1199
|
-
}>;
|
|
1200
|
-
/** Check if command exists */
|
|
1201
|
-
declare function commandExists(command: string): Promise<boolean>;
|
|
1202
|
-
/** Ensure directory exists */
|
|
1203
|
-
declare function ensureDir(dirPath: string): void;
|
|
1204
|
-
/** Find existing FRP version in work directory */
|
|
1205
|
-
declare function findExistingVersion(workDir: string): string | null;
|
|
1206
|
-
/**
|
|
1207
|
-
* Parse TOML-like config to JSON
|
|
1208
|
-
*/
|
|
1209
|
-
declare function parseToml(content: string): Record<string, any>;
|
|
1210
|
-
/**
|
|
1211
|
-
* Convert JSON to TOML-like config
|
|
1212
|
-
*/
|
|
1213
|
-
declare function toToml(obj: Record<string, any>): string;
|
|
1214
|
-
|
|
1215
|
-
export { ARCH_MAP, BINARY_NAMES, BinaryNotFoundError, ClientNodeCollector, ConfigInvalidError, ConfigNotFoundError, DEFAULT_PRESET_CONFIG, DownloadFailedError, FrpBridgeErrorBase as Error, ExponentialBackoffStrategy, ExtractionFailedError, FileNodeStorage, FileSnapshotStorage, FixedIntervalStrategy, FrpBridge, FrpBridgeErrorBase, FrpProcessManager, FrpRuntime, GITHUB_OWNER, GITHUB_REPO, GenericError, InfiniteReconnectStrategy, LinearBackoffStrategy, MiddlewarePipeline, ModeError, NodeManager, NotFoundError, OS_MAP, PlatformError, ProcessAlreadyRunningError, ProcessNotRunningError, ProcessStartFailedError, RpcClient, RpcMessageType, RpcServer, ValidationError, VersionFetchError, authMiddleware, commandExists, configToToml, downloadFile, ensureDir, errorHandlerMiddleware, executeCommand, findExistingVersion, getDownloadUrl, getLatestVersion, getPlatform, isCommandMessage, isEventMessage, isEventRpcMessage, isNodeDeletePayload, isPingMessage, isPongMessage, isRegisterMessage, isRpcRequest, isRpcResponse, isTunnelAddPayload, isTunnelDeletePayload, isValidToml, loggingMiddleware, mergeConfigs, parse, parseToml, safeParse, saveFrpConfigFile, stringify, timeoutMiddleware, toToml, validatePresetConfig };
|
|
1216
|
-
export type { AllRpcMessage, Awaitable, ClientCollectorOptions, CommandHandler, CommandHandlerContext, CommandMetadata, CommandResult, CommandRpcMessage, CommandStatus, ConfigSnapshot, EventRpcMessage, EventRpcMessageEvent, FrpBridgeOptions, FrpProcessManagerOptions, FrpcPresetConfig, FrpsPresetConfig, MiddlewareContext, MiddlewareFn, MiddlewareOptions, NodeDeletePayload, NodeEvent, NodeInfo, NodeManagerOptions, NodeResponsePayload, NodeStorage, ParseOptions, PingMessage, PongMessage, PresetConfig, QueryHandler, QueryResult, ReconnectStrategy, RegisterMessage, RpcClientOptions, RpcCommandStatus, RpcMessage, RpcRequest, RpcResponse, RpcResponseStatus, RpcServerOptions, RuntimeAdapters, RuntimeCommand, RuntimeContext, RuntimeError, RuntimeErrorCode, RuntimeEvent, RuntimeLogger, RuntimeMode, RuntimeQuery, RuntimeState, RuntimeStatus, SnapshotStorage, StringifyOptions, TunnelAddPayload, TunnelDeletePayload, TunnelResponsePayload };
|