@desaubv/quik 0.1.2 → 0.1.4

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/dist/index.cjs CHANGED
@@ -390,6 +390,7 @@ var QuikRouter = class {
390
390
  return this;
391
391
  }
392
392
  register(method, handler) {
393
+ if (!this.router[method]) return this;
393
394
  this.router[method](
394
395
  this.currentPath,
395
396
  ...this.pendingMiddleware,
@@ -414,6 +415,9 @@ var QuikRouter = class {
414
415
  put(handler) {
415
416
  return this.register("put", handler);
416
417
  }
418
+ query(handler) {
419
+ return this.register("query", handler);
420
+ }
417
421
  patch(handler) {
418
422
  return this.register("patch", handler);
419
423
  }
@@ -427,6 +431,7 @@ function Router() {
427
431
 
428
432
  // src/core/server.ts
429
433
  var import_express2 = __toESM(require("express"), 1);
434
+ var import_express_fileupload = __toESM(require("express-fileupload"), 1);
430
435
  var import_node_http = __toESM(require("http"), 1);
431
436
  var import_node_path2 = __toESM(require("path"), 1);
432
437
  var import_node_fs2 = __toESM(require("fs"), 1);
@@ -569,6 +574,10 @@ var QuikServer = class {
569
574
  express: {
570
575
  ...this.config.express,
571
576
  ...config2.express
577
+ },
578
+ fileUpload: {
579
+ ...this.config.fileUpload,
580
+ ...config2.fileUpload
572
581
  }
573
582
  };
574
583
  if (config2.timeZone && !isValidTimeZone(config2.timeZone)) {
@@ -684,29 +693,44 @@ var QuikServer = class {
684
693
  }
685
694
  return this;
686
695
  }
696
+ #configureFileUpload() {
697
+ const config2 = this.config.fileUpload;
698
+ if (config2) {
699
+ this.app.use(
700
+ (0, import_express_fileupload.default)(config2)
701
+ );
702
+ }
703
+ return this;
704
+ }
687
705
  #configureMiddleware() {
688
706
  const bodyParser = this.config.bodyParser;
689
707
  switch (bodyParser.type) {
690
- case "json":
708
+ case "json": {
691
709
  this.app.use(
692
710
  import_express2.default.json(bodyParser.options)
693
711
  );
694
712
  break;
695
- case "urlencoded":
713
+ }
714
+ case "urlencoded": {
715
+ const options = bodyParser.options ?? { extended: true };
696
716
  this.app.use(
697
- import_express2.default.urlencoded(bodyParser.options)
717
+ import_express2.default.urlencoded(options)
698
718
  );
699
719
  break;
700
- case "raw":
720
+ }
721
+ case "raw": {
722
+ const options = bodyParser.options ?? { type: "*/*" };
701
723
  this.app.use(
702
- import_express2.default.raw(bodyParser.options)
724
+ import_express2.default.raw(options)
703
725
  );
704
726
  break;
705
- case "text":
727
+ }
728
+ case "text": {
706
729
  this.app.use(
707
730
  import_express2.default.text(bodyParser.options)
708
731
  );
709
732
  break;
733
+ }
710
734
  }
711
735
  if (this.middlewares.length > 0)
712
736
  this.app.use(...this.middlewares);
@@ -793,6 +817,7 @@ var QuikServer = class {
793
817
  start() {
794
818
  this.#configureExpress();
795
819
  this.#configureMiddleware();
820
+ this.#configureFileUpload();
796
821
  this.#loadStaticDirs();
797
822
  this.#loadRoutes();
798
823
  this.#loadHandlers();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/core/errors/serverErrors.ts","../src/core/logger.ts","../src/core/colors.ts","../src/core/time.ts","../src/locales/en.json","../src/locales/es.json","../src/core/translator.ts","../src/core/router.ts","../src/core/server.ts","../src/cron/cron.ts","../src/http/status.ts","../src/core/handlers/notFoundHandler.ts","../src/core/handlers/httpErrorHandler.ts"],"sourcesContent":["export { ServerInvalidRouteError } from \"./core/errors/serverErrors.js\";\r\nexport { logger } from \"./core/logger.js\";\r\nexport { Router, QuikRouter } from \"./core/router.js\";\r\nexport { Server } from \"./core/server.js\";\r\n","class ServerInvalidRouteError extends Error {\r\n constructor(path: string) {\r\n super(`\"${path}\" is not a QuikRouter instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidCronError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikCron instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidWebSocketError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikWebSocket instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidSocketIOError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikSocketIO instance.`);\r\n }\r\n}\r\n\r\nexport { ServerInvalidRouteError, ServerInvalidCronError, ServerInvalidWebSocketError, ServerInvalidSocketIOError }","import fs from \"node:fs\"\r\nimport path from \"node:path\";\r\n\r\nimport { colors } from \"./colors.js\"\r\nimport { dateToString, isValidTimeZone } from \"./time.js\";\r\nimport { translate } from \"./translator.js\";\r\n\r\n/* Types */\r\ntype ConfigValue = string | null | false;\r\ntype Cases = \"uppercase\" | \"lowercase\" | \"capitalize\" | \"none\" | null;\r\ntype ColorName =\r\n | \"black\"\r\n | \"red\"\r\n | \"green\"\r\n | \"yellow\"\r\n | \"blue\"\r\n | \"magenta\"\r\n | \"cyan\"\r\n | \"white\";\r\n\r\ntype ColorValue = ColorName | null;\r\ntype SaveConfig = {\r\n infoFilePath: ConfigValue,\r\n logFilePath: ConfigValue,\r\n errorFilePath: ConfigValue,\r\n warningFilePath: ConfigValue,\r\n}\r\ntype ColorConfig = {\r\n logColor: ColorValue;\r\n infoColor: ColorValue;\r\n errorColor: ColorValue;\r\n warningColor: ColorValue;\r\n debugColor: ColorValue;\r\n}\r\ntype Formatconfig = {\r\n timestampFormat: ConfigValue,\r\n titleCase: Cases,\r\n prefix?: string\r\n suffix?: string\r\n timeZone?: string\r\n}\r\n\r\ntype LoggerConfig = {\r\n language: Language,\r\n save: SaveConfig,\r\n color: ColorConfig,\r\n format: Formatconfig,\r\n}\r\ntype PartialConfig = Partial<{\r\n save: Partial<SaveConfig>;\r\n color: Partial<ColorConfig>;\r\n format: Partial<Formatconfig>;\r\n}>;\r\n\r\nconst defaultConfig: LoggerConfig = {\r\n language: \"en\",\r\n save: {\r\n logFilePath: null,\r\n infoFilePath: null,\r\n errorFilePath: \"logs/error.log\",\r\n warningFilePath: \"logs/warning.log\",\r\n },\r\n color: {\r\n logColor: \"blue\",\r\n infoColor: \"green\",\r\n errorColor: \"red\",\r\n warningColor: \"yellow\",\r\n debugColor: null\r\n },\r\n format: {\r\n timestampFormat: \"DD-MM-YYYY hh:mm:ss\",\r\n titleCase: \"uppercase\"\r\n }\r\n}\r\n\r\nlet config = structuredClone(defaultConfig);\r\n\r\nfunction tokenize(...args: unknown[]): string[] {\r\n return args.map(arg => {\r\n if (typeof arg === \"string\") return arg;\r\n\r\n if (arg instanceof Error) {\r\n return arg.stack ?? arg.message;\r\n }\r\n\r\n if (arg === null || arg === undefined) {\r\n return String(arg);\r\n }\r\n\r\n if (typeof arg === \"object\") {\r\n try {\r\n return JSON.stringify(arg);\r\n } catch {\r\n return \"[Circular]\";\r\n }\r\n }\r\n\r\n return String(arg);\r\n });\r\n}\r\n\r\nfunction write(\r\n level: string,\r\n color: ColorName | null | false,\r\n file: ConfigValue,\r\n ...content: unknown[]\r\n) {\r\n const [header, body] = parseContent(level, ...content);\r\n saveToFile(file, header + body);\r\n\r\n const prefix = config.format.prefix ?? \"\";\r\n const suffix = config.format.suffix ?? \"\";\r\n\r\n if (color) {\r\n const colorFn = colors[color] ?? ((s: string) => s);\r\n console.log(`${prefix}${header}${colorFn(body)}${suffix}`);\r\n } else {\r\n console.log(`${prefix}${header}${body}${suffix}`);\r\n }\r\n}\r\n\r\nfunction parseContent(level: string, ...body: unknown[]): [string, string] {\r\n let header = \"\";\r\n if (config.format.timestampFormat) {\r\n const now = new Date();\r\n const timeZone = config.format.timeZone;\r\n let tz = timeZone;\r\n\r\n if (timeZone && !isValidTimeZone(timeZone)) {\r\n tz = undefined;\r\n }\r\n\r\n const timestamp = dateToString(\r\n now,\r\n config.format.timestampFormat,\r\n tz\r\n );\r\n\r\n header += `${timestamp} `;\r\n }\r\n\r\n switch (config.format.titleCase) {\r\n case \"uppercase\":\r\n level = `[${level.toUpperCase()}] `;\r\n break;\r\n case \"lowercase\":\r\n level = `[${level.toLocaleLowerCase()}] `;\r\n break;\r\n case \"capitalize\":\r\n level = `[${level.charAt(0).toUpperCase() + level.slice(1).toLowerCase()}] `;\r\n break;\r\n case \"none\":\r\n level = `[${level}] `;\r\n break;\r\n default:\r\n level = \"\";\r\n break;\r\n }\r\n let content = level + tokenize(...body).join(\" \");\r\n return [header, content];\r\n}\r\n\r\nfunction saveToFile(filePath: ConfigValue, content: string): void {\r\n if (!filePath || !content.length) return;\r\n\r\n const dir = path.dirname(filePath);\r\n const logMessage = content + \"\\n\";\r\n\r\n fs.mkdirSync(dir, { recursive: true });\r\n fs.appendFileSync(filePath, logMessage);\r\n}\r\n\r\nfunction mergeConfig(\r\n current: LoggerConfig,\r\n update: PartialConfig\r\n): LoggerConfig {\r\n return {\r\n ...current,\r\n ...update,\r\n save: {\r\n ...current.save,\r\n ...update.save,\r\n },\r\n color: {\r\n ...current.color,\r\n ...update.color,\r\n },\r\n format: {\r\n ...current.format,\r\n ...update.format,\r\n },\r\n };\r\n}\r\n\r\nexport const logger = {\r\n // Setter config\r\n setConfig(newConfig: PartialConfig): void {\r\n config = mergeConfig(config, newConfig);\r\n },\r\n\r\n // Getter config\r\n config(): Readonly<LoggerConfig> {\r\n return Object.freeze(structuredClone(config));\r\n },\r\n\r\n log(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.log,\r\n config.color.logColor,\r\n config.save.logFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n info(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.info,\r\n config.color.infoColor,\r\n config.save.infoFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n error(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.error,\r\n config.color.errorColor,\r\n config.save.errorFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n warning(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.warning,\r\n config.color.warningColor,\r\n config.save.warningFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n debug(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.debug,\r\n config.color.debugColor,\r\n null,\r\n ...content\r\n );\r\n },\r\n\r\n clear() {\r\n console.clear();\r\n },\r\n\r\n custom(\r\n level: string,\r\n color: ColorName | null | false,\r\n file: ConfigValue,\r\n ...content: unknown[]\r\n ) {\r\n write(level, color, file, ...content);\r\n }\r\n}","const color = {\r\n reset: \"\\x1b[0m\",\r\n\r\n black: \"\\x1b[30m\",\r\n red: \"\\x1b[31m\",\r\n green: \"\\x1b[32m\",\r\n yellow: \"\\x1b[33m\",\r\n blue: \"\\x1b[34m\",\r\n magenta: \"\\x1b[35m\",\r\n cyan: \"\\x1b[36m\",\r\n white: \"\\x1b[37m\",\r\n\r\n bold: \"\\x1b[1m\",\r\n underline: \"\\x1b[4m\"\r\n} as const;\r\n\r\n\r\ntype Color = keyof Omit<typeof color, \"reset\">;\r\nconst colors = Object.fromEntries(\r\n Object.entries(color)\r\n .filter(([key]) => key !== \"reset\")\r\n .map(([key, value]) => [\r\n key,\r\n (text: string) => `${value}${text}${color.reset}`\r\n ])\r\n) as Record<Color, (text: string) => string>;\r\n\r\nexport { color, colors };","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","{\r\n \"logger\": {\r\n \"levels\": {\r\n \"log\": \"log\",\r\n \"info\": \"info\",\r\n \"warning\": \"warning\",\r\n \"error\": \"error\",\r\n \"debug\": \"debug\"\r\n }\r\n },\r\n \"server\": {\r\n \"name\": \"server\",\r\n \"start\": \"Server running at\",\r\n \"routers_loaded\": \"routers loaded\",\r\n \"crons_loaded\": \"crons loaded\",\r\n \"socket_loaded\": \"socket loaded\",\r\n \"static_loaded\": \"static dirs loaded\",\r\n \"views_loaded\": \"views dirs loaded\",\r\n\r\n \"static_warn\": \"directory does not exist\",\r\n \"view_warn\": \"file don't not exist\"\r\n },\r\n \"time\": {\r\n \"invalidTimeZone1\": \"Invalid time zone:\",\r\n \"invalidTimeZone2\": \"Using system default time zone.\"\r\n }\r\n}","{\r\n \"logger\": {\r\n \"levels\": {\r\n \"log\": \"log\",\r\n \"info\": \"info\",\r\n \"warning\": \"advertencia\",\r\n \"error\": \"error\",\r\n \"debug\": \"depuración\"\r\n }\r\n },\r\n \"server\": {\r\n \"name\": \"servidor\",\r\n \"start\": \"Servidor corriendo en\",\r\n \"routers_loaded\": \"rutas cargadas\",\r\n \"crons_loaded\": \"crons cargados\",\r\n \"socket_loaded\": \"socket cargado\",\r\n \"static_loaded\": \"carpetas estaticas cargadas\",\r\n \"views_loaded\": \"carpetas de vistas cargadas\",\r\n\r\n \"static_warn\": \"no existe el directorio\",\r\n \"view_warn\": \"no existe el archivo\"\r\n },\r\n \"time\": {\r\n \"invalidTimeZone1\": \"Zona horaria inválida:\",\r\n \"invalidTimeZone2\": \"Usando la zona horaria predeterminada del sistema.\"\r\n }\r\n}","import en from \"../locales/en.json\" with { type: \"json\" };\r\nimport es from \"../locales/es.json\" with { type: \"json\" };\r\n\r\ntype Locale = typeof en;\r\n\r\nconst locales = {\r\n en,\r\n es,\r\n} satisfies Record<string, Locale>;\r\n\r\ntype Language = keyof typeof locales;\r\ntype TranslationKey = keyof Locale;\r\n\r\nfunction translate<K extends TranslationKey>(\r\n language: Language,\r\n key: K\r\n): Locale[K] {\r\n return locales[language][key];\r\n}\r\n\r\nexport {\r\n translate,\r\n};\r\n","import type { RequestHandler, Router as RouterType } from \"express\";\r\nimport { Router as ExpressRouter } from \"express\";\r\n\r\ntype HttpMethod =\r\n | \"get\"\r\n | \"post\"\r\n | \"put\"\r\n | \"patch\"\r\n | \"delete\"\r\n | \"options\"\r\n | \"head\"\r\n | \"all\";\r\n\r\nclass QuikRouter {\r\n readonly router: RouterType;\r\n private pendingMiddleware: RequestHandler[] = [];\r\n private currentPath: string = \"\";\r\n\r\n constructor() {\r\n this.router = ExpressRouter();\r\n }\r\n\r\n middleware(...handlers: RequestHandler[]) {\r\n this.pendingMiddleware.push(...handlers);\r\n return this;\r\n }\r\n\r\n path(path: string) {\r\n this.currentPath = path;\r\n return this;\r\n }\r\n\r\n private register (\r\n method: HttpMethod,\r\n handler: RequestHandler\r\n ) {\r\n this.router[method](\r\n this.currentPath,\r\n ...this.pendingMiddleware,\r\n async (req, res, next) => {\r\n try {\r\n await handler(req, res, next);\r\n } catch (err) {\r\n next(err);\r\n }\r\n }\r\n );\r\n\r\n this.pendingMiddleware = [];\r\n this.currentPath = \"\";\r\n\r\n return this;\r\n }\r\n\r\n get(handler: RequestHandler) {\r\n return this.register(\"get\", handler);\r\n }\r\n\r\n post(handler: RequestHandler) {\r\n return this.register(\"post\", handler);\r\n }\r\n\r\n put(handler: RequestHandler) {\r\n return this.register(\"put\", handler);\r\n }\r\n\r\n patch(handler: RequestHandler) {\r\n return this.register(\"patch\", handler);\r\n }\r\n\r\n delete(handler: RequestHandler) {\r\n return this.register(\"delete\", handler);\r\n }\r\n \r\n}\r\n\r\nfunction Router() {\r\n return new QuikRouter;\r\n}\r\n\r\nexport { QuikRouter, Router };","import express, { type ErrorRequestHandler, type Express, type RequestHandler } from \"express\";\r\nimport http, { type Server as HTTPServer } from \"node:http\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs\";\r\n\r\nimport { QuikRouter } from \"./router.js\";\r\nimport { logger } from \"./logger.js\";\r\nimport { translate } from \"./translator.js\";\r\nimport { isValidTimeZone } from \"./time.js\";\r\nimport { QuikCron } from \"../cron/cron.js\";\r\n\r\n\r\nimport { ServerInvalidCronError, ServerInvalidRouteError, ServerInvalidSocketIOError, ServerInvalidWebSocketError } from \"./errors/serverErrors.js\";\r\nimport { QuikNotFoundHandler } from \"./handlers/notFoundHandler.js\";\r\nimport { QuikErrorHandler } from \"./handlers/httpErrorHandler.js\";\r\nimport type { QuikSocketIO } from \"../socket.io/socket.js\";\r\nimport type { QuikWebSocket } from \"../ws/websockets.js\";\r\n\r\ntype JsonOptions = Parameters<typeof express.json>[0];\r\ntype UrlencodedOptions = Parameters<typeof express.urlencoded>[0];\r\ntype RawOptions = Parameters<typeof express.raw>[0];\r\ntype TextOptions = Parameters<typeof express.text>[0];\r\ntype BodyParserConfig =\r\n | {\r\n type: \"json\";\r\n options?: JsonOptions;\r\n }\r\n | {\r\n type: \"urlencoded\";\r\n options?: UrlencodedOptions;\r\n }\r\n | {\r\n type: \"raw\";\r\n options?: RawOptions;\r\n }\r\n | {\r\n type: \"text\";\r\n options?: TextOptions;\r\n };\r\ntype HTTPConfig = {\r\n port: number;\r\n host?: string;\r\n\r\n keepAlive?: number;\r\n timeout?: number;\r\n maxConnections?: number;\r\n shutdownTimeout?: number;\r\n};\r\n\r\ntype ExpressConfig = {\r\n name?: string;\r\n env?: string;\r\n trustProxy?: boolean;\r\n viewEngine?: string;\r\n};\r\ntype QuikServerConfig = {\r\n language: Language,\r\n timeZone?: string;\r\n bodyParser: BodyParserConfig;\r\n http: HTTPConfig;\r\n express: ExpressConfig;\r\n};\r\ntype RoutingDict = Record<string, QuikRouter>;\r\n\r\nconst defaultConfig: QuikServerConfig = {\r\n language: \"en\",\r\n bodyParser: {\r\n type: \"json\"\r\n },\r\n\r\n http: {\r\n port: 8080\r\n },\r\n\r\n express: {}\r\n}\r\nconst defaultNotFoundHandler = QuikNotFoundHandler;\r\nconst defaultErrorHandler = QuikErrorHandler;\r\n\r\nclass QuikServer {\r\n app: Express;\r\n httpServer: HTTPServer;\r\n\r\n middlewares: RequestHandler[] = [];\r\n routes: RoutingDict = {};\r\n staticDirs: string[] = [];\r\n crons: QuikCron[] = [];\r\n ws: QuikWebSocket | QuikSocketIO | undefined;\r\n viewDirs: string[] = [];\r\n\r\n notFoundHandler: RequestHandler | undefined;\r\n errorHandler: ErrorRequestHandler | undefined;\r\n\r\n\r\n config: QuikServerConfig;\r\n\r\n constructor() {\r\n this.app = express();\r\n this.config = structuredClone(defaultConfig);\r\n this.httpServer = http.createServer(\r\n this.app\r\n );\r\n\r\n this.ws = undefined;\r\n\r\n this.notFoundHandler = defaultNotFoundHandler;\r\n this.errorHandler = defaultErrorHandler;\r\n }\r\n\r\n\r\n setConfig(config: Partial<QuikServerConfig>) {\r\n this.config = {\r\n ...this.config,\r\n ...config,\r\n http: {\r\n ...this.config.http,\r\n ...config.http\r\n },\r\n express: {\r\n ...this.config.express,\r\n ...config.express\r\n }\r\n };\r\n\r\n // Notify if the provided time zone is invalid\r\n if (config.timeZone && !isValidTimeZone(config.timeZone)) {\r\n const messages = translate(this.config.language, \"time\");\r\n\r\n logger.warning(\r\n `${messages.invalidTimeZone1} ${config.timeZone}. ${messages.invalidTimeZone2}`\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n setNotFoundHandler(handler: RequestHandler | null) {\r\n if (!handler) {\r\n this.notFoundHandler = undefined;\r\n return this;\r\n }\r\n this.notFoundHandler = handler;\r\n\r\n return this;\r\n }\r\n\r\n setErrorHandler(handler: ErrorRequestHandler | null) {\r\n if (!handler) {\r\n this.errorHandler = undefined;\r\n return this;\r\n }\r\n this.errorHandler = handler;\r\n\r\n return this;\r\n }\r\n\r\n addMiddleware(...middlewares: RequestHandler[]) {\r\n this.middlewares.push(\r\n ...middlewares\r\n );\r\n\r\n return this;\r\n }\r\n\r\n addRoute(path: string, router: QuikRouter) {\r\n if (!(router instanceof QuikRouter)) {\r\n throw new ServerInvalidRouteError(path)\r\n }\r\n\r\n if (!path.startsWith(\"/\"))\r\n path = \"/\" + path;\r\n\r\n this.routes[path] = router;\r\n\r\n return this;\r\n }\r\n\r\n\r\n addViewDir(...paths: string[]) {\r\n for (const view of paths) {\r\n const viewPath = path.resolve(view);\r\n\r\n if (!fs.existsSync(viewPath)) {\r\n const messages = translate(this.config.language, \"server\");\r\n\r\n logger.warning(\r\n `[ VIEW ] \"${view}\" ${messages.view_warn}`\r\n );\r\n\r\n continue;\r\n }\r\n\r\n this.viewDirs.push(viewPath);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n addCron(cron: QuikCron) {\r\n if (cron.constructor.name != \"QuikCron\") {\r\n throw new ServerInvalidCronError()\r\n }\r\n this.crons.push(cron);\r\n\r\n return this;\r\n }\r\n\r\n useWebSocket(ws: QuikWebSocket) {\r\n if (ws.constructor.name != \"QuikWebSocket\") {\r\n throw new ServerInvalidWebSocketError()\r\n }\r\n this.ws = ws;\r\n return this;\r\n }\r\n\r\n useSocketIO(socket: QuikSocketIO) {\r\n if (socket?.constructor.name != \"QuikSocketIO\") {\r\n throw new ServerInvalidSocketIOError()\r\n }\r\n this.ws = socket;\r\n\r\n return this;\r\n }\r\n\r\n addStaticDir(...paths: string[]) {\r\n for (const dir of paths) {\r\n const dirPath = path.resolve(dir);\r\n\r\n if (!fs.existsSync(dirPath)) {\r\n const messages = translate(this.config.language, \"server\");\r\n logger.warning(\r\n `[ STATIC ] \"${dir}\" ${messages.static_warn}`\r\n );\r\n\r\n continue;\r\n }\r\n\r\n this.staticDirs.push(dirPath);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #configureExpress() {\r\n const config = this.config.express;\r\n const { name, env, trustProxy, viewEngine } = config;\r\n\r\n if (trustProxy) {\r\n this.app.set(\r\n \"trust proxy\",\r\n config.trustProxy\r\n );\r\n }\r\n\r\n if (env) {\r\n this.app.set(\"env\", config.env);\r\n }\r\n\r\n if (name) {\r\n this.app.set(\"name\", name);\r\n }\r\n\r\n if (viewEngine) {\r\n this.app.set(\"view engine\", viewEngine);\r\n }\r\n\r\n if (this.viewDirs.length > 0) {\r\n const messages = translate(this.config.language, \"server\")\r\n logger.info(`[ VIEWS ] ${this.viewDirs.length} ${messages.views_loaded}.`)\r\n this.app.set(\"views\", this.viewDirs);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #configureMiddleware() {\r\n const bodyParser = this.config.bodyParser;\r\n\r\n switch (bodyParser.type) {\r\n case \"json\":\r\n this.app.use(\r\n express.json(bodyParser.options)\r\n );\r\n break;\r\n\r\n\r\n case \"urlencoded\":\r\n this.app.use(\r\n express.urlencoded(bodyParser.options)\r\n );\r\n break;\r\n\r\n\r\n case \"raw\":\r\n this.app.use(\r\n express.raw(bodyParser.options)\r\n );\r\n break;\r\n\r\n\r\n case \"text\":\r\n this.app.use(\r\n express.text(bodyParser.options)\r\n );\r\n break;\r\n\r\n }\r\n\r\n if (this.middlewares.length > 0)\r\n this.app.use(...this.middlewares);\r\n\r\n return this;\r\n }\r\n\r\n #loadRoutes() {\r\n for (const [path, router] of Object.entries(this.routes)) {\r\n this.app.use(\r\n path,\r\n router.router\r\n );\r\n }\r\n const messages = translate(this.config.language, \"server\");\r\n if (Object.entries(this.routes).length > 0) {\r\n logger.info(`[ ROUTER ] ${Object.entries(this.routes).length} ${messages.routers_loaded}.`);\r\n }\r\n return this;\r\n }\r\n\r\n #loadCrons() {\r\n for (const cron of this.crons) {\r\n cron.start();\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.crons.length > 0) {\r\n logger.info(`[ CRON ] ${this.crons.length} ${messages.crons_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadWS() {\r\n if (this.ws) {\r\n this.ws.start(this.httpServer);\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.ws) {\r\n logger.info(`[ SOCKET ] ${messages.socket_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadStaticDirs() {\r\n for (const dir of this.staticDirs) {\r\n const dirPath = path.resolve(dir);\r\n\r\n this.app.use(express.static(dirPath));\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.staticDirs.length > 0) {\r\n logger.info(`[ STATIC ] ${this.staticDirs.length} ${messages.static_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadHandlers() {\r\n if (this.notFoundHandler) {\r\n this.app.use(\r\n this.notFoundHandler\r\n );\r\n }\r\n\r\n if (this.errorHandler) {\r\n this.app.use(\r\n this.errorHandler\r\n );\r\n }\r\n }\r\n\r\n #configureHTTP() {\r\n const config = this.config.http;\r\n\r\n if (config.timeout)\r\n this.httpServer.timeout = config.timeout;\r\n\r\n if (config.keepAlive)\r\n this.httpServer.keepAliveTimeout = config.keepAlive;\r\n\r\n if (config.maxConnections)\r\n this.httpServer.maxConnections = config.maxConnections;\r\n\r\n return this;\r\n }\r\n\r\n #listen() {\r\n const { port, host } = this.config.http;\r\n const messages = translate(this.config.language, \"server\");\r\n\r\n this.httpServer.listen(port, host, () => {\r\n logger.info(`${messages.start} ${host ?? \"localhost\"}:${port}`);\r\n }\r\n );\r\n\r\n return this;\r\n }\r\n\r\n start() {\r\n this.#configureExpress();\r\n this.#configureMiddleware();\r\n\r\n this.#loadStaticDirs()\r\n this.#loadRoutes();\r\n this.#loadHandlers();\r\n this.#loadCrons();\r\n this.#loadWS();\r\n\r\n this.#configureHTTP();\r\n\r\n this.#listen();\r\n return this;\r\n }\r\n}\r\n\r\nfunction Server() {\r\n return new QuikServer();\r\n}\r\n\r\nexport {\r\n Server\r\n};\r\n","import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","const Status = {\r\n // 1xx Informational\r\n CONTINUE: 100,\r\n SWITCHING_PROTOCOLS: 101,\r\n PROCESSING: 102,\r\n EARLY_HINTS: 103,\r\n\r\n // 2xx Success\r\n OK: 200,\r\n CREATED: 201,\r\n ACCEPTED: 202,\r\n NON_AUTHORITATIVE_INFORMATION: 203,\r\n NO_CONTENT: 204,\r\n RESET_CONTENT: 205,\r\n PARTIAL_CONTENT: 206,\r\n MULTI_STATUS: 207,\r\n ALREADY_REPORTED: 208,\r\n IM_USED: 226,\r\n\r\n // 3xx Redirection\r\n MULTIPLE_CHOICES: 300,\r\n MOVED_PERMANENTLY: 301,\r\n FOUND: 302,\r\n SEE_OTHER: 303,\r\n NOT_MODIFIED: 304,\r\n TEMPORARY_REDIRECT: 307,\r\n PERMANENT_REDIRECT: 308,\r\n\r\n // 4xx Client Errors\r\n BAD_REQUEST: 400,\r\n UNAUTHORIZED: 401,\r\n PAYMENT_REQUIRED: 402,\r\n FORBIDDEN: 403,\r\n NOT_FOUND: 404,\r\n METHOD_NOT_ALLOWED: 405,\r\n NOT_ACCEPTABLE: 406,\r\n PROXY_AUTHENTICATION_REQUIRED: 407,\r\n REQUEST_TIMEOUT: 408,\r\n CONFLICT: 409,\r\n GONE: 410,\r\n LENGTH_REQUIRED: 411,\r\n PRECONDITION_FAILED: 412,\r\n PAYLOAD_TOO_LARGE: 413,\r\n URI_TOO_LONG: 414,\r\n UNSUPPORTED_MEDIA_TYPE: 415,\r\n RANGE_NOT_SATISFIABLE: 416,\r\n EXPECTATION_FAILED: 417,\r\n IM_A_TEAPOT: 418,\r\n MISDIRECTED_REQUEST: 421,\r\n UNPROCESSABLE_CONTENT: 422,\r\n LOCKED: 423,\r\n FAILED_DEPENDENCY: 424,\r\n UPGRADE_REQUIRED: 426,\r\n PRECONDITION_REQUIRED: 428,\r\n TOO_MANY_REQUESTS: 429,\r\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\r\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\r\n\r\n // 5xx Server Errors\r\n INTERNAL_SERVER_ERROR: 500,\r\n NOT_IMPLEMENTED: 501,\r\n BAD_GATEWAY: 502,\r\n SERVICE_UNAVAILABLE: 503,\r\n GATEWAY_TIMEOUT: 504,\r\n HTTP_VERSION_NOT_SUPPORTED: 505,\r\n VARIANT_ALSO_NEGOTIATES: 506,\r\n INSUFFICIENT_STORAGE: 507,\r\n LOOP_DETECTED: 508,\r\n NOT_EXTENDED: 510,\r\n NETWORK_AUTHENTICATION_REQUIRED: 511\r\n} as const;\r\n\r\nexport {\r\n Status\r\n};","import type { RequestHandler } from \"express\";\r\nimport { Status } from \"../../http/index.js\";\r\n\r\nexport const QuikNotFoundHandler: RequestHandler = (req, res) => {\r\n res.status(Status.NOT_FOUND).json({\r\n error: \"Not Found\",\r\n message: `Route ${req.method} ${req.originalUrl} not found`\r\n });\r\n};","import type { ErrorRequestHandler, Request, Response, Errback } from \"express\";\r\nimport { logger } from \"../logger.js\";\r\nimport { Status } from \"../../http/index.js\";\r\n\r\nexport const QuikErrorHandler: ErrorRequestHandler = (err, req, res, next) => {\r\n logger.error(err);\r\n\r\n if (res.headersSent) {\r\n return next(err);\r\n }\r\n\r\n res.status(Status.INTERNAL_SERVER_ERROR).json({\r\n error: \"Internal Server Error\"\r\n });\r\n};"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAM,0BAAN,cAAsC,MAAM;AAAA,EACxC,YAAYA,OAAc;AACtB,UAAM,IAAIA,KAAI,iCAAiC;AAAA,EACnD;AACJ;AAEA,IAAM,yBAAN,cAAqC,MAAM;AAAA,EACvC,cAAc;AACV,UAAM,8CAA8C;AAAA,EACxD;AACJ;AAEA,IAAM,8BAAN,cAA0C,MAAM;AAAA,EAC5C,cAAc;AACV,UAAM,mDAAmD;AAAA,EAC7D;AACJ;AAEA,IAAM,6BAAN,cAAyC,MAAM;AAAA,EAC3C,cAAc;AACV,UAAM,kDAAkD;AAAA,EAC5D;AACJ;;;ACtBA,qBAAe;AACf,uBAAiB;;;ACDjB,IAAM,QAAQ;AAAA,EACZ,OAAO;AAAA,EAEP,OAAO;AAAA,EACP,KAAK;AAAA,EACL,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,OAAO;AAAA,EAEP,MAAM;AAAA,EACN,WAAW;AACb;AAIA,IAAM,SAAS,OAAO;AAAA,EACpB,OAAO,QAAQ,KAAK,EACjB,OAAO,CAAC,CAAC,GAAG,MAAM,QAAQ,OAAO,EACjC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AAAA,IACrB;AAAA,IACA,CAAC,SAAiB,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,KAAK;AAAA,EACjD,CAAC;AACL;;;ACzBA,SAAS,aAAa,MAAY,QAAgB,UAA2B;AACzE,QAAM,YAAY,IAAI,KAAK,eAAe,SAAS;AAAA,IAC/C;AAAA,IACA,MAAM;AAAA,IACN,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,WAAW;AAAA,EACf,CAAC;AAED,QAAM,QAAQ,UAAU,cAAc,IAAI;AAC1C,QAAM,SAAS,OAAO;AAAA,IAClB,MACK,OAAO,CAAC,EAAE,KAAK,MAAM,SAAS,SAAS,EACvC,IAAI,CAAC,EAAE,MAAM,MAAM,MAAM,CAAC,MAAM,KAAK,CAAC;AAAA,EAC/C;AAEA,SAAO,OAAO,QAAQ,0BAA0B,CAAC,UAAkB;AAC/D,YAAQ,OAAO;AAAA,MACX,KAAK;AACD,eAAO,OAAO,QAAQ;AAAA,MAC1B,KAAK;AACD,eAAO,OAAO,SAAS;AAAA,MAC3B,KAAK;AACD,eAAO,OAAO,OAAO;AAAA,MACzB,KAAK;AACD,eAAO,OAAO,QAAQ;AAAA,MAC1B,KAAK;AACD,eAAO,OAAO,UAAU;AAAA,MAC5B,KAAK;AACD,eAAO,OAAO,UAAU;AAAA,MAC5B;AACI,eAAO;AAAA,IACf;AAAA,EACJ,CAAC;AACL;AAEA,SAAS,gBAAgB,UAA2B;AAChD,MAAI;AACA,QAAI,KAAK,eAAe,SAAS;AAAA,MAC7B;AAAA,IACJ,CAAC;AAED,WAAO;AAAA,EACX,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;;;ACjDA;AAAA,EACI,QAAU;AAAA,IACN,QAAU;AAAA,MACN,KAAO;AAAA,MACP,MAAQ;AAAA,MACR,SAAW;AAAA,MACX,OAAS;AAAA,MACT,OAAS;AAAA,IACb;AAAA,EACJ;AAAA,EACA,QAAU;AAAA,IACN,MAAQ;AAAA,IACR,OAAS;AAAA,IACT,gBAAkB;AAAA,IAClB,cAAgB;AAAA,IAChB,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,cAAgB;AAAA,IAEhB,aAAe;AAAA,IACf,WAAa;AAAA,EACjB;AAAA,EACA,MAAQ;AAAA,IACJ,kBAAoB;AAAA,IACpB,kBAAoB;AAAA,EACxB;AACJ;;;AC1BA;AAAA,EACI,QAAU;AAAA,IACN,QAAU;AAAA,MACN,KAAO;AAAA,MACP,MAAQ;AAAA,MACR,SAAW;AAAA,MACX,OAAS;AAAA,MACT,OAAS;AAAA,IACb;AAAA,EACJ;AAAA,EACA,QAAU;AAAA,IACN,MAAQ;AAAA,IACR,OAAS;AAAA,IACT,gBAAkB;AAAA,IAClB,cAAgB;AAAA,IAChB,eAAiB;AAAA,IACjB,eAAiB;AAAA,IACjB,cAAgB;AAAA,IAEhB,aAAe;AAAA,IACf,WAAa;AAAA,EACjB;AAAA,EACA,MAAQ;AAAA,IACJ,kBAAoB;AAAA,IACpB,kBAAoB;AAAA,EACxB;AACJ;;;ACrBA,IAAM,UAAU;AAAA,EACZ;AAAA,EACA;AACJ;AAKA,SAAS,UACL,UACA,KACS;AACT,SAAO,QAAQ,QAAQ,EAAE,GAAG;AAChC;;;ALoCA,IAAM,gBAA8B;AAAA,EAChC,UAAU;AAAA,EACV,MAAM;AAAA,IACF,aAAa;AAAA,IACb,cAAc;AAAA,IACd,eAAe;AAAA,IACf,iBAAiB;AAAA,EACrB;AAAA,EACA,OAAO;AAAA,IACH,UAAU;AAAA,IACV,WAAW;AAAA,IACX,YAAY;AAAA,IACZ,cAAc;AAAA,IACd,YAAY;AAAA,EAChB;AAAA,EACA,QAAQ;AAAA,IACJ,iBAAiB;AAAA,IACjB,WAAW;AAAA,EACf;AACJ;AAEA,IAAI,SAAS,gBAAgB,aAAa;AAE1C,SAAS,YAAY,MAA2B;AAC5C,SAAO,KAAK,IAAI,SAAO;AACnB,QAAI,OAAO,QAAQ,SAAU,QAAO;AAEpC,QAAI,eAAe,OAAO;AACtB,aAAO,IAAI,SAAS,IAAI;AAAA,IAC5B;AAEA,QAAI,QAAQ,QAAQ,QAAQ,QAAW;AACnC,aAAO,OAAO,GAAG;AAAA,IACrB;AAEA,QAAI,OAAO,QAAQ,UAAU;AACzB,UAAI;AACA,eAAO,KAAK,UAAU,GAAG;AAAA,MAC7B,QAAQ;AACJ,eAAO;AAAA,MACX;AAAA,IACJ;AAEA,WAAO,OAAO,GAAG;AAAA,EACrB,CAAC;AACL;AAEA,SAAS,MACL,OACAC,QACA,SACG,SACL;AACE,QAAM,CAAC,QAAQ,IAAI,IAAI,aAAa,OAAO,GAAG,OAAO;AACrD,aAAW,MAAM,SAAS,IAAI;AAE9B,QAAM,SAAS,OAAO,OAAO,UAAU;AACvC,QAAM,SAAS,OAAO,OAAO,UAAU;AAEvC,MAAIA,QAAO;AACP,UAAM,UAAU,OAAOA,MAAK,MAAM,CAAC,MAAc;AACjD,YAAQ,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,IAAI,CAAC,GAAG,MAAM,EAAE;AAAA,EAC7D,OAAO;AACH,YAAQ,IAAI,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,EAAE;AAAA,EACpD;AACJ;AAEA,SAAS,aAAa,UAAkB,MAAmC;AACvE,MAAI,SAAS;AACb,MAAI,OAAO,OAAO,iBAAiB;AAC/B,UAAM,MAAM,oBAAI,KAAK;AACrB,UAAM,WAAW,OAAO,OAAO;AAC/B,QAAI,KAAK;AAET,QAAI,YAAY,CAAC,gBAAgB,QAAQ,GAAG;AACxC,WAAK;AAAA,IACT;AAEA,UAAM,YAAY;AAAA,MACd;AAAA,MACA,OAAO,OAAO;AAAA,MACd;AAAA,IACJ;AAEA,cAAU,GAAG,SAAS;AAAA,EAC1B;AAEA,UAAQ,OAAO,OAAO,WAAW;AAAA,IAC7B,KAAK;AACD,cAAQ,IAAI,MAAM,YAAY,CAAC;AAC/B;AAAA,IACJ,KAAK;AACD,cAAQ,IAAI,MAAM,kBAAkB,CAAC;AACrC;AAAA,IACJ,KAAK;AACD,cAAQ,IAAI,MAAM,OAAO,CAAC,EAAE,YAAY,IAAI,MAAM,MAAM,CAAC,EAAE,YAAY,CAAC;AACxE;AAAA,IACJ,KAAK;AACD,cAAQ,IAAI,KAAK;AACjB;AAAA,IACJ;AACI,cAAQ;AACR;AAAA,EACR;AACA,MAAI,UAAU,QAAQ,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG;AAChD,SAAO,CAAC,QAAQ,OAAO;AAC3B;AAEA,SAAS,WAAW,UAAuB,SAAuB;AAC9D,MAAI,CAAC,YAAY,CAAC,QAAQ,OAAQ;AAElC,QAAM,MAAM,iBAAAC,QAAK,QAAQ,QAAQ;AACjC,QAAM,aAAa,UAAU;AAE7B,iBAAAC,QAAG,UAAU,KAAK,EAAE,WAAW,KAAK,CAAC;AACrC,iBAAAA,QAAG,eAAe,UAAU,UAAU;AAC1C;AAEA,SAAS,YACL,SACA,QACY;AACZ,SAAO;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,MAAM;AAAA,MACF,GAAG,QAAQ;AAAA,MACX,GAAG,OAAO;AAAA,IACd;AAAA,IACA,OAAO;AAAA,MACH,GAAG,QAAQ;AAAA,MACX,GAAG,OAAO;AAAA,IACd;AAAA,IACA,QAAQ;AAAA,MACJ,GAAG,QAAQ;AAAA,MACX,GAAG,OAAO;AAAA,IACd;AAAA,EACJ;AACJ;AAEO,IAAM,SAAS;AAAA;AAAA,EAElB,UAAU,WAAgC;AACtC,aAAS,YAAY,QAAQ,SAAS;AAAA,EAC1C;AAAA;AAAA,EAGA,SAAiC;AAC7B,WAAO,OAAO,OAAO,gBAAgB,MAAM,CAAC;AAAA,EAChD;AAAA,EAEA,OAAO,SAAoB;AACvB,UAAM,WAAW,UAAU,OAAO,UAAU,QAAQ;AACpD;AAAA,MACI,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,QAAQ,SAAoB;AACxB,UAAM,WAAW,UAAU,OAAO,UAAU,QAAQ;AACpD;AAAA,MACI,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,SAAS,SAAoB;AACzB,UAAM,WAAW,UAAU,OAAO,UAAU,QAAQ;AACpD;AAAA,MACI,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,WAAW,SAAoB;AAC3B,UAAM,WAAW,UAAU,OAAO,UAAU,QAAQ;AACpD;AAAA,MACI,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb,OAAO,KAAK;AAAA,MACZ,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,SAAS,SAAoB;AACzB,UAAM,WAAW,UAAU,OAAO,UAAU,QAAQ;AACpD;AAAA,MACI,SAAS,OAAO;AAAA,MAChB,OAAO,MAAM;AAAA,MACb;AAAA,MACA,GAAG;AAAA,IACP;AAAA,EACJ;AAAA,EAEA,QAAQ;AACJ,YAAQ,MAAM;AAAA,EAClB;AAAA,EAEA,OACI,OACAF,QACA,SACG,SACL;AACE,UAAM,OAAOA,QAAO,MAAM,GAAG,OAAO;AAAA,EACxC;AACJ;;;AM1QA,qBAAwC;AAYxC,IAAM,aAAN,MAAiB;AAAA,EACJ;AAAA,EACD,oBAAsC,CAAC;AAAA,EACvC,cAAsB;AAAA,EAE9B,cAAc;AACV,SAAK,aAAS,eAAAG,QAAc;AAAA,EAChC;AAAA,EAEA,cAAc,UAA4B;AACtC,SAAK,kBAAkB,KAAK,GAAG,QAAQ;AACvC,WAAO;AAAA,EACX;AAAA,EAEA,KAAKC,OAAc;AACf,SAAK,cAAcA;AACnB,WAAO;AAAA,EACX;AAAA,EAEQ,SACJ,QACA,SACF;AACE,SAAK,OAAO,MAAM;AAAA,MACd,KAAK;AAAA,MACL,GAAG,KAAK;AAAA,MACR,OAAO,KAAK,KAAK,SAAS;AACtB,YAAI;AACA,gBAAM,QAAQ,KAAK,KAAK,IAAI;AAAA,QAChC,SAAS,KAAK;AACV,eAAK,GAAG;AAAA,QACZ;AAAA,MACJ;AAAA,IACJ;AAEA,SAAK,oBAAoB,CAAC;AAC1B,SAAK,cAAc;AAEnB,WAAO;AAAA,EACX;AAAA,EAEA,IAAI,SAAyB;AACzB,WAAO,KAAK,SAAS,OAAO,OAAO;AAAA,EACvC;AAAA,EAEA,KAAK,SAAyB;AAC1B,WAAO,KAAK,SAAS,QAAQ,OAAO;AAAA,EACxC;AAAA,EAEA,IAAI,SAAyB;AACzB,WAAO,KAAK,SAAS,OAAO,OAAO;AAAA,EACvC;AAAA,EAEA,MAAM,SAAyB;AAC3B,WAAO,KAAK,SAAS,SAAS,OAAO;AAAA,EACzC;AAAA,EAEA,OAAO,SAAyB;AAC5B,WAAO,KAAK,SAAS,UAAU,OAAO;AAAA,EAC1C;AAEJ;AAEA,SAAS,SAAS;AACd,SAAO,IAAI;AACf;;;AC9EA,IAAAC,kBAAqF;AACrF,uBAAgD;AAChD,IAAAC,oBAAiB;AACjB,IAAAC,kBAAe;;;ACHf,uBAAiB;AACjB,IAAAC,oBAAmC;;;ACDnC,IAAM,SAAS;AAAA;AAAA,EAEX,UAAU;AAAA,EACV,qBAAqB;AAAA,EACrB,YAAY;AAAA,EACZ,aAAa;AAAA;AAAA,EAGb,IAAI;AAAA,EACJ,SAAS;AAAA,EACT,UAAU;AAAA,EACV,+BAA+B;AAAA,EAC/B,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,SAAS;AAAA;AAAA,EAGT,kBAAkB;AAAA,EAClB,mBAAmB;AAAA,EACnB,OAAO;AAAA,EACP,WAAW;AAAA,EACX,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,oBAAoB;AAAA;AAAA,EAGpB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,WAAW;AAAA,EACX,oBAAoB;AAAA,EACpB,gBAAgB;AAAA,EAChB,+BAA+B;AAAA,EAC/B,iBAAiB;AAAA,EACjB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,uBAAuB;AAAA,EACvB,QAAQ;AAAA,EACR,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,mBAAmB;AAAA,EACnB,iCAAiC;AAAA,EACjC,+BAA+B;AAAA;AAAA,EAG/B,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,qBAAqB;AAAA,EACrB,iBAAiB;AAAA,EACjB,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,sBAAsB;AAAA,EACtB,eAAe;AAAA,EACf,cAAc;AAAA,EACd,iCAAiC;AACrC;;;ACnEO,IAAM,sBAAsC,CAAC,KAAK,QAAQ;AAC7D,MAAI,OAAO,OAAO,SAAS,EAAE,KAAK;AAAA,IAC9B,OAAO;AAAA,IACP,SAAS,SAAS,IAAI,MAAM,IAAI,IAAI,WAAW;AAAA,EACnD,CAAC;AACL;;;ACJO,IAAM,mBAAwC,CAAC,KAAK,KAAK,KAAK,SAAS;AAC1E,SAAO,MAAM,GAAG;AAEhB,MAAI,IAAI,aAAa;AACjB,WAAO,KAAK,GAAG;AAAA,EACnB;AAEA,MAAI,OAAO,OAAO,qBAAqB,EAAE,KAAK;AAAA,IAC1C,OAAO;AAAA,EACX,CAAC;AACL;;;AJkDA,IAAMC,iBAAkC;AAAA,EACpC,UAAU;AAAA,EACV,YAAY;AAAA,IACR,MAAM;AAAA,EACV;AAAA,EAEA,MAAM;AAAA,IACF,MAAM;AAAA,EACV;AAAA,EAEA,SAAS,CAAC;AACd;AACA,IAAM,yBAAyB;AAC/B,IAAM,sBAAsB;AAE5B,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA;AAAA,EAEA,cAAgC,CAAC;AAAA,EACjC,SAAsB,CAAC;AAAA,EACvB,aAAuB,CAAC;AAAA,EACxB,QAAoB,CAAC;AAAA,EACrB;AAAA,EACA,WAAqB,CAAC;AAAA,EAEtB;AAAA,EACA;AAAA,EAGA;AAAA,EAEA,cAAc;AACV,SAAK,UAAM,gBAAAC,SAAQ;AACnB,SAAK,SAAS,gBAAgBD,cAAa;AAC3C,SAAK,aAAa,iBAAAE,QAAK;AAAA,MACnB,KAAK;AAAA,IACT;AAEA,SAAK,KAAK;AAEV,SAAK,kBAAkB;AACvB,SAAK,eAAe;AAAA,EACxB;AAAA,EAGA,UAAUC,SAAmC;AACzC,SAAK,SAAS;AAAA,MACV,GAAG,KAAK;AAAA,MACR,GAAGA;AAAA,MACH,MAAM;AAAA,QACF,GAAG,KAAK,OAAO;AAAA,QACf,GAAGA,QAAO;AAAA,MACd;AAAA,MACA,SAAS;AAAA,QACL,GAAG,KAAK,OAAO;AAAA,QACf,GAAGA,QAAO;AAAA,MACd;AAAA,IACJ;AAGA,QAAIA,QAAO,YAAY,CAAC,gBAAgBA,QAAO,QAAQ,GAAG;AACtD,YAAM,WAAW,UAAU,KAAK,OAAO,UAAU,MAAM;AAEvD,aAAO;AAAA,QACH,GAAG,SAAS,gBAAgB,IAAIA,QAAO,QAAQ,KAAK,SAAS,gBAAgB;AAAA,MACjF;AAAA,IACJ;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,mBAAmB,SAAgC;AAC/C,QAAI,CAAC,SAAS;AACV,WAAK,kBAAkB;AACvB,aAAO;AAAA,IACX;AACA,SAAK,kBAAkB;AAEvB,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,SAAqC;AACjD,QAAI,CAAC,SAAS;AACV,WAAK,eAAe;AACpB,aAAO;AAAA,IACX;AACA,SAAK,eAAe;AAEpB,WAAO;AAAA,EACX;AAAA,EAEA,iBAAiB,aAA+B;AAC5C,SAAK,YAAY;AAAA,MACb,GAAG;AAAA,IACP;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,SAASC,OAAc,QAAoB;AACvC,QAAI,EAAE,kBAAkB,aAAa;AACjC,YAAM,IAAI,wBAAwBA,KAAI;AAAA,IAC1C;AAEA,QAAI,CAACA,MAAK,WAAW,GAAG;AACpB,MAAAA,QAAO,MAAMA;AAEjB,SAAK,OAAOA,KAAI,IAAI;AAEpB,WAAO;AAAA,EACX;AAAA,EAGA,cAAc,OAAiB;AAC3B,eAAW,QAAQ,OAAO;AACtB,YAAM,WAAW,kBAAAA,QAAK,QAAQ,IAAI;AAElC,UAAI,CAAC,gBAAAC,QAAG,WAAW,QAAQ,GAAG;AAC1B,cAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AAEzD,eAAO;AAAA,UACH,aAAa,IAAI,KAAK,SAAS,SAAS;AAAA,QAC5C;AAEA;AAAA,MACJ;AAEA,WAAK,SAAS,KAAK,QAAQ;AAAA,IAC/B;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,QAAQC,OAAgB;AACpB,QAAIA,MAAK,YAAY,QAAQ,YAAY;AACrC,YAAM,IAAI,uBAAuB;AAAA,IACrC;AACA,SAAK,MAAM,KAAKA,KAAI;AAEpB,WAAO;AAAA,EACX;AAAA,EAEA,aAAa,IAAmB;AAC5B,QAAI,GAAG,YAAY,QAAQ,iBAAiB;AACxC,YAAM,IAAI,4BAA4B;AAAA,IAC1C;AACA,SAAK,KAAK;AACV,WAAO;AAAA,EACX;AAAA,EAEA,YAAY,QAAsB;AAC9B,QAAI,QAAQ,YAAY,QAAQ,gBAAgB;AAC5C,YAAM,IAAI,2BAA2B;AAAA,IACzC;AACA,SAAK,KAAK;AAEV,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB,OAAiB;AAC7B,eAAW,OAAO,OAAO;AACrB,YAAM,UAAU,kBAAAF,QAAK,QAAQ,GAAG;AAEhC,UAAI,CAAC,gBAAAC,QAAG,WAAW,OAAO,GAAG;AACzB,cAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,eAAO;AAAA,UACH,eAAe,GAAG,KAAK,SAAS,WAAW;AAAA,QAC/C;AAEA;AAAA,MACJ;AAEA,WAAK,WAAW,KAAK,OAAO;AAAA,IAChC;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,oBAAoB;AAChB,UAAMF,UAAS,KAAK,OAAO;AAC3B,UAAM,EAAE,MAAM,KAAK,YAAY,WAAW,IAAIA;AAE9C,QAAI,YAAY;AACZ,WAAK,IAAI;AAAA,QACL;AAAA,QACAA,QAAO;AAAA,MACX;AAAA,IACJ;AAEA,QAAI,KAAK;AACL,WAAK,IAAI,IAAI,OAAOA,QAAO,GAAG;AAAA,IAClC;AAEA,QAAI,MAAM;AACN,WAAK,IAAI,IAAI,QAAQ,IAAI;AAAA,IAC7B;AAEA,QAAI,YAAY;AACZ,WAAK,IAAI,IAAI,eAAe,UAAU;AAAA,IAC1C;AAEA,QAAI,KAAK,SAAS,SAAS,GAAG;AAC1B,YAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,aAAO,KAAK,eAAe,KAAK,SAAS,MAAM,IAAI,SAAS,YAAY,GAAG;AAC3E,WAAK,IAAI,IAAI,SAAS,KAAK,QAAQ;AAAA,IACvC;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,uBAAuB;AACnB,UAAM,aAAa,KAAK,OAAO;AAE/B,YAAQ,WAAW,MAAM;AAAA,MACrB,KAAK;AACD,aAAK,IAAI;AAAA,UACL,gBAAAF,QAAQ,KAAK,WAAW,OAAO;AAAA,QACnC;AACA;AAAA,MAGJ,KAAK;AACD,aAAK,IAAI;AAAA,UACL,gBAAAA,QAAQ,WAAW,WAAW,OAAO;AAAA,QACzC;AACA;AAAA,MAGJ,KAAK;AACD,aAAK,IAAI;AAAA,UACL,gBAAAA,QAAQ,IAAI,WAAW,OAAO;AAAA,QAClC;AACA;AAAA,MAGJ,KAAK;AACD,aAAK,IAAI;AAAA,UACL,gBAAAA,QAAQ,KAAK,WAAW,OAAO;AAAA,QACnC;AACA;AAAA,IAER;AAEA,QAAI,KAAK,YAAY,SAAS;AAC1B,WAAK,IAAI,IAAI,GAAG,KAAK,WAAW;AAEpC,WAAO;AAAA,EACX;AAAA,EAEA,cAAc;AACV,eAAW,CAACG,OAAM,MAAM,KAAK,OAAO,QAAQ,KAAK,MAAM,GAAG;AACtD,WAAK,IAAI;AAAA,QACLA;AAAA,QACA,OAAO;AAAA,MACX;AAAA,IACJ;AACA,UAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,QAAI,OAAO,QAAQ,KAAK,MAAM,EAAE,SAAS,GAAG;AACxC,aAAO,KAAK,cAAc,OAAO,QAAQ,KAAK,MAAM,EAAE,MAAM,IAAI,SAAS,cAAc,GAAG;AAAA,IAC9F;AACA,WAAO;AAAA,EACX;AAAA,EAEA,aAAa;AACT,eAAWE,SAAQ,KAAK,OAAO;AAC3B,MAAAA,MAAK,MAAM;AAAA,IACf;AAEA,UAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,QAAI,KAAK,MAAM,SAAS,GAAG;AACvB,aAAO,KAAK,cAAc,KAAK,MAAM,MAAM,IAAI,SAAS,YAAY,GAAG;AAAA,IAC3E;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,UAAU;AACN,QAAI,KAAK,IAAI;AACT,WAAK,GAAG,MAAM,KAAK,UAAU;AAAA,IACjC;AAEA,UAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,QAAI,KAAK,IAAI;AACT,aAAO,KAAK,cAAc,SAAS,aAAa,GAAG;AAAA,IACvD;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,kBAAkB;AACd,eAAW,OAAO,KAAK,YAAY;AAC/B,YAAM,UAAU,kBAAAF,QAAK,QAAQ,GAAG;AAEhC,WAAK,IAAI,IAAI,gBAAAH,QAAQ,OAAO,OAAO,CAAC;AAAA,IACxC;AAEA,UAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AACzD,QAAI,KAAK,WAAW,SAAS,GAAG;AAC5B,aAAO,KAAK,cAAc,KAAK,WAAW,MAAM,IAAI,SAAS,aAAa,GAAG;AAAA,IACjF;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,gBAAgB;AACZ,QAAI,KAAK,iBAAiB;AACtB,WAAK,IAAI;AAAA,QACL,KAAK;AAAA,MACT;AAAA,IACJ;AAEA,QAAI,KAAK,cAAc;AACnB,WAAK,IAAI;AAAA,QACL,KAAK;AAAA,MACT;AAAA,IACJ;AAAA,EACJ;AAAA,EAEA,iBAAiB;AACb,UAAME,UAAS,KAAK,OAAO;AAE3B,QAAIA,QAAO;AACP,WAAK,WAAW,UAAUA,QAAO;AAErC,QAAIA,QAAO;AACP,WAAK,WAAW,mBAAmBA,QAAO;AAE9C,QAAIA,QAAO;AACP,WAAK,WAAW,iBAAiBA,QAAO;AAE5C,WAAO;AAAA,EACX;AAAA,EAEA,UAAU;AACN,UAAM,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO;AACnC,UAAM,WAAW,UAAU,KAAK,OAAO,UAAU,QAAQ;AAEzD,SAAK,WAAW;AAAA,MAAO;AAAA,MAAM;AAAA,MAAM,MAAM;AACrC,eAAO,KAAK,GAAG,SAAS,KAAK,IAAI,QAAQ,WAAW,IAAI,IAAI,EAAE;AAAA,MAClE;AAAA,IACA;AAEA,WAAO;AAAA,EACX;AAAA,EAEA,QAAQ;AACJ,SAAK,kBAAkB;AACvB,SAAK,qBAAqB;AAE1B,SAAK,gBAAgB;AACrB,SAAK,YAAY;AACjB,SAAK,cAAc;AACnB,SAAK,WAAW;AAChB,SAAK,QAAQ;AAEb,SAAK,eAAe;AAEpB,SAAK,QAAQ;AACb,WAAO;AAAA,EACX;AACJ;AAEA,SAAS,SAAS;AACd,SAAO,IAAI,WAAW;AAC1B;","names":["path","color","path","fs","ExpressRouter","path","import_express","import_node_path","import_node_fs","import_node_cron","defaultConfig","express","http","config","path","fs","cron"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/core/errors/serverErrors.ts","../src/core/logger.ts","../src/core/colors.ts","../src/core/time.ts","../src/locales/en.json","../src/locales/es.json","../src/core/translator.ts","../src/core/router.ts","../src/core/server.ts","../src/cron/cron.ts","../src/http/status.ts","../src/core/handlers/notFoundHandler.ts","../src/core/handlers/httpErrorHandler.ts"],"sourcesContent":["export { ServerInvalidRouteError } from \"./core/errors/serverErrors.js\";\r\nexport { logger } from \"./core/logger.js\";\r\nexport { Router, QuikRouter } from \"./core/router.js\";\r\nexport { Server, type QuikServerConfig } from \"./core/server.js\";\r\n","class ServerInvalidRouteError extends Error {\r\n constructor(path: string) {\r\n super(`\"${path}\" is not a QuikRouter instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidCronError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikCron instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidWebSocketError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikWebSocket instance.`);\r\n }\r\n}\r\n\r\nclass ServerInvalidSocketIOError extends Error {\r\n constructor() {\r\n super(`Invalid object, must be a QuikSocketIO instance.`);\r\n }\r\n}\r\n\r\nexport { ServerInvalidRouteError, ServerInvalidCronError, ServerInvalidWebSocketError, ServerInvalidSocketIOError }","import fs from \"node:fs\"\r\nimport path from \"node:path\";\r\n\r\nimport { colors } from \"./colors.js\"\r\nimport { dateToString, isValidTimeZone } from \"./time.js\";\r\nimport { translate } from \"./translator.js\";\r\n\r\n/* Types */\r\ntype ConfigValue = string | null | false;\r\ntype Cases = \"uppercase\" | \"lowercase\" | \"capitalize\" | \"none\" | null;\r\ntype ColorName =\r\n | \"black\"\r\n | \"red\"\r\n | \"green\"\r\n | \"yellow\"\r\n | \"blue\"\r\n | \"magenta\"\r\n | \"cyan\"\r\n | \"white\";\r\n\r\ntype ColorValue = ColorName | null;\r\ntype SaveConfig = {\r\n infoFilePath: ConfigValue,\r\n logFilePath: ConfigValue,\r\n errorFilePath: ConfigValue,\r\n warningFilePath: ConfigValue,\r\n}\r\ntype ColorConfig = {\r\n logColor: ColorValue;\r\n infoColor: ColorValue;\r\n errorColor: ColorValue;\r\n warningColor: ColorValue;\r\n debugColor: ColorValue;\r\n}\r\ntype Formatconfig = {\r\n timestampFormat: ConfigValue,\r\n titleCase: Cases,\r\n prefix?: string\r\n suffix?: string\r\n timeZone?: string\r\n}\r\n\r\ntype LoggerConfig = {\r\n language: Language,\r\n save: SaveConfig,\r\n color: ColorConfig,\r\n format: Formatconfig,\r\n}\r\ntype PartialConfig = Partial<{\r\n save: Partial<SaveConfig>;\r\n color: Partial<ColorConfig>;\r\n format: Partial<Formatconfig>;\r\n}>;\r\n\r\nconst defaultConfig: LoggerConfig = {\r\n language: \"en\",\r\n save: {\r\n logFilePath: null,\r\n infoFilePath: null,\r\n errorFilePath: \"logs/error.log\",\r\n warningFilePath: \"logs/warning.log\",\r\n },\r\n color: {\r\n logColor: \"blue\",\r\n infoColor: \"green\",\r\n errorColor: \"red\",\r\n warningColor: \"yellow\",\r\n debugColor: null\r\n },\r\n format: {\r\n timestampFormat: \"DD-MM-YYYY hh:mm:ss\",\r\n titleCase: \"uppercase\"\r\n }\r\n}\r\n\r\nlet config = structuredClone(defaultConfig);\r\n\r\nfunction tokenize(...args: unknown[]): string[] {\r\n return args.map(arg => {\r\n if (typeof arg === \"string\") return arg;\r\n\r\n if (arg instanceof Error) {\r\n return arg.stack ?? arg.message;\r\n }\r\n\r\n if (arg === null || arg === undefined) {\r\n return String(arg);\r\n }\r\n\r\n if (typeof arg === \"object\") {\r\n try {\r\n return JSON.stringify(arg);\r\n } catch {\r\n return \"[Circular]\";\r\n }\r\n }\r\n\r\n return String(arg);\r\n });\r\n}\r\n\r\nfunction write(\r\n level: string,\r\n color: ColorName | null | false,\r\n file: ConfigValue,\r\n ...content: unknown[]\r\n) {\r\n const [header, body] = parseContent(level, ...content);\r\n saveToFile(file, header + body);\r\n\r\n const prefix = config.format.prefix ?? \"\";\r\n const suffix = config.format.suffix ?? \"\";\r\n\r\n if (color) {\r\n const colorFn = colors[color] ?? ((s: string) => s);\r\n console.log(`${prefix}${header}${colorFn(body)}${suffix}`);\r\n } else {\r\n console.log(`${prefix}${header}${body}${suffix}`);\r\n }\r\n}\r\n\r\nfunction parseContent(level: string, ...body: unknown[]): [string, string] {\r\n let header = \"\";\r\n if (config.format.timestampFormat) {\r\n const now = new Date();\r\n const timeZone = config.format.timeZone;\r\n let tz = timeZone;\r\n\r\n if (timeZone && !isValidTimeZone(timeZone)) {\r\n tz = undefined;\r\n }\r\n\r\n const timestamp = dateToString(\r\n now,\r\n config.format.timestampFormat,\r\n tz\r\n );\r\n\r\n header += `${timestamp} `;\r\n }\r\n\r\n switch (config.format.titleCase) {\r\n case \"uppercase\":\r\n level = `[${level.toUpperCase()}] `;\r\n break;\r\n case \"lowercase\":\r\n level = `[${level.toLocaleLowerCase()}] `;\r\n break;\r\n case \"capitalize\":\r\n level = `[${level.charAt(0).toUpperCase() + level.slice(1).toLowerCase()}] `;\r\n break;\r\n case \"none\":\r\n level = `[${level}] `;\r\n break;\r\n default:\r\n level = \"\";\r\n break;\r\n }\r\n let content = level + tokenize(...body).join(\" \");\r\n return [header, content];\r\n}\r\n\r\nfunction saveToFile(filePath: ConfigValue, content: string): void {\r\n if (!filePath || !content.length) return;\r\n\r\n const dir = path.dirname(filePath);\r\n const logMessage = content + \"\\n\";\r\n\r\n fs.mkdirSync(dir, { recursive: true });\r\n fs.appendFileSync(filePath, logMessage);\r\n}\r\n\r\nfunction mergeConfig(\r\n current: LoggerConfig,\r\n update: PartialConfig\r\n): LoggerConfig {\r\n return {\r\n ...current,\r\n ...update,\r\n save: {\r\n ...current.save,\r\n ...update.save,\r\n },\r\n color: {\r\n ...current.color,\r\n ...update.color,\r\n },\r\n format: {\r\n ...current.format,\r\n ...update.format,\r\n },\r\n };\r\n}\r\n\r\nexport const logger = {\r\n // Setter config\r\n setConfig(newConfig: PartialConfig): void {\r\n config = mergeConfig(config, newConfig);\r\n },\r\n\r\n // Getter config\r\n config(): Readonly<LoggerConfig> {\r\n return Object.freeze(structuredClone(config));\r\n },\r\n\r\n log(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.log,\r\n config.color.logColor,\r\n config.save.logFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n info(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.info,\r\n config.color.infoColor,\r\n config.save.infoFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n error(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.error,\r\n config.color.errorColor,\r\n config.save.errorFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n warning(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.warning,\r\n config.color.warningColor,\r\n config.save.warningFilePath,\r\n ...content\r\n );\r\n },\r\n\r\n debug(...content: unknown[]) {\r\n const messages = translate(config.language, \"logger\");\r\n write(\r\n messages.levels.debug,\r\n config.color.debugColor,\r\n null,\r\n ...content\r\n );\r\n },\r\n\r\n clear() {\r\n console.clear();\r\n },\r\n\r\n custom(\r\n level: string,\r\n color: ColorName | null | false,\r\n file: ConfigValue,\r\n ...content: unknown[]\r\n ) {\r\n write(level, color, file, ...content);\r\n }\r\n}","const color = {\r\n reset: \"\\x1b[0m\",\r\n\r\n black: \"\\x1b[30m\",\r\n red: \"\\x1b[31m\",\r\n green: \"\\x1b[32m\",\r\n yellow: \"\\x1b[33m\",\r\n blue: \"\\x1b[34m\",\r\n magenta: \"\\x1b[35m\",\r\n cyan: \"\\x1b[36m\",\r\n white: \"\\x1b[37m\",\r\n\r\n bold: \"\\x1b[1m\",\r\n underline: \"\\x1b[4m\"\r\n} as const;\r\n\r\n\r\ntype Color = keyof Omit<typeof color, \"reset\">;\r\nconst colors = Object.fromEntries(\r\n Object.entries(color)\r\n .filter(([key]) => key !== \"reset\")\r\n .map(([key, value]) => [\r\n key,\r\n (text: string) => `${value}${text}${color.reset}`\r\n ])\r\n) as Record<Color, (text: string) => string>;\r\n\r\nexport { color, colors };","function dateToString(date: Date, format: string, timeZone?: string): string {\r\n const formatter = new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n year: \"numeric\",\r\n month: \"2-digit\",\r\n day: \"2-digit\",\r\n hour: \"2-digit\",\r\n minute: \"2-digit\",\r\n second: \"2-digit\",\r\n hourCycle: \"h23\",\r\n });\r\n\r\n const parts = formatter.formatToParts(date);\r\n const values = Object.fromEntries(\r\n parts\r\n .filter(({ type }) => type !== \"literal\")\r\n .map(({ type, value }) => [type, value])\r\n );\r\n\r\n return format.replace(/(YYYY|MM|DD|hh|mm|ss)/g, (match): string => {\r\n switch (match) {\r\n case \"YYYY\":\r\n return values.year || \"\";\r\n case \"MM\":\r\n return values.month || \"\";\r\n case \"DD\":\r\n return values.day || \"\";\r\n case \"hh\":\r\n return values.hour || \"\";\r\n case \"mm\":\r\n return values.minute || \"\";\r\n case \"ss\":\r\n return values.second || \"\";\r\n default:\r\n return match;\r\n }\r\n });\r\n}\r\n\r\nfunction isValidTimeZone(timeZone: string): boolean {\r\n try {\r\n new Intl.DateTimeFormat(\"en-US\", {\r\n timeZone,\r\n });\r\n\r\n return true;\r\n } catch {\r\n return false;\r\n }\r\n}\r\n\r\nexport { dateToString, isValidTimeZone };\r\n","{\r\n \"logger\": {\r\n \"levels\": {\r\n \"log\": \"log\",\r\n \"info\": \"info\",\r\n \"warning\": \"warning\",\r\n \"error\": \"error\",\r\n \"debug\": \"debug\"\r\n }\r\n },\r\n \"server\": {\r\n \"name\": \"server\",\r\n \"start\": \"Server running at\",\r\n \"routers_loaded\": \"routers loaded\",\r\n \"crons_loaded\": \"crons loaded\",\r\n \"socket_loaded\": \"socket loaded\",\r\n \"static_loaded\": \"static dirs loaded\",\r\n \"views_loaded\": \"views dirs loaded\",\r\n\r\n \"static_warn\": \"directory does not exist\",\r\n \"view_warn\": \"file don't not exist\"\r\n },\r\n \"time\": {\r\n \"invalidTimeZone1\": \"Invalid time zone:\",\r\n \"invalidTimeZone2\": \"Using system default time zone.\"\r\n }\r\n}","{\r\n \"logger\": {\r\n \"levels\": {\r\n \"log\": \"log\",\r\n \"info\": \"info\",\r\n \"warning\": \"advertencia\",\r\n \"error\": \"error\",\r\n \"debug\": \"depuración\"\r\n }\r\n },\r\n \"server\": {\r\n \"name\": \"servidor\",\r\n \"start\": \"Servidor corriendo en\",\r\n \"routers_loaded\": \"rutas cargadas\",\r\n \"crons_loaded\": \"crons cargados\",\r\n \"socket_loaded\": \"socket cargado\",\r\n \"static_loaded\": \"carpetas estaticas cargadas\",\r\n \"views_loaded\": \"carpetas de vistas cargadas\",\r\n\r\n \"static_warn\": \"no existe el directorio\",\r\n \"view_warn\": \"no existe el archivo\"\r\n },\r\n \"time\": {\r\n \"invalidTimeZone1\": \"Zona horaria inválida:\",\r\n \"invalidTimeZone2\": \"Usando la zona horaria predeterminada del sistema.\"\r\n }\r\n}","import en from \"../locales/en.json\" with { type: \"json\" };\r\nimport es from \"../locales/es.json\" with { type: \"json\" };\r\n\r\ntype Locale = typeof en;\r\n\r\nconst locales = {\r\n en,\r\n es,\r\n} satisfies Record<string, Locale>;\r\n\r\ntype Language = keyof typeof locales;\r\ntype TranslationKey = keyof Locale;\r\n\r\nfunction translate<K extends TranslationKey>(\r\n language: Language,\r\n key: K\r\n): Locale[K] {\r\n return locales[language][key];\r\n}\r\n\r\nexport {\r\n translate,\r\n};\r\n","import type { RequestHandler, Router as RouterType } from \"express\";\r\nimport { Router as ExpressRouter } from \"express\";\r\n\r\ntype HttpMethod =\r\n | \"get\"\r\n | \"post\"\r\n | \"put\"\r\n | \"patch\"\r\n | \"delete\"\r\n | \"options\"\r\n | \"head\"\r\n | \"query\"\r\n | \"all\";\r\n\r\nclass QuikRouter {\r\n readonly router: RouterType;\r\n private pendingMiddleware: RequestHandler[] = [];\r\n private currentPath: string = \"\";\r\n\r\n constructor() {\r\n this.router = ExpressRouter();\r\n }\r\n\r\n middleware(...handlers: RequestHandler[]) {\r\n this.pendingMiddleware.push(...handlers);\r\n return this;\r\n }\r\n\r\n path(path: string) {\r\n this.currentPath = path;\r\n return this;\r\n }\r\n\r\n private register (\r\n method: HttpMethod,\r\n handler: RequestHandler\r\n ) {\r\n if(!this.router[method]) return this;\r\n \r\n this.router[method](\r\n this.currentPath,\r\n ...this.pendingMiddleware,\r\n async (req, res, next) => {\r\n try {\r\n await handler(req, res, next);\r\n } catch (err) {\r\n next(err);\r\n }\r\n }\r\n );\r\n\r\n this.pendingMiddleware = [];\r\n this.currentPath = \"\";\r\n\r\n return this;\r\n }\r\n\r\n get(handler: RequestHandler) {\r\n return this.register(\"get\", handler);\r\n }\r\n\r\n post(handler: RequestHandler) {\r\n return this.register(\"post\", handler);\r\n }\r\n\r\n put(handler: RequestHandler) {\r\n return this.register(\"put\", handler);\r\n }\r\n\r\n query(handler: RequestHandler) {\r\n return this.register(\"query\", handler);\r\n }\r\n\r\n patch(handler: RequestHandler) {\r\n return this.register(\"patch\", handler);\r\n }\r\n\r\n delete(handler: RequestHandler) {\r\n return this.register(\"delete\", handler);\r\n }\r\n \r\n}\r\n\r\nfunction Router() {\r\n return new QuikRouter();\r\n}\r\n\r\nexport { \r\n QuikRouter, Router,\r\n type HttpMethod\r\n};","import express, { type ErrorRequestHandler, type Express, type RequestHandler } from \"express\";\r\nimport fileUpload from \"express-fileupload\";\r\nimport http, { type Server as HTTPServer } from \"node:http\";\r\nimport path from \"node:path\";\r\nimport fs from \"node:fs\";\r\n\r\nimport { QuikRouter } from \"./router.js\";\r\nimport { logger } from \"./logger.js\";\r\nimport { translate } from \"./translator.js\";\r\nimport { isValidTimeZone } from \"./time.js\";\r\nimport { QuikCron } from \"../cron/cron.js\";\r\n\r\n\r\nimport { ServerInvalidCronError, ServerInvalidRouteError, ServerInvalidSocketIOError, ServerInvalidWebSocketError } from \"./errors/serverErrors.js\";\r\nimport { QuikNotFoundHandler } from \"./handlers/notFoundHandler.js\";\r\nimport { QuikErrorHandler } from \"./handlers/httpErrorHandler.js\";\r\nimport type { QuikSocketIO } from \"../socket.io/socket.js\";\r\nimport type { QuikWebSocket } from \"../ws/websockets.js\";\r\n\r\ntype JsonOptions = Parameters<typeof express.json>[0];\r\ntype UrlencodedOptions = Parameters<typeof express.urlencoded>[0];\r\ntype RawOptions = Parameters<typeof express.raw>[0];\r\ntype TextOptions = Parameters<typeof express.text>[0];\r\ntype BodyParserConfig =\r\n | {\r\n type: \"json\";\r\n options?: JsonOptions;\r\n } | {\r\n type: \"urlencoded\";\r\n options?: UrlencodedOptions;\r\n } | {\r\n type: \"raw\";\r\n options?: RawOptions;\r\n } | {\r\n type: \"text\";\r\n options?: TextOptions;\r\n };\r\ntype HTTPConfig = {\r\n port: number;\r\n host?: string;\r\n\r\n keepAlive?: number;\r\n timeout?: number;\r\n maxConnections?: number;\r\n shutdownTimeout?: number;\r\n};\r\n\r\ntype FileUploadConfig = {\r\n createParentPath?: boolean;\r\n uriDecodeFileNames?: boolean;\r\n safeFileNames?: boolean | RegExp;\r\n preserveExtension?: number | boolean | undefined;\r\n abortOnLimit?: boolean;\r\n responseOnLimit?: string;\r\n limitHandler?: false | ((req: express.Request, res: express.Response, next: express.NextFunction) => void);\r\n useTempFiles?: boolean;\r\n tempFileDir?: string;\r\n tempFilePermissions?: fs.Mode;\r\n parseNested?: boolean;\r\n debug?: boolean;\r\n logger?: { log: (...data: any[]) => void }; \r\n uploadTimeout?: number;\r\n hashAlgorithm?: string;\r\n}\r\n\r\ntype ExpressConfig = {\r\n name?: string;\r\n env?: string;\r\n trustProxy?: boolean;\r\n viewEngine?: string;\r\n};\r\ntype QuikServerConfig = {\r\n language: Language,\r\n timeZone?: string;\r\n bodyParser: BodyParserConfig;\r\n http: HTTPConfig;\r\n express: ExpressConfig;\r\n fileUpload?: FileUploadConfig;\r\n};\r\ntype RoutingDict = Record<string, QuikRouter>;\r\n\r\nconst defaultConfig: QuikServerConfig = {\r\n language: \"en\",\r\n bodyParser: {\r\n type: \"json\"\r\n },\r\n\r\n http: {\r\n port: 8080\r\n },\r\n\r\n express: {}\r\n}\r\nconst defaultNotFoundHandler = QuikNotFoundHandler;\r\nconst defaultErrorHandler = QuikErrorHandler;\r\n\r\nclass QuikServer {\r\n app: Express;\r\n httpServer: HTTPServer;\r\n\r\n middlewares: RequestHandler[] = [];\r\n routes: RoutingDict = {};\r\n staticDirs: string[] = [];\r\n crons: QuikCron[] = [];\r\n ws: QuikWebSocket | QuikSocketIO | undefined;\r\n viewDirs: string[] = [];\r\n\r\n notFoundHandler: RequestHandler | undefined;\r\n errorHandler: ErrorRequestHandler | undefined;\r\n\r\n\r\n config: QuikServerConfig;\r\n\r\n constructor() {\r\n this.app = express();\r\n this.config = structuredClone(defaultConfig);\r\n this.httpServer = http.createServer(\r\n this.app\r\n );\r\n\r\n this.ws = undefined;\r\n\r\n this.notFoundHandler = defaultNotFoundHandler;\r\n this.errorHandler = defaultErrorHandler;\r\n }\r\n\r\n\r\n setConfig(config: Partial<QuikServerConfig>) {\r\n this.config = {\r\n ...this.config,\r\n ...config,\r\n http: {\r\n ...this.config.http,\r\n ...config.http\r\n },\r\n express: {\r\n ...this.config.express,\r\n ...config.express\r\n },\r\n fileUpload: {\r\n ...this.config.fileUpload,\r\n ...config.fileUpload\r\n }\r\n\r\n };\r\n\r\n // Notify if the provided time zone is invalid\r\n if (config.timeZone && !isValidTimeZone(config.timeZone)) {\r\n const messages = translate(this.config.language, \"time\");\r\n\r\n logger.warning(\r\n `${messages.invalidTimeZone1} ${config.timeZone}. ${messages.invalidTimeZone2}`\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n setNotFoundHandler(handler: RequestHandler | null) {\r\n if (!handler) {\r\n this.notFoundHandler = undefined;\r\n return this;\r\n }\r\n this.notFoundHandler = handler;\r\n\r\n return this;\r\n }\r\n\r\n setErrorHandler(handler: ErrorRequestHandler | null) {\r\n if (!handler) {\r\n this.errorHandler = undefined;\r\n return this;\r\n }\r\n this.errorHandler = handler;\r\n\r\n return this;\r\n }\r\n\r\n addMiddleware(...middlewares: RequestHandler[]) {\r\n this.middlewares.push(\r\n ...middlewares\r\n );\r\n\r\n return this;\r\n }\r\n\r\n addRoute(path: string, router: QuikRouter) {\r\n if (!(router instanceof QuikRouter)) {\r\n throw new ServerInvalidRouteError(path)\r\n }\r\n\r\n if (!path.startsWith(\"/\"))\r\n path = \"/\" + path;\r\n\r\n this.routes[path] = router;\r\n\r\n return this;\r\n }\r\n\r\n\r\n addViewDir(...paths: string[]) {\r\n for (const view of paths) {\r\n const viewPath = path.resolve(view);\r\n\r\n if (!fs.existsSync(viewPath)) {\r\n const messages = translate(this.config.language, \"server\");\r\n\r\n logger.warning(\r\n `[ VIEW ] \"${view}\" ${messages.view_warn}`\r\n );\r\n\r\n continue;\r\n }\r\n\r\n this.viewDirs.push(viewPath);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n addCron(cron: QuikCron) {\r\n if (cron.constructor.name != \"QuikCron\") {\r\n throw new ServerInvalidCronError()\r\n }\r\n this.crons.push(cron);\r\n\r\n return this;\r\n }\r\n\r\n useWebSocket(ws: QuikWebSocket) {\r\n if (ws.constructor.name != \"QuikWebSocket\") {\r\n throw new ServerInvalidWebSocketError()\r\n }\r\n this.ws = ws;\r\n return this;\r\n }\r\n\r\n useSocketIO(socket: QuikSocketIO) {\r\n if (socket?.constructor.name != \"QuikSocketIO\") {\r\n throw new ServerInvalidSocketIOError()\r\n }\r\n this.ws = socket;\r\n\r\n return this;\r\n }\r\n\r\n addStaticDir(...paths: string[]) {\r\n for (const dir of paths) {\r\n const dirPath = path.resolve(dir);\r\n\r\n if (!fs.existsSync(dirPath)) {\r\n const messages = translate(this.config.language, \"server\");\r\n logger.warning(\r\n `[ STATIC ] \"${dir}\" ${messages.static_warn}`\r\n );\r\n\r\n continue;\r\n }\r\n\r\n this.staticDirs.push(dirPath);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #configureExpress() {\r\n const config = this.config.express;\r\n const { name, env, trustProxy, viewEngine } = config;\r\n\r\n if (trustProxy) {\r\n this.app.set(\r\n \"trust proxy\",\r\n config.trustProxy\r\n );\r\n }\r\n\r\n if (env) {\r\n this.app.set(\"env\", config.env);\r\n }\r\n\r\n if (name) {\r\n this.app.set(\"name\", name);\r\n }\r\n\r\n if (viewEngine) {\r\n this.app.set(\"view engine\", viewEngine);\r\n }\r\n\r\n if (this.viewDirs.length > 0) {\r\n const messages = translate(this.config.language, \"server\")\r\n logger.info(`[ VIEWS ] ${this.viewDirs.length} ${messages.views_loaded}.`)\r\n this.app.set(\"views\", this.viewDirs);\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #configureFileUpload() {\r\n const config = this.config.fileUpload;\r\n\r\n if (config) {\r\n this.app.use(\r\n fileUpload(config)\r\n );\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #configureMiddleware() {\r\n const bodyParser = this.config.bodyParser;\r\n\r\n switch (bodyParser.type) {\r\n case \"json\": {\r\n this.app.use(\r\n express.json(bodyParser.options)\r\n );\r\n break;\r\n }\r\n\r\n case \"urlencoded\": {\r\n const options = bodyParser.options ?? { extended: true };\r\n\r\n this.app.use(\r\n express.urlencoded(options)\r\n );\r\n break;\r\n }\r\n\r\n case \"raw\": {\r\n const options = bodyParser.options ?? { type: \"*/*\" };\r\n\r\n this.app.use(\r\n express.raw(options)\r\n );\r\n break;\r\n }\r\n\r\n case \"text\": {\r\n this.app.use(\r\n express.text(bodyParser.options)\r\n );\r\n break;\r\n }\r\n }\r\n\r\n if (this.middlewares.length > 0)\r\n this.app.use(...this.middlewares);\r\n\r\n return this;\r\n }\r\n\r\n #loadRoutes() {\r\n for (const [path, router] of Object.entries(this.routes)) {\r\n this.app.use(\r\n path,\r\n router.router\r\n );\r\n }\r\n const messages = translate(this.config.language, \"server\");\r\n if (Object.entries(this.routes).length > 0) {\r\n logger.info(`[ ROUTER ] ${Object.entries(this.routes).length} ${messages.routers_loaded}.`);\r\n }\r\n return this;\r\n }\r\n\r\n #loadCrons() {\r\n for (const cron of this.crons) {\r\n cron.start();\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.crons.length > 0) {\r\n logger.info(`[ CRON ] ${this.crons.length} ${messages.crons_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadWS() {\r\n if (this.ws) {\r\n this.ws.start(this.httpServer);\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.ws) {\r\n logger.info(`[ SOCKET ] ${messages.socket_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadStaticDirs() {\r\n for (const dir of this.staticDirs) {\r\n const dirPath = path.resolve(dir);\r\n\r\n this.app.use(express.static(dirPath));\r\n }\r\n\r\n const messages = translate(this.config.language, \"server\")\r\n if (this.staticDirs.length > 0) {\r\n logger.info(`[ STATIC ] ${this.staticDirs.length} ${messages.static_loaded}.`)\r\n }\r\n\r\n return this;\r\n }\r\n\r\n #loadHandlers() {\r\n if (this.notFoundHandler) {\r\n this.app.use(\r\n this.notFoundHandler\r\n );\r\n }\r\n\r\n if (this.errorHandler) {\r\n this.app.use(\r\n this.errorHandler\r\n );\r\n }\r\n }\r\n\r\n #configureHTTP() {\r\n const config = this.config.http;\r\n\r\n if (config.timeout)\r\n this.httpServer.timeout = config.timeout;\r\n\r\n if (config.keepAlive)\r\n this.httpServer.keepAliveTimeout = config.keepAlive;\r\n\r\n if (config.maxConnections)\r\n this.httpServer.maxConnections = config.maxConnections;\r\n\r\n return this;\r\n }\r\n\r\n #listen() {\r\n const { port, host } = this.config.http;\r\n const messages = translate(this.config.language, \"server\");\r\n\r\n this.httpServer.listen(port, host, () => {\r\n logger.info(`${messages.start} ${host ?? \"localhost\"}:${port}`);\r\n }\r\n );\r\n\r\n return this;\r\n }\r\n\r\n start() {\r\n this.#configureExpress();\r\n this.#configureMiddleware();\r\n this.#configureFileUpload();\r\n\r\n this.#loadStaticDirs()\r\n this.#loadRoutes();\r\n this.#loadHandlers();\r\n this.#loadCrons();\r\n this.#loadWS();\r\n\r\n this.#configureHTTP();\r\n\r\n this.#listen();\r\n return this;\r\n }\r\n}\r\n\r\nfunction Server() {\r\n return new QuikServer();\r\n}\r\n\r\nexport {\r\n Server,\r\n type QuikServerConfig\r\n};\r\n","import cron from \"node-cron\";\r\nimport { type ScheduledTask } from \"node-cron\";\r\n\r\nimport {\r\n CronTaskAlreadyExistsError,\r\n CronInvalidScheduleError,\r\n CronInvalidTimeZoneError,\r\n CronTaskExecutionError,\r\n} from \"./exceptions.js\";\r\n\r\nimport { isValidTimeZone } from \"../core/time.js\";\r\nimport type { CronConfig, CronTask, PartialCronConfig } from \"./types.js\";\r\n\r\n// Default configuration \r\nconst defaultConfig: CronConfig = {\r\n language: \"en\",\r\n};\r\n\r\n// Cron Class\r\nclass QuikCron {\r\n private tasks = new Map<string, CronTask>();\r\n private jobs = new Map<string, ScheduledTask>();\r\n\r\n #config: CronConfig = structuredClone(defaultConfig);\r\n\r\n constructor() {\r\n \r\n }\r\n\r\n add(task: CronTask): void {\r\n if (this.tasks.has(task.name)) {\r\n throw new CronTaskAlreadyExistsError(\r\n task.name\r\n );\r\n }\r\n\r\n if (!cron.validate(task.schedule)) {\r\n throw new CronInvalidScheduleError(\r\n task.schedule\r\n );\r\n }\r\n\r\n if (\r\n task.timezone &&\r\n !isValidTimeZone(task.timezone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n task.timezone\r\n );\r\n }\r\n\r\n this.tasks.set(task.name, {\r\n ...task,\r\n });\r\n }\r\n\r\n remove(name: string): boolean {\r\n this.jobs.get(name)?.stop();\r\n this.jobs.delete(name);\r\n\r\n return this.tasks.delete(name);\r\n }\r\n\r\n has(name: string): boolean {\r\n return this.tasks.has(name);\r\n }\r\n\r\n get(name: string): CronTask | undefined {\r\n return this.tasks.get(name);\r\n }\r\n\r\n getTasks(): CronTask[] {\r\n return [...this.tasks.values()];\r\n }\r\n\r\n start(): void {\r\n for (const task of this.tasks.values()) {\r\n if (this.jobs.has(task.name)) {\r\n continue;\r\n }\r\n\r\n const timezone =\r\n task.timezone ?? this.#config.timeZone;\r\n\r\n const options = timezone\r\n ? { timezone }\r\n : {};\r\n\r\n const job = cron.schedule(\r\n task.schedule,\r\n async () => {\r\n try {\r\n await task.task();\r\n } catch (error) {\r\n const exception =\r\n new CronTaskExecutionError(\r\n task.name,\r\n error\r\n );\r\n\r\n this.#config.onError?.(exception);\r\n }\r\n },\r\n options\r\n );\r\n\r\n this.jobs.set(task.name, job);\r\n }\r\n }\r\n\r\n stop(): void {\r\n for (const job of this.jobs.values()) {\r\n job.stop();\r\n }\r\n\r\n this.jobs.clear();\r\n }\r\n\r\n config(): Readonly<CronConfig> {\r\n return Object.freeze(\r\n structuredClone(this.#config)\r\n );\r\n }\r\n\r\n setConfig(config: PartialCronConfig): void {\r\n if (\r\n config.timeZone &&\r\n !isValidTimeZone(config.timeZone)\r\n ) {\r\n throw new CronInvalidTimeZoneError(\r\n config.timeZone\r\n );\r\n }\r\n\r\n this.#config = {\r\n ...this.#config,\r\n ...config,\r\n };\r\n }\r\n}\r\n\r\nfunction Cron(): QuikCron {\r\n return new QuikCron();\r\n}\r\n\r\nexport { QuikCron, Cron };\r\n","const Status = {\r\n // 1xx Informational\r\n CONTINUE: 100,\r\n SWITCHING_PROTOCOLS: 101,\r\n PROCESSING: 102,\r\n EARLY_HINTS: 103,\r\n\r\n // 2xx Success\r\n OK: 200,\r\n CREATED: 201,\r\n ACCEPTED: 202,\r\n NON_AUTHORITATIVE_INFORMATION: 203,\r\n NO_CONTENT: 204,\r\n RESET_CONTENT: 205,\r\n PARTIAL_CONTENT: 206,\r\n MULTI_STATUS: 207,\r\n ALREADY_REPORTED: 208,\r\n IM_USED: 226,\r\n\r\n // 3xx Redirection\r\n MULTIPLE_CHOICES: 300,\r\n MOVED_PERMANENTLY: 301,\r\n FOUND: 302,\r\n SEE_OTHER: 303,\r\n NOT_MODIFIED: 304,\r\n TEMPORARY_REDIRECT: 307,\r\n PERMANENT_REDIRECT: 308,\r\n\r\n // 4xx Client Errors\r\n BAD_REQUEST: 400,\r\n UNAUTHORIZED: 401,\r\n PAYMENT_REQUIRED: 402,\r\n FORBIDDEN: 403,\r\n NOT_FOUND: 404,\r\n METHOD_NOT_ALLOWED: 405,\r\n NOT_ACCEPTABLE: 406,\r\n PROXY_AUTHENTICATION_REQUIRED: 407,\r\n REQUEST_TIMEOUT: 408,\r\n CONFLICT: 409,\r\n GONE: 410,\r\n LENGTH_REQUIRED: 411,\r\n PRECONDITION_FAILED: 412,\r\n PAYLOAD_TOO_LARGE: 413,\r\n URI_TOO_LONG: 414,\r\n UNSUPPORTED_MEDIA_TYPE: 415,\r\n RANGE_NOT_SATISFIABLE: 416,\r\n EXPECTATION_FAILED: 417,\r\n IM_A_TEAPOT: 418,\r\n MISDIRECTED_REQUEST: 421,\r\n UNPROCESSABLE_CONTENT: 422,\r\n LOCKED: 423,\r\n FAILED_DEPENDENCY: 424,\r\n UPGRADE_REQUIRED: 426,\r\n PRECONDITION_REQUIRED: 428,\r\n TOO_MANY_REQUESTS: 429,\r\n REQUEST_HEADER_FIELDS_TOO_LARGE: 431,\r\n UNAVAILABLE_FOR_LEGAL_REASONS: 451,\r\n\r\n // 5xx Server Errors\r\n INTERNAL_SERVER_ERROR: 500,\r\n NOT_IMPLEMENTED: 501,\r\n BAD_GATEWAY: 502,\r\n SERVICE_UNAVAILABLE: 503,\r\n GATEWAY_TIMEOUT: 504,\r\n HTTP_VERSION_NOT_SUPPORTED: 505,\r\n VARIANT_ALSO_NEGOTIATES: 506,\r\n INSUFFICIENT_STORAGE: 507,\r\n LOOP_DETECTED: 508,\r\n NOT_EXTENDED: 510,\r\n NETWORK_AUTHENTICATION_REQUIRED: 511\r\n} as const;\r\n\r\nexport {\r\n Status\r\n};","import type { RequestHandler } from \"express\";\r\nimport { Status } from \"../../http/index.js\";\r\n\r\nexport const QuikNotFoundHandler: RequestHandler = (req, res) => {\r\n res.status(Status.NOT_FOUND).json({\r\n error: \"Not Found\",\r\n message: `Route ${req.method} ${req.originalUrl} not found`\r\n });\r\n};","import type { ErrorRequestHandler, Request, Response, Errback } from \"express\";\r\nimport { logger } from \"../logger.js\";\r\nimport { Status } from \"../../http/index.js\";\r\n\r\nexport const QuikErrorHandler: ErrorRequestHandler = (err, req, res, next) => {\r\n logger.error(err);\r\n\r\n if (res.headersSent) {\r\n return next(err);\r\n }\r\n\r\n res.status(Status.INTERNAL_SERVER_ERROR).json({\r\n error: \"Internal Server Error\"\r\n });\r\n};"],"mappings":"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","names":["path","color","path","fs","ExpressRouter","path","import_express","import_node_path","import_node_fs","import_node_cron","defaultConfig","express","http","config","path","fs","cron","fileUpload"]}
package/dist/index.d.cts CHANGED
@@ -1,5 +1,6 @@
1
1
  import express, { Router as Router$1, RequestHandler, Express, ErrorRequestHandler } from 'express';
2
2
  import { Server as Server$1 } from 'node:http';
3
+ import fs from 'node:fs';
3
4
  import { Q as QuikCron } from './cron-BLi976po.cjs';
4
5
  import { Q as QuikSocketIO } from './index-CmT_nxIe.cjs';
5
6
  import { QuikWebSocket } from './ws/index.cjs';
@@ -68,6 +69,7 @@ declare class QuikRouter {
68
69
  get(handler: RequestHandler): this;
69
70
  post(handler: RequestHandler): this;
70
71
  put(handler: RequestHandler): this;
72
+ query(handler: RequestHandler): this;
71
73
  patch(handler: RequestHandler): this;
72
74
  delete(handler: RequestHandler): this;
73
75
  }
@@ -98,6 +100,25 @@ type HTTPConfig = {
98
100
  maxConnections?: number;
99
101
  shutdownTimeout?: number;
100
102
  };
103
+ type FileUploadConfig = {
104
+ createParentPath?: boolean;
105
+ uriDecodeFileNames?: boolean;
106
+ safeFileNames?: boolean | RegExp;
107
+ preserveExtension?: number | boolean | undefined;
108
+ abortOnLimit?: boolean;
109
+ responseOnLimit?: string;
110
+ limitHandler?: false | ((req: express.Request, res: express.Response, next: express.NextFunction) => void);
111
+ useTempFiles?: boolean;
112
+ tempFileDir?: string;
113
+ tempFilePermissions?: fs.Mode;
114
+ parseNested?: boolean;
115
+ debug?: boolean;
116
+ logger?: {
117
+ log: (...data: any[]) => void;
118
+ };
119
+ uploadTimeout?: number;
120
+ hashAlgorithm?: string;
121
+ };
101
122
  type ExpressConfig = {
102
123
  name?: string;
103
124
  env?: string;
@@ -110,6 +131,7 @@ type QuikServerConfig = {
110
131
  bodyParser: BodyParserConfig;
111
132
  http: HTTPConfig;
112
133
  express: ExpressConfig;
134
+ fileUpload?: FileUploadConfig;
113
135
  };
114
136
  type RoutingDict = Record<string, QuikRouter>;
115
137
  declare class QuikServer {
@@ -140,4 +162,4 @@ declare class QuikServer {
140
162
  }
141
163
  declare function Server(): QuikServer;
142
164
 
143
- export { QuikRouter, Router, Server, ServerInvalidRouteError, logger };
165
+ export { QuikRouter, type QuikServerConfig, Router, Server, ServerInvalidRouteError, logger };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import express, { Router as Router$1, RequestHandler, Express, ErrorRequestHandler } from 'express';
2
2
  import { Server as Server$1 } from 'node:http';
3
+ import fs from 'node:fs';
3
4
  import { Q as QuikCron } from './cron-BLi976po.js';
4
5
  import { Q as QuikSocketIO } from './index-CmT_nxIe.js';
5
6
  import { QuikWebSocket } from './ws/index.js';
@@ -68,6 +69,7 @@ declare class QuikRouter {
68
69
  get(handler: RequestHandler): this;
69
70
  post(handler: RequestHandler): this;
70
71
  put(handler: RequestHandler): this;
72
+ query(handler: RequestHandler): this;
71
73
  patch(handler: RequestHandler): this;
72
74
  delete(handler: RequestHandler): this;
73
75
  }
@@ -98,6 +100,25 @@ type HTTPConfig = {
98
100
  maxConnections?: number;
99
101
  shutdownTimeout?: number;
100
102
  };
103
+ type FileUploadConfig = {
104
+ createParentPath?: boolean;
105
+ uriDecodeFileNames?: boolean;
106
+ safeFileNames?: boolean | RegExp;
107
+ preserveExtension?: number | boolean | undefined;
108
+ abortOnLimit?: boolean;
109
+ responseOnLimit?: string;
110
+ limitHandler?: false | ((req: express.Request, res: express.Response, next: express.NextFunction) => void);
111
+ useTempFiles?: boolean;
112
+ tempFileDir?: string;
113
+ tempFilePermissions?: fs.Mode;
114
+ parseNested?: boolean;
115
+ debug?: boolean;
116
+ logger?: {
117
+ log: (...data: any[]) => void;
118
+ };
119
+ uploadTimeout?: number;
120
+ hashAlgorithm?: string;
121
+ };
101
122
  type ExpressConfig = {
102
123
  name?: string;
103
124
  env?: string;
@@ -110,6 +131,7 @@ type QuikServerConfig = {
110
131
  bodyParser: BodyParserConfig;
111
132
  http: HTTPConfig;
112
133
  express: ExpressConfig;
134
+ fileUpload?: FileUploadConfig;
113
135
  };
114
136
  type RoutingDict = Record<string, QuikRouter>;
115
137
  declare class QuikServer {
@@ -140,4 +162,4 @@ declare class QuikServer {
140
162
  }
141
163
  declare function Server(): QuikServer;
142
164
 
143
- export { QuikRouter, Router, Server, ServerInvalidRouteError, logger };
165
+ export { QuikRouter, type QuikServerConfig, Router, Server, ServerInvalidRouteError, logger };
package/dist/index.js CHANGED
@@ -350,6 +350,7 @@ var QuikRouter = class {
350
350
  return this;
351
351
  }
352
352
  register(method, handler) {
353
+ if (!this.router[method]) return this;
353
354
  this.router[method](
354
355
  this.currentPath,
355
356
  ...this.pendingMiddleware,
@@ -374,6 +375,9 @@ var QuikRouter = class {
374
375
  put(handler) {
375
376
  return this.register("put", handler);
376
377
  }
378
+ query(handler) {
379
+ return this.register("query", handler);
380
+ }
377
381
  patch(handler) {
378
382
  return this.register("patch", handler);
379
383
  }
@@ -387,6 +391,7 @@ function Router() {
387
391
 
388
392
  // src/core/server.ts
389
393
  import express from "express";
394
+ import fileUpload from "express-fileupload";
390
395
  import http from "http";
391
396
  import path2 from "path";
392
397
  import fs2 from "fs";
@@ -529,6 +534,10 @@ var QuikServer = class {
529
534
  express: {
530
535
  ...this.config.express,
531
536
  ...config2.express
537
+ },
538
+ fileUpload: {
539
+ ...this.config.fileUpload,
540
+ ...config2.fileUpload
532
541
  }
533
542
  };
534
543
  if (config2.timeZone && !isValidTimeZone(config2.timeZone)) {
@@ -644,29 +653,44 @@ var QuikServer = class {
644
653
  }
645
654
  return this;
646
655
  }
656
+ #configureFileUpload() {
657
+ const config2 = this.config.fileUpload;
658
+ if (config2) {
659
+ this.app.use(
660
+ fileUpload(config2)
661
+ );
662
+ }
663
+ return this;
664
+ }
647
665
  #configureMiddleware() {
648
666
  const bodyParser = this.config.bodyParser;
649
667
  switch (bodyParser.type) {
650
- case "json":
668
+ case "json": {
651
669
  this.app.use(
652
670
  express.json(bodyParser.options)
653
671
  );
654
672
  break;
655
- case "urlencoded":
673
+ }
674
+ case "urlencoded": {
675
+ const options = bodyParser.options ?? { extended: true };
656
676
  this.app.use(
657
- express.urlencoded(bodyParser.options)
677
+ express.urlencoded(options)
658
678
  );
659
679
  break;
660
- case "raw":
680
+ }
681
+ case "raw": {
682
+ const options = bodyParser.options ?? { type: "*/*" };
661
683
  this.app.use(
662
- express.raw(bodyParser.options)
684
+ express.raw(options)
663
685
  );
664
686
  break;
665
- case "text":
687
+ }
688
+ case "text": {
666
689
  this.app.use(
667
690
  express.text(bodyParser.options)
668
691
  );
669
692
  break;
693
+ }
670
694
  }
671
695
  if (this.middlewares.length > 0)
672
696
  this.app.use(...this.middlewares);
@@ -753,6 +777,7 @@ var QuikServer = class {
753
777
  start() {
754
778
  this.#configureExpress();
755
779
  this.#configureMiddleware();
780
+ this.#configureFileUpload();
756
781
  this.#loadStaticDirs();
757
782
  this.#loadRoutes();
758
783
  this.#loadHandlers();