rpc-express-toolkit 3.0.2 β†’ 4.0.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.
@@ -10,7 +10,7 @@ const context = {
10
10
  userId: 'system',
11
11
  };
12
12
 
13
- // Create JSON-RPC endpoint with clean names
13
+ // Create JSON-RPC endpoint
14
14
  const rpc = new RpcEndpoint(app, context);
15
15
 
16
16
  // Add some methods
@@ -29,12 +29,12 @@ rpc.addMethod('getData', (req, ctx, params) => {
29
29
  return { key, value };
30
30
  });
31
31
 
32
- rpc.addMethod('getAllData', (req, ctx) => {
33
- return Array.from(ctx.database.entries()).map(([key, value]) => ({
32
+ rpc.addMethod('getAllData', (req, ctx) =>
33
+ Array.from(ctx.database.entries()).map(([key, value]) => ({
34
34
  key,
35
35
  value,
36
- }));
37
- });
36
+ }))
37
+ );
38
38
 
39
39
  rpc.addMethod('testBigInt', (req, ctx, params) => {
40
40
  const bigNumber = BigInt(params.number || '123456789012345678901234567890');
@@ -49,61 +49,61 @@ rpc.addMethod('testBigInt', (req, ctx, params) => {
49
49
  // Start server
50
50
  const PORT = process.env.PORT || 3000;
51
51
  const server = app.listen(PORT, () => {
52
- console.log(`πŸš€ JSON-RPC Server running on http://localhost:${PORT}`);
53
- console.log(`πŸ“‘ Endpoint: http://localhost:${PORT}/api`);
52
+ console.log(`Server running on http://localhost:${PORT}`);
53
+ console.log(`Endpoint: http://localhost:${PORT}/api`);
54
54
 
55
55
  // === CLIENT DEMO ===
56
56
  setTimeout(async () => {
57
- console.log('\nπŸ”§ Testing client...');
57
+ console.log('\nTesting client...');
58
58
 
59
59
  const client = new RpcClient(`http://localhost:${PORT}/api`);
60
60
 
61
61
  try {
62
62
  // Test 1: Save some data
63
- console.log('πŸ“ Saving data...');
63
+ console.log('Saving data...');
64
64
  const saveResult = await client.call('saveData', {
65
65
  key: 'test',
66
66
  value: 'Hello World!',
67
67
  });
68
- console.log('βœ… Save result:', saveResult);
68
+ console.log('Save result:', saveResult);
69
69
 
70
70
  // Test 2: Get data back
71
- console.log('\nπŸ“– Getting data...');
71
+ console.log('\nGetting data...');
72
72
  const getData = await client.call('getData', { key: 'test' });
73
- console.log('βœ… Get result:', getData);
73
+ console.log('Get result:', getData);
74
74
 
75
75
  // Test 3: Test BigInt handling
76
- console.log('\nπŸ”’ Testing BigInt...');
76
+ console.log('\nTesting BigInt...');
77
77
  const bigIntResult = await client.call('testBigInt', {
78
78
  number: '999999999999999999999999999999',
79
79
  });
80
- console.log('βœ… BigInt result:', bigIntResult);
81
- console.log(' - Original BigInt type:', typeof bigIntResult.bigint);
82
- console.log(' - Doubled BigInt type:', typeof bigIntResult.doubled);
83
- console.log(' - Timestamp type:', typeof bigIntResult.timestamp);
80
+ console.log('BigInt result:', bigIntResult);
81
+ console.log(' - bigint type:', typeof bigIntResult.bigint);
82
+ console.log(' - doubled type:', typeof bigIntResult.doubled);
83
+ console.log(' - timestamp type:', typeof bigIntResult.timestamp);
84
84
 
85
85
  // Test 4: Get all data
86
- console.log('\nπŸ“Š Getting all data...');
86
+ console.log('\nGetting all data...');
87
87
  const allData = await client.call('getAllData');
88
- console.log('βœ… All data:', allData);
88
+ console.log('All data:', allData);
89
89
 
90
90
  // Test 5: Test error handling
91
- console.log('\n❌ Testing error handling...');
91
+ console.log('\nTesting error handling...');
92
92
  try {
93
93
  await client.call('getData', { key: 'nonexistent' });
94
94
  } catch (error) {
95
- console.log('βœ… Error caught correctly:', error.message);
95
+ console.log('Error caught correctly:', error.message);
96
96
  }
97
97
 
98
- console.log('\n✨ All tests completed successfully!');
98
+ console.log('\nAll tests completed successfully!');
99
99
  } catch (error) {
100
- console.error('❌ Client error:', error);
100
+ console.error('Client error:', error);
101
101
  }
102
102
 
103
103
  // Close server after demo
104
104
  setTimeout(() => {
105
105
  server.close(() => {
106
- console.log('\nπŸ‘‹ Server closed');
106
+ console.log('\nServer closed');
107
107
  process.exit(0);
108
108
  });
109
109
  }, 1000);
@@ -112,9 +112,9 @@ const server = app.listen(PORT, () => {
112
112
 
113
113
  // Handle graceful shutdown
114
114
  process.on('SIGINT', () => {
115
- console.log('\nπŸ›‘ Shutting down server...');
115
+ console.log('\nShutting down server...');
116
116
  server.close(() => {
117
- console.log('πŸ‘‹ Server closed');
117
+ console.log('Server closed');
118
118
  process.exit(0);
119
119
  });
120
120
  });
@@ -1,15 +1,8 @@
1
+ /* eslint-disable no-unused-vars, no-console */
1
2
  /**
2
- * Example demonstratin // Example 3: Best practices
3
- console.log('3. Best Practices:');
4
- console.log(' βœ“ Always use SSL validation in production');
5
- console.log(' βœ“ Disable validation only for development with self-signed certificates');
6
- console.log(' βœ“ Use environment variables to control SSL behavior');
7
- console.log(' βœ“ Never commit process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" to production');
8
- console.log(' βœ“ Consider using valid development certificates instead of disabling validation\n');o use RpcClient with self-signed certificates
9
- * in development environments.
10
- *
11
- * WARNING: Only use rejectUnauthorized: false in development!
12
- * Never use this in production as it disables SSL certificate validation.
3
+ * Example: Using RpcClient with self-signed certificates in development.
4
+ *
5
+ * WARNING: Do not disable SSL validation in production.
13
6
  */
14
7
 
15
8
  const { RpcClient } = require('../src/index.js');
@@ -22,35 +15,33 @@ async function demonstrateSSLOptions() {
22
15
  const productionClient = new RpcClient('https://api.example.com/rpc', {
23
16
  Authorization: 'Bearer prod-token',
24
17
  });
25
- console.log(' βœ“ Created client with strict SSL validation (default)\n');
18
+ console.log(' - Created client with strict SSL validation (default)\n');
26
19
 
27
- // Example 2: Development client for self-signed certificates (bypasses ALL SSL validation)
28
- console.log('2. Development Client (bypasses SSL validation):');
20
+ // Example 2: Development client for self-signed certificates (bypass validation)
21
+ console.log('2. Development Client (bypass SSL validation):');
29
22
  console.log(
30
- ' ⚠️ To bypass SSL validation in Node.js, set BEFORE starting the client:'
23
+ ' To bypass SSL validation in Node.js, set BEFORE starting the client:'
31
24
  );
32
25
  console.log(' process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0";');
33
26
  console.log(
34
- ' βœ“ All requests will accept self-signed certificates (development only!)\n'
27
+ ' - All requests will accept self-signed certificates (development only!)\n'
35
28
  );
36
29
 
37
- // Example 3: Best practice
30
+ // Example 3: Best practices summary
38
31
  console.log('3. Best Practices:');
39
- console.log(' βœ“ Usa sempre la validazione SSL in produzione');
40
- console.log(
41
- ' βœ“ Disabilita la validazione solo per sviluppo con self-signed'
42
- );
32
+ console.log(' - Always use SSL validation in production');
43
33
  console.log(
44
- ' βœ“ Usa variabili d’ambiente per controllare il comportamento SSL'
34
+ ' - Disable validation only for development with self-signed certificates'
45
35
  );
36
+ console.log(' - Use environment variables to control SSL behavior');
46
37
  console.log(
47
- ' βœ“ Non committare mai process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" in produzione'
38
+ ' - Never commit process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0" to production'
48
39
  );
49
40
  console.log(
50
- ' βœ“ Considera l’uso di certificati di sviluppo validi invece di disabilitare la validazione\n'
41
+ ' - Consider using valid development certificates instead of disabling validation\n'
51
42
  );
52
43
 
53
- // Example 4: Demonstrate how to choose configuration based on environment
44
+ // Example 4: Choose configuration based on environment
54
45
  console.log('4. Environment-based Configuration:');
55
46
  const isDevelopment = process.env.NODE_ENV === 'development';
56
47
  const baseUrl = isDevelopment
@@ -61,32 +52,10 @@ async function demonstrateSSLOptions() {
61
52
  'X-Environment': process.env.NODE_ENV || 'development',
62
53
  });
63
54
  console.log(
64
- ` βœ“ Created client for ${isDevelopment ? 'development' : 'production'} environment`
65
- );
66
- console.log(
67
- ` βœ“ SSL validation: ${isDevelopment ? 'controlled by NODE_TLS_REJECT_UNAUTHORIZED' : 'enabled (secure)'}\n`
68
- );
69
-
70
- // Example usage (commented out since we don't have a real server)
71
- /*
72
- try {
73
- // This would work with a real server
74
- const result = await developmentClient.call('ping', {});
75
- console.log('Server response:', result);
76
- } catch (error) {
77
- console.error('Error calling server:', error.message);
78
- }
79
- */
80
-
81
- console.log('5. Best Practices Summary:');
82
- console.log(' βœ“ Always use strict SSL validation in production');
83
- console.log(
84
- ' βœ“ Only disable SSL validation for development with self-signed certificates'
55
+ ` - Created client for ${isDevelopment ? 'development' : 'production'} environment`
85
56
  );
86
- console.log(' βœ“ Use environment variables to control SSL behavior');
87
- console.log(' βœ“ Never commit rejectUnauthorized: false to production code');
88
57
  console.log(
89
- ' βœ“ Consider using proper development certificates instead of disabling validation\n'
58
+ ` - SSL validation: ${isDevelopment ? 'controlled by NODE_TLS_REJECT_UNAUTHORIZED' : 'enabled (secure)'}\n`
90
59
  );
91
60
 
92
61
  console.log('=== Example Complete ===');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rpc-express-toolkit",
3
- "version": "3.0.2",
3
+ "version": "4.0.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. JSON middleware validation and explicit configuration.",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -19,8 +19,8 @@
19
19
  "clean": "node -e \"require('fs').existsSync('dist') && require('fs').rmSync('dist', {recursive: true})\"",
20
20
  "build": "npm run build:minify",
21
21
  "build:minify": "npm run build:js && npm run build:mjs",
22
- "build:js": "terser src/clients/rpc-client.js -o src/clients/rpc-client.min.js --compress --mangle --comments false",
23
- "build:mjs": "terser src/clients/rpc-client.mjs -o src/clients/rpc-client.min.mjs --compress --mangle --comments false --module",
22
+ "build:js": "terser src/clients/rpc-client.js -o src/clients/rpc-client.min.js --compress --mangle --comments false --ecma 2020",
23
+ "build:mjs": "terser src/clients/rpc-client.mjs -o src/clients/rpc-client.min.mjs --compress --mangle --comments false --module --ecma 2020",
24
24
  "prepublishOnly": "npm run build",
25
25
  "precommit": "npm run lint && npm test"
26
26
  },
@@ -30,6 +30,8 @@
30
30
  },
31
31
  "keywords": [
32
32
  "json-rpc",
33
+ "jsonrpc",
34
+ "json-rpc-2.0",
33
35
  "express",
34
36
  "toolkit",
35
37
  "rpc",
@@ -37,13 +39,24 @@
37
39
  "client",
38
40
  "middleware",
39
41
  "validation",
42
+ "schema",
43
+ "ajv",
40
44
  "bigint",
45
+ "date",
41
46
  "enterprise",
42
47
  "nodejs",
48
+ "node",
49
+ "browser",
43
50
  "ssl",
44
51
  "self-signed",
45
52
  "secure",
46
- "fetch"
53
+ "fetch",
54
+ "batch",
55
+ "typescript",
56
+ "logging",
57
+ "cors",
58
+ "rate-limit",
59
+ "authentication"
47
60
  ],
48
61
  "author": "Nicola Carpanese <nicola.carpanese@gmail.com>",
49
62
  "license": "MIT",
@@ -52,7 +65,7 @@
52
65
  },
53
66
  "homepage": "https://github.com/n-car/rpc-express-toolkit#readme",
54
67
  "engines": {
55
- "node": ">=14.0.0"
68
+ "node": ">=18.0.0"
56
69
  },
57
70
  "devDependencies": {
58
71
  "eslint": "^8.57.1",
package/src/batch.js CHANGED
@@ -156,12 +156,21 @@ class BatchHandler {
156
156
  // If no id is provided, this is a notification - don't return response
157
157
  const isNotification = id === undefined || id === null;
158
158
 
159
+ // Determine client safe mode from headers and deserialize params accordingly
160
+ const clientSafeHeader = req.headers['x-rpc-safe-enabled'];
161
+ const clientSafeEnabled = clientSafeHeader === 'true';
162
+ const deserializedParams = params
163
+ ? this.endpoint.deserializeBigIntsAndDates(params, {
164
+ safeEnabled: clientSafeEnabled,
165
+ })
166
+ : params;
167
+
159
168
  // Initialize middleware context
160
169
  let middlewareContext = {
161
170
  req,
162
171
  res: null, // No response object for batch items
163
172
  method,
164
- params,
173
+ params: deserializedParams,
165
174
  context,
166
175
  batchIndex,
167
176
  isNotification,