tezx 1.0.7 → 1.0.8
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.d.ts +52 -33
- package/dist/index.js +188 -172
- package/dist/index.mjs +184 -171
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -212,7 +212,11 @@ declare class Context<T extends Record<string, any> = {}> {
|
|
|
212
212
|
* @type {HeadersParser}
|
|
213
213
|
*/
|
|
214
214
|
headers: HeadersParser;
|
|
215
|
-
|
|
215
|
+
/**
|
|
216
|
+
* Parser for handling and manipulating HTTP response(Read Only)
|
|
217
|
+
* @type {Response}
|
|
218
|
+
*/
|
|
219
|
+
readonly res: Response | undefined;
|
|
216
220
|
/**
|
|
217
221
|
* Request path without query parameters
|
|
218
222
|
* @type {string}
|
|
@@ -417,7 +421,7 @@ declare class MiddlewareConfigure<T extends Record<string, any> = {}> extends Co
|
|
|
417
421
|
type NextCallback = () => Promise<any>;
|
|
418
422
|
type ctx<T extends Record<string, any> = {}> = Context<T> & T;
|
|
419
423
|
type Callback<T extends Record<string, any> = {}> = (ctx: ctx<T>) => Promise<Response> | Response;
|
|
420
|
-
type Middleware<T extends Record<string, any> = {}> = (ctx: ctx<T>, next: NextCallback) => NextCallback | Promise<Response> | Response;
|
|
424
|
+
type Middleware<T extends Record<string, any> = {}> = (ctx: ctx<T>, next: NextCallback) => NextCallback | Promise<NextCallback | Response> | Response;
|
|
421
425
|
type RouterConfig = {
|
|
422
426
|
/**
|
|
423
427
|
* `env` allows you to define environment variables for the router.
|
|
@@ -610,15 +614,6 @@ interface ServeResponse {
|
|
|
610
614
|
body: string;
|
|
611
615
|
statusText: string;
|
|
612
616
|
}
|
|
613
|
-
type LoggerFnType = () => {
|
|
614
|
-
request?: (method: HTTPMethod, pathname: string) => void;
|
|
615
|
-
response?: (method: HTTPMethod, pathname: string, status?: number) => void;
|
|
616
|
-
info?: (msg: string, ...args: unknown[]) => void;
|
|
617
|
-
warn?: (msg: string, ...args: unknown[]) => void;
|
|
618
|
-
error?: (msg: string, ...args: unknown[]) => void;
|
|
619
|
-
debug?: (msg: string, ...args: unknown[]) => void;
|
|
620
|
-
success?: (msg: string, ...args: unknown[]) => void;
|
|
621
|
-
};
|
|
622
617
|
type TezXConfig = {
|
|
623
618
|
/**
|
|
624
619
|
* `allowDuplicateMw` determines whether duplicate middleware functions
|
|
@@ -644,16 +639,17 @@ type TezXConfig = {
|
|
|
644
639
|
*/
|
|
645
640
|
overwriteMethod?: boolean;
|
|
646
641
|
/**
|
|
647
|
-
*
|
|
648
|
-
*
|
|
642
|
+
* Enables or disables debugging for the middleware.
|
|
643
|
+
* When set to `true`, detailed debug logs will be output,
|
|
644
|
+
* useful for tracking the flow of requests and identifying issues.
|
|
649
645
|
*
|
|
650
|
-
*
|
|
646
|
+
* @default false
|
|
651
647
|
*/
|
|
652
|
-
|
|
648
|
+
debugMode?: boolean;
|
|
653
649
|
} & RouterConfig;
|
|
654
650
|
declare class TezX<T extends Record<string, any> = {}> extends Router<T> {
|
|
655
651
|
#private;
|
|
656
|
-
constructor({ basePath, env,
|
|
652
|
+
constructor({ basePath, env, debugMode, allowDuplicateMw, overwriteMethod, }?: TezXConfig);
|
|
657
653
|
protected findRoute(method: HTTPMethod, pathname: string): {
|
|
658
654
|
callback: any;
|
|
659
655
|
middlewares: Middleware<T>[];
|
|
@@ -681,26 +677,16 @@ declare function useParams({ path, urlPattern, }: {
|
|
|
681
677
|
};
|
|
682
678
|
|
|
683
679
|
/**
|
|
684
|
-
*
|
|
685
|
-
* @
|
|
680
|
+
* Generate a unique request ID
|
|
681
|
+
* @returns {string} - A unique request identifier
|
|
686
682
|
*/
|
|
687
|
-
declare function
|
|
683
|
+
declare function generateID(): string;
|
|
688
684
|
|
|
689
|
-
type LogLevel = "info" | "warn" | "error" | "debug" | "success";
|
|
690
685
|
/**
|
|
691
|
-
*
|
|
692
|
-
* @param
|
|
693
|
-
* @param callback - The operation to measure and execute.
|
|
686
|
+
* Loads environment variables from .env files.
|
|
687
|
+
* @param basePath - The base directory where .env files are located.
|
|
694
688
|
*/
|
|
695
|
-
declare function
|
|
696
|
-
request: (method: HTTPMethod, pathname: string) => void;
|
|
697
|
-
response: (method: HTTPMethod, pathname: string, status?: number) => void;
|
|
698
|
-
info: (msg: string, ...args: unknown[]) => void;
|
|
699
|
-
warn: (msg: string, ...args: unknown[]) => void;
|
|
700
|
-
error: (msg: string, ...args: unknown[]) => void;
|
|
701
|
-
debug: (msg: string, ...args: unknown[]) => void;
|
|
702
|
-
success: (msg: string, ...args: unknown[]) => void;
|
|
703
|
-
};
|
|
689
|
+
declare function loadEnv(basePath?: string): Record<string, string>;
|
|
704
690
|
|
|
705
691
|
type CorsOptions = {
|
|
706
692
|
origin?: string | RegExp | (string | RegExp)[] | ((reqOrigin: string) => boolean);
|
|
@@ -712,4 +698,37 @@ type CorsOptions = {
|
|
|
712
698
|
};
|
|
713
699
|
declare function cors(option?: CorsOptions): (ctx: ctx, next: () => Promise<any>) => Promise<any>;
|
|
714
700
|
|
|
715
|
-
|
|
701
|
+
/**
|
|
702
|
+
* Logger Middleware
|
|
703
|
+
* Logs incoming requests with method, pathname, status, and execution time.
|
|
704
|
+
*
|
|
705
|
+
* @returns {Middleware} - A middleware function for logging HTTP requests.
|
|
706
|
+
*
|
|
707
|
+
* @example
|
|
708
|
+
* ```ts
|
|
709
|
+
* import { logger } from 'tezx';
|
|
710
|
+
*
|
|
711
|
+
* app.use(logger());
|
|
712
|
+
* ```
|
|
713
|
+
*/
|
|
714
|
+
declare function logger(): Middleware;
|
|
715
|
+
|
|
716
|
+
/**
|
|
717
|
+
* PoweredBy Middleware
|
|
718
|
+
* Adds an "X-Powered-By" header to responses.
|
|
719
|
+
*
|
|
720
|
+
* @param {string} [serverName] - Optional custom server name; defaults to "TezX".
|
|
721
|
+
* @returns {Middleware} - A middleware function for setting the "X-Powered-By" header.
|
|
722
|
+
*
|
|
723
|
+
* @example
|
|
724
|
+
* ```ts
|
|
725
|
+
* import { poweredBy } from 'tezx';
|
|
726
|
+
*
|
|
727
|
+
* app.use(poweredBy("MyServer"));
|
|
728
|
+
* ```
|
|
729
|
+
*/
|
|
730
|
+
declare const poweredBy: (serverName?: string) => Middleware;
|
|
731
|
+
|
|
732
|
+
declare let version: string;
|
|
733
|
+
|
|
734
|
+
export { type Callback, type ctx as Context, type CorsOptions, type Middleware, type NextCallback, Router, type RouterConfig, type StaticServeOption, TezX, type TezXConfig, type UrlRef, bunAdapter, cors, denoAdapter, generateID, loadEnv, logger, nodeAdapter, poweredBy, useParams, version };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const COLORS = {
|
|
4
|
+
reset: "\x1B[0m",
|
|
5
|
+
bold: "\x1B[1m",
|
|
6
|
+
underline: "\x1B[4m",
|
|
7
|
+
gray: "\x1B[90m",
|
|
8
|
+
white: "\x1B[97m",
|
|
9
|
+
black: "\x1B[30m",
|
|
10
|
+
red: "\x1B[31m",
|
|
11
|
+
green: "\x1B[32m",
|
|
12
|
+
yellow: "\x1B[33m",
|
|
13
|
+
blue: "\x1B[34m",
|
|
14
|
+
magenta: "\x1B[35m",
|
|
15
|
+
cyan: "\x1B[36m",
|
|
16
|
+
bgRed: "\x1B[41m",
|
|
17
|
+
bgGreen: "\x1B[42m",
|
|
18
|
+
bgYellow: "\x1B[43m",
|
|
19
|
+
bgBlue: "\x1B[44m",
|
|
20
|
+
bgMagenta: "\x1B[45m",
|
|
21
|
+
bgCyan: "\x1B[46m",
|
|
22
|
+
bgWhite: "\x1B[47m"
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const loggerOutput = (level, message, ...args) => {
|
|
26
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
27
|
+
const LEVEL_COLORS = {
|
|
28
|
+
info: COLORS.blue,
|
|
29
|
+
warn: COLORS.yellow,
|
|
30
|
+
error: COLORS.red,
|
|
31
|
+
debug: COLORS.cyan,
|
|
32
|
+
success: COLORS.green
|
|
33
|
+
};
|
|
34
|
+
const prefix = `${COLORS.gray}[${timestamp}]${COLORS.reset}`;
|
|
35
|
+
const levelText = `${LEVEL_COLORS[level]}[${level.toUpperCase()}]${COLORS.reset}`;
|
|
36
|
+
console.log(`${prefix} ${levelText} ${message}`, ...args?.flat());
|
|
37
|
+
};
|
|
38
|
+
|
|
3
39
|
let GlobalConfig = class {
|
|
4
40
|
static notFound = (ctx2) => {
|
|
5
41
|
const {
|
|
@@ -14,10 +50,27 @@ let GlobalConfig = class {
|
|
|
14
50
|
};
|
|
15
51
|
static allowDuplicateMw = false;
|
|
16
52
|
static overwriteMethod = true;
|
|
17
|
-
static
|
|
18
|
-
static
|
|
19
|
-
return {
|
|
20
|
-
|
|
53
|
+
static debugMode = false;
|
|
54
|
+
static get debugging() {
|
|
55
|
+
return this.debugMode ? {
|
|
56
|
+
info: (msg, ...args) => loggerOutput("info", msg, ...args),
|
|
57
|
+
warn: (msg, ...args) => loggerOutput("warn", msg, ...args),
|
|
58
|
+
error: (msg, ...args) => loggerOutput("error", msg, ...args),
|
|
59
|
+
debug: (msg, ...args) => loggerOutput("debug", msg, ...args),
|
|
60
|
+
success: (msg, ...args) => loggerOutput("success", msg, ...args)
|
|
61
|
+
} : {
|
|
62
|
+
info: (msg, ...args) => {
|
|
63
|
+
},
|
|
64
|
+
warn: (msg, ...args) => {
|
|
65
|
+
},
|
|
66
|
+
error: (msg, ...args) => {
|
|
67
|
+
},
|
|
68
|
+
debug: (msg, ...args) => {
|
|
69
|
+
},
|
|
70
|
+
success: (msg, ...args) => {
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
}
|
|
21
74
|
};
|
|
22
75
|
|
|
23
76
|
function denoAdapter(TezX2) {
|
|
@@ -45,10 +98,7 @@ function denoAdapter(TezX2) {
|
|
|
45
98
|
if (typeof callback === "function") {
|
|
46
99
|
callback(message);
|
|
47
100
|
} else {
|
|
48
|
-
|
|
49
|
-
if (logger.success) {
|
|
50
|
-
logger.success(message);
|
|
51
|
-
}
|
|
101
|
+
GlobalConfig.debugging.success(message);
|
|
52
102
|
}
|
|
53
103
|
return server;
|
|
54
104
|
} catch (err) {
|
|
@@ -86,10 +136,7 @@ function bunAdapter(TezX2) {
|
|
|
86
136
|
if (typeof callback == "function") {
|
|
87
137
|
callback(message);
|
|
88
138
|
} else {
|
|
89
|
-
|
|
90
|
-
if (logger.success) {
|
|
91
|
-
logger.success(message);
|
|
92
|
-
}
|
|
139
|
+
GlobalConfig.debugging.success(message);
|
|
93
140
|
}
|
|
94
141
|
return server;
|
|
95
142
|
} catch (err) {
|
|
@@ -128,10 +175,7 @@ function nodeAdapter(TezX2) {
|
|
|
128
175
|
if (typeof callback == "function") {
|
|
129
176
|
callback(message);
|
|
130
177
|
} else {
|
|
131
|
-
|
|
132
|
-
if (logger.success) {
|
|
133
|
-
logger.success(message);
|
|
134
|
-
}
|
|
178
|
+
GlobalConfig.debugging.success(message);
|
|
135
179
|
}
|
|
136
180
|
return server;
|
|
137
181
|
});
|
|
@@ -205,7 +249,7 @@ function urlParse(url) {
|
|
|
205
249
|
};
|
|
206
250
|
}
|
|
207
251
|
);
|
|
208
|
-
return paramsObj.reduce(function(total, value) {
|
|
252
|
+
return paramsObj.reduce(function (total, value) {
|
|
209
253
|
return { ...total, ...value };
|
|
210
254
|
}, {});
|
|
211
255
|
} else {
|
|
@@ -1450,11 +1494,11 @@ class Context {
|
|
|
1450
1494
|
* @type {HeadersParser}
|
|
1451
1495
|
*/
|
|
1452
1496
|
headers = new HeadersParser();
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
res
|
|
1497
|
+
/**
|
|
1498
|
+
* Parser for handling and manipulating HTTP response(Read Only)
|
|
1499
|
+
* @type {Response}
|
|
1500
|
+
*/
|
|
1501
|
+
res;
|
|
1458
1502
|
/**
|
|
1459
1503
|
* Request path without query parameters
|
|
1460
1504
|
* @type {string}
|
|
@@ -1522,12 +1566,12 @@ class Context {
|
|
|
1522
1566
|
* @type {any}
|
|
1523
1567
|
*/
|
|
1524
1568
|
#preparedHeaders;
|
|
1525
|
-
/**
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1569
|
+
// /**
|
|
1570
|
+
// * Native response object reference
|
|
1571
|
+
// * @private
|
|
1572
|
+
// * @type {any}
|
|
1573
|
+
// */
|
|
1574
|
+
// res: any;
|
|
1531
1575
|
/**
|
|
1532
1576
|
* Flag indicating if the response is fresh/unmodified
|
|
1533
1577
|
* @private
|
|
@@ -1660,10 +1704,10 @@ class Context {
|
|
|
1660
1704
|
} else if (typeof args[0] === "object") {
|
|
1661
1705
|
headers = { ...headers, ...args[0] };
|
|
1662
1706
|
}
|
|
1663
|
-
return this.#handleResponse(
|
|
1707
|
+
return this.#handleResponse(JSON.stringify(body), {
|
|
1664
1708
|
status,
|
|
1665
1709
|
headers
|
|
1666
|
-
})
|
|
1710
|
+
});
|
|
1667
1711
|
}
|
|
1668
1712
|
send(body, ...args) {
|
|
1669
1713
|
let status = this.#status;
|
|
@@ -1686,10 +1730,10 @@ class Context {
|
|
|
1686
1730
|
headers["Content-Type"] = "application/octet-stream";
|
|
1687
1731
|
}
|
|
1688
1732
|
}
|
|
1689
|
-
return this.#handleResponse(
|
|
1733
|
+
return this.#handleResponse(body, {
|
|
1690
1734
|
status,
|
|
1691
1735
|
headers
|
|
1692
|
-
})
|
|
1736
|
+
});
|
|
1693
1737
|
}
|
|
1694
1738
|
html(data, ...args) {
|
|
1695
1739
|
let status = this.#status;
|
|
@@ -1704,10 +1748,10 @@ class Context {
|
|
|
1704
1748
|
} else if (typeof args[0] === "object") {
|
|
1705
1749
|
headers = { ...headers, ...args[0] };
|
|
1706
1750
|
}
|
|
1707
|
-
return this.#handleResponse(
|
|
1751
|
+
return this.#handleResponse(data, {
|
|
1708
1752
|
status,
|
|
1709
1753
|
headers
|
|
1710
|
-
})
|
|
1754
|
+
});
|
|
1711
1755
|
}
|
|
1712
1756
|
text(data, ...args) {
|
|
1713
1757
|
let status = this.#status;
|
|
@@ -1722,10 +1766,10 @@ class Context {
|
|
|
1722
1766
|
} else if (typeof args[0] === "object") {
|
|
1723
1767
|
headers = { ...headers, ...args[0] };
|
|
1724
1768
|
}
|
|
1725
|
-
return this.#handleResponse(
|
|
1769
|
+
return this.#handleResponse(data, {
|
|
1726
1770
|
status,
|
|
1727
1771
|
headers
|
|
1728
|
-
})
|
|
1772
|
+
});
|
|
1729
1773
|
}
|
|
1730
1774
|
xml(data, ...args) {
|
|
1731
1775
|
let status = this.#status;
|
|
@@ -1740,10 +1784,10 @@ class Context {
|
|
|
1740
1784
|
} else if (typeof args[0] === "object") {
|
|
1741
1785
|
headers = { ...headers, ...args[0] };
|
|
1742
1786
|
}
|
|
1743
|
-
return this.#handleResponse(
|
|
1787
|
+
return this.#handleResponse(data, {
|
|
1744
1788
|
status,
|
|
1745
1789
|
headers
|
|
1746
|
-
})
|
|
1790
|
+
});
|
|
1747
1791
|
}
|
|
1748
1792
|
/**
|
|
1749
1793
|
* HTTP status code..
|
|
@@ -1807,14 +1851,14 @@ class Context {
|
|
|
1807
1851
|
} else if (runtime === "deno") {
|
|
1808
1852
|
fileBuffer = await Deno.readFile(filePath);
|
|
1809
1853
|
}
|
|
1810
|
-
return this.#handleResponse(
|
|
1854
|
+
return this.#handleResponse(fileBuffer, {
|
|
1811
1855
|
status: 200,
|
|
1812
1856
|
headers: {
|
|
1813
1857
|
"Content-Disposition": `attachment; filename="${fileName}"`,
|
|
1814
1858
|
"Content-Type": "application/octet-stream",
|
|
1815
1859
|
"Content-Length": fileBuffer.byteLength.toString()
|
|
1816
1860
|
}
|
|
1817
|
-
})
|
|
1861
|
+
});
|
|
1818
1862
|
} catch (error) {
|
|
1819
1863
|
throw Error("Internal Server Error" + error?.message);
|
|
1820
1864
|
}
|
|
@@ -1878,21 +1922,29 @@ class Context {
|
|
|
1878
1922
|
if (fileName) {
|
|
1879
1923
|
headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
1880
1924
|
}
|
|
1881
|
-
return this.#handleResponse(
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
})
|
|
1886
|
-
);
|
|
1925
|
+
return this.#handleResponse(fileStream, {
|
|
1926
|
+
status: 200,
|
|
1927
|
+
headers
|
|
1928
|
+
});
|
|
1887
1929
|
} catch (error) {
|
|
1888
1930
|
throw Error("Internal Server Error" + error?.message);
|
|
1889
1931
|
}
|
|
1890
1932
|
}
|
|
1891
|
-
#handleResponse(
|
|
1892
|
-
let
|
|
1893
|
-
|
|
1933
|
+
#handleResponse(body, { headers, status }) {
|
|
1934
|
+
let response = new Response(body, {
|
|
1935
|
+
status,
|
|
1936
|
+
headers
|
|
1937
|
+
});
|
|
1938
|
+
let clone = response.clone();
|
|
1939
|
+
this.res = response;
|
|
1894
1940
|
return clone;
|
|
1895
1941
|
}
|
|
1942
|
+
// get res() {
|
|
1943
|
+
// return this.res;
|
|
1944
|
+
// }
|
|
1945
|
+
// set res(res: Response) {
|
|
1946
|
+
// this.res = res;
|
|
1947
|
+
// }
|
|
1896
1948
|
/**
|
|
1897
1949
|
* Getter that creates a standardized Request object from internal state
|
|
1898
1950
|
* @returns {Request} - Normalized request object combining:
|
|
@@ -1987,8 +2039,8 @@ function useParams({
|
|
|
1987
2039
|
const paramName = patternSegment.slice(1, -1);
|
|
1988
2040
|
const nextPattern = patternSegments[i + 1];
|
|
1989
2041
|
if (nextPattern && !nextPattern.startsWith(":") && nextPattern !== "*" && pathIndex < pathLength && // !/test == /:user?/test
|
|
1990
|
-
|
|
1991
|
-
|
|
2042
|
+
// বর্তমান পথ যদি পরবর্তী প্যাটার্ন মানে স্ট্যাটিক পথ এর সাথে মাইল তাহলে
|
|
2043
|
+
pathSegments[pathIndex] === nextPattern) {
|
|
1992
2044
|
params[paramName] = null;
|
|
1993
2045
|
continue;
|
|
1994
2046
|
}
|
|
@@ -2036,15 +2088,14 @@ class TezX extends Router {
|
|
|
2036
2088
|
constructor({
|
|
2037
2089
|
basePath = "/",
|
|
2038
2090
|
env = {},
|
|
2039
|
-
|
|
2091
|
+
debugMode = false,
|
|
2040
2092
|
allowDuplicateMw = false,
|
|
2041
2093
|
overwriteMethod = true
|
|
2042
2094
|
} = {}) {
|
|
2043
2095
|
GlobalConfig.allowDuplicateMw = allowDuplicateMw;
|
|
2044
2096
|
GlobalConfig.overwriteMethod = overwriteMethod;
|
|
2045
|
-
if (
|
|
2046
|
-
GlobalConfig.
|
|
2047
|
-
GlobalConfig.enableLogger = true;
|
|
2097
|
+
if (debugMode) {
|
|
2098
|
+
GlobalConfig.debugMode = debugMode;
|
|
2048
2099
|
}
|
|
2049
2100
|
super({ basePath, env });
|
|
2050
2101
|
this.serve = this.serve.bind(this);
|
|
@@ -2109,13 +2160,16 @@ class TezX extends Router {
|
|
|
2109
2160
|
let index = 0;
|
|
2110
2161
|
const next = async () => {
|
|
2111
2162
|
if (index < middlewares.length) {
|
|
2112
|
-
return middlewares[index++](ctx, next);
|
|
2163
|
+
return await middlewares[index++](ctx, next);
|
|
2113
2164
|
} else {
|
|
2114
|
-
|
|
2115
|
-
return response;
|
|
2165
|
+
return await finalCallback(ctx);
|
|
2116
2166
|
}
|
|
2117
2167
|
};
|
|
2118
|
-
|
|
2168
|
+
const response = await next();
|
|
2169
|
+
if (!response) {
|
|
2170
|
+
throw new Error(`Handler did not return a response or next() was not called. Path: ${ctx.pathname}, Method: ${ctx.method}`);
|
|
2171
|
+
}
|
|
2172
|
+
return response;
|
|
2119
2173
|
};
|
|
2120
2174
|
}
|
|
2121
2175
|
#findMiddleware(pathname) {
|
|
@@ -2142,61 +2196,49 @@ class TezX extends Router {
|
|
|
2142
2196
|
const { pathname } = urlRef;
|
|
2143
2197
|
let middlewares = this.#findMiddleware(pathname);
|
|
2144
2198
|
ctx.env = this.env;
|
|
2145
|
-
const logger = GlobalConfig.loggerFn();
|
|
2146
|
-
if (logger.request) {
|
|
2147
|
-
logger.request(ctx.method, ctx.pathname);
|
|
2148
|
-
}
|
|
2149
2199
|
try {
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
}
|
|
2165
|
-
const statusText = response?.statusText || httpStatusMap[response?.status] || "";
|
|
2166
|
-
const status = response.status || ctx2.getStatus;
|
|
2167
|
-
let headers = ctx2.headers.toObject();
|
|
2168
|
-
if (logger.response) {
|
|
2169
|
-
logger.response(ctx2.method, ctx2.pathname, status);
|
|
2170
|
-
}
|
|
2171
|
-
if (response instanceof Response) {
|
|
2172
|
-
return new Response(response.body, {
|
|
2173
|
-
status,
|
|
2174
|
-
statusText,
|
|
2175
|
-
headers
|
|
2176
|
-
});
|
|
2177
|
-
}
|
|
2178
|
-
return new Response(response.body, {
|
|
2179
|
-
status,
|
|
2180
|
-
statusText,
|
|
2181
|
-
headers
|
|
2182
|
-
});
|
|
2183
|
-
} else {
|
|
2184
|
-
if (logger.response) {
|
|
2185
|
-
logger.response(ctx2.method, ctx2.pathname, 404);
|
|
2186
|
-
}
|
|
2187
|
-
return GlobalConfig.notFound(ctx2);
|
|
2188
|
-
}
|
|
2200
|
+
let callback = async (ctx2) => {
|
|
2201
|
+
const find = this.findRoute(ctx2.req.method, pathname);
|
|
2202
|
+
if (find?.callback) {
|
|
2203
|
+
ctx2.params = find.params;
|
|
2204
|
+
const callback2 = find.callback;
|
|
2205
|
+
let middlewares2 = find.middlewares;
|
|
2206
|
+
return await this.#createHandler(
|
|
2207
|
+
middlewares2,
|
|
2208
|
+
callback2
|
|
2209
|
+
)(ctx2);
|
|
2210
|
+
} else {
|
|
2211
|
+
let res = await GlobalConfig.notFound(ctx2);
|
|
2212
|
+
ctx2.setStatus = res.status;
|
|
2213
|
+
return res;
|
|
2189
2214
|
}
|
|
2190
|
-
|
|
2215
|
+
};
|
|
2216
|
+
let response = await this.#createHandler([...this.triMiddlewares.middlewares, ...middlewares], callback)(ctx);
|
|
2217
|
+
let finalResponse = () => {
|
|
2218
|
+
return (ctx2) => {
|
|
2219
|
+
if (response?.headers) {
|
|
2220
|
+
ctx2.headers.add(response.headers);
|
|
2221
|
+
}
|
|
2222
|
+
const statusText = response?.statusText || httpStatusMap[response?.status] || "";
|
|
2223
|
+
const status = response.status || ctx2.getStatus;
|
|
2224
|
+
let headers = ctx2.headers.toObject();
|
|
2225
|
+
return new Response(response.body, {
|
|
2226
|
+
status,
|
|
2227
|
+
statusText,
|
|
2228
|
+
headers
|
|
2229
|
+
});
|
|
2230
|
+
};
|
|
2231
|
+
};
|
|
2232
|
+
return finalResponse()(ctx);
|
|
2191
2233
|
} catch (err) {
|
|
2192
2234
|
let error = err;
|
|
2193
2235
|
if (err instanceof Error) {
|
|
2194
2236
|
error = err.stack;
|
|
2195
2237
|
}
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
return
|
|
2238
|
+
GlobalConfig.debugging.error(`${COLORS.bgRed}${ctx.pathname}, Method: ${ctx.method}${COLORS.reset}`, `${httpStatusMap[500]}: ${error} `);
|
|
2239
|
+
let res = await GlobalConfig.onError(error, ctx);
|
|
2240
|
+
ctx.setStatus = res.status;
|
|
2241
|
+
return res;
|
|
2200
2242
|
}
|
|
2201
2243
|
}
|
|
2202
2244
|
async serve(req) {
|
|
@@ -2204,6 +2246,13 @@ class TezX extends Router {
|
|
|
2204
2246
|
}
|
|
2205
2247
|
}
|
|
2206
2248
|
|
|
2249
|
+
function generateID() {
|
|
2250
|
+
const timestamp = Date.now().toString(16);
|
|
2251
|
+
const random = Math.floor(Math.random() * 281474976710655).toString(16).padStart(12, "0");
|
|
2252
|
+
const pid = (process.pid % 65536).toString(16).padStart(4, "0");
|
|
2253
|
+
return `${timestamp}-${random}-${pid}`;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
2207
2256
|
function parseEnvFile(filePath, result) {
|
|
2208
2257
|
try {
|
|
2209
2258
|
let fileExists = false;
|
|
@@ -2265,71 +2314,6 @@ function loadEnv(basePath = "./") {
|
|
|
2265
2314
|
return result;
|
|
2266
2315
|
}
|
|
2267
2316
|
|
|
2268
|
-
const COLORS = {
|
|
2269
|
-
reset: "\x1B[0m",
|
|
2270
|
-
bold: "\x1B[1m",
|
|
2271
|
-
gray: "\x1B[90m",
|
|
2272
|
-
red: "\x1B[31m",
|
|
2273
|
-
green: "\x1B[32m",
|
|
2274
|
-
yellow: "\x1B[33m",
|
|
2275
|
-
blue: "\x1B[34m",
|
|
2276
|
-
magenta: "\x1B[35m",
|
|
2277
|
-
cyan: "\x1B[36m",
|
|
2278
|
-
bgBlue: "\x1B[44m",
|
|
2279
|
-
bgMagenta: "\x1B[45m"};
|
|
2280
|
-
const loggerOutput = (level, message, ...args) => {
|
|
2281
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2282
|
-
const LEVEL_COLORS = {
|
|
2283
|
-
info: COLORS.blue,
|
|
2284
|
-
warn: COLORS.yellow,
|
|
2285
|
-
error: COLORS.red,
|
|
2286
|
-
debug: COLORS.cyan,
|
|
2287
|
-
success: COLORS.green
|
|
2288
|
-
};
|
|
2289
|
-
const prefix = `${COLORS.gray}[${timestamp}]${COLORS.reset}`;
|
|
2290
|
-
const levelText = `${LEVEL_COLORS[level]}[${level.toUpperCase()}]${COLORS.reset}`;
|
|
2291
|
-
console.log(`${prefix} ${levelText} ${message}`, ...args?.flat());
|
|
2292
|
-
};
|
|
2293
|
-
function logger() {
|
|
2294
|
-
const startTime = performance.now();
|
|
2295
|
-
if (GlobalConfig.enableLogger) {
|
|
2296
|
-
return {
|
|
2297
|
-
request: (method, pathname) => {
|
|
2298
|
-
console.log(
|
|
2299
|
-
`${COLORS.bold}<-- ${COLORS.reset}${COLORS.bgMagenta} ${method} ${COLORS.reset} ${pathname}`
|
|
2300
|
-
);
|
|
2301
|
-
},
|
|
2302
|
-
response: (method, pathname, status) => {
|
|
2303
|
-
const elapsed = performance.now() - startTime;
|
|
2304
|
-
console.log(
|
|
2305
|
-
`${COLORS.bold}--> ${COLORS.reset}${COLORS.bgBlue} ${method} ${COLORS.reset} ${pathname} ${COLORS.yellow}${status}${COLORS.reset} ${COLORS.magenta}${elapsed.toFixed(2)}ms${COLORS.reset}`
|
|
2306
|
-
);
|
|
2307
|
-
},
|
|
2308
|
-
info: (msg, ...args) => loggerOutput("info", msg, ...args),
|
|
2309
|
-
warn: (msg, ...args) => loggerOutput("warn", msg, ...args),
|
|
2310
|
-
error: (msg, ...args) => loggerOutput("error", msg, ...args),
|
|
2311
|
-
debug: (msg, ...args) => loggerOutput("debug", msg, ...args),
|
|
2312
|
-
success: (msg, ...args) => loggerOutput("success", msg, ...args)
|
|
2313
|
-
};
|
|
2314
|
-
}
|
|
2315
|
-
return {
|
|
2316
|
-
request: (method, pathname) => {
|
|
2317
|
-
},
|
|
2318
|
-
response: (method, pathname, status) => {
|
|
2319
|
-
},
|
|
2320
|
-
info: (msg, ...args) => {
|
|
2321
|
-
},
|
|
2322
|
-
warn: (msg, ...args) => {
|
|
2323
|
-
},
|
|
2324
|
-
error: (msg, ...args) => {
|
|
2325
|
-
},
|
|
2326
|
-
debug: (msg, ...args) => {
|
|
2327
|
-
},
|
|
2328
|
-
success: (msg, ...args) => {
|
|
2329
|
-
}
|
|
2330
|
-
};
|
|
2331
|
-
}
|
|
2332
|
-
|
|
2333
2317
|
function cors(option = {}) {
|
|
2334
2318
|
const {
|
|
2335
2319
|
methods,
|
|
@@ -2389,12 +2373,44 @@ function cors(option = {}) {
|
|
|
2389
2373
|
};
|
|
2390
2374
|
}
|
|
2391
2375
|
|
|
2376
|
+
function logger() {
|
|
2377
|
+
return async (ctx, next) => {
|
|
2378
|
+
try {
|
|
2379
|
+
console.log(
|
|
2380
|
+
`${COLORS.bold}<-- ${COLORS.reset}${COLORS.bgMagenta} ${ctx.method} ${COLORS.reset} ${ctx.pathname}`
|
|
2381
|
+
);
|
|
2382
|
+
const startTime = performance.now();
|
|
2383
|
+
let n = await next();
|
|
2384
|
+
const elapsed = performance.now() - startTime;
|
|
2385
|
+
console.log(
|
|
2386
|
+
`${COLORS.bold}--> ${COLORS.reset}${COLORS.bgBlue} ${ctx.method} ${COLORS.reset} ${ctx.pathname} ${COLORS.yellow}${ctx.getStatus}${COLORS.reset} ${COLORS.magenta}${elapsed.toFixed(2)}ms${COLORS.reset}`
|
|
2387
|
+
);
|
|
2388
|
+
return n;
|
|
2389
|
+
} catch (err) {
|
|
2390
|
+
console.error(`${COLORS.red}Error:${COLORS.reset}`, err.stack);
|
|
2391
|
+
throw new Error(err.stack);
|
|
2392
|
+
}
|
|
2393
|
+
};
|
|
2394
|
+
}
|
|
2395
|
+
|
|
2396
|
+
const poweredBy = (serverName) => {
|
|
2397
|
+
return (ctx, next) => {
|
|
2398
|
+
ctx.header("X-Powered-By", serverName || "TezX");
|
|
2399
|
+
return next();
|
|
2400
|
+
};
|
|
2401
|
+
};
|
|
2402
|
+
|
|
2403
|
+
let version = "1.0.8";
|
|
2404
|
+
|
|
2392
2405
|
exports.Router = Router;
|
|
2393
2406
|
exports.TezX = TezX;
|
|
2394
2407
|
exports.bunAdapter = bunAdapter;
|
|
2395
2408
|
exports.cors = cors;
|
|
2396
2409
|
exports.denoAdapter = denoAdapter;
|
|
2410
|
+
exports.generateID = generateID;
|
|
2397
2411
|
exports.loadEnv = loadEnv;
|
|
2398
2412
|
exports.logger = logger;
|
|
2399
2413
|
exports.nodeAdapter = nodeAdapter;
|
|
2414
|
+
exports.poweredBy = poweredBy;
|
|
2400
2415
|
exports.useParams = useParams;
|
|
2416
|
+
exports.version = version;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,40 @@
|
|
|
1
|
-
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);
|
|
1
|
+
import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(import.meta.url);const COLORS = {
|
|
2
|
+
reset: "\x1B[0m",
|
|
3
|
+
bold: "\x1B[1m",
|
|
4
|
+
underline: "\x1B[4m",
|
|
5
|
+
gray: "\x1B[90m",
|
|
6
|
+
white: "\x1B[97m",
|
|
7
|
+
black: "\x1B[30m",
|
|
8
|
+
red: "\x1B[31m",
|
|
9
|
+
green: "\x1B[32m",
|
|
10
|
+
yellow: "\x1B[33m",
|
|
11
|
+
blue: "\x1B[34m",
|
|
12
|
+
magenta: "\x1B[35m",
|
|
13
|
+
cyan: "\x1B[36m",
|
|
14
|
+
bgRed: "\x1B[41m",
|
|
15
|
+
bgGreen: "\x1B[42m",
|
|
16
|
+
bgYellow: "\x1B[43m",
|
|
17
|
+
bgBlue: "\x1B[44m",
|
|
18
|
+
bgMagenta: "\x1B[45m",
|
|
19
|
+
bgCyan: "\x1B[46m",
|
|
20
|
+
bgWhite: "\x1B[47m"
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const loggerOutput = (level, message, ...args) => {
|
|
24
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
25
|
+
const LEVEL_COLORS = {
|
|
26
|
+
info: COLORS.blue,
|
|
27
|
+
warn: COLORS.yellow,
|
|
28
|
+
error: COLORS.red,
|
|
29
|
+
debug: COLORS.cyan,
|
|
30
|
+
success: COLORS.green
|
|
31
|
+
};
|
|
32
|
+
const prefix = `${COLORS.gray}[${timestamp}]${COLORS.reset}`;
|
|
33
|
+
const levelText = `${LEVEL_COLORS[level]}[${level.toUpperCase()}]${COLORS.reset}`;
|
|
34
|
+
console.log(`${prefix} ${levelText} ${message}`, ...args?.flat());
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
let GlobalConfig = class {
|
|
2
38
|
static notFound = (ctx2) => {
|
|
3
39
|
const {
|
|
4
40
|
method,
|
|
@@ -12,10 +48,27 @@ import{createRequire as _pkgrollCR}from"node:module";const require=_pkgrollCR(im
|
|
|
12
48
|
};
|
|
13
49
|
static allowDuplicateMw = false;
|
|
14
50
|
static overwriteMethod = true;
|
|
15
|
-
static
|
|
16
|
-
static
|
|
17
|
-
return {
|
|
18
|
-
|
|
51
|
+
static debugMode = false;
|
|
52
|
+
static get debugging() {
|
|
53
|
+
return this.debugMode ? {
|
|
54
|
+
info: (msg, ...args) => loggerOutput("info", msg, ...args),
|
|
55
|
+
warn: (msg, ...args) => loggerOutput("warn", msg, ...args),
|
|
56
|
+
error: (msg, ...args) => loggerOutput("error", msg, ...args),
|
|
57
|
+
debug: (msg, ...args) => loggerOutput("debug", msg, ...args),
|
|
58
|
+
success: (msg, ...args) => loggerOutput("success", msg, ...args)
|
|
59
|
+
} : {
|
|
60
|
+
info: (msg, ...args) => {
|
|
61
|
+
},
|
|
62
|
+
warn: (msg, ...args) => {
|
|
63
|
+
},
|
|
64
|
+
error: (msg, ...args) => {
|
|
65
|
+
},
|
|
66
|
+
debug: (msg, ...args) => {
|
|
67
|
+
},
|
|
68
|
+
success: (msg, ...args) => {
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
19
72
|
};
|
|
20
73
|
|
|
21
74
|
function denoAdapter(TezX2) {
|
|
@@ -43,10 +96,7 @@ function denoAdapter(TezX2) {
|
|
|
43
96
|
if (typeof callback === "function") {
|
|
44
97
|
callback(message);
|
|
45
98
|
} else {
|
|
46
|
-
|
|
47
|
-
if (logger.success) {
|
|
48
|
-
logger.success(message);
|
|
49
|
-
}
|
|
99
|
+
GlobalConfig.debugging.success(message);
|
|
50
100
|
}
|
|
51
101
|
return server;
|
|
52
102
|
} catch (err) {
|
|
@@ -84,10 +134,7 @@ function bunAdapter(TezX2) {
|
|
|
84
134
|
if (typeof callback == "function") {
|
|
85
135
|
callback(message);
|
|
86
136
|
} else {
|
|
87
|
-
|
|
88
|
-
if (logger.success) {
|
|
89
|
-
logger.success(message);
|
|
90
|
-
}
|
|
137
|
+
GlobalConfig.debugging.success(message);
|
|
91
138
|
}
|
|
92
139
|
return server;
|
|
93
140
|
} catch (err) {
|
|
@@ -126,10 +173,7 @@ function nodeAdapter(TezX2) {
|
|
|
126
173
|
if (typeof callback == "function") {
|
|
127
174
|
callback(message);
|
|
128
175
|
} else {
|
|
129
|
-
|
|
130
|
-
if (logger.success) {
|
|
131
|
-
logger.success(message);
|
|
132
|
-
}
|
|
176
|
+
GlobalConfig.debugging.success(message);
|
|
133
177
|
}
|
|
134
178
|
return server;
|
|
135
179
|
});
|
|
@@ -1448,11 +1492,11 @@ class Context {
|
|
|
1448
1492
|
* @type {HeadersParser}
|
|
1449
1493
|
*/
|
|
1450
1494
|
headers = new HeadersParser();
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
res
|
|
1495
|
+
/**
|
|
1496
|
+
* Parser for handling and manipulating HTTP response(Read Only)
|
|
1497
|
+
* @type {Response}
|
|
1498
|
+
*/
|
|
1499
|
+
res;
|
|
1456
1500
|
/**
|
|
1457
1501
|
* Request path without query parameters
|
|
1458
1502
|
* @type {string}
|
|
@@ -1520,12 +1564,12 @@ class Context {
|
|
|
1520
1564
|
* @type {any}
|
|
1521
1565
|
*/
|
|
1522
1566
|
#preparedHeaders;
|
|
1523
|
-
/**
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1567
|
+
// /**
|
|
1568
|
+
// * Native response object reference
|
|
1569
|
+
// * @private
|
|
1570
|
+
// * @type {any}
|
|
1571
|
+
// */
|
|
1572
|
+
// res: any;
|
|
1529
1573
|
/**
|
|
1530
1574
|
* Flag indicating if the response is fresh/unmodified
|
|
1531
1575
|
* @private
|
|
@@ -1658,10 +1702,10 @@ class Context {
|
|
|
1658
1702
|
} else if (typeof args[0] === "object") {
|
|
1659
1703
|
headers = { ...headers, ...args[0] };
|
|
1660
1704
|
}
|
|
1661
|
-
return this.#handleResponse(
|
|
1705
|
+
return this.#handleResponse(JSON.stringify(body), {
|
|
1662
1706
|
status,
|
|
1663
1707
|
headers
|
|
1664
|
-
})
|
|
1708
|
+
});
|
|
1665
1709
|
}
|
|
1666
1710
|
send(body, ...args) {
|
|
1667
1711
|
let status = this.#status;
|
|
@@ -1684,10 +1728,10 @@ class Context {
|
|
|
1684
1728
|
headers["Content-Type"] = "application/octet-stream";
|
|
1685
1729
|
}
|
|
1686
1730
|
}
|
|
1687
|
-
return this.#handleResponse(
|
|
1731
|
+
return this.#handleResponse(body, {
|
|
1688
1732
|
status,
|
|
1689
1733
|
headers
|
|
1690
|
-
})
|
|
1734
|
+
});
|
|
1691
1735
|
}
|
|
1692
1736
|
html(data, ...args) {
|
|
1693
1737
|
let status = this.#status;
|
|
@@ -1702,10 +1746,10 @@ class Context {
|
|
|
1702
1746
|
} else if (typeof args[0] === "object") {
|
|
1703
1747
|
headers = { ...headers, ...args[0] };
|
|
1704
1748
|
}
|
|
1705
|
-
return this.#handleResponse(
|
|
1749
|
+
return this.#handleResponse(data, {
|
|
1706
1750
|
status,
|
|
1707
1751
|
headers
|
|
1708
|
-
})
|
|
1752
|
+
});
|
|
1709
1753
|
}
|
|
1710
1754
|
text(data, ...args) {
|
|
1711
1755
|
let status = this.#status;
|
|
@@ -1720,10 +1764,10 @@ class Context {
|
|
|
1720
1764
|
} else if (typeof args[0] === "object") {
|
|
1721
1765
|
headers = { ...headers, ...args[0] };
|
|
1722
1766
|
}
|
|
1723
|
-
return this.#handleResponse(
|
|
1767
|
+
return this.#handleResponse(data, {
|
|
1724
1768
|
status,
|
|
1725
1769
|
headers
|
|
1726
|
-
})
|
|
1770
|
+
});
|
|
1727
1771
|
}
|
|
1728
1772
|
xml(data, ...args) {
|
|
1729
1773
|
let status = this.#status;
|
|
@@ -1738,10 +1782,10 @@ class Context {
|
|
|
1738
1782
|
} else if (typeof args[0] === "object") {
|
|
1739
1783
|
headers = { ...headers, ...args[0] };
|
|
1740
1784
|
}
|
|
1741
|
-
return this.#handleResponse(
|
|
1785
|
+
return this.#handleResponse(data, {
|
|
1742
1786
|
status,
|
|
1743
1787
|
headers
|
|
1744
|
-
})
|
|
1788
|
+
});
|
|
1745
1789
|
}
|
|
1746
1790
|
/**
|
|
1747
1791
|
* HTTP status code..
|
|
@@ -1805,14 +1849,14 @@ class Context {
|
|
|
1805
1849
|
} else if (runtime === "deno") {
|
|
1806
1850
|
fileBuffer = await Deno.readFile(filePath);
|
|
1807
1851
|
}
|
|
1808
|
-
return this.#handleResponse(
|
|
1852
|
+
return this.#handleResponse(fileBuffer, {
|
|
1809
1853
|
status: 200,
|
|
1810
1854
|
headers: {
|
|
1811
1855
|
"Content-Disposition": `attachment; filename="${fileName}"`,
|
|
1812
1856
|
"Content-Type": "application/octet-stream",
|
|
1813
1857
|
"Content-Length": fileBuffer.byteLength.toString()
|
|
1814
1858
|
}
|
|
1815
|
-
})
|
|
1859
|
+
});
|
|
1816
1860
|
} catch (error) {
|
|
1817
1861
|
throw Error("Internal Server Error" + error?.message);
|
|
1818
1862
|
}
|
|
@@ -1876,21 +1920,29 @@ class Context {
|
|
|
1876
1920
|
if (fileName) {
|
|
1877
1921
|
headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
1878
1922
|
}
|
|
1879
|
-
return this.#handleResponse(
|
|
1880
|
-
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
})
|
|
1884
|
-
);
|
|
1923
|
+
return this.#handleResponse(fileStream, {
|
|
1924
|
+
status: 200,
|
|
1925
|
+
headers
|
|
1926
|
+
});
|
|
1885
1927
|
} catch (error) {
|
|
1886
1928
|
throw Error("Internal Server Error" + error?.message);
|
|
1887
1929
|
}
|
|
1888
1930
|
}
|
|
1889
|
-
#handleResponse(
|
|
1890
|
-
let
|
|
1891
|
-
|
|
1931
|
+
#handleResponse(body, { headers, status }) {
|
|
1932
|
+
let response = new Response(body, {
|
|
1933
|
+
status,
|
|
1934
|
+
headers
|
|
1935
|
+
});
|
|
1936
|
+
let clone = response.clone();
|
|
1937
|
+
this.res = response;
|
|
1892
1938
|
return clone;
|
|
1893
1939
|
}
|
|
1940
|
+
// get res() {
|
|
1941
|
+
// return this.res;
|
|
1942
|
+
// }
|
|
1943
|
+
// set res(res: Response) {
|
|
1944
|
+
// this.res = res;
|
|
1945
|
+
// }
|
|
1894
1946
|
/**
|
|
1895
1947
|
* Getter that creates a standardized Request object from internal state
|
|
1896
1948
|
* @returns {Request} - Normalized request object combining:
|
|
@@ -2034,15 +2086,14 @@ class TezX extends Router {
|
|
|
2034
2086
|
constructor({
|
|
2035
2087
|
basePath = "/",
|
|
2036
2088
|
env = {},
|
|
2037
|
-
|
|
2089
|
+
debugMode = false,
|
|
2038
2090
|
allowDuplicateMw = false,
|
|
2039
2091
|
overwriteMethod = true
|
|
2040
2092
|
} = {}) {
|
|
2041
2093
|
GlobalConfig.allowDuplicateMw = allowDuplicateMw;
|
|
2042
2094
|
GlobalConfig.overwriteMethod = overwriteMethod;
|
|
2043
|
-
if (
|
|
2044
|
-
GlobalConfig.
|
|
2045
|
-
GlobalConfig.enableLogger = true;
|
|
2095
|
+
if (debugMode) {
|
|
2096
|
+
GlobalConfig.debugMode = debugMode;
|
|
2046
2097
|
}
|
|
2047
2098
|
super({ basePath, env });
|
|
2048
2099
|
this.serve = this.serve.bind(this);
|
|
@@ -2107,13 +2158,16 @@ class TezX extends Router {
|
|
|
2107
2158
|
let index = 0;
|
|
2108
2159
|
const next = async () => {
|
|
2109
2160
|
if (index < middlewares.length) {
|
|
2110
|
-
return middlewares[index++](ctx, next);
|
|
2161
|
+
return await middlewares[index++](ctx, next);
|
|
2111
2162
|
} else {
|
|
2112
|
-
|
|
2113
|
-
return response;
|
|
2163
|
+
return await finalCallback(ctx);
|
|
2114
2164
|
}
|
|
2115
2165
|
};
|
|
2116
|
-
|
|
2166
|
+
const response = await next();
|
|
2167
|
+
if (!response) {
|
|
2168
|
+
throw new Error(`Handler did not return a response or next() was not called. Path: ${ctx.pathname}, Method: ${ctx.method}`);
|
|
2169
|
+
}
|
|
2170
|
+
return response;
|
|
2117
2171
|
};
|
|
2118
2172
|
}
|
|
2119
2173
|
#findMiddleware(pathname) {
|
|
@@ -2140,61 +2194,49 @@ class TezX extends Router {
|
|
|
2140
2194
|
const { pathname } = urlRef;
|
|
2141
2195
|
let middlewares = this.#findMiddleware(pathname);
|
|
2142
2196
|
ctx.env = this.env;
|
|
2143
|
-
const logger = GlobalConfig.loggerFn();
|
|
2144
|
-
if (logger.request) {
|
|
2145
|
-
logger.request(ctx.method, ctx.pathname);
|
|
2146
|
-
}
|
|
2147
2197
|
try {
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
}
|
|
2163
|
-
const statusText = response?.statusText || httpStatusMap[response?.status] || "";
|
|
2164
|
-
const status = response.status || ctx2.getStatus;
|
|
2165
|
-
let headers = ctx2.headers.toObject();
|
|
2166
|
-
if (logger.response) {
|
|
2167
|
-
logger.response(ctx2.method, ctx2.pathname, status);
|
|
2168
|
-
}
|
|
2169
|
-
if (response instanceof Response) {
|
|
2170
|
-
return new Response(response.body, {
|
|
2171
|
-
status,
|
|
2172
|
-
statusText,
|
|
2173
|
-
headers
|
|
2174
|
-
});
|
|
2175
|
-
}
|
|
2176
|
-
return new Response(response.body, {
|
|
2177
|
-
status,
|
|
2178
|
-
statusText,
|
|
2179
|
-
headers
|
|
2180
|
-
});
|
|
2181
|
-
} else {
|
|
2182
|
-
if (logger.response) {
|
|
2183
|
-
logger.response(ctx2.method, ctx2.pathname, 404);
|
|
2184
|
-
}
|
|
2185
|
-
return GlobalConfig.notFound(ctx2);
|
|
2186
|
-
}
|
|
2198
|
+
let callback = async (ctx2) => {
|
|
2199
|
+
const find = this.findRoute(ctx2.req.method, pathname);
|
|
2200
|
+
if (find?.callback) {
|
|
2201
|
+
ctx2.params = find.params;
|
|
2202
|
+
const callback2 = find.callback;
|
|
2203
|
+
let middlewares2 = find.middlewares;
|
|
2204
|
+
return await this.#createHandler(
|
|
2205
|
+
middlewares2,
|
|
2206
|
+
callback2
|
|
2207
|
+
)(ctx2);
|
|
2208
|
+
} else {
|
|
2209
|
+
let res = await GlobalConfig.notFound(ctx2);
|
|
2210
|
+
ctx2.setStatus = res.status;
|
|
2211
|
+
return res;
|
|
2187
2212
|
}
|
|
2188
|
-
|
|
2213
|
+
};
|
|
2214
|
+
let response = await this.#createHandler([...this.triMiddlewares.middlewares, ...middlewares], callback)(ctx);
|
|
2215
|
+
let finalResponse = () => {
|
|
2216
|
+
return (ctx2) => {
|
|
2217
|
+
if (response?.headers) {
|
|
2218
|
+
ctx2.headers.add(response.headers);
|
|
2219
|
+
}
|
|
2220
|
+
const statusText = response?.statusText || httpStatusMap[response?.status] || "";
|
|
2221
|
+
const status = response.status || ctx2.getStatus;
|
|
2222
|
+
let headers = ctx2.headers.toObject();
|
|
2223
|
+
return new Response(response.body, {
|
|
2224
|
+
status,
|
|
2225
|
+
statusText,
|
|
2226
|
+
headers
|
|
2227
|
+
});
|
|
2228
|
+
};
|
|
2229
|
+
};
|
|
2230
|
+
return finalResponse()(ctx);
|
|
2189
2231
|
} catch (err) {
|
|
2190
2232
|
let error = err;
|
|
2191
2233
|
if (err instanceof Error) {
|
|
2192
2234
|
error = err.stack;
|
|
2193
2235
|
}
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
return
|
|
2236
|
+
GlobalConfig.debugging.error(`${COLORS.bgRed}${ctx.pathname}, Method: ${ctx.method}${COLORS.reset}`, `${httpStatusMap[500]}: ${error} `);
|
|
2237
|
+
let res = await GlobalConfig.onError(error, ctx);
|
|
2238
|
+
ctx.setStatus = res.status;
|
|
2239
|
+
return res;
|
|
2198
2240
|
}
|
|
2199
2241
|
}
|
|
2200
2242
|
async serve(req) {
|
|
@@ -2202,6 +2244,13 @@ class TezX extends Router {
|
|
|
2202
2244
|
}
|
|
2203
2245
|
}
|
|
2204
2246
|
|
|
2247
|
+
function generateID() {
|
|
2248
|
+
const timestamp = Date.now().toString(16);
|
|
2249
|
+
const random = Math.floor(Math.random() * 281474976710655).toString(16).padStart(12, "0");
|
|
2250
|
+
const pid = (process.pid % 65536).toString(16).padStart(4, "0");
|
|
2251
|
+
return `${timestamp}-${random}-${pid}`;
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2205
2254
|
function parseEnvFile(filePath, result) {
|
|
2206
2255
|
try {
|
|
2207
2256
|
let fileExists = false;
|
|
@@ -2263,71 +2312,6 @@ function loadEnv(basePath = "./") {
|
|
|
2263
2312
|
return result;
|
|
2264
2313
|
}
|
|
2265
2314
|
|
|
2266
|
-
const COLORS = {
|
|
2267
|
-
reset: "\x1B[0m",
|
|
2268
|
-
bold: "\x1B[1m",
|
|
2269
|
-
gray: "\x1B[90m",
|
|
2270
|
-
red: "\x1B[31m",
|
|
2271
|
-
green: "\x1B[32m",
|
|
2272
|
-
yellow: "\x1B[33m",
|
|
2273
|
-
blue: "\x1B[34m",
|
|
2274
|
-
magenta: "\x1B[35m",
|
|
2275
|
-
cyan: "\x1B[36m",
|
|
2276
|
-
bgBlue: "\x1B[44m",
|
|
2277
|
-
bgMagenta: "\x1B[45m"};
|
|
2278
|
-
const loggerOutput = (level, message, ...args) => {
|
|
2279
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2280
|
-
const LEVEL_COLORS = {
|
|
2281
|
-
info: COLORS.blue,
|
|
2282
|
-
warn: COLORS.yellow,
|
|
2283
|
-
error: COLORS.red,
|
|
2284
|
-
debug: COLORS.cyan,
|
|
2285
|
-
success: COLORS.green
|
|
2286
|
-
};
|
|
2287
|
-
const prefix = `${COLORS.gray}[${timestamp}]${COLORS.reset}`;
|
|
2288
|
-
const levelText = `${LEVEL_COLORS[level]}[${level.toUpperCase()}]${COLORS.reset}`;
|
|
2289
|
-
console.log(`${prefix} ${levelText} ${message}`, ...args?.flat());
|
|
2290
|
-
};
|
|
2291
|
-
function logger() {
|
|
2292
|
-
const startTime = performance.now();
|
|
2293
|
-
if (GlobalConfig.enableLogger) {
|
|
2294
|
-
return {
|
|
2295
|
-
request: (method, pathname) => {
|
|
2296
|
-
console.log(
|
|
2297
|
-
`${COLORS.bold}<-- ${COLORS.reset}${COLORS.bgMagenta} ${method} ${COLORS.reset} ${pathname}`
|
|
2298
|
-
);
|
|
2299
|
-
},
|
|
2300
|
-
response: (method, pathname, status) => {
|
|
2301
|
-
const elapsed = performance.now() - startTime;
|
|
2302
|
-
console.log(
|
|
2303
|
-
`${COLORS.bold}--> ${COLORS.reset}${COLORS.bgBlue} ${method} ${COLORS.reset} ${pathname} ${COLORS.yellow}${status}${COLORS.reset} ${COLORS.magenta}${elapsed.toFixed(2)}ms${COLORS.reset}`
|
|
2304
|
-
);
|
|
2305
|
-
},
|
|
2306
|
-
info: (msg, ...args) => loggerOutput("info", msg, ...args),
|
|
2307
|
-
warn: (msg, ...args) => loggerOutput("warn", msg, ...args),
|
|
2308
|
-
error: (msg, ...args) => loggerOutput("error", msg, ...args),
|
|
2309
|
-
debug: (msg, ...args) => loggerOutput("debug", msg, ...args),
|
|
2310
|
-
success: (msg, ...args) => loggerOutput("success", msg, ...args)
|
|
2311
|
-
};
|
|
2312
|
-
}
|
|
2313
|
-
return {
|
|
2314
|
-
request: (method, pathname) => {
|
|
2315
|
-
},
|
|
2316
|
-
response: (method, pathname, status) => {
|
|
2317
|
-
},
|
|
2318
|
-
info: (msg, ...args) => {
|
|
2319
|
-
},
|
|
2320
|
-
warn: (msg, ...args) => {
|
|
2321
|
-
},
|
|
2322
|
-
error: (msg, ...args) => {
|
|
2323
|
-
},
|
|
2324
|
-
debug: (msg, ...args) => {
|
|
2325
|
-
},
|
|
2326
|
-
success: (msg, ...args) => {
|
|
2327
|
-
}
|
|
2328
|
-
};
|
|
2329
|
-
}
|
|
2330
|
-
|
|
2331
2315
|
function cors(option = {}) {
|
|
2332
2316
|
const {
|
|
2333
2317
|
methods,
|
|
@@ -2387,4 +2371,33 @@ function cors(option = {}) {
|
|
|
2387
2371
|
};
|
|
2388
2372
|
}
|
|
2389
2373
|
|
|
2390
|
-
|
|
2374
|
+
function logger() {
|
|
2375
|
+
return async (ctx, next) => {
|
|
2376
|
+
try {
|
|
2377
|
+
console.log(
|
|
2378
|
+
`${COLORS.bold}<-- ${COLORS.reset}${COLORS.bgMagenta} ${ctx.method} ${COLORS.reset} ${ctx.pathname}`
|
|
2379
|
+
);
|
|
2380
|
+
const startTime = performance.now();
|
|
2381
|
+
let n = await next();
|
|
2382
|
+
const elapsed = performance.now() - startTime;
|
|
2383
|
+
console.log(
|
|
2384
|
+
`${COLORS.bold}--> ${COLORS.reset}${COLORS.bgBlue} ${ctx.method} ${COLORS.reset} ${ctx.pathname} ${COLORS.yellow}${ctx.getStatus}${COLORS.reset} ${COLORS.magenta}${elapsed.toFixed(2)}ms${COLORS.reset}`
|
|
2385
|
+
);
|
|
2386
|
+
return n;
|
|
2387
|
+
} catch (err) {
|
|
2388
|
+
console.error(`${COLORS.red}Error:${COLORS.reset}`, err.stack);
|
|
2389
|
+
throw new Error(err.stack);
|
|
2390
|
+
}
|
|
2391
|
+
};
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
const poweredBy = (serverName) => {
|
|
2395
|
+
return (ctx, next) => {
|
|
2396
|
+
ctx.header("X-Powered-By", serverName || "TezX");
|
|
2397
|
+
return next();
|
|
2398
|
+
};
|
|
2399
|
+
};
|
|
2400
|
+
|
|
2401
|
+
let version = "1.0.7";
|
|
2402
|
+
|
|
2403
|
+
export { Router, TezX, bunAdapter, cors, denoAdapter, generateID, loadEnv, logger, nodeAdapter, poweredBy, useParams, version };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tezx",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "TezX is a cutting-edge, high-performance, and lightweight JavaScript framework designed for speed, scalability, and flexibility. Built with modern web development needs in mind, TezX enables efficient routing, middleware management, and static file serving with minimal configuration. It is fully compatible with Node.js, Deno, and Bun, making it a truly cross-environment framework.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|