@pulzar/core
Version:
Next-generation Node.js framework for ultra-fast web applications with zero-reflection DI, GraphQL, WebSockets, events, and edge runtime support
124 lines • 4.54 kB
JavaScript
import fastify from "fastify";
import { logger } from "../utils/logger";
export class FastifyAdapter {
app;
constructor(options = {}) {
this.app = fastify({
logger: options.logger ?? logger,
trustProxy: options.trustProxy ?? true,
disableRequestLogging: options.disableRequestLogging ?? false,
ignoreTrailingSlash: options.ignoreTrailingSlash ?? true,
maxParamLength: options.maxParamLength ?? 100,
caseSensitive: options.caseSensitive ?? false,
allowUnsafeRegex: options.allowUnsafeRegex ?? false,
requestIdHeader: options.requestIdHeader ?? "x-request-id",
requestIdLogLabel: options.requestIdLogLabel ?? "reqId",
genReqId: options.genReqId,
bodyLimit: options.bodyLimit ?? 1048576, // 1MB
querystringParser: options.querystringParser,
exposeHeadRoutes: options.exposeHeadRoutes ?? true,
constraints: options.constraints,
});
this.setupDefaults();
}
generateRequestId(req) {
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
}
async setupDefaults() {
// Register sensible defaults
await this.app.register(import("@fastify/cors"), {
origin: process.env.CORS_ORIGIN
? process.env.CORS_ORIGIN.split(",")
: true,
credentials: true,
});
await this.app.register(import("@fastify/helmet"), {
contentSecurityPolicy: process.env.NODE_ENV === "production" ? undefined : false,
});
await this.app.register(import("@fastify/rate-limit"), {
max: parseInt(process.env.RATE_LIMIT_MAX || "100"),
timeWindow: parseInt(process.env.RATE_LIMIT_WINDOW || "900000"), // 15 minutes
});
await this.app.register(import("@fastify/compress"));
// Health check endpoint
this.app.get("/health", async () => ({
status: "ok",
timestamp: new Date().toISOString(),
uptime: process.uptime(),
}));
}
addRoute(options) {
this.app.route(options);
}
addPlugin(plugin, options) {
this.app.register(plugin, options || {});
}
addHook(hookName, hookHandler) {
this.app.addHook(hookName, hookHandler);
}
addPreHandler(handler) {
this.app.addHook("preHandler", handler);
}
addErrorHandler(handler) {
this.app.setErrorHandler(handler);
}
getInstance() {
return this.app;
}
async listen(port, host = "0.0.0.0") {
try {
const address = await this.app.listen({ port, host });
logger.info(`Server listening at ${address}`);
return address;
}
catch (error) {
logger.error("Failed to start server", { error });
throw error;
}
}
async close() {
await this.app.close();
}
// Plugin factory for middleware conversion
static createPluginFromMiddleware(middlewareFunction) {
return async (fastify) => {
fastify.addHook("preHandler", async (request, reply) => {
return new Promise((resolve, reject) => {
const req = this.createExpressLikeRequest(request);
const res = this.createExpressLikeResponse(reply);
middlewareFunction(req, res, (error) => {
if (error) {
reject(error);
}
else {
resolve();
}
});
});
});
};
}
static createExpressLikeRequest(request) {
return {
...request,
path: request.url,
get: (header) => request.headers[header.toLowerCase()],
header: (header) => request.headers[header.toLowerCase()],
};
}
static createExpressLikeResponse(reply) {
return {
...reply,
json: (data) => reply.send(data),
send: (data) => reply.send(data),
status: (code) => reply.code(code),
setHeader: (name, value) => reply.header(name, value),
get: (name) => reply.getHeader(name),
locals: {},
};
}
}
export function createFastifyAdapter(options) {
return new FastifyAdapter(options);
}
//# sourceMappingURL=fastify-adapter.js.map