bxo 0.0.10-dev.2 → 0.0.10-dev.4

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.
@@ -0,0 +1,136 @@
1
+ import BXO from "../src";
2
+
3
+ // Example configurations for different deployment scenarios
4
+
5
+ // 1. Development - Local only
6
+ export const developmentConfig = new BXO({
7
+ serve: {
8
+ hostname: "127.0.0.1", // Only localhost
9
+ port: 3000,
10
+ development: true
11
+ }
12
+ });
13
+
14
+ // 2. Local Network - Accessible from other devices on same network
15
+ export const localNetworkConfig = new BXO({
16
+ serve: {
17
+ hostname: "0.0.0.0", // All interfaces
18
+ port: 3000,
19
+ development: true
20
+ }
21
+ });
22
+
23
+ // 3. Production - External access with security
24
+ export const productionConfig = new BXO({
25
+ serve: {
26
+ hostname: "0.0.0.0", // All interfaces
27
+ port: 8080,
28
+ development: false
29
+ }
30
+ });
31
+
32
+ // 4. Docker Container - Internal network
33
+ export const dockerConfig = new BXO({
34
+ serve: {
35
+ hostname: "0.0.0.0", // All interfaces (required for Docker)
36
+ port: 3000,
37
+ development: false
38
+ }
39
+ });
40
+
41
+ // 5. Cloud Deployment (AWS, GCP, Azure)
42
+ export const cloudConfig = new BXO({
43
+ serve: {
44
+ hostname: "0.0.0.0", // All interfaces
45
+ port: process.env.PORT || 8080, // Use environment port
46
+ development: false
47
+ }
48
+ });
49
+
50
+ // 6. Specific IP binding
51
+ export const specificIPConfig = new BXO({
52
+ serve: {
53
+ hostname: "192.168.1.100", // Specific IP
54
+ port: 3000
55
+ }
56
+ });
57
+
58
+ // 7. Domain binding (if you have a specific domain)
59
+ export const domainConfig = new BXO({
60
+ serve: {
61
+ hostname: "api.yourdomain.com", // Specific domain
62
+ port: 80
63
+ }
64
+ });
65
+
66
+ // Example usage function
67
+ async function runExample() {
68
+ console.log("šŸš€ BXO Deployment Configuration Examples\n");
69
+
70
+ // Choose which configuration to use
71
+ const app = localNetworkConfig; // Change this to test different configs
72
+
73
+ // Add some routes
74
+ app.get("/", (ctx) => {
75
+ return ctx.json({
76
+ message: "BXO Server Running",
77
+ hostname: app.server?.hostname || "default",
78
+ port: app.server?.port,
79
+ environment: process.env.NODE_ENV || "development",
80
+ accessible: app.server?.hostname === "0.0.0.0" ? "External networks" : "Local only"
81
+ });
82
+ });
83
+
84
+ app.get("/health", (ctx) => {
85
+ return ctx.json({
86
+ status: "healthy",
87
+ timestamp: new Date().toISOString(),
88
+ hostname: app.server?.hostname,
89
+ port: app.server?.port
90
+ });
91
+ });
92
+
93
+ // WebSocket example with hostname info
94
+ app.ws("/ws", {
95
+ open(ws) {
96
+ const data = ws.data;
97
+ console.log(`šŸ”Œ WebSocket connected from ${data.ip} to hostname: ${app.server?.hostname}`);
98
+ ws.send(`Connected to server on ${app.server?.hostname}:${app.server?.port}`);
99
+ },
100
+
101
+ message(ws, message) {
102
+ const data = ws.data;
103
+ console.log(`šŸ’¬ Message from ${data.ip}: ${message}`);
104
+ ws.send(`Echo from ${app.server?.hostname}: ${message}`);
105
+ }
106
+ });
107
+
108
+ app.start();
109
+
110
+ console.log(`āœ… Server started successfully!`);
111
+ console.log(`šŸ“ Hostname: ${app.server?.hostname}`);
112
+ console.log(`šŸ”Œ Port: ${app.server?.port}`);
113
+ console.log(`🌐 Access URLs:`);
114
+
115
+ if (app.server?.hostname === "0.0.0.0") {
116
+ console.log(` • http://localhost:${app.server.port}`);
117
+ console.log(` • http://127.0.0.1:${app.server.port}`);
118
+ console.log(` • http://your-server-ip:${app.server.port}`);
119
+ console.log(` • http://your-domain.com:${app.server.port}`);
120
+ } else if (app.server?.hostname === "127.0.0.1") {
121
+ console.log(` • http://localhost:${app.server.port}`);
122
+ console.log(` • http://127.0.0.1:${app.server.port}`);
123
+ } else {
124
+ console.log(` • http://${app.server?.hostname}:${app.server?.port}`);
125
+ }
126
+
127
+ console.log(`\nšŸ“‹ Configuration Guide:`);
128
+ console.log(` • Development: hostname: "127.0.0.1" (localhost only)`);
129
+ console.log(` • Local Network: hostname: "0.0.0.0" (all interfaces)`);
130
+ console.log(` • Production: hostname: "0.0.0.0" + reverse proxy`);
131
+ console.log(` • Docker: hostname: "0.0.0.0" (required for container networking)`);
132
+ console.log(` • Cloud: hostname: "0.0.0.0" + environment port`);
133
+ }
134
+
135
+ // Run the example
136
+ runExample().catch(console.error);
@@ -0,0 +1,127 @@
1
+ import BXO from "../src";
2
+
3
+ async function main() {
4
+ console.log("🌐 BXO Hostname Configuration Examples\n");
5
+
6
+ // Example 1: Serve on all interfaces (0.0.0.0) - accessible from external networks
7
+ console.log("1. Serving on all interfaces (0.0.0.0) - accessible from external networks");
8
+ const app1 = new BXO({
9
+ serve: {
10
+ hostname: "0.0.0.0", // Listen on all network interfaces
11
+ port: 3000
12
+ }
13
+ });
14
+
15
+ app1.get("/", (ctx) => {
16
+ return ctx.json({
17
+ message: "Hello from BXO!",
18
+ hostname: "0.0.0.0",
19
+ accessible: "From any network interface",
20
+ examples: [
21
+ "http://localhost:3000",
22
+ "http://127.0.0.1:3000",
23
+ "http://your-server-ip:3000",
24
+ "http://your-domain.com:3000"
25
+ ]
26
+ });
27
+ });
28
+
29
+ // Example 2: Serve on specific hostname/IP
30
+ console.log("2. Serving on specific hostname/IP");
31
+ const app2 = new BXO({
32
+ serve: {
33
+ hostname: "127.0.0.1", // Only localhost
34
+ port: 3001
35
+ }
36
+ });
37
+
38
+ app2.get("/", (ctx) => {
39
+ return ctx.json({
40
+ message: "Hello from BXO!",
41
+ hostname: "127.0.0.1",
42
+ accessible: "Only from localhost",
43
+ examples: [
44
+ "http://localhost:3001",
45
+ "http://127.0.0.1:3001"
46
+ ]
47
+ });
48
+ });
49
+
50
+ // Example 3: Production configuration with external access
51
+ console.log("3. Production configuration with external access");
52
+ const app3 = new BXO({
53
+ serve: {
54
+ hostname: "0.0.0.0", // Listen on all interfaces
55
+ port: 8080,
56
+ // Additional production options
57
+ development: false,
58
+ // You can add more Bun.serve options here
59
+ }
60
+ });
61
+
62
+ app3.get("/", (ctx) => {
63
+ return ctx.json({
64
+ message: "Production BXO Server",
65
+ hostname: "0.0.0.0",
66
+ port: 8080,
67
+ accessible: "From external networks",
68
+ deployment: "Production ready"
69
+ });
70
+ });
71
+
72
+ // Example 4: Custom hostname for specific deployment
73
+ console.log("4. Custom hostname for specific deployment");
74
+ const app4 = new BXO({
75
+ serve: {
76
+ hostname: "192.168.1.100", // Specific IP address
77
+ port: 4000
78
+ }
79
+ });
80
+
81
+ app4.get("/", (ctx) => {
82
+ return ctx.json({
83
+ message: "BXO on specific IP",
84
+ hostname: "192.168.1.100",
85
+ accessible: "From network 192.168.1.x",
86
+ examples: [
87
+ "http://192.168.1.100:4000"
88
+ ]
89
+ });
90
+ });
91
+
92
+ // Start the server you want to test
93
+ const selectedApp = app1; // Change this to app1, app2, app3, or app4
94
+
95
+ selectedApp.start();
96
+
97
+ console.log(`šŸš€ Server started!`);
98
+ console.log(`šŸ“ Hostname: ${selectedApp.server?.hostname || 'default'}`);
99
+ console.log(`šŸ”Œ Port: ${selectedApp.server?.port}`);
100
+ console.log(`🌐 Accessible at:`);
101
+
102
+ if (selectedApp === app1) {
103
+ console.log(` • http://localhost:3000`);
104
+ console.log(` • http://127.0.0.1:3000`);
105
+ console.log(` • http://your-server-ip:3000`);
106
+ console.log(` • http://your-domain.com:3000`);
107
+ } else if (selectedApp === app2) {
108
+ console.log(` • http://localhost:3001`);
109
+ console.log(` • http://127.0.0.1:3001`);
110
+ } else if (selectedApp === app3) {
111
+ console.log(` • http://localhost:8080`);
112
+ console.log(` • http://your-server-ip:8080`);
113
+ console.log(` • http://your-domain.com:8080`);
114
+ } else if (selectedApp === app4) {
115
+ console.log(` • http://192.168.1.100:4000`);
116
+ }
117
+
118
+ console.log(`\nšŸ“ Configuration Options:`);
119
+ console.log(` • hostname: "0.0.0.0" - Listen on all interfaces (external access)`);
120
+ console.log(` • hostname: "127.0.0.1" - Only localhost access`);
121
+ console.log(` • hostname: "192.168.1.100" - Specific IP address`);
122
+ console.log(` • hostname: "your-domain.com" - Specific domain`);
123
+ console.log(` • port: 3000 - Custom port number`);
124
+ console.log(` • development: false - Production mode`);
125
+ }
126
+
127
+ main().catch(console.error);
@@ -0,0 +1,194 @@
1
+ import BXO from "../src";
2
+
3
+ async function main() {
4
+ const app = new BXO({ serve: { port: 3000, hostname: '0.0.0.0' } });
5
+
6
+ // Enhanced IP detection function
7
+ function getClientIP(req: Request): string {
8
+ // Check proxy headers first
9
+ const forwardedFor = req.headers.get("x-forwarded-for");
10
+ const realIP = req.headers.get("x-real-ip");
11
+ const clientIP = req.headers.get("x-client-ip");
12
+ const cfConnectingIP = req.headers.get("cf-connecting-ip"); // Cloudflare
13
+
14
+ if (forwardedFor) {
15
+ // X-Forwarded-For can contain multiple IPs: "client, proxy1, proxy2"
16
+ // The first IP is usually the original client
17
+ return forwardedFor.split(',')[0].trim();
18
+ }
19
+
20
+ if (realIP) return realIP;
21
+ if (clientIP) return clientIP;
22
+ if (cfConnectingIP) return cfConnectingIP;
23
+
24
+ // If no proxy headers, try to get from connection
25
+ // Note: This is a workaround since Bun doesn't expose connection IP directly
26
+ // In production, you should always use a reverse proxy that sets proper headers
27
+
28
+ // For localhost development, return localhost
29
+ const host = req.headers.get("host");
30
+ if (host?.includes("localhost") || host?.includes("127.0.0.1")) {
31
+ return "127.0.0.1";
32
+ }
33
+
34
+ return "unknown";
35
+ }
36
+
37
+ // HTTP route with enhanced IP detection
38
+ app.get("/api/ip", (ctx) => {
39
+ const ip = getClientIP(ctx.request);
40
+
41
+ return ctx.json({
42
+ ip: ip,
43
+ headers: {
44
+ "x-forwarded-for": ctx.headers["x-forwarded-for"],
45
+ "x-real-ip": ctx.headers["x-real-ip"],
46
+ "x-client-ip": ctx.headers["x-client-ip"],
47
+ "cf-connecting-ip": ctx.headers["cf-connecting-ip"],
48
+ "host": ctx.headers["host"]
49
+ },
50
+ allHeaders: ctx.headers,
51
+ message: ip === "unknown" ?
52
+ "IP detection failed. In production, use a reverse proxy (nginx, Cloudflare, etc.) that sets X-Forwarded-For headers." :
53
+ "IP detected successfully!"
54
+ });
55
+ });
56
+
57
+ // WebSocket route with enhanced IP detection
58
+ app.ws("/ws", {
59
+ open(ws) {
60
+ // For WebSocket, we need to get IP from the original request
61
+ // This is a workaround since BXO's WebSocket data might show "unknown"
62
+ const ip = ws.data.ip !== "unknown" ? ws.data.ip : "127.0.0.1";
63
+
64
+ console.log(`WebSocket client connected from IP: ${ip}`);
65
+ ws.send(`Hello! Your IP is: ${ip}`);
66
+ },
67
+ message(ws, message) {
68
+ const ip = ws.data.ip !== "unknown" ? ws.data.ip : "127.0.0.1";
69
+ console.log(`Message from ${ip}: ${message}`);
70
+ ws.send(`Echo: ${message} (from IP: ${ip})`);
71
+ }
72
+ });
73
+
74
+ // Debug route to see all headers
75
+ app.get("/debug", (ctx) => {
76
+ return ctx.json({
77
+ message: "Debug information",
78
+ headers: ctx.headers,
79
+ cookies: ctx.cookies,
80
+ userAgent: ctx.headers["user-agent"]
81
+ });
82
+ });
83
+
84
+ // Home page with test interface
85
+ app.get("/", (ctx) => {
86
+ return ctx.html(`
87
+ <!DOCTYPE html>
88
+ <html>
89
+ <head>
90
+ <title>BXO IP Detection Test</title>
91
+ <style>
92
+ body { font-family: Arial, sans-serif; margin: 40px; }
93
+ button { padding: 10px 20px; margin: 10px; background: #007bff; color: white; border: none; border-radius: 5px; cursor: pointer; }
94
+ button:hover { background: #0056b3; }
95
+ .result { background: #f8f9fa; padding: 20px; margin: 20px 0; border-radius: 5px; }
96
+ pre { background: #e9ecef; padding: 10px; border-radius: 3px; overflow-x: auto; }
97
+ </style>
98
+ </head>
99
+ <body>
100
+ <h1>BXO IP Detection Test</h1>
101
+
102
+ <div>
103
+ <button onclick="checkIP()">Check My IP</button>
104
+ <button onclick="checkDebug()">Debug Headers</button>
105
+ <button onclick="connectWebSocket()">Connect WebSocket</button>
106
+ </div>
107
+
108
+ <div id="result" class="result" style="display: none;">
109
+ <h3>Result:</h3>
110
+ <pre id="resultContent"></pre>
111
+ </div>
112
+
113
+ <div id="wsMessages" class="result" style="display: none;">
114
+ <h3>WebSocket Messages:</h3>
115
+ <div id="wsContent"></div>
116
+ </div>
117
+
118
+ <script>
119
+ let ws = null;
120
+
121
+ async function checkIP() {
122
+ try {
123
+ const res = await fetch('/api/ip');
124
+ const data = await res.json();
125
+ showResult(data);
126
+ } catch (error) {
127
+ showResult({ error: error.message });
128
+ }
129
+ }
130
+
131
+ async function checkDebug() {
132
+ try {
133
+ const res = await fetch('/debug');
134
+ const data = await res.json();
135
+ showResult(data);
136
+ } catch (error) {
137
+ showResult({ error: error.message });
138
+ }
139
+ }
140
+
141
+ function connectWebSocket() {
142
+ if (ws) {
143
+ ws.close();
144
+ }
145
+
146
+ ws = new WebSocket('ws://localhost:3000/ws');
147
+
148
+ ws.onopen = function() {
149
+ addWSMessage('Connected to WebSocket');
150
+ };
151
+
152
+ ws.onmessage = function(event) {
153
+ addWSMessage('Received: ' + event.data);
154
+ };
155
+
156
+ ws.onclose = function() {
157
+ addWSMessage('Disconnected from WebSocket');
158
+ };
159
+
160
+ ws.onerror = function(error) {
161
+ addWSMessage('Error: ' + error);
162
+ };
163
+ }
164
+
165
+ function showResult(data) {
166
+ document.getElementById('result').style.display = 'block';
167
+ document.getElementById('resultContent').textContent = JSON.stringify(data, null, 2);
168
+ }
169
+
170
+ function addWSMessage(message) {
171
+ document.getElementById('wsMessages').style.display = 'block';
172
+ const div = document.createElement('div');
173
+ div.textContent = new Date().toLocaleTimeString() + ': ' + message;
174
+ document.getElementById('wsContent').appendChild(div);
175
+ }
176
+ </script>
177
+ </body>
178
+ </html>
179
+ `);
180
+ });
181
+
182
+ console.log("šŸš€ BXO IP Detection Example");
183
+ console.log("šŸ“” Server running on http://localhost:3000");
184
+ console.log("šŸ” Visit http://localhost:3000 to test IP detection");
185
+ console.log("\nšŸ’” Tips for getting real IP addresses:");
186
+ console.log("1. Use a reverse proxy (nginx, Apache) that sets X-Forwarded-For headers");
187
+ console.log("2. Deploy behind Cloudflare (sets CF-Connecting-IP header)");
188
+ console.log("3. Use AWS ALB/ELB (sets X-Forwarded-For header)");
189
+ console.log("4. For local development, IP will show as 127.0.0.1 or unknown");
190
+
191
+ app.start();
192
+ }
193
+
194
+ main().catch(console.error);
@@ -0,0 +1,48 @@
1
+ # Nginx configuration for BXO with proper IP forwarding
2
+ # This ensures X-Forwarded-For headers are set correctly
3
+
4
+ server {
5
+ listen 80;
6
+ server_name your-domain.com;
7
+
8
+ # Forward all requests to BXO server
9
+ location / {
10
+ proxy_pass http://127.0.0.1:3000;
11
+
12
+ # Set headers for IP detection
13
+ proxy_set_header Host $host;
14
+ proxy_set_header X-Real-IP $remote_addr;
15
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
16
+ proxy_set_header X-Forwarded-Proto $scheme;
17
+
18
+ # WebSocket support
19
+ proxy_http_version 1.1;
20
+ proxy_set_header Upgrade $http_upgrade;
21
+ proxy_set_header Connection "upgrade";
22
+ }
23
+ }
24
+
25
+ # HTTPS version (recommended for production)
26
+ server {
27
+ listen 443 ssl;
28
+ server_name your-domain.com;
29
+
30
+ # SSL configuration
31
+ ssl_certificate /path/to/your/certificate.crt;
32
+ ssl_certificate_key /path/to/your/private.key;
33
+
34
+ location / {
35
+ proxy_pass http://127.0.0.1:3000;
36
+
37
+ # Set headers for IP detection
38
+ proxy_set_header Host $host;
39
+ proxy_set_header X-Real-IP $remote_addr;
40
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
41
+ proxy_set_header X-Forwarded-Proto $scheme;
42
+
43
+ # WebSocket support
44
+ proxy_http_version 1.1;
45
+ proxy_set_header Upgrade $http_upgrade;
46
+ proxy_set_header Connection "upgrade";
47
+ }
48
+ }
@@ -1,7 +1,13 @@
1
1
  import BXO from "../src";
2
2
 
3
3
  async function main() {
4
- const app = new BXO({ serve: { port: 3000 } });
4
+ // Configure hostname for external access
5
+ const app = new BXO({
6
+ serve: {
7
+ hostname: "0.0.0.0", // Listen on all interfaces for external access
8
+ port: 3000
9
+ }
10
+ });
5
11
 
6
12
  // HTTP routes
7
13
  app.get("/", (ctx) => {
@@ -252,9 +258,19 @@ async function main() {
252
258
  });
253
259
 
254
260
  app.start();
255
- console.log(`šŸš€ Server is running on http://localhost:${app.server?.port}`);
256
- console.log(`šŸ”Œ WebSocket available at ws://localhost:${app.server?.port}/ws`);
257
- console.log(`šŸ’¬ Chat WebSocket available at ws://localhost:${app.server?.port}/chat/:room`);
261
+ console.log(`šŸš€ Server is running:`);
262
+ console.log(`šŸ“ Hostname: ${app.server?.hostname || 'default'}`);
263
+ console.log(`šŸ”Œ Port: ${app.server?.port}`);
264
+ console.log(`🌐 HTTP: http://localhost:${app.server?.port}`);
265
+ console.log(`šŸ”Œ WebSocket: ws://localhost:${app.server?.port}/ws`);
266
+ console.log(`šŸ’¬ Chat WebSocket: ws://localhost:${app.server?.port}/chat/:room`);
267
+
268
+ if (app.server?.hostname === "0.0.0.0") {
269
+ console.log(`\nšŸŒ External Access Available:`);
270
+ console.log(` • http://your-server-ip:${app.server.port}`);
271
+ console.log(` • http://your-domain.com:${app.server.port}`);
272
+ console.log(` • ws://your-server-ip:${app.server.port}/ws`);
273
+ }
258
274
  console.log(`\nšŸ“ Features demonstrated:`);
259
275
  console.log(` • ws.data.id - Short, unique client identifier`);
260
276
  console.log(` • ws.data.connectionId - Detailed connection ID`);
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  ".": "./src/index.ts",
6
6
  "./plugins": "./plugins/index.ts"
7
7
  },
8
- "version": "0.0.10-dev.2",
8
+ "version": "0.0.10-dev.4",
9
9
  "type": "module",
10
10
  "devDependencies": {
11
11
  "@types/bun": "latest"
package/src/index.ts CHANGED
@@ -82,6 +82,7 @@ export type Context<P extends string = string, S extends RouteSchema | undefined
82
82
  };
83
83
  json: <T>(data: T, status?: number) => Response;
84
84
  text: (data: string, status?: number) => Response;
85
+ html: (data: string, status?: number) => Response;
85
86
  status: <T extends number>(status: T, data: InferResponse<S, T>) => Response;
86
87
  redirect: (url: string, status?: 301 | 302 | 303 | 307 | 308) => Response;
87
88
  };
@@ -195,11 +196,14 @@ function parseQuery<T extends z.ZodTypeAny>(searchParams: URLSearchParams, schem
195
196
  function parseQuery(searchParams: URLSearchParams, schema?: z.ZodTypeAny): any {
196
197
  const out: QueryObject = {};
197
198
  for (const [k, v] of searchParams.entries()) {
198
- if (k in out) {
199
- const existing = out[k];
200
- if (Array.isArray(existing)) out[k] = [...existing, v];
201
- else out[k] = [existing as string, v];
202
- } else out[k] = v;
199
+ // Handle array notation like fields[] -> fields
200
+ const key = k.endsWith('[]') ? k.slice(0, -2) : k;
201
+
202
+ if (key in out) {
203
+ const existing = out[key];
204
+ if (Array.isArray(existing)) out[key] = [...existing, v];
205
+ else out[key] = [existing as string, v];
206
+ } else out[key] = v;
203
207
  }
204
208
  if (schema) {
205
209
  return (schema as any).parse ? (schema as any).parse(out) : out;
@@ -808,6 +812,19 @@ export default class BXO {
808
812
  headers: { "Content-Type": "text/plain" }
809
813
  });
810
814
  },
815
+ html: (data, status = 200) => {
816
+ if (route.schema?.response?.[status]) {
817
+ const sch = route.schema.response[status]!;
818
+ const res = (sch as any).safeParse ? (sch as any).safeParse(data) : { success: true };
819
+ if (!res.success) {
820
+ return new Response(JSON.stringify({ error: "Invalid response", issues: res.error?.issues ?? [] }), { status: 500, headers: { "Content-Type": "application/json" } });
821
+ }
822
+ }
823
+ return new Response(String(data), {
824
+ status,
825
+ headers: { "Content-Type": "text/html; charset=utf-8" }
826
+ });
827
+ },
811
828
  status: (status, data) => {
812
829
  // Response validation if declared
813
830
  if (route.schema?.response?.[status]) {
@@ -1,75 +0,0 @@
1
- import BXO from "./src";
2
-
3
- async function testDefaultContentType() {
4
- const bxo = new BXO({ serve: { port: 0 } });
5
-
6
- // Test route that returns a string without explicit content type
7
- bxo.get("/test-string", (ctx) => {
8
- return "Hello World";
9
- });
10
-
11
- // Test route that returns a string with explicit content type
12
- bxo.get("/test-string-explicit", (ctx) => {
13
- return new Response("Hello World", {
14
- headers: { "Content-Type": "text/plain" }
15
- });
16
- });
17
-
18
- // Test route that uses ctx.json (should be application/json)
19
- bxo.get("/test-json", (ctx) => {
20
- return ctx.json({ message: "Hello World" });
21
- });
22
-
23
- // Test route that uses ctx.text (should be text/plain)
24
- bxo.get("/test-text", (ctx) => {
25
- return ctx.text("Hello World");
26
- });
27
-
28
- bxo.start();
29
-
30
- const baseUrl = `http://localhost:${bxo.server?.port}`;
31
-
32
- console.log("Testing default content type...");
33
-
34
- // Test 1: String response should default to text/html
35
- try {
36
- const response1 = await fetch(`${baseUrl}/test-string`);
37
- const contentType1 = response1.headers.get('Content-Type');
38
- console.log(`āœ“ String response Content-Type: ${contentType1} (should be text/html)`);
39
- } catch (error) {
40
- console.error("āœ— Error testing string response:", error);
41
- }
42
-
43
- // Test 2: Explicit content type should be preserved
44
- try {
45
- const response2 = await fetch(`${baseUrl}/test-string-explicit`);
46
- const contentType2 = response2.headers.get('Content-Type');
47
- console.log(`āœ“ Explicit Content-Type: ${contentType2} (should be text/plain)`);
48
- } catch (error) {
49
- console.error("āœ— Error testing explicit content type:", error);
50
- }
51
-
52
- // Test 3: ctx.json should be application/json
53
- try {
54
- const response3 = await fetch(`${baseUrl}/test-json`);
55
- const contentType3 = response3.headers.get('Content-Type');
56
- console.log(`āœ“ ctx.json Content-Type: ${contentType3} (should be application/json)`);
57
- } catch (error) {
58
- console.error("āœ— Error testing ctx.json:", error);
59
- }
60
-
61
- // Test 4: ctx.text should be text/plain
62
- try {
63
- const response4 = await fetch(`${baseUrl}/test-text`);
64
- const contentType4 = response4.headers.get('Content-Type');
65
- console.log(`āœ“ ctx.text Content-Type: ${contentType4} (should be text/plain)`);
66
- } catch (error) {
67
- console.error("āœ— Error testing ctx.text:", error);
68
- }
69
-
70
- // Close the server
71
- bxo.server?.stop();
72
- console.log("Test completed!");
73
- }
74
-
75
- testDefaultContentType().catch(console.error);