@scpxl/nodejs-framework 1.0.20 → 1.0.24

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.
Files changed (103) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +719 -66
  3. package/dist/application/base-application.d.ts.map +1 -1
  4. package/dist/application/base-application.interface.d.ts +1 -0
  5. package/dist/application/base-application.interface.d.ts.map +1 -1
  6. package/dist/application/base-application.js +4 -1
  7. package/dist/application/base-application.js.map +2 -2
  8. package/dist/application/command-application.d.ts.map +1 -1
  9. package/dist/application/command-application.js.map +2 -2
  10. package/dist/application/web-application.d.ts.map +1 -1
  11. package/dist/application/web-application.js +2 -0
  12. package/dist/application/web-application.js.map +2 -2
  13. package/dist/cli/index.d.ts +2 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +5655 -0
  16. package/dist/cli/index.js.map +7 -0
  17. package/dist/command/command.d.ts +1 -1
  18. package/dist/command/command.d.ts.map +1 -1
  19. package/dist/command/command.js.map +1 -1
  20. package/dist/config/schema.d.ts +40 -16
  21. package/dist/config/schema.d.ts.map +1 -1
  22. package/dist/config/schema.js +17 -7
  23. package/dist/config/schema.js.map +2 -2
  24. package/dist/event/manager.d.ts +2 -2
  25. package/dist/event/manager.d.ts.map +1 -1
  26. package/dist/event/manager.interface.d.ts +4 -1
  27. package/dist/event/manager.interface.d.ts.map +1 -1
  28. package/dist/event/manager.js.map +2 -2
  29. package/dist/lifecycle/lifecycle-manager.d.ts +1 -1
  30. package/dist/lifecycle/lifecycle-manager.d.ts.map +1 -1
  31. package/dist/lifecycle/lifecycle-manager.js +6 -11
  32. package/dist/lifecycle/lifecycle-manager.js.map +2 -2
  33. package/dist/logger/logger.d.ts +4 -0
  34. package/dist/logger/logger.d.ts.map +1 -1
  35. package/dist/logger/logger.js +29 -2
  36. package/dist/logger/logger.js.map +2 -2
  37. package/dist/queue/index.d.ts +1 -1
  38. package/dist/queue/index.d.ts.map +1 -1
  39. package/dist/queue/index.js.map +1 -1
  40. package/dist/queue/job.interface.d.ts +4 -3
  41. package/dist/queue/job.interface.d.ts.map +1 -1
  42. package/dist/queue/manager.d.ts +14 -6
  43. package/dist/queue/manager.d.ts.map +1 -1
  44. package/dist/queue/manager.js +24 -12
  45. package/dist/queue/manager.js.map +2 -2
  46. package/dist/queue/processor/base.d.ts +6 -5
  47. package/dist/queue/processor/base.d.ts.map +1 -1
  48. package/dist/queue/processor/base.js.map +2 -2
  49. package/dist/queue/processor/processor.interface.d.ts +4 -3
  50. package/dist/queue/processor/processor.interface.d.ts.map +1 -1
  51. package/dist/redis/manager.d.ts.map +1 -1
  52. package/dist/redis/manager.js +13 -14
  53. package/dist/redis/manager.js.map +2 -2
  54. package/dist/services/aws/s3.js.map +2 -2
  55. package/dist/util/helper.d.ts +9 -10
  56. package/dist/util/helper.d.ts.map +1 -1
  57. package/dist/util/helper.js +73 -11
  58. package/dist/util/helper.js.map +2 -2
  59. package/dist/util/loader.d.ts +8 -6
  60. package/dist/util/loader.d.ts.map +1 -1
  61. package/dist/util/loader.js +5 -2
  62. package/dist/util/loader.js.map +2 -2
  63. package/dist/util/timing.interface.d.ts +1 -1
  64. package/dist/util/timing.interface.d.ts.map +1 -1
  65. package/dist/webserver/controller/base.d.ts +9 -9
  66. package/dist/webserver/controller/base.d.ts.map +1 -1
  67. package/dist/webserver/controller/base.interface.d.ts +12 -9
  68. package/dist/webserver/controller/base.interface.d.ts.map +1 -1
  69. package/dist/webserver/controller/base.js.map +2 -2
  70. package/dist/webserver/define-action.d.ts +26 -0
  71. package/dist/webserver/define-action.d.ts.map +1 -0
  72. package/dist/webserver/define-action.js +16 -0
  73. package/dist/webserver/define-action.js.map +7 -0
  74. package/dist/webserver/define-route.d.ts +53 -0
  75. package/dist/webserver/define-route.d.ts.map +1 -0
  76. package/dist/webserver/define-route.js +27 -0
  77. package/dist/webserver/define-route.js.map +7 -0
  78. package/dist/webserver/index.d.ts +4 -2
  79. package/dist/webserver/index.d.ts.map +1 -1
  80. package/dist/webserver/index.js +4 -0
  81. package/dist/webserver/index.js.map +2 -2
  82. package/dist/webserver/util.d.ts.map +1 -1
  83. package/dist/webserver/util.js +5 -2
  84. package/dist/webserver/util.js.map +2 -2
  85. package/dist/webserver/webserver.d.ts +20 -6
  86. package/dist/webserver/webserver.d.ts.map +1 -1
  87. package/dist/webserver/webserver.interface.d.ts +30 -4
  88. package/dist/webserver/webserver.interface.d.ts.map +1 -1
  89. package/dist/webserver/webserver.interface.js.map +2 -2
  90. package/dist/webserver/webserver.js +209 -57
  91. package/dist/webserver/webserver.js.map +2 -2
  92. package/dist/websocket/websocket-base.d.ts +6 -2
  93. package/dist/websocket/websocket-base.d.ts.map +1 -1
  94. package/dist/websocket/websocket-base.js.map +2 -2
  95. package/dist/websocket/websocket-client.js.map +1 -1
  96. package/dist/websocket/websocket-server.d.ts.map +1 -1
  97. package/dist/websocket/websocket-server.js +38 -14
  98. package/dist/websocket/websocket-server.js.map +2 -2
  99. package/dist/websocket/websocket.interface.d.ts +9 -4
  100. package/dist/websocket/websocket.interface.d.ts.map +1 -1
  101. package/dist/websocket/websocket.interface.js.map +2 -2
  102. package/package.json +14 -13
  103. package/pxl.js +0 -4
package/README.md CHANGED
@@ -1,120 +1,418 @@
1
1
  # PXL Node.js Framework
2
2
 
3
- A comprehensive Node.js framework for building modern applications with support for web servers, databases, queues, caching, and more.
3
+ [![npm version](https://img.shields.io/npm/v/@scpxl/nodejs-framework.svg)](https://www.npmjs.com/package/@scpxl/nodejs-framework)
4
+ [![Node.js Version](https://img.shields.io/node/v/@scpxl/nodejs-framework.svg)](https://nodejs.org)
5
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.8-blue.svg)](https://www.typescriptlang.org/)
4
7
 
5
- Opinionated TypeScript framework combining Fastify, WebSockets, Redis, BullMQ, and MikroORM under a unified Application lifecycle.
8
+ A comprehensive, production-ready Node.js framework for building modern applications with built-in support for web servers, databases, queues, caching, WebSockets, and more.
6
9
 
7
- ## Install
10
+ **Opinionated TypeScript framework** combining Fastify, WebSockets, Redis, BullMQ, and MikroORM under a unified Application lifecycle with graceful shutdown, health checks, and observability.
11
+
12
+ ---
13
+
14
+ ## ✨ Features
15
+
16
+ ### 🚀 **Core Application System**
17
+
18
+ - **Unified Lifecycle Management** - Coordinated startup, readiness probes, and graceful shutdown
19
+ - **TypeScript-First** - Full type safety with strict mode enabled and comprehensive type definitions
20
+ - **Configuration Validation** - Zod-based schema validation with fail-fast error reporting
21
+ - **Modular Architecture** - Use only what you need via granular package exports
22
+
23
+ ### 🌐 **Web & Networking**
24
+
25
+ - **Fastify Web Server** - High-performance HTTP server with route management and middleware
26
+ - **Route Autoloading** - Drop route modules into a directory and have them loaded automatically
27
+ - **WebSocket Support** - Real-time bidirectional communication with room-based routing
28
+ - **CORS & Security** - Built-in CORS, Helmet integration, and rate limiting support
29
+ - **File Uploads** - Multipart form data handling with configurable limits
30
+
31
+ ### 💾 **Data & State Management**
32
+
33
+ - **PostgreSQL + MikroORM** - Type-safe database access with migrations and entities
34
+ - **Redis Integration** - Connection pooling, pub/sub, and caching via `ioredis`
35
+ - **Queue Processing (BullMQ)** - Background job processing with Redis-backed queues
36
+ - **LRU Caching** - High-performance in-memory caching with TTL support
37
+
38
+ ### 🔧 **Developer Experience**
39
+
40
+ - **Structured Logging** - Winston-based logging with context and Sentry integration
41
+ - **CLI Commands** - Yargs-based command system for scripts and utilities
42
+ - **Hot Module Reload** - Fast development iteration with automatic rebuilds
43
+ - **Request Context** - Trace requests across async boundaries with correlation IDs
44
+ - **Error Handling** - Standardized error classes with detailed context
45
+
46
+ ### ⚙️ **Operations & Observability**
47
+
48
+ - **Health Endpoints** - Liveness (`/health/live`) and readiness (`/health/ready`) probes
49
+ - **Performance Monitoring** - Track connection health, queue metrics, and resource usage
50
+ - **Graceful Shutdown** - Coordinated cleanup of connections, intervals, and resources
51
+ - **Cluster Support** - Multi-process scaling with built-in cluster management
52
+
53
+ ### 🔐 **Security & Authentication**
54
+
55
+ - **JWT Authentication** - JOSE-based token signing and verification
56
+ - **Input Validation** - Zod schemas with runtime validation and type inference
57
+ - **AWS S3 Integration** - Secure file storage with presigned URLs
58
+ - **Prototype Pollution Protection** - Safe object operations and property access
59
+
60
+ ---
61
+
62
+ ## 📦 Installation
8
63
 
9
64
  ```bash
10
65
  npm install @scpxl/nodejs-framework
11
66
  ```
12
67
 
13
- ## Quick Start
68
+ **Requirements:**
14
69
 
15
- ```ts
16
- import { Application } from '@scpxl/nodejs-framework';
70
+ - Node.js >= 22.0.0
71
+ - PostgreSQL (optional, for database features)
72
+ - Redis (optional, for caching and queues)
17
73
 
18
- const app = new Application({
19
- webserver: { port: 3000 },
20
- logger: { level: 'info' },
21
- });
74
+ ---
22
75
 
23
- await app.start();
76
+ ## 🚀 Quick Start
77
+
78
+ ### Basic Web Application
79
+
80
+ ```typescript
81
+ import { WebApplication } from '@scpxl/nodejs-framework';
24
82
 
83
+ const app = new WebApplication({
84
+ name: 'my-app',
85
+ webserver: {
86
+ port: 3000,
87
+ host: '0.0.0.0',
88
+ },
89
+ redis: {
90
+ host: '127.0.0.1',
91
+ port: 6379,
92
+ },
93
+ logger: {
94
+ level: 'info',
95
+ },
96
+ });
97
+
98
+ // Add routes
25
99
  app.webserver.route({
26
100
  method: 'GET',
27
- url: '/health',
28
- handler: async () => ({ ok: true }),
101
+ url: '/api/health',
102
+ handler: async (request, reply) => {
103
+ return { status: 'healthy', timestamp: new Date() };
104
+ },
29
105
  });
106
+
107
+ // Start the application
108
+ await app.start();
109
+
110
+ console.log(`Server running at http://localhost:3000`);
30
111
  ```
31
112
 
32
- ## Add WebSocket
113
+ ### With Database & Queue
33
114
 
34
- ```ts
35
- app.websocket.onConnection(client => {
36
- client.sendJSON({ welcome: true });
115
+ ```typescript
116
+ import { WebApplication } from '@scpxl/nodejs-framework';
117
+
118
+ const app = new WebApplication({
119
+ name: 'my-app',
120
+ webserver: { port: 3000 },
121
+ database: {
122
+ enabled: true,
123
+ host: 'localhost',
124
+ port: 5432,
125
+ username: 'postgres',
126
+ password: 'password',
127
+ databaseName: 'myapp',
128
+ entitiesDirectory: './src/database/entities',
129
+ },
130
+ queue: {
131
+ enabled: true,
132
+ queues: [
133
+ {
134
+ id: 'email',
135
+ jobs: [{ id: 'send-welcome', processor: './src/processors/email-processor.ts' }],
136
+ },
137
+ ],
138
+ },
139
+ redis: {
140
+ host: '127.0.0.1',
141
+ port: 6379,
142
+ },
37
143
  });
144
+
145
+ await app.start();
146
+
147
+ // Add a job to the queue
148
+ await app.queue.manager.addJobToQueue({
149
+ queueId: 'email',
150
+ jobId: 'send-welcome',
151
+ data: { userId: 123, email: 'user@example.com' },
152
+ });
153
+ ```
154
+
155
+ ### Simple Load Test
156
+
157
+ Run lightweight load against any endpoint while iterating locally:
158
+
159
+ ```bash
160
+ npm run load:test -- --url http://localhost:3000/health --requests 200 --concurrency 10
38
161
  ```
39
162
 
40
- ## Add Queue Job
163
+ Switch to a time-based stream for soak-style checks:
41
164
 
42
- ```ts
43
- await app.queue.manager.add('email', { userId: 123 });
165
+ ```bash
166
+ npm run load:test -- --url http://localhost:3000/api/users --duration 30 --concurrency 8 --method POST --body '{"name":"Test"}' --header 'Content-Type: application/json'
44
167
  ```
45
168
 
46
- ## Configuration Example
169
+ The script reports latency percentiles, status code counts, and a few failure samples for quick feedback.
170
+
171
+ ### WebSocket Server
172
+
173
+ Real-time bidirectional communication with room support and authentication:
174
+
175
+ ```typescript
176
+ import { WebApplication } from '@scpxl/nodejs-framework';
177
+ import { WebSocketServerBaseController } from '@scpxl/nodejs-framework/websocket';
178
+ import type { WebSocket } from 'ws';
179
+
180
+ // Create WebSocket controller
181
+ class ChatController extends WebSocketServerBaseController {
182
+ public send = (ws: WebSocket, clientId: string, data: any) => {
183
+ // Broadcast to all clients
184
+ this.webSocketServer.sendMessageToAll({
185
+ data: {
186
+ type: 'chat',
187
+ action: 'message',
188
+ data: {
189
+ clientId,
190
+ text: data.text,
191
+ timestamp: new Date().toISOString(),
192
+ },
193
+ },
194
+ });
195
+
196
+ return { success: true };
197
+ };
198
+ }
47
199
 
48
- ```ts
49
- new Application({
200
+ const app = new WebApplication({
201
+ name: 'chat-app',
50
202
  webserver: { port: 3000 },
51
- websocket: { enabled: true },
52
- queue: { enabled: true },
203
+ websocket: {
204
+ enabled: true,
205
+ type: 'server',
206
+ url: 'ws://localhost:3000/ws',
207
+ controllersDirectory: './controllers',
208
+ routes: [
209
+ {
210
+ type: 'chat',
211
+ action: 'send',
212
+ controllerName: 'chat',
213
+ controller: ChatController,
214
+ },
215
+ ],
216
+ // Optional: JWT authentication
217
+ // Clients connect with: ws://localhost:3000/ws?token=<jwt>
218
+ events: {
219
+ onConnected: ({ ws, clientId }) => {
220
+ console.log('Client connected:', clientId);
221
+ ws.send(
222
+ JSON.stringify({
223
+ type: 'system',
224
+ action: 'connected',
225
+ data: { clientId, message: 'Welcome!' },
226
+ }),
227
+ );
228
+ },
229
+ },
230
+ },
53
231
  redis: { host: '127.0.0.1', port: 6379 },
54
- database: {
55
- /* MikroORM config */
232
+ auth: {
233
+ jwtSecretKey: process.env.JWT_SECRET || 'your-secret-key',
56
234
  },
57
- logger: { level: 'info' },
58
235
  });
236
+
237
+ await app.start();
238
+ console.log('WebSocket server running at ws://localhost:3000/ws');
59
239
  ```
60
240
 
61
- ## Features
241
+ #### Using Rooms
242
+
243
+ ```typescript
244
+ // Client joins a room (built-in system controller)
245
+ // Send from client: { type: 'system', action: 'joinRoom', data: { roomName: 'general', username: 'Alice' } }
246
+
247
+ // Server-side: Broadcast to room members
248
+ const roomClients = app.websocket.server.rooms.get('general');
249
+ roomClients?.forEach(clientId => {
250
+ const client = app.websocket.server.clientManager.getClient({ clientId });
251
+ if (client?.ws) {
252
+ app.websocket.server.sendClientMessage(client.ws, {
253
+ type: 'room',
254
+ action: 'message',
255
+ data: { text: 'Room-specific announcement' },
256
+ });
257
+ }
258
+ });
259
+ ```
62
260
 
63
- - Unified lifecycle (start/stop all subsystems)
64
- - Fastify routing + raw access
65
- - WebSocket client + room management
66
- - BullMQ queue integration
67
- - MikroORM database integration
68
- - Redis cache + pub/sub
69
- - Structured logging
70
- - Utilities & services layer
261
+ #### Using WebSocket Service
71
262
 
72
- ## Documentation
263
+ Simplified API for common operations:
73
264
 
74
- Full docs & guides (VitePress) + API reference (TypeDoc).
265
+ ```typescript
266
+ import { WebSocketService } from '@scpxl/nodejs-framework/websocket';
75
267
 
76
- - Getting Started, Concepts, Guides
77
- - API: https://pxlbros.github.io/pxl-nodejs-framework/
268
+ const wsService = new WebSocketService({
269
+ webSocketServer: app.websocket.server,
270
+ redisInstance: app.redis.instance,
271
+ workerId: String(process.pid),
272
+ });
78
273
 
79
- To run local docs site (once cloned):
274
+ // Broadcast to all clients
275
+ await wsService.broadcast({
276
+ type: 'notification',
277
+ action: 'alert',
278
+ data: { message: 'New features available!' },
279
+ });
80
280
 
81
- ```bash
82
- npm run docs:site:dev
281
+ // Send to specific rooms
282
+ await wsService.sendToRooms(['vip', 'premium'], {
283
+ type: 'offer',
284
+ action: 'new',
285
+ data: { discount: 20 },
286
+ });
287
+
288
+ // Convenience methods
289
+ await wsService.sendUserMessage('profileUpdated', { userId: 123 });
290
+ await wsService.sendSystemMessage('maintenance', { minutes: 5 });
83
291
  ```
84
292
 
85
- ## Graceful Shutdown
293
+ See the [WebSocket Guide](./docs/guides/websocket.md) for complete documentation.
294
+
295
+ ---
296
+
297
+ ## 📚 Documentation
298
+
299
+ ### Architecture
300
+
301
+ The framework is built around three main application types:
302
+
303
+ 1. **`BaseApplication`** - Abstract base with Redis, Database, Queue, Events, Performance Monitoring
304
+ 2. **`WebApplication`** - Extends `BaseApplication` with Fastify web server and WebSocket support
305
+ 3. **`CommandApplication`** - Extends `BaseApplication` for CLI commands and scripts
306
+
307
+ ### Core Components
308
+
309
+ | Component | Description | Import Path |
310
+ | ------------------- | ------------------------------------------------ | ----------------------------------------- |
311
+ | **Application** | Main application classes | `@scpxl/nodejs-framework/application` |
312
+ | **Logger** | Structured logging with Winston | `@scpxl/nodejs-framework/logger` |
313
+ | **Database** | MikroORM integration and entity management | `@scpxl/nodejs-framework/database` |
314
+ | **WebServer** | Fastify server and routing | `@scpxl/nodejs-framework/webserver` |
315
+ | **WebSocket** | WebSocket server and client | `@scpxl/nodejs-framework/websocket` |
316
+ | **Queue** | BullMQ job queue management | `@scpxl/nodejs-framework/queue` |
317
+ | **Redis** | Redis connection management | `@scpxl/nodejs-framework/redis` |
318
+ | **Cache** | High-level caching abstraction | `@scpxl/nodejs-framework/cache` |
319
+ | **Auth** | JWT authentication utilities | `@scpxl/nodejs-framework/auth` |
320
+ | **Request Context** | Request correlation and tracing | `@scpxl/nodejs-framework/request-context` |
321
+ | **Lifecycle** | Application lifecycle and shutdown management | `@scpxl/nodejs-framework/lifecycle` |
322
+ | **Error** | Custom error classes | `@scpxl/nodejs-framework/error` |
323
+ | **Utilities** | File, string, time, URL helpers | `@scpxl/nodejs-framework/util` |
324
+ | **Performance** | Performance monitoring and metrics | `@scpxl/nodejs-framework/performance` |
325
+ | **API Requester** | HTTP client wrapper (migrated to native `fetch`) | `@scpxl/nodejs-framework/api-requester` |
326
+ | **Command** | CLI command framework | `@scpxl/nodejs-framework/command` |
327
+ | **Services** | Additional service integrations (AWS S3, etc.) | `@scpxl/nodejs-framework/services` |
328
+
329
+ ### Key Patterns
330
+
331
+ #### Lifecycle Hooks
332
+
333
+ ```typescript
334
+ const app = new WebApplication(config);
335
+
336
+ // Register lifecycle hooks
337
+ app.lifecycle.onStart(async () => {
338
+ console.log('Application starting...');
339
+ });
340
+
341
+ app.lifecycle.onReady(async () => {
342
+ console.log('Application ready for traffic');
343
+ });
86
344
 
87
- ```ts
88
- process.on('SIGINT', () => app.stop());
89
- process.on('SIGTERM', () => app.stop());
345
+ app.lifecycle.onShutdown(async () => {
346
+ console.log('Cleaning up resources...');
347
+ });
348
+
349
+ await app.start();
90
350
  ```
91
351
 
92
- ## Example Service Pattern
352
+ #### Graceful Shutdown
353
+
354
+ ```typescript
355
+ const app = new WebApplication(config);
356
+
357
+ await app.start();
358
+
359
+ // Handle signals
360
+ process.on('SIGINT', async () => {
361
+ console.log('Received SIGINT, shutting down gracefully...');
362
+ await app.stop();
363
+ process.exit(0);
364
+ });
93
365
 
94
- ```ts
366
+ process.on('SIGTERM', async () => {
367
+ console.log('Received SIGTERM, shutting down gracefully...');
368
+ await app.stop();
369
+ process.exit(0);
370
+ });
371
+ ```
372
+
373
+ #### Service Injection Pattern
374
+
375
+ ```typescript
95
376
  class UserService {
96
- constructor(private app: Application) {}
97
- async register(data: any) {
98
- // use app.database / app.queue / app.logger
377
+ constructor(private app: WebApplication) {}
378
+
379
+ async createUser(data: CreateUserDto) {
380
+ // Use database
381
+ const user = this.app.database.instance.em.create(User, data);
382
+ await this.app.database.instance.em.flush();
383
+
384
+ // Use queue
385
+ await this.app.queue.manager.addJobToQueue({
386
+ queueId: 'email',
387
+ jobId: 'send-welcome',
388
+ data: { userId: user.id },
389
+ });
390
+
391
+ // Use logger
392
+ this.app.logger.info('User created', { userId: user.id });
393
+
394
+ return user;
99
395
  }
100
396
  }
101
397
  ```
102
398
 
103
- ## Examples
399
+ ---
400
+
401
+ ## 📖 Examples
104
402
 
105
- The `examples/` directory contains working examples demonstrating the framework:
403
+ The `examples/` directory contains working demonstrations:
106
404
 
107
405
  ### Hello World Example
108
406
 
109
- A simple full-stack example with:
407
+ A full-stack example with:
110
408
 
111
- - Backend: PXL WebApplication with TypeScript
112
- - Frontend: Vue 3 + TypeScript + Vite
409
+ - **Backend**: PXL WebApplication with TypeScript, WebSocket support, and API routes
410
+ - **Frontend**: Vue 3 + TypeScript + Vite with real-time WebSocket updates
113
411
 
114
412
  **Run the example:**
115
413
 
116
414
  ```bash
117
- # Install dependencies for the example (one-time setup)
415
+ # Install dependencies for examples (one-time setup)
118
416
  npm run example:install
119
417
 
120
418
  # Run backend + frontend together with hot-reload
@@ -127,21 +425,376 @@ npm run example:hello-world:frontend
127
425
 
128
426
  Then open http://localhost:5173 to see the app.
129
427
 
428
+ ### CLI Commands Example
429
+
430
+ Demonstrates the command framework with examples:
431
+
432
+ ```bash
433
+ # Install dependencies
434
+ npm run example:commands:install
435
+
436
+ # Run hello command
437
+ npm run example:commands:hello
438
+
439
+ # Run database seed command
440
+ npm run example:commands:seed
441
+
442
+ # Run queue processing command
443
+ npm run example:commands:queue
444
+ ```
445
+
130
446
  See [examples/README.md](examples/README.md) for more details.
131
447
 
132
- ## When Not to Use
448
+ ---
449
+
450
+ ## 🛠️ Development
451
+
452
+ ### CLI (`pxl`)
453
+
454
+ The framework now ships with a bundled CLI executable exposed as `pxl` when the package is installed.
133
455
 
134
- If you only need a single HTTP server or minimal script, this framework may be heavier than needed.
456
+ Current capabilities:
135
457
 
136
- ## Contributing
458
+ - `pxl --version` / `pxl -v` / `pxl version` – Print framework version
459
+ - `pxl info` (or just `pxl`) – Display banner + roadmap
137
460
 
138
- Issues and PRs welcome. Development scripts remain available:
461
+ Planned subcommands (roadmap):
462
+
463
+ - `pxl doctor` – Environment diagnostics (Node version, dependency checks, Redis/Postgres availability)
464
+ - `pxl generate` – Scaffolding for applications, routes, commands, processors
465
+ - `pxl analyze` – Project inspection (unused files, dependency graph summary)
466
+
467
+ Usage examples:
139
468
 
140
469
  ```bash
141
- npm run dev # watch build
142
- npm run build # production build
470
+ # Show version
471
+ pxl --version
472
+
473
+ # Show framework banner and roadmap
474
+ pxl info
475
+
476
+ # (Future) Run doctor diagnostics
477
+ pxl doctor
143
478
  ```
144
479
 
480
+ Development Note:
481
+
482
+ When iterating locally, rebuild after CLI changes:
483
+
484
+ ```bash
485
+ npm run build && pxl info
486
+ ```
487
+
488
+ To test unpublished changes in another project via yalc:
489
+
490
+ ```bash
491
+ npm run build:local
492
+ yalc add @scpxl/nodejs-framework
493
+ ```
494
+
495
+ For contributions adding new subcommands, implement them in `src/cli/` and register via the yargs builder in `src/cli/index.ts`.
496
+
497
+ ### Build Commands
498
+
499
+ ```bash
500
+ # Development with hot-reload
501
+ npm run dev
502
+
503
+ # Production build
504
+ npm run build
505
+
506
+ # Type checking
507
+ npm run typecheck
508
+
509
+ # Linting
510
+ npm run lint
511
+ npm run lint:fix
512
+
513
+ # Code formatting
514
+ npm run prettier
515
+ npm run prettier:fix
516
+ ```
517
+
518
+ ### Testing
519
+
520
+ ```bash
521
+ # Run all tests
522
+ npm test
523
+
524
+ # Run tests in watch mode
525
+ npm run test:watch
526
+
527
+ # Run with coverage report
528
+ npm run test:coverage
529
+
530
+ # Run specific test suites
531
+ npm run test:unit
532
+ npm run test:integration
533
+ npm run test:e2e
534
+
535
+ # Run tests with UI
536
+ npm run test:ui
537
+ ```
538
+
539
+ The framework maintains **80% code coverage** across all metrics (lines, branches, functions, statements) as enforced by Vitest thresholds.
540
+
541
+ ### Framework Status Report
542
+
543
+ Generate a cross-platform project health snapshot (dependency counts, git status, directory sizes, large packages, outdated/age metrics):
544
+
545
+ ```bash
546
+ npm run status
547
+ ```
548
+
549
+ Optional flags:
550
+
551
+ ```bash
552
+ npm run status -- --include-cache # Include .turbo/ and .next/cache directories
553
+ npm run status -- --exclude "coverage,fixtures,**/*.snap" # Additional exclude globs (comma-separated)
554
+ ```
555
+
556
+ What it does:
557
+
558
+ - Collects repo & package metadata (version, scripts, dependency counts)
559
+ - Summarizes current git branch, last commit, and pending change counts
560
+ - Computes sizes for `src`, `dist`, and `node_modules` using fast native traversal (`fast-folder-size`) with a JS fallback, filtering via `.gitignore` / `.npmignore` plus exclusions
561
+ - Lists the largest packages in `node_modules` (top 8 by size)
562
+ - Ranks outdated dependencies by publish age and major version lag (uses `npm outdated` / `npm view`)
563
+ - Provides age distribution stats for installed top-level packages
564
+
565
+ Exclusions & Ignore Behavior:
566
+
567
+ - Always respects patterns found in `.gitignore` and `.npmignore` (except always keeps top-level `dist` & `node_modules`)
568
+ - Built-in default excludes: `coverage/`, `fixtures/`, and `**/*.snap`
569
+ - Skips heavy build caches (`.turbo`, `.next/cache`) unless `--include-cache` is passed
570
+
571
+ Return codes: exits with non-zero only on unexpected internal errors; missing npm or network failures simply degrade sections gracefully.
572
+
573
+ ### Local Development with Yalc
574
+
575
+ For testing changes in consuming applications:
576
+
577
+ ```bash
578
+ # Publish framework locally
579
+ npm run build:local
580
+
581
+ # In your consuming project
582
+ yalc add @scpxl/nodejs-framework
583
+
584
+ # Push updates after changes
585
+ npm run yalc:push
586
+ ```
587
+
588
+ ---
589
+
590
+ ## 🔧 Configuration
591
+
592
+ ### Environment Variables
593
+
594
+ Create a `.env` file in your project root:
595
+
596
+ ```env
597
+ # Application
598
+ NODE_ENV=development
599
+ APP_NAME=my-app
600
+ APP_PORT=3000
601
+
602
+ # Database
603
+ DB_HOST=localhost
604
+ DB_PORT=5432
605
+ DB_USERNAME=postgres
606
+ DB_PASSWORD=password
607
+ DB_NAME=myapp
608
+
609
+ # Redis
610
+ REDIS_HOST=127.0.0.1
611
+ REDIS_PORT=6379
612
+ REDIS_PASSWORD=
613
+
614
+ # Logging
615
+ LOG_LEVEL=info
616
+
617
+ # Sentry (optional)
618
+ SENTRY_DSN=https://...
619
+ ```
620
+
621
+ ### TypeScript Configuration
622
+
623
+ The framework uses **ESNext** module target with `.js` extensions in imports:
624
+
625
+ ```typescript
626
+ // ✅ Correct
627
+ import { WebApplication } from '@scpxl/nodejs-framework/application';
628
+
629
+ // ✅ Also correct (in framework source)
630
+ import { Logger } from '../logger/index.js';
631
+
632
+ // ❌ Incorrect (in framework source)
633
+ import { Logger } from '../logger'; // Missing .js extension
634
+ ```
635
+
636
+ ---
637
+
638
+ ## 🏗️ Architecture Overview
639
+
640
+ ```
641
+ ┌─────────────────────────────────────────────────────────┐
642
+ │ Application Layer │
643
+ │ ┌─────────────┐ ┌──────────────┐ ┌───────────────┐ │
644
+ │ │ Web │ │ Command │ │ Custom App │ │
645
+ │ │ Application │ │ Application │ │ │ │
646
+ │ └──────┬──────┘ └──────┬───────┘ └───────┬───────┘ │
647
+ └─────────┼─────────────────┼──────────────────┼──────────┘
648
+ │ │ │
649
+ └─────────────────┴──────────────────┘
650
+
651
+ ┌─────────────────▼──────────────────┐
652
+ │ Base Application │
653
+ │ ┌──────────────────────────────┐ │
654
+ │ │ Lifecycle Manager │ │
655
+ │ │ - Startup phases │ │
656
+ │ │ - Readiness probes │ │
657
+ │ │ - Graceful shutdown │ │
658
+ │ └──────────────────────────────┘ │
659
+ └────────────────┬───────────────────┘
660
+
661
+ ┌─────────────────────┼─────────────────────┐
662
+ │ │ │
663
+ ┌────▼─────┐ ┌────────▼────────┐ ┌───────▼──────┐
664
+ │ Redis │ │ Database │ │ Queue │
665
+ │ Manager │◄─────┤ Manager │ │ Manager │
666
+ └────┬─────┘ └────────┬────────┘ └───────┬──────┘
667
+ │ │ │
668
+ ┌────▼─────┐ ┌────────▼────────┐ ┌───────▼──────┐
669
+ │ Cache │ │ MikroORM │ │ BullMQ │
670
+ │ Manager │ │ PostgreSQL │ │ Workers │
671
+ └──────────┘ └─────────────────┘ └──────────────┘
672
+ ```
673
+
674
+ ---
675
+
676
+ ## 🎯 When to Use PXL Framework
677
+
678
+ ### ✅ **Good Fit**
679
+
680
+ - Building **APIs** or **microservices** with TypeScript
681
+ - Need **real-time features** via WebSockets
682
+ - Require **background job processing** with queues
683
+ - Want **structured application lifecycle** with health checks
684
+ - Building **full-stack applications** with unified backend framework
685
+ - Need **production-ready** defaults with observability built-in
686
+
687
+ ### ⚠️ **Consider Alternatives**
688
+
689
+ - **Simple scripts** or **single-purpose utilities** - Framework may be heavier than needed
690
+ - **Serverless functions** - Better suited for lightweight frameworks
691
+ - **Non-TypeScript projects** - Framework is TypeScript-first
692
+
693
+ ---
694
+
695
+ ## 🤝 Contributing
696
+
697
+ We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for:
698
+
699
+ - Development setup instructions
700
+ - Code style guidelines
701
+ - Testing requirements
702
+ - Pull request process
703
+
704
+ ### Quick Contribution Guide
705
+
706
+ 1. Fork the repository
707
+ 2. Create a feature branch: `git checkout -b feature/my-feature`
708
+ 3. Make your changes with tests
709
+ 4. Run checks: `npm run check-all` (linting, prettier, typecheck)
710
+ 5. Ensure tests pass: `npm test`
711
+ 6. Commit with descriptive message
712
+ 7. Push and create a Pull Request
713
+
714
+ ---
715
+
716
+ ## 🐛 Troubleshooting
717
+
718
+ ### Database Connection Issues
719
+
720
+ ```
721
+ Error: Connection to database failed
722
+ ```
723
+
724
+ **Solution**: Ensure PostgreSQL is running and credentials are correct in `.env`
725
+
726
+ ```bash
727
+ # Check PostgreSQL status
728
+ docker ps | grep postgres
729
+
730
+ # Start PostgreSQL with Docker
731
+ docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres:16
732
+ ```
733
+
734
+ ### Redis Connection Errors
735
+
736
+ ```
737
+ Error: Redis connection refused
738
+ ```
739
+
740
+ **Solution**: Ensure Redis is running
741
+
742
+ ```bash
743
+ # Start Redis with Docker
744
+ docker run -d -p 6379:6379 redis:7-alpine
745
+ ```
746
+
747
+ ### Port Already in Use
748
+
749
+ ```
750
+ Error: listen EADDRINUSE: address already in use :::3000
751
+ ```
752
+
753
+ **Solution**: Change the port in configuration or kill the process using the port
754
+
755
+ ```bash
756
+ # Find process using port 3000
757
+ lsof -i :3000
758
+
759
+ # Kill the process
760
+ kill -9 <PID>
761
+ ```
762
+
763
+ ### TypeScript Module Resolution
764
+
765
+ ```
766
+ Error: Cannot find module '../logger/index.js'
767
+ ```
768
+
769
+ **Solution**: Ensure all imports in framework source code use `.js` extensions (required for ESM)
770
+
771
+ ---
772
+
773
+ ## 📄 License
774
+
775
+ [ISC License](LICENSE) - Copyright (c) PXL Agency
776
+
777
+ ---
778
+
779
+ ## 🔗 Links
780
+
781
+ - **Documentation**: https://pxlbros.github.io/pxl-nodejs-framework/
782
+ - **npm Package**: https://www.npmjs.com/package/@scpxl/nodejs-framework
783
+ - **GitHub Repository**: https://github.com/pxlbros/pxl-nodejs-framework
784
+ - **Issues**: https://github.com/pxlbros/pxl-nodejs-framework/issues
785
+ - **Changelog**: [CHANGELOG.md](CHANGELOG.md)
786
+ - **TODO/Roadmap**: [TODO.md](TODO.md)
787
+
788
+ ---
789
+
790
+ ## 💬 Support
791
+
792
+ For questions, issues, or feature requests:
793
+
794
+ - Open an [issue on GitHub](https://github.com/pxlbros/pxl-nodejs-framework/issues)
795
+ - Check existing [discussions](https://github.com/pxlbros/pxl-nodejs-framework/discussions)
796
+ - Review [documentation](https://pxlbros.github.io/pxl-nodejs-framework/)
797
+
145
798
  ---
146
799
 
147
- Released under ISC License.
800
+ **Built with ❤️ by [PXL Agency](https://pxlagency.com)**