@xenterprises/fastify-xconfig 2.1.4 → 2.2.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.
Files changed (82) hide show
  1. package/LICENSE +100 -0
  2. package/README.md +140 -141
  3. package/examples/.env.example +17 -0
  4. package/examples/basic.js +127 -0
  5. package/index.d.ts +75 -0
  6. package/package.json +12 -5
  7. package/src/integrations/prisma.js +13 -17
  8. package/src/lifecycle/xFastifyAfter.js +4 -15
  9. package/src/middleware/bugsnag.js +7 -7
  10. package/src/middleware/cors.js +14 -15
  11. package/src/middleware/fancyErrors.js +17 -22
  12. package/src/middleware/multipart.js +4 -4
  13. package/src/middleware/rateLimit.js +4 -4
  14. package/src/middleware/underPressure.js +4 -4
  15. package/src/utils/formatBytes.js +3 -1
  16. package/src/utils/health.js +10 -36
  17. package/src/xConfig.js +21 -39
  18. package/dist/integrations/cloudinary.d.ts +0 -1
  19. package/dist/integrations/cloudinary.js +0 -25
  20. package/dist/integrations/cloudinary.js.map +0 -1
  21. package/dist/integrations/prisma.d.ts +0 -1
  22. package/dist/integrations/prisma.js +0 -13
  23. package/dist/integrations/prisma.js.map +0 -1
  24. package/dist/integrations/sendgrid.d.ts +0 -1
  25. package/dist/integrations/sendgrid.js +0 -22
  26. package/dist/integrations/sendgrid.js.map +0 -1
  27. package/dist/integrations/stripe.d.ts +0 -1
  28. package/dist/integrations/stripe.js +0 -15
  29. package/dist/integrations/stripe.js.map +0 -1
  30. package/dist/integrations/twilio.d.ts +0 -1
  31. package/dist/integrations/twilio.js +0 -17
  32. package/dist/integrations/twilio.js.map +0 -1
  33. package/dist/middleware/bugsnag.d.ts +0 -2
  34. package/dist/middleware/bugsnag.js +0 -9
  35. package/dist/middleware/bugsnag.js.map +0 -1
  36. package/dist/middleware/cors.d.ts +0 -2
  37. package/dist/middleware/cors.js +0 -11
  38. package/dist/middleware/cors.js.map +0 -1
  39. package/dist/middleware/errorHandler.d.ts +0 -2
  40. package/dist/middleware/errorHandler.js +0 -19
  41. package/dist/middleware/errorHandler.js.map +0 -1
  42. package/dist/middleware/multipart.d.ts +0 -2
  43. package/dist/middleware/multipart.js +0 -7
  44. package/dist/middleware/multipart.js.map +0 -1
  45. package/dist/middleware/rateLimit.d.ts +0 -2
  46. package/dist/middleware/rateLimit.js +0 -7
  47. package/dist/middleware/rateLimit.js.map +0 -1
  48. package/dist/middleware/underPressure.d.ts +0 -2
  49. package/dist/middleware/underPressure.js +0 -7
  50. package/dist/middleware/underPressure.js.map +0 -1
  51. package/dist/utils/colorize.d.ts +0 -4
  52. package/dist/utils/colorize.js +0 -33
  53. package/dist/utils/colorize.js.map +0 -1
  54. package/dist/utils/formatBytes.d.ts +0 -1
  55. package/dist/utils/formatBytes.js +0 -10
  56. package/dist/utils/formatBytes.js.map +0 -1
  57. package/dist/utils/randomUUID.d.ts +0 -1
  58. package/dist/utils/randomUUID.js +0 -3
  59. package/dist/utils/randomUUID.js.map +0 -1
  60. package/dist/utils/statAsync.d.ts +0 -2
  61. package/dist/utils/statAsync.js +0 -4
  62. package/dist/utils/statAsync.js.map +0 -1
  63. package/dist/xConfig.d.ts +0 -3
  64. package/dist/xConfig.js +0 -9
  65. package/dist/xConfig.js.map +0 -1
  66. package/ts-reference/integrations/cloudinary.ts +0 -26
  67. package/ts-reference/integrations/prisma.ts +0 -13
  68. package/ts-reference/integrations/sendgrid.ts +0 -27
  69. package/ts-reference/integrations/stripe.ts +0 -15
  70. package/ts-reference/integrations/twilio.ts +0 -20
  71. package/ts-reference/middleware/bugsnag.ts +0 -10
  72. package/ts-reference/middleware/cors.ts +0 -13
  73. package/ts-reference/middleware/errorHandler.ts +0 -24
  74. package/ts-reference/middleware/multipart.ts +0 -8
  75. package/ts-reference/middleware/rateLimit.ts +0 -8
  76. package/ts-reference/middleware/underPressure.ts +0 -11
  77. package/ts-reference/utils/colorize.ts +0 -45
  78. package/ts-reference/utils/formatBytes.ts +0 -8
  79. package/ts-reference/utils/randomUUID.ts +0 -3
  80. package/ts-reference/utils/statAsync.ts +0 -4
  81. package/tsconfig.json +0 -14
  82. package/xConfigReference.js +0 -119
package/LICENSE ADDED
@@ -0,0 +1,100 @@
1
+ PROPRIETARY SOFTWARE LICENSE
2
+
3
+ Copyright (c) 2024-2026 X Enterprises LLC. All Rights Reserved.
4
+
5
+ This software and associated documentation files (the "Software") are the
6
+ exclusive property of X Enterprises LLC, a Washington limited liability
7
+ company ("X Enterprises"). The Software is distributed through public
8
+ package registries (including npm) for operational convenience only; such
9
+ distribution does not grant any rights beyond those expressly stated below.
10
+
11
+ TERMS AND CONDITIONS
12
+
13
+ 1. OWNERSHIP
14
+ All rights, title, and interest in and to the Software, including all
15
+ intellectual property rights, are and shall remain the exclusive property
16
+ of X Enterprises. No rights are granted except as expressly set forth in
17
+ this License.
18
+
19
+ 2. PERMITTED USE
20
+ Subject to the restrictions in Section 3, you are permitted to download,
21
+ install, and execute the Software solely as a dependency of:
22
+
23
+ (a) software developed, owned, or operated by X Enterprises;
24
+
25
+ (b) software that X Enterprises has developed, delivered, or licensed to
26
+ a third party ("Client") under a written engagement agreement with
27
+ X Enterprises, when such use is performed by or on behalf of that
28
+ Client; or
29
+
30
+ (c) end-user access to, or consumption of, a product or service described
31
+ in (a) or (b), provided that such access does not involve
32
+ redistribution, modification, or separate use of the Software.
33
+
34
+ Permitted Use includes automated installation and execution by continuous
35
+ integration systems, container builds, hosting platforms, and similar
36
+ infrastructure, to the extent necessary to support (a), (b), or (c).
37
+
38
+ 3. RESTRICTIONS
39
+ Except as expressly permitted in Section 2, and without the prior written
40
+ consent of X Enterprises, you may not:
41
+
42
+ (a) copy, modify, adapt, translate, or create derivative works of the
43
+ Software for any purpose outside the scope of Section 2;
44
+
45
+ (b) redistribute, republish, sublicense, sell, lease, rent, or otherwise
46
+ transfer the Software, in whole or in part, whether standalone or
47
+ bundled with other software;
48
+
49
+ (c) reverse engineer, decompile, disassemble, or attempt to derive the
50
+ source code or underlying ideas, algorithms, structure, or
51
+ organization of the Software, except to the extent such activity is
52
+ expressly permitted by applicable law notwithstanding this
53
+ restriction;
54
+
55
+ (d) use the Software, in whole or in part, to develop, operate, or
56
+ provide any product or service that competes with or substitutes for
57
+ any X Enterprises product or service;
58
+
59
+ (e) remove, obscure, or alter any copyright, trademark, license, or other
60
+ proprietary notice contained in or on the Software; or
61
+
62
+ (f) use the Software in violation of any applicable law or regulation.
63
+
64
+ 4. NO WARRANTY
65
+ THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
66
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
67
+ FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL
68
+ X ENTERPRISES BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY,
69
+ WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT
70
+ OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
71
+ THE SOFTWARE.
72
+
73
+ 5. LIMITATION OF LIABILITY
74
+ IN NO EVENT SHALL X ENTERPRISES BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
75
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
76
+ TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
77
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
78
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
79
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
80
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
81
+
82
+ 6. GOVERNING LAW
83
+ This License shall be governed by and construed in accordance with the
84
+ laws of the State of Washington, United States, without regard to its
85
+ conflict of law provisions. Exclusive jurisdiction for any dispute
86
+ arising out of this License shall lie in the state or federal courts
87
+ located in King County, Washington.
88
+
89
+ 7. TERMINATION
90
+ This License is effective until terminated. Your rights under this
91
+ License will terminate automatically and without notice if you fail to
92
+ comply with any term herein. Upon termination, you must cease all use of
93
+ the Software and destroy all copies in your possession or control.
94
+ Sections 1, 3, 4, 5, 6, and 7 survive termination.
95
+
96
+ For licensing inquiries, contact: legal@x.enterprises
97
+
98
+ ---
99
+ X Enterprises LLC
100
+ Bothell, Washington, United States
package/README.md CHANGED
@@ -1,18 +1,8 @@
1
- # xConfig Plugin
1
+ # @xenterprises/fastify-xconfig
2
2
 
3
- A Fastify plugin that provides core configuration, middleware setup, and foundational services for Fastify applications.
3
+ Fastify plugin for centralized middleware orchestration, health checks, and utility decorators.
4
4
 
5
- ## Overview
6
-
7
- xConfig is a lightweight configuration and middleware orchestration plugin for Fastify. It handles:
8
-
9
- - **Middleware Setup**: CORS, rate limiting, multipart handling, error handling
10
- - **Health Checks**: Disk space monitoring and application uptime tracking
11
- - **Error Tracking**: Bugsnag integration for production error monitoring
12
- - **Prisma Integration**: Database connectivity through @prisma/client
13
- - **Back Pressure Handling**: Automatic shutdown management for overloaded servers
14
-
15
- ## Installation
5
+ ## Install
16
6
 
17
7
  ```bash
18
8
  npm install @xenterprises/fastify-xconfig
@@ -20,155 +10,164 @@ npm install @xenterprises/fastify-xconfig
20
10
 
21
11
  ## Usage
22
12
 
23
- ### Basic Configuration
24
-
25
13
  ```javascript
26
14
  import Fastify from 'fastify';
27
15
  import xConfig from '@xenterprises/fastify-xconfig';
28
16
 
29
- const fastify = Fastify();
17
+ const fastify = Fastify({ logger: true });
30
18
 
31
19
  await fastify.register(xConfig, {
32
- prisma: {}, // Prisma client configuration
33
- cors: {
34
- active: true,
35
- origin: ['http://localhost:3000'],
36
- credentials: true
37
- },
38
- rateLimit: {
39
- max: 100,
40
- timeWindow: '1 minute'
41
- },
42
- bugsnag: {
43
- apiKey: process.env.BUGSNAG_API_KEY // Optional
44
- }
20
+ prisma: { active: false },
21
+ bugsnag: { active: false },
22
+ cors: { origin: ['http://localhost:3000'], credentials: true },
23
+ rateLimit: { max: 100, timeWindow: '1 minute' },
24
+ multipart: { limits: { fileSize: 52428800 } },
25
+ underPressure: { maxEventLoopDelay: 1000 },
45
26
  });
46
27
 
47
- await fastify.listen({ port: 3000 });
48
- ```
49
-
50
- ## Configuration Options
51
-
52
- ### Core Options
53
-
54
- | Option | Type | Required | Description |
55
- |--------|------|----------|-------------|
56
- | `prisma` | Object | No | Prisma client configuration. If empty, plugin uses default connection pool. |
57
- | `professional` | Boolean | No | Enable professional mode features (default: false) |
58
- | `fancyErrors` | Boolean | No | Enable formatted error responses (default: true) |
28
+ // Utility decorators are now available:
29
+ fastify.xSlugify('Hello World'); // "hello-world"
30
+ fastify.xRandomUUID(); // "a1b2c3d4-..."
31
+ fastify.xFormatBytes(1048576); // "1 MB"
32
+ fastify.xEcho(); // "Hello from X Enterprises!"
59
33
 
60
- ### Middleware Options
61
-
62
- | Option | Type | Required | Description |
63
- |--------|------|----------|-------------|
64
- | `cors` | Object | No | CORS configuration with `active`, `origin`, and `credentials` |
65
- | `rateLimit` | Object | No | Rate limiting with `max` requests and `timeWindow` |
66
- | `multipart` | Object | No | Multipart form handling configuration |
67
- | `underPressure` | Object | No | Back pressure monitoring configuration |
68
-
69
- ### Observability Options
70
-
71
- | Option | Type | Required | Description |
72
- |--------|------|----------|-------------|
73
- | `bugsnag` | Object | No | Bugsnag error tracking with `apiKey` |
74
-
75
- ## Available Decorators
76
-
77
- After registration, the following are available on the fastify instance:
78
-
79
- ```javascript
80
- // Health check function
81
- fastify.health.check() // Returns { status, diskSpace, uptime }
82
-
83
- // Prisma client (if configured)
84
- fastify.prisma
34
+ await fastify.listen({ port: 3000 });
85
35
  ```
86
36
 
87
- ## Environment Variables
88
-
89
- The plugin reads these environment variables:
90
-
91
- ```bash
92
- # Database
93
- DATABASE_URL=postgresql://user:password@localhost:5432/dbname?sslmode=require
94
-
95
- # Server
96
- NODE_ENV=development
97
- PORT=3002
98
- FASTIFY_ADDRESS=0.0.0.0
99
-
100
- # Observability
101
- BUGSNAG_API_KEY=your-bugsnag-api-key
102
-
103
- # CORS
104
- CORS_ORIGIN=http://localhost:3000,https://example.com
105
- RATE_LIMIT_MAX=100
106
- RATE_LIMIT_TIME_WINDOW=1 minute
37
+ ## Options
38
+
39
+ | Name | Type | Default | Required | Description |
40
+ |------|------|---------|----------|-------------|
41
+ | `professional` | `boolean` | `false` | No | Disable route listing on startup |
42
+ | `fancyErrors` | `boolean` | `true` | No | Enable formatted error responses with status codes |
43
+ | `prisma` | `object` | `{}` | No | Prisma client configuration (see below) |
44
+ | `bugsnag` | `object` | `{}` | No | Bugsnag error tracking configuration (see below) |
45
+ | `cors` | `object` | `{}` | No | CORS configuration passed to @fastify/cors |
46
+ | `rateLimit` | `object` | `{}` | No | Rate limiting configuration passed to @fastify/rate-limit |
47
+ | `multipart` | `object` | `{}` | No | Multipart configuration passed to @fastify/multipart |
48
+ | `underPressure` | `object` | `{}` | No | Back-pressure configuration passed to @fastify/under-pressure |
49
+
50
+ ### `prisma` Options
51
+
52
+ | Name | Type | Default | Required | Description |
53
+ |------|------|---------|----------|-------------|
54
+ | `active` | `boolean` | `true` | No | Enable/disable Prisma integration |
55
+ | `client` | `PrismaClient` | — | Yes (if active) | Your generated PrismaClient class |
56
+ | `...rest` | `object` | — | No | Passed directly to `new PrismaClient(...)` |
57
+
58
+ ### `bugsnag` Options
59
+
60
+ | Name | Type | Default | Required | Description |
61
+ |------|------|---------|----------|-------------|
62
+ | `active` | `boolean` | `true` | No | Enable/disable Bugsnag integration |
63
+ | `apiKey` | `string` | — | Yes (if active) | Bugsnag project API key |
64
+
65
+ ### `cors` Options
66
+
67
+ | Name | Type | Default | Required | Description |
68
+ |------|------|---------|----------|-------------|
69
+ | `active` | `boolean` | `true` | No | Enable/disable CORS |
70
+ | `origin` | `string\|array` | env-based | No | Allowed origins (production reads `CORS_ORIGIN` env var) |
71
+ | `credentials` | `boolean` | `true` | No | Allow credentials |
72
+ | `methods` | `array` | `["GET","POST","PUT","DELETE","OPTIONS"]` | No | Allowed HTTP methods |
73
+ | `...rest` | `object` | — | No | Passed directly to @fastify/cors |
74
+
75
+ ### Middleware `active` Flag
76
+
77
+ All middleware options (`cors`, `rateLimit`, `multipart`, `underPressure`, `bugsnag`, `prisma`) accept `active: false` to disable the middleware entirely. When omitted, the middleware is enabled by default.
78
+
79
+ ## Decorated Properties
80
+
81
+ | Name | Type | Description |
82
+ |------|------|-------------|
83
+ | `fastify.prisma` | `PrismaClient` | Prisma client instance (only if prisma is active) |
84
+ | `fastify.xEcho()` | `function` | Returns `"Hello from X Enterprises!"` |
85
+ | `fastify.xSlugify(str)` | `function` | Converts string to URL-safe slug |
86
+ | `fastify.xRandomUUID()` | `function` | Generates a UUID v4 string |
87
+ | `fastify.xGenerateUUID()` | `function` | Alias for `xRandomUUID` |
88
+ | `fastify.xFormatBytes(bytes, decimals?)` | `function` | Formats bytes to human-readable string |
89
+
90
+ ## Routes
91
+
92
+ | Method | Path | Description |
93
+ |--------|------|-------------|
94
+ | `GET` | `/health` | Health check endpoint with system metrics |
95
+
96
+ ### Health Check Response
97
+
98
+ ```json
99
+ {
100
+ "status": "healthy",
101
+ "timestamp": "2025-01-15T12:00:00.000Z",
102
+ "uptime": 3600,
103
+ "environment": "production",
104
+ "dependencies": {
105
+ "database": "up",
106
+ "redis": "not configured"
107
+ },
108
+ "resources": {
109
+ "memory": { "rss": "50 MB", "heapTotal": "30 MB", "heapUsed": "25 MB" },
110
+ "cpu": { "loadAverage": [1.2, 0.8, 0.5], "cpus": 4 },
111
+ "disk": { "free": "100 GB", "size": "500 GB" }
112
+ },
113
+ "details": {}
114
+ }
107
115
  ```
108
116
 
109
- ## Service Separation
110
-
111
- The following services have been extracted to separate, dedicated plugins:
112
-
113
- | Service | Plugin | Package |
114
- |---------|--------|---------|
115
- | Authentication/JWKS | xAuthJWSK | @xenterprises/fastify-xauth-jwks |
116
- | Geocoding | xGeocode | @xenterprises/fastify-xgeocode |
117
- | SMS/Email | xTwilio | @xenterprises/fastify-xtwilio (separate module) |
118
- | File Storage | xStorage | @xenterprises/fastify-xstorage (separate module) |
119
- | Payment Processing | xStripe | @xenterprises/fastify-xstripe (separate module) |
120
-
121
- ## Development
122
-
123
- ### Running Tests
117
+ Returns `200` when healthy, `503` when degraded.
124
118
 
125
- ```bash
126
- npm test
127
- ```
128
-
129
- ### Starting Development Server
119
+ ## Environment Variables
130
120
 
131
- ```bash
132
- npm run dev
121
+ | Name | Required | Description |
122
+ |------|----------|-------------|
123
+ | `NODE_ENV` | No | `development` or `production` (affects error stack traces, CORS defaults) |
124
+ | `PORT` | No | Server port (default: `3000`) |
125
+ | `FASTIFY_ADDRESS` | No | Server bind address (default: `0.0.0.0`) |
126
+ | `CORS_ORIGIN` | No | Comma-separated CORS origins for production |
127
+ | `RATE_LIMIT_MAX` | No | Max requests per window (default: `100`) |
128
+ | `RATE_LIMIT_TIME_WINDOW` | No | Rate limit window (default: `1 minute`) |
129
+ | `BUGSNAG_API_KEY` | If bugsnag active | Bugsnag project API key |
130
+ | `DATABASE_URL` | If prisma active | Database connection string |
131
+
132
+ ## Error Reference
133
+
134
+ | Error | When |
135
+ |-------|------|
136
+ | `[xConfig] professional must be a boolean` | `professional` option is not a boolean |
137
+ | `[xConfig] fancyErrors must be a boolean` | `fancyErrors` option is not a boolean |
138
+ | `[xConfig] prisma.client is required - pass your PrismaClient class from your generated client` | Prisma is active but `client` not provided |
139
+ | `[xConfig] prisma.client must be a PrismaClient constructor` | `prisma.client` is not a function/class |
140
+ | `[xConfig] bugsnag.apiKey is required and must be a string` | Bugsnag is active but `apiKey` missing or not a string |
141
+
142
+ ## Fancy Error Response Format
143
+
144
+ When `fancyErrors: true` (default), unhandled errors return:
145
+
146
+ ```json
147
+ {
148
+ "status": 500,
149
+ "message": "Error description",
150
+ "stack": "..."
151
+ }
133
152
  ```
134
153
 
135
- The development server watches for file changes and auto-restarts.
154
+ The `stack` field is only included when `NODE_ENV !== "production"`.
136
155
 
137
- ### Starting Production Server
156
+ ## How It Works
138
157
 
139
- ```bash
140
- npm start
141
- ```
142
-
143
- ## Architecture
144
-
145
- ```
146
- fastify app
147
-
148
- └─→ xConfig (core middleware & config)
149
- ├─→ @fastify/cors
150
- ├─→ @fastify/rate-limit
151
- ├─→ @fastify/multipart
152
- ├─→ @fastify/under-pressure
153
- ├─→ @fastify/sensible
154
- ├─→ fastify-bugsnag (optional)
155
- └─→ Prisma client
156
- ```
158
+ xConfig is a single Fastify plugin that orchestrates registration of multiple sub-plugins in a specific order:
157
159
 
158
- ## Dependencies
160
+ 1. **Prisma** — decorates `fastify.prisma` with a connected PrismaClient and registers an `onClose` hook to disconnect on shutdown.
161
+ 2. **Middleware** — registers CORS, under-pressure monitoring, rate limiting, and multipart handling (each skippable via `active: false`).
162
+ 3. **Bugsnag** — optional error tracking that integrates with the fancy error handler.
163
+ 4. **Fancy Errors** — sets a custom `errorHandler` that normalizes error responses and optionally reports to Bugsnag.
164
+ 5. **@fastify/sensible** — adds `.httpErrors`, `.to()`, and other HTTP utilities.
165
+ 6. **Utilities** — registers `xEcho`, `xSlugify`, `xRandomUUID`, and `xFormatBytes` decorators.
166
+ 7. **Health Check** — registers `GET /health` with dependency checks (database, redis), resource monitoring (memory, CPU, disk), and environment validation.
167
+ 8. **Lifecycle** — sets up route listing on startup (unless `professional: true`) and a goodbye log on shutdown.
159
168
 
160
- - `fastify` (^5.0.0) - Web framework
161
- - `@fastify/cors` - CORS middleware
162
- - `@fastify/rate-limit` - Rate limiting
163
- - `@fastify/multipart` - Multipart form handling
164
- - `@fastify/sensible` - HTTP utilities
165
- - `@fastify/under-pressure` - Back pressure handling
166
- - `@prisma/client` - ORM for database access
167
- - `fastify-bugsnag` - Error tracking (optional)
168
- - `fastify-plugin` - Plugin wrapper
169
- - `uncrypto` - Crypto utilities
170
- - `check-disk-space` - Disk space monitoring
169
+ The plugin is wrapped with `fastify-plugin` so all decorators and routes are available in the parent scope.
171
170
 
172
171
  ## License
173
172
 
174
- ISC
173
+ UNLICENSED
@@ -0,0 +1,17 @@
1
+ # Server
2
+ PORT=3000
3
+ FASTIFY_ADDRESS=0.0.0.0
4
+ NODE_ENV=development
5
+
6
+ # CORS
7
+ CORS_ORIGIN=http://localhost:3000,http://localhost:3001
8
+
9
+ # Rate Limiting
10
+ RATE_LIMIT_MAX=100
11
+ RATE_LIMIT_TIME_WINDOW=1 minute
12
+
13
+ # Bugsnag (optional)
14
+ # BUGSNAG_API_KEY=your-bugsnag-api-key
15
+
16
+ # Database (required only if prisma.active is true)
17
+ # DATABASE_URL=postgresql://user:password@localhost:5432/mydb
@@ -0,0 +1,127 @@
1
+ /**
2
+ * fastify-x-config — Basic Example
3
+ *
4
+ * Demonstrates all features of the xConfig plugin:
5
+ * - CORS, rate limiting, multipart, under-pressure middleware
6
+ * - Fancy error handling
7
+ * - Health check endpoint
8
+ * - Utility decorators: xEcho, xSlugify, xRandomUUID, xFormatBytes
9
+ *
10
+ * Run: node examples/basic.js
11
+ * Requires: .env or environment variables (see .env.example)
12
+ */
13
+
14
+ import Fastify from "fastify";
15
+ import xConfig from "../src/xConfig.js";
16
+
17
+ const fastify = Fastify({
18
+ logger: true,
19
+ });
20
+
21
+ // ─── Register xConfig with all options ───────────────────────────────────────
22
+
23
+ await fastify.register(xConfig, {
24
+ // Disable route listing in production
25
+ professional: process.env.NODE_ENV === "production",
26
+
27
+ // Enable fancy error formatting (default: true)
28
+ fancyErrors: true,
29
+
30
+ // Prisma — disabled for this demo; pass { client: PrismaClient } to enable
31
+ prisma: { active: false },
32
+
33
+ // Bugsnag — disabled for this demo; pass { apiKey: "..." } to enable
34
+ bugsnag: { active: false },
35
+
36
+ // CORS configuration
37
+ cors: {
38
+ origin: process.env.CORS_ORIGIN
39
+ ? process.env.CORS_ORIGIN.split(",")
40
+ : ["http://localhost:3000"],
41
+ credentials: true,
42
+ },
43
+
44
+ // Rate limiting
45
+ rateLimit: {
46
+ max: parseInt(process.env.RATE_LIMIT_MAX || "100", 10),
47
+ timeWindow: process.env.RATE_LIMIT_TIME_WINDOW || "1 minute",
48
+ },
49
+
50
+ // Multipart file uploads
51
+ multipart: {
52
+ limits: {
53
+ fileSize: 52428800, // 50 MB
54
+ },
55
+ },
56
+
57
+ // Back-pressure monitoring
58
+ underPressure: {
59
+ maxEventLoopDelay: 1000,
60
+ maxHeapUsedBytes: 1_000_000_000,
61
+ maxRssBytes: 1_000_000_000,
62
+ },
63
+ });
64
+
65
+ // ─── 1. Health check (auto-registered by xConfig at /health) ─────────────────
66
+
67
+ // Try: curl http://localhost:3000/health
68
+
69
+ // ─── 2. xEcho — simple ping utility ─────────────────────────────────────────
70
+
71
+ fastify.get("/echo", async () => {
72
+ return { message: fastify.xEcho() };
73
+ });
74
+
75
+ // ─── 3. xSlugify — URL-safe slugification ───────────────────────────────────
76
+
77
+ fastify.get("/slug/:text", async (request) => {
78
+ const { text } = request.params;
79
+ return {
80
+ original: text,
81
+ slug: fastify.xSlugify(text),
82
+ };
83
+ });
84
+
85
+ // ─── 4. xRandomUUID — UUID generation ───────────────────────────────────────
86
+
87
+ fastify.get("/uuid", async () => {
88
+ return {
89
+ uuid: fastify.xRandomUUID(),
90
+ // xGenerateUUID is also available as an alias
91
+ uuid2: fastify.xGenerateUUID(),
92
+ };
93
+ });
94
+
95
+ // ─── 5. xFormatBytes — human-readable byte formatting ───────────────────────
96
+
97
+ fastify.get("/format-bytes/:bytes", async (request) => {
98
+ const bytes = parseInt(request.params.bytes, 10);
99
+ return {
100
+ bytes,
101
+ formatted: fastify.xFormatBytes(bytes),
102
+ };
103
+ });
104
+
105
+ // ─── 6. Fancy error handling demo ────────────────────────────────────────────
106
+
107
+ fastify.get("/error", async () => {
108
+ throw new Error("This demonstrates fancy error formatting");
109
+ });
110
+
111
+ fastify.get("/error/:code", async (request) => {
112
+ const err = new Error(`Custom ${request.params.code} error`);
113
+ err.statusCode = parseInt(request.params.code, 10);
114
+ throw err;
115
+ });
116
+
117
+ // ─── Start server ────────────────────────────────────────────────────────────
118
+
119
+ const port = parseInt(process.env.PORT || "3000", 10);
120
+ const address = process.env.FASTIFY_ADDRESS || "0.0.0.0";
121
+
122
+ try {
123
+ await fastify.listen({ port, host: address });
124
+ } catch (err) {
125
+ fastify.log.error(err);
126
+ process.exit(1);
127
+ }
package/index.d.ts ADDED
@@ -0,0 +1,75 @@
1
+ import { FastifyPluginAsync } from 'fastify';
2
+
3
+ declare module 'fastify' {
4
+ interface FastifyInstance {
5
+ /** Prisma client instance (only available if prisma option is active) */
6
+ prisma?: any;
7
+ /** Returns "Hello from X Enterprises!" */
8
+ xEcho(): string;
9
+ /** Converts a string to a URL-safe slug */
10
+ xSlugify(input: string | number): string;
11
+ /** Generates a UUID v4 string */
12
+ xRandomUUID(): string;
13
+ /** Generates a UUID v4 string (alias for xRandomUUID) */
14
+ xGenerateUUID(): string;
15
+ /** Formats bytes into a human-readable string (e.g. "1.5 MB") */
16
+ xFormatBytes(bytes: number, decimals?: number): string;
17
+ }
18
+ }
19
+
20
+ interface XConfigCorsOptions {
21
+ active?: boolean;
22
+ origin?: string | string[] | boolean;
23
+ credentials?: boolean;
24
+ methods?: string[];
25
+ [key: string]: any;
26
+ }
27
+
28
+ interface XConfigRateLimitOptions {
29
+ active?: boolean;
30
+ max?: number;
31
+ timeWindow?: string | number;
32
+ [key: string]: any;
33
+ }
34
+
35
+ interface XConfigMultipartOptions {
36
+ active?: boolean;
37
+ limits?: {
38
+ fileSize?: number;
39
+ [key: string]: any;
40
+ };
41
+ [key: string]: any;
42
+ }
43
+
44
+ interface XConfigUnderPressureOptions {
45
+ active?: boolean;
46
+ maxEventLoopDelay?: number;
47
+ maxHeapUsedBytes?: number;
48
+ maxRssBytes?: number;
49
+ [key: string]: any;
50
+ }
51
+
52
+ interface XConfigPrismaOptions {
53
+ active?: boolean;
54
+ client?: any;
55
+ [key: string]: any;
56
+ }
57
+
58
+ interface XConfigBugsnagOptions {
59
+ active?: boolean;
60
+ apiKey?: string;
61
+ }
62
+
63
+ interface XConfigOptions {
64
+ professional?: boolean;
65
+ fancyErrors?: boolean;
66
+ prisma?: XConfigPrismaOptions;
67
+ bugsnag?: XConfigBugsnagOptions;
68
+ cors?: XConfigCorsOptions;
69
+ rateLimit?: XConfigRateLimitOptions;
70
+ multipart?: XConfigMultipartOptions;
71
+ underPressure?: XConfigUnderPressureOptions;
72
+ }
73
+
74
+ declare const xConfig: FastifyPluginAsync<XConfigOptions>;
75
+ export default xConfig;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@xenterprises/fastify-xconfig",
3
3
  "type": "module",
4
- "version": "2.1.4",
4
+ "version": "2.2.1",
5
5
  "description": "Fastify configuration plugin for setting up middleware, services, and route handling.",
6
6
  "main": "src/xConfig.js",
7
7
  "scripts": {
@@ -10,7 +10,7 @@
10
10
  "test": "node --test test/xConfig.test.js"
11
11
  },
12
12
  "author": "Tim Mushen",
13
- "license": "ISC",
13
+ "license": "SEE LICENSE IN LICENSE",
14
14
  "repository": {
15
15
  "type": "git",
16
16
  "url": "https://gitlab.com/x-enterprises/fastify-plugins/fastify-x-config"
@@ -33,14 +33,21 @@
33
33
  "@fastify/rate-limit": "^10.0.0",
34
34
  "@fastify/sensible": "^6.0.0",
35
35
  "@fastify/under-pressure": "^9.0.0",
36
- "@prisma/client": "^7.3.0",
37
36
  "check-disk-space": "^3.4.0",
38
- "fastify": "^5.1.0",
39
37
  "fastify-bugsnag": "^5.0.0",
40
38
  "fastify-plugin": "^5.0.0",
41
39
  "uncrypto": "^0.1.3"
42
40
  },
43
41
  "peerDependencies": {
44
- "fastify": "^5.0.0"
42
+ "fastify": ">=5.0.0",
43
+ "@prisma/client": ">=5.0.0"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "@prisma/client": {
47
+ "optional": true
48
+ }
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
45
52
  }
46
53
  }