rpc-express-toolkit 2.3.0 → 2.3.1
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/README.md +21 -8
- package/package.json +1 -1
- package/src/clients/rpc-client.js +16 -8
- package/src/clients/rpc-client.min.js +1 -1
package/README.md
CHANGED
|
@@ -109,20 +109,21 @@ const client = new RpcClient('/api');
|
|
|
109
109
|
const user = await client.call('getUser', { userId: 123 });
|
|
110
110
|
```
|
|
111
111
|
|
|
112
|
-
#### SSL e certificati self-signed in sviluppo (Node.js)
|
|
113
112
|
|
|
114
|
-
|
|
113
|
+
#### ⚠️ SSL and self-signed certificates in development (Node.js)
|
|
114
|
+
|
|
115
|
+
If you need to connect to a server with a self-signed certificate during development, set the following environment variable **before** starting your Node.js process:
|
|
115
116
|
|
|
116
117
|
```js
|
|
117
118
|
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";
|
|
118
119
|
```
|
|
119
120
|
|
|
120
|
-
**
|
|
121
|
-
-
|
|
122
|
-
-
|
|
123
|
-
-
|
|
121
|
+
**Warning:**
|
|
122
|
+
- This disables SSL certificate validation for all HTTPS requests in the Node.js process.
|
|
123
|
+
- Use this only in development environments!
|
|
124
|
+
- Never commit or enable this setting in production.
|
|
124
125
|
|
|
125
|
-
|
|
126
|
+
Advanced options like `agent` and `ca` have been removed for simplicity and compatibility with modern Node.js. This is the only universal and reliable way to bypass SSL validation for development with self-signed certificates.
|
|
126
127
|
|
|
127
128
|
## Advanced Usage
|
|
128
129
|
|
|
@@ -337,14 +338,26 @@ new RpcClient(baseUrl, options)
|
|
|
337
338
|
|
|
338
339
|
#### Methods
|
|
339
340
|
|
|
341
|
+
|
|
340
342
|
##### `call(method, params, options)`
|
|
341
343
|
|
|
342
344
|
Make a single RPC call.
|
|
343
345
|
|
|
344
346
|
```javascript
|
|
345
|
-
|
|
347
|
+
// If the method does not require parameters, you can omit the params argument:
|
|
348
|
+
const result = await client.call('ping');
|
|
349
|
+
|
|
350
|
+
// If you pass params as undefined or null, the field will be omitted from the JSON-RPC payload (per spec):
|
|
351
|
+
await client.call('ping', undefined);
|
|
352
|
+
await client.call('ping', null);
|
|
353
|
+
|
|
354
|
+
// If you pass an object or array, it will be sent as params:
|
|
355
|
+
await client.call('add', { a: 1, b: 2 });
|
|
346
356
|
```
|
|
347
357
|
|
|
358
|
+
> **Note:**
|
|
359
|
+
> The `params` field is omitted from the JSON-RPC request if you pass `undefined` or `null`, as required by the JSON-RPC 2.0 specification. If you pass an object or array, it will be included as `params`.
|
|
360
|
+
|
|
348
361
|
##### `batch(requests)`
|
|
349
362
|
|
|
350
363
|
Make batch RPC calls.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rpc-express-toolkit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "Enterprise-ready JSON-RPC 2.0 toolkit for Express.js with simplified APIs, structured logging, middleware system, schema validation, comprehensive BigInt/Date support. Semplificato: gestione SSL avanzata rimossa, vedi README.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -77,13 +77,16 @@ class RpcClient {
|
|
|
77
77
|
async call(method, params = {}, id = undefined, overrideHeaders = {}) {
|
|
78
78
|
// Auto-generate ID if not provided (null means notification)
|
|
79
79
|
const requestId = id === undefined ? this.#generateId() : id;
|
|
80
|
-
|
|
80
|
+
|
|
81
|
+
// Costruisci il payload secondo lo standard: params omesso se undefined/null
|
|
81
82
|
const requestBody = {
|
|
82
83
|
jsonrpc: "2.0",
|
|
83
84
|
method,
|
|
84
|
-
params,
|
|
85
85
|
id: requestId,
|
|
86
86
|
};
|
|
87
|
+
if (params !== undefined && params !== null) {
|
|
88
|
+
requestBody.params = params;
|
|
89
|
+
}
|
|
87
90
|
|
|
88
91
|
try {
|
|
89
92
|
const response = await fetchFn(this.#endpoint, {
|
|
@@ -132,12 +135,17 @@ class RpcClient {
|
|
|
132
135
|
* @returns {Promise<Array<any>>} Array of results in the same order as requests.
|
|
133
136
|
*/
|
|
134
137
|
async batch(requests, overrideHeaders = {}) {
|
|
135
|
-
const batchRequests = requests.map(req =>
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
const batchRequests = requests.map(req => {
|
|
139
|
+
const obj = {
|
|
140
|
+
jsonrpc: "2.0",
|
|
141
|
+
method: req.method,
|
|
142
|
+
id: req.id !== undefined ? req.id : this.#generateId()
|
|
143
|
+
};
|
|
144
|
+
if (req.params !== undefined && req.params !== null) {
|
|
145
|
+
obj.params = req.params;
|
|
146
|
+
}
|
|
147
|
+
return obj;
|
|
148
|
+
});
|
|
141
149
|
|
|
142
150
|
try {
|
|
143
151
|
const response = await fetchFn(this.#endpoint, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
let fetchFn;if("undefined"==typeof BigInt||BigInt.prototype.toJSON||(BigInt.prototype.toJSON=function(){return this.toString()}),"undefined"!=typeof fetch)fetchFn=fetch;else try{fetchFn=require("node-fetch")}catch(t){if("undefined"==typeof globalThis||!globalThis.fetch)throw new Error("fetch is not available. Please install node-fetch or use Node.js 18+");fetchFn=globalThis.fetch}class RpcClient{#t;#e;#r;#i;constructor(t,e={},r={}){this.#t=t,this.#e={"Content-Type":"application/json",...e},this.#r=1e3*Date.now()+Math.floor(1e3*Math.random()),this.#i={}}#s(){return++this.#r}async call(t,e={},r=void 0,i={}){const s={jsonrpc:"2.0",method:t,
|
|
1
|
+
let fetchFn;if("undefined"==typeof BigInt||BigInt.prototype.toJSON||(BigInt.prototype.toJSON=function(){return this.toString()}),"undefined"!=typeof fetch)fetchFn=fetch;else try{fetchFn=require("node-fetch")}catch(t){if("undefined"==typeof globalThis||!globalThis.fetch)throw new Error("fetch is not available. Please install node-fetch or use Node.js 18+");fetchFn=globalThis.fetch}class RpcClient{#t;#e;#r;#i;constructor(t,e={},r={}){this.#t=t,this.#e={"Content-Type":"application/json",...e},this.#r=1e3*Date.now()+Math.floor(1e3*Math.random()),this.#i={}}#s(){return++this.#r}async call(t,e={},r=void 0,i={}){const s={jsonrpc:"2.0",method:t,id:void 0===r?this.#s():r};null!=e&&(s.params=e);try{const t=await fetchFn(this.#t,{method:"POST",headers:{...this.#e,...i},body:JSON.stringify(s),...this.#i});if(!t.ok)throw new Error(`HTTP Error: ${t.status} ${t.statusText}`);const e=await t.json();if(e.error)throw e.error;return this.deserializeBigIntsAndDates(e.result)}catch(t){throw console.error("RPC call failed:",t),t}}async notify(t,e={},r={}){await this.call(t,e,null,r)}async batch(t,e={}){const r=t.map(t=>{const e={jsonrpc:"2.0",method:t.method,id:void 0!==t.id?t.id:this.#s()};return void 0!==t.params&&null!==t.params&&(e.params=t.params),e});try{const t=await fetchFn(this.#t,{method:"POST",headers:{...this.#e,...e},body:JSON.stringify(r),...this.#i});if(!t.ok)throw new Error(`HTTP Error: ${t.status} ${t.statusText}`);const i=await t.json();if(Array.isArray(i))return i.map(t=>{if(t.error)throw t.error;return this.deserializeBigIntsAndDates(t.result)});if(i.error)throw i.error;return[this.deserializeBigIntsAndDates(i.result)]}catch(t){throw console.error("Batch RPC call failed:",t),t}}serializeBigIntsAndDates(t){if("bigint"==typeof t)return t.toString();if(Array.isArray(t))return t.map(t=>this.serializeBigIntsAndDates(t));if(t instanceof Date)return t.toISOString();if(t&&"object"==typeof t){const e={};for(const[r,i]of Object.entries(t))e[r]=this.serializeBigIntsAndDates(i);return e}return t}deserializeBigIntsAndDates(t){const e=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})?$/;if("string"==typeof t){if(/^-?\d+n?$/.test(t))return BigInt(t.replace(/n$/,""));if(e.test(t)){const e=new Date(t);if(!isNaN(e.getTime()))return e}}return Array.isArray(t)?t.map(t=>this.deserializeBigIntsAndDates(t)):t&&"object"==typeof t?Object.fromEntries(Object.entries(t).map(([t,e])=>[t,this.deserializeBigIntsAndDates(e)])):t}}module.exports=RpcClient,module.exports.RpcClient=RpcClient;
|