tezx 1.0.41 → 1.0.43

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.
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Context = exports.httpStatusMap = void 0;
4
+ const state_1 = require("../utils/state");
5
+ const staticFile_1 = require("../utils/staticFile");
4
6
  const environment_1 = require("./environment");
5
7
  const header_1 = require("./header");
6
8
  const request_1 = require("./request");
7
- const state_1 = require("../utils/state");
8
- const staticFile_1 = require("../utils/staticFile");
9
9
  exports.httpStatusMap = {
10
10
  100: "Continue",
11
11
  101: "Switching Protocols",
@@ -81,7 +81,8 @@ class Context {
81
81
  #status = 200;
82
82
  state = new state_1.State();
83
83
  #params = {};
84
- #resBody;
84
+ resBody;
85
+ #body;
85
86
  #localAddress = {};
86
87
  #remoteAddress = {};
87
88
  constructor(req, connInfo) {
@@ -392,6 +393,7 @@ class Context {
392
393
  status: status,
393
394
  headers,
394
395
  });
396
+ this.resBody = body;
395
397
  return response;
396
398
  }
397
399
  get req() {
@@ -401,10 +403,10 @@ class Context {
401
403
  this.#params = params;
402
404
  }
403
405
  set body(body) {
404
- this.#resBody = body;
406
+ this.#body = body;
405
407
  }
406
408
  get body() {
407
- return this.#resBody;
409
+ return this.#body;
408
410
  }
409
411
  get params() {
410
412
  return this.#params;
package/cjs/index.js CHANGED
@@ -7,4 +7,4 @@ var server_1 = require("./core/server");
7
7
  Object.defineProperty(exports, "TezX", { enumerable: true, get: function () { return server_1.TezX; } });
8
8
  var params_1 = require("./utils/params");
9
9
  Object.defineProperty(exports, "useParams", { enumerable: true, get: function () { return params_1.useParams; } });
10
- exports.version = "1.0.41";
10
+ exports.version = "1.0.43";
@@ -7,7 +7,7 @@ const config_1 = require("../core/config");
7
7
  const detectBot = (options = {}) => {
8
8
  const { botUserAgents = ["bot", "spider", "crawl", "slurp"], maxRequests = 30, windowMs = 60000, isBlacklisted = async () => false, queryKeyBot = "bot", onBotDetected = "block", enableRateLimiting = false, customBotDetector = async () => false, customBlockedResponse = (ctx, { reason }) => {
9
9
  ctx.setStatus = 403;
10
- ctx.body = { error: `Bot detected: ${reason}` };
10
+ return ctx.json({ error: `Bot detected: ${reason}` });
11
11
  }, storage, confidenceThreshold = 0.5, } = options;
12
12
  let store = storage;
13
13
  if (enableRateLimiting) {
@@ -19,7 +19,8 @@ const detectBot = (options = {}) => {
19
19
  indicators: [],
20
20
  };
21
21
  const userAgent = ctx.headers.get("user-agent")?.toLowerCase() || "";
22
- const remoteAddress = `${ctx.req.remoteAddress?.address}:${ctx.req.remoteAddress?.port}` || "unknown";
22
+ const remoteAddress = `${ctx.req.remoteAddress?.address}:${ctx.req.remoteAddress?.port}` ||
23
+ "unknown";
23
24
  const isBotQuery = ctx.req.query[queryKeyBot] === "true";
24
25
  if (botUserAgents.some((agent) => userAgent.includes(agent))) {
25
26
  detectionResult.indicators.push("User-Agent");
@@ -27,6 +27,7 @@ const paginationHandler = (options = {}) => {
27
27
  const pagination = {
28
28
  page,
29
29
  limit,
30
+ offset,
30
31
  totalItems: total,
31
32
  totalPages: Math.ceil(total / limit),
32
33
  hasNextPage: page < Math.ceil(total / limit),
@@ -40,12 +41,13 @@ const paginationHandler = (options = {}) => {
40
41
  [countKey]: total,
41
42
  pagination,
42
43
  };
44
+ ctx.body = body;
43
45
  if (next) {
44
- ctx.body = body;
45
46
  return await next();
46
47
  }
47
- return (ctx.body = body);
48
+ return ctx.json(body);
48
49
  }
50
+ return await next();
49
51
  };
50
52
  };
51
53
  exports.paginationHandler = paginationHandler;
package/core/context.d.ts CHANGED
@@ -1,6 +1,6 @@
1
+ import { State } from "../utils/state";
1
2
  import { HeadersParser } from "./header";
2
3
  import { ConnAddress, HTTPMethod, Request } from "./request";
3
- import { State } from "../utils/state";
4
4
  export interface CookieOptions {
5
5
  expires?: Date;
6
6
  path?: string;
@@ -46,6 +46,7 @@ export declare class Context<T extends Record<string, any> = {}> {
46
46
  * @type {State}
47
47
  */
48
48
  state: State;
49
+ protected readonly resBody?: BodyInit | null;
49
50
  constructor(req: any, connInfo: ConnAddress);
50
51
  /**
51
52
  * Appends or set a value to an existing header or creates a new one.
@@ -60,14 +61,14 @@ export declare class Context<T extends Record<string, any> = {}> {
60
61
  append?: false;
61
62
  }): this;
62
63
  /**
63
- * Cookie handling utility with get/set/delete operations
64
- * @returns {{
65
- * get: (name: string) => string | undefined,
66
- * all: () => Record<string, string>,
67
- * delete: (name: string, options?: CookieOptions) => void,
68
- * set: (name: string, value: string, options?: CookieOptions) => void
69
- * }} Cookie handling interface
70
- */
64
+ * Cookie handling utility with get/set/delete operations
65
+ * @returns {{
66
+ * get: (name: string) => string | undefined,
67
+ * all: () => Record<string, string>,
68
+ * delete: (name: string, options?: CookieOptions) => void,
69
+ * set: (name: string, value: string, options?: CookieOptions) => void
70
+ * }} Cookie handling interface
71
+ */
71
72
  get cookies(): {
72
73
  /**
73
74
  * Get a specific cookie by name.
@@ -101,9 +102,9 @@ export declare class Context<T extends Record<string, any> = {}> {
101
102
  * @param headers - (Optional) Additional response headers.
102
103
  * @returns Response object with JSON data.
103
104
  */
104
- json(body: any, status?: number, headers?: ResponseHeaders): Response;
105
- json(body: any, headers?: ResponseHeaders): Response;
106
- json(body: any, status?: number): Response;
105
+ json(body: object, status?: number, headers?: ResponseHeaders): Response;
106
+ json(body: object, headers?: ResponseHeaders): Response;
107
+ json(body: object, status?: number): Response;
107
108
  /**
108
109
  * Sends a response with any content type.
109
110
  * Automatically determines content type if not provided.
@@ -193,16 +194,30 @@ export declare class Context<T extends Record<string, any> = {}> {
193
194
  get req(): Request;
194
195
  protected set params(params: Record<string, any>);
195
196
  /**
196
- * Sets the HTTP response body to be returned to the client.
197
- * This can be a string, object, or any serializable data.
198
- * @param body - The response payload to be stored internally.
197
+ * Set response body to be passed between middlewares or returned as final output.
198
+ *
199
+ * 🔄 Use-case:
200
+ * - Middleware or route handlers can set this value to share data.
201
+ * - If no explicit Response is returned (e.g., `ctx.json()` or `new Response()`),
202
+ * then this body will be auto-wrapped into a `Response` by the framework.
203
+ *
204
+ * ⚠️ Note:
205
+ * Always use `return next()` or an explicit return like `return ctx.json(...)`
206
+ * to ensure proper flow control and response resolution.
207
+ *
208
+ * @param body - The response content (string, object, etc).
199
209
  */
200
- set body(body: any | undefined);
210
+ set body(body: any);
201
211
  /**
202
- * Retrieves the current response body set for the outgoing HTTP response.
203
- * This value will be used when sending the final response.
204
- * @returns The internally stored response payload.
212
+ * Get the current response body.
213
+ *
214
+ * 🧠 Use-case:
215
+ * - Allows middleware or route handler to access any pre-set data
216
+ * from earlier in the middleware chain.
217
+ * - Common for situations where response is deferred or centrally handled.
218
+ *
219
+ * @returns The currently stored response body.
205
220
  */
206
- get body(): any | undefined;
221
+ get body(): any;
207
222
  protected get params(): Record<string, any>;
208
223
  }
package/core/context.js CHANGED
@@ -1,8 +1,8 @@
1
+ import { State } from "../utils/state";
2
+ import { defaultMimeType, mimeTypes } from "../utils/staticFile";
1
3
  import { EnvironmentDetector } from "./environment";
2
4
  import { HeadersParser } from "./header";
3
5
  import { Request } from "./request";
4
- import { State } from "../utils/state";
5
- import { defaultMimeType, mimeTypes } from "../utils/staticFile";
6
6
  export const httpStatusMap = {
7
7
  100: "Continue",
8
8
  101: "Switching Protocols",
@@ -78,7 +78,8 @@ export class Context {
78
78
  #status = 200;
79
79
  state = new State();
80
80
  #params = {};
81
- #resBody;
81
+ resBody;
82
+ #body;
82
83
  #localAddress = {};
83
84
  #remoteAddress = {};
84
85
  constructor(req, connInfo) {
@@ -389,6 +390,7 @@ export class Context {
389
390
  status: status,
390
391
  headers,
391
392
  });
393
+ this.resBody = body;
392
394
  return response;
393
395
  }
394
396
  get req() {
@@ -398,10 +400,10 @@ export class Context {
398
400
  this.#params = params;
399
401
  }
400
402
  set body(body) {
401
- this.#resBody = body;
403
+ this.#body = body;
402
404
  }
403
405
  get body() {
404
- return this.#resBody;
406
+ return this.#body;
405
407
  }
406
408
  get params() {
407
409
  return this.#params;
package/core/router.d.ts CHANGED
@@ -1,10 +1,11 @@
1
1
  import { Context, ResponseHeaders } from "./context";
2
2
  import MiddlewareConfigure, { DuplicateMiddlewares, UniqueMiddlewares } from "./MiddlewareConfigure";
3
3
  import { HTTPMethod } from "./request";
4
- export type NextCallback = () => Promise<any>;
5
4
  export type ctx<T extends Record<string, any> = {}> = Context<T> & T;
6
- export type Callback<T extends Record<string, any> = {}> = (ctx: ctx<T>) => Promise<Response> | Response | string | Record<string, any> | void;
7
- export type Middleware<T extends Record<string, any> = {}> = (ctx: ctx<T>, next: NextCallback) => NextCallback | Promise<NextCallback> | Response | string | Record<string, any> | void;
5
+ export type NextCallback = () => Promise<any>;
6
+ export type CallbackReturn = Promise<Response> | Response;
7
+ export type Callback<T extends Record<string, any> = {}> = (ctx: ctx<T>) => CallbackReturn;
8
+ export type Middleware<T extends Record<string, any> = {}> = (ctx: ctx<T>, next: NextCallback) => Promise<Response> | Response | NextCallback;
8
9
  export type RouterConfig = {
9
10
  /**
10
11
  * `env` allows you to define environment variables for the router.
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Router } from "./core/router";
2
2
  export { TezX } from "./core/server";
3
3
  export { useParams } from "./utils/params";
4
- export let version = "1.0.41";
4
+ export let version = "1.0.43";
@@ -1,4 +1,5 @@
1
1
  import { Context, Middleware } from "..";
2
+ import { CallbackReturn } from "../core/router";
2
3
  export type DetectBotReason = "User-Agent" | "Blacklisted IP" | "Query Parameter" | "Rate Limiting" | "Custom Detector" | "Multiple Indicators";
3
4
  type BotDetectionResult = {
4
5
  isBot: boolean;
@@ -35,7 +36,7 @@ type DetectBotOptions = {
35
36
  * 🛡️ Action to take when bot is detected
36
37
  * @default "block"
37
38
  */
38
- onBotDetected?: "block" | ((ctx: Context, result: BotDetectionResult) => void);
39
+ onBotDetected?: "block" | ((ctx: Context, result: BotDetectionResult) => CallbackReturn);
39
40
  /**
40
41
  * ⚖️ Enable rate-limiting based detection
41
42
  * @default false
@@ -49,7 +50,7 @@ type DetectBotOptions = {
49
50
  /**
50
51
  * ✉️ Custom response for blocked requests
51
52
  */
52
- customBlockedResponse?: (ctx: Context, result: BotDetectionResult) => void;
53
+ customBlockedResponse?: (ctx: Context, result: BotDetectionResult) => CallbackReturn;
53
54
  /**
54
55
  * 🔄 Custom cache storage implementation (e.g., using `Map`, `Redis`, etc.).
55
56
  * By default, it uses a `Map<string, { count: number; resetTime: number }>`.
@@ -96,7 +97,7 @@ type DetectBotOptions = {
96
97
  * isBlacklistedIP: async (ip) => await checkIPReputation(ip),
97
98
  * onBotDetected: (ctx, { reason }) => {
98
99
  * ctx.status = 403;
99
- * ctx.body = { error: `Bot detected (${reason})` };
100
+ * return ctx.json({ error: `Bot detected (${reason})` });
100
101
  * }
101
102
  * }));
102
103
  */
@@ -2,7 +2,7 @@ import { GlobalConfig } from "../core/config";
2
2
  export const detectBot = (options = {}) => {
3
3
  const { botUserAgents = ["bot", "spider", "crawl", "slurp"], maxRequests = 30, windowMs = 60000, isBlacklisted = async () => false, queryKeyBot = "bot", onBotDetected = "block", enableRateLimiting = false, customBotDetector = async () => false, customBlockedResponse = (ctx, { reason }) => {
4
4
  ctx.setStatus = 403;
5
- ctx.body = { error: `Bot detected: ${reason}` };
5
+ return ctx.json({ error: `Bot detected: ${reason}` });
6
6
  }, storage, confidenceThreshold = 0.5, } = options;
7
7
  let store = storage;
8
8
  if (enableRateLimiting) {
@@ -14,7 +14,8 @@ export const detectBot = (options = {}) => {
14
14
  indicators: [],
15
15
  };
16
16
  const userAgent = ctx.headers.get("user-agent")?.toLowerCase() || "";
17
- const remoteAddress = `${ctx.req.remoteAddress?.address}:${ctx.req.remoteAddress?.port}` || "unknown";
17
+ const remoteAddress = `${ctx.req.remoteAddress?.address}:${ctx.req.remoteAddress?.port}` ||
18
+ "unknown";
18
19
  const isBotQuery = ctx.req.query[queryKeyBot] === "true";
19
20
  if (botUserAgents.some((agent) => userAgent.includes(agent))) {
20
21
  detectionResult.indicators.push("User-Agent");
@@ -67,6 +67,7 @@ export type PaginationBodyType = {
67
67
  page: number;
68
68
  limit: number;
69
69
  totalItems: any;
70
+ offset: number;
70
71
  totalPages: number;
71
72
  hasNextPage: boolean;
72
73
  hasPrevPage: boolean;
@@ -24,6 +24,7 @@ export const paginationHandler = (options = {}) => {
24
24
  const pagination = {
25
25
  page,
26
26
  limit,
27
+ offset,
27
28
  totalItems: total,
28
29
  totalPages: Math.ceil(total / limit),
29
30
  hasNextPage: page < Math.ceil(total / limit),
@@ -37,11 +38,12 @@ export const paginationHandler = (options = {}) => {
37
38
  [countKey]: total,
38
39
  pagination,
39
40
  };
41
+ ctx.body = body;
40
42
  if (next) {
41
- ctx.body = body;
42
43
  return await next();
43
44
  }
44
- return (ctx.body = body);
45
+ return ctx.json(body);
45
46
  }
47
+ return await next();
46
48
  };
47
49
  };
@@ -1,5 +1,5 @@
1
1
  import { Context } from "../core/context";
2
- import { Middleware } from "../core/router";
2
+ import { CallbackReturn, Middleware } from "../core/router";
3
3
  export type RateLimiterOptions = {
4
4
  /**
5
5
  * 🔴 Maximum allowed requests in the time window
@@ -49,7 +49,7 @@ export type RateLimiterOptions = {
49
49
  * throw new Error( `Rate limit exceeded. Try again in ${retryAfter} seconds.`);
50
50
  * }
51
51
  */
52
- onError?: (ctx: Context, retryAfter: number, error: Error) => void;
52
+ onError?: (ctx: Context, retryAfter: number, error: Error) => CallbackReturn;
53
53
  };
54
54
  /**
55
55
  * 🚦 Rate limiting middleware for request throttling
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tezx",
3
- "version": "1.0.41",
3
+ "version": "1.0.43",
4
4
  "description": "TezX is a high-performance, lightweight JavaScript framework designed for speed, scalability, and flexibility. It enables efficient routing, middleware management, and static file serving with minimal configuration. Fully compatible with Node.js, Deno, and Bun.",
5
5
  "main": "cjs/index.js",
6
6
  "module": "index.js",