@wishcore/wish-rpc 0.6.13 → 0.6.15
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/src/index.d.ts +43 -1
- package/dist/src/index.js +1 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/method-registry.d.ts +60 -0
- package/dist/src/method-registry.js +135 -0
- package/dist/src/method-registry.js.map +1 -0
- package/dist/src/rpc-server.d.ts +146 -42
- package/dist/src/rpc-server.js +337 -280
- package/dist/src/rpc-server.js.map +1 -1
- package/package.json +2 -2
- package/dist/test/stream-clean.spec.d.ts +0 -1
- package/dist/test/stream-clean.spec.js +0 -146
- package/dist/test/stream-clean.spec.js.map +0 -1
- package/dist/test/stream.spec.d.ts +0 -1
- package/dist/test/stream.spec.js +0 -113
- package/dist/test/stream.spec.js.map +0 -1
- package/dist/test/test-client.d.ts +0 -1
- package/dist/test/test-client.js +0 -88
- package/dist/test/test-client.js.map +0 -1
- package/dist/test/test-rpc-acl.d.ts +0 -1
- package/dist/test/test-rpc-acl.js +0 -103
- package/dist/test/test-rpc-acl.js.map +0 -1
- package/dist/test/test-rpc.spec.d.ts +0 -1
- package/dist/test/test-rpc.spec.js +0 -143
- package/dist/test/test-rpc.spec.js.map +0 -1
- package/dist/test/test-session.spec.d.ts +0 -1
- package/dist/test/test-session.spec.js +0 -46
- package/dist/test/test-session.spec.js.map +0 -1
- package/dist/test/test-stream.d.ts +0 -1
- package/dist/test/test-stream.js +0 -253
- package/dist/test/test-stream.js.map +0 -1
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,37 @@
|
|
|
1
1
|
export interface MethodMap {
|
|
2
2
|
[endpoint: string]: any;
|
|
3
3
|
}
|
|
4
|
+
export interface EndpointConfig {
|
|
5
|
+
doc?: string;
|
|
6
|
+
args?: string;
|
|
7
|
+
validate?: (args: any[], context: any) => any;
|
|
8
|
+
validateResult?: (result: any) => any;
|
|
9
|
+
fullname?: string;
|
|
10
|
+
[key: string]: any;
|
|
11
|
+
}
|
|
12
|
+
export interface BaseEndpointConfig {
|
|
13
|
+
doc?: string;
|
|
14
|
+
args?: string;
|
|
15
|
+
fullname?: string;
|
|
16
|
+
[key: string]: any;
|
|
17
|
+
}
|
|
18
|
+
export interface EndpointHandler {
|
|
19
|
+
(req: RpcRequest, res: RpcResponse, context?: any): any;
|
|
20
|
+
}
|
|
21
|
+
export interface RpcRequest {
|
|
22
|
+
args: any[];
|
|
23
|
+
id?: number;
|
|
24
|
+
op?: string;
|
|
25
|
+
context?: any;
|
|
26
|
+
end?: any;
|
|
27
|
+
send?: any;
|
|
28
|
+
}
|
|
29
|
+
export interface RpcResponse {
|
|
30
|
+
send(data?: any): void;
|
|
31
|
+
emit(data?: any): void;
|
|
32
|
+
error(data?: any): void;
|
|
33
|
+
close(data?: any): void;
|
|
34
|
+
}
|
|
4
35
|
export interface RequestMessage {
|
|
5
36
|
op: string;
|
|
6
37
|
args?: any[];
|
|
@@ -18,11 +49,22 @@ export interface ResponseMessage {
|
|
|
18
49
|
end?: number;
|
|
19
50
|
push?: number;
|
|
20
51
|
data?: any;
|
|
52
|
+
fin?: number;
|
|
53
|
+
}
|
|
54
|
+
export interface RequestContext {
|
|
55
|
+
id?: number;
|
|
56
|
+
op?: string;
|
|
57
|
+
args?: any[];
|
|
58
|
+
context?: any;
|
|
59
|
+
end?: any;
|
|
60
|
+
send?: any;
|
|
61
|
+
data?: any;
|
|
21
62
|
}
|
|
22
63
|
export interface RequestMap {
|
|
23
64
|
[clientId: string]: {
|
|
24
|
-
[requestId: string]:
|
|
65
|
+
[requestId: string]: RequestContext;
|
|
25
66
|
};
|
|
26
67
|
}
|
|
27
68
|
export * from './rpc-client';
|
|
28
69
|
export * from './rpc-server';
|
|
70
|
+
export * from './method-registry';
|
package/dist/src/index.js
CHANGED
|
@@ -12,4 +12,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
12
12
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
13
|
__exportStar(require("./rpc-client"), exports);
|
|
14
14
|
__exportStar(require("./rpc-server"), exports);
|
|
15
|
+
__exportStar(require("./method-registry"), exports);
|
|
15
16
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AA+
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;AA+EA,+CAA6B;AAC7B,+CAA6B;AAC7B,oDAAkC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { EndpointConfig, EndpointHandler, MethodMap, BaseEndpointConfig } from './index';
|
|
2
|
+
/**
|
|
3
|
+
* Manages RPC method registration and retrieval
|
|
4
|
+
*/
|
|
5
|
+
export declare class MethodRegistry<T extends BaseEndpointConfig = EndpointConfig> {
|
|
6
|
+
private modules;
|
|
7
|
+
private methods;
|
|
8
|
+
/**
|
|
9
|
+
* Register a new endpoint with modern syntax
|
|
10
|
+
*/
|
|
11
|
+
registerEndpoint(name: string, config: T, handler: EndpointHandler): void;
|
|
12
|
+
/**
|
|
13
|
+
* Register methods using legacy underscore-prefixed structure
|
|
14
|
+
*/
|
|
15
|
+
registerLegacyMethods(methodMap: MethodMap): void;
|
|
16
|
+
/**
|
|
17
|
+
* Get all registered modules
|
|
18
|
+
*/
|
|
19
|
+
getModules(): Record<string, T>;
|
|
20
|
+
/**
|
|
21
|
+
* Get all registered methods
|
|
22
|
+
*/
|
|
23
|
+
getMethods(): Record<string, EndpointHandler>;
|
|
24
|
+
/**
|
|
25
|
+
* Get a specific method by name
|
|
26
|
+
*/
|
|
27
|
+
getMethod(name: string): EndpointHandler | undefined;
|
|
28
|
+
/**
|
|
29
|
+
* Get a specific module config by name
|
|
30
|
+
*/
|
|
31
|
+
getModule(name: string): T | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a method exists
|
|
34
|
+
*/
|
|
35
|
+
hasMethod(name: string): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Get method listing excluding internal fields
|
|
38
|
+
*/
|
|
39
|
+
getMethodListing(): Record<string, Partial<T>>;
|
|
40
|
+
/**
|
|
41
|
+
* Recursively processes method map with underscore-prefixed descriptors
|
|
42
|
+
*/
|
|
43
|
+
private processMethodMap;
|
|
44
|
+
/**
|
|
45
|
+
* Registers a single method using legacy format
|
|
46
|
+
*/
|
|
47
|
+
private registerLegacyMethod;
|
|
48
|
+
/**
|
|
49
|
+
* Creates a copy of config object excluding specified fields
|
|
50
|
+
*/
|
|
51
|
+
private copyConfig;
|
|
52
|
+
/**
|
|
53
|
+
* Checks if a key represents module metadata
|
|
54
|
+
*/
|
|
55
|
+
private isModuleMeta;
|
|
56
|
+
/**
|
|
57
|
+
* Checks if a key is a descriptor (starts with underscore)
|
|
58
|
+
*/
|
|
59
|
+
private isDescriptor;
|
|
60
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MethodRegistry = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Manages RPC method registration and retrieval
|
|
6
|
+
*/
|
|
7
|
+
class MethodRegistry {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.modules = {};
|
|
10
|
+
this.methods = {};
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Register a new endpoint with modern syntax
|
|
14
|
+
*/
|
|
15
|
+
registerEndpoint(name, config, handler) {
|
|
16
|
+
if (!name || typeof name !== 'string') {
|
|
17
|
+
throw new Error('Endpoint name must be a non-empty string');
|
|
18
|
+
}
|
|
19
|
+
if (typeof handler !== 'function') {
|
|
20
|
+
throw new Error('Endpoint handler must be a function');
|
|
21
|
+
}
|
|
22
|
+
this.modules[name] = Object.assign(Object.assign({}, config), { fullname: name });
|
|
23
|
+
this.methods[name] = handler;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register methods using legacy underscore-prefixed structure
|
|
27
|
+
*/
|
|
28
|
+
registerLegacyMethods(methodMap) {
|
|
29
|
+
this.processMethodMap('', methodMap);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get all registered modules
|
|
33
|
+
*/
|
|
34
|
+
getModules() {
|
|
35
|
+
return Object.assign({}, this.modules);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get all registered methods
|
|
39
|
+
*/
|
|
40
|
+
getMethods() {
|
|
41
|
+
return Object.assign({}, this.methods);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get a specific method by name
|
|
45
|
+
*/
|
|
46
|
+
getMethod(name) {
|
|
47
|
+
return this.methods[name];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get a specific module config by name
|
|
51
|
+
*/
|
|
52
|
+
getModule(name) {
|
|
53
|
+
return this.modules[name];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Check if a method exists
|
|
57
|
+
*/
|
|
58
|
+
hasMethod(name) {
|
|
59
|
+
return name in this.methods;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get method listing excluding internal fields
|
|
63
|
+
*/
|
|
64
|
+
getMethodListing() {
|
|
65
|
+
const result = {};
|
|
66
|
+
const excludeFields = new Set(['fullname']);
|
|
67
|
+
for (const methodName in this.modules) {
|
|
68
|
+
const config = this.modules[methodName];
|
|
69
|
+
result[methodName] = this.copyConfig(config, excludeFields);
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Recursively processes method map with underscore-prefixed descriptors
|
|
75
|
+
*/
|
|
76
|
+
processMethodMap(path, methodMap) {
|
|
77
|
+
const prefix = path ? `${path}.` : '';
|
|
78
|
+
for (const key in methodMap) {
|
|
79
|
+
if (this.isModuleMeta(key) || this.isDescriptor(key)) {
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const descriptor = methodMap[`_${key}`];
|
|
83
|
+
if (!descriptor) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
const item = methodMap[key];
|
|
87
|
+
if (typeof item === 'function') {
|
|
88
|
+
this.registerLegacyMethod(prefix, key, descriptor, item);
|
|
89
|
+
}
|
|
90
|
+
else if (typeof item === 'object' && item !== null) {
|
|
91
|
+
this.processMethodMap(`${prefix}${key}`, item);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Registers a single method using legacy format
|
|
97
|
+
*/
|
|
98
|
+
registerLegacyMethod(prefix, name, descriptor, handler) {
|
|
99
|
+
const fullName = prefix + (descriptor.name || name);
|
|
100
|
+
const config = Object.assign(Object.assign({}, descriptor), { fullname: fullName });
|
|
101
|
+
try {
|
|
102
|
+
this.modules[fullName] = config;
|
|
103
|
+
this.methods[fullName] = handler;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error(`Failed to register method ${fullName}:`, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Creates a copy of config object excluding specified fields
|
|
111
|
+
*/
|
|
112
|
+
copyConfig(source, excludeFields) {
|
|
113
|
+
const result = {};
|
|
114
|
+
for (const key in source) {
|
|
115
|
+
if (!excludeFields.has(key) && Object.prototype.hasOwnProperty.call(source, key)) {
|
|
116
|
+
result[key] = source[key];
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Checks if a key represents module metadata
|
|
123
|
+
*/
|
|
124
|
+
isModuleMeta(key) {
|
|
125
|
+
return key === '_';
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Checks if a key is a descriptor (starts with underscore)
|
|
129
|
+
*/
|
|
130
|
+
isDescriptor(key) {
|
|
131
|
+
return key.startsWith('_');
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
exports.MethodRegistry = MethodRegistry;
|
|
135
|
+
//# sourceMappingURL=method-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"method-registry.js","sourceRoot":"","sources":["../../src/method-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/src/rpc-server.d.ts
CHANGED
|
@@ -1,39 +1,91 @@
|
|
|
1
|
+
import { MethodMap, RequestMessage, EndpointConfig, EndpointHandler, BaseEndpointConfig } from './index';
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
* remotely, to enable access control and return data directly, asynchronously or
|
|
4
|
-
* opening a stream which delivers data for long running tasks or large data
|
|
5
|
-
* transfers.
|
|
3
|
+
* RPC Server for registering and handling remote procedure calls.
|
|
6
4
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* which have a descriptor property with the same name prepended with "_".
|
|
5
|
+
* Supports both modern endpoint registration and legacy underscore-prefixed methods.
|
|
6
|
+
* Provides real-time communication with support for streaming, events, and async operations.
|
|
10
7
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
8
|
+
* Type-safe endpoint registration with custom configuration:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* interface ReasonEndpoint extends BaseEndpointConfig {
|
|
11
|
+
* validateArgs?: (args: any[], context: any) => boolean;
|
|
12
|
+
* permissions?: string[];
|
|
13
|
+
* rateLimit?: number;
|
|
14
|
+
* }
|
|
13
15
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
16
|
+
* const server = new Server<ReasonEndpoint>();
|
|
17
|
+
* server.endpoint('user.get', {
|
|
18
|
+
* doc: 'Get user by ID',
|
|
19
|
+
* args: 'userId: string',
|
|
20
|
+
* validateArgs: (args, context) => validateUserArgs(args),
|
|
21
|
+
* permissions: ['user', 'admin'],
|
|
22
|
+
* rateLimit: 100
|
|
23
|
+
* }, async (req, res) => {
|
|
24
|
+
* const user = await getUserById(req.args[0]);
|
|
25
|
+
* res.send(user);
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* Default usage (backwards compatible):
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const server = new Server();
|
|
32
|
+
* server.endpoint('user.get', {
|
|
33
|
+
* doc: 'Get user by ID',
|
|
34
|
+
* args: 'userId: string',
|
|
35
|
+
* validate: (args, context) => validateUserArgs(args)
|
|
36
|
+
* }, async (req, res) => {
|
|
37
|
+
* const user = await getUserById(req.args[0]);
|
|
38
|
+
* res.send(user);
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*
|
|
42
|
+
* Legacy method registration (backwards compatibility):
|
|
43
|
+
* ```typescript
|
|
44
|
+
* server.insertMethods({
|
|
45
|
+
* _getUser: {
|
|
46
|
+
* doc: 'Get user by ID',
|
|
47
|
+
* args: 'userId: string'
|
|
48
|
+
* },
|
|
49
|
+
* getUser: async (req, res) => {
|
|
50
|
+
* const user = await getUserById(req.args[0]);
|
|
51
|
+
* res.send(user);
|
|
52
|
+
* }
|
|
53
|
+
* });
|
|
54
|
+
* ```
|
|
55
|
+
*
|
|
56
|
+
* Accessing metadata for custom validation and introspection:
|
|
57
|
+
* ```typescript
|
|
58
|
+
* // Get method metadata and check for custom validation properties
|
|
59
|
+
* const meta = server.getMethodMeta('user.get');
|
|
60
|
+
* if (meta?.validateArgs) {
|
|
61
|
+
* const isValid = meta.validateArgs(args, context);
|
|
62
|
+
* }
|
|
63
|
+
* if (meta?.schema) {
|
|
64
|
+
* const result = meta.schema.safeParse(args); // e.g., Zod
|
|
65
|
+
* }
|
|
66
|
+
* if (meta?.validator) {
|
|
67
|
+
* meta.validator.validate(args); // e.g., Joi
|
|
68
|
+
* }
|
|
69
|
+
*
|
|
70
|
+
* // Generate documentation from all methods
|
|
71
|
+
* const allMeta = server.getAllMethodMeta();
|
|
72
|
+
* for (const [name, config] of Object.entries(allMeta)) {
|
|
73
|
+
* console.log(`${name}: ${config.doc || 'No documentation'}`);
|
|
74
|
+
* if (config.args) console.log(` Args: ${config.args}`);
|
|
75
|
+
* }
|
|
76
|
+
* ```
|
|
77
|
+
*
|
|
78
|
+
* Features:
|
|
79
|
+
* - Type-safe endpoint registration with TypeScript
|
|
80
|
+
* - Streaming support for large data transfers
|
|
81
|
+
* - Real-time events and signals
|
|
82
|
+
* - Request validation and error handling
|
|
83
|
+
* - Session management and cleanup
|
|
84
|
+
* - Method discovery and documentation
|
|
85
|
+
* - Metadata access for external validation and introspection
|
|
32
86
|
*/
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
private modules;
|
|
36
|
-
private methods;
|
|
87
|
+
export declare class Server<T extends BaseEndpointConfig = EndpointConfig> {
|
|
88
|
+
private registry;
|
|
37
89
|
private requests;
|
|
38
90
|
private clientIdCounter;
|
|
39
91
|
/** internal request id counter */
|
|
@@ -42,14 +94,60 @@ export declare class Server {
|
|
|
42
94
|
private invokeId;
|
|
43
95
|
constructor(methods?: MethodMap);
|
|
44
96
|
destroy(): void;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
97
|
+
/**
|
|
98
|
+
* Legacy method for backwards compatibility
|
|
99
|
+
* Registers methods using the old underscore-prefixed structure
|
|
100
|
+
*/
|
|
101
|
+
insertMethods(methodMap: MethodMap): void;
|
|
102
|
+
/**
|
|
103
|
+
* Lists all available methods and their configurations
|
|
104
|
+
*/
|
|
105
|
+
listMethods(args: any[], context: any, callback: (error: any, result?: any) => void): void;
|
|
106
|
+
/**
|
|
107
|
+
* Cleanup when a client goes offline
|
|
108
|
+
*/
|
|
48
109
|
clientOffline(clientId: number): void;
|
|
110
|
+
/**
|
|
111
|
+
* Close all active connections and cleanup
|
|
112
|
+
*/
|
|
49
113
|
closeAll(): void;
|
|
50
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Safely cleanup a specific request
|
|
116
|
+
*/
|
|
117
|
+
private cleanupRequest;
|
|
118
|
+
/**
|
|
119
|
+
* Parse and handle incoming RPC messages
|
|
120
|
+
*/
|
|
121
|
+
parse(msg: RequestMessage, respond: (data: any) => void, context: any, clientId: number): void;
|
|
51
122
|
emit(op: string, data: any): void;
|
|
52
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Process raw RPC invocation
|
|
125
|
+
*/
|
|
126
|
+
invokeRaw(msg: RequestMessage, respond: (data: any) => void, context: any, clientId: number): void;
|
|
127
|
+
/**
|
|
128
|
+
* Handle push (streaming data) messages
|
|
129
|
+
*/
|
|
130
|
+
private handlePushMessage;
|
|
131
|
+
/**
|
|
132
|
+
* Handle signal (streaming) messages
|
|
133
|
+
*/
|
|
134
|
+
private handleSignalMessage;
|
|
135
|
+
/**
|
|
136
|
+
* Create response handlers for signal messages
|
|
137
|
+
*/
|
|
138
|
+
private createSignalResponseHandlers;
|
|
139
|
+
/**
|
|
140
|
+
* Handle event messages (no response expected)
|
|
141
|
+
*/
|
|
142
|
+
private handleEventMessage;
|
|
143
|
+
/**
|
|
144
|
+
* Handle regular RPC requests
|
|
145
|
+
*/
|
|
146
|
+
private handleRegularRequest;
|
|
147
|
+
/**
|
|
148
|
+
* Create response handlers for regular requests
|
|
149
|
+
*/
|
|
150
|
+
private createRegularResponseHandlers;
|
|
53
151
|
close(clientId: number): void;
|
|
54
152
|
open(): number;
|
|
55
153
|
/**
|
|
@@ -58,10 +156,16 @@ export declare class Server {
|
|
|
58
156
|
* @param config - Configuration object with doc, args, validate, etc.
|
|
59
157
|
* @param handler - The endpoint handler function
|
|
60
158
|
*/
|
|
61
|
-
endpoint(name: string, config:
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
159
|
+
endpoint(name: string, config: T, handler: EndpointHandler): void;
|
|
160
|
+
/**
|
|
161
|
+
* Get metadata for a specific method (including all custom properties)
|
|
162
|
+
* @param name - Method name
|
|
163
|
+
* @returns The complete method configuration or undefined if not found
|
|
164
|
+
*/
|
|
165
|
+
getMethodMeta(name: string): T | undefined;
|
|
166
|
+
/**
|
|
167
|
+
* Get metadata for all registered methods
|
|
168
|
+
* @returns Object containing all method configurations
|
|
169
|
+
*/
|
|
170
|
+
getAllMethodMeta(): Record<string, T>;
|
|
67
171
|
}
|