@scpxl/nodejs-framework 1.0.20 β 1.0.22
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 +15 -0
- package/README.md +530 -67
- package/dist/application/base-application.js +1 -1
- package/dist/application/base-application.js.map +2 -2
- package/dist/application/command-application.js.map +2 -2
- package/dist/application/web-application.js +1 -0
- package/dist/application/web-application.js.map +2 -2
- package/dist/command/command.js.map +1 -1
- package/dist/config/schema.js +17 -7
- package/dist/config/schema.js.map +2 -2
- package/dist/event/manager.js.map +2 -2
- package/dist/lifecycle/lifecycle-manager.js.map +2 -2
- package/dist/logger/logger.js +21 -1
- package/dist/logger/logger.js.map +2 -2
- package/dist/queue/index.js.map +1 -1
- package/dist/queue/manager.js +24 -12
- package/dist/queue/manager.js.map +2 -2
- package/dist/queue/processor/base.js.map +2 -2
- package/dist/services/aws/s3.js.map +2 -2
- package/dist/util/helper.js +1 -1
- package/dist/util/helper.js.map +2 -2
- package/dist/util/loader.js.map +2 -2
- package/dist/webserver/controller/base.js.map +2 -2
- package/dist/webserver/define-route.js +22 -0
- package/dist/webserver/define-route.js.map +7 -0
- package/dist/webserver/index.js +2 -0
- package/dist/webserver/index.js.map +2 -2
- package/dist/webserver/webserver.interface.js.map +2 -2
- package/dist/webserver/webserver.js +211 -56
- package/dist/webserver/webserver.js.map +2 -2
- package/dist/websocket/websocket-base.js.map +2 -2
- package/dist/websocket/websocket-client.js.map +1 -1
- package/dist/websocket/websocket-server.js +5 -5
- package/dist/websocket/websocket-server.js.map +2 -2
- package/dist/websocket/websocket.interface.js.map +2 -2
- package/package.json +3 -2
- package/dist/api-requester/api-requester.d.ts +0 -32
- package/dist/api-requester/api-requester.d.ts.map +0 -1
- package/dist/api-requester/index.d.ts +0 -3
- package/dist/api-requester/index.d.ts.map +0 -1
- package/dist/application/base-application.d.ts +0 -106
- package/dist/application/base-application.d.ts.map +0 -1
- package/dist/application/base-application.interface.d.ts +0 -161
- package/dist/application/base-application.interface.d.ts.map +0 -1
- package/dist/application/command-application.d.ts +0 -18
- package/dist/application/command-application.d.ts.map +0 -1
- package/dist/application/command-application.interface.d.ts +0 -26
- package/dist/application/command-application.interface.d.ts.map +0 -1
- package/dist/application/index.d.ts +0 -5
- package/dist/application/index.d.ts.map +0 -1
- package/dist/application/web-application.d.ts +0 -43
- package/dist/application/web-application.d.ts.map +0 -1
- package/dist/application/web-application.interface.d.ts +0 -21
- package/dist/application/web-application.interface.d.ts.map +0 -1
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/jwt.d.ts +0 -25
- package/dist/auth/jwt.d.ts.map +0 -1
- package/dist/cache/index.d.ts +0 -2
- package/dist/cache/index.d.ts.map +0 -1
- package/dist/cache/manager.d.ts +0 -107
- package/dist/cache/manager.d.ts.map +0 -1
- package/dist/cluster/cluster-manager.d.ts +0 -15
- package/dist/cluster/cluster-manager.d.ts.map +0 -1
- package/dist/cluster/cluster-manager.interface.d.ts +0 -23
- package/dist/cluster/cluster-manager.interface.d.ts.map +0 -1
- package/dist/cluster/index.d.ts +0 -2
- package/dist/cluster/index.d.ts.map +0 -1
- package/dist/command/command-manager.d.ts +0 -19
- package/dist/command/command-manager.d.ts.map +0 -1
- package/dist/command/command.d.ts +0 -27
- package/dist/command/command.d.ts.map +0 -1
- package/dist/command/command.interface.d.ts +0 -11
- package/dist/command/command.interface.d.ts.map +0 -1
- package/dist/command/index.d.ts +0 -3
- package/dist/command/index.d.ts.map +0 -1
- package/dist/config/env.d.ts +0 -11
- package/dist/config/env.d.ts.map +0 -1
- package/dist/config/index.d.ts +0 -3
- package/dist/config/index.d.ts.map +0 -1
- package/dist/config/schema.d.ts +0 -408
- package/dist/config/schema.d.ts.map +0 -1
- package/dist/database/dynamic-entity-form-decorators.d.ts +0 -31
- package/dist/database/dynamic-entity-form-decorators.d.ts.map +0 -1
- package/dist/database/dynamic-entity.d.ts +0 -15
- package/dist/database/dynamic-entity.d.ts.map +0 -1
- package/dist/database/index.d.ts +0 -5
- package/dist/database/index.d.ts.map +0 -1
- package/dist/database/instance.d.ts +0 -36
- package/dist/database/instance.d.ts.map +0 -1
- package/dist/database/instance.interface.d.ts +0 -5
- package/dist/database/instance.interface.d.ts.map +0 -1
- package/dist/database/manager.d.ts +0 -27
- package/dist/database/manager.d.ts.map +0 -1
- package/dist/database/manager.interface.d.ts +0 -18
- package/dist/database/manager.interface.d.ts.map +0 -1
- package/dist/error/error-reporter.d.ts +0 -96
- package/dist/error/error-reporter.d.ts.map +0 -1
- package/dist/error/error.interface.d.ts +0 -126
- package/dist/error/error.interface.d.ts.map +0 -1
- package/dist/error/framework-errors.d.ts +0 -113
- package/dist/error/framework-errors.d.ts.map +0 -1
- package/dist/error/index.d.ts +0 -6
- package/dist/error/index.d.ts.map +0 -1
- package/dist/event/controller/base.d.ts +0 -23
- package/dist/event/controller/base.d.ts.map +0 -1
- package/dist/event/controller/base.interface.d.ts +0 -11
- package/dist/event/controller/base.interface.d.ts.map +0 -1
- package/dist/event/index.d.ts +0 -5
- package/dist/event/index.d.ts.map +0 -1
- package/dist/event/manager.d.ts +0 -21
- package/dist/event/manager.d.ts.map +0 -1
- package/dist/event/manager.interface.d.ts +0 -134
- package/dist/event/manager.interface.d.ts.map +0 -1
- package/dist/index.d.ts +0 -22
- package/dist/index.d.ts.map +0 -1
- package/dist/lifecycle/exit.d.ts +0 -11
- package/dist/lifecycle/exit.d.ts.map +0 -1
- package/dist/lifecycle/index.d.ts +0 -7
- package/dist/lifecycle/index.d.ts.map +0 -1
- package/dist/lifecycle/lifecycle-manager.d.ts +0 -66
- package/dist/lifecycle/lifecycle-manager.d.ts.map +0 -1
- package/dist/lifecycle/shutdown-controller.d.ts +0 -15
- package/dist/lifecycle/shutdown-controller.d.ts.map +0 -1
- package/dist/lifecycle/types.d.ts +0 -28
- package/dist/lifecycle/types.d.ts.map +0 -1
- package/dist/logger/index.d.ts +0 -2
- package/dist/logger/index.d.ts.map +0 -1
- package/dist/logger/logger.d.ts +0 -55
- package/dist/logger/logger.d.ts.map +0 -1
- package/dist/logger/logger.interface.d.ts +0 -2
- package/dist/logger/logger.interface.d.ts.map +0 -1
- package/dist/performance/cache-performance.d.ts +0 -64
- package/dist/performance/cache-performance.d.ts.map +0 -1
- package/dist/performance/database-performance.d.ts +0 -40
- package/dist/performance/database-performance.d.ts.map +0 -1
- package/dist/performance/index.d.ts +0 -8
- package/dist/performance/index.d.ts.map +0 -1
- package/dist/performance/performance-monitor.d.ts +0 -68
- package/dist/performance/performance-monitor.d.ts.map +0 -1
- package/dist/performance/performance-monitor.plugin.d.ts +0 -24
- package/dist/performance/performance-monitor.plugin.d.ts.map +0 -1
- package/dist/performance/queue-performance.d.ts +0 -46
- package/dist/performance/queue-performance.d.ts.map +0 -1
- package/dist/performance/webserver-performance.d.ts +0 -69
- package/dist/performance/webserver-performance.d.ts.map +0 -1
- package/dist/performance/websocket-performance.d.ts +0 -44
- package/dist/performance/websocket-performance.d.ts.map +0 -1
- package/dist/queue/index.d.ts +0 -6
- package/dist/queue/index.d.ts.map +0 -1
- package/dist/queue/index.interface.d.ts +0 -10
- package/dist/queue/index.interface.d.ts.map +0 -1
- package/dist/queue/job.interface.d.ts +0 -42
- package/dist/queue/job.interface.d.ts.map +0 -1
- package/dist/queue/manager.d.ts +0 -36
- package/dist/queue/manager.d.ts.map +0 -1
- package/dist/queue/manager.interface.d.ts +0 -18
- package/dist/queue/manager.interface.d.ts.map +0 -1
- package/dist/queue/processor/base.d.ts +0 -28
- package/dist/queue/processor/base.d.ts.map +0 -1
- package/dist/queue/processor/processor.interface.d.ts +0 -15
- package/dist/queue/processor/processor.interface.d.ts.map +0 -1
- package/dist/queue/worker.d.ts +0 -14
- package/dist/queue/worker.d.ts.map +0 -1
- package/dist/queue/worker.interface.d.ts +0 -13
- package/dist/queue/worker.interface.d.ts.map +0 -1
- package/dist/redis/index.d.ts +0 -3
- package/dist/redis/index.d.ts.map +0 -1
- package/dist/redis/instance.d.ts +0 -32
- package/dist/redis/instance.d.ts.map +0 -1
- package/dist/redis/instance.interface.d.ts +0 -9
- package/dist/redis/instance.interface.d.ts.map +0 -1
- package/dist/redis/manager.d.ts +0 -15
- package/dist/redis/manager.d.ts.map +0 -1
- package/dist/redis/manager.interface.d.ts +0 -8
- package/dist/redis/manager.interface.d.ts.map +0 -1
- package/dist/request-context/index.d.ts +0 -3
- package/dist/request-context/index.d.ts.map +0 -1
- package/dist/request-context/request-context.d.ts +0 -108
- package/dist/request-context/request-context.d.ts.map +0 -1
- package/dist/request-context/request-context.interface.d.ts +0 -46
- package/dist/request-context/request-context.interface.d.ts.map +0 -1
- package/dist/services/aws/index.d.ts +0 -2
- package/dist/services/aws/index.d.ts.map +0 -1
- package/dist/services/aws/s3.d.ts +0 -54
- package/dist/services/aws/s3.d.ts.map +0 -1
- package/dist/services/aws/s3.interface.d.ts +0 -14
- package/dist/services/aws/s3.interface.d.ts.map +0 -1
- package/dist/services/index.d.ts +0 -2
- package/dist/services/index.d.ts.map +0 -1
- package/dist/util/file.d.ts +0 -58
- package/dist/util/file.d.ts.map +0 -1
- package/dist/util/helper.d.ts +0 -52
- package/dist/util/helper.d.ts.map +0 -1
- package/dist/util/image.d.ts +0 -12
- package/dist/util/image.d.ts.map +0 -1
- package/dist/util/index.d.ts +0 -11
- package/dist/util/index.d.ts.map +0 -1
- package/dist/util/loader.d.ts +0 -19
- package/dist/util/loader.d.ts.map +0 -1
- package/dist/util/num.d.ts +0 -13
- package/dist/util/num.d.ts.map +0 -1
- package/dist/util/os.d.ts +0 -6
- package/dist/util/os.d.ts.map +0 -1
- package/dist/util/str.d.ts +0 -39
- package/dist/util/str.d.ts.map +0 -1
- package/dist/util/time.d.ts +0 -19
- package/dist/util/time.d.ts.map +0 -1
- package/dist/util/time.interface.d.ts +0 -12
- package/dist/util/time.interface.d.ts.map +0 -1
- package/dist/util/timing.d.ts +0 -36
- package/dist/util/timing.d.ts.map +0 -1
- package/dist/util/timing.interface.d.ts +0 -47
- package/dist/util/timing.interface.d.ts.map +0 -1
- package/dist/util/url.d.ts +0 -7
- package/dist/util/url.d.ts.map +0 -1
- package/dist/webserver/controller/auth-middleware.d.ts +0 -21
- package/dist/webserver/controller/auth-middleware.d.ts.map +0 -1
- package/dist/webserver/controller/base.d.ts +0 -41
- package/dist/webserver/controller/base.d.ts.map +0 -1
- package/dist/webserver/controller/base.interface.d.ts +0 -47
- package/dist/webserver/controller/base.interface.d.ts.map +0 -1
- package/dist/webserver/controller/entity.d.ts +0 -94
- package/dist/webserver/controller/entity.d.ts.map +0 -1
- package/dist/webserver/controller/example-auth.d.ts +0 -12
- package/dist/webserver/controller/example-auth.d.ts.map +0 -1
- package/dist/webserver/controller/health.d.ts +0 -15
- package/dist/webserver/controller/health.d.ts.map +0 -1
- package/dist/webserver/index.d.ts +0 -12
- package/dist/webserver/index.d.ts.map +0 -1
- package/dist/webserver/util.d.ts +0 -10
- package/dist/webserver/util.d.ts.map +0 -1
- package/dist/webserver/webserver.d.ts +0 -79
- package/dist/webserver/webserver.d.ts.map +0 -1
- package/dist/webserver/webserver.interface.d.ts +0 -155
- package/dist/webserver/webserver.interface.d.ts.map +0 -1
- package/dist/websocket/controller/client/base.d.ts +0 -12
- package/dist/websocket/controller/client/base.d.ts.map +0 -1
- package/dist/websocket/controller/client/base.interface.d.ts +0 -12
- package/dist/websocket/controller/client/base.interface.d.ts.map +0 -1
- package/dist/websocket/controller/server/base.d.ts +0 -13
- package/dist/websocket/controller/server/base.d.ts.map +0 -1
- package/dist/websocket/controller/server/base.interface.d.ts +0 -13
- package/dist/websocket/controller/server/base.interface.d.ts.map +0 -1
- package/dist/websocket/controllers/client/system.d.ts +0 -6
- package/dist/websocket/controllers/client/system.d.ts.map +0 -1
- package/dist/websocket/controllers/server/system.d.ts +0 -7
- package/dist/websocket/controllers/server/system.d.ts.map +0 -1
- package/dist/websocket/index.d.ts +0 -7
- package/dist/websocket/index.d.ts.map +0 -1
- package/dist/websocket/routes/client/system.d.ts +0 -3
- package/dist/websocket/routes/client/system.d.ts.map +0 -1
- package/dist/websocket/routes/server/system.d.ts +0 -3
- package/dist/websocket/routes/server/system.d.ts.map +0 -1
- package/dist/websocket/utils.d.ts +0 -9
- package/dist/websocket/utils.d.ts.map +0 -1
- package/dist/websocket/websocket-base.d.ts +0 -15
- package/dist/websocket/websocket-base.d.ts.map +0 -1
- package/dist/websocket/websocket-client-manager.d.ts +0 -53
- package/dist/websocket/websocket-client-manager.d.ts.map +0 -1
- package/dist/websocket/websocket-client-manager.interface.d.ts +0 -8
- package/dist/websocket/websocket-client-manager.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-client.d.ts +0 -35
- package/dist/websocket/websocket-client.d.ts.map +0 -1
- package/dist/websocket/websocket-client.interface.d.ts +0 -14
- package/dist/websocket/websocket-client.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-room-manager.d.ts +0 -32
- package/dist/websocket/websocket-room-manager.d.ts.map +0 -1
- package/dist/websocket/websocket-server.d.ts +0 -92
- package/dist/websocket/websocket-server.d.ts.map +0 -1
- package/dist/websocket/websocket-server.interface.d.ts +0 -16
- package/dist/websocket/websocket-server.interface.d.ts.map +0 -1
- package/dist/websocket/websocket-service.d.ts +0 -44
- package/dist/websocket/websocket-service.d.ts.map +0 -1
- package/dist/websocket/websocket.interface.d.ts +0 -119
- package/dist/websocket/websocket.interface.d.ts.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
ISC License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 PXL Agency <devops@pxlagency.com>
|
|
4
|
+
|
|
5
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
6
|
+
purpose with or without fee is hereby granted, provided that the above
|
|
7
|
+
copyright notice and this permission notice appear in all copies.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
10
|
+
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
11
|
+
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
12
|
+
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
13
|
+
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
14
|
+
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
15
|
+
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,120 +1,305 @@
|
|
|
1
1
|
# PXL Node.js Framework
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@scpxl/nodejs-framework)
|
|
4
|
+
[](https://nodejs.org)
|
|
5
|
+
[](https://opensource.org/licenses/ISC)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
4
7
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
68
|
+
**Requirements:**
|
|
14
69
|
|
|
15
|
-
|
|
16
|
-
|
|
70
|
+
- Node.js >= 22.0.0
|
|
71
|
+
- PostgreSQL (optional, for database features)
|
|
72
|
+
- Redis (optional, for caching and queues)
|
|
17
73
|
|
|
18
|
-
|
|
19
|
-
webserver: { port: 3000 },
|
|
20
|
-
logger: { level: 'info' },
|
|
21
|
-
});
|
|
74
|
+
---
|
|
22
75
|
|
|
23
|
-
|
|
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 () =>
|
|
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
|
-
|
|
113
|
+
### With Database & Queue
|
|
33
114
|
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
|
|
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
|
});
|
|
38
|
-
```
|
|
39
144
|
|
|
40
|
-
|
|
145
|
+
await app.start();
|
|
41
146
|
|
|
42
|
-
|
|
43
|
-
await app.queue.manager.
|
|
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
|
+
});
|
|
44
153
|
```
|
|
45
154
|
|
|
46
|
-
|
|
155
|
+
### WebSocket Server
|
|
47
156
|
|
|
48
|
-
```
|
|
49
|
-
|
|
157
|
+
```typescript
|
|
158
|
+
import { WebApplication } from '@scpxl/nodejs-framework';
|
|
159
|
+
|
|
160
|
+
const app = new WebApplication({
|
|
161
|
+
name: 'chat-app',
|
|
50
162
|
webserver: { port: 3000 },
|
|
51
163
|
websocket: { enabled: true },
|
|
52
|
-
queue: { enabled: true },
|
|
53
164
|
redis: { host: '127.0.0.1', port: 6379 },
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
await app.start();
|
|
168
|
+
|
|
169
|
+
// Handle WebSocket connections
|
|
170
|
+
app.websocket.server.onConnection(client => {
|
|
171
|
+
console.log('Client connected:', client.id);
|
|
172
|
+
|
|
173
|
+
client.sendJSON({ type: 'welcome', message: 'Connected to chat server' });
|
|
174
|
+
|
|
175
|
+
client.on('message', data => {
|
|
176
|
+
// Broadcast to all clients
|
|
177
|
+
app.websocket.server.broadcast({ type: 'chat', data });
|
|
178
|
+
});
|
|
58
179
|
});
|
|
59
180
|
```
|
|
60
181
|
|
|
61
|
-
|
|
182
|
+
---
|
|
62
183
|
|
|
63
|
-
|
|
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
|
|
184
|
+
## π Documentation
|
|
71
185
|
|
|
72
|
-
|
|
186
|
+
### Architecture
|
|
73
187
|
|
|
74
|
-
|
|
188
|
+
The framework is built around three main application types:
|
|
75
189
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
190
|
+
1. **`BaseApplication`** - Abstract base with Redis, Database, Queue, Events, Performance Monitoring
|
|
191
|
+
2. **`WebApplication`** - Extends `BaseApplication` with Fastify web server and WebSocket support
|
|
192
|
+
3. **`CommandApplication`** - Extends `BaseApplication` for CLI commands and scripts
|
|
78
193
|
|
|
79
|
-
|
|
194
|
+
### Core Components
|
|
80
195
|
|
|
81
|
-
|
|
82
|
-
|
|
196
|
+
| Component | Description | Import Path |
|
|
197
|
+
| ------------------- | ------------------------------------------------ | ----------------------------------------- |
|
|
198
|
+
| **Application** | Main application classes | `@scpxl/nodejs-framework/application` |
|
|
199
|
+
| **Logger** | Structured logging with Winston | `@scpxl/nodejs-framework/logger` |
|
|
200
|
+
| **Database** | MikroORM integration and entity management | `@scpxl/nodejs-framework/database` |
|
|
201
|
+
| **WebServer** | Fastify server and routing | `@scpxl/nodejs-framework/webserver` |
|
|
202
|
+
| **WebSocket** | WebSocket server and client | `@scpxl/nodejs-framework/websocket` |
|
|
203
|
+
| **Queue** | BullMQ job queue management | `@scpxl/nodejs-framework/queue` |
|
|
204
|
+
| **Redis** | Redis connection management | `@scpxl/nodejs-framework/redis` |
|
|
205
|
+
| **Cache** | High-level caching abstraction | `@scpxl/nodejs-framework/cache` |
|
|
206
|
+
| **Auth** | JWT authentication utilities | `@scpxl/nodejs-framework/auth` |
|
|
207
|
+
| **Request Context** | Request correlation and tracing | `@scpxl/nodejs-framework/request-context` |
|
|
208
|
+
| **Lifecycle** | Application lifecycle and shutdown management | `@scpxl/nodejs-framework/lifecycle` |
|
|
209
|
+
| **Error** | Custom error classes | `@scpxl/nodejs-framework/error` |
|
|
210
|
+
| **Utilities** | File, string, time, URL helpers | `@scpxl/nodejs-framework/util` |
|
|
211
|
+
| **Performance** | Performance monitoring and metrics | `@scpxl/nodejs-framework/performance` |
|
|
212
|
+
| **API Requester** | HTTP client wrapper (migrated to native `fetch`) | `@scpxl/nodejs-framework/api-requester` |
|
|
213
|
+
| **Command** | CLI command framework | `@scpxl/nodejs-framework/command` |
|
|
214
|
+
| **Services** | Additional service integrations (AWS S3, etc.) | `@scpxl/nodejs-framework/services` |
|
|
215
|
+
|
|
216
|
+
### Key Patterns
|
|
217
|
+
|
|
218
|
+
#### Lifecycle Hooks
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
const app = new WebApplication(config);
|
|
222
|
+
|
|
223
|
+
// Register lifecycle hooks
|
|
224
|
+
app.lifecycle.onStart(async () => {
|
|
225
|
+
console.log('Application starting...');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
app.lifecycle.onReady(async () => {
|
|
229
|
+
console.log('Application ready for traffic');
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
app.lifecycle.onShutdown(async () => {
|
|
233
|
+
console.log('Cleaning up resources...');
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
await app.start();
|
|
83
237
|
```
|
|
84
238
|
|
|
85
|
-
|
|
239
|
+
#### Graceful Shutdown
|
|
240
|
+
|
|
241
|
+
```typescript
|
|
242
|
+
const app = new WebApplication(config);
|
|
86
243
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
244
|
+
await app.start();
|
|
245
|
+
|
|
246
|
+
// Handle signals
|
|
247
|
+
process.on('SIGINT', async () => {
|
|
248
|
+
console.log('Received SIGINT, shutting down gracefully...');
|
|
249
|
+
await app.stop();
|
|
250
|
+
process.exit(0);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
process.on('SIGTERM', async () => {
|
|
254
|
+
console.log('Received SIGTERM, shutting down gracefully...');
|
|
255
|
+
await app.stop();
|
|
256
|
+
process.exit(0);
|
|
257
|
+
});
|
|
90
258
|
```
|
|
91
259
|
|
|
92
|
-
|
|
260
|
+
#### Service Injection Pattern
|
|
93
261
|
|
|
94
|
-
```
|
|
262
|
+
```typescript
|
|
95
263
|
class UserService {
|
|
96
|
-
constructor(private app:
|
|
97
|
-
|
|
98
|
-
|
|
264
|
+
constructor(private app: WebApplication) {}
|
|
265
|
+
|
|
266
|
+
async createUser(data: CreateUserDto) {
|
|
267
|
+
// Use database
|
|
268
|
+
const user = this.app.database.instance.em.create(User, data);
|
|
269
|
+
await this.app.database.instance.em.flush();
|
|
270
|
+
|
|
271
|
+
// Use queue
|
|
272
|
+
await this.app.queue.manager.addJobToQueue({
|
|
273
|
+
queueId: 'email',
|
|
274
|
+
jobId: 'send-welcome',
|
|
275
|
+
data: { userId: user.id },
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// Use logger
|
|
279
|
+
this.app.logger.info('User created', { userId: user.id });
|
|
280
|
+
|
|
281
|
+
return user;
|
|
99
282
|
}
|
|
100
283
|
}
|
|
101
284
|
```
|
|
102
285
|
|
|
103
|
-
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## π Examples
|
|
104
289
|
|
|
105
|
-
The `examples/` directory contains working
|
|
290
|
+
The `examples/` directory contains working demonstrations:
|
|
106
291
|
|
|
107
292
|
### Hello World Example
|
|
108
293
|
|
|
109
|
-
A
|
|
294
|
+
A full-stack example with:
|
|
110
295
|
|
|
111
|
-
- Backend
|
|
112
|
-
- Frontend
|
|
296
|
+
- **Backend**: PXL WebApplication with TypeScript, WebSocket support, and API routes
|
|
297
|
+
- **Frontend**: Vue 3 + TypeScript + Vite with real-time WebSocket updates
|
|
113
298
|
|
|
114
299
|
**Run the example:**
|
|
115
300
|
|
|
116
301
|
```bash
|
|
117
|
-
# Install dependencies for
|
|
302
|
+
# Install dependencies for examples (one-time setup)
|
|
118
303
|
npm run example:install
|
|
119
304
|
|
|
120
305
|
# Run backend + frontend together with hot-reload
|
|
@@ -127,21 +312,299 @@ npm run example:hello-world:frontend
|
|
|
127
312
|
|
|
128
313
|
Then open http://localhost:5173 to see the app.
|
|
129
314
|
|
|
315
|
+
### CLI Commands Example
|
|
316
|
+
|
|
317
|
+
Demonstrates the command framework with examples:
|
|
318
|
+
|
|
319
|
+
```bash
|
|
320
|
+
# Install dependencies
|
|
321
|
+
npm run example:commands:install
|
|
322
|
+
|
|
323
|
+
# Run hello command
|
|
324
|
+
npm run example:commands:hello
|
|
325
|
+
|
|
326
|
+
# Run database seed command
|
|
327
|
+
npm run example:commands:seed
|
|
328
|
+
|
|
329
|
+
# Run queue processing command
|
|
330
|
+
npm run example:commands:queue
|
|
331
|
+
```
|
|
332
|
+
|
|
130
333
|
See [examples/README.md](examples/README.md) for more details.
|
|
131
334
|
|
|
132
|
-
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## π οΈ Development
|
|
338
|
+
|
|
339
|
+
### Build Commands
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
# Development with hot-reload
|
|
343
|
+
npm run dev
|
|
344
|
+
|
|
345
|
+
# Production build
|
|
346
|
+
npm run build
|
|
347
|
+
|
|
348
|
+
# Type checking
|
|
349
|
+
npm run typecheck
|
|
350
|
+
|
|
351
|
+
# Linting
|
|
352
|
+
npm run lint
|
|
353
|
+
npm run lint:fix
|
|
354
|
+
|
|
355
|
+
# Code formatting
|
|
356
|
+
npm run prettier
|
|
357
|
+
npm run prettier:fix
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### Testing
|
|
361
|
+
|
|
362
|
+
```bash
|
|
363
|
+
# Run all tests
|
|
364
|
+
npm test
|
|
365
|
+
|
|
366
|
+
# Run tests in watch mode
|
|
367
|
+
npm run test:watch
|
|
368
|
+
|
|
369
|
+
# Run with coverage report
|
|
370
|
+
npm run test:coverage
|
|
371
|
+
|
|
372
|
+
# Run specific test suites
|
|
373
|
+
npm run test:unit
|
|
374
|
+
npm run test:integration
|
|
375
|
+
npm run test:e2e
|
|
376
|
+
|
|
377
|
+
# Run tests with UI
|
|
378
|
+
npm run test:ui
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
The framework maintains **80% code coverage** across all metrics (lines, branches, functions, statements) as enforced by Vitest thresholds.
|
|
382
|
+
|
|
383
|
+
### Local Development with Yalc
|
|
384
|
+
|
|
385
|
+
For testing changes in consuming applications:
|
|
386
|
+
|
|
387
|
+
```bash
|
|
388
|
+
# Publish framework locally
|
|
389
|
+
npm run build:local
|
|
390
|
+
|
|
391
|
+
# In your consuming project
|
|
392
|
+
yalc add @scpxl/nodejs-framework
|
|
393
|
+
|
|
394
|
+
# Push updates after changes
|
|
395
|
+
npm run yalc:push
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
---
|
|
399
|
+
|
|
400
|
+
## π§ Configuration
|
|
401
|
+
|
|
402
|
+
### Environment Variables
|
|
403
|
+
|
|
404
|
+
Create a `.env` file in your project root:
|
|
405
|
+
|
|
406
|
+
```env
|
|
407
|
+
# Application
|
|
408
|
+
NODE_ENV=development
|
|
409
|
+
APP_NAME=my-app
|
|
410
|
+
APP_PORT=3000
|
|
411
|
+
|
|
412
|
+
# Database
|
|
413
|
+
DB_HOST=localhost
|
|
414
|
+
DB_PORT=5432
|
|
415
|
+
DB_USERNAME=postgres
|
|
416
|
+
DB_PASSWORD=password
|
|
417
|
+
DB_NAME=myapp
|
|
418
|
+
|
|
419
|
+
# Redis
|
|
420
|
+
REDIS_HOST=127.0.0.1
|
|
421
|
+
REDIS_PORT=6379
|
|
422
|
+
REDIS_PASSWORD=
|
|
423
|
+
|
|
424
|
+
# Logging
|
|
425
|
+
LOG_LEVEL=info
|
|
426
|
+
|
|
427
|
+
# Sentry (optional)
|
|
428
|
+
SENTRY_DSN=https://...
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### TypeScript Configuration
|
|
432
|
+
|
|
433
|
+
The framework uses **ESNext** module target with `.js` extensions in imports:
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
// β
Correct
|
|
437
|
+
import { WebApplication } from '@scpxl/nodejs-framework/application';
|
|
438
|
+
|
|
439
|
+
// β
Also correct (in framework source)
|
|
440
|
+
import { Logger } from '../logger/index.js';
|
|
441
|
+
|
|
442
|
+
// β Incorrect (in framework source)
|
|
443
|
+
import { Logger } from '../logger'; // Missing .js extension
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
## ποΈ Architecture Overview
|
|
449
|
+
|
|
450
|
+
```
|
|
451
|
+
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
452
|
+
β Application Layer β
|
|
453
|
+
β βββββββββββββββ ββββββββββββββββ βββββββββββββββββ β
|
|
454
|
+
β β Web β β Command β β Custom App β β
|
|
455
|
+
β β Application β β Application β β β β
|
|
456
|
+
β ββββββββ¬βββββββ ββββββββ¬ββββββββ βββββββββ¬ββββββββ β
|
|
457
|
+
βββββββββββΌββββββββββββββββββΌβββββββββββββββββββΌβββββββββββ
|
|
458
|
+
β β β
|
|
459
|
+
βββββββββββββββββββ΄βββββββββββββββββββ
|
|
460
|
+
β
|
|
461
|
+
βββββββββββββββββββΌβββββββββββββββββββ
|
|
462
|
+
β Base Application β
|
|
463
|
+
β ββββββββββββββββββββββββββββββββ β
|
|
464
|
+
β β Lifecycle Manager β β
|
|
465
|
+
β β - Startup phases β β
|
|
466
|
+
β β - Readiness probes β β
|
|
467
|
+
β β - Graceful shutdown β β
|
|
468
|
+
β ββββββββββββββββββββββββββββββββ β
|
|
469
|
+
ββββββββββββββββββ¬ββββββββββββββββββββ
|
|
470
|
+
β
|
|
471
|
+
βββββββββββββββββββββββΌββββββββββββββββββββββ
|
|
472
|
+
β β β
|
|
473
|
+
ββββββΌββββββ ββββββββββΌβββββββββ βββββββββΌβββββββ
|
|
474
|
+
β Redis β β Database β β Queue β
|
|
475
|
+
β Manager ββββββββ€ Manager β β Manager β
|
|
476
|
+
ββββββ¬ββββββ ββββββββββ¬βββββββββ βββββββββ¬βββββββ
|
|
477
|
+
β β β
|
|
478
|
+
ββββββΌββββββ ββββββββββΌβββββββββ βββββββββΌβββββββ
|
|
479
|
+
β Cache β β MikroORM β β BullMQ β
|
|
480
|
+
β Manager β β PostgreSQL β β Workers β
|
|
481
|
+
ββββββββββββ βββββββββββββββββββ ββββββββββββββββ
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## π― When to Use PXL Framework
|
|
487
|
+
|
|
488
|
+
### β
**Good Fit**
|
|
489
|
+
|
|
490
|
+
- Building **APIs** or **microservices** with TypeScript
|
|
491
|
+
- Need **real-time features** via WebSockets
|
|
492
|
+
- Require **background job processing** with queues
|
|
493
|
+
- Want **structured application lifecycle** with health checks
|
|
494
|
+
- Building **full-stack applications** with unified backend framework
|
|
495
|
+
- Need **production-ready** defaults with observability built-in
|
|
496
|
+
|
|
497
|
+
### β οΈ **Consider Alternatives**
|
|
498
|
+
|
|
499
|
+
- **Simple scripts** or **single-purpose utilities** - Framework may be heavier than needed
|
|
500
|
+
- **Serverless functions** - Better suited for lightweight frameworks
|
|
501
|
+
- **Non-TypeScript projects** - Framework is TypeScript-first
|
|
502
|
+
|
|
503
|
+
---
|
|
504
|
+
|
|
505
|
+
## π€ Contributing
|
|
506
|
+
|
|
507
|
+
We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for:
|
|
508
|
+
|
|
509
|
+
- Development setup instructions
|
|
510
|
+
- Code style guidelines
|
|
511
|
+
- Testing requirements
|
|
512
|
+
- Pull request process
|
|
513
|
+
|
|
514
|
+
### Quick Contribution Guide
|
|
515
|
+
|
|
516
|
+
1. Fork the repository
|
|
517
|
+
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
518
|
+
3. Make your changes with tests
|
|
519
|
+
4. Run checks: `npm run check-all` (linting, prettier, typecheck)
|
|
520
|
+
5. Ensure tests pass: `npm test`
|
|
521
|
+
6. Commit with descriptive message
|
|
522
|
+
7. Push and create a Pull Request
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
## π Troubleshooting
|
|
527
|
+
|
|
528
|
+
### Database Connection Issues
|
|
529
|
+
|
|
530
|
+
```
|
|
531
|
+
Error: Connection to database failed
|
|
532
|
+
```
|
|
533
|
+
|
|
534
|
+
**Solution**: Ensure PostgreSQL is running and credentials are correct in `.env`
|
|
535
|
+
|
|
536
|
+
```bash
|
|
537
|
+
# Check PostgreSQL status
|
|
538
|
+
docker ps | grep postgres
|
|
539
|
+
|
|
540
|
+
# Start PostgreSQL with Docker
|
|
541
|
+
docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=password postgres:16
|
|
542
|
+
```
|
|
133
543
|
|
|
134
|
-
|
|
544
|
+
### Redis Connection Errors
|
|
135
545
|
|
|
136
|
-
|
|
546
|
+
```
|
|
547
|
+
Error: Redis connection refused
|
|
548
|
+
```
|
|
137
549
|
|
|
138
|
-
|
|
550
|
+
**Solution**: Ensure Redis is running
|
|
139
551
|
|
|
140
552
|
```bash
|
|
141
|
-
|
|
142
|
-
|
|
553
|
+
# Start Redis with Docker
|
|
554
|
+
docker run -d -p 6379:6379 redis:7-alpine
|
|
555
|
+
```
|
|
556
|
+
|
|
557
|
+
### Port Already in Use
|
|
558
|
+
|
|
559
|
+
```
|
|
560
|
+
Error: listen EADDRINUSE: address already in use :::3000
|
|
143
561
|
```
|
|
144
562
|
|
|
563
|
+
**Solution**: Change the port in configuration or kill the process using the port
|
|
564
|
+
|
|
565
|
+
```bash
|
|
566
|
+
# Find process using port 3000
|
|
567
|
+
lsof -i :3000
|
|
568
|
+
|
|
569
|
+
# Kill the process
|
|
570
|
+
kill -9 <PID>
|
|
571
|
+
```
|
|
572
|
+
|
|
573
|
+
### TypeScript Module Resolution
|
|
574
|
+
|
|
575
|
+
```
|
|
576
|
+
Error: Cannot find module '../logger/index.js'
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
**Solution**: Ensure all imports in framework source code use `.js` extensions (required for ESM)
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
## π License
|
|
584
|
+
|
|
585
|
+
[ISC License](LICENSE) - Copyright (c) PXL Agency
|
|
586
|
+
|
|
587
|
+
---
|
|
588
|
+
|
|
589
|
+
## π Links
|
|
590
|
+
|
|
591
|
+
- **Documentation**: https://pxlbros.github.io/pxl-nodejs-framework/
|
|
592
|
+
- **npm Package**: https://www.npmjs.com/package/@scpxl/nodejs-framework
|
|
593
|
+
- **GitHub Repository**: https://github.com/pxlbros/pxl-nodejs-framework
|
|
594
|
+
- **Issues**: https://github.com/pxlbros/pxl-nodejs-framework/issues
|
|
595
|
+
- **Changelog**: [CHANGELOG.md](CHANGELOG.md)
|
|
596
|
+
- **TODO/Roadmap**: [TODO.md](TODO.md)
|
|
597
|
+
|
|
598
|
+
---
|
|
599
|
+
|
|
600
|
+
## π¬ Support
|
|
601
|
+
|
|
602
|
+
For questions, issues, or feature requests:
|
|
603
|
+
|
|
604
|
+
- Open an [issue on GitHub](https://github.com/pxlbros/pxl-nodejs-framework/issues)
|
|
605
|
+
- Check existing [discussions](https://github.com/pxlbros/pxl-nodejs-framework/discussions)
|
|
606
|
+
- Review [documentation](https://pxlbros.github.io/pxl-nodejs-framework/)
|
|
607
|
+
|
|
145
608
|
---
|
|
146
609
|
|
|
147
|
-
|
|
610
|
+
**Built with β€οΈ by [PXL Agency](https://pxlagency.com)**
|
|
@@ -283,7 +283,7 @@ ${formatted}`);
|
|
|
283
283
|
Logger.error({
|
|
284
284
|
error: reason instanceof Error ? reason : new Error(String(reason)),
|
|
285
285
|
message: "Unhandled Rejection",
|
|
286
|
-
meta: { promise }
|
|
286
|
+
meta: { promise: String(promise) }
|
|
287
287
|
});
|
|
288
288
|
this.initiateGracefulShutdown();
|
|
289
289
|
});
|