@xenterprises/fastify-xconfig 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/dist/integrations/cloudinary.d.ts +1 -0
  2. package/dist/integrations/cloudinary.js +25 -0
  3. package/dist/integrations/cloudinary.js.map +1 -0
  4. package/dist/integrations/prisma.d.ts +1 -0
  5. package/dist/integrations/prisma.js +13 -0
  6. package/dist/integrations/prisma.js.map +1 -0
  7. package/dist/integrations/sendgrid.d.ts +1 -0
  8. package/dist/integrations/sendgrid.js +22 -0
  9. package/dist/integrations/sendgrid.js.map +1 -0
  10. package/dist/integrations/stripe.d.ts +1 -0
  11. package/dist/integrations/stripe.js +15 -0
  12. package/dist/integrations/stripe.js.map +1 -0
  13. package/dist/integrations/twilio.d.ts +1 -0
  14. package/dist/integrations/twilio.js +17 -0
  15. package/dist/integrations/twilio.js.map +1 -0
  16. package/dist/middleware/bugsnag.d.ts +2 -0
  17. package/dist/middleware/bugsnag.js +9 -0
  18. package/dist/middleware/bugsnag.js.map +1 -0
  19. package/dist/middleware/cors.d.ts +2 -0
  20. package/dist/middleware/cors.js +11 -0
  21. package/dist/middleware/cors.js.map +1 -0
  22. package/dist/middleware/errorHandler.d.ts +2 -0
  23. package/dist/middleware/errorHandler.js +19 -0
  24. package/dist/middleware/errorHandler.js.map +1 -0
  25. package/dist/middleware/multipart.d.ts +2 -0
  26. package/dist/middleware/multipart.js +7 -0
  27. package/dist/middleware/multipart.js.map +1 -0
  28. package/dist/middleware/rateLimit.d.ts +2 -0
  29. package/dist/middleware/rateLimit.js +7 -0
  30. package/dist/middleware/rateLimit.js.map +1 -0
  31. package/dist/middleware/underPressure.d.ts +2 -0
  32. package/dist/middleware/underPressure.js +7 -0
  33. package/dist/middleware/underPressure.js.map +1 -0
  34. package/dist/utils/colorize.d.ts +4 -0
  35. package/dist/utils/colorize.js +33 -0
  36. package/dist/utils/colorize.js.map +1 -0
  37. package/dist/utils/formatBytes.d.ts +1 -0
  38. package/dist/utils/formatBytes.js +10 -0
  39. package/dist/utils/formatBytes.js.map +1 -0
  40. package/dist/utils/randomUUID.d.ts +1 -0
  41. package/dist/utils/randomUUID.js +3 -0
  42. package/dist/utils/randomUUID.js.map +1 -0
  43. package/dist/utils/statAsync.d.ts +2 -0
  44. package/dist/utils/statAsync.js +4 -0
  45. package/dist/utils/statAsync.js.map +1 -0
  46. package/dist/xConfig.d.ts +4 -0
  47. package/dist/xConfig.js +14 -0
  48. package/dist/xConfig.js.map +1 -0
  49. package/package.json +34 -9
  50. package/src/integrations/cloudinary.ts +26 -0
  51. package/src/integrations/prisma.ts +13 -0
  52. package/src/integrations/sendgrid.ts +27 -0
  53. package/src/integrations/stripe.ts +15 -0
  54. package/src/integrations/twilio.ts +20 -0
  55. package/src/middleware/bugsnag.ts +10 -0
  56. package/src/middleware/cors.ts +13 -0
  57. package/src/middleware/errorHandler.ts +24 -0
  58. package/src/middleware/multipart.ts +8 -0
  59. package/src/middleware/rateLimit.ts +8 -0
  60. package/src/middleware/underPressure.ts +11 -0
  61. package/src/utils/colorize.ts +45 -0
  62. package/src/utils/formatBytes.ts +8 -0
  63. package/src/utils/randomUUID.ts +3 -0
  64. package/src/utils/statAsync.ts +4 -0
  65. package/src/xConfig.ts +20 -0
  66. package/test/index.test-d.ts +1 -1
  67. package/tsconfig.json +15 -8
  68. package/index.js +0 -9
  69. /package/{index.d.ts → example.ts} +0 -0
@@ -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: () => `${string}-${string}-${string}-${string}-${string}`;
@@ -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,4 @@
1
+ import type { FastifyInstance, FastifyPluginOptions } from "fastify";
2
+ declare function xConfig(fastify: FastifyInstance, options: FastifyPluginOptions): Promise<void>;
3
+ declare const _default: typeof xConfig;
4
+ export default _default;
@@ -0,0 +1,14 @@
1
+ import fp from "fastify-plugin";
2
+ import { captureRoutes, printRoutes } from "./utils/colorize";
3
+ async function xConfig(fastify, options) {
4
+ // Capture routes using the hook
5
+ const routes = captureRoutes(fastify);
6
+ // After all plugins are loaded, print the routes
7
+ fastify.ready(() => {
8
+ printRoutes(routes);
9
+ });
10
+ }
11
+ export default fp(xConfig, {
12
+ name: "xConfig",
13
+ });
14
+ //# sourceMappingURL=xConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"xConfig.js","sourceRoot":"","sources":["../src/xConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE9D,KAAK,UAAU,OAAO,CACpB,OAAwB,EACxB,OAA6B;IAE7B,gCAAgC;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEtC,iDAAiD;IACjD,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;QACjB,WAAW,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,eAAe,EAAE,CAAC,OAAO,EAAE;IACzB,IAAI,EAAE,SAAS;CAChB,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,13 +1,16 @@
1
1
  {
2
2
  "name": "@xenterprises/fastify-xconfig",
3
- "version": "1.0.1",
4
- "description": "[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/) ![CI workflow](__MY_PLUGIN_URL__ /workflows/CI%20workflow/badge.svg)",
5
- "main": "index.js",
3
+ "version": "1.0.2",
4
+ "description": "Fastify configuration plugin for setting up middleware, services, and route handling.",
5
+ "main": "dist/xConfig.js",
6
6
  "directories": {
7
7
  "test": "test"
8
8
  },
9
+ "type": "module",
9
10
  "scripts": {
10
- "test": "npm run lint && npm run unit && npm run test:typescript",
11
+ "build": "tsc",
12
+ "prepare": "npm run build",
13
+ "test": "node dist/xConfig.js",
11
14
  "lint": "standard && npm run lint:typescript",
12
15
  "lint:typescript": "ts-standard",
13
16
  "test:typescript": "tsd",
@@ -16,17 +19,39 @@
16
19
  "keywords": [],
17
20
  "author": "Tim Mushen",
18
21
  "license": "MIT",
19
- "types": "index.d.ts",
22
+ "types": "dist/xConfig.d.ts",
20
23
  "dependencies": {
21
- "fastify-plugin": "^4.0.0"
24
+ "@fastify/autoload": "^6.0.1",
25
+ "@fastify/cookie": "^9.4.0",
26
+ "@fastify/cors": "^9.0.1",
27
+ "@fastify/jwt": "^8.0.1",
28
+ "@fastify/multipart": "^8.3.0",
29
+ "@fastify/rate-limit": "^9.1.0",
30
+ "@fastify/sensible": "^5.6.0",
31
+ "@fastify/under-pressure": "^9.0.1",
32
+ "@prisma/client": "^5.20.0",
33
+ "@sendgrid/client": "^8.1.3",
34
+ "@sendgrid/mail": "^8.1.3",
35
+ "bcrypt": "^5.1.1",
36
+ "fastify-bugsnag": "^4.1.4",
37
+ "fastify-cli": "^6.2.1",
38
+ "fastify-cloudinary": "^2.0.0",
39
+ "fastify-list-routes": "^1.0.0",
40
+ "fastify-multipart": "^5.4.0",
41
+ "fastify-rate-limit": "^5.9.0",
42
+ "stripe": "^16.12.0",
43
+ "twilio": "^5.3.2",
44
+ "uncrypto": "^0.1.3"
22
45
  },
23
46
  "devDependencies": {
24
- "@types/node": "^20.4.4",
47
+ "@types/node": "^20.17.0",
48
+ "fastify": "^4.28.1",
49
+ "fastify-plugin": "^4.0.0",
25
50
  "fastify-tsconfig": "^2.0.0",
26
51
  "standard": "^17.0.0",
27
52
  "ts-standard": "^12.0.1",
28
53
  "tsd": "^0.31.0",
29
- "typescript": "^5.2.2"
54
+ "typescript": "^5.6.3"
30
55
  },
31
56
  "tsd": {
32
57
  "directory": "test"
@@ -39,4 +64,4 @@
39
64
  "url": "https://github.com/xenterprises/module-fastify-xconfig/issues"
40
65
  },
41
66
  "homepage": "https://github.com/xenterprises/module-fastify-xconfig#readme"
42
- }
67
+ }
@@ -0,0 +1,26 @@
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
+ }
@@ -0,0 +1,13 @@
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
+ }
@@ -0,0 +1,27 @@
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
+ }
@@ -0,0 +1,15 @@
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
+ }
@@ -0,0 +1,20 @@
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
+ }
@@ -0,0 +1,10 @@
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
+ }
@@ -0,0 +1,13 @@
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
+ }
@@ -0,0 +1,24 @@
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
+ }
@@ -0,0 +1,8 @@
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
+ }
@@ -0,0 +1,8 @@
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
+ }
@@ -0,0 +1,11 @@
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
+ }
@@ -0,0 +1,45 @@
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
+ }
@@ -0,0 +1,8 @@
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
+ }
@@ -0,0 +1,3 @@
1
+ import { randomUUID } from "uncrypto";
2
+
3
+ export const generateUUID = randomUUID;
@@ -0,0 +1,4 @@
1
+ import fs from "fs";
2
+ import util from "util";
3
+
4
+ export const statAsync = util.promisify(fs.stat);
package/src/xConfig.ts ADDED
@@ -0,0 +1,20 @@
1
+ import fp from "fastify-plugin";
2
+ import type { FastifyInstance, FastifyPluginOptions } from "fastify";
3
+ import { captureRoutes, printRoutes } from "./utils/colorize";
4
+
5
+ async function xConfig(
6
+ fastify: FastifyInstance,
7
+ options: FastifyPluginOptions
8
+ ) {
9
+ // Capture routes using the hook
10
+ const routes = captureRoutes(fastify);
11
+
12
+ // After all plugins are loaded, print the routes
13
+ fastify.ready(() => {
14
+ printRoutes(routes);
15
+ });
16
+ }
17
+
18
+ export default fp(xConfig, {
19
+ name: "xConfig",
20
+ });
@@ -1,5 +1,5 @@
1
1
  import fastify from 'fastify'
2
- import example from '..'
2
+ import example from '../example'
3
3
  import { expectType } from 'tsd'
4
4
 
5
5
  let app
package/tsconfig.json CHANGED
@@ -1,9 +1,16 @@
1
1
  {
2
- "extends": "fastify-tsconfig",
3
- "compilerOptions": {
4
- "noEmit": true
5
- },
6
- "include": [
7
- "**/*.ts"
8
- ]
9
- }
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "declaration": true, // Generates .d.ts files for types
6
+ "outDir": "./dist", // Output directory for compiled files
7
+ "strict": true, // Enable all strict type-checking options
8
+ "moduleResolution": "node", // Proper module resolution
9
+ "esModuleInterop": true, // Allows default imports from CJS modules
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "sourceMap": true
13
+ },
14
+ "include": ["src/**/*"], // Specifies files to include for compilation
15
+ "exclude": ["node_modules", "dist"]
16
+ }
package/index.js DELETED
@@ -1,9 +0,0 @@
1
- 'use strict'
2
-
3
- const fp = require('fastify-plugin')
4
-
5
- module.exports = fp(async function (fastify, opts) {
6
- fastify.decorate('exampleDecorator', () => {
7
- return 'decorated'
8
- })
9
- }, { fastify: '^4.x' })
File without changes