@anyme/anymejs
Version:
189 lines (185 loc) • 7.14 kB
JavaScript
'use strict';
var routingControllers = require('routing-controllers');
var require$$0 = require('node:https');
var node_http = require('node:http');
var require$$0$1 = require('node:fs');
var index = require('../utils/index.js');
var constants = require('../utils/constants.js');
class Service {
app;
context;
iocAdapter;
logger;
constructor(app, context, iocAdapter) {
this.app = app;
this.context = context;
this.iocAdapter = iocAdapter;
this.logger = context.logger;
}
async createServer() {
const config = await this.context.config.get();
routingControllers.useContainer(this.iocAdapter);
const app = routingControllers.useExpressServer(this.app, config.server.route);
const { ssl, enable } = config.server.https;
const http = {
server: node_http.createServer(app),
scheme: "http",
port: config.server.port,
};
if (!enable)
return http;
const [key, cert] = await Promise.all([
this.readFile(ssl.key),
this.readFile(ssl.cert),
]);
if (!key || !cert) {
this.logger.warn("SSL key or certificate not found");
return http;
}
let ca;
if (ssl.requestCert && ssl.ca?.length) {
ca = (await Promise.allSettled(ssl.ca.map(this.readFile)))
.filter((p) => p.status === "fulfilled")
.map((p) => p.value);
if (!ca.length)
this.logger.warn("SSL CA certificates not found");
}
return {
server: require$$0.createServer({
...ssl,
key,
cert,
ca: ca?.length ? ca : undefined,
}, app),
scheme: "https",
port: config.server.https.port,
};
}
async applyRoute() {
this.app
.get("/", (_, res) => {
res.setHeader("Content-Type", "text/html; charset=utf-8");
res.send(constants.WELLCOME_HTML);
})
.get("/encrypt/:text", (req, res) => res.send(index.encrypt(req.params.text, index.getEncryptionKey())));
}
async applyLimiter() {
const { limiter: config } = await this.context.config.get();
const { enable, rules, rule } = config;
if (!enable)
return;
const { rateLimit } = await index.importModule("express-rate-limit");
const { slowDown } = await index.importModule("express-slow-down");
let store;
if (config.store === "redis") {
const RedisStore = await index.importModule("rate-limit-redis");
const redisClient = this.context.redis?.get(config.redis);
if (!redisClient)
throw new Error("limiter redis is required");
store = new RedisStore({
sendCommand: (command, ...args) => redisClient.call(command, ...args),
});
}
const withStore = (options) => {
if (store && options)
options.store = store;
return options;
};
if (rules) {
Object.entries(rules).forEach(([key, value]) => {
if (Array.isArray(value)) {
const [slowOpts, rateOpts] = value.map(withStore);
this.app.use(key, slowDown(slowOpts), rateLimit(rateOpts));
}
else {
const { slowDownOptions, rateLimitOptions } = value;
if (slowDownOptions)
this.app.use(key, slowDown(withStore(slowDownOptions)));
if (rateLimitOptions)
this.app.use(key, rateLimit(withStore(rateLimitOptions)));
}
});
}
else if (rule) {
const { slowDownOptions, rateLimitOptions } = rule;
if (slowDownOptions)
this.app.use(slowDown(withStore(slowDownOptions)));
if (rateLimitOptions)
this.app.use(rateLimit(withStore(rateLimitOptions)));
}
}
async applySession() {
try {
const { session: config } = await this.context.config.get();
const { enable, store, prefix, client } = config;
if (!enable)
return;
const session = await index.importModule("express-session");
if (store === "redis") {
const redisClient = this.context.redis?.get(config.redis);
if (!redisClient)
throw new Error("session redis is required");
const RedisStore = await index.importModule("@anyme/session-ioredis");
client.store = new RedisStore({
client: redisClient,
prefix,
});
}
this.app.use(session(client));
this.logger.info(`✅ Session set with ${store} store`);
}
catch (error) {
this.logger.error("❌ Failed to config session:", error);
throw error;
}
}
async applySocket(server) {
const config = await this.context.config.get();
if (!config.io.enable)
return;
const { Server } = await index.importModule("socket.io");
const SocketRouter = await index.importModule("@anyme/socket");
const io = new Server(server, config.io.options);
if (config.io.adapter === "cluster") {
const { createAdapter } = await index.importModule("@socket.io/cluster-adapter");
io.adapter(createAdapter());
}
if (config.io.adapter === "redis") {
const { createAdapter } = await index.importModule("@socket.io/redis-adapter");
const pub = this.context.redis.get(config.io.redis);
const sub = pub.duplicate();
io.adapter(createAdapter(pub, sub));
}
if (config.io.sticky) {
const { setupWorker } = await index.importModule("@socket.io/sticky");
setupWorker(io);
}
const socketRouter = new SocketRouter(io, this.context);
socketRouter.useContainer(this.iocAdapter).register(config.io.controllers);
}
async applySSE() {
const { sse: config } = await this.context.config.get();
if (!config.enable)
return;
const { SSERouter } = await index.importModule("@anyme/sse");
const sseRouter = new SSERouter(this.app, {
defaultOptions: config.options,
prefix: config.prefix,
context: this.context,
});
if (Array.isArray(config.controllers))
sseRouter.useContainer(this.iocAdapter).register(config.controllers);
if (config.routes)
sseRouter.add(config.routes);
}
async readFile(path) {
try {
return require$$0$1.readFileSync(index.getAbsolutePath(path));
}
catch {
return null;
}
}
}
exports.Service = Service;
//# sourceMappingURL=service.js.map