@xenterprises/fastify-xconfig 1.0.1 → 1.1.0

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 (99) hide show
  1. package/README.md +171 -18
  2. package/dist/integrations/cloudinary.d.ts +1 -0
  3. package/dist/integrations/cloudinary.js +25 -0
  4. package/dist/integrations/cloudinary.js.map +1 -0
  5. package/dist/integrations/prisma.d.ts +1 -0
  6. package/dist/integrations/prisma.js +13 -0
  7. package/dist/integrations/prisma.js.map +1 -0
  8. package/dist/integrations/sendgrid.d.ts +1 -0
  9. package/dist/integrations/sendgrid.js +22 -0
  10. package/dist/integrations/sendgrid.js.map +1 -0
  11. package/dist/integrations/stripe.d.ts +1 -0
  12. package/dist/integrations/stripe.js +15 -0
  13. package/dist/integrations/stripe.js.map +1 -0
  14. package/dist/integrations/twilio.d.ts +1 -0
  15. package/dist/integrations/twilio.js +17 -0
  16. package/dist/integrations/twilio.js.map +1 -0
  17. package/dist/middleware/bugsnag.d.ts +2 -0
  18. package/dist/middleware/bugsnag.js +9 -0
  19. package/dist/middleware/bugsnag.js.map +1 -0
  20. package/dist/middleware/cors.d.ts +2 -0
  21. package/dist/middleware/cors.js +11 -0
  22. package/dist/middleware/cors.js.map +1 -0
  23. package/dist/middleware/errorHandler.d.ts +2 -0
  24. package/dist/middleware/errorHandler.js +19 -0
  25. package/dist/middleware/errorHandler.js.map +1 -0
  26. package/dist/middleware/multipart.d.ts +2 -0
  27. package/dist/middleware/multipart.js +7 -0
  28. package/dist/middleware/multipart.js.map +1 -0
  29. package/dist/middleware/rateLimit.d.ts +2 -0
  30. package/dist/middleware/rateLimit.js +7 -0
  31. package/dist/middleware/rateLimit.js.map +1 -0
  32. package/dist/middleware/underPressure.d.ts +2 -0
  33. package/dist/middleware/underPressure.js +7 -0
  34. package/dist/middleware/underPressure.js.map +1 -0
  35. package/dist/utils/colorize.d.ts +4 -0
  36. package/dist/utils/colorize.js +33 -0
  37. package/dist/utils/colorize.js.map +1 -0
  38. package/dist/utils/formatBytes.d.ts +1 -0
  39. package/dist/utils/formatBytes.js +10 -0
  40. package/dist/utils/formatBytes.js.map +1 -0
  41. package/dist/utils/randomUUID.d.ts +1 -0
  42. package/dist/utils/randomUUID.js +3 -0
  43. package/dist/utils/randomUUID.js.map +1 -0
  44. package/dist/utils/statAsync.d.ts +2 -0
  45. package/dist/utils/statAsync.js +4 -0
  46. package/dist/utils/statAsync.js.map +1 -0
  47. package/dist/xConfig.d.ts +3 -0
  48. package/dist/xConfig.js +9 -0
  49. package/dist/xConfig.js.map +1 -0
  50. package/package.json +39 -33
  51. package/server/app.js +78 -0
  52. package/src/auth/admin.js +181 -0
  53. package/src/auth/portal.js +177 -0
  54. package/src/integrations/cloudinary.js +98 -0
  55. package/src/integrations/geocode.js +43 -0
  56. package/src/integrations/prisma.js +30 -0
  57. package/src/integrations/sendgrid.js +58 -0
  58. package/src/integrations/twilio.js +146 -0
  59. package/src/lifecycle/xFastifyAfter.js +27 -0
  60. package/src/middleware/bugsnag.js +10 -0
  61. package/src/middleware/cors.js +10 -0
  62. package/src/middleware/fancyErrors.js +26 -0
  63. package/src/middleware/multipart.js +6 -0
  64. package/src/middleware/rateLimit.js +6 -0
  65. package/src/middleware/underPressure.js +6 -0
  66. package/src/utils/colorize.js +37 -0
  67. package/src/utils/cookie.js +5 -0
  68. package/src/utils/formatBytes.js +16 -0
  69. package/src/utils/health.js +126 -0
  70. package/src/utils/xEcho.js +12 -0
  71. package/src/utils/xSlugify.js +20 -0
  72. package/src/utils/xUUID.js +14 -0
  73. package/src/xConfig.js +117 -0
  74. package/test/index.js +17 -0
  75. package/ts-reference/integrations/cloudinary.ts +26 -0
  76. package/ts-reference/integrations/prisma.ts +13 -0
  77. package/ts-reference/integrations/sendgrid.ts +27 -0
  78. package/ts-reference/integrations/stripe.ts +15 -0
  79. package/ts-reference/integrations/twilio.ts +20 -0
  80. package/ts-reference/middleware/bugsnag.ts +10 -0
  81. package/ts-reference/middleware/cors.ts +13 -0
  82. package/ts-reference/middleware/errorHandler.ts +24 -0
  83. package/ts-reference/middleware/multipart.ts +8 -0
  84. package/ts-reference/middleware/rateLimit.ts +8 -0
  85. package/ts-reference/middleware/underPressure.ts +11 -0
  86. package/ts-reference/utils/colorize.ts +45 -0
  87. package/ts-reference/utils/formatBytes.ts +8 -0
  88. package/ts-reference/utils/randomUUID.ts +3 -0
  89. package/ts-reference/utils/statAsync.ts +4 -0
  90. package/tsconfig.json +13 -8
  91. package/xConfigReference.js +1526 -0
  92. package/xConfigWorkingList.js +720 -0
  93. package/.github/workflows/ci.yml +0 -19
  94. package/.taprc +0 -3
  95. package/index.d.ts +0 -13
  96. package/index.js +0 -9
  97. package/test/index.test-d.ts +0 -13
  98. package/test/index.test.js +0 -14
  99. package/test/xConfig.js +0 -115
package/README.md CHANGED
@@ -1,29 +1,182 @@
1
- # __MY_PLUGIN__
1
+ # xConfig - Fastify Configuration Plugin
2
2
 
3
- [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) ![CI workflow](__MY_PLUGIN_URL__
4
- /workflows/CI%20workflow/badge.svg)
3
+ **xConfig** is a Fastify configuration plugin designed for setting up middleware, services, and route handling.
5
4
 
6
- Supports Fastify versions `4.x`
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.
7
6
 
8
- ## Install
9
- ```
10
- npm i __MY_PLUGIN__
11
- ```
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 Stack Auth integration.
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.
12
15
 
13
16
  ## Usage
14
- Require `__MY_PLUGIN__` and register.
15
- ```js
16
- const fastify = require('fastify')()
17
17
 
18
- fastify.register(require('__MY_PLUGIN__'), {
19
- // put your options here
20
- })
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";
21
25
 
22
- fastify.listen({ port: 3000 })
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
+ excludedPaths: ["/public", "/portal/auth/register"],
42
+ admin: {
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
+ },
54
+ },
55
+ cors: { origin: ["https://your-frontend.com"], credentials: true },
56
+ });
57
+
58
+ fastify.listen({ port: 3000 });
23
59
  ```
24
60
 
25
- ## Acknowledgements
61
+ ## Parameters
62
+
63
+ - **prisma**: Prisma Client configuration (optional).
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).
73
+
74
+ ## Authentication
75
+
76
+ The plugin provides both Admin and User authentication with Stack Auth integration. It handles token verification, protected routes, and authentication endpoints.
77
+
78
+ ### User Authentication
79
+
80
+ - `/portal/auth/login` - User login endpoint
81
+ - `/portal/auth/me` - Get current user information
82
+ - `/portal/auth/verify` - Verify a user token
83
+
84
+ ### Admin Authentication
85
+
86
+ - `/admin/auth/login` - Admin login endpoint
87
+ - `/admin/auth/me` - Get current admin information
88
+ - `/admin/auth/verify` - Verify an admin token
89
+
90
+ ### Stack Auth Integration
91
+
92
+ The plugin integrates with [Stack Auth](https://stack-auth.com) for secure authentication. You'll need to provide:
93
+
94
+ - `stackProjectId` - Your Stack Auth project ID
95
+ - `publishableKey` - Your Stack Auth publishable client key
96
+ - `secretKey` - Your Stack Auth secret server key
97
+
98
+ These can be provided via environment variables or in the plugin options.
99
+
100
+ ## Health Check
26
101
 
27
- ## License
102
+ The `/health` route provides a health check with details about uptime, memory usage, CPU load, database and Redis status, and environment variable validation.
28
103
 
29
- Licensed under [MIT](./LICENSE).<br/>
104
+ ## Services
105
+
106
+ - **Prisma**: Initializes Prisma Client and decorates the Fastify instance for database queries.
107
+ - **SendGrid**: Provides an email sending service through SendGrid, integrated with the Fastify instance.
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.
111
+
112
+ ## Hooks
113
+
114
+ - **onRequest**: Validates tokens for protected routes.
115
+ - **onClose**: Gracefully disconnects Prisma and other services on server shutdown.
116
+
117
+ ## Error Handling
118
+
119
+ Enhanced error handling is enabled by default, showing detailed error messages during development. Bugsnag integration is optional for real-time error reporting.
120
+
121
+ ## Route Listing
122
+
123
+ The plugin prints all routes after registration, color-coded by HTTP method, unless disabled.
124
+
125
+ ## Dependencies
126
+
127
+ The following dependencies are used for various services and integrations:
128
+
129
+ - Prisma Client, SendGrid, Twilio, Cloudinary, Fastify CORS, Fastify Rate Limit, Fastify Multipart, Fastify Under Pressure, and Fastify Bugsnag.
130
+
131
+ ## Environment Variables
132
+
133
+ ### Required for Authentication
134
+
135
+ - `ADMIN_STACK_PROJECT_ID` - Stack Auth project ID for admin authentication
136
+ - `ADMIN_STACK_PUBLISHABLE_CLIENT_KEY` - Stack Auth publishable key for admin authentication
137
+ - `ADMIN_STACK_SECRET_SERVER_KEY` - Stack Auth secret key for admin authentication
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
141
+
142
+ ### Other Environment Variables
143
+
144
+ - `DATABASE_URL` - Required for Prisma Client
145
+ - `SENDGRID_API_KEY` - Required for SendGrid integration
146
+ - `TWILIO_ACCOUNT_SID`, `TWILIO_AUTH_TOKEN`, `TWILIO_PHONE_NUMBER` - Required for Twilio integration
147
+ - `CLOUDINARY_CLOUD_NAME`, `CLOUDINARY_API_KEY`, `CLOUDINARY_API_SECRET` - Required for Cloudinary integration
148
+
149
+ ## Example Configuration
150
+
151
+ ```javascript
152
+ fastify.register(xConfig, {
153
+ prisma: { active: true },
154
+ sendGrid: { apiKey: "SG.your_api_key" },
155
+ twilio: {
156
+ accountSid: "ACxxxxxxxxxxxxxxxx",
157
+ authToken: "your_auth_token",
158
+ phoneNumber: "+1234567890",
159
+ },
160
+ cloudinary: {
161
+ cloudName: "your-cloud-name",
162
+ apiKey: "your-api-key",
163
+ apiSecret: "your-api-secret",
164
+ },
165
+ auth: {
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
+ ```
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupBugsnag(fastify: FastifyInstance, options: any): Promise<void>;
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupCors(fastify: FastifyInstance, options: any): Promise<void>;
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupErrorHandler(fastify: FastifyInstance, fancyErrors: boolean): Promise<void>;
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupMultipart(fastify: FastifyInstance, options: any): Promise<void>;
@@ -0,0 +1,7 @@
1
+ export async function setupMultipart(fastify, options) {
2
+ if (options.active !== false) {
3
+ await fastify.register(import("@fastify/multipart"), options);
4
+ console.info(" ✅ Multipart Enabled");
5
+ }
6
+ }
7
+ //# sourceMappingURL=multipart.js.map
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupRateLimit(fastify: FastifyInstance, options: any): Promise<void>;
@@ -0,0 +1,7 @@
1
+ export async function setupRateLimit(fastify, options) {
2
+ if (options.active !== false) {
3
+ await fastify.register(import("@fastify/rate-limit"), options);
4
+ console.info(" ✅ Rate Limiting Enabled");
5
+ }
6
+ }
7
+ //# sourceMappingURL=rateLimit.js.map
@@ -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,2 @@
1
+ import { FastifyInstance } from "fastify";
2
+ export declare function setupUnderPressure(fastify: FastifyInstance, options: any): Promise<void>;
@@ -0,0 +1,7 @@
1
+ export async function setupUnderPressure(fastify, options) {
2
+ if (options.active !== false) {
3
+ await fastify.register(import("@fastify/under-pressure"), options);
4
+ console.info(" ✅ Under Pressure Enabled");
5
+ }
6
+ }
7
+ //# sourceMappingURL=underPressure.js.map
@@ -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,3 @@
1
+ import { randomUUID } from "uncrypto";
2
+ export const generateUUID = randomUUID;
3
+ //# sourceMappingURL=randomUUID.js.map
@@ -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,2 @@
1
+ import fs from "fs";
2
+ export declare const statAsync: typeof fs.stat.__promisify__;
@@ -0,0 +1,4 @@
1
+ import fs from "fs";
2
+ import util from "util";
3
+ export const statAsync = util.promisify(fs.stat);
4
+ //# sourceMappingURL=statAsync.js.map
@@ -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"}
@@ -0,0 +1,3 @@
1
+ declare function xConfig(fastify: any, options: any): Promise<void>;
2
+ declare const _default: typeof xConfig;
3
+ export default _default;
@@ -0,0 +1,9 @@
1
+ //src/xConfig.js
2
+ import fp from "fastify-plugin";
3
+ async function xConfig(fastify, options) {
4
+ fastify.decorate("xEcho", () => "Hello from X Enterprises!");
5
+ }
6
+ export default fp(xConfig, {
7
+ name: "xConfig",
8
+ });
9
+ //# sourceMappingURL=xConfig.js.map
@@ -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"}