tezx 1.0.77 → 2.0.0

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.
Files changed (58) hide show
  1. package/bun/index.d.ts +2 -0
  2. package/bun/index.js +2 -0
  3. package/cjs/{adapter → bun}/index.js +2 -3
  4. package/cjs/core/config.js +1 -1
  5. package/cjs/core/context.js +13 -7
  6. package/cjs/core/environment.js +3 -3
  7. package/cjs/core/request.js +7 -2
  8. package/cjs/core/router.js +18 -1
  9. package/cjs/core/server.js +5 -1
  10. package/cjs/{helper/env-parser.js → deno/env.js} +12 -26
  11. package/cjs/deno/index.js +18 -0
  12. package/cjs/helper/index.js +9 -18
  13. package/cjs/index.js +1 -1
  14. package/cjs/middleware/cors.js +1 -1
  15. package/cjs/node/adapter.js +105 -0
  16. package/cjs/node/env.js +50 -0
  17. package/cjs/node/index.js +18 -0
  18. package/cjs/utils/staticFile.js +1 -1
  19. package/cjs/utils/url.js +3 -7
  20. package/cjs/ws/index.js +1 -1
  21. package/core/config.d.ts +1 -1
  22. package/core/config.js +2 -2
  23. package/core/context.js +14 -8
  24. package/core/environment.d.ts +1 -1
  25. package/core/environment.js +1 -1
  26. package/core/request.js +7 -2
  27. package/core/router.d.ts +4 -0
  28. package/core/router.js +18 -1
  29. package/core/server.js +5 -1
  30. package/{helper/env-parser.js → deno/env.js} +13 -27
  31. package/deno/index.d.ts +2 -0
  32. package/deno/index.js +2 -0
  33. package/helper/index.d.ts +4 -2
  34. package/helper/index.js +4 -2
  35. package/index.d.ts +3 -2
  36. package/index.js +1 -1
  37. package/middleware/cors.js +1 -1
  38. package/node/adapter.js +102 -0
  39. package/node/env.d.ts +5 -0
  40. package/node/env.js +47 -0
  41. package/node/index.d.ts +2 -0
  42. package/node/index.js +2 -0
  43. package/package.json +21 -6
  44. package/utils/staticFile.js +2 -2
  45. package/utils/url.js +3 -7
  46. package/ws/index.js +2 -2
  47. package/adapter/index.d.ts +0 -4
  48. package/adapter/index.js +0 -3
  49. package/adapter/node.js +0 -85
  50. package/cjs/adapter/node.js +0 -87
  51. /package/{adapter/bun.d.ts → bun/adapter.d.ts} +0 -0
  52. /package/{adapter/bun.js → bun/adapter.js} +0 -0
  53. /package/cjs/{adapter/bun.js → bun/adapter.js} +0 -0
  54. /package/cjs/{adapter/deno.js → deno/adpater.js} +0 -0
  55. /package/{adapter/deno.d.ts → deno/adpater.d.ts} +0 -0
  56. /package/{adapter/deno.js → deno/adpater.js} +0 -0
  57. /package/{helper/env-parser.d.ts → deno/env.d.ts} +0 -0
  58. /package/{adapter/node.d.ts → node/adapter.d.ts} +0 -0
package/bun/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./adapter.js";
2
+ export * from "../node/index.js";
package/bun/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./adapter.js";
2
+ export * from "../node/index.js";
@@ -14,6 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./bun.js"), exports);
18
- __exportStar(require("./deno.js"), exports);
19
- __exportStar(require("./node.js"), exports);
17
+ __exportStar(require("./adapter.js"), exports);
18
+ __exportStar(require("../node/index.js"), exports);
@@ -15,7 +15,7 @@ let GlobalConfig = class {
15
15
  static overwriteMethod = true;
16
16
  static debugMode = false;
17
17
  static server;
18
- static adapter = environment_js_1.EnvironmentDetector.getEnvironment;
18
+ static adapter = environment_js_1.Environment.getEnvironment;
19
19
  static get debugging() {
20
20
  return this.debugMode
21
21
  ? {
@@ -107,12 +107,18 @@ class Context {
107
107
  else if (typeof args[0] === "object") {
108
108
  headers = args[0];
109
109
  }
110
- if (!headers["Content-Type"] && !headers["content-type"]) {
111
- if (typeof body === "string" || typeof body == "number") {
112
- headers["Content-Type"] = "text/plain;";
110
+ const contentTypeHeader = headers["Content-Type"] || headers["content-type"] || "";
111
+ if (!contentTypeHeader) {
112
+ if (typeof body === "string") {
113
+ headers["Content-Type"] = "text/plain; charset=utf-8";
113
114
  }
114
- else if (typeof body === "object" && body !== null) {
115
- headers["Content-Type"] = "application/json;";
115
+ else if (typeof body === "number" || typeof body === "boolean") {
116
+ headers["Content-Type"] = "text/plain; charset=utf-8";
117
+ }
118
+ else if (typeof body === "object" &&
119
+ body !== null &&
120
+ !(body instanceof ReadableStream)) {
121
+ headers["Content-Type"] = "application/json; charset=utf-8";
116
122
  body = JSON.stringify(body);
117
123
  }
118
124
  else {
@@ -207,7 +213,7 @@ class Context {
207
213
  async download(filePath, fileName) {
208
214
  try {
209
215
  let fileExists = false;
210
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
216
+ const runtime = environment_js_1.Environment.getEnvironment;
211
217
  if (runtime === "node") {
212
218
  const { existsSync } = await Promise.resolve().then(() => require("node:fs"));
213
219
  fileExists = existsSync(filePath);
@@ -255,7 +261,7 @@ class Context {
255
261
  }
256
262
  async sendFile(filePath, ...args) {
257
263
  try {
258
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
264
+ const runtime = environment_js_1.Environment.getEnvironment;
259
265
  const resolvedPath = filePath;
260
266
  let fileExists = false;
261
267
  if (runtime === "node") {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EnvironmentDetector = void 0;
4
- class EnvironmentDetector {
3
+ exports.Environment = void 0;
4
+ class Environment {
5
5
  static get getEnvironment() {
6
6
  if (typeof Bun !== "undefined")
7
7
  return "bun";
@@ -12,4 +12,4 @@ class EnvironmentDetector {
12
12
  return "unknown";
13
13
  }
14
14
  }
15
- exports.EnvironmentDetector = EnvironmentDetector;
15
+ exports.Environment = Environment;
@@ -52,7 +52,11 @@ class Request {
52
52
  return requestHeaders.forEach(callbackfn);
53
53
  },
54
54
  toJSON() {
55
- return requestHeaders.toJSON();
55
+ const obj = {};
56
+ for (const [key, value] of requestHeaders.entries()) {
57
+ obj[key] = value;
58
+ }
59
+ return obj;
56
60
  },
57
61
  };
58
62
  }
@@ -106,7 +110,8 @@ class Request {
106
110
  val.size > options.maxSize) {
107
111
  throw new Error(`File size exceeds the limit: ${val.size} bytes (Max: ${options.maxSize} bytes)`);
108
112
  }
109
- if (typeof options?.maxFiles != "undefined" && options.maxFiles == 0) {
113
+ if (typeof options?.maxFiles != "undefined" &&
114
+ options.maxFiles == 0) {
110
115
  throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
111
116
  }
112
117
  val = new File([await val.arrayBuffer()], filename, {
@@ -65,7 +65,24 @@ class Router extends MiddlewareConfigure_js_1.default {
65
65
  }
66
66
  sse(path, handler) {
67
67
  this.get(path, async (ctx) => {
68
- return handler(ctx);
68
+ let res = await handler(ctx);
69
+ const headersMap = {};
70
+ if (res instanceof Response) {
71
+ for (const [key, value] of res.headers.entries()) {
72
+ headersMap[key.toLowerCase()] = value;
73
+ }
74
+ res = res.body;
75
+ }
76
+ const headers = {
77
+ ...headersMap,
78
+ "content-type": "text/event-stream",
79
+ "cache-control": "no-cache",
80
+ connection: "keep-alive",
81
+ };
82
+ return new Response(res, {
83
+ status: 200,
84
+ headers,
85
+ });
69
86
  });
70
87
  }
71
88
  post(path, ...args) {
@@ -131,7 +131,11 @@ class TezX extends router_js_1.Router {
131
131
  throw new Error(`Handler failed: Middleware chain incomplete or response missing. Did you forget ${colors_js_1.COLORS.bgRed} 'await next()' ${colors_js_1.COLORS.reset} or to return a response? ${colors_js_1.COLORS.bgCyan} Path: ${ctx.pathname}, Method: ${ctx.method} ${colors_js_1.COLORS.reset}`);
132
132
  }
133
133
  const resBody = res || ctx.body;
134
- return ctx.send(resBody, ctx.headers.toJSON());
134
+ const toJson = {};
135
+ for (const [key, value] of ctx.headers.entries()) {
136
+ toJson[key] = value;
137
+ }
138
+ return ctx.send(resBody, toJson);
135
139
  };
136
140
  }
137
141
  #findMiddleware(pathname) {
@@ -2,34 +2,25 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.loadEnv = loadEnv;
4
4
  const environment_js_1 = require("../core/environment.js");
5
+ const colors_js_1 = require("../utils/colors.js");
5
6
  function parseEnvFile(filePath, result) {
6
7
  try {
8
+ let runtime = environment_js_1.Environment.getEnvironment;
9
+ if (runtime !== "deno") {
10
+ throw new Error(`Please use ${colors_js_1.COLORS.bgRed}import {loadEnv} from "tezx/${runtime}"${colors_js_1.COLORS.reset} environment`);
11
+ }
7
12
  let fileExists = false;
8
- let runtime = environment_js_1.EnvironmentDetector.getEnvironment;
9
- if (runtime === "node" || runtime === "bun") {
10
- const { existsSync } = require("fs");
11
- fileExists = existsSync(filePath);
13
+ try {
14
+ Deno.statSync(filePath);
15
+ fileExists = true;
12
16
  }
13
- else if (runtime === "deno") {
14
- try {
15
- Deno.statSync(filePath);
16
- fileExists = true;
17
- }
18
- catch {
19
- fileExists = false;
20
- }
17
+ catch {
18
+ fileExists = false;
21
19
  }
22
20
  if (!fileExists) {
23
21
  return;
24
22
  }
25
- let fileContent = "";
26
- if (runtime === "node" || runtime === "bun") {
27
- const { readFileSync } = require("fs");
28
- fileContent = readFileSync(filePath, "utf8");
29
- }
30
- else if (runtime === "deno") {
31
- fileContent = new TextDecoder("utf-8").decode(Deno.readFileSync(filePath));
32
- }
23
+ let fileContent = new TextDecoder("utf-8").decode(Deno.readFileSync(filePath));
33
24
  const lines = fileContent.split("\n");
34
25
  for (const line of lines) {
35
26
  const trimmedLine = line.trim();
@@ -41,12 +32,7 @@ function parseEnvFile(filePath, result) {
41
32
  .replace(/^"(.*)"$/, "$1")
42
33
  .replace(/^'(.*)'$/, "$1");
43
34
  result[key] = parsedValue;
44
- if (runtime === "node" || runtime === "bun") {
45
- process.env[key] = parsedValue;
46
- }
47
- else if (runtime === "deno") {
48
- Deno.env.set(key, parsedValue);
49
- }
35
+ Deno.env.set(key, parsedValue);
50
36
  }
51
37
  }
52
38
  }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./adpater.js"), exports);
18
+ __exportStar(require("./env.js"), exports);
@@ -1,20 +1,11 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.loadEnv = void 0;
18
- __exportStar(require("./common.js"), exports);
19
- var env_parser_js_1 = require("./env-parser.js");
20
- Object.defineProperty(exports, "loadEnv", { enumerable: true, get: function () { return env_parser_js_1.loadEnv; } });
3
+ exports.generateID = exports.sanitizePathSplit = exports.GlobalConfig = exports.Environment = void 0;
4
+ var environment_js_1 = require("../core/environment.js");
5
+ Object.defineProperty(exports, "Environment", { enumerable: true, get: function () { return environment_js_1.Environment; } });
6
+ var config_js_1 = require("../core/config.js");
7
+ Object.defineProperty(exports, "GlobalConfig", { enumerable: true, get: function () { return config_js_1.GlobalConfig; } });
8
+ var url_js_1 = require("../utils/url.js");
9
+ Object.defineProperty(exports, "sanitizePathSplit", { enumerable: true, get: function () { return url_js_1.sanitizePathSplit; } });
10
+ var common_js_1 = require("./common.js");
11
+ Object.defineProperty(exports, "generateID", { enumerable: true, get: function () { return common_js_1.generateID; } });
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.77";
10
+ exports.version = "2.0.0";
@@ -41,7 +41,7 @@ function cors(option = {}) {
41
41
  if (ctx.req.method === "OPTIONS") {
42
42
  return new Response(null, {
43
43
  status: 204,
44
- headers: ctx.headers.toJSON(),
44
+ headers: ctx.headers,
45
45
  });
46
46
  }
47
47
  return await next();
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nodeAdapter = nodeAdapter;
4
+ const node_buffer_1 = require("node:buffer");
5
+ const node_http_1 = require("node:http");
6
+ const node_https_1 = require("node:https");
7
+ const config_js_1 = require("../core/config.js");
8
+ const context_js_1 = require("../core/context.js");
9
+ function nodeAdapter(TezX, options = {}) {
10
+ function listen(...arg) {
11
+ let ssl = options?.enableSSL;
12
+ let createServerFn = ssl ? node_https_1.createServer : node_http_1.createServer;
13
+ config_js_1.GlobalConfig.adapter = "node";
14
+ let server = createServerFn(options, async (req, res) => {
15
+ let address = {};
16
+ if (req.socket) {
17
+ address = {
18
+ remoteAddr: {
19
+ family: req.socket.remoteFamily,
20
+ address: req.socket.remoteAddress,
21
+ port: req.socket.remotePort,
22
+ },
23
+ localAddr: {
24
+ address: req.socket.localAddress,
25
+ port: req.socket.localPort,
26
+ family: req.socket.localFamily,
27
+ },
28
+ };
29
+ }
30
+ let options = {
31
+ connInfo: address,
32
+ };
33
+ const response = await TezX.serve(req, options);
34
+ if (typeof response?.websocket === "function" &&
35
+ response.ctx instanceof context_js_1.Context &&
36
+ response.ctx.wsProtocol) {
37
+ response.websocket(response.ctx, server);
38
+ return res.end();
39
+ }
40
+ const statusText = response?.statusText;
41
+ if (!(response instanceof Response)) {
42
+ throw new Error("Invalid response from TezX.serve");
43
+ }
44
+ if (statusText) {
45
+ res.statusMessage = statusText;
46
+ }
47
+ res.writeHead(response.status, [...response.headers.entries()]);
48
+ const { Readable } = await Promise.resolve().then(() => require("node:stream"));
49
+ const body = response.body;
50
+ if (response.headers.get("Content-Type") === "text/event-stream") {
51
+ req.socket.setTimeout(0);
52
+ }
53
+ if (body instanceof Readable) {
54
+ return body.pipe(res);
55
+ }
56
+ else if (body?.pipeTo || body?.getReader) {
57
+ try {
58
+ return Readable.fromWeb(body).pipe(res);
59
+ }
60
+ catch (err) {
61
+ config_js_1.GlobalConfig.debugging.warn("Failed to stream web body:", err);
62
+ return res.end();
63
+ }
64
+ }
65
+ else if (typeof body?.[Symbol.asyncIterator] === "function") {
66
+ const readable = Readable.from(body);
67
+ return readable.pipe(res);
68
+ }
69
+ else {
70
+ try {
71
+ const buffer = await response.arrayBuffer?.();
72
+ if (buffer && buffer.byteLength > 0) {
73
+ return res.end(node_buffer_1.Buffer.from(buffer));
74
+ }
75
+ else {
76
+ return res.end();
77
+ }
78
+ }
79
+ catch (err) {
80
+ config_js_1.GlobalConfig.debugging.warn("Body extraction failed, trying text fallback...");
81
+ const text = await response.text?.();
82
+ return res.end(text ?? "");
83
+ }
84
+ }
85
+ });
86
+ const port = typeof arg[0] === "function" ? undefined : arg[0];
87
+ const callback = typeof arg[0] === "function" ? arg[0] : arg[1];
88
+ server.listen(options?.unix || port || 0, () => {
89
+ const protocol = ssl ? "\x1b[1;35mhttps\x1b[0m" : "\x1b[1;34mhttp\x1b[0m";
90
+ const address = server.address();
91
+ const message = typeof address === "string"
92
+ ? `\x1b[1mNodeJS TezX Server running at unix://${address}\x1b[0m`
93
+ : `\x1b[1mNodeJS TezX Server running at ${protocol}://localhost:${address?.port}/\x1b[0m`;
94
+ config_js_1.GlobalConfig.server = server;
95
+ config_js_1.GlobalConfig.debugging.success(message);
96
+ if (typeof callback == "function")
97
+ callback();
98
+ return server;
99
+ });
100
+ return server;
101
+ }
102
+ return {
103
+ listen,
104
+ };
105
+ }
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadEnv = loadEnv;
4
+ const node_fs_1 = require("node:fs");
5
+ const environment_js_1 = require("../core/environment.js");
6
+ const colors_js_1 = require("../utils/colors.js");
7
+ function parseEnvFile(filePath, result) {
8
+ try {
9
+ let runtime = environment_js_1.Environment.getEnvironment;
10
+ if (runtime !== "bun" && runtime !== "node") {
11
+ throw new Error(`Please use ${colors_js_1.COLORS.bgRed}import {loadEnv} from "tezx/${runtime}"${colors_js_1.COLORS.reset} environment`);
12
+ }
13
+ let fileExists = (0, node_fs_1.existsSync)(filePath);
14
+ if (!fileExists) {
15
+ return;
16
+ }
17
+ let fileContent = "";
18
+ fileContent = (0, node_fs_1.readFileSync)(filePath, "utf8");
19
+ const lines = fileContent.split("\n");
20
+ for (const line of lines) {
21
+ const trimmedLine = line.trim();
22
+ if (!trimmedLine || trimmedLine.startsWith("#"))
23
+ continue;
24
+ const [key, value] = trimmedLine.split("=", 2).map((part) => part.trim());
25
+ if (key && value) {
26
+ const parsedValue = value
27
+ .replace(/^"(.*)"$/, "$1")
28
+ .replace(/^'(.*)'$/, "$1");
29
+ result[key] = parsedValue;
30
+ process.env[key] = parsedValue;
31
+ }
32
+ }
33
+ }
34
+ catch (error) {
35
+ console.error(`[dotenv] Error parsing file: ${filePath}`, error);
36
+ }
37
+ }
38
+ function loadEnv(basePath = "./") {
39
+ const result = {};
40
+ const envFiles = [
41
+ ".env",
42
+ ".env.local",
43
+ `.env.${process?.env?.NODE_ENV || "development"}`,
44
+ `.env.${process?.env?.NODE_ENV || "development"}.local`,
45
+ ];
46
+ for (const envFile of envFiles) {
47
+ parseEnvFile(`${basePath}${envFile}`, result);
48
+ }
49
+ return result;
50
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./adapter.js"), exports);
18
+ __exportStar(require("./env.js"), exports);
@@ -109,7 +109,7 @@ exports.mimeTypes = {
109
109
  exports.defaultMimeType = "application/octet-stream";
110
110
  async function getFiles(dir, basePath = "/", ref, option) {
111
111
  const files = [];
112
- const runtime = environment_js_1.EnvironmentDetector.getEnvironment;
112
+ const runtime = environment_js_1.Environment.getEnvironment;
113
113
  if (runtime == "deno") {
114
114
  for await (const entry of Deno.readDir(dir)) {
115
115
  const path = `${dir}/${entry.name}`;
package/cjs/utils/url.js CHANGED
@@ -4,16 +4,12 @@ exports.wildcardOrOptionalParamRegex = void 0;
4
4
  exports.sanitizePathSplit = sanitizePathSplit;
5
5
  exports.urlParse = urlParse;
6
6
  function normalizePath(path) {
7
- return ('/' +
8
- path
9
- .replace(/\\/g, '')
10
- .replace(/\/+/g, '/')
11
- .replace(/^\/+/, ''));
7
+ return ("/" + path.replace(/\\/g, "").replace(/\/+/g, "/").replace(/^\/+/, ""));
12
8
  }
13
9
  function sanitizePathSplit(basePath, path) {
14
10
  const parts = `${basePath}/${path}`
15
- .replace(/\\/g, '')
16
- .replace(/\/+/g, '/')
11
+ .replace(/\\/g, "")
12
+ .replace(/\/+/g, "/")
17
13
  ?.split("/")
18
14
  .filter(Boolean);
19
15
  return parts;
package/cjs/ws/index.js CHANGED
@@ -23,7 +23,7 @@ function upgradeWebSocket(callback, options = {}) {
23
23
  }
24
24
  ctx.wsProtocol = ctx.req.urlRef.protocol === "https:" ? "wss" : "ws";
25
25
  try {
26
- const env = environment_js_1.EnvironmentDetector.getEnvironment;
26
+ const env = environment_js_1.Environment.getEnvironment;
27
27
  if (!callback) {
28
28
  throw new Error("WebSocket callback is missing. Please provide a valid callback function to handle the WebSocket events.");
29
29
  }
package/core/config.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { AdapterType } from "../adapter/index.js";
2
1
  import { Callback, ctx } from "./router.js";
2
+ export type AdapterType = "bun" | "deno" | "node";
3
3
  export declare let GlobalConfig: {
4
4
  new (): {};
5
5
  notFound: Callback;
package/core/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { loggerOutput } from "../utils/debugging.js";
2
- import { EnvironmentDetector } from "./environment.js";
2
+ import { Environment } from "./environment.js";
3
3
  export let GlobalConfig = class {
4
4
  static notFound = (ctx) => {
5
5
  const { method, urlRef: { pathname }, } = ctx.req;
@@ -12,7 +12,7 @@ export let GlobalConfig = class {
12
12
  static overwriteMethod = true;
13
13
  static debugMode = false;
14
14
  static server;
15
- static adapter = EnvironmentDetector.getEnvironment;
15
+ static adapter = Environment.getEnvironment;
16
16
  static get debugging() {
17
17
  return this.debugMode
18
18
  ? {
package/core/context.js CHANGED
@@ -2,7 +2,7 @@ import { State } from "../utils/state.js";
2
2
  import { defaultMimeType, mimeTypes } from "../utils/staticFile.js";
3
3
  import { toWebRequest } from "../utils/toWebRequest.js";
4
4
  import { GlobalConfig } from "./config.js";
5
- import { EnvironmentDetector } from "./environment.js";
5
+ import { Environment } from "./environment.js";
6
6
  import { Request as RequestParser } from "./request.js";
7
7
  export class Context {
8
8
  rawRequest;
@@ -104,12 +104,18 @@ export class Context {
104
104
  else if (typeof args[0] === "object") {
105
105
  headers = args[0];
106
106
  }
107
- if (!headers["Content-Type"] && !headers["content-type"]) {
108
- if (typeof body === "string" || typeof body == "number") {
109
- headers["Content-Type"] = "text/plain;";
107
+ const contentTypeHeader = headers["Content-Type"] || headers["content-type"] || "";
108
+ if (!contentTypeHeader) {
109
+ if (typeof body === "string") {
110
+ headers["Content-Type"] = "text/plain; charset=utf-8";
110
111
  }
111
- else if (typeof body === "object" && body !== null) {
112
- headers["Content-Type"] = "application/json;";
112
+ else if (typeof body === "number" || typeof body === "boolean") {
113
+ headers["Content-Type"] = "text/plain; charset=utf-8";
114
+ }
115
+ else if (typeof body === "object" &&
116
+ body !== null &&
117
+ !(body instanceof ReadableStream)) {
118
+ headers["Content-Type"] = "application/json; charset=utf-8";
113
119
  body = JSON.stringify(body);
114
120
  }
115
121
  else {
@@ -204,7 +210,7 @@ export class Context {
204
210
  async download(filePath, fileName) {
205
211
  try {
206
212
  let fileExists = false;
207
- const runtime = EnvironmentDetector.getEnvironment;
213
+ const runtime = Environment.getEnvironment;
208
214
  if (runtime === "node") {
209
215
  const { existsSync } = await import("node:fs");
210
216
  fileExists = existsSync(filePath);
@@ -252,7 +258,7 @@ export class Context {
252
258
  }
253
259
  async sendFile(filePath, ...args) {
254
260
  try {
255
- const runtime = EnvironmentDetector.getEnvironment;
261
+ const runtime = Environment.getEnvironment;
256
262
  const resolvedPath = filePath;
257
263
  let fileExists = false;
258
264
  if (runtime === "node") {
@@ -1,3 +1,3 @@
1
- export declare class EnvironmentDetector {
1
+ export declare class Environment {
2
2
  static get getEnvironment(): "node" | "bun" | "deno" | "unknown";
3
3
  }
@@ -1,4 +1,4 @@
1
- export class EnvironmentDetector {
1
+ export class Environment {
2
2
  static get getEnvironment() {
3
3
  if (typeof Bun !== "undefined")
4
4
  return "bun";
package/core/request.js CHANGED
@@ -49,7 +49,11 @@ export class Request {
49
49
  return requestHeaders.forEach(callbackfn);
50
50
  },
51
51
  toJSON() {
52
- return requestHeaders.toJSON();
52
+ const obj = {};
53
+ for (const [key, value] of requestHeaders.entries()) {
54
+ obj[key] = value;
55
+ }
56
+ return obj;
53
57
  },
54
58
  };
55
59
  }
@@ -103,7 +107,8 @@ export class Request {
103
107
  val.size > options.maxSize) {
104
108
  throw new Error(`File size exceeds the limit: ${val.size} bytes (Max: ${options.maxSize} bytes)`);
105
109
  }
106
- if (typeof options?.maxFiles != "undefined" && options.maxFiles == 0) {
110
+ if (typeof options?.maxFiles != "undefined" &&
111
+ options.maxFiles == 0) {
107
112
  throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
108
113
  }
109
114
  val = new File([await val.arrayBuffer()], filename, {
package/core/router.d.ts CHANGED
@@ -91,6 +91,10 @@ export declare class Router<T extends Record<string, any> = {}> extends Middlewa
91
91
  * const stream = new ReadableStream({
92
92
  * start(controller) {
93
93
  * controller.enqueue(new TextEncoder().encode("data: Hello\n\n"));
94
+ * ctx.rawRequest?.signal?.addEventListener("abort", () => {
95
+ * clearInterval(interval);
96
+ * controller.close()
97
+ * });
94
98
  * },
95
99
  * });
96
100
  *
package/core/router.js CHANGED
@@ -61,7 +61,24 @@ export class Router extends MiddlewareConfigure {
61
61
  }
62
62
  sse(path, handler) {
63
63
  this.get(path, async (ctx) => {
64
- return handler(ctx);
64
+ let res = await handler(ctx);
65
+ const headersMap = {};
66
+ if (res instanceof Response) {
67
+ for (const [key, value] of res.headers.entries()) {
68
+ headersMap[key.toLowerCase()] = value;
69
+ }
70
+ res = res.body;
71
+ }
72
+ const headers = {
73
+ ...headersMap,
74
+ "content-type": "text/event-stream",
75
+ "cache-control": "no-cache",
76
+ connection: "keep-alive",
77
+ };
78
+ return new Response(res, {
79
+ status: 200,
80
+ headers,
81
+ });
65
82
  });
66
83
  }
67
84
  post(path, ...args) {