rpc-express-toolkit 4.2.1 → 4.3.2
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/LICENSE +0 -0
- package/README.md +88 -9
- package/examples/example.js +0 -0
- package/examples/introspection/client.js +68 -68
- package/examples/introspection/server.js +89 -89
- package/examples/safe-preset-example.js +0 -0
- package/examples/server-client-example.js +0 -0
- package/examples/ssl-development-example.js +0 -0
- package/package.json +124 -126
- package/src/batch.js +90 -55
- package/src/index.d.ts +33 -63
- package/src/index.js +1153 -1035
- package/src/logger.js +17 -5
- package/src/middleware.js +0 -0
- package/src/protocol.js +97 -0
- package/src/safe.d.ts +0 -0
- package/src/safe.js +0 -0
- package/src/validation.js +222 -222
- package/src/clients/rpc-client.js +0 -403
- package/src/clients/rpc-client.min.js +0 -1
- package/src/clients/rpc-client.min.mjs +0 -1
- package/src/clients/rpc-client.mjs +0 -393
package/LICENSE
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
@@ -42,9 +42,61 @@ app.listen(3000);
|
|
|
42
42
|
### Client
|
|
43
43
|
|
|
44
44
|
```javascript
|
|
45
|
-
const { RpcClient } = require('rpc-express-toolkit');
|
|
45
|
+
const { RpcClient, RpcSafeClient } = require('rpc-express-toolkit');
|
|
46
|
+
|
|
46
47
|
const client = new RpcClient('http://localhost:3000/api');
|
|
47
48
|
const sum = await client.call('add', { a: 1, b: 2 });
|
|
49
|
+
|
|
50
|
+
const safeClient = new RpcSafeClient('http://localhost:3000/api');
|
|
51
|
+
await safeClient.notify('add', { a: 0, b: 0 });
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
`RpcClient` and `RpcSafeClient` are re-exported from the shared `rpc-toolkit-js-client` package, so existing Node.js imports from `rpc-express-toolkit` continue to work.
|
|
55
|
+
|
|
56
|
+
### Browser Client Assets
|
|
57
|
+
|
|
58
|
+
Serve the shared browser client bundles from the endpoint:
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
const { RpcEndpoint } = require('rpc-express-toolkit');
|
|
62
|
+
|
|
63
|
+
RpcEndpoint.serveScripts(app);
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Default paths:
|
|
67
|
+
|
|
68
|
+
```text
|
|
69
|
+
/vendor/rpc-client/rpc-client.js
|
|
70
|
+
/vendor/rpc-client/rpc-client.min.js
|
|
71
|
+
/vendor/rpc-client/rpc-client.mjs
|
|
72
|
+
/vendor/rpc-client/rpc-client.min.mjs
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Classic browser script:
|
|
76
|
+
|
|
77
|
+
```html
|
|
78
|
+
<script src="/vendor/rpc-client/rpc-client.min.js"></script>
|
|
79
|
+
<script>
|
|
80
|
+
const client = new RpcToolkitClient.RpcClient('/api');
|
|
81
|
+
const safeClient = new RpcToolkitClient.RpcSafeClient('/api');
|
|
82
|
+
|
|
83
|
+
client.call('add', { a: 1, b: 2 }).then(console.log);
|
|
84
|
+
safeClient.notify('add', { a: 0, b: 0 });
|
|
85
|
+
</script>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Module script:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<script type="module">
|
|
92
|
+
import { RpcClient, RpcSafeClient } from '/vendor/rpc-client/rpc-client.mjs';
|
|
93
|
+
|
|
94
|
+
const client = new RpcClient('/api');
|
|
95
|
+
const safeClient = new RpcSafeClient('/api');
|
|
96
|
+
|
|
97
|
+
console.log(await client.call('add', { a: 1, b: 2 }));
|
|
98
|
+
await safeClient.notify('add', { a: 0, b: 0 });
|
|
99
|
+
</script>
|
|
48
100
|
```
|
|
49
101
|
|
|
50
102
|
### Safe Type Disambiguation (optional)
|
|
@@ -60,6 +112,31 @@ Safe type disambiguation is disabled by default for maximum JSON-RPC 2.0 compati
|
|
|
60
112
|
- `client.batch([...])`: batch.
|
|
61
113
|
- `client.notify(method, params?)`: notification.
|
|
62
114
|
|
|
115
|
+
## Authentication And Method Restrictions
|
|
116
|
+
|
|
117
|
+
Authentication is supported through the built-in `auth` middleware. The `auth` option is a function that receives the Express request. Returning a truthy value allows the RPC call; returning a falsy value rejects it with JSON-RPC error `-32001` and message `Authentication required`. Throwing also rejects the call and returns a JSON-RPC error based on the thrown error.
|
|
118
|
+
|
|
119
|
+
```js
|
|
120
|
+
const rpc = new RpcEndpoint(app, context, {
|
|
121
|
+
auth: async (req) => {
|
|
122
|
+
const token = req.headers.authorization;
|
|
123
|
+
return token === 'Bearer secret-token';
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
rpc.addMethod('ping', () => 'pong');
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
For simple method-level restriction, use `methodWhitelist`:
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
const rpc = new RpcEndpoint(app, context, {
|
|
134
|
+
methodWhitelist: ['ping', 'status.read'],
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Calls to methods outside the whitelist are rejected. This is a basic method restriction mechanism, not a complete role or permission system. Project-specific authorization rules can be implemented with middleware hooks such as `beforeCall`; see `README_ADVANCED.md`.
|
|
139
|
+
|
|
63
140
|
### Safe Import (opt-in)
|
|
64
141
|
|
|
65
142
|
[](https://www.npmjs.com/package/rpc-express-toolkit-safe)
|
|
@@ -70,16 +147,16 @@ When you control both client and server and want safer type round-trips, import
|
|
|
70
147
|
```js
|
|
71
148
|
// Server (safe preset)
|
|
72
149
|
const express = require('express');
|
|
73
|
-
const {
|
|
150
|
+
const { RpcSafeEndpoint } = require('rpc-express-toolkit/safe');
|
|
74
151
|
|
|
75
152
|
const app = express();
|
|
76
153
|
app.use(express.json());
|
|
77
154
|
|
|
78
|
-
const rpc =
|
|
155
|
+
const rpc = new RpcSafeEndpoint(app, {}, { endpoint: '/api' /* strictMode: true by default */ });
|
|
79
156
|
|
|
80
157
|
// Client (safe preset)
|
|
81
|
-
const {
|
|
82
|
-
const client =
|
|
158
|
+
const { RpcSafeClient } = require('rpc-express-toolkit/safe');
|
|
159
|
+
const client = new RpcSafeClient('http://localhost:3000/api');
|
|
83
160
|
```
|
|
84
161
|
|
|
85
162
|
This keeps JSON-RPC 2.0 compliance as default for the main entrypoint, while offering a convenient safe-mode import for projects that prefer explicit type disambiguation.
|
|
@@ -95,14 +172,14 @@ npm install rpc-express-toolkit-safe
|
|
|
95
172
|
```js
|
|
96
173
|
// Server
|
|
97
174
|
const express = require('express');
|
|
98
|
-
const {
|
|
175
|
+
const { RpcSafeEndpoint } = require('rpc-express-toolkit-safe');
|
|
99
176
|
const app = express();
|
|
100
177
|
app.use(express.json());
|
|
101
|
-
const rpc =
|
|
178
|
+
const rpc = new RpcSafeEndpoint(app, {}, { endpoint: '/api' });
|
|
102
179
|
|
|
103
180
|
// Client
|
|
104
|
-
const {
|
|
105
|
-
const client =
|
|
181
|
+
const { RpcSafeClient } = require('rpc-express-toolkit-safe');
|
|
182
|
+
const client = new RpcSafeClient('http://localhost:3000/api');
|
|
106
183
|
```
|
|
107
184
|
|
|
108
185
|
## Introspection Methods
|
|
@@ -142,6 +219,8 @@ const methods = await client.call('__rpc.listMethods');
|
|
|
142
219
|
const addInfo = await client.call('__rpc.describe', { method: 'add' });
|
|
143
220
|
```
|
|
144
221
|
|
|
222
|
+
In `__rpc.capabilities`, `auth` is a boolean indicating whether authentication middleware is configured. It does not expose roles, scopes, or permission rules.
|
|
223
|
+
|
|
145
224
|
**Note:** The introspection prefix is configurable via `introspectionPrefix` option (default: `__rpc`). User methods starting with this prefix are rejected to prevent conflicts.
|
|
146
225
|
|
|
147
226
|
## Full Details
|
package/examples/example.js
CHANGED
|
File without changes
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Introspection Example - Client
|
|
3
|
-
* Demonstrates how to use __rpc.* introspection methods
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { RpcClient } = require('../..');
|
|
7
|
-
|
|
8
|
-
async function main() {
|
|
9
|
-
const client = new RpcClient('http://localhost:3000/api');
|
|
10
|
-
|
|
11
|
-
console.log('=== RPC Introspection Demo ===\n');
|
|
12
|
-
|
|
13
|
-
// 1. List all methods
|
|
14
|
-
console.log('1. __rpc.listMethods():');
|
|
15
|
-
const methods = await client.call('__rpc.listMethods');
|
|
16
|
-
console.log(' Available methods:', methods);
|
|
17
|
-
console.log('');
|
|
18
|
-
|
|
19
|
-
// 2. Get version info
|
|
20
|
-
console.log('2. __rpc.version():');
|
|
21
|
-
const version = await client.call('__rpc.version');
|
|
22
|
-
console.log(' Toolkit:', version.toolkit);
|
|
23
|
-
console.log(' Version:', version.version);
|
|
24
|
-
console.log(' Express:', version.expressVersion);
|
|
25
|
-
console.log(' Node:', version.nodeVersion);
|
|
26
|
-
console.log('');
|
|
27
|
-
|
|
28
|
-
// 3. Get server capabilities
|
|
29
|
-
console.log('3. __rpc.capabilities():');
|
|
30
|
-
const caps = await client.call('__rpc.capabilities');
|
|
31
|
-
console.log(' Safe Mode:', caps.safeMode);
|
|
32
|
-
console.log(' Batch Support:', caps.batch);
|
|
33
|
-
console.log(' Introspection:', caps.introspection);
|
|
34
|
-
console.log(' Method Count:', caps.methodCount);
|
|
35
|
-
console.log('');
|
|
36
|
-
|
|
37
|
-
// 4. Describe a specific method
|
|
38
|
-
console.log('4. __rpc.describe({ method: "add" }):');
|
|
39
|
-
const addInfo = await client.call('__rpc.describe', { method: 'add' });
|
|
40
|
-
console.log(' Name:', addInfo.name);
|
|
41
|
-
console.log(' Description:', addInfo.description);
|
|
42
|
-
console.log(' Schema:', JSON.stringify(addInfo.schema, null, 2));
|
|
43
|
-
console.log('');
|
|
44
|
-
|
|
45
|
-
// 5. Describe all public methods
|
|
46
|
-
console.log('5. __rpc.describeAll():');
|
|
47
|
-
const allMethods = await client.call('__rpc.describeAll');
|
|
48
|
-
allMethods.forEach((method) => {
|
|
49
|
-
console.log(` - ${method.name}: ${method.description}`);
|
|
50
|
-
});
|
|
51
|
-
console.log('');
|
|
52
|
-
|
|
53
|
-
// 6. Try to describe a private method (should fail)
|
|
54
|
-
console.log('6. Try to describe private method:');
|
|
55
|
-
try {
|
|
56
|
-
await client.call('__rpc.describe', { method: 'internalCalculation' });
|
|
57
|
-
} catch (error) {
|
|
58
|
-
console.log(' Error:', error.message);
|
|
59
|
-
}
|
|
60
|
-
console.log('');
|
|
61
|
-
|
|
62
|
-
// 7. Test a public method
|
|
63
|
-
console.log('7. Call add method:');
|
|
64
|
-
const sum = await client.call('add', { a: 5, b: 3 });
|
|
65
|
-
console.log(' 5 + 3 =', sum);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
main().catch(console.error);
|
|
1
|
+
/**
|
|
2
|
+
* Introspection Example - Client
|
|
3
|
+
* Demonstrates how to use __rpc.* introspection methods
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { RpcClient } = require('../..');
|
|
7
|
+
|
|
8
|
+
async function main() {
|
|
9
|
+
const client = new RpcClient('http://localhost:3000/api');
|
|
10
|
+
|
|
11
|
+
console.log('=== RPC Introspection Demo ===\n');
|
|
12
|
+
|
|
13
|
+
// 1. List all methods
|
|
14
|
+
console.log('1. __rpc.listMethods():');
|
|
15
|
+
const methods = await client.call('__rpc.listMethods');
|
|
16
|
+
console.log(' Available methods:', methods);
|
|
17
|
+
console.log('');
|
|
18
|
+
|
|
19
|
+
// 2. Get version info
|
|
20
|
+
console.log('2. __rpc.version():');
|
|
21
|
+
const version = await client.call('__rpc.version');
|
|
22
|
+
console.log(' Toolkit:', version.toolkit);
|
|
23
|
+
console.log(' Version:', version.version);
|
|
24
|
+
console.log(' Express:', version.expressVersion);
|
|
25
|
+
console.log(' Node:', version.nodeVersion);
|
|
26
|
+
console.log('');
|
|
27
|
+
|
|
28
|
+
// 3. Get server capabilities
|
|
29
|
+
console.log('3. __rpc.capabilities():');
|
|
30
|
+
const caps = await client.call('__rpc.capabilities');
|
|
31
|
+
console.log(' Safe Mode:', caps.safeMode);
|
|
32
|
+
console.log(' Batch Support:', caps.batch);
|
|
33
|
+
console.log(' Introspection:', caps.introspection);
|
|
34
|
+
console.log(' Method Count:', caps.methodCount);
|
|
35
|
+
console.log('');
|
|
36
|
+
|
|
37
|
+
// 4. Describe a specific method
|
|
38
|
+
console.log('4. __rpc.describe({ method: "add" }):');
|
|
39
|
+
const addInfo = await client.call('__rpc.describe', { method: 'add' });
|
|
40
|
+
console.log(' Name:', addInfo.name);
|
|
41
|
+
console.log(' Description:', addInfo.description);
|
|
42
|
+
console.log(' Schema:', JSON.stringify(addInfo.schema, null, 2));
|
|
43
|
+
console.log('');
|
|
44
|
+
|
|
45
|
+
// 5. Describe all public methods
|
|
46
|
+
console.log('5. __rpc.describeAll():');
|
|
47
|
+
const allMethods = await client.call('__rpc.describeAll');
|
|
48
|
+
allMethods.forEach((method) => {
|
|
49
|
+
console.log(` - ${method.name}: ${method.description}`);
|
|
50
|
+
});
|
|
51
|
+
console.log('');
|
|
52
|
+
|
|
53
|
+
// 6. Try to describe a private method (should fail)
|
|
54
|
+
console.log('6. Try to describe private method:');
|
|
55
|
+
try {
|
|
56
|
+
await client.call('__rpc.describe', { method: 'internalCalculation' });
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.log(' Error:', error.message);
|
|
59
|
+
}
|
|
60
|
+
console.log('');
|
|
61
|
+
|
|
62
|
+
// 7. Test a public method
|
|
63
|
+
console.log('7. Call add method:');
|
|
64
|
+
const sum = await client.call('add', { a: 5, b: 3 });
|
|
65
|
+
console.log(' 5 + 3 =', sum);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
main().catch(console.error);
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Introspection Example - Server
|
|
3
|
-
* Demonstrates how to enable and use __rpc.* introspection methods
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const express = require('express');
|
|
7
|
-
const { RpcEndpoint } = require('../..');
|
|
8
|
-
|
|
9
|
-
const app = express();
|
|
10
|
-
app.use(express.json());
|
|
11
|
-
|
|
12
|
-
// Context for methods
|
|
13
|
-
const context = {
|
|
14
|
-
database: 'mock-db',
|
|
15
|
-
config: { maxValue: 1000 },
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// Create endpoint with introspection enabled
|
|
19
|
-
const rpc = new RpcEndpoint(app, context, {
|
|
20
|
-
endpoint: '/api',
|
|
21
|
-
enableIntrospection: true, // Enable __rpc.* methods
|
|
22
|
-
introspectionPrefix: '__rpc', // Optional: customize prefix (default: __rpc)
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
// Public method with exposed schema
|
|
26
|
-
rpc.addMethod('add', async (req, ctx, params) => params.a + params.b, {
|
|
27
|
-
schema: {
|
|
28
|
-
type: 'object',
|
|
29
|
-
properties: {
|
|
30
|
-
a: { type: 'number' },
|
|
31
|
-
b: { type: 'number' },
|
|
32
|
-
},
|
|
33
|
-
required: ['a', 'b'],
|
|
34
|
-
},
|
|
35
|
-
exposeSchema: true,
|
|
36
|
-
description: 'Add two numbers and return the sum',
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
// Public method with exposed schema
|
|
40
|
-
rpc.addMethod('multiply', async (req, ctx, params) => params.a * params.b, {
|
|
41
|
-
schema: {
|
|
42
|
-
type: 'object',
|
|
43
|
-
properties: {
|
|
44
|
-
a: { type: 'number' },
|
|
45
|
-
b: { type: 'number' },
|
|
46
|
-
},
|
|
47
|
-
required: ['a', 'b'],
|
|
48
|
-
},
|
|
49
|
-
exposeSchema: true,
|
|
50
|
-
description: 'Multiply two numbers',
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Private method (schema not exposed)
|
|
54
|
-
rpc.addMethod(
|
|
55
|
-
'internalCalculation',
|
|
56
|
-
async (req, ctx, params) => params.value * 2 + 42,
|
|
57
|
-
{
|
|
58
|
-
schema: {
|
|
59
|
-
type: 'object',
|
|
60
|
-
properties: {
|
|
61
|
-
value: { type: 'number' },
|
|
62
|
-
},
|
|
63
|
-
required: ['value'],
|
|
64
|
-
},
|
|
65
|
-
exposeSchema: false, // Schema is private
|
|
66
|
-
description: 'Internal calculation (not exposed)',
|
|
67
|
-
}
|
|
68
|
-
);
|
|
69
|
-
|
|
70
|
-
// Public method without schema
|
|
71
|
-
rpc.addMethod('echo', async (req, ctx, params) => params, {
|
|
72
|
-
exposeSchema: true,
|
|
73
|
-
description: 'Echo back the parameters',
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
// Start server
|
|
77
|
-
const PORT = process.env.PORT || 3000;
|
|
78
|
-
app.listen(PORT, () => {
|
|
79
|
-
console.log(
|
|
80
|
-
`RPC Server with introspection running on http://localhost:${PORT}/api`
|
|
81
|
-
);
|
|
82
|
-
console.log('\nAvailable introspection methods:');
|
|
83
|
-
console.log('- __rpc.listMethods()');
|
|
84
|
-
console.log('- __rpc.describe({method: "add"})');
|
|
85
|
-
console.log('- __rpc.describeAll()');
|
|
86
|
-
console.log('- __rpc.version()');
|
|
87
|
-
console.log('- __rpc.capabilities()');
|
|
88
|
-
console.log('\nTry: node client.js');
|
|
89
|
-
});
|
|
1
|
+
/**
|
|
2
|
+
* Introspection Example - Server
|
|
3
|
+
* Demonstrates how to enable and use __rpc.* introspection methods
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const express = require('express');
|
|
7
|
+
const { RpcEndpoint } = require('../..');
|
|
8
|
+
|
|
9
|
+
const app = express();
|
|
10
|
+
app.use(express.json());
|
|
11
|
+
|
|
12
|
+
// Context for methods
|
|
13
|
+
const context = {
|
|
14
|
+
database: 'mock-db',
|
|
15
|
+
config: { maxValue: 1000 },
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
// Create endpoint with introspection enabled
|
|
19
|
+
const rpc = new RpcEndpoint(app, context, {
|
|
20
|
+
endpoint: '/api',
|
|
21
|
+
enableIntrospection: true, // Enable __rpc.* methods
|
|
22
|
+
introspectionPrefix: '__rpc', // Optional: customize prefix (default: __rpc)
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Public method with exposed schema
|
|
26
|
+
rpc.addMethod('add', async (req, ctx, params) => params.a + params.b, {
|
|
27
|
+
schema: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
a: { type: 'number' },
|
|
31
|
+
b: { type: 'number' },
|
|
32
|
+
},
|
|
33
|
+
required: ['a', 'b'],
|
|
34
|
+
},
|
|
35
|
+
exposeSchema: true,
|
|
36
|
+
description: 'Add two numbers and return the sum',
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Public method with exposed schema
|
|
40
|
+
rpc.addMethod('multiply', async (req, ctx, params) => params.a * params.b, {
|
|
41
|
+
schema: {
|
|
42
|
+
type: 'object',
|
|
43
|
+
properties: {
|
|
44
|
+
a: { type: 'number' },
|
|
45
|
+
b: { type: 'number' },
|
|
46
|
+
},
|
|
47
|
+
required: ['a', 'b'],
|
|
48
|
+
},
|
|
49
|
+
exposeSchema: true,
|
|
50
|
+
description: 'Multiply two numbers',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Private method (schema not exposed)
|
|
54
|
+
rpc.addMethod(
|
|
55
|
+
'internalCalculation',
|
|
56
|
+
async (req, ctx, params) => params.value * 2 + 42,
|
|
57
|
+
{
|
|
58
|
+
schema: {
|
|
59
|
+
type: 'object',
|
|
60
|
+
properties: {
|
|
61
|
+
value: { type: 'number' },
|
|
62
|
+
},
|
|
63
|
+
required: ['value'],
|
|
64
|
+
},
|
|
65
|
+
exposeSchema: false, // Schema is private
|
|
66
|
+
description: 'Internal calculation (not exposed)',
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Public method without schema
|
|
71
|
+
rpc.addMethod('echo', async (req, ctx, params) => params, {
|
|
72
|
+
exposeSchema: true,
|
|
73
|
+
description: 'Echo back the parameters',
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Start server
|
|
77
|
+
const PORT = process.env.PORT || 3000;
|
|
78
|
+
app.listen(PORT, () => {
|
|
79
|
+
console.log(
|
|
80
|
+
`RPC Server with introspection running on http://localhost:${PORT}/api`
|
|
81
|
+
);
|
|
82
|
+
console.log('\nAvailable introspection methods:');
|
|
83
|
+
console.log('- __rpc.listMethods()');
|
|
84
|
+
console.log('- __rpc.describe({method: "add"})');
|
|
85
|
+
console.log('- __rpc.describeAll()');
|
|
86
|
+
console.log('- __rpc.version()');
|
|
87
|
+
console.log('- __rpc.capabilities()');
|
|
88
|
+
console.log('\nTry: node client.js');
|
|
89
|
+
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|