@xenterprises/fastify-xconfig 1.1.8 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +189 -0
- package/README.md +127 -135
- package/package.json +16 -24
- package/server/app.js +9 -46
- package/src/lifecycle/xFastifyAfter.js +4 -4
- package/src/middleware/cors.js +6 -1
- package/src/utils/health.js +10 -11
- package/src/xConfig.js +1 -29
- package/test/index.js +6 -6
- package/test/xConfig.test.js +278 -0
- package/xConfigReference.js +103 -1505
- package/src/auth/admin.js +0 -182
- package/src/auth/portal.js +0 -176
- package/src/integrations/cloudinary.js +0 -98
- package/src/integrations/geocode.js +0 -43
- package/src/integrations/sendgrid.js +0 -58
- package/src/integrations/twilio.js +0 -146
- package/xConfigWorkingList.js +0 -720
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
## [2.0.0] - 2025-12-28
|
|
6
|
+
|
|
7
|
+
### BREAKING CHANGES
|
|
8
|
+
|
|
9
|
+
This is a major version release with significant architectural changes.
|
|
10
|
+
|
|
11
|
+
#### Removed Services
|
|
12
|
+
|
|
13
|
+
The following services have been extracted to dedicated plugins and are **no longer** available in xConfig:
|
|
14
|
+
|
|
15
|
+
- **SendGrid Integration** - Use `@xenterprises/fastify-xsendgrid` (planned) or implement separately
|
|
16
|
+
- **Twilio Integration** - Use `@xenterprises/fastify-xtwilio` (planned) or implement separately
|
|
17
|
+
- **Cloudinary Integration** - Use `@xenterprises/fastify-xstorage` (planned) or implement separately
|
|
18
|
+
- **Stripe Integration** - Use `@xenterprises/fastify-xstripe` (planned) or implement separately
|
|
19
|
+
- **Stack Auth Integration** - Use `@xenterprises/fastify-xauth-jwks` instead
|
|
20
|
+
|
|
21
|
+
#### Configuration Changes
|
|
22
|
+
|
|
23
|
+
The following options are **no longer supported** in xConfig registration:
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
// ❌ These options are now REMOVED
|
|
27
|
+
fastify.register(xConfig, {
|
|
28
|
+
sendGrid: { ... }, // REMOVED - use separate plugin
|
|
29
|
+
twilio: { ... }, // REMOVED - use separate plugin
|
|
30
|
+
cloudinary: { ... }, // REMOVED - use separate plugin
|
|
31
|
+
stripe: { ... }, // REMOVED - use separate plugin
|
|
32
|
+
auth: { ... }, // REMOVED - use xAuthJWSK plugin
|
|
33
|
+
geocode: { ... }, // REMOVED - use xGeocode plugin
|
|
34
|
+
});
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
#### New Plugin-Based Architecture
|
|
38
|
+
|
|
39
|
+
xConfig now focuses on core middleware only. Use these dedicated plugins for removed services:
|
|
40
|
+
|
|
41
|
+
```javascript
|
|
42
|
+
import Fastify from 'fastify';
|
|
43
|
+
import xConfig from '@xenterprises/fastify-xconfig';
|
|
44
|
+
import xAuthJWSK from '@xenterprises/fastify-xauth-jwks';
|
|
45
|
+
import xGeocode from '@xenterprises/fastify-xgeocode';
|
|
46
|
+
|
|
47
|
+
const fastify = Fastify();
|
|
48
|
+
|
|
49
|
+
// Core config (middleware & database)
|
|
50
|
+
await fastify.register(xConfig, {
|
|
51
|
+
prisma: {},
|
|
52
|
+
cors: { origin: ['https://example.com'] },
|
|
53
|
+
rateLimit: { max: 100, timeWindow: '1 minute' },
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// Dedicated plugins for other services
|
|
57
|
+
await fastify.register(xAuthJWSK, { /* config */ });
|
|
58
|
+
await fastify.register(xGeocode, { /* config */ });
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Added
|
|
62
|
+
|
|
63
|
+
- ✅ Enhanced CORS security - Environment-aware origin defaults
|
|
64
|
+
- Production: Only allows configured domain
|
|
65
|
+
- Development: Allows localhost:3000 and localhost:3001
|
|
66
|
+
- ✅ Improved health check endpoint - Better environment validation
|
|
67
|
+
- ✅ Test suite - 8 comprehensive tests covering core functionality
|
|
68
|
+
- ✅ Production hardening - Security audit and best practices applied
|
|
69
|
+
|
|
70
|
+
### Changed
|
|
71
|
+
|
|
72
|
+
- **Core Focus**: xConfig now provides only essential middleware and configuration
|
|
73
|
+
- **Plugin Architecture**: Services moved to dedicated, focused plugins
|
|
74
|
+
- **Dependencies**: Reduced from 22 to 11 (50% reduction)
|
|
75
|
+
- **Bundle Size**: ~42% smaller with removed integrations
|
|
76
|
+
- **Code Quality**: Improved maintainability and single responsibility
|
|
77
|
+
|
|
78
|
+
### Fixed
|
|
79
|
+
|
|
80
|
+
- ⚠️ Prisma disconnect hook - Now properly called only once on shutdown
|
|
81
|
+
- ✅ Health endpoint - No longer fails when Prisma is disabled
|
|
82
|
+
- ✅ Lifecycle hooks - Fixed "already listening" errors in test scenarios
|
|
83
|
+
|
|
84
|
+
### Security
|
|
85
|
+
|
|
86
|
+
- **npm audit**: 0 vulnerabilities
|
|
87
|
+
- **CORS**: Secure defaults based on environment
|
|
88
|
+
- **Error Handling**: Stack traces hidden in production
|
|
89
|
+
- **Error Reporting**: Optional Bugsnag integration
|
|
90
|
+
|
|
91
|
+
### Migration Guide
|
|
92
|
+
|
|
93
|
+
#### Before (v1.x)
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
fastify.register(xConfig, {
|
|
97
|
+
sendGrid: { apiKey: '...' },
|
|
98
|
+
twilio: { accountSid: '...', authToken: '...', phoneNumber: '...' },
|
|
99
|
+
cloudinary: { cloudName: '...' },
|
|
100
|
+
auth: { admin: { ... }, user: { ... } },
|
|
101
|
+
geocode: { apiKey: '...' },
|
|
102
|
+
});
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### After (v2.0)
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
// Step 1: Core config only
|
|
109
|
+
fastify.register(xConfig, {
|
|
110
|
+
prisma: {},
|
|
111
|
+
cors: { active: true, origin: ['https://yourdomain.com'] },
|
|
112
|
+
rateLimit: { max: 100, timeWindow: '1 minute' },
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Step 2: Add service plugins
|
|
116
|
+
fastify.register(xAuthJWSK, {
|
|
117
|
+
paths: {
|
|
118
|
+
admin: { pathPattern: '/admin', jwksUrl: '...' },
|
|
119
|
+
api: { pathPattern: '/api', jwksUrl: '...' }
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
fastify.register(xGeocode, {
|
|
124
|
+
apiKey: process.env.GEOCODIO_API_KEY
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
// Step 3: Implement other services separately or wait for dedicated plugins
|
|
128
|
+
// - Email: Use SendGrid SDK directly or wait for @xenterprises/fastify-xsendgrid
|
|
129
|
+
// - SMS: Use Twilio SDK directly or wait for @xenterprises/fastify-xtwilio
|
|
130
|
+
// - Storage: Use AWS S3 SDK directly or wait for @xenterprises/fastify-xstorage
|
|
131
|
+
// - Payments: Use Stripe SDK directly or wait for @xenterprises/fastify-xstripe
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### Deprecation Notes
|
|
135
|
+
|
|
136
|
+
- The `auth` option is deprecated. Use `@xenterprises/fastify-xauth-jwks` instead
|
|
137
|
+
- The `geocode` option is deprecated. Use `@xenterprises/fastify-xgeocode` instead
|
|
138
|
+
- Stack Auth integration is deprecated. Use `@xenterprises/fastify-xauth-jwks` instead
|
|
139
|
+
|
|
140
|
+
### Environment Variables
|
|
141
|
+
|
|
142
|
+
**Removed** (no longer supported):
|
|
143
|
+
- `ADMIN_STACK_PROJECT_ID`
|
|
144
|
+
- `ADMIN_STACK_PUBLISHABLE_CLIENT_KEY`
|
|
145
|
+
- `ADMIN_STACK_SECRET_SERVER_KEY`
|
|
146
|
+
- `USER_STACK_PROJECT_ID`
|
|
147
|
+
- `USER_STACK_PUBLISHABLE_CLIENT_KEY`
|
|
148
|
+
- `USER_STACK_SECRET_SERVER_KEY`
|
|
149
|
+
- `SENDGRID_API_KEY`
|
|
150
|
+
- `SENDGRID_API_EMAIL_VALIDATION_KEY`
|
|
151
|
+
- `SENDGRID_FROM_EMAIL`
|
|
152
|
+
- `TWILIO_ACCOUNT_SID`
|
|
153
|
+
- `TWILIO_AUTH_TOKEN`
|
|
154
|
+
- `TWILIO_PHONE_NUMBER`
|
|
155
|
+
- `CLOUDINARY_CLOUD_NAME`
|
|
156
|
+
- `CLOUDINARY_API_KEY`
|
|
157
|
+
- `CLOUDINARY_API_SECRET`
|
|
158
|
+
- `CLOUDINARY_BASE_PATH`
|
|
159
|
+
- `STRIPE_API_KEY`
|
|
160
|
+
|
|
161
|
+
**Still Supported**:
|
|
162
|
+
- `DATABASE_URL` - PostgreSQL connection string (if Prisma enabled)
|
|
163
|
+
- `NODE_ENV` - Application environment
|
|
164
|
+
- `PORT` - Server port
|
|
165
|
+
- `FASTIFY_ADDRESS` - Server address
|
|
166
|
+
- `BUGSNAG_API_KEY` - Error tracking (optional)
|
|
167
|
+
- `CORS_ORIGIN` - Allowed CORS origins
|
|
168
|
+
- `RATE_LIMIT_MAX` - Rate limit threshold
|
|
169
|
+
- `RATE_LIMIT_TIME_WINDOW` - Rate limit window
|
|
170
|
+
|
|
171
|
+
### Testing
|
|
172
|
+
|
|
173
|
+
- ✅ All tests passing (8/8)
|
|
174
|
+
- ✅ npm audit clean (0 vulnerabilities)
|
|
175
|
+
- ✅ Production hardening complete
|
|
176
|
+
- ✅ Graceful shutdown verified
|
|
177
|
+
- ✅ Health endpoint validated
|
|
178
|
+
|
|
179
|
+
### Dependencies Updated
|
|
180
|
+
|
|
181
|
+
- Updated `@prisma/client` to ^7.2.0
|
|
182
|
+
- All @fastify packages verified and up-to-date
|
|
183
|
+
- Removed: @sendgrid/mail, @sendgrid/client, twilio, cloudinary, jose, stripe
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## [1.x] - Previous Versions
|
|
188
|
+
|
|
189
|
+
See git history for previous releases.
|
package/README.md
CHANGED
|
@@ -1,182 +1,174 @@
|
|
|
1
|
-
# xConfig
|
|
1
|
+
# xConfig Plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A Fastify plugin that provides core configuration, middleware setup, and foundational services for Fastify applications.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
xConfig is a lightweight configuration and middleware orchestration plugin for Fastify. It handles:
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
- Customizes route listing and applies various performance and security options.
|
|
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
|
|
15
14
|
|
|
16
|
-
##
|
|
15
|
+
## Installation
|
|
17
16
|
|
|
18
|
-
|
|
17
|
+
```bash
|
|
18
|
+
npm install @xenterprises/fastify-xconfig
|
|
19
|
+
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
## Usage
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
### Basic Configuration
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
import Fastify from 'fastify';
|
|
27
|
+
import xConfig from '@xenterprises/fastify-xconfig';
|
|
25
28
|
|
|
26
29
|
const fastify = Fastify();
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
},
|
|
35
|
-
cloudinary: {
|
|
36
|
-
cloudName: "your-cloud-name",
|
|
37
|
-
apiKey: "your-api-key",
|
|
38
|
-
apiSecret: "your-api-secret",
|
|
30
|
+
|
|
31
|
+
await fastify.register(xConfig, {
|
|
32
|
+
prisma: {}, // Prisma client configuration
|
|
33
|
+
cors: {
|
|
34
|
+
active: true,
|
|
35
|
+
origin: ['http://localhost:3000'],
|
|
36
|
+
credentials: true
|
|
39
37
|
},
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
active: true,
|
|
44
|
-
stackProjectId: "your-admin-stack-project-id",
|
|
45
|
-
publishableKey: "your-admin-stack-publishable-key",
|
|
46
|
-
secretKey: "your-admin-stack-secret-key",
|
|
47
|
-
},
|
|
48
|
-
user: {
|
|
49
|
-
active: true,
|
|
50
|
-
stackProjectId: "your-user-stack-project-id",
|
|
51
|
-
publishableKey: "your-user-stack-publishable-key",
|
|
52
|
-
secretKey: "your-user-stack-secret-key",
|
|
53
|
-
},
|
|
38
|
+
rateLimit: {
|
|
39
|
+
max: 100,
|
|
40
|
+
timeWindow: '1 minute'
|
|
54
41
|
},
|
|
55
|
-
|
|
42
|
+
bugsnag: {
|
|
43
|
+
apiKey: process.env.BUGSNAG_API_KEY // Optional
|
|
44
|
+
}
|
|
56
45
|
});
|
|
57
46
|
|
|
58
|
-
fastify.listen({ port: 3000 });
|
|
47
|
+
await fastify.listen({ port: 3000 });
|
|
59
48
|
```
|
|
60
49
|
|
|
61
|
-
##
|
|
50
|
+
## Configuration Options
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
- **sendGrid**: SendGrid configuration for email services (optional).
|
|
65
|
-
- **twilio**: Twilio configuration for SMS services (optional).
|
|
66
|
-
- **cloudinary**: Cloudinary configuration for media upload services (optional).
|
|
67
|
-
- **auth**: Authentication configuration for Admin and User with Stack Auth integration (optional).
|
|
68
|
-
- **cors**: CORS configuration (optional).
|
|
69
|
-
- **rateLimit**: Rate-limiting options (optional).
|
|
70
|
-
- **multipart**: Multipart handling options for file uploads (optional).
|
|
71
|
-
- **bugsnag**: Bugsnag error reporting configuration (optional).
|
|
72
|
-
- **underPressure**: Under Pressure plugin options for monitoring and throttling under load (optional).
|
|
52
|
+
### Core Options
|
|
73
53
|
|
|
74
|
-
|
|
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) |
|
|
75
59
|
|
|
76
|
-
|
|
60
|
+
### Middleware Options
|
|
77
61
|
|
|
78
|
-
|
|
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 |
|
|
79
68
|
|
|
80
|
-
|
|
81
|
-
- `/portal/auth/me` - Get current user information
|
|
82
|
-
- `/portal/auth/verify` - Verify a user token
|
|
69
|
+
### Observability Options
|
|
83
70
|
|
|
84
|
-
|
|
71
|
+
| Option | Type | Required | Description |
|
|
72
|
+
|--------|------|----------|-------------|
|
|
73
|
+
| `bugsnag` | Object | No | Bugsnag error tracking with `apiKey` |
|
|
85
74
|
|
|
86
|
-
|
|
87
|
-
- `/admin/auth/me` - Get current admin information
|
|
88
|
-
- `/admin/auth/verify` - Verify an admin token
|
|
75
|
+
## Available Decorators
|
|
89
76
|
|
|
90
|
-
|
|
77
|
+
After registration, the following are available on the fastify instance:
|
|
91
78
|
|
|
92
|
-
|
|
79
|
+
```javascript
|
|
80
|
+
// Health check function
|
|
81
|
+
fastify.health.check() // Returns { status, diskSpace, uptime }
|
|
93
82
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
// Prisma client (if configured)
|
|
84
|
+
fastify.prisma
|
|
85
|
+
```
|
|
97
86
|
|
|
98
|
-
|
|
87
|
+
## Environment Variables
|
|
99
88
|
|
|
100
|
-
|
|
89
|
+
The plugin reads these environment variables:
|
|
101
90
|
|
|
102
|
-
|
|
91
|
+
```bash
|
|
92
|
+
# Database
|
|
93
|
+
DATABASE_URL=postgresql://user:password@localhost:5432/dbname?sslmode=require
|
|
103
94
|
|
|
104
|
-
|
|
95
|
+
# Server
|
|
96
|
+
NODE_ENV=development
|
|
97
|
+
PORT=3002
|
|
98
|
+
FASTIFY_ADDRESS=0.0.0.0
|
|
105
99
|
|
|
106
|
-
|
|
107
|
-
-
|
|
108
|
-
- **Twilio**: Provides SMS sending and phone number validation services.
|
|
109
|
-
- **Cloudinary**: Handles file uploads to Cloudinary and deletion of media files.
|
|
110
|
-
- **Authentication**: Stack Auth integration for secure user and admin authentication.
|
|
100
|
+
# Observability
|
|
101
|
+
BUGSNAG_API_KEY=your-bugsnag-api-key
|
|
111
102
|
|
|
112
|
-
|
|
103
|
+
# CORS
|
|
104
|
+
CORS_ORIGIN=http://localhost:3000,https://example.com
|
|
105
|
+
RATE_LIMIT_MAX=100
|
|
106
|
+
RATE_LIMIT_TIME_WINDOW=1 minute
|
|
107
|
+
```
|
|
113
108
|
|
|
114
|
-
|
|
115
|
-
- **onClose**: Gracefully disconnects Prisma and other services on server shutdown.
|
|
109
|
+
## Service Separation
|
|
116
110
|
|
|
117
|
-
|
|
111
|
+
The following services have been extracted to separate, dedicated plugins:
|
|
118
112
|
|
|
119
|
-
|
|
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
120
|
|
|
121
|
-
##
|
|
121
|
+
## Development
|
|
122
122
|
|
|
123
|
-
|
|
123
|
+
### Running Tests
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
```bash
|
|
126
|
+
npm test
|
|
127
|
+
```
|
|
126
128
|
|
|
127
|
-
|
|
129
|
+
### Starting Development Server
|
|
128
130
|
|
|
129
|
-
|
|
131
|
+
```bash
|
|
132
|
+
npm run dev
|
|
133
|
+
```
|
|
130
134
|
|
|
131
|
-
|
|
135
|
+
The development server watches for file changes and auto-restarts.
|
|
132
136
|
|
|
133
|
-
###
|
|
137
|
+
### Starting Production Server
|
|
134
138
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
- `USER_STACK_PROJECT_ID` - Stack Auth project ID for user authentication
|
|
139
|
-
- `USER_STACK_PUBLISHABLE_CLIENT_KEY` - Stack Auth publishable key for user authentication
|
|
140
|
-
- `USER_STACK_SECRET_SERVER_KEY` - Stack Auth secret key for user authentication
|
|
139
|
+
```bash
|
|
140
|
+
npm start
|
|
141
|
+
```
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
## Architecture
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
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
|
+
```
|
|
148
157
|
|
|
149
|
-
##
|
|
158
|
+
## Dependencies
|
|
150
159
|
|
|
151
|
-
|
|
152
|
-
fastify
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
excludedPaths: ["/public", "/portal/auth/login", "/portal/auth/register"],
|
|
167
|
-
admin: {
|
|
168
|
-
active: true,
|
|
169
|
-
stackProjectId: "your-admin-stack-project-id",
|
|
170
|
-
publishableKey: "your-admin-stack-publishable-key",
|
|
171
|
-
secretKey: "your-admin-stack-secret-key",
|
|
172
|
-
},
|
|
173
|
-
user: {
|
|
174
|
-
active: true,
|
|
175
|
-
stackProjectId: "your-user-stack-project-id",
|
|
176
|
-
publishableKey: "your-user-stack-publishable-key",
|
|
177
|
-
secretKey: "your-user-stack-secret-key",
|
|
178
|
-
},
|
|
179
|
-
},
|
|
180
|
-
cors: { origin: ["https://your-frontend.com"], credentials: true },
|
|
181
|
-
});
|
|
182
|
-
```
|
|
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
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
ISC
|
package/package.json
CHANGED
|
@@ -1,46 +1,38 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenterprises/fastify-xconfig",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "2.0.1",
|
|
5
5
|
"description": "Fastify configuration plugin for setting up middleware, services, and route handling.",
|
|
6
6
|
"main": "src/xConfig.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"start": "fastify start -l info server/app.js",
|
|
9
9
|
"dev": "fastify start -w -l info -P server/app.js",
|
|
10
|
-
"test": "node --test test
|
|
10
|
+
"test": "node --test test/xConfig.test.js"
|
|
11
11
|
},
|
|
12
12
|
"author": "Tim Mushen",
|
|
13
13
|
"license": "ISC",
|
|
14
14
|
"devDependencies": {
|
|
15
15
|
"@types/node": "^22.7.4",
|
|
16
16
|
"c8": "^9.0.0",
|
|
17
|
-
"fastify": "^
|
|
18
|
-
"fastify-plugin": "^
|
|
17
|
+
"fastify": "^5.1.0",
|
|
18
|
+
"fastify-plugin": "^5.0.0",
|
|
19
19
|
"fastify-tsconfig": "^2.0.0",
|
|
20
20
|
"typescript": "^5.6.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@fastify/
|
|
24
|
-
"@fastify/
|
|
25
|
-
"@fastify/
|
|
26
|
-
"@fastify/
|
|
27
|
-
"@fastify/
|
|
28
|
-
"@
|
|
29
|
-
"@prisma/client": "^6.8.2",
|
|
30
|
-
"@sendgrid/client": "^8.1.3",
|
|
31
|
-
"@sendgrid/mail": "^8.1.3",
|
|
23
|
+
"@fastify/cors": "^10.0.0",
|
|
24
|
+
"@fastify/multipart": "^9.0.0",
|
|
25
|
+
"@fastify/rate-limit": "^10.0.0",
|
|
26
|
+
"@fastify/sensible": "^6.0.0",
|
|
27
|
+
"@fastify/under-pressure": "^9.0.0",
|
|
28
|
+
"@prisma/client": "^7.2.0",
|
|
32
29
|
"check-disk-space": "^3.4.0",
|
|
33
|
-
"fastify": "^
|
|
34
|
-
"fastify-bugsnag": "^
|
|
35
|
-
"fastify-
|
|
36
|
-
"fastify-cloudinary": "^2.0.0",
|
|
37
|
-
"fastify-list-routes": "^1.0.0",
|
|
38
|
-
"fastify-multipart": "^5.4.0",
|
|
39
|
-
"fastify-plugin": "^4.0.0",
|
|
40
|
-
"fastify-rate-limit": "^5.9.0",
|
|
41
|
-
"jose": "^6.0.11",
|
|
42
|
-
"stripe": "^16.12.0",
|
|
43
|
-
"twilio": "^5.3.2",
|
|
30
|
+
"fastify": "^5.1.0",
|
|
31
|
+
"fastify-bugsnag": "^5.0.0",
|
|
32
|
+
"fastify-plugin": "^5.0.0",
|
|
44
33
|
"uncrypto": "^0.1.3"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"fastify": "^5.0.0"
|
|
45
37
|
}
|
|
46
38
|
}
|
package/server/app.js
CHANGED
|
@@ -19,57 +19,20 @@ export default async function (fastify, opts) {
|
|
|
19
19
|
max: process.env.RATE_LIMIT_MAX || 100,
|
|
20
20
|
timeWindow: process.env.RATE_LIMIT_TIME_WINDOW || '1 minute'
|
|
21
21
|
},
|
|
22
|
-
stripe: {
|
|
23
|
-
active: false,
|
|
24
|
-
apiKey: process.env.STRIPE_API_KEY
|
|
25
|
-
},
|
|
26
|
-
sendGrid: {
|
|
27
|
-
active: true,
|
|
28
|
-
apiKey: process.env.SENDGRID_API_KEY,
|
|
29
|
-
apiKeyEmailValidation: process.env.SENDGRID_API_EMAIL_VALIDATION_KEY,
|
|
30
|
-
fromEmail: process.env.SENDGRID_FROM_EMAIL || 'ops@getx.io',
|
|
31
|
-
},
|
|
32
|
-
twilio: {
|
|
33
|
-
active: true,
|
|
34
|
-
accountSid: process.env.TWILIO_ACCOUNT_SID,
|
|
35
|
-
authToken: process.env.TWILIO_AUTH_TOKEN,
|
|
36
|
-
phoneNumber: process.env.TWILIO_PHONE_NUMBER
|
|
37
|
-
},
|
|
38
|
-
cloudinary: {
|
|
39
|
-
active: false,
|
|
40
|
-
cloudName: process.env.CLOUDINARY_CLOUD_NAME,
|
|
41
|
-
apiKey: process.env.CLOUDINARY_API_KEY,
|
|
42
|
-
apiSecret: process.env.CLOUDINARY_API_SECRET,
|
|
43
|
-
basePath: process.env.CLOUDINARY_BASE_PATH || 'basepath'
|
|
44
|
-
},
|
|
45
22
|
cors: {
|
|
46
23
|
active: true,
|
|
47
|
-
origin: process.env.CORS_ORIGIN || ['http://localhost:3000'
|
|
24
|
+
origin: process.env.CORS_ORIGIN || ['http://localhost:3000'],
|
|
48
25
|
credentials: true
|
|
49
26
|
},
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
stackProjectId: process.env.ADMIN_STACK_PROJECT_ID,
|
|
55
|
-
publishableKey: process.env.ADMIN_STACK_PUBLISHABLE_CLIENT_KEY,
|
|
56
|
-
secretKey: process.env.ADMIN_STACK_SECRET_SERVER_KEY,
|
|
57
|
-
},
|
|
58
|
-
user: {
|
|
59
|
-
active: true,
|
|
60
|
-
portalStackProjectId: process.env.STACK_PROJECT_ID,
|
|
61
|
-
me: {
|
|
62
|
-
isOnboarded: true
|
|
63
|
-
},
|
|
64
|
-
registerEmail: {
|
|
65
|
-
subject: 'Welcome to Bandmate!',
|
|
66
|
-
templateId: ''
|
|
67
|
-
}
|
|
68
|
-
},
|
|
27
|
+
multipart: {
|
|
28
|
+
limits: {
|
|
29
|
+
fileSize: 52428800 // 50MB
|
|
30
|
+
}
|
|
69
31
|
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
32
|
+
underPressure: {
|
|
33
|
+
maxEventLoopDelay: 1000,
|
|
34
|
+
maxHeapUsedBytes: 1000000000,
|
|
35
|
+
maxRssBytes: 1000000000
|
|
73
36
|
}
|
|
74
37
|
}); // Register the default export, which should be a function
|
|
75
38
|
fastify.get('/', async (request, reply) => {
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
// src/lifecycle/xFastifyAfter.js
|
|
2
2
|
import { printRoutes } from "../utils/colorize.js";
|
|
3
3
|
export async function xFastifyAfter(fastify, options) {
|
|
4
|
+
// Add the goodbye emoji hook before listening
|
|
5
|
+
fastify.addHook("onClose", () => {
|
|
6
|
+
console.info("Server shutting down... Goodbye 👋");
|
|
7
|
+
});
|
|
4
8
|
|
|
5
9
|
/*
|
|
6
10
|
===== LIST ROUTES AFTER ALL PLUGINS =====
|
|
@@ -15,10 +19,6 @@ export async function xFastifyAfter(fastify, options) {
|
|
|
15
19
|
console.info(
|
|
16
20
|
`🚀 Server is ready on port ${process.env.PORT || 3000}\n\n`
|
|
17
21
|
);
|
|
18
|
-
// Add goodbye emoji for server shutting down
|
|
19
|
-
fastify.addHook("onClose", () =>
|
|
20
|
-
console.info("Server shutting down... Goodbye 👋")
|
|
21
|
-
);
|
|
22
22
|
});
|
|
23
23
|
}
|
|
24
24
|
});
|
package/src/middleware/cors.js
CHANGED
|
@@ -3,8 +3,13 @@ export async function setupCors(fastify, options) {
|
|
|
3
3
|
// Extract active flag and pass all other options directly to the CORS plugin
|
|
4
4
|
const { active, ...corsOptions } = options;
|
|
5
5
|
|
|
6
|
+
// Set default origins based on environment for security
|
|
7
|
+
const defaultOrigins = process.env.NODE_ENV === 'production'
|
|
8
|
+
? ["https://getx.io"] // Production: only allow production domain
|
|
9
|
+
: ["http://localhost:3000", "http://localhost:3001"]; // Development: allow localhost
|
|
10
|
+
|
|
6
11
|
await fastify.register(await import("@fastify/cors"), {
|
|
7
|
-
origin: corsOptions.origin ||
|
|
12
|
+
origin: corsOptions.origin || defaultOrigins,
|
|
8
13
|
credentials: corsOptions.credentials !== undefined ? corsOptions.credentials : true,
|
|
9
14
|
methods: corsOptions.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
10
15
|
...corsOptions // This will include ignorePaths: ['/public'] in the preflight config
|