tezx 3.0.14-beta → 3.0.14-beta2
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/bun/env.d.ts +5 -0
- package/bun/env.js +44 -0
- package/bun/index.d.ts +1 -1
- package/bun/index.js +1 -1
- package/bun/ws.js +4 -3
- package/cjs/bun/env.js +47 -0
- package/cjs/bun/index.js +1 -1
- package/cjs/bun/ws.js +4 -3
- package/cjs/core/context.js +4 -3
- package/cjs/core/error.js +8 -0
- package/cjs/core/request.js +3 -2
- package/cjs/core/router.js +11 -17
- package/cjs/core/server.js +14 -9
- package/cjs/deno/env.js +2 -1
- package/cjs/deno/serveStatic.js +2 -1
- package/cjs/deno/ws.js +4 -3
- package/cjs/helper/index.js +12 -10
- package/cjs/index.js +1 -1
- package/cjs/jwt/node.js +94 -0
- package/cjs/jwt/web.js +178 -0
- package/cjs/middleware/basic-auth.js +9 -14
- package/cjs/middleware/bearer-auth.js +5 -5
- package/cjs/middleware/cache-control.js +44 -0
- package/cjs/middleware/cors.js +1 -1
- package/cjs/middleware/detect-bot.js +57 -0
- package/cjs/middleware/i18n.js +92 -0
- package/cjs/middleware/index.js +5 -0
- package/cjs/middleware/logger.js +3 -2
- package/cjs/middleware/rate-limiter.js +1 -1
- package/cjs/middleware/sanitize-headers.js +1 -1
- package/cjs/middleware/secure-headers copy.js +143 -0
- package/cjs/middleware/secure-headers.js +157 -0
- package/cjs/node/env.js +4 -3
- package/cjs/node/serveStatic.js +2 -1
- package/cjs/node/ws.js +3 -2
- package/cjs/registry/RadixRouter.js +2 -33
- package/cjs/utils/buffer.js +17 -0
- package/cjs/utils/file.js +28 -6
- package/cjs/utils/generateID.js +10 -0
- package/cjs/utils/response.js +3 -1
- package/core/context.d.ts +3 -3
- package/core/context.js +4 -3
- package/core/error.d.ts +1 -0
- package/core/error.js +7 -0
- package/core/request.js +3 -2
- package/core/router.d.ts +3 -8
- package/core/router.js +11 -17
- package/core/server.d.ts +10 -23
- package/core/server.js +15 -10
- package/deno/env.js +2 -1
- package/deno/index.d.ts +1 -1
- package/deno/serveStatic.js +2 -1
- package/deno/ws.d.ts +1 -1
- package/deno/ws.js +4 -3
- package/helper/index.d.ts +7 -6
- package/helper/index.js +7 -6
- package/index.d.ts +5 -2
- package/index.js +1 -1
- package/jwt/node.d.ts +39 -0
- package/jwt/node.js +87 -0
- package/jwt/web.d.ts +14 -0
- package/jwt/web.js +174 -0
- package/middleware/basic-auth.d.ts +2 -1
- package/middleware/basic-auth.js +9 -14
- package/middleware/bearer-auth.d.ts +2 -1
- package/middleware/bearer-auth.js +5 -5
- package/middleware/cache-control.d.ts +30 -0
- package/middleware/cache-control.js +40 -0
- package/middleware/cors.js +1 -1
- package/middleware/detect-bot.d.ts +113 -0
- package/middleware/detect-bot.js +53 -0
- package/middleware/i18n.d.ts +194 -0
- package/middleware/i18n.js +88 -0
- package/middleware/index.d.ts +5 -0
- package/middleware/index.js +5 -0
- package/middleware/logger.d.ts +1 -1
- package/middleware/logger.js +3 -2
- package/middleware/rate-limiter.d.ts +3 -2
- package/middleware/rate-limiter.js +1 -1
- package/middleware/sanitize-headers.js +1 -1
- package/middleware/secure-headers copy.d.ts +15 -0
- package/middleware/secure-headers copy.js +136 -0
- package/middleware/secure-headers.d.ts +132 -0
- package/middleware/secure-headers.js +153 -0
- package/node/env.js +4 -3
- package/node/serveStatic.d.ts +8 -0
- package/node/serveStatic.js +2 -1
- package/node/ws.d.ts +1 -1
- package/node/ws.js +3 -2
- package/package.json +12 -1
- package/registry/RadixRouter.js +2 -33
- package/types/index.d.ts +1 -1
- package/utils/buffer.d.ts +1 -0
- package/utils/buffer.js +14 -0
- package/utils/file.d.ts +6 -2
- package/utils/file.js +27 -6
- package/utils/generateID.d.ts +9 -0
- package/utils/generateID.js +9 -0
- package/utils/response.js +3 -1
- package/cjs/utils/regexRouter.js +0 -57
- package/utils/regexRouter.d.ts +0 -66
- package/utils/regexRouter.js +0 -52
package/utils/file.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TezXError } from "../core/error.js";
|
|
1
2
|
import { runtime } from "./runtime.js";
|
|
2
3
|
export async function fileExists(path) {
|
|
3
4
|
switch (runtime) {
|
|
@@ -37,7 +38,7 @@ export async function getFileBuffer(path) {
|
|
|
37
38
|
case "deno":
|
|
38
39
|
return Deno.readFile(path);
|
|
39
40
|
default:
|
|
40
|
-
throw new
|
|
41
|
+
throw new TezXError("Unsupported runtime environment");
|
|
41
42
|
}
|
|
42
43
|
}
|
|
43
44
|
export async function readStream(path) {
|
|
@@ -54,22 +55,42 @@ export async function readStream(path) {
|
|
|
54
55
|
return (await Deno.open(path, { read: true })).readable;
|
|
55
56
|
}
|
|
56
57
|
default:
|
|
57
|
-
throw new
|
|
58
|
+
throw new TezXError("Unsupported runtime environment");
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
export async function fileSize(path) {
|
|
61
62
|
switch (runtime) {
|
|
62
63
|
case "node": {
|
|
63
64
|
const { stat } = await import("node:fs/promises");
|
|
64
|
-
|
|
65
|
+
const st = await stat(path);
|
|
66
|
+
return { size: st.size, mtime: st.mtime };
|
|
65
67
|
}
|
|
66
68
|
case "bun": {
|
|
67
|
-
|
|
69
|
+
const st = await Bun.file(path).stat();
|
|
70
|
+
return { size: st.size, mtime: st.mtime };
|
|
68
71
|
}
|
|
69
72
|
case "deno": {
|
|
70
|
-
|
|
73
|
+
const st = await Deno.stat(path);
|
|
74
|
+
return {
|
|
75
|
+
size: st.size,
|
|
76
|
+
mtime: st.mtime ?? new Date(),
|
|
77
|
+
};
|
|
71
78
|
}
|
|
72
79
|
default:
|
|
73
|
-
|
|
80
|
+
throw new TezXError("Unsupported runtime: " + runtime);
|
|
74
81
|
}
|
|
75
82
|
}
|
|
83
|
+
export async function etagDigest(algo = "MD5", data) {
|
|
84
|
+
const encoded = typeof data === "string" ? new TextEncoder().encode(data) : data;
|
|
85
|
+
if (runtime === "bun") {
|
|
86
|
+
return Bun.hash(data, 256).toString(16);
|
|
87
|
+
}
|
|
88
|
+
if (globalThis?.crypto?.subtle) {
|
|
89
|
+
const buffer = await crypto.subtle.digest(algo, encoded);
|
|
90
|
+
return Array.from(new Uint8Array(buffer))
|
|
91
|
+
.map((b) => b.toString(16).padStart(2, "0"))
|
|
92
|
+
.join("");
|
|
93
|
+
}
|
|
94
|
+
const { createHash } = await import("node:crypto");
|
|
95
|
+
return createHash(algo).update(encoded).digest("hex");
|
|
96
|
+
}
|
package/utils/generateID.d.ts
CHANGED
|
@@ -31,3 +31,12 @@ export declare function generateID(): string;
|
|
|
31
31
|
* console.log(uuid); // "a63e47b6-6a3b-4d53-90b6-8db2f2d07943"
|
|
32
32
|
*/
|
|
33
33
|
export declare function generateUUID(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Generate a short nonce (JS-only, low-GC) by sampling the BASE64 charset.
|
|
36
|
+
* This function intentionally uses Math.random for speed and low allocation.
|
|
37
|
+
* If you require cryptographic randomness, swap with crypto.randomFillSync.
|
|
38
|
+
*
|
|
39
|
+
* @param {number} [length=16] - nonce length in characters
|
|
40
|
+
* @returns {string} generated nonce string
|
|
41
|
+
*/
|
|
42
|
+
export declare function generateRandomBase64(length?: number): string;
|
package/utils/generateID.js
CHANGED
|
@@ -21,3 +21,12 @@ export function generateUUID() {
|
|
|
21
21
|
return crypto.randomUUID();
|
|
22
22
|
return generateID();
|
|
23
23
|
}
|
|
24
|
+
export function generateRandomBase64(length = 16) {
|
|
25
|
+
let result = "";
|
|
26
|
+
const BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
27
|
+
for (let i = 0; i < length; i++) {
|
|
28
|
+
const idx = Math.floor(Math.random() * 64);
|
|
29
|
+
result += BASE64[idx];
|
|
30
|
+
}
|
|
31
|
+
return result;
|
|
32
|
+
}
|
package/utils/response.js
CHANGED
|
@@ -9,7 +9,9 @@ export let notFoundResponse = (ctx) => {
|
|
|
9
9
|
export async function handleErrorResponse(err = TezXError.internal(), ctx) {
|
|
10
10
|
if (err instanceof TezXError) {
|
|
11
11
|
GlobalConfig.debugging.error(err.details ?? err?.message);
|
|
12
|
-
return ctx
|
|
12
|
+
return ctx
|
|
13
|
+
.status(err.statusCode ?? 500)
|
|
14
|
+
.send(err.details ?? err?.message ?? "Internal Server Error");
|
|
13
15
|
}
|
|
14
16
|
return await handleErrorResponse(TezXError.internal(), ctx);
|
|
15
17
|
}
|
package/cjs/utils/regexRouter.js
DELETED
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compileRegexRoute = compileRegexRoute;
|
|
4
|
-
exports.addBaseToRegex = addBaseToRegex;
|
|
5
|
-
exports.regexMatchRoute = regexMatchRoute;
|
|
6
|
-
const low_level_js_1 = require("./low-level.js");
|
|
7
|
-
function compileRegexRoute(seg) {
|
|
8
|
-
const segments = typeof seg == "string" ? seg.split("/").filter(Boolean) : seg;
|
|
9
|
-
let regexStr = "^";
|
|
10
|
-
const paramNames = [];
|
|
11
|
-
for (let seg of segments) {
|
|
12
|
-
if (seg.startsWith(":")) {
|
|
13
|
-
const isOptional = seg.endsWith("?");
|
|
14
|
-
const name = seg.replace(":", "").replace("?", "");
|
|
15
|
-
paramNames.push(name);
|
|
16
|
-
regexStr += isOptional ? `(?:\\/([^\\/]+))?` : `\\/([^\\/]+)`;
|
|
17
|
-
}
|
|
18
|
-
else if (seg.startsWith("*")) {
|
|
19
|
-
const name = seg.slice(1) || "*";
|
|
20
|
-
paramNames.push(name);
|
|
21
|
-
regexStr += `\\/(.+)`;
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
else {
|
|
25
|
-
regexStr += `\\/${seg}`;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
regexStr += "\\/?$";
|
|
29
|
-
return {
|
|
30
|
-
regex: new RegExp(regexStr),
|
|
31
|
-
paramNames,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
function addBaseToRegex(basePath, routeRegex) {
|
|
35
|
-
basePath = "/" + (0, low_level_js_1.sanitizePathSplitBasePath)("/", basePath)?.join("/");
|
|
36
|
-
if (basePath === "/")
|
|
37
|
-
basePath = "";
|
|
38
|
-
let body = routeRegex.source.replace(/^(\^)/, "").replace(/(\$)$/, "");
|
|
39
|
-
body = body.replace(/\\\//g, "/");
|
|
40
|
-
if (body.startsWith("/")) {
|
|
41
|
-
body = body.slice(1);
|
|
42
|
-
}
|
|
43
|
-
const cleaned = body.replace(/^\/+|\/+$/g, "").replace(/\/?\?$/, "");
|
|
44
|
-
const combined = basePath + "/" + cleaned + "/?";
|
|
45
|
-
const finalRegex = new RegExp(`^${combined}$`);
|
|
46
|
-
return finalRegex;
|
|
47
|
-
}
|
|
48
|
-
function regexMatchRoute(regex, url, paramNames = []) {
|
|
49
|
-
const match = url.match(regex);
|
|
50
|
-
if (!match)
|
|
51
|
-
return { success: false, params: {} };
|
|
52
|
-
const params = {};
|
|
53
|
-
paramNames.forEach((name, idx) => {
|
|
54
|
-
params[name] = match[idx + 1] ?? null;
|
|
55
|
-
});
|
|
56
|
-
return { params, success: true };
|
|
57
|
-
}
|
package/utils/regexRouter.d.ts
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compiles a route string or segment array into a regular expression for matching URL paths.
|
|
3
|
-
* Supports dynamic `:param`, optional `:param?`, and wildcard `*param` segments.
|
|
4
|
-
*
|
|
5
|
-
* @param {string | string[]} seg - The route pattern, either as a string (`'/user/:id'`)
|
|
6
|
-
* or an array of segments (`['user', ':id']`).
|
|
7
|
-
*
|
|
8
|
-
* @returns {{
|
|
9
|
-
* regex: RegExp,
|
|
10
|
-
* paramNames: string[]
|
|
11
|
-
* }}
|
|
12
|
-
* @example
|
|
13
|
-
* const { regex, paramNames } = compileRegexRoute('/user/:id/post/:slug?');
|
|
14
|
-
* // regex: /^\/user\/([^\/]+)\/(?:([^\/]+))?\/?$/
|
|
15
|
-
* // paramNames: ['id', 'slug']
|
|
16
|
-
*
|
|
17
|
-
* regex.test('/user/123/post/hello'); // ✅ true
|
|
18
|
-
* regex.test('/user/123/post'); // ✅ true (because :slug? is optional)
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* const { regex, paramNames } = compileRegexRoute('/files/*path');
|
|
22
|
-
* // regex: /^\/files\/(.+)\/?$/
|
|
23
|
-
* // paramNames: ['path']
|
|
24
|
-
*
|
|
25
|
-
* regex.test('/files/images/cat.jpg'); // ✅ true
|
|
26
|
-
*/
|
|
27
|
-
export declare function compileRegexRoute(seg: string | string[]): {
|
|
28
|
-
regex: RegExp;
|
|
29
|
-
paramNames: string[];
|
|
30
|
-
};
|
|
31
|
-
/**
|
|
32
|
-
* Combines a base path with a route regex pattern.
|
|
33
|
-
*
|
|
34
|
-
* @param basePath - The base path to prepend (e.g., '/api/v1')
|
|
35
|
-
* @param routeRegex - The original route regex (e.g., /^\/users\/([^/]+?)$/)
|
|
36
|
-
* @returns A new regex that includes the base path
|
|
37
|
-
*/
|
|
38
|
-
export declare function addBaseToRegex(basePath: string, routeRegex: RegExp): RegExp;
|
|
39
|
-
/**
|
|
40
|
-
* Matches a given URL against a provided regular expression and extracts named parameters.
|
|
41
|
-
*
|
|
42
|
-
* @param {RegExp} regex - The regular expression to match against the URL.
|
|
43
|
-
* It should include capturing groups for each parameter.
|
|
44
|
-
* Example: /^\/user\/(\d+)\/post\/(\w+)$/
|
|
45
|
-
*
|
|
46
|
-
* @param {string} url - The URL string to match.
|
|
47
|
-
* Example: "/user/123/post/abc"
|
|
48
|
-
*
|
|
49
|
-
* @param {string[]} paramNames - An array of parameter names corresponding to the capturing groups in the regex.
|
|
50
|
-
* Example: ["userId", "postId"]
|
|
51
|
-
*
|
|
52
|
-
* @returns {{ success: boolean, params: Record<string, string | null> }} An object indicating:
|
|
53
|
-
* - `success`: whether the URL matched the regex.
|
|
54
|
-
* - `params`: an object mapping parameter names to their matched values, or `null` if not found.
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* const regex = /^\/user\/(\d+)\/post\/(\w+)$/;
|
|
58
|
-
* const url = "/user/123/post/abc";
|
|
59
|
-
* const paramNames = ["userId", "postId"];
|
|
60
|
-
* const result = regexMatchRoute(regex, url, paramNames);
|
|
61
|
-
* // result = { success: true, params: { userId: "123", postId: "abc" } }
|
|
62
|
-
*/
|
|
63
|
-
export declare function regexMatchRoute(regex: RegExp, url: string, paramNames?: string[]): {
|
|
64
|
-
params: Record<string, string | null>;
|
|
65
|
-
success: boolean;
|
|
66
|
-
};
|
package/utils/regexRouter.js
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { sanitizePathSplitBasePath } from "./low-level.js";
|
|
2
|
-
export function compileRegexRoute(seg) {
|
|
3
|
-
const segments = typeof seg == "string" ? seg.split("/").filter(Boolean) : seg;
|
|
4
|
-
let regexStr = "^";
|
|
5
|
-
const paramNames = [];
|
|
6
|
-
for (let seg of segments) {
|
|
7
|
-
if (seg.startsWith(":")) {
|
|
8
|
-
const isOptional = seg.endsWith("?");
|
|
9
|
-
const name = seg.replace(":", "").replace("?", "");
|
|
10
|
-
paramNames.push(name);
|
|
11
|
-
regexStr += isOptional ? `(?:\\/([^\\/]+))?` : `\\/([^\\/]+)`;
|
|
12
|
-
}
|
|
13
|
-
else if (seg.startsWith("*")) {
|
|
14
|
-
const name = seg.slice(1) || "*";
|
|
15
|
-
paramNames.push(name);
|
|
16
|
-
regexStr += `\\/(.+)`;
|
|
17
|
-
break;
|
|
18
|
-
}
|
|
19
|
-
else {
|
|
20
|
-
regexStr += `\\/${seg}`;
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
regexStr += "\\/?$";
|
|
24
|
-
return {
|
|
25
|
-
regex: new RegExp(regexStr),
|
|
26
|
-
paramNames,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
export function addBaseToRegex(basePath, routeRegex) {
|
|
30
|
-
basePath = "/" + sanitizePathSplitBasePath("/", basePath)?.join("/");
|
|
31
|
-
if (basePath === "/")
|
|
32
|
-
basePath = "";
|
|
33
|
-
let body = routeRegex.source.replace(/^(\^)/, "").replace(/(\$)$/, "");
|
|
34
|
-
body = body.replace(/\\\//g, "/");
|
|
35
|
-
if (body.startsWith("/")) {
|
|
36
|
-
body = body.slice(1);
|
|
37
|
-
}
|
|
38
|
-
const cleaned = body.replace(/^\/+|\/+$/g, "").replace(/\/?\?$/, "");
|
|
39
|
-
const combined = basePath + "/" + cleaned + "/?";
|
|
40
|
-
const finalRegex = new RegExp(`^${combined}$`);
|
|
41
|
-
return finalRegex;
|
|
42
|
-
}
|
|
43
|
-
export function regexMatchRoute(regex, url, paramNames = []) {
|
|
44
|
-
const match = url.match(regex);
|
|
45
|
-
if (!match)
|
|
46
|
-
return { success: false, params: {} };
|
|
47
|
-
const params = {};
|
|
48
|
-
paramNames.forEach((name, idx) => {
|
|
49
|
-
params[name] = match[idx + 1] ?? null;
|
|
50
|
-
});
|
|
51
|
-
return { params, success: true };
|
|
52
|
-
}
|