@xenterprises/fastify-xconfig 0.0.1 → 0.0.2
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/README.md +145 -0
- package/dist/integrations/cloudinary.d.ts +1 -0
- package/dist/integrations/cloudinary.js +25 -0
- package/dist/integrations/cloudinary.js.map +1 -0
- package/dist/integrations/prisma.d.ts +1 -0
- package/dist/integrations/prisma.js +13 -0
- package/dist/integrations/prisma.js.map +1 -0
- package/dist/integrations/sendgrid.d.ts +1 -0
- package/dist/integrations/sendgrid.js +22 -0
- package/dist/integrations/sendgrid.js.map +1 -0
- package/dist/integrations/stripe.d.ts +1 -0
- package/dist/integrations/stripe.js +15 -0
- package/dist/integrations/stripe.js.map +1 -0
- package/dist/integrations/twilio.d.ts +1 -0
- package/dist/integrations/twilio.js +17 -0
- package/dist/integrations/twilio.js.map +1 -0
- package/dist/middleware/bugsnag.d.ts +2 -0
- package/dist/middleware/bugsnag.js +9 -0
- package/dist/middleware/bugsnag.js.map +1 -0
- package/dist/middleware/cors.d.ts +2 -0
- package/dist/middleware/cors.js +11 -0
- package/dist/middleware/cors.js.map +1 -0
- package/dist/middleware/errorHandler.d.ts +2 -0
- package/dist/middleware/errorHandler.js +19 -0
- package/dist/middleware/errorHandler.js.map +1 -0
- package/dist/middleware/multipart.d.ts +2 -0
- package/dist/middleware/multipart.js +7 -0
- package/dist/middleware/multipart.js.map +1 -0
- package/dist/middleware/rateLimit.d.ts +2 -0
- package/dist/middleware/rateLimit.js +7 -0
- package/dist/middleware/rateLimit.js.map +1 -0
- package/dist/middleware/underPressure.d.ts +2 -0
- package/dist/middleware/underPressure.js +7 -0
- package/dist/middleware/underPressure.js.map +1 -0
- package/dist/utils/colorize.d.ts +4 -0
- package/dist/utils/colorize.js +33 -0
- package/dist/utils/colorize.js.map +1 -0
- package/dist/utils/formatBytes.d.ts +1 -0
- package/dist/utils/formatBytes.js +10 -0
- package/dist/utils/formatBytes.js.map +1 -0
- package/dist/utils/randomUUID.d.ts +1 -0
- package/dist/utils/randomUUID.js +3 -0
- package/dist/utils/randomUUID.js.map +1 -0
- package/dist/utils/statAsync.d.ts +2 -0
- package/dist/utils/statAsync.js +4 -0
- package/dist/utils/statAsync.js.map +1 -0
- package/dist/xConfig.d.ts +3 -0
- package/dist/xConfig.js +9 -0
- package/dist/xConfig.js.map +1 -0
- package/package.json +25 -2
- package/server/app.js +78 -1
- package/src/auth/admin.js +241 -0
- package/src/auth/portal.js +280 -0
- package/src/integrations/cloudinary.js +98 -0
- package/src/integrations/geocode.js +43 -0
- package/src/integrations/prisma.js +30 -0
- package/src/integrations/sendgrid.js +57 -0
- package/src/integrations/twilio.js +146 -0
- package/src/lifecycle/xFastifyAfter.js +27 -0
- package/src/middleware/bugsnag.js +10 -0
- package/src/middleware/cors.js +10 -0
- package/src/middleware/fancyErrors.js +26 -0
- package/src/middleware/multipart.js +6 -0
- package/src/middleware/rateLimit.js +6 -0
- package/src/middleware/underPressure.js +6 -0
- package/src/utils/colorize.js +37 -0
- package/src/utils/cookie.js +5 -0
- package/src/utils/formatBytes.js +16 -0
- package/src/utils/health.js +126 -0
- package/src/utils/xEcho.js +12 -0
- package/src/utils/xSlugify.js +20 -0
- package/src/utils/xUUID.js +14 -0
- package/src/xConfig.js +110 -3
- package/ts-reference/integrations/cloudinary.ts +26 -0
- package/ts-reference/integrations/prisma.ts +13 -0
- package/ts-reference/integrations/sendgrid.ts +27 -0
- package/ts-reference/integrations/stripe.ts +15 -0
- package/ts-reference/integrations/twilio.ts +20 -0
- package/ts-reference/middleware/bugsnag.ts +10 -0
- package/ts-reference/middleware/cors.ts +13 -0
- package/ts-reference/middleware/errorHandler.ts +24 -0
- package/ts-reference/middleware/multipart.ts +8 -0
- package/ts-reference/middleware/rateLimit.ts +8 -0
- package/ts-reference/middleware/underPressure.ts +11 -0
- package/ts-reference/utils/colorize.ts +45 -0
- package/ts-reference/utils/formatBytes.ts +8 -0
- package/ts-reference/utils/randomUUID.ts +3 -0
- package/ts-reference/utils/statAsync.ts +4 -0
- package/xConfigReference.js +1495 -0
- package/xConfigWorkingList.js +720 -0
- package/tsconfig.json +0 -16
package/README.md
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# xConfig - Fastify Configuration Plugin
|
|
2
|
+
|
|
3
|
+
**xConfig** is a Fastify configuration plugin designed for setting up middleware, services, and route handling.
|
|
4
|
+
|
|
5
|
+
This plugin provides a comprehensive setup for configuring various services such as Prisma, SendGrid, Twilio, Cloudinary, CORS, rate limiting, authentication, and more within a Fastify instance. It centralizes configuration, allowing for easy customization and scaling.
|
|
6
|
+
|
|
7
|
+
## Key Features
|
|
8
|
+
|
|
9
|
+
- Handles CORS, rate-limiting, multipart handling, and error handling out of the box.
|
|
10
|
+
- Integrates with third-party services such as SendGrid, Twilio, Cloudinary, Stripe, and Bugsnag.
|
|
11
|
+
- Provides authentication setup for both Admin and User, with JWT-based token handling.
|
|
12
|
+
- Includes Prisma database connection and gracefully handles disconnecting on server shutdown.
|
|
13
|
+
- Adds health check routes and resource usage monitoring, with environment validation.
|
|
14
|
+
- Customizes route listing and applies various performance and security options.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
This plugin should be registered in your Fastify instance with custom options provided for each service. It ensures proper initialization of services like SendGrid, Twilio, and Prisma.
|
|
19
|
+
|
|
20
|
+
### Example
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import Fastify from "fastify";
|
|
24
|
+
import xConfig from "./path/to/xConfig";
|
|
25
|
+
|
|
26
|
+
const fastify = Fastify();
|
|
27
|
+
fastify.register(xConfig, {
|
|
28
|
+
prisma: { active: true },
|
|
29
|
+
sendGrid: { apiKey: "your-sendgrid-api-key" },
|
|
30
|
+
twilio: {
|
|
31
|
+
accountSid: "your-account-sid",
|
|
32
|
+
authToken: "your-auth-token",
|
|
33
|
+
phoneNumber: "your-twilio-number",
|
|
34
|
+
},
|
|
35
|
+
cloudinary: {
|
|
36
|
+
cloudName: "your-cloud-name",
|
|
37
|
+
apiKey: "your-api-key",
|
|
38
|
+
apiSecret: "your-api-secret",
|
|
39
|
+
},
|
|
40
|
+
auth: {
|
|
41
|
+
admin: { secret: "admin-jwt-secret", expiresIn: "1h" },
|
|
42
|
+
user: { secret: "user-jwt-secret", expiresIn: "1h" },
|
|
43
|
+
},
|
|
44
|
+
cors: { origin: ["https://your-frontend.com"], credentials: true },
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
fastify.listen({ port: 3000 });
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Parameters
|
|
51
|
+
|
|
52
|
+
- **prisma**: Prisma Client configuration (optional).
|
|
53
|
+
- **sendGrid**: SendGrid configuration for email services (optional).
|
|
54
|
+
- **twilio**: Twilio configuration for SMS services (optional).
|
|
55
|
+
- **cloudinary**: Cloudinary configuration for media upload services (optional).
|
|
56
|
+
- **auth**: Authentication configuration for Admin and User JWT tokens (optional).
|
|
57
|
+
- **cors**: CORS configuration (optional).
|
|
58
|
+
- **rateLimit**: Rate-limiting options (optional).
|
|
59
|
+
- **multipart**: Multipart handling options for file uploads (optional).
|
|
60
|
+
- **bugsnag**: Bugsnag error reporting configuration (optional).
|
|
61
|
+
- **underPressure**: Under Pressure plugin options for monitoring and throttling under load (optional).
|
|
62
|
+
|
|
63
|
+
## Authentication
|
|
64
|
+
|
|
65
|
+
The plugin provides both Admin and User authentication with JWT support. It sets secure cookies, manages token refresh, and validates tokens on protected routes.
|
|
66
|
+
|
|
67
|
+
- `/admin/auth/login` for admin login.
|
|
68
|
+
- `/portal/auth/login` for user login.
|
|
69
|
+
- `/admin/auth/me` to check authentication status for admins.
|
|
70
|
+
- `/portal/auth/me` to check authentication status for users.
|
|
71
|
+
|
|
72
|
+
## Health Check
|
|
73
|
+
|
|
74
|
+
The `/health` route provides a health check with details about uptime, memory usage, CPU load, database and Redis status, and environment variable validation.
|
|
75
|
+
|
|
76
|
+
## Services
|
|
77
|
+
|
|
78
|
+
- **Prisma**: Initializes Prisma Client and decorates the Fastify instance for database queries.
|
|
79
|
+
- **SendGrid**: Provides an email sending service through SendGrid, integrated with the Fastify instance.
|
|
80
|
+
- **Twilio**: Provides SMS sending and phone number validation services.
|
|
81
|
+
- **Cloudinary**: Handles file uploads to Cloudinary and deletion of media files.
|
|
82
|
+
- **Authentication**: JWT-based authentication for Admin and User with token-based sessions.
|
|
83
|
+
|
|
84
|
+
## Hooks
|
|
85
|
+
|
|
86
|
+
- **onRequest**: Validates JWT tokens for protected routes.
|
|
87
|
+
- **onClose**: Gracefully disconnects Prisma and other services on server shutdown.
|
|
88
|
+
|
|
89
|
+
## Error Handling
|
|
90
|
+
|
|
91
|
+
Enhanced error handling is enabled by default, showing detailed error messages during development. Bugsnag integration is optional for real-time error reporting.
|
|
92
|
+
|
|
93
|
+
## Route Listing
|
|
94
|
+
|
|
95
|
+
The plugin prints all routes after registration, color-coded by HTTP method, unless disabled.
|
|
96
|
+
|
|
97
|
+
## Dependencies
|
|
98
|
+
|
|
99
|
+
The following dependencies are used for various services and integrations:
|
|
100
|
+
|
|
101
|
+
- Prisma Client, SendGrid, Twilio, Cloudinary, Fastify CORS, Fastify Rate Limit, Fastify Multipart, Fastify Under Pressure, and Fastify Bugsnag.
|
|
102
|
+
|
|
103
|
+
## Notes
|
|
104
|
+
|
|
105
|
+
- Environment variables such as `DATABASE_URL`, `ADMIN_JWT_SECRET`, and `USER_JWT_SECRET` are expected to be set.
|
|
106
|
+
- Services like SendGrid, Twilio, and Cloudinary require API keys to be passed via the options.
|
|
107
|
+
- This plugin is highly customizable, with options to enable/disable each feature.
|
|
108
|
+
|
|
109
|
+
## Example Configuration
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
fastify.register(xConfig, {
|
|
113
|
+
prisma: { active: true },
|
|
114
|
+
sendGrid: { apiKey: "SG.your_api_key" },
|
|
115
|
+
twilio: {
|
|
116
|
+
accountSid: "ACxxxxxxxxxxxxxxxx",
|
|
117
|
+
authToken: "your_auth_token",
|
|
118
|
+
phoneNumber: "+1234567890",
|
|
119
|
+
},
|
|
120
|
+
cloudinary: {
|
|
121
|
+
cloudName: "your-cloud-name",
|
|
122
|
+
apiKey: "your-api-key",
|
|
123
|
+
apiSecret: "your-api-secret",
|
|
124
|
+
},
|
|
125
|
+
auth: {
|
|
126
|
+
admin: {
|
|
127
|
+
secret: "admin-secret",
|
|
128
|
+
expiresIn: "1h",
|
|
129
|
+
cookieOptions: {
|
|
130
|
+
name: "adminCookie",
|
|
131
|
+
refreshTokenName: "adminRefreshToken",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
user: {
|
|
135
|
+
secret: "user-secret",
|
|
136
|
+
expiresIn: "1h",
|
|
137
|
+
cookieOptions: {
|
|
138
|
+
name: "userCookie",
|
|
139
|
+
refreshTokenName: "userRefreshToken",
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
cors: { origin: ["https://your-frontend.com"], credentials: true },
|
|
144
|
+
});
|
|
145
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupCloudinary(fastify: any, cloudinaryOptions: any): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { v2 as Cloudinary } from "cloudinary";
|
|
2
|
+
export async function setupCloudinary(fastify, cloudinaryOptions) {
|
|
3
|
+
if (cloudinaryOptions.active !== false) {
|
|
4
|
+
Cloudinary.config({
|
|
5
|
+
cloud_name: cloudinaryOptions.cloudName,
|
|
6
|
+
api_key: cloudinaryOptions.apiKey,
|
|
7
|
+
api_secret: cloudinaryOptions.apiSecret,
|
|
8
|
+
});
|
|
9
|
+
fastify.decorate("cloudinary", {
|
|
10
|
+
async upload(fileStream, options = {}) {
|
|
11
|
+
return new Promise((resolve, reject) => {
|
|
12
|
+
const uploadStream = Cloudinary.uploader.upload_stream(options, (error, result) => {
|
|
13
|
+
if (error)
|
|
14
|
+
reject(error);
|
|
15
|
+
else
|
|
16
|
+
resolve(result);
|
|
17
|
+
});
|
|
18
|
+
fileStream.pipe(uploadStream);
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
console.info(" ✅ Cloudinary Enabled");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=cloudinary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cloudinary.js","sourceRoot":"","sources":["../../src/integrations/cloudinary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,IAAI,UAAU,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAY,EAAE,iBAAsB;IACxE,IAAI,iBAAiB,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACvC,UAAU,CAAC,MAAM,CAAC;YAChB,UAAU,EAAE,iBAAiB,CAAC,SAAS;YACvC,OAAO,EAAE,iBAAiB,CAAC,MAAM;YACjC,UAAU,EAAE,iBAAiB,CAAC,SAAS;SACxC,CAAC,CAAC;QACH,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE;YAC7B,KAAK,CAAC,MAAM,CAAC,UAAe,EAAE,OAAO,GAAG,EAAE;gBACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;oBACrC,MAAM,YAAY,GAAG,UAAU,CAAC,QAAQ,CAAC,aAAa,CACpD,OAAO,EACP,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;wBAChB,IAAI,KAAK;4BAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;4BACpB,OAAO,CAAC,MAAM,CAAC,CAAC;oBACvB,CAAC,CACF,CAAC;oBACF,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;gBAChC,CAAC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupPrisma(fastify: any, prismaOptions: any): Promise<void>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PrismaClient } from "@prisma/client";
|
|
2
|
+
export async function setupPrisma(fastify, prismaOptions) {
|
|
3
|
+
if (prismaOptions.active !== false) {
|
|
4
|
+
const prisma = new PrismaClient(prismaOptions);
|
|
5
|
+
await prisma.$connect();
|
|
6
|
+
fastify.decorate("prisma", prisma);
|
|
7
|
+
fastify.addHook("onClose", async () => {
|
|
8
|
+
await fastify.prisma.$disconnect();
|
|
9
|
+
});
|
|
10
|
+
console.info(" ✅ Prisma Enabled");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=prisma.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prisma.js","sourceRoot":"","sources":["../../src/integrations/prisma.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAY,EAAE,aAAkB;IAChE,IAAI,aAAa,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,aAAa,CAAC,CAAC;QAC/C,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACnC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,EAAE;YACpC,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACrC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupSendGrid(fastify: any, sendGridOptions: any): Promise<void>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import Sendgrid from "@sendgrid/mail";
|
|
2
|
+
export async function setupSendGrid(fastify, sendGridOptions) {
|
|
3
|
+
if (sendGridOptions.active !== false) {
|
|
4
|
+
if (!sendGridOptions.apiKey)
|
|
5
|
+
throw new Error("SendGrid API key must be provided.");
|
|
6
|
+
Sendgrid.setApiKey(sendGridOptions.apiKey);
|
|
7
|
+
fastify.decorate("sendgrid", {
|
|
8
|
+
async sendEmail(to, subject, templateId, dynamicTemplateData) {
|
|
9
|
+
const msg = {
|
|
10
|
+
to,
|
|
11
|
+
from: sendGridOptions.fromEmail,
|
|
12
|
+
subject,
|
|
13
|
+
templateId,
|
|
14
|
+
dynamicTemplateData,
|
|
15
|
+
};
|
|
16
|
+
await Sendgrid.send(msg);
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
console.info(" ✅ SendGrid Enabled");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=sendgrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendgrid.js","sourceRoot":"","sources":["../../src/integrations/sendgrid.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAY,EAAE,eAAoB;IACpE,IAAI,eAAe,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACrC,IAAI,CAAC,eAAe,CAAC,MAAM;YACzB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,QAAQ,CAAC,SAAS,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;QAC3C,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE;YAC3B,KAAK,CAAC,SAAS,CACb,EAAU,EACV,OAAe,EACf,UAAkB,EAClB,mBAAwB;gBAExB,MAAM,GAAG,GAAG;oBACV,EAAE;oBACF,IAAI,EAAE,eAAe,CAAC,SAAS;oBAC/B,OAAO;oBACP,UAAU;oBACV,mBAAmB;iBACpB,CAAC;gBACF,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACxC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupStripe(fastify: any, stripeOptions: any): Promise<void>;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Stripe from "stripe";
|
|
2
|
+
export async function setupStripe(fastify, stripeOptions) {
|
|
3
|
+
if (stripeOptions.active !== false) {
|
|
4
|
+
const stripeClient = new Stripe(stripeOptions.apiKey, {
|
|
5
|
+
apiVersion: "2024-06-20",
|
|
6
|
+
});
|
|
7
|
+
fastify.decorate("stripe", {
|
|
8
|
+
async createPaymentIntent(amount, currency = "usd") {
|
|
9
|
+
return await stripeClient.paymentIntents.create({ amount, currency });
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
console.info(" ✅ Stripe Enabled");
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=stripe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stripe.js","sourceRoot":"","sources":["../../src/integrations/stripe.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAY,EAAE,aAAkB;IAChE,IAAI,aAAa,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE;YACpD,UAAU,EAAE,YAAY;SACzB,CAAC,CAAC;QACH,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE;YACzB,KAAK,CAAC,mBAAmB,CAAC,MAAc,EAAE,QAAQ,GAAG,KAAK;gBACxD,OAAO,MAAM,YAAY,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;YACxE,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function setupTwilio(fastify: any, twilioOptions: any): Promise<void>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import Twilio from "twilio";
|
|
2
|
+
export async function setupTwilio(fastify, twilioOptions) {
|
|
3
|
+
if (twilioOptions.active !== false) {
|
|
4
|
+
const twilioClient = Twilio(twilioOptions.accountSid, twilioOptions.authToken);
|
|
5
|
+
fastify.decorate("twilio", {
|
|
6
|
+
async sendSMS(to, body) {
|
|
7
|
+
return await twilioClient.messages.create({
|
|
8
|
+
body,
|
|
9
|
+
to,
|
|
10
|
+
from: twilioOptions.phoneNumber,
|
|
11
|
+
});
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
console.info(" ✅ Twilio Enabled");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=twilio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"twilio.js","sourceRoot":"","sources":["../../src/integrations/twilio.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAY,EAAE,aAAkB;IAChE,IAAI,aAAa,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QACnC,MAAM,YAAY,GAAG,MAAM,CACzB,aAAa,CAAC,UAAU,EACxB,aAAa,CAAC,SAAS,CACxB,CAAC;QACF,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE;YACzB,KAAK,CAAC,OAAO,CAAC,EAAU,EAAE,IAAY;gBACpC,OAAO,MAAM,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC;oBACxC,IAAI;oBACJ,EAAE;oBACF,IAAI,EAAE,aAAa,CAAC,WAAW;iBAChC,CAAC,CAAC;YACL,CAAC;SACF,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export async function setupBugsnag(fastify, options) {
|
|
2
|
+
if (options.active !== false && options.apiKey) {
|
|
3
|
+
await fastify.register(import("fastify-bugsnag"), {
|
|
4
|
+
apiKey: options.apiKey,
|
|
5
|
+
});
|
|
6
|
+
console.info(" ✅ Bugsnag Enabled");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=bugsnag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bugsnag.js","sourceRoot":"","sources":["../../src/middleware/bugsnag.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAwB,EAAE,OAAY;IACvE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC/C,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,iBAAiB,CAAC,EAAE;YAChD,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACvC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export async function setupCors(fastify, options) {
|
|
2
|
+
if (options.active !== false) {
|
|
3
|
+
await fastify.register(import("@fastify/cors"), {
|
|
4
|
+
origin: options.origin || ["https://getx.io", "http://localhost:3000"],
|
|
5
|
+
credentials: options.credentials !== undefined ? options.credentials : true,
|
|
6
|
+
methods: options.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
|
|
7
|
+
});
|
|
8
|
+
console.info(" ✅ CORS Enabled");
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=cors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../src/middleware/cors.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAwB,EAAE,OAAY;IACpE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE;YAC9C,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,CAAC,iBAAiB,EAAE,uBAAuB,CAAC;YACtE,WAAW,EACT,OAAO,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YAChE,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC;SACxE,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IACpC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export async function setupErrorHandler(fastify, fancyErrors) {
|
|
2
|
+
if (fancyErrors !== false) {
|
|
3
|
+
fastify.setErrorHandler((error, request, reply) => {
|
|
4
|
+
const statusCode = error.statusCode || 500;
|
|
5
|
+
const response = {
|
|
6
|
+
status: statusCode,
|
|
7
|
+
message: error.message || "Internal Server Error",
|
|
8
|
+
stack: process.env.NODE_ENV === "development" ? error.stack : undefined,
|
|
9
|
+
};
|
|
10
|
+
// Optional Bugsnag error reporting
|
|
11
|
+
if (fastify.bugsnag)
|
|
12
|
+
fastify.bugsnag.notify(error);
|
|
13
|
+
fastify.log.error(response);
|
|
14
|
+
reply.status(statusCode).send(response);
|
|
15
|
+
});
|
|
16
|
+
console.info(" ✅ Fancy Errors Enabled");
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errorHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errorHandler.js","sourceRoot":"","sources":["../../src/middleware/errorHandler.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,OAAwB,EACxB,WAAoB;IAEpB,IAAI,WAAW,KAAK,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,eAAe,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;YAChD,MAAM,UAAU,GAAG,KAAK,CAAC,UAAU,IAAI,GAAG,CAAC;YAC3C,MAAM,QAAQ,GAAG;gBACf,MAAM,EAAE,UAAU;gBAClB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,uBAAuB;gBACjD,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,aAAa,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;aACxE,CAAC;YAEF,mCAAmC;YACnC,IAAI,OAAO,CAAC,OAAO;gBAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAEnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC5B,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multipart.js","sourceRoot":"","sources":["../../src/middleware/multipart.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAwB,EAAE,OAAY;IACzE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,OAAO,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACzC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rateLimit.js","sourceRoot":"","sources":["../../src/middleware/rateLimit.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAwB,EAAE,OAAY;IACzE,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC,CAAC;QAC/D,OAAO,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"underPressure.js","sourceRoot":"","sources":["../../src/middleware/underPressure.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAwB,EACxB,OAAY;IAEZ,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;QAC7B,MAAM,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,yBAAyB,CAAC,EAAE,OAAO,CAAC,CAAC;QACnE,OAAO,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC9C,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { FastifyInstance, RouteOptions } from "fastify";
|
|
2
|
+
export declare function colorize(method: string, text: string): string;
|
|
3
|
+
export declare function printRoutes(routes: RouteOptions[], colors?: boolean): void;
|
|
4
|
+
export declare function captureRoutes(fastify: FastifyInstance): RouteOptions[];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const COLORS = {
|
|
2
|
+
POST: 33,
|
|
3
|
+
GET: 32,
|
|
4
|
+
PUT: 34,
|
|
5
|
+
DELETE: 31,
|
|
6
|
+
PATCH: 90,
|
|
7
|
+
clear: 39,
|
|
8
|
+
};
|
|
9
|
+
// Function to colorize method and path names
|
|
10
|
+
export function colorize(method, text) {
|
|
11
|
+
const colorCode = COLORS[method] || COLORS.clear;
|
|
12
|
+
return `\u001b[${colorCode}m${text}\u001b[${COLORS.clear}m`;
|
|
13
|
+
}
|
|
14
|
+
// Function to print the collected routes
|
|
15
|
+
export function printRoutes(routes, colors = true) {
|
|
16
|
+
routes
|
|
17
|
+
.sort((a, b) => a.url.localeCompare(b.url))
|
|
18
|
+
.forEach(({ method, url }) => {
|
|
19
|
+
const methodsArray = Array.isArray(method) ? method : [method];
|
|
20
|
+
methodsArray
|
|
21
|
+
.filter((m) => m !== "HEAD")
|
|
22
|
+
.forEach((m) => console.info(`${colors ? colorize(m, m) : m}\t${colors ? colorize(m, url) : url}`));
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Helper function to capture all registered routes
|
|
26
|
+
export function captureRoutes(fastify) {
|
|
27
|
+
const routes = [];
|
|
28
|
+
fastify.addHook("onRoute", (routeOptions) => {
|
|
29
|
+
routes.push(routeOptions);
|
|
30
|
+
});
|
|
31
|
+
return routes;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=colorize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colorize.js","sourceRoot":"","sources":["../../src/utils/colorize.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,GAA+B;IACzC,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,EAAE;IACP,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,EAAE;IACV,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,EAAE;CACV,CAAC;AAEF,6CAA6C;AAC7C,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,IAAY;IACnD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAoB,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC;IAC/D,OAAO,UAAU,SAAS,IAAI,IAAI,UAAU,MAAM,CAAC,KAAK,GAAG,CAAC;AAC9D,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,WAAW,CAAC,MAAsB,EAAE,MAAM,GAAG,IAAI;IAC/D,MAAM;SACH,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;SAC1C,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE;QAC3B,MAAM,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/D,YAAY;aACT,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC;aAC3B,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CACb,OAAO,CAAC,IAAI,CACV,GAAG,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CACrE,CACF,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC;AAED,mDAAmD;AACnD,MAAM,UAAU,aAAa,CAAC,OAAwB;IACpD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAElC,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC,YAAY,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatBytes(bytes: number, decimals?: number): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function formatBytes(bytes, decimals = 2) {
|
|
2
|
+
if (bytes === 0)
|
|
3
|
+
return "0 Bytes";
|
|
4
|
+
const k = 1024;
|
|
5
|
+
const dm = decimals < 0 ? 0 : decimals;
|
|
6
|
+
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
|
|
7
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
8
|
+
return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=formatBytes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formatBytes.js","sourceRoot":"","sources":["../../src/utils/formatBytes.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,KAAa,EAAE,QAAQ,GAAG,CAAC;IACrD,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAClC,MAAM,CAAC,GAAG,IAAI,CAAC;IACf,MAAM,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IACvC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IACtD,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,GAAG,UAAU,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const generateUUID: any;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"randomUUID.js","sourceRoot":"","sources":["../../src/utils/randomUUID.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAEtC,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statAsync.js","sourceRoot":"","sources":["../../src/utils/statAsync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC"}
|
package/dist/xConfig.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xConfig.js","sourceRoot":"","sources":["../src/xConfig.ts"],"names":[],"mappings":"AAAA,gBAAgB;AAChB,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,KAAK,UAAU,OAAO,CAAC,OAAO,EAAE,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,2BAA2B,CAAC,CAAC;AAC/D,CAAC;AAED,eAAe,EAAE,CAAC,OAAO,EAAE;IACzB,IAAI,EAAE,SAAS;CAChB,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xenterprises/fastify-xconfig",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "Fastify configuration plugin for setting up middleware, services, and route handling.",
|
|
6
6
|
"main": "src/xConfig.js",
|
|
7
7
|
"scripts": {
|
|
@@ -20,6 +20,29 @@
|
|
|
20
20
|
"typescript": "^5.6.3"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@fastify/autoload": "^6.0.2"
|
|
23
|
+
"@fastify/autoload": "^6.0.2",
|
|
24
|
+
"@fastify/cookie": "^9.4.0",
|
|
25
|
+
"@fastify/cors": "^9.0.1",
|
|
26
|
+
"@fastify/jwt": "^8.0.1",
|
|
27
|
+
"@fastify/multipart": "^8.3.0",
|
|
28
|
+
"@fastify/rate-limit": "^9.1.0",
|
|
29
|
+
"@fastify/sensible": "^5.6.0",
|
|
30
|
+
"@fastify/under-pressure": "^9.0.1",
|
|
31
|
+
"@prisma/client": "^5.20.0",
|
|
32
|
+
"@sendgrid/client": "^8.1.3",
|
|
33
|
+
"@sendgrid/mail": "^8.1.3",
|
|
34
|
+
"bcrypt": "^5.1.1",
|
|
35
|
+
"check-disk-space": "^3.4.0",
|
|
36
|
+
"fastify": "^4.28.1",
|
|
37
|
+
"fastify-bugsnag": "^4.1.4",
|
|
38
|
+
"fastify-cli": "^6.2.1",
|
|
39
|
+
"fastify-cloudinary": "^2.0.0",
|
|
40
|
+
"fastify-list-routes": "^1.0.0",
|
|
41
|
+
"fastify-multipart": "^5.4.0",
|
|
42
|
+
"fastify-plugin": "^4.0.0",
|
|
43
|
+
"fastify-rate-limit": "^5.9.0",
|
|
44
|
+
"stripe": "^16.12.0",
|
|
45
|
+
"twilio": "^5.3.2",
|
|
46
|
+
"uncrypto": "^0.1.3"
|
|
24
47
|
}
|
|
25
48
|
}
|
package/server/app.js
CHANGED
|
@@ -6,7 +6,84 @@ const fastify = Fastify();
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
export default async function (fastify, opts) {
|
|
9
|
-
fastify.register(xConfig
|
|
9
|
+
fastify.register(xConfig, {
|
|
10
|
+
professional: false,
|
|
11
|
+
fancyErrors: true,
|
|
12
|
+
prisma: {
|
|
13
|
+
active: false,
|
|
14
|
+
},
|
|
15
|
+
bugsnag: {
|
|
16
|
+
apiKey: process.env.BUGSNAG_API_KEY
|
|
17
|
+
},
|
|
18
|
+
rateLimit: {
|
|
19
|
+
max: process.env.RATE_LIMIT_MAX || 100,
|
|
20
|
+
timeWindow: process.env.RATE_LIMIT_TIME_WINDOW || '1 minute'
|
|
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
|
+
cors: {
|
|
46
|
+
active: true,
|
|
47
|
+
origin: process.env.CORS_ORIGIN || ['http://localhost:3000', 'https://app.bandmate.io'],
|
|
48
|
+
credentials: true
|
|
49
|
+
},
|
|
50
|
+
auth: {
|
|
51
|
+
excludedPaths: ['/public', '/portal/auth/register'],
|
|
52
|
+
admin: {
|
|
53
|
+
active: true,
|
|
54
|
+
secret: process.env.ADMIN_JWT_SECRET,
|
|
55
|
+
expiresIn: '1h',
|
|
56
|
+
cookieOptions: {
|
|
57
|
+
name: 'adminToken',
|
|
58
|
+
httpOnly: true,
|
|
59
|
+
secure: true, // Set to false if not using HTTPS
|
|
60
|
+
sameSite: 'strict', // Can be 'lax', 'strict', or 'none'
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
user: {
|
|
64
|
+
active: true,
|
|
65
|
+
secret: process.env.USER_JWT_SECRET,
|
|
66
|
+
expiresIn: '1h',
|
|
67
|
+
cookieOptions: {
|
|
68
|
+
name: 'userToken',
|
|
69
|
+
httpOnly: true,
|
|
70
|
+
secure: true,
|
|
71
|
+
sameSite: 'strict',
|
|
72
|
+
},
|
|
73
|
+
me: {
|
|
74
|
+
isOnboarded: true
|
|
75
|
+
},
|
|
76
|
+
registerEmail: {
|
|
77
|
+
subject: 'Welcome to Bandmate!',
|
|
78
|
+
templateId: ''
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
geocode: {
|
|
83
|
+
active: true,
|
|
84
|
+
apiKey: process.env.GEOCODIO_API_KEY
|
|
85
|
+
}
|
|
86
|
+
}); // Register the default export, which should be a function
|
|
10
87
|
fastify.get('/', async (request, reply) => {
|
|
11
88
|
console.log(fastify.xEcho())
|
|
12
89
|
return { status: fastify.xEcho() }
|