@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,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupMultipart(fastify: FastifyInstance, options: any): Promise<void>;
@@ -1,7 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupRateLimit(fastify: FastifyInstance, options: any): Promise<void>;
@@ -1,7 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
- export declare function setupUnderPressure(fastify: FastifyInstance, options: any): Promise<void>;
@@ -1,7 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,4 +0,0 @@
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[];
@@ -1,33 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare function formatBytes(bytes: number, decimals?: number): string;
@@ -1,10 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1 +0,0 @@
1
- export declare const generateUUID: any;
@@ -1,3 +0,0 @@
1
- import { randomUUID } from "uncrypto";
2
- export const generateUUID = randomUUID;
3
- //# sourceMappingURL=randomUUID.js.map
@@ -1 +0,0 @@
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"}
@@ -1,2 +0,0 @@
1
- import fs from "fs";
2
- export declare const statAsync: typeof fs.stat.__promisify__;
@@ -1,4 +0,0 @@
1
- import fs from "fs";
2
- import util from "util";
3
- export const statAsync = util.promisify(fs.stat);
4
- //# sourceMappingURL=statAsync.js.map
@@ -1 +0,0 @@
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.d.ts DELETED
@@ -1,3 +0,0 @@
1
- declare function xConfig(fastify: any, options: any): Promise<void>;
2
- declare const _default: typeof xConfig;
3
- export default _default;
package/dist/xConfig.js DELETED
@@ -1,9 +0,0 @@
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
@@ -1 +0,0 @@
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"}
@@ -1,26 +0,0 @@
1
- import { v2 as Cloudinary } from "cloudinary";
2
-
3
- export async function setupCloudinary(fastify: any, cloudinaryOptions: any) {
4
- if (cloudinaryOptions.active !== false) {
5
- Cloudinary.config({
6
- cloud_name: cloudinaryOptions.cloudName,
7
- api_key: cloudinaryOptions.apiKey,
8
- api_secret: cloudinaryOptions.apiSecret,
9
- });
10
- fastify.decorate("cloudinary", {
11
- async upload(fileStream: any, options = {}) {
12
- return new Promise((resolve, reject) => {
13
- const uploadStream = Cloudinary.uploader.upload_stream(
14
- options,
15
- (error, result) => {
16
- if (error) reject(error);
17
- else resolve(result);
18
- }
19
- );
20
- fileStream.pipe(uploadStream);
21
- });
22
- },
23
- });
24
- console.info(" ✅ Cloudinary Enabled");
25
- }
26
- }
@@ -1,13 +0,0 @@
1
- import { PrismaClient } from "@prisma/client";
2
-
3
- export async function setupPrisma(fastify: any, prismaOptions: any) {
4
- if (prismaOptions.active !== false) {
5
- const prisma = new PrismaClient(prismaOptions);
6
- await prisma.$connect();
7
- fastify.decorate("prisma", prisma);
8
- fastify.addHook("onClose", async () => {
9
- await fastify.prisma.$disconnect();
10
- });
11
- console.info(" ✅ Prisma Enabled");
12
- }
13
- }
@@ -1,27 +0,0 @@
1
- import Sendgrid from "@sendgrid/mail";
2
-
3
- export async function setupSendGrid(fastify: any, sendGridOptions: any) {
4
- if (sendGridOptions.active !== false) {
5
- if (!sendGridOptions.apiKey)
6
- throw new Error("SendGrid API key must be provided.");
7
- Sendgrid.setApiKey(sendGridOptions.apiKey);
8
- fastify.decorate("sendgrid", {
9
- async sendEmail(
10
- to: string,
11
- subject: string,
12
- templateId: string,
13
- dynamicTemplateData: any
14
- ) {
15
- const msg = {
16
- to,
17
- from: sendGridOptions.fromEmail,
18
- subject,
19
- templateId,
20
- dynamicTemplateData,
21
- };
22
- await Sendgrid.send(msg);
23
- },
24
- });
25
- console.info(" ✅ SendGrid Enabled");
26
- }
27
- }
@@ -1,15 +0,0 @@
1
- import Stripe from "stripe";
2
-
3
- export async function setupStripe(fastify: any, stripeOptions: any) {
4
- if (stripeOptions.active !== false) {
5
- const stripeClient = new Stripe(stripeOptions.apiKey, {
6
- apiVersion: "2024-06-20",
7
- });
8
- fastify.decorate("stripe", {
9
- async createPaymentIntent(amount: number, currency = "usd") {
10
- return await stripeClient.paymentIntents.create({ amount, currency });
11
- },
12
- });
13
- console.info(" ✅ Stripe Enabled");
14
- }
15
- }
@@ -1,20 +0,0 @@
1
- import Twilio from "twilio";
2
-
3
- export async function setupTwilio(fastify: any, twilioOptions: any) {
4
- if (twilioOptions.active !== false) {
5
- const twilioClient = Twilio(
6
- twilioOptions.accountSid,
7
- twilioOptions.authToken
8
- );
9
- fastify.decorate("twilio", {
10
- async sendSMS(to: string, body: string) {
11
- return await twilioClient.messages.create({
12
- body,
13
- to,
14
- from: twilioOptions.phoneNumber,
15
- });
16
- },
17
- });
18
- console.info(" ✅ Twilio Enabled");
19
- }
20
- }
@@ -1,10 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupBugsnag(fastify: FastifyInstance, options: any) {
4
- if (options.active !== false && options.apiKey) {
5
- await fastify.register(import("fastify-bugsnag"), {
6
- apiKey: options.apiKey,
7
- });
8
- console.info(" ✅ Bugsnag Enabled");
9
- }
10
- }
@@ -1,13 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupCors(fastify: FastifyInstance, options: any) {
4
- if (options.active !== false) {
5
- await fastify.register(import("@fastify/cors"), {
6
- origin: options.origin || ["https://getx.io", "http://localhost:3000"],
7
- credentials:
8
- options.credentials !== undefined ? options.credentials : true,
9
- methods: options.methods || ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
10
- });
11
- console.info(" ✅ CORS Enabled");
12
- }
13
- }
@@ -1,24 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupErrorHandler(
4
- fastify: FastifyInstance,
5
- fancyErrors: boolean
6
- ) {
7
- if (fancyErrors !== false) {
8
- fastify.setErrorHandler((error, request, reply) => {
9
- const statusCode = error.statusCode || 500;
10
- const response = {
11
- status: statusCode,
12
- message: error.message || "Internal Server Error",
13
- stack: process.env.NODE_ENV === "development" ? error.stack : undefined,
14
- };
15
-
16
- // Optional Bugsnag error reporting
17
- if (fastify.bugsnag) fastify.bugsnag.notify(error);
18
-
19
- fastify.log.error(response);
20
- reply.status(statusCode).send(response);
21
- });
22
- console.info(" ✅ Fancy Errors Enabled");
23
- }
24
- }
@@ -1,8 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupMultipart(fastify: FastifyInstance, options: any) {
4
- if (options.active !== false) {
5
- await fastify.register(import("@fastify/multipart"), options);
6
- console.info(" ✅ Multipart Enabled");
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupRateLimit(fastify: FastifyInstance, options: any) {
4
- if (options.active !== false) {
5
- await fastify.register(import("@fastify/rate-limit"), options);
6
- console.info(" ✅ Rate Limiting Enabled");
7
- }
8
- }
@@ -1,11 +0,0 @@
1
- import { FastifyInstance } from "fastify";
2
-
3
- export async function setupUnderPressure(
4
- fastify: FastifyInstance,
5
- options: any
6
- ) {
7
- if (options.active !== false) {
8
- await fastify.register(import("@fastify/under-pressure"), options);
9
- console.info(" ✅ Under Pressure Enabled");
10
- }
11
- }
@@ -1,45 +0,0 @@
1
- import type { FastifyInstance, RouteOptions } from "fastify";
2
-
3
- type HttpMethod = "POST" | "GET" | "PUT" | "DELETE" | "PATCH" | "clear";
4
-
5
- const COLORS: Record<HttpMethod, number> = {
6
- POST: 33,
7
- GET: 32,
8
- PUT: 34,
9
- DELETE: 31,
10
- PATCH: 90,
11
- clear: 39,
12
- };
13
-
14
- // Function to colorize method and path names
15
- export function colorize(method: string, text: string) {
16
- const colorCode = COLORS[method as HttpMethod] || COLORS.clear;
17
- return `\u001b[${colorCode}m${text}\u001b[${COLORS.clear}m`;
18
- }
19
-
20
- // Function to print the collected routes
21
- export function printRoutes(routes: RouteOptions[], colors = true): void {
22
- routes
23
- .sort((a, b) => a.url.localeCompare(b.url))
24
- .forEach(({ method, url }) => {
25
- const methodsArray = Array.isArray(method) ? method : [method];
26
- methodsArray
27
- .filter((m) => m !== "HEAD")
28
- .forEach((m) =>
29
- console.info(
30
- `${colors ? colorize(m, m) : m}\t${colors ? colorize(m, url) : url}`
31
- )
32
- );
33
- });
34
- }
35
-
36
- // Helper function to capture all registered routes
37
- export function captureRoutes(fastify: FastifyInstance): RouteOptions[] {
38
- const routes: RouteOptions[] = [];
39
-
40
- fastify.addHook("onRoute", (routeOptions) => {
41
- routes.push(routeOptions);
42
- });
43
-
44
- return routes;
45
- }
@@ -1,8 +0,0 @@
1
- export function formatBytes(bytes: number, decimals = 2): string {
2
- if (bytes === 0) return "0 Bytes";
3
- const k = 1024;
4
- const dm = decimals < 0 ? 0 : decimals;
5
- const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB"];
6
- const i = Math.floor(Math.log(bytes) / Math.log(k));
7
- return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`;
8
- }
@@ -1,3 +0,0 @@
1
- import { randomUUID } from "uncrypto";
2
-
3
- export const generateUUID = randomUUID;
@@ -1,4 +0,0 @@
1
- import fs from "fs";
2
- import util from "util";
3
-
4
- export const statAsync = util.promisify(fs.stat);
package/tsconfig.json DELETED
@@ -1,14 +0,0 @@
1
- {
2
- "extends": "fastify-tsconfig",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "sourceMap": true,
6
- "moduleResolution": "node",
7
- "module": "NodeNext",
8
- "target": "ES2022",
9
- "esModuleInterop": true,
10
- "allowSyntheticDefaultImports": true
11
- },
12
- "include": ["src/**/*.ts", "ts-reference/**/*.ts"],
13
- "exclude": ["node_modules", "dist"]
14
- }
@@ -1,119 +0,0 @@
1
- /**
2
- * xConfig - Fastify configuration plugin for core middleware and services
3
- *
4
- * This plugin provides centralized configuration for essential Fastify middleware and services:
5
- * - CORS and rate limiting
6
- * - Multipart form handling and back pressure monitoring
7
- * - Prisma database integration
8
- * - Error tracking (Bugsnag)
9
- * - Health checks and resource monitoring
10
- *
11
- * Key Features:
12
- * - Handles CORS, rate-limiting, multipart handling, and error handling out of the box
13
- * - Integrates with Prisma for database operations
14
- * - Provides optional Bugsnag integration for error tracking
15
- * - Includes health check routes with resource usage monitoring
16
- * - Gracefully handles server shutdown and resource cleanup
17
- *
18
- * Usage:
19
- * This plugin should be registered in your Fastify instance with options for each service.
20
- *
21
- * Example:
22
- * ```javascript
23
- * import Fastify from 'fastify';
24
- * import xConfig from '@xenterprises/fastify-xconfig';
25
- *
26
- * const fastify = Fastify();
27
- * fastify.register(xConfig, {
28
- * professional: false,
29
- * fancyErrors: true,
30
- * prisma: {},
31
- * bugsnag: { apiKey: process.env.BUGSNAG_API_KEY },
32
- * cors: {
33
- * active: true,
34
- * origin: ['http://localhost:3000'],
35
- * credentials: true
36
- * },
37
- * rateLimit: {
38
- * max: 100,
39
- * timeWindow: '1 minute'
40
- * },
41
- * multipart: {
42
- * limits: { fileSize: 52428800 } // 50MB
43
- * },
44
- * underPressure: {
45
- * maxEventLoopDelay: 1000,
46
- * maxHeapUsedBytes: 1000000000,
47
- * maxRssBytes: 1000000000
48
- * }
49
- * });
50
- *
51
- * fastify.listen({ port: 3000 });
52
- * ```
53
- *
54
- * Parameters:
55
- * @param {Object} options - Configuration options
56
- * - professional {Boolean}: Disable route listing in professional mode (default: false)
57
- * - fancyErrors {Boolean}: Enable formatted error responses (default: true)
58
- * - prisma {Object}: Prisma Client configuration (optional)
59
- * - bugsnag {Object}: Bugsnag error reporting config with apiKey (optional)
60
- * - cors {Object}: CORS configuration with active, origin, credentials (optional)
61
- * - rateLimit {Object}: Rate-limiting with max and timeWindow (optional)
62
- * - multipart {Object}: Multipart handling options (optional)
63
- * - underPressure {Object}: Back pressure monitoring configuration (optional)
64
- *
65
- * Health Check:
66
- * The `/health` route provides status about:
67
- * - Application uptime and version
68
- * - Database connectivity
69
- * - Memory and CPU usage
70
- * - Disk space availability
71
- * - Environment configuration validation
72
- *
73
- * Services:
74
- * - Prisma: Database ORM for queries
75
- * - CORS: Cross-origin resource sharing
76
- * - Rate Limiting: Request rate throttling
77
- * - Multipart: File upload handling
78
- * - Under Pressure: Load monitoring and throttling
79
- * - Bugsnag: Error tracking and reporting
80
- *
81
- * Decorators:
82
- * - fastify.health.check(): Get health status
83
- * - fastify.prisma: Prisma client instance
84
- * - fastify.slugify(string): Convert string to slug format
85
- * - fastify.UUID(): Generate UUID
86
- *
87
- * Separated Services:
88
- * The following services have been extracted to dedicated plugins:
89
- * - Authentication/JWKS → xAuthJWSK plugin
90
- * - Geocoding → xGeocode plugin
91
- * - SMS/Email → xTwilio plugin (separate module)
92
- * - File Storage → xStorage plugin (separate module)
93
- * - Payment Processing → xStripe plugin (separate module)
94
- *
95
- * Environment Variables:
96
- * - DATABASE_URL: PostgreSQL connection string
97
- * - NODE_ENV: development/production
98
- * - BUGSNAG_API_KEY: Optional error tracking
99
- * - CORS_ORIGIN: Comma-separated CORS origins
100
- * - RATE_LIMIT_MAX: Max requests (default: 100)
101
- * - RATE_LIMIT_TIME_WINDOW: Rate limit window (default: '1 minute')
102
- *
103
- * Error Handling:
104
- * Fancy error handling is enabled by default, showing enhanced error messages during development.
105
- * Errors are logged with full stack traces in development and clean messages in production.
106
- * Bugsnag integration is optional for real-time error reporting in production.
107
- *
108
- * Hooks:
109
- * - onClose: Gracefully disconnects Prisma on server shutdown
110
- *
111
- * Notes:
112
- * - This plugin is designed for essential middleware only
113
- * - Third-party services (SendGrid, Twilio, Stripe, etc.) should use dedicated plugins
114
- * - All configuration is optional except DATABASE_URL (if using Prisma)
115
- * - The plugin is highly customizable and works well in both development and production
116
- */
117
-
118
- // This file serves as documentation and reference for the xConfig plugin
119
- // The actual implementation is in src/xConfig.js