tezx 1.0.58 → 1.0.60

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/adapter/bun.js CHANGED
@@ -2,8 +2,8 @@ import { GlobalConfig } from "../core/config.js";
2
2
  import { Context } from "../core/context.js";
3
3
  export function bunAdapter(TezX, options = {}) {
4
4
  function listen(...arg) {
5
- let port = typeof arg?.[0] === "number" ? arg?.[0] : undefined;
6
- let callback = typeof arg[0] == "function" ? arg[0] : arg?.[1];
5
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
6
+ const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
7
7
  const serve = typeof Bun !== "undefined" ? Bun.serve : null;
8
8
  try {
9
9
  if (!serve) {
@@ -21,7 +21,7 @@ export function bunAdapter(TezX, options = {}) {
21
21
  })
22
22
  : serve({
23
23
  error: (error) => {
24
- return (options?.error)(server, error);
24
+ return options?.error?.(server, error);
25
25
  },
26
26
  development: options?.development,
27
27
  hostname: options?.hostname,
package/adapter/deno.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { GlobalConfig } from "../core/config.js";
2
2
  export function denoAdapter(TezX, options = {}) {
3
3
  function listen(...arg) {
4
- let port = typeof arg?.[0] === "number" ? arg?.[0] : undefined;
5
- let callback = typeof arg[0] == "function" ? arg[0] : arg?.[1];
4
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
5
+ const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
6
6
  const isDeno = typeof Deno !== "undefined";
7
7
  try {
8
8
  async function handleRequest(req, connInfo) {
package/adapter/node.d.ts CHANGED
@@ -11,9 +11,9 @@ type SSLOptions = ServerOptions & TlsOptions & {
11
11
  type TezXServerOptions = UnixSocketOptions | SSLOptions;
12
12
  export declare function nodeAdapter<T extends Record<string, any> = {}>(TezX: TezX<T>, options?: TezXServerOptions): {
13
13
  listen: {
14
- (callback?: (message: string) => void): any;
14
+ (callback?: () => void): any;
15
15
  (port?: number): any;
16
- (port?: number, callback?: (message: string) => void): any;
16
+ (port?: number, callback?: () => void): any;
17
17
  };
18
18
  };
19
19
  export {};
package/adapter/node.js CHANGED
@@ -58,7 +58,7 @@ export function nodeAdapter(TezX, options = {}) {
58
58
  }
59
59
  }
60
60
  });
61
- const port = typeof arg[0] === "number" ? arg[0] : undefined;
61
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
62
62
  const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
63
63
  server.listen(options?.unix || port || 0, () => {
64
64
  const protocol = ssl ? "\x1b[1;35mhttps\x1b[0m" : "\x1b[1;34mhttp\x1b[0m";
@@ -67,12 +67,9 @@ export function nodeAdapter(TezX, options = {}) {
67
67
  ? `\x1b[1mNodeJS TezX Server running at unix://${address}\x1b[0m`
68
68
  : `\x1b[1mNodeJS TezX Server running at ${protocol}://localhost:${address?.port}/\x1b[0m`;
69
69
  GlobalConfig.server = server;
70
- if (typeof callback == "function") {
71
- callback(message);
72
- }
73
- else {
74
- GlobalConfig.debugging.success(message);
75
- }
70
+ GlobalConfig.debugging.success(message);
71
+ if (typeof callback == "function")
72
+ callback();
76
73
  return server;
77
74
  });
78
75
  })
@@ -5,8 +5,8 @@ const config_js_1 = require("../core/config.js");
5
5
  const context_js_1 = require("../core/context.js");
6
6
  function bunAdapter(TezX, options = {}) {
7
7
  function listen(...arg) {
8
- let port = typeof arg?.[0] === "number" ? arg?.[0] : undefined;
9
- let callback = typeof arg[0] == "function" ? arg[0] : arg?.[1];
8
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
9
+ const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
10
10
  const serve = typeof Bun !== "undefined" ? Bun.serve : null;
11
11
  try {
12
12
  if (!serve) {
@@ -24,7 +24,7 @@ function bunAdapter(TezX, options = {}) {
24
24
  })
25
25
  : serve({
26
26
  error: (error) => {
27
- return (options?.error)(server, error);
27
+ return options?.error?.(server, error);
28
28
  },
29
29
  development: options?.development,
30
30
  hostname: options?.hostname,
@@ -4,8 +4,8 @@ exports.denoAdapter = denoAdapter;
4
4
  const config_js_1 = require("../core/config.js");
5
5
  function denoAdapter(TezX, options = {}) {
6
6
  function listen(...arg) {
7
- let port = typeof arg?.[0] === "number" ? arg?.[0] : undefined;
8
- let callback = typeof arg[0] == "function" ? arg[0] : arg?.[1];
7
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
8
+ const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
9
9
  const isDeno = typeof Deno !== "undefined";
10
10
  try {
11
11
  async function handleRequest(req, connInfo) {
@@ -60,7 +60,7 @@ function nodeAdapter(TezX, options = {}) {
60
60
  }
61
61
  }
62
62
  });
63
- const port = typeof arg[0] === "number" ? arg[0] : undefined;
63
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
64
64
  const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
65
65
  server.listen(options?.unix || port || 0, () => {
66
66
  const protocol = ssl ? "\x1b[1;35mhttps\x1b[0m" : "\x1b[1;34mhttp\x1b[0m";
@@ -69,12 +69,9 @@ function nodeAdapter(TezX, options = {}) {
69
69
  ? `\x1b[1mNodeJS TezX Server running at unix://${address}\x1b[0m`
70
70
  : `\x1b[1mNodeJS TezX Server running at ${protocol}://localhost:${address?.port}/\x1b[0m`;
71
71
  config_js_1.GlobalConfig.server = server;
72
- if (typeof callback == "function") {
73
- callback(message);
74
- }
75
- else {
76
- config_js_1.GlobalConfig.debugging.success(message);
77
- }
72
+ config_js_1.GlobalConfig.debugging.success(message);
73
+ if (typeof callback == "function")
74
+ callback();
78
75
  return server;
79
76
  });
80
77
  })
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GlobalConfig = void 0;
4
4
  const debugging_js_1 = require("../utils/debugging.js");
5
+ const environment_js_1 = require("./environment.js");
5
6
  let GlobalConfig = class {
6
7
  static notFound = (ctx) => {
7
8
  const { method, urlRef: { pathname }, } = ctx.req;
@@ -14,7 +15,7 @@ let GlobalConfig = class {
14
15
  static overwriteMethod = true;
15
16
  static debugMode = false;
16
17
  static server;
17
- static adapter;
18
+ static adapter = environment_js_1.EnvironmentDetector.getEnvironment;
18
19
  static get debugging() {
19
20
  return this.debugMode
20
21
  ? {
@@ -93,8 +93,7 @@ class Context {
93
93
  this.#rawRequest = req;
94
94
  this.method = req?.method?.toUpperCase();
95
95
  this.#requestHeaders = new header_js_1.HeadersParser(req?.headers);
96
- if (environment_js_1.EnvironmentDetector.getEnvironment == "node" ||
97
- config_js_1.GlobalConfig.adapter == "node") {
96
+ if (config_js_1.GlobalConfig.adapter == "node") {
98
97
  let encrypted = req?.socket?.encrypted;
99
98
  const protocol = typeof encrypted === "boolean"
100
99
  ? encrypted
@@ -286,7 +285,7 @@ class Context {
286
285
  let fileExists = false;
287
286
  const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
288
287
  if (runtime === "node") {
289
- const { existsSync } = await Promise.resolve().then(() => require("fs"));
288
+ const { existsSync } = await Promise.resolve().then(() => require("node:fs"));
290
289
  fileExists = existsSync(filePath);
291
290
  }
292
291
  else if (runtime === "bun") {
@@ -306,7 +305,7 @@ class Context {
306
305
  }
307
306
  let fileBuffer;
308
307
  if (runtime === "node") {
309
- const { readFileSync } = await Promise.resolve().then(() => require("fs"));
308
+ const { readFileSync } = await Promise.resolve().then(() => require("node:fs"));
310
309
  fileBuffer = await readFileSync(filePath);
311
310
  }
312
311
  else if (runtime === "bun") {
@@ -336,7 +335,7 @@ class Context {
336
335
  const resolvedPath = filePath;
337
336
  let fileExists = false;
338
337
  if (runtime === "node") {
339
- const { existsSync } = await Promise.resolve().then(() => require("fs"));
338
+ const { existsSync } = await Promise.resolve().then(() => require("node:fs"));
340
339
  fileExists = existsSync(resolvedPath);
341
340
  }
342
341
  else if (runtime === "bun") {
@@ -356,7 +355,7 @@ class Context {
356
355
  }
357
356
  let fileSize = 0;
358
357
  if (runtime === "node") {
359
- const { statSync } = await Promise.resolve().then(() => require("fs"));
358
+ const { statSync } = await Promise.resolve().then(() => require("node:fs"));
360
359
  fileSize = statSync(resolvedPath).size;
361
360
  }
362
361
  else if (runtime === "bun") {
@@ -370,7 +369,7 @@ class Context {
370
369
  const mimeType = staticFile_js_1.mimeTypes[ext] || staticFile_js_1.defaultMimeType;
371
370
  let fileStream;
372
371
  if (runtime === "node") {
373
- const { createReadStream } = await Promise.resolve().then(() => require("fs"));
372
+ const { createReadStream } = await Promise.resolve().then(() => require("node:fs"));
374
373
  fileStream = createReadStream(resolvedPath);
375
374
  }
376
375
  else if (runtime === "bun") {
@@ -70,7 +70,7 @@ class HeadersParser {
70
70
  }
71
71
  forEach(callback) {
72
72
  for (const [key, value] of this.headers) {
73
- callback(key, value);
73
+ callback(value, key);
74
74
  }
75
75
  }
76
76
  toObject() {
@@ -83,10 +83,11 @@ class Request {
83
83
  return (0, formData_js_1.parseUrlEncodedBody)(this.rawRequest);
84
84
  }
85
85
  else if (contentType.includes("multipart/form-data")) {
86
- const boundary = contentType?.split("; ")?.[1]?.split("=")?.[1];
87
- if (!boundary) {
88
- throw Error("Boundary not found");
86
+ const boundaryMatch = contentType.match(/boundary=([^;]+)/);
87
+ if (!boundaryMatch) {
88
+ throw new Error("Boundary not found in multipart/form-data");
89
89
  }
90
+ const boundary = boundaryMatch[1];
90
91
  return await (0, formData_js_1.parseMultipartBody)(this.rawRequest, boundary, options);
91
92
  }
92
93
  else {
@@ -25,14 +25,13 @@ class Router extends MiddlewareConfigure_js_1.default {
25
25
  this.basePath = basePath;
26
26
  this.env = { ...env };
27
27
  this.triRouter = new TrieRouter(basePath);
28
- this.get.bind(this);
29
- this.post.bind(this);
30
- this.put.bind(this);
31
- this.delete.bind(this);
32
- this.all.bind(this);
33
- this.#routeAddTriNode.bind(this);
34
- this.addRouter.bind(this);
35
- this.group.bind(this);
28
+ this.get = this.get.bind(this);
29
+ this.post = this.post.bind(this);
30
+ this.put = this.put.bind(this);
31
+ this.delete = this.delete.bind(this);
32
+ this.all = this.all.bind(this);
33
+ this.addRouter = this.addRouter.bind(this);
34
+ this.group = this.group.bind(this);
36
35
  }
37
36
  static(...args) {
38
37
  let route = "";
@@ -179,7 +178,7 @@ class Router extends MiddlewareConfigure_js_1.default {
179
178
  finalMiddleware = new Set(middlewares);
180
179
  }
181
180
  let p = parts.join("/");
182
- if (/(\/\*|\?)/.test(`/${p}`)) {
181
+ if (url_js_1.wildcardOrOptionalParamRegex.test(`/${p}`)) {
183
182
  let handler = this.routers.get(p);
184
183
  if (!handler) {
185
184
  handler = new Map();
@@ -122,18 +122,22 @@ class TezX extends router_js_1.Router {
122
122
  }
123
123
  return middlewares;
124
124
  }
125
- async #handleRequest(req, options) {
126
- let ctx = new context_js_1.Context(req, options);
127
- const urlRef = ctx.req.urlRef;
128
- const { pathname } = urlRef;
125
+ async #resolvePath(pathname) {
129
126
  let resolvePath = pathname;
130
127
  if (this.#onPathResolve) {
131
- resolvePath = this.#onPathResolve(pathname);
128
+ resolvePath = await this.#onPathResolve(pathname);
132
129
  config_js_1.GlobalConfig.debugging.warn(`${colors_js_1.COLORS.white} PATH RESOLVE ${colors_js_1.COLORS.reset} ${colors_js_1.COLORS.red}${pathname}${colors_js_1.COLORS.reset} ➞ ${colors_js_1.COLORS.cyan}${resolvePath}${colors_js_1.COLORS.reset}`);
133
130
  }
134
131
  if (typeof resolvePath !== "string") {
135
132
  throw new Error(`Path resolution failed: expected a string, got ${typeof resolvePath}`);
136
133
  }
134
+ return resolvePath;
135
+ }
136
+ async #handleRequest(req, options) {
137
+ let ctx = new context_js_1.Context(req, options);
138
+ const urlRef = ctx.req.urlRef;
139
+ const { pathname } = urlRef;
140
+ let resolvePath = await this.#resolvePath(pathname);
137
141
  let middlewares = this.#findMiddleware(resolvePath);
138
142
  ctx.env = this.env;
139
143
  try {
@@ -179,15 +183,18 @@ class TezX extends router_js_1.Router {
179
183
  return finalResponse()(ctx);
180
184
  }
181
185
  catch (err) {
182
- let error = err;
183
- if (err instanceof Error) {
184
- error = err.stack;
185
- }
186
- config_js_1.GlobalConfig.debugging.error(`${colors_js_1.COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${colors_js_1.COLORS.reset}`, `${context_js_1.httpStatusMap[500]}: ${error} `);
187
- let res = await config_js_1.GlobalConfig.onError(error, ctx);
188
- ctx.setStatus = res.status;
189
- return res;
186
+ return this.#handleError(err, ctx);
187
+ }
188
+ }
189
+ async #handleError(err, ctx) {
190
+ let error = err;
191
+ if (err instanceof Error) {
192
+ error = err.stack;
190
193
  }
194
+ config_js_1.GlobalConfig.debugging.error(`${colors_js_1.COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${colors_js_1.COLORS.reset}`, `${context_js_1.httpStatusMap[500]}: ${error} `);
195
+ let res = await config_js_1.GlobalConfig.onError(error, ctx);
196
+ ctx.setStatus = res.status;
197
+ return res;
191
198
  }
192
199
  async serve(req, options) {
193
200
  return this.#handleRequest(req, options);
package/cjs/index.js CHANGED
@@ -7,4 +7,4 @@ var server_js_1 = require("./core/server.js");
7
7
  Object.defineProperty(exports, "TezX", { enumerable: true, get: function () { return server_js_1.TezX; } });
8
8
  var params_js_1 = require("./utils/params.js");
9
9
  Object.defineProperty(exports, "useParams", { enumerable: true, get: function () { return params_js_1.useParams; } });
10
- exports.version = "1.0.58";
10
+ exports.version = "1.0.60";
@@ -4,9 +4,9 @@ exports.parseJsonBody = parseJsonBody;
4
4
  exports.parseTextBody = parseTextBody;
5
5
  exports.parseUrlEncodedBody = parseUrlEncodedBody;
6
6
  exports.parseMultipartBody = parseMultipartBody;
7
- const environment_js_1 = require("../core/environment.js");
7
+ const config_js_1 = require("../core/config.js");
8
8
  async function parseJsonBody(req) {
9
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
9
+ const runtime = config_js_1.GlobalConfig.adapter;
10
10
  if (runtime === "node") {
11
11
  return new Promise((resolve, reject) => {
12
12
  let body = "";
@@ -31,7 +31,7 @@ async function parseJsonBody(req) {
31
31
  }
32
32
  }
33
33
  async function parseTextBody(req) {
34
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
34
+ const runtime = config_js_1.GlobalConfig.adapter;
35
35
  if (runtime === "node") {
36
36
  return new Promise((resolve, reject) => {
37
37
  let body = "";
@@ -56,7 +56,7 @@ async function parseTextBody(req) {
56
56
  }
57
57
  }
58
58
  async function parseUrlEncodedBody(req) {
59
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
59
+ const runtime = config_js_1.GlobalConfig.adapter;
60
60
  if (runtime === "node") {
61
61
  return new Promise((resolve, reject) => {
62
62
  let body = "";
@@ -92,7 +92,7 @@ async function parseUrlEncodedBody(req) {
92
92
  }
93
93
  }
94
94
  async function parseMultipartBody(req, boundary, options) {
95
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
95
+ const runtime = config_js_1.GlobalConfig.adapter;
96
96
  if (runtime === "node") {
97
97
  return new Promise((resolve, reject) => {
98
98
  let body = "";
@@ -126,8 +126,8 @@ async function getFiles(dir, basePath = "/", ref, option) {
126
126
  }
127
127
  }
128
128
  else {
129
- const fs = await Promise.resolve().then(() => require("fs/promises"));
130
- const path = await Promise.resolve().then(() => require("path"));
129
+ const fs = await Promise.resolve().then(() => require("node:fs/promises"));
130
+ const path = await Promise.resolve().then(() => require("node:path"));
131
131
  const entries = await fs.readdir(dir, { withFileTypes: true });
132
132
  for (const entry of entries) {
133
133
  const fullPath = path.join(dir, entry.name);
package/cjs/utils/url.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.wildcardOrOptionalParamRegex = void 0;
3
4
  exports.sanitizePathSplit = sanitizePathSplit;
4
5
  exports.urlParse = urlParse;
5
6
  function sanitizePathSplit(basePath, path) {
@@ -9,6 +10,7 @@ function sanitizePathSplit(basePath, path) {
9
10
  .filter(Boolean);
10
11
  return parts;
11
12
  }
13
+ exports.wildcardOrOptionalParamRegex = /\/\*|:[^/]+[?*]/;
12
14
  function urlParse(url) {
13
15
  let u = URL.parse(url);
14
16
  let query = {};
@@ -10,7 +10,7 @@ export declare class TriMiddleware {
10
10
  constructor(pathname?: string);
11
11
  }
12
12
  export default class MiddlewareConfigure<T extends Record<string, any> = {}> extends CommonHandler {
13
- triMiddlewares: TriMiddleware;
13
+ protected triMiddlewares: TriMiddleware;
14
14
  protected basePath: string;
15
15
  constructor(basePath?: string);
16
16
  protected addMiddleware(pathname: string, middlewares: Middleware<T>[]): void;
package/core/config.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { loggerOutput } from "../utils/debugging.js";
2
+ import { EnvironmentDetector } from "./environment.js";
2
3
  export let GlobalConfig = class {
3
4
  static notFound = (ctx) => {
4
5
  const { method, urlRef: { pathname }, } = ctx.req;
@@ -11,7 +12,7 @@ export let GlobalConfig = class {
11
12
  static overwriteMethod = true;
12
13
  static debugMode = false;
13
14
  static server;
14
- static adapter;
15
+ static adapter = EnvironmentDetector.getEnvironment;
15
16
  static get debugging() {
16
17
  return this.debugMode
17
18
  ? {
package/core/context.js CHANGED
@@ -90,8 +90,7 @@ export class Context {
90
90
  this.#rawRequest = req;
91
91
  this.method = req?.method?.toUpperCase();
92
92
  this.#requestHeaders = new HeadersParser(req?.headers);
93
- if (EnvironmentDetector.getEnvironment == "node" ||
94
- GlobalConfig.adapter == "node") {
93
+ if (GlobalConfig.adapter == "node") {
95
94
  let encrypted = req?.socket?.encrypted;
96
95
  const protocol = typeof encrypted === "boolean"
97
96
  ? encrypted
@@ -283,7 +282,7 @@ export class Context {
283
282
  let fileExists = false;
284
283
  const runtime = EnvironmentDetector.getEnvironment;
285
284
  if (runtime === "node") {
286
- const { existsSync } = await import("fs");
285
+ const { existsSync } = await import("node:fs");
287
286
  fileExists = existsSync(filePath);
288
287
  }
289
288
  else if (runtime === "bun") {
@@ -303,7 +302,7 @@ export class Context {
303
302
  }
304
303
  let fileBuffer;
305
304
  if (runtime === "node") {
306
- const { readFileSync } = await import("fs");
305
+ const { readFileSync } = await import("node:fs");
307
306
  fileBuffer = await readFileSync(filePath);
308
307
  }
309
308
  else if (runtime === "bun") {
@@ -333,7 +332,7 @@ export class Context {
333
332
  const resolvedPath = filePath;
334
333
  let fileExists = false;
335
334
  if (runtime === "node") {
336
- const { existsSync } = await import("fs");
335
+ const { existsSync } = await import("node:fs");
337
336
  fileExists = existsSync(resolvedPath);
338
337
  }
339
338
  else if (runtime === "bun") {
@@ -353,7 +352,7 @@ export class Context {
353
352
  }
354
353
  let fileSize = 0;
355
354
  if (runtime === "node") {
356
- const { statSync } = await import("fs");
355
+ const { statSync } = await import("node:fs");
357
356
  fileSize = statSync(resolvedPath).size;
358
357
  }
359
358
  else if (runtime === "bun") {
@@ -367,7 +366,7 @@ export class Context {
367
366
  const mimeType = mimeTypes[ext] || defaultMimeType;
368
367
  let fileStream;
369
368
  if (runtime === "node") {
370
- const { createReadStream } = await import("fs");
369
+ const { createReadStream } = await import("node:fs");
371
370
  fileStream = createReadStream(resolvedPath);
372
371
  }
373
372
  else if (runtime === "bun") {
package/core/header.d.ts CHANGED
@@ -62,7 +62,7 @@ export declare class HeadersParser {
62
62
  * Iterates over headers and executes a callback function.
63
63
  * @param callback - Function to execute for each header.
64
64
  */
65
- forEach(callback: (key: string, value: string[]) => void): void;
65
+ forEach(callback: (value: string[], key: string) => void): void;
66
66
  /**
67
67
  * Converts headers into a plain object.
68
68
  * @returns A record of headers where single-value headers are returned as a string.
package/core/header.js CHANGED
@@ -67,7 +67,7 @@ export class HeadersParser {
67
67
  }
68
68
  forEach(callback) {
69
69
  for (const [key, value] of this.headers) {
70
- callback(key, value);
70
+ callback(value, key);
71
71
  }
72
72
  }
73
73
  toObject() {
package/core/request.d.ts CHANGED
@@ -128,7 +128,7 @@ export declare class Request {
128
128
  * console.log(key, value);
129
129
  * });
130
130
  */
131
- forEach: (callback: (key: string, value: string[]) => void) => void;
131
+ forEach: (callback: (value: string[], key: string) => void) => void;
132
132
  /**
133
133
  * Converts all headers into a plain JavaScript object.
134
134
  * Single-value headers are represented as a string, and multi-value headers as an array.
package/core/request.js CHANGED
@@ -80,10 +80,11 @@ export class Request {
80
80
  return parseUrlEncodedBody(this.rawRequest);
81
81
  }
82
82
  else if (contentType.includes("multipart/form-data")) {
83
- const boundary = contentType?.split("; ")?.[1]?.split("=")?.[1];
84
- if (!boundary) {
85
- throw Error("Boundary not found");
83
+ const boundaryMatch = contentType.match(/boundary=([^;]+)/);
84
+ if (!boundaryMatch) {
85
+ throw new Error("Boundary not found in multipart/form-data");
86
86
  }
87
+ const boundary = boundaryMatch[1];
87
88
  return await parseMultipartBody(this.rawRequest, boundary, options);
88
89
  }
89
90
  else {
package/core/router.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getFiles } from "../utils/staticFile.js";
2
- import { sanitizePathSplit } from "../utils/url.js";
2
+ import { sanitizePathSplit, wildcardOrOptionalParamRegex } from "../utils/url.js";
3
3
  import { GlobalConfig } from "./config.js";
4
4
  import MiddlewareConfigure, { TriMiddleware, } from "./MiddlewareConfigure.js";
5
5
  class TrieRouter {
@@ -22,14 +22,13 @@ export class Router extends MiddlewareConfigure {
22
22
  this.basePath = basePath;
23
23
  this.env = { ...env };
24
24
  this.triRouter = new TrieRouter(basePath);
25
- this.get.bind(this);
26
- this.post.bind(this);
27
- this.put.bind(this);
28
- this.delete.bind(this);
29
- this.all.bind(this);
30
- this.#routeAddTriNode.bind(this);
31
- this.addRouter.bind(this);
32
- this.group.bind(this);
25
+ this.get = this.get.bind(this);
26
+ this.post = this.post.bind(this);
27
+ this.put = this.put.bind(this);
28
+ this.delete = this.delete.bind(this);
29
+ this.all = this.all.bind(this);
30
+ this.addRouter = this.addRouter.bind(this);
31
+ this.group = this.group.bind(this);
33
32
  }
34
33
  static(...args) {
35
34
  let route = "";
@@ -176,7 +175,7 @@ export class Router extends MiddlewareConfigure {
176
175
  finalMiddleware = new Set(middlewares);
177
176
  }
178
177
  let p = parts.join("/");
179
- if (/(\/\*|\?)/.test(`/${p}`)) {
178
+ if (wildcardOrOptionalParamRegex.test(`/${p}`)) {
180
179
  let handler = this.routers.get(p);
181
180
  if (!handler) {
182
181
  handler = new Map();
package/core/server.js CHANGED
@@ -119,18 +119,22 @@ export class TezX extends Router {
119
119
  }
120
120
  return middlewares;
121
121
  }
122
- async #handleRequest(req, options) {
123
- let ctx = new Context(req, options);
124
- const urlRef = ctx.req.urlRef;
125
- const { pathname } = urlRef;
122
+ async #resolvePath(pathname) {
126
123
  let resolvePath = pathname;
127
124
  if (this.#onPathResolve) {
128
- resolvePath = this.#onPathResolve(pathname);
125
+ resolvePath = await this.#onPathResolve(pathname);
129
126
  GlobalConfig.debugging.warn(`${COLORS.white} PATH RESOLVE ${COLORS.reset} ${COLORS.red}${pathname}${COLORS.reset} ➞ ${COLORS.cyan}${resolvePath}${COLORS.reset}`);
130
127
  }
131
128
  if (typeof resolvePath !== "string") {
132
129
  throw new Error(`Path resolution failed: expected a string, got ${typeof resolvePath}`);
133
130
  }
131
+ return resolvePath;
132
+ }
133
+ async #handleRequest(req, options) {
134
+ let ctx = new Context(req, options);
135
+ const urlRef = ctx.req.urlRef;
136
+ const { pathname } = urlRef;
137
+ let resolvePath = await this.#resolvePath(pathname);
134
138
  let middlewares = this.#findMiddleware(resolvePath);
135
139
  ctx.env = this.env;
136
140
  try {
@@ -176,15 +180,18 @@ export class TezX extends Router {
176
180
  return finalResponse()(ctx);
177
181
  }
178
182
  catch (err) {
179
- let error = err;
180
- if (err instanceof Error) {
181
- error = err.stack;
182
- }
183
- GlobalConfig.debugging.error(`${COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${COLORS.reset}`, `${httpStatusMap[500]}: ${error} `);
184
- let res = await GlobalConfig.onError(error, ctx);
185
- ctx.setStatus = res.status;
186
- return res;
183
+ return this.#handleError(err, ctx);
184
+ }
185
+ }
186
+ async #handleError(err, ctx) {
187
+ let error = err;
188
+ if (err instanceof Error) {
189
+ error = err.stack;
187
190
  }
191
+ GlobalConfig.debugging.error(`${COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${COLORS.reset}`, `${httpStatusMap[500]}: ${error} `);
192
+ let res = await GlobalConfig.onError(error, ctx);
193
+ ctx.setStatus = res.status;
194
+ return res;
188
195
  }
189
196
  async serve(req, options) {
190
197
  return this.#handleRequest(req, options);
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
1
  export { Router } from "./core/router.js";
2
2
  export { TezX } from "./core/server.js";
3
3
  export { useParams } from "./utils/params.js";
4
- export let version = "1.0.58";
4
+ export let version = "1.0.60";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tezx",
3
- "version": "1.0.58",
3
+ "version": "1.0.60",
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",
package/utils/formData.js CHANGED
@@ -1,6 +1,6 @@
1
- import { EnvironmentDetector } from "../core/environment.js";
1
+ import { GlobalConfig } from "../core/config.js";
2
2
  export async function parseJsonBody(req) {
3
- const runtime = EnvironmentDetector.getEnvironment;
3
+ const runtime = GlobalConfig.adapter;
4
4
  if (runtime === "node") {
5
5
  return new Promise((resolve, reject) => {
6
6
  let body = "";
@@ -25,7 +25,7 @@ export async function parseJsonBody(req) {
25
25
  }
26
26
  }
27
27
  export async function parseTextBody(req) {
28
- const runtime = EnvironmentDetector.getEnvironment;
28
+ const runtime = GlobalConfig.adapter;
29
29
  if (runtime === "node") {
30
30
  return new Promise((resolve, reject) => {
31
31
  let body = "";
@@ -50,7 +50,7 @@ export async function parseTextBody(req) {
50
50
  }
51
51
  }
52
52
  export async function parseUrlEncodedBody(req) {
53
- const runtime = EnvironmentDetector.getEnvironment;
53
+ const runtime = GlobalConfig.adapter;
54
54
  if (runtime === "node") {
55
55
  return new Promise((resolve, reject) => {
56
56
  let body = "";
@@ -86,7 +86,7 @@ export async function parseUrlEncodedBody(req) {
86
86
  }
87
87
  }
88
88
  export async function parseMultipartBody(req, boundary, options) {
89
- const runtime = EnvironmentDetector.getEnvironment;
89
+ const runtime = GlobalConfig.adapter;
90
90
  if (runtime === "node") {
91
91
  return new Promise((resolve, reject) => {
92
92
  let body = "";
@@ -122,8 +122,8 @@ export async function getFiles(dir, basePath = "/", ref, option) {
122
122
  }
123
123
  }
124
124
  else {
125
- const fs = await import("fs/promises");
126
- const path = await import("path");
125
+ const fs = await import("node:fs/promises");
126
+ const path = await import("node:path");
127
127
  const entries = await fs.readdir(dir, { withFileTypes: true });
128
128
  for (const entry of entries) {
129
129
  const fullPath = path.join(dir, entry.name);
package/utils/url.d.ts CHANGED
@@ -10,4 +10,5 @@ export type UrlRef = {
10
10
  pathname: string | undefined;
11
11
  };
12
12
  export declare function sanitizePathSplit(basePath: string, path: string): string[];
13
+ export declare const wildcardOrOptionalParamRegex: RegExp;
13
14
  export declare function urlParse(url: string): UrlRef;
package/utils/url.js CHANGED
@@ -5,6 +5,7 @@ export function sanitizePathSplit(basePath, path) {
5
5
  .filter(Boolean);
6
6
  return parts;
7
7
  }
8
+ export const wildcardOrOptionalParamRegex = /\/\*|:[^/]+[?*]/;
8
9
  export function urlParse(url) {
9
10
  let u = URL.parse(url);
10
11
  let query = {};