@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.
- package/LICENSE +100 -0
- package/README.md +140 -141
- package/examples/.env.example +17 -0
- package/examples/basic.js +127 -0
- package/index.d.ts +75 -0
- package/package.json +12 -5
- package/src/integrations/prisma.js +13 -17
- package/src/lifecycle/xFastifyAfter.js +4 -15
- package/src/middleware/bugsnag.js +7 -7
- package/src/middleware/cors.js +14 -15
- package/src/middleware/fancyErrors.js +17 -22
- package/src/middleware/multipart.js +4 -4
- package/src/middleware/rateLimit.js +4 -4
- package/src/middleware/underPressure.js +4 -4
- package/src/utils/formatBytes.js +3 -1
- package/src/utils/health.js +10 -36
- package/src/xConfig.js +21 -39
- package/dist/integrations/cloudinary.d.ts +0 -1
- package/dist/integrations/cloudinary.js +0 -25
- package/dist/integrations/cloudinary.js.map +0 -1
- package/dist/integrations/prisma.d.ts +0 -1
- package/dist/integrations/prisma.js +0 -13
- package/dist/integrations/prisma.js.map +0 -1
- package/dist/integrations/sendgrid.d.ts +0 -1
- package/dist/integrations/sendgrid.js +0 -22
- package/dist/integrations/sendgrid.js.map +0 -1
- package/dist/integrations/stripe.d.ts +0 -1
- package/dist/integrations/stripe.js +0 -15
- package/dist/integrations/stripe.js.map +0 -1
- package/dist/integrations/twilio.d.ts +0 -1
- package/dist/integrations/twilio.js +0 -17
- package/dist/integrations/twilio.js.map +0 -1
- package/dist/middleware/bugsnag.d.ts +0 -2
- package/dist/middleware/bugsnag.js +0 -9
- package/dist/middleware/bugsnag.js.map +0 -1
- package/dist/middleware/cors.d.ts +0 -2
- package/dist/middleware/cors.js +0 -11
- package/dist/middleware/cors.js.map +0 -1
- package/dist/middleware/errorHandler.d.ts +0 -2
- package/dist/middleware/errorHandler.js +0 -19
- package/dist/middleware/errorHandler.js.map +0 -1
- package/dist/middleware/multipart.d.ts +0 -2
- package/dist/middleware/multipart.js +0 -7
- package/dist/middleware/multipart.js.map +0 -1
- package/dist/middleware/rateLimit.d.ts +0 -2
- package/dist/middleware/rateLimit.js +0 -7
- package/dist/middleware/rateLimit.js.map +0 -1
- package/dist/middleware/underPressure.d.ts +0 -2
- package/dist/middleware/underPressure.js +0 -7
- package/dist/middleware/underPressure.js.map +0 -1
- package/dist/utils/colorize.d.ts +0 -4
- package/dist/utils/colorize.js +0 -33
- package/dist/utils/colorize.js.map +0 -1
- package/dist/utils/formatBytes.d.ts +0 -1
- package/dist/utils/formatBytes.js +0 -10
- package/dist/utils/formatBytes.js.map +0 -1
- package/dist/utils/randomUUID.d.ts +0 -1
- package/dist/utils/randomUUID.js +0 -3
- package/dist/utils/randomUUID.js.map +0 -1
- package/dist/utils/statAsync.d.ts +0 -2
- package/dist/utils/statAsync.js +0 -4
- package/dist/utils/statAsync.js.map +0 -1
- package/dist/xConfig.d.ts +0 -3
- package/dist/xConfig.js +0 -9
- package/dist/xConfig.js.map +0 -1
- package/ts-reference/integrations/cloudinary.ts +0 -26
- package/ts-reference/integrations/prisma.ts +0 -13
- package/ts-reference/integrations/sendgrid.ts +0 -27
- package/ts-reference/integrations/stripe.ts +0 -15
- package/ts-reference/integrations/twilio.ts +0 -20
- package/ts-reference/middleware/bugsnag.ts +0 -10
- package/ts-reference/middleware/cors.ts +0 -13
- package/ts-reference/middleware/errorHandler.ts +0 -24
- package/ts-reference/middleware/multipart.ts +0 -8
- package/ts-reference/middleware/rateLimit.ts +0 -8
- package/ts-reference/middleware/underPressure.ts +0 -11
- package/ts-reference/utils/colorize.ts +0 -45
- package/ts-reference/utils/formatBytes.ts +0 -8
- package/ts-reference/utils/randomUUID.ts +0 -3
- package/ts-reference/utils/statAsync.ts +0 -4
- package/tsconfig.json +0 -14
- package/xConfigReference.js +0 -119
|
@@ -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 +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 +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"}
|
package/dist/utils/colorize.d.ts
DELETED
|
@@ -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[];
|
package/dist/utils/colorize.js
DELETED
|
@@ -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;
|
package/dist/utils/randomUUID.js
DELETED
|
@@ -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"}
|
package/dist/utils/statAsync.js
DELETED
|
@@ -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
package/dist/xConfig.js
DELETED
package/dist/xConfig.js.map
DELETED
|
@@ -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
|
-
}
|
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
|
-
}
|
package/xConfigReference.js
DELETED
|
@@ -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
|