@naman_deep_singh/server-utils 1.0.1 → 1.0.3

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/server.d.ts CHANGED
@@ -55,6 +55,7 @@ export declare class ExpressServer implements ServerInstance {
55
55
  private rpcMethods;
56
56
  private socketIO?;
57
57
  constructor(name?: string, version?: string, config?: ServerConfig);
58
+ private setupMiddleware;
58
59
  start(): Promise<ServerInstance>;
59
60
  stop(): Promise<void>;
60
61
  getInfo(): ServerInfo;
package/dist/server.js CHANGED
@@ -27,6 +27,54 @@ class ExpressServer {
27
27
  gracefulShutdown: config.gracefulShutdown ?? true,
28
28
  socketIO: config.socketIO
29
29
  };
30
+ // Apply middleware based on configuration
31
+ this.setupMiddleware();
32
+ }
33
+ setupMiddleware() {
34
+ // Apply CORS if enabled
35
+ if (this.config.cors) {
36
+ try {
37
+ const cors = require('cors');
38
+ const corsOptions = typeof this.config.cors === 'object' ? this.config.cors : undefined;
39
+ this.app.use(cors(corsOptions));
40
+ }
41
+ catch (error) {
42
+ console.warn(`${this.config.name}: CORS middleware not available. Install cors package.`);
43
+ }
44
+ }
45
+ // Apply Helmet if enabled
46
+ if (this.config.helmet) {
47
+ try {
48
+ const helmet = require('helmet');
49
+ this.app.use(helmet());
50
+ }
51
+ catch (error) {
52
+ console.warn(`${this.config.name}: Helmet middleware not available. Install helmet package.`);
53
+ }
54
+ }
55
+ // Apply JSON parser if enabled
56
+ if (this.config.json) {
57
+ this.app.use(express_1.default.json());
58
+ }
59
+ // Apply custom middleware
60
+ if (this.config.customMiddleware && this.config.customMiddleware.length > 0) {
61
+ this.config.customMiddleware.forEach(middleware => {
62
+ this.app.use(middleware);
63
+ });
64
+ }
65
+ // Add health check if enabled
66
+ if (this.config.healthCheck) {
67
+ const healthPath = typeof this.config.healthCheck === 'string' ? this.config.healthCheck : '/health';
68
+ this.app.get(healthPath, (req, res) => {
69
+ res.status(200).json({
70
+ status: 'healthy',
71
+ service: this.config.name,
72
+ version: this.config.version,
73
+ uptime: Date.now() - this.config.startTime.getTime(),
74
+ timestamp: new Date().toISOString()
75
+ });
76
+ });
77
+ }
30
78
  }
31
79
  async start() {
32
80
  this.status = 'starting';
@@ -98,11 +146,11 @@ class ExpressServer {
98
146
  });
99
147
  this.grpcServer.bindAsync(`0.0.0.0:${port}`, grpc.ServerCredentials.createInsecure(), () => {
100
148
  this.grpcServer.start();
101
- console.log(`🔗 gRPC server running on port ${port}`);
149
+ console.log(`🔗 ${this.config.name} gRPC server running on port ${port}`);
102
150
  });
103
151
  }
104
152
  catch (error) {
105
- console.warn('gRPC not available. Install @grpc/grpc-js to use gRPC features.');
153
+ console.warn(`${this.config.name}: gRPC not available. Install @grpc/grpc-js to use gRPC features.`);
106
154
  }
107
155
  }
108
156
  }
@@ -113,10 +161,10 @@ class ExpressServer {
113
161
  const jayson = require('jayson');
114
162
  const rpcServer = jayson.server(this.rpcMethods);
115
163
  this.app.use(path, rpcServer.middleware());
116
- console.log(`📡 JSON-RPC server mounted on ${path}`);
164
+ console.log(`📡 ${this.config.name} JSON-RPC server mounted on ${path}`);
117
165
  }
118
166
  catch (error) {
119
- console.warn('JSON-RPC not available. Install jayson to use RPC features.');
167
+ console.warn(`${this.config.name}: JSON-RPC not available. Install jayson to use RPC features.`);
120
168
  }
121
169
  }
122
170
  addWebhook(config) {
@@ -147,11 +195,11 @@ class ExpressServer {
147
195
  res.status(500).json({ error: 'Webhook processing failed' });
148
196
  }
149
197
  });
150
- console.log(`🪝 Webhook registered at ${config.path}`);
198
+ console.log(`🪝 ${this.config.name} webhook registered at ${config.path}${config.secret ? ' (with signature verification)' : ''}`);
151
199
  }
152
200
  addSocketIO(config = {}) {
153
201
  if (!this.server) {
154
- throw new Error('Server must be started before adding Socket.IO');
202
+ throw new Error(`${this.config.name}: Server must be started before adding Socket.IO`);
155
203
  }
156
204
  try {
157
205
  // eslint-disable-next-line @typescript-eslint/no-var-requires
@@ -170,25 +218,25 @@ class ExpressServer {
170
218
  // Handle connections
171
219
  io.on('connection', (socket) => {
172
220
  const typedSocket = socket;
173
- console.log(`🔌 Socket connected: ${typedSocket.id}`);
221
+ console.log(`🔌 ${this.config.name}: Socket connected [${typedSocket.id}]`);
174
222
  // Call user-defined connection handler
175
223
  if (config.onConnection) {
176
224
  config.onConnection(socket);
177
225
  }
178
226
  // Handle disconnection
179
227
  typedSocket.on('disconnect', (reason) => {
180
- console.log(`🔌 Socket disconnected: ${typedSocket.id} - ${reason}`);
228
+ console.log(`🔌 ${this.config.name}: Socket disconnected [${typedSocket.id}] - ${reason}`);
181
229
  // Call user-defined disconnection handler
182
230
  if (config.onDisconnection) {
183
231
  config.onDisconnection(socket, reason);
184
232
  }
185
233
  });
186
234
  });
187
- console.log(`🔌 Socket.IO server attached${config.path ? ` at ${config.path}` : ''}`);
235
+ console.log(`🔌 ${this.config.name} Socket.IO server attached${config.path ? ` at ${config.path}` : ''}${config.cors ? ' (CORS enabled)' : ''}`);
188
236
  return io;
189
237
  }
190
238
  catch (error) {
191
- console.warn('Socket.IO not available. Install socket.io to use WebSocket features.');
239
+ console.warn(`${this.config.name}: Socket.IO not available. Install socket.io to use WebSocket features.`);
192
240
  return null;
193
241
  }
194
242
  }
@@ -2,4 +2,4 @@ import { Server } from 'http';
2
2
  import { GracefulShutdownConfig, ServerPlugin } from './types';
3
3
  export declare function createGracefulShutdown(server: Server, config?: GracefulShutdownConfig): void;
4
4
  export declare function withGracefulShutdown(config?: GracefulShutdownConfig): ServerPlugin;
5
- export declare function startServerWithShutdown(app: any, port: number, shutdownConfig?: GracefulShutdownConfig): Server;
5
+ export declare function startServerWithShutdown(app: any, port: number, shutdownConfig?: GracefulShutdownConfig, serverName?: string, serverVersion?: string): Server;
package/dist/shutdown.js CHANGED
@@ -4,11 +4,12 @@ exports.createGracefulShutdown = createGracefulShutdown;
4
4
  exports.withGracefulShutdown = withGracefulShutdown;
5
5
  exports.startServerWithShutdown = startServerWithShutdown;
6
6
  function createGracefulShutdown(server, config = {}) {
7
- const { timeout = 10000, onShutdown } = config;
7
+ const { timeout = 10000, onShutdown, serverName, serverVersion } = config;
8
+ const nameVersion = serverName && serverVersion ? `${serverName} v${serverVersion}` : 'Server';
8
9
  const shutdown = async (signal) => {
9
- console.log(`🛑 Received ${signal}, shutting down gracefully...`);
10
+ console.log(`🛑 ${nameVersion} received ${signal}, shutting down gracefully...`);
10
11
  const shutdownTimer = setTimeout(() => {
11
- console.log('⏰ Shutdown timeout reached, forcing exit');
12
+ console.log(`⏰ ${nameVersion} shutdown timeout reached, forcing exit`);
12
13
  process.exit(1);
13
14
  }, timeout);
14
15
  try {
@@ -19,13 +20,13 @@ function createGracefulShutdown(server, config = {}) {
19
20
  // Close server
20
21
  server.close(() => {
21
22
  clearTimeout(shutdownTimer);
22
- console.log('👋 Server closed. Exiting now.');
23
+ console.log(`👋 ${nameVersion} closed. Exiting now.`);
23
24
  process.exit(0);
24
25
  });
25
26
  }
26
27
  catch (error) {
27
28
  clearTimeout(shutdownTimer);
28
- console.error('❌ Error during shutdown:', error);
29
+ console.error(`❌ ${nameVersion} error during shutdown:`, error);
29
30
  process.exit(1);
30
31
  }
31
32
  };
@@ -39,12 +40,18 @@ function withGracefulShutdown(config = {}) {
39
40
  app.__gracefulShutdownConfig = config;
40
41
  };
41
42
  }
42
- function startServerWithShutdown(app, port, shutdownConfig = {}) {
43
+ function startServerWithShutdown(app, port, shutdownConfig = {}, serverName, serverVersion) {
43
44
  const server = app.listen(port, () => {
44
- console.log(`🚀 Server running on http://localhost:${port}`);
45
+ const nameVersion = serverName && serverVersion ? `${serverName} v${serverVersion}` : 'Server';
46
+ console.log(`🚀 ${nameVersion} running on http://localhost:${port}`);
45
47
  });
46
48
  // Apply graceful shutdown from stored config or provided config
47
49
  const config = app.__gracefulShutdownConfig || shutdownConfig;
48
- createGracefulShutdown(server, config);
50
+ const enhancedConfig = {
51
+ ...config,
52
+ serverName,
53
+ serverVersion
54
+ };
55
+ createGracefulShutdown(server, enhancedConfig);
49
56
  return server;
50
57
  }
package/dist/types.d.ts CHANGED
@@ -43,6 +43,8 @@ export interface HealthCheck {
43
43
  export interface GracefulShutdownConfig {
44
44
  timeout?: number;
45
45
  onShutdown?: () => Promise<void>;
46
+ serverName?: string;
47
+ serverVersion?: string;
46
48
  }
47
49
  export interface SocketInstance {
48
50
  id: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@naman_deep_singh/server-utils",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Extensible server utilities for Express.js microservices with TypeScript",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/server.ts CHANGED
@@ -88,6 +88,58 @@ export class ExpressServer implements ServerInstance {
88
88
  gracefulShutdown: config.gracefulShutdown ?? true,
89
89
  socketIO: config.socketIO
90
90
  };
91
+
92
+ // Apply middleware based on configuration
93
+ this.setupMiddleware();
94
+ }
95
+
96
+ private setupMiddleware(): void {
97
+ // Apply CORS if enabled
98
+ if (this.config.cors) {
99
+ try {
100
+ const cors = require('cors');
101
+ const corsOptions = typeof this.config.cors === 'object' ? this.config.cors : undefined;
102
+ this.app.use(cors(corsOptions));
103
+ } catch (error) {
104
+ console.warn(`${this.config.name}: CORS middleware not available. Install cors package.`);
105
+ }
106
+ }
107
+
108
+ // Apply Helmet if enabled
109
+ if (this.config.helmet) {
110
+ try {
111
+ const helmet = require('helmet');
112
+ this.app.use(helmet());
113
+ } catch (error) {
114
+ console.warn(`${this.config.name}: Helmet middleware not available. Install helmet package.`);
115
+ }
116
+ }
117
+
118
+ // Apply JSON parser if enabled
119
+ if (this.config.json) {
120
+ this.app.use(express.json());
121
+ }
122
+
123
+ // Apply custom middleware
124
+ if (this.config.customMiddleware && this.config.customMiddleware.length > 0) {
125
+ this.config.customMiddleware.forEach(middleware => {
126
+ this.app.use(middleware);
127
+ });
128
+ }
129
+
130
+ // Add health check if enabled
131
+ if (this.config.healthCheck) {
132
+ const healthPath = typeof this.config.healthCheck === 'string' ? this.config.healthCheck : '/health';
133
+ this.app.get(healthPath, (req, res) => {
134
+ res.status(200).json({
135
+ status: 'healthy',
136
+ service: this.config.name,
137
+ version: this.config.version,
138
+ uptime: Date.now() - this.config.startTime.getTime(),
139
+ timestamp: new Date().toISOString()
140
+ });
141
+ });
142
+ }
91
143
  }
92
144
 
93
145
  async start(): Promise<ServerInstance> {
@@ -184,11 +236,11 @@ export class ExpressServer implements ServerInstance {
184
236
  grpc.ServerCredentials.createInsecure(),
185
237
  () => {
186
238
  this.grpcServer!.start();
187
- console.log(`🔗 gRPC server running on port ${port}`);
239
+ console.log(`🔗 ${this.config.name} gRPC server running on port ${port}`);
188
240
  }
189
241
  );
190
242
  } catch (error: unknown) {
191
- console.warn('gRPC not available. Install @grpc/grpc-js to use gRPC features.');
243
+ console.warn(`${this.config.name}: gRPC not available. Install @grpc/grpc-js to use gRPC features.`);
192
244
  }
193
245
  }
194
246
  }
@@ -205,9 +257,9 @@ export class ExpressServer implements ServerInstance {
205
257
  };
206
258
  const rpcServer = jayson.server(this.rpcMethods);
207
259
  this.app.use(path, rpcServer.middleware());
208
- console.log(`📡 JSON-RPC server mounted on ${path}`);
260
+ console.log(`📡 ${this.config.name} JSON-RPC server mounted on ${path}`);
209
261
  } catch (error: unknown) {
210
- console.warn('JSON-RPC not available. Install jayson to use RPC features.');
262
+ console.warn(`${this.config.name}: JSON-RPC not available. Install jayson to use RPC features.`);
211
263
  }
212
264
  }
213
265
 
@@ -243,12 +295,12 @@ export class ExpressServer implements ServerInstance {
243
295
  }
244
296
  });
245
297
 
246
- console.log(`🪝 Webhook registered at ${config.path}`);
298
+ console.log(`🪝 ${this.config.name} webhook registered at ${config.path}${config.secret ? ' (with signature verification)' : ''}`);
247
299
  }
248
300
 
249
301
  addSocketIO(config: SocketIOConfig = {}): unknown {
250
302
  if (!this.server) {
251
- throw new Error('Server must be started before adding Socket.IO');
303
+ throw new Error(`${this.config.name}: Server must be started before adding Socket.IO`);
252
304
  }
253
305
 
254
306
  try {
@@ -284,7 +336,7 @@ export class ExpressServer implements ServerInstance {
284
336
  // Handle connections
285
337
  io.on('connection', (socket: unknown) => {
286
338
  const typedSocket = socket as SocketInstance;
287
- console.log(`🔌 Socket connected: ${typedSocket.id}`);
339
+ console.log(`🔌 ${this.config.name}: Socket connected [${typedSocket.id}]`);
288
340
 
289
341
  // Call user-defined connection handler
290
342
  if (config.onConnection) {
@@ -293,7 +345,7 @@ export class ExpressServer implements ServerInstance {
293
345
 
294
346
  // Handle disconnection
295
347
  typedSocket.on('disconnect', (reason) => {
296
- console.log(`🔌 Socket disconnected: ${typedSocket.id} - ${reason}`);
348
+ console.log(`🔌 ${this.config.name}: Socket disconnected [${typedSocket.id}] - ${reason}`);
297
349
 
298
350
  // Call user-defined disconnection handler
299
351
  if (config.onDisconnection) {
@@ -302,10 +354,10 @@ export class ExpressServer implements ServerInstance {
302
354
  });
303
355
  });
304
356
 
305
- console.log(`🔌 Socket.IO server attached${config.path ? ` at ${config.path}` : ''}`);
357
+ console.log(`🔌 ${this.config.name} Socket.IO server attached${config.path ? ` at ${config.path}` : ''}${config.cors ? ' (CORS enabled)' : ''}`);
306
358
  return io;
307
359
  } catch (error: unknown) {
308
- console.warn('Socket.IO not available. Install socket.io to use WebSocket features.');
360
+ console.warn(`${this.config.name}: Socket.IO not available. Install socket.io to use WebSocket features.`);
309
361
  return null;
310
362
  }
311
363
  }
package/src/shutdown.ts CHANGED
@@ -2,13 +2,14 @@ import { Server } from 'http';
2
2
  import { GracefulShutdownConfig, ServerPlugin } from './types';
3
3
 
4
4
  export function createGracefulShutdown(server: Server, config: GracefulShutdownConfig = {}): void {
5
- const { timeout = 10000, onShutdown } = config;
5
+ const { timeout = 10000, onShutdown, serverName, serverVersion } = config;
6
+ const nameVersion = serverName && serverVersion ? `${serverName} v${serverVersion}` : 'Server';
6
7
 
7
8
  const shutdown = async (signal: string) => {
8
- console.log(`🛑 Received ${signal}, shutting down gracefully...`);
9
+ console.log(`🛑 ${nameVersion} received ${signal}, shutting down gracefully...`);
9
10
 
10
11
  const shutdownTimer = setTimeout(() => {
11
- console.log('⏰ Shutdown timeout reached, forcing exit');
12
+ console.log(`⏰ ${nameVersion} shutdown timeout reached, forcing exit`);
12
13
  process.exit(1);
13
14
  }, timeout);
14
15
 
@@ -21,12 +22,12 @@ export function createGracefulShutdown(server: Server, config: GracefulShutdownC
21
22
  // Close server
22
23
  server.close(() => {
23
24
  clearTimeout(shutdownTimer);
24
- console.log('👋 Server closed. Exiting now.');
25
+ console.log(`👋 ${nameVersion} closed. Exiting now.`);
25
26
  process.exit(0);
26
27
  });
27
28
  } catch (error) {
28
29
  clearTimeout(shutdownTimer);
29
- console.error('❌ Error during shutdown:', error);
30
+ console.error(`❌ ${nameVersion} error during shutdown:`, error);
30
31
  process.exit(1);
31
32
  }
32
33
  };
@@ -46,15 +47,23 @@ export function withGracefulShutdown(config: GracefulShutdownConfig = {}): Serve
46
47
  export function startServerWithShutdown(
47
48
  app: any,
48
49
  port: number,
49
- shutdownConfig: GracefulShutdownConfig = {}
50
+ shutdownConfig: GracefulShutdownConfig = {},
51
+ serverName?: string,
52
+ serverVersion?: string
50
53
  ): Server {
51
54
  const server = app.listen(port, () => {
52
- console.log(`🚀 Server running on http://localhost:${port}`);
55
+ const nameVersion = serverName && serverVersion ? `${serverName} v${serverVersion}` : 'Server';
56
+ console.log(`🚀 ${nameVersion} running on http://localhost:${port}`);
53
57
  });
54
58
 
55
59
  // Apply graceful shutdown from stored config or provided config
56
60
  const config = app.__gracefulShutdownConfig || shutdownConfig;
57
- createGracefulShutdown(server, config);
61
+ const enhancedConfig = {
62
+ ...config,
63
+ serverName,
64
+ serverVersion
65
+ };
66
+ createGracefulShutdown(server, enhancedConfig);
58
67
 
59
68
  return server;
60
69
  }
package/src/types.ts CHANGED
@@ -49,6 +49,8 @@ export interface HealthCheck {
49
49
  export interface GracefulShutdownConfig {
50
50
  timeout?: number;
51
51
  onShutdown?: () => Promise<void>;
52
+ serverName?: string;
53
+ serverVersion?: string;
52
54
  }
53
55
 
54
56
  export interface SocketInstance {