@xenterprises/fastify-xconfig 2.1.4 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/LICENSE +100 -0
  2. package/README.md +140 -141
  3. package/examples/.env.example +17 -0
  4. package/examples/basic.js +127 -0
  5. package/index.d.ts +75 -0
  6. package/package.json +12 -5
  7. package/src/integrations/prisma.js +13 -17
  8. package/src/lifecycle/xFastifyAfter.js +4 -15
  9. package/src/middleware/bugsnag.js +7 -7
  10. package/src/middleware/cors.js +14 -15
  11. package/src/middleware/fancyErrors.js +17 -22
  12. package/src/middleware/multipart.js +4 -4
  13. package/src/middleware/rateLimit.js +4 -4
  14. package/src/middleware/underPressure.js +4 -4
  15. package/src/utils/formatBytes.js +3 -1
  16. package/src/utils/health.js +10 -36
  17. package/src/xConfig.js +21 -39
  18. package/dist/integrations/cloudinary.d.ts +0 -1
  19. package/dist/integrations/cloudinary.js +0 -25
  20. package/dist/integrations/cloudinary.js.map +0 -1
  21. package/dist/integrations/prisma.d.ts +0 -1
  22. package/dist/integrations/prisma.js +0 -13
  23. package/dist/integrations/prisma.js.map +0 -1
  24. package/dist/integrations/sendgrid.d.ts +0 -1
  25. package/dist/integrations/sendgrid.js +0 -22
  26. package/dist/integrations/sendgrid.js.map +0 -1
  27. package/dist/integrations/stripe.d.ts +0 -1
  28. package/dist/integrations/stripe.js +0 -15
  29. package/dist/integrations/stripe.js.map +0 -1
  30. package/dist/integrations/twilio.d.ts +0 -1
  31. package/dist/integrations/twilio.js +0 -17
  32. package/dist/integrations/twilio.js.map +0 -1
  33. package/dist/middleware/bugsnag.d.ts +0 -2
  34. package/dist/middleware/bugsnag.js +0 -9
  35. package/dist/middleware/bugsnag.js.map +0 -1
  36. package/dist/middleware/cors.d.ts +0 -2
  37. package/dist/middleware/cors.js +0 -11
  38. package/dist/middleware/cors.js.map +0 -1
  39. package/dist/middleware/errorHandler.d.ts +0 -2
  40. package/dist/middleware/errorHandler.js +0 -19
  41. package/dist/middleware/errorHandler.js.map +0 -1
  42. package/dist/middleware/multipart.d.ts +0 -2
  43. package/dist/middleware/multipart.js +0 -7
  44. package/dist/middleware/multipart.js.map +0 -1
  45. package/dist/middleware/rateLimit.d.ts +0 -2
  46. package/dist/middleware/rateLimit.js +0 -7
  47. package/dist/middleware/rateLimit.js.map +0 -1
  48. package/dist/middleware/underPressure.d.ts +0 -2
  49. package/dist/middleware/underPressure.js +0 -7
  50. package/dist/middleware/underPressure.js.map +0 -1
  51. package/dist/utils/colorize.d.ts +0 -4
  52. package/dist/utils/colorize.js +0 -33
  53. package/dist/utils/colorize.js.map +0 -1
  54. package/dist/utils/formatBytes.d.ts +0 -1
  55. package/dist/utils/formatBytes.js +0 -10
  56. package/dist/utils/formatBytes.js.map +0 -1
  57. package/dist/utils/randomUUID.d.ts +0 -1
  58. package/dist/utils/randomUUID.js +0 -3
  59. package/dist/utils/randomUUID.js.map +0 -1
  60. package/dist/utils/statAsync.d.ts +0 -2
  61. package/dist/utils/statAsync.js +0 -4
  62. package/dist/utils/statAsync.js.map +0 -1
  63. package/dist/xConfig.d.ts +0 -3
  64. package/dist/xConfig.js +0 -9
  65. package/dist/xConfig.js.map +0 -1
  66. package/ts-reference/integrations/cloudinary.ts +0 -26
  67. package/ts-reference/integrations/prisma.ts +0 -13
  68. package/ts-reference/integrations/sendgrid.ts +0 -27
  69. package/ts-reference/integrations/stripe.ts +0 -15
  70. package/ts-reference/integrations/twilio.ts +0 -20
  71. package/ts-reference/middleware/bugsnag.ts +0 -10
  72. package/ts-reference/middleware/cors.ts +0 -13
  73. package/ts-reference/middleware/errorHandler.ts +0 -24
  74. package/ts-reference/middleware/multipart.ts +0 -8
  75. package/ts-reference/middleware/rateLimit.ts +0 -8
  76. package/ts-reference/middleware/underPressure.ts +0 -11
  77. package/ts-reference/utils/colorize.ts +0 -45
  78. package/ts-reference/utils/formatBytes.ts +0 -8
  79. package/ts-reference/utils/randomUUID.ts +0 -3
  80. package/ts-reference/utils/statAsync.ts +0 -4
  81. package/tsconfig.json +0 -14
  82. package/xConfigReference.js +0 -119
@@ -1,24 +1,20 @@
1
1
  export async function setupPrisma(fastify, options) {
2
- if (options.active !== false) {
3
- const { client: PrismaClient, active, ...prismaOptions } = options;
4
- if (!PrismaClient) {
5
- throw new Error("prisma.client is required - pass your PrismaClient class from your generated client");
6
- }
2
+ if (options.active === false) return;
7
3
 
8
- const prisma = new PrismaClient(prismaOptions);
9
-
10
- fastify.decorate("prisma", prisma);
11
-
12
- fastify.addHook("onClose", async () => {
13
- await fastify.prisma.$disconnect();
14
- });
15
-
16
- console.info(" ✅ Prisma Enabled");
4
+ const { client: PrismaClient, active, ...prismaOptions } = options;
5
+ if (!PrismaClient) {
6
+ throw new Error("[xConfig] prisma.client is required - pass your PrismaClient class from your generated client");
17
7
  }
8
+ if (typeof PrismaClient !== 'function') {
9
+ throw new Error("[xConfig] prisma.client must be a PrismaClient constructor");
10
+ }
11
+
12
+ const prisma = new PrismaClient(prismaOptions);
13
+ fastify.decorate("prisma", prisma);
18
14
 
19
15
  fastify.addHook("onClose", async () => {
20
- if (fastify.prisma) {
21
- await fastify.prisma.$disconnect();
22
- }
16
+ await fastify.prisma.$disconnect();
23
17
  });
18
+
19
+ fastify.log.info("[xConfig] Prisma enabled");
24
20
  }
@@ -1,27 +1,16 @@
1
- // src/lifecycle/xFastifyAfter.js
2
1
  import { printRoutes } from "../utils/colorize.js";
3
- export async function xFastifyAfter(fastify, options) {
4
- // Add the goodbye emoji hook before listening
2
+
3
+ export function xFastifyAfter(fastify, options) {
5
4
  fastify.addHook("onClose", () => {
6
- console.info("Server shutting down... Goodbye 👋");
5
+ fastify.log.info("Server shutting down... Goodbye");
7
6
  });
8
7
 
9
- /*
10
- ===== LIST ROUTES AFTER ALL PLUGINS =====
11
- Use the after() method to ensure this runs after all plugins are registered.
12
- */
13
8
  fastify.after(() => {
14
9
  if (options.professional !== true) {
15
- console.info(" ✅ Listing Routes:");
16
10
  fastify.ready(() => {
17
11
  printRoutes(options.routes, options.colors !== false);
18
- // Add rocket emoji
19
- console.info(
20
- `🚀 Server is ready on port ${process.env.PORT || 3000}\n\n`
21
- );
12
+ fastify.log.info(`Server is ready on port ${process.env.PORT || 3000}`);
22
13
  });
23
14
  }
24
15
  });
25
-
26
-
27
16
  }
@@ -1,10 +1,10 @@
1
1
  export async function setupBugsnag(fastify, options) {
2
- if (options.active !== false) {
3
- if (!options.apiKey)
4
- throw new Error("Bugsnag API key must be provided.");
5
- fastify.register(import("fastify-bugsnag"), {
6
- apiKey: options.apiKey,
7
- });
8
- console.info(" ✅ BugSnag Enabled");
2
+ if (options.active === false) return;
3
+ if (!options.apiKey || typeof options.apiKey !== 'string') {
4
+ throw new Error("[xConfig] bugsnag.apiKey is required and must be a string");
9
5
  }
6
+ fastify.register(import("fastify-bugsnag"), {
7
+ apiKey: options.apiKey,
8
+ });
9
+ fastify.log.info("[xConfig] Bugsnag enabled");
10
10
  }
@@ -1,19 +1,18 @@
1
1
  export async function setupCors(fastify, options) {
2
- if (options.active !== false) {
3
- // Extract active flag and pass all other options directly to the CORS plugin
4
- const { active, ...corsOptions } = options;
2
+ if (options.active === false) return;
5
3
 
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
4
+ const { active, ...corsOptions } = options;
10
5
 
11
- await fastify.register(await import("@fastify/cors"), {
12
- origin: corsOptions.origin || defaultOrigins,
13
- credentials: corsOptions.credentials !== undefined ? corsOptions.credentials : true,
14
- methods: corsOptions.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
15
- ...corsOptions // This will include ignorePaths: ['/public'] in the preflight config
16
- });
17
- console.info(" ✅ CORS Enabled");
18
- }
6
+ const defaultOrigins = process.env.NODE_ENV === 'production'
7
+ ? (process.env.CORS_ORIGIN ? process.env.CORS_ORIGIN.split(',').map(s => s.trim()) : true)
8
+ : ["http://localhost:3000", "http://localhost:3001"];
9
+
10
+ await fastify.register(await import("@fastify/cors"), {
11
+ origin: corsOptions.origin || defaultOrigins,
12
+ credentials: corsOptions.credentials !== undefined ? corsOptions.credentials : true,
13
+ methods: corsOptions.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
14
+ ...corsOptions,
15
+ });
16
+
17
+ fastify.log.info("[xConfig] CORS enabled");
19
18
  }
@@ -1,26 +1,21 @@
1
- export async function setupFancyErrors(fastify, options) {
1
+ export function setupFancyErrors(fastify, enabled) {
2
+ if (enabled === false) return;
2
3
 
3
- /*
4
- ===== EXTEND ERRORS =====
5
- */
6
- if (options.fancyErrors !== false) {
7
- fastify.setErrorHandler((error, request, reply) => {
8
- const statusCode = error.statusCode || 500;
9
- const response = {
10
- status: statusCode,
11
- message: error.message || "Internal Server Error",
12
- // Only show stack in development mode
13
- stack: process.env.NODE_ENV === "development" ? error.stack : undefined,
14
- };
4
+ fastify.setErrorHandler((error, request, reply) => {
5
+ const statusCode = error.statusCode || 500;
6
+ const response = {
7
+ status: statusCode,
8
+ message: error.message || "Internal Server Error",
9
+ stack: process.env.NODE_ENV !== "production" ? error.stack : undefined,
10
+ };
15
11
 
16
- // Optional Bugsnag error reporting
17
- if (fastify.bugsnag) {
18
- fastify.bugsnag.notify(error);
19
- }
12
+ if (fastify.bugsnag && typeof fastify.bugsnag.notify === 'function') {
13
+ fastify.bugsnag.notify(error);
14
+ }
20
15
 
21
- fastify.log.error(response);
22
- reply.status(statusCode).send(response);
23
- });
24
- console.info(" ✅ Fancy Errors Enabled");
25
- }
16
+ fastify.log.error(response);
17
+ reply.status(statusCode).send(response);
18
+ });
19
+
20
+ fastify.log.info("[xConfig] Fancy errors enabled");
26
21
  }
@@ -1,6 +1,6 @@
1
1
  export async function setupMultipart(fastify, options) {
2
- if (options.active !== false) {
3
- fastify.register(import("@fastify/multipart"), options);
4
- console.info(" ✅ Multipart Enabled");
5
- }
2
+ if (options.active === false) return;
3
+ const { active, ...multipartOptions } = options;
4
+ fastify.register(import("@fastify/multipart"), multipartOptions);
5
+ fastify.log.info("[xConfig] Multipart enabled");
6
6
  }
@@ -1,6 +1,6 @@
1
1
  export async function setupRateLimit(fastify, options) {
2
- if (options.active !== false) {
3
- fastify.register(import("@fastify/rate-limit"), options);
4
- console.info(" ✅ Rate Limiting Enabled");
5
- }
2
+ if (options.active === false) return;
3
+ const { active, ...rateLimitOptions } = options;
4
+ fastify.register(import("@fastify/rate-limit"), rateLimitOptions);
5
+ fastify.log.info("[xConfig] Rate limiting enabled");
6
6
  }
@@ -1,6 +1,6 @@
1
1
  export async function setupUnderPressure(fastify, options) {
2
- if (options.active !== false) {
3
- fastify.register(import("@fastify/under-pressure"), options);
4
- console.info(" ✅ Under Pressure Enabled");
5
- }
2
+ if (options.active === false) return;
3
+ const { active, ...underPressureOptions } = options;
4
+ fastify.register(import("@fastify/under-pressure"), underPressureOptions);
5
+ fastify.log.info("[xConfig] Under pressure enabled");
6
6
  }
@@ -13,4 +13,6 @@ async function formatBytesPlugin(fastify, options) {
13
13
  });
14
14
  }
15
15
 
16
- export default fp(formatBytesPlugin);
16
+ export default fp(formatBytesPlugin, {
17
+ name: "xFormatBytes",
18
+ });
@@ -1,42 +1,29 @@
1
- // Import necessary modules
2
1
  import os from "os";
3
2
  import process from "process";
4
- import fs from "fs";
5
- import util from "util";
6
3
 
7
-
8
- // Promisify fs functions
9
- const statAsync = util.promisify(fs.stat);
10
-
11
- // Record the server start time
12
- const serverStartTime = Date.now();
13
-
14
- // Helper function to format bytes into human-readable format
15
4
  function formatBytes(bytes, decimals = 2) {
16
5
  if (bytes === 0) return "0 Bytes";
17
6
  const k = 1024;
18
7
  const dm = decimals < 0 ? 0 : decimals;
19
8
  const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
20
9
  const i = Math.floor(Math.log(bytes) / Math.log(k));
21
- const formattedNumber = parseFloat((bytes / Math.pow(k, i)).toFixed(dm));
22
- return `${formattedNumber} ${sizes[i]}`;
10
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
23
11
  }
24
12
 
25
- export async function setupHealth(fastify, options) {
13
+ export async function setupHealth(fastify) {
26
14
  fastify.get("/health", async (request, reply) => {
27
15
  const status = {
28
16
  status: "healthy",
29
17
  timestamp: new Date().toISOString(),
30
- uptime: process.uptime(), // Uptime in seconds
31
- version: "1.0.0", // Fetch dynamically if possible
18
+ uptime: process.uptime(),
32
19
  environment: process.env.NODE_ENV || "development",
33
20
  dependencies: {},
34
21
  resources: {},
35
22
  details: {},
36
23
  };
37
24
 
25
+ // Database connectivity check
38
26
  try {
39
- // Database connectivity check
40
27
  if (fastify.prisma) {
41
28
  await fastify.prisma.$queryRaw`SELECT 1`;
42
29
  status.dependencies.database = "up";
@@ -49,8 +36,8 @@ export async function setupHealth(fastify, options) {
49
36
  status.details.databaseError = error.message;
50
37
  }
51
38
 
39
+ // Redis connectivity check
52
40
  try {
53
- // Redis connectivity check
54
41
  if (fastify.redis) {
55
42
  await fastify.redis.ping();
56
43
  status.dependencies.redis = "up";
@@ -65,8 +52,6 @@ export async function setupHealth(fastify, options) {
65
52
 
66
53
  // Resource usage
67
54
  const memoryUsage = process.memoryUsage();
68
- const loadAverage = os.loadavg();
69
-
70
55
  status.resources.memory = {
71
56
  rss: formatBytes(memoryUsage.rss),
72
57
  heapTotal: formatBytes(memoryUsage.heapTotal),
@@ -76,16 +61,14 @@ export async function setupHealth(fastify, options) {
76
61
  };
77
62
 
78
63
  status.resources.cpu = {
79
- loadAverage, // 1, 5, and 15 minute load averages
64
+ loadAverage: os.loadavg(),
80
65
  cpus: os.cpus().length,
81
66
  };
82
67
 
83
68
  // Disk space availability
84
69
  try {
85
- // Implement disk space check using 'check-disk-space' package
86
- // Install it via 'npm install check-disk-space'
87
70
  const checkDiskSpace = (await import("check-disk-space")).default;
88
- const diskSpace = await checkDiskSpace("/"); // Replace '/' with your drive or mount point
71
+ const diskSpace = await checkDiskSpace("/");
89
72
  status.resources.disk = {
90
73
  free: formatBytes(diskSpace.free),
91
74
  size: formatBytes(diskSpace.size),
@@ -95,15 +78,7 @@ export async function setupHealth(fastify, options) {
95
78
  status.details.diskError = error.message;
96
79
  }
97
80
 
98
- // Application-specific checks
99
- // Example: Check if a scheduled job is running
100
- if (typeof isJobRunning === "function" && !isJobRunning()) {
101
- status.status = "degraded";
102
- status.details.jobStatus = "Scheduled job is not running";
103
- }
104
-
105
- // Configuration validation
106
- // Only check required env vars if Prisma is enabled
81
+ // Configuration validation — only if Prisma is enabled
107
82
  if (fastify.prisma) {
108
83
  const requiredEnvVars = ["DATABASE_URL"];
109
84
  const missingEnvVars = requiredEnvVars.filter(
@@ -115,11 +90,10 @@ export async function setupHealth(fastify, options) {
115
90
  }
116
91
  }
117
92
 
118
- // Determine overall health
119
93
  if (status.status === "healthy") {
120
94
  reply.send(status);
121
95
  } else {
122
- reply.status(500).send(status);
96
+ reply.status(503).send(status);
123
97
  }
124
98
  });
125
- }
99
+ }
package/src/xConfig.js CHANGED
@@ -1,36 +1,28 @@
1
- // src/xConfig.js
2
1
  import fp from "fastify-plugin";
3
- const isProduction = process.env.NODE_ENV === 'production';
4
2
 
5
- /*
6
- * Integrations
7
- */
8
3
  import { setupPrisma } from "./integrations/prisma.js";
9
-
10
- /*
11
- * Lifecycle
12
- */
13
4
  import { xFastifyAfter } from "./lifecycle/xFastifyAfter.js";
14
-
15
- /*
16
- * Middleware
17
- */
18
5
  import { setupCors } from './middleware/cors.js';
19
6
  import { setupUnderPressure } from './middleware/underPressure.js';
20
7
  import { setupRateLimit } from './middleware/rateLimit.js';
21
8
  import { setupMultipart } from './middleware/multipart.js';
22
9
  import { setupBugsnag } from './middleware/bugsnag.js';
23
- import { setupFancyErrors } from './middleware/fancyErrors.js'
24
-
25
- /*
26
- * Utils
27
- */
10
+ import { setupFancyErrors } from './middleware/fancyErrors.js';
28
11
  import xEcho from "./utils/xEcho.js";
29
12
  import { setupHealth } from "./utils/health.js";
30
13
  import xSlugify from "./utils/xSlugify.js";
31
14
  import xUUID from "./utils/xUUID.js";
15
+ import xFormatBytes from "./utils/formatBytes.js";
32
16
 
33
17
  async function xConfig(fastify, options) {
18
+ // Validate top-level options
19
+ if (options.professional !== undefined && typeof options.professional !== 'boolean') {
20
+ throw new Error("[xConfig] professional must be a boolean");
21
+ }
22
+ if (options.fancyErrors !== undefined && typeof options.fancyErrors !== 'boolean') {
23
+ throw new Error("[xConfig] fancyErrors must be a boolean");
24
+ }
25
+
34
26
  const {
35
27
  professional = false,
36
28
  fancyErrors = true,
@@ -42,46 +34,36 @@ async function xConfig(fastify, options) {
42
34
  rateLimit: rateLimitOptions = {},
43
35
  } = options;
44
36
 
45
- // add starting console with emoji
46
- console.info("\n 🌮 Starting xConfig...\n");
37
+ fastify.log.info("[xConfig] Starting...");
47
38
 
48
- /*
49
- ===== LIST ROUTES =====
50
- Moved the onRoute hook to the top to capture all routes.
51
- */
39
+ // Capture all registered routes for listing
52
40
  const routes = [];
53
41
  fastify.addHook("onRoute", (r) => routes.push(r));
54
42
 
55
- /*
56
- * Integrations
57
- */
43
+ // Integrations
58
44
  await setupPrisma(fastify, prismaOptions);
59
45
 
60
- /*
61
- * Middleware
62
- */
46
+ // Middleware
63
47
  await setupCors(fastify, corsOptions);
64
48
  await setupUnderPressure(fastify, underPressureOptions);
65
49
  await setupRateLimit(fastify, rateLimitOptions);
66
50
  await setupMultipart(fastify, multipartOptions);
67
51
  await setupBugsnag(fastify, bugsnagOptions);
68
- await setupFancyErrors(fastify, fancyErrors);
69
- fastify.register(import('@fastify/sensible'))
70
-
71
- /*
72
- * Utils
73
- */
52
+ setupFancyErrors(fastify, fancyErrors);
53
+ fastify.register(import('@fastify/sensible'));
74
54
 
55
+ // Utils
75
56
  fastify.register(xEcho);
76
57
  fastify.register(xSlugify);
77
58
  fastify.register(xUUID);
59
+ fastify.register(xFormatBytes);
78
60
  await setupHealth(fastify);
79
61
 
80
- //.after() method to ensure this runs after all plugins are registered.
81
- await xFastifyAfter(fastify, { professional, routes });
82
-
62
+ // Lifecycle route listing after all plugins
63
+ xFastifyAfter(fastify, { professional, routes });
83
64
  }
84
65
 
85
66
  export default fp(xConfig, {
86
67
  name: "xConfig",
68
+ fastify: ">=5.0.0",
87
69
  });
@@ -1 +0,0 @@
1
- export declare function setupCloudinary(fastify: any, cloudinaryOptions: any): Promise<void>;
@@ -1,25 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare function setupPrisma(fastify: any, prismaOptions: any): Promise<void>;
@@ -1,13 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare function setupSendGrid(fastify: any, sendGridOptions: any): Promise<void>;
@@ -1,22 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare function setupStripe(fastify: any, stripeOptions: any): Promise<void>;
@@ -1,15 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare function setupTwilio(fastify: any, twilioOptions: any): Promise<void>;
@@ -1,17 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupBugsnag(fastify: FastifyInstance, options: any): Promise<void>;
@@ -1,9 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupCors(fastify: FastifyInstance, options: any): Promise<void>;
@@ -1,11 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupErrorHandler(fastify: FastifyInstance, fancyErrors: boolean): Promise<void>;
@@ -1,19 +0,0 @@
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
@@ -1 +0,0 @@
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"}