{"version":3,"sources":["../../../../src/server/impls/express.ts"],"sourcesContent":["import http from 'http'\n\nimport cookie from 'cookie-parser'\nimport cors from 'cors'\nimport express from 'express'\nimport fileUpload from 'express-fileupload'\nimport { rateLimit } from 'express-rate-limit'\n// import slowDown from 'express-slow-down'\nimport helmet from 'helmet'\nimport { pinoHttp } from 'pino-http'\n\nimport { Instance } from '../../instance'\nimport { getMediaDuration } from '../../utilities'\nimport type { ServerConfig } from '../pipes'\nimport { Request } from '../requests'\nimport { type IncomingFile, StatusCodes } from '../types'\nimport { Server } from './base'\n\nexport class ExpressServer extends Server<express.Request, express.Response> {\n\tconstructor(config: ServerConfig) {\n\t\tconst app = express()\n\t\tconst instance = Instance.get()\n\t\tsuper(http.createServer(app), config, {\n\t\t\tparseRequest: async (req) => {\n\t\t\t\tconst files = Object.fromEntries(\n\t\t\t\t\tawait Promise.all(\n\t\t\t\t\t\tObject.entries(req.files ?? {}).map(async ([key, file]) => {\n\t\t\t\t\t\t\tconst uploads = Array.isArray(file) ? file : [file]\n\t\t\t\t\t\t\tconst fileArray: IncomingFile[] = await Promise.all(\n\t\t\t\t\t\t\t\tuploads.map(async (f) => ({\n\t\t\t\t\t\t\t\t\tname: f.name,\n\t\t\t\t\t\t\t\t\ttype: f.mimetype,\n\t\t\t\t\t\t\t\t\tsize: f.size,\n\t\t\t\t\t\t\t\t\tisTruncated: f.truncated,\n\t\t\t\t\t\t\t\t\tdata: f.data,\n\t\t\t\t\t\t\t\t\tduration: await getMediaDuration(f.data),\n\t\t\t\t\t\t\t\t})),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\treturn <const>[key, fileArray]\n\t\t\t\t\t\t}),\n\t\t\t\t\t),\n\t\t\t\t)\n\n\t\t\t\treturn new Request<any>({\n\t\t\t\t\tip: req.ip,\n\t\t\t\t\tbody: req.body ?? {},\n\t\t\t\t\tcookies: req.cookies ?? {},\n\t\t\t\t\tparams: req.params ?? {},\n\t\t\t\t\tquery: req.query ?? {},\n\t\t\t\t\tmethod: <any>req.method,\n\t\t\t\t\tpath: req.path,\n\t\t\t\t\theaders: req.headers,\n\t\t\t\t\tfiles,\n\t\t\t\t})\n\t\t\t},\n\t\t\thandleResponse: async (res, response) => {\n\t\t\t\tif (!response.piped) {\n\t\t\t\t\tObject.entries(response.headers).forEach(([key, value]) => res.header(key, value as string))\n\t\t\t\t\tObject.entries(response.cookies).forEach(([key, { value, ...opts }]) => res.cookie(key, value, opts))\n\t\t\t\t\tconst type = response.body === null || response.body === undefined ? 'json' : 'send'\n\t\t\t\t\tres.status(response.status)[type](response.body).end()\n\t\t\t\t} else {\n\t\t\t\t\tresponse.body.pipe(res)\n\t\t\t\t}\n\t\t\t},\n\t\t\tregisterRoute: (method, path, cb) => {\n\t\t\t\tapp[method]?.(path, async (req, res) => cb(req, res))\n\t\t\t},\n\t\t\tregisterErrorHandler: (cb) => {\n\t\t\t\tapp.use(async (err, req, res, _next) => cb(err, req, res))\n\t\t\t},\n\t\t\tregisterNotFoundHandler: (cb) => {\n\t\t\t\tapp.use(async (req, res, _next) => cb(req, res))\n\t\t\t},\n\t\t\tstart: async (port) =>\n\t\t\t\tnew Promise((resolve: (s: boolean) => void, reject: (e: Error) => void) => {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst app = this.server.listen({ host: '0.0.0.0', port }, async () => resolve(true))\n\t\t\t\t\t\tInstance.on('close', app.close, 1)\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\treject(<Error>err)\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t})\n\n\t\tapp.disable('x-powered-by')\n\t\tif (config.requests.log) app.use(pinoHttp({ logger: instance.log }))\n\t\tapp.use(express.json())\n\t\tapp.use(express.text())\n\t\tapp.use(cookie())\n\t\tapp.use(\n\t\t\thelmet({\n\t\t\t\tcrossOriginResourcePolicy: { policy: 'cross-origin' },\n\t\t\t\tcontentSecurityPolicy: false,\n\t\t\t}),\n\t\t)\n\t\tapp.use(cors(this.cors))\n\t\tapp.use(express.urlencoded({ extended: false }))\n\t\tif (config.publicPath) app.use(express.static(config.publicPath))\n\t\tapp.use(\n\t\t\tfileUpload({\n\t\t\t\tlimits: { fileSize: instance.settings.utils.maxFileUploadSizeInMb * 1024 * 1024 },\n\t\t\t\tuseTempFiles: false,\n\t\t\t}),\n\t\t)\n\t\tif (config.requests.rateLimit.enabled)\n\t\t\tapp.use(\n\t\t\t\trateLimit({\n\t\t\t\t\twindowMs: config.requests.rateLimit.periodInMs,\n\t\t\t\t\tlimit: config.requests.rateLimit.limit,\n\t\t\t\t\thandler: (_: express.Request, res: express.Response) =>\n\t\t\t\t\t\tres.status(StatusCodes.TooManyRequests).json([{ message: 'Too Many Requests' }]),\n\t\t\t\t}),\n\t\t\t)\n\t\t/* if (this.settings.slowdown.enabled) app.use(slowDown({\n\t\t\twindowMs: this.settings.slowdown.periodInMs,\n\t\t\tdelayAfter: this.settings.slowdown.delayAfter,\n\t\t\tdelayMs: this.settings.slowdown.delayInMs\n\t\t})) */\n\t}\n}\n"],"mappings":"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","names":["app"]}