bxo 0.0.5-dev.65 โ†’ 0.0.5-dev.67

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 (37) hide show
  1. package/README.md +83 -675
  2. package/example/cors-example.ts +49 -0
  3. package/example/index.html +5 -0
  4. package/example/index.ts +57 -0
  5. package/package.json +9 -15
  6. package/plugins/cors.ts +124 -98
  7. package/plugins/index.ts +2 -9
  8. package/plugins/openapi.ts +130 -0
  9. package/src/index.ts +646 -59
  10. package/tsconfig.json +3 -5
  11. package/.cursor/rules/use-bun-instead-of-node-vite-npm-pnpm.mdc +0 -111
  12. package/examples/serve-react/README.md +0 -15
  13. package/examples/serve-react/app.tsx +0 -8
  14. package/examples/serve-react/bun.lock +0 -42
  15. package/examples/serve-react/index.html +0 -9
  16. package/examples/serve-react/index.ts +0 -27
  17. package/examples/serve-react/package.json +0 -17
  18. package/examples/serve-react/tsconfig.json +0 -29
  19. package/index.ts +0 -5
  20. package/plugins/README.md +0 -160
  21. package/plugins/ratelimit.ts +0 -136
  22. package/src/core/bxo.ts +0 -458
  23. package/src/handlers/request-handler.ts +0 -230
  24. package/src/types/index.ts +0 -167
  25. package/src/utils/context-factory.ts +0 -158
  26. package/src/utils/helpers.ts +0 -40
  27. package/src/utils/index.ts +0 -448
  28. package/src/utils/response-handler.ts +0 -293
  29. package/src/utils/route-matcher.ts +0 -191
  30. package/tests/README.md +0 -359
  31. package/tests/integration/bxo.test.ts +0 -616
  32. package/tests/run-tests.ts +0 -44
  33. package/tests/unit/context-factory.test.ts +0 -386
  34. package/tests/unit/helpers.test.ts +0 -253
  35. package/tests/unit/response-handler.test.ts +0 -327
  36. package/tests/unit/route-matcher.test.ts +0 -181
  37. package/tests/unit/utils.test.ts +0 -475
package/README.md CHANGED
@@ -1,746 +1,154 @@
1
- # ๐ŸฆŠ BXO - A Type-Safe Web Framework for Bun
1
+ # bxo
2
2
 
3
- BXO is a fast, lightweight, and fully type-safe web framework built specifically for Bun runtime. Inspired by Elysia, it provides excellent developer experience with automatic type inference, Zod validation, and a powerful plugin system.
3
+ A fast, lightweight web framework for Bun with built-in Zod validation and lifecycle hooks.
4
4
 
5
- ## โœจ Features
5
+ ## Features
6
6
 
7
- - ๐Ÿš€ **Built for Bun** - Leverages Bun's native HTTP server for maximum performance
8
- - ๐Ÿ”’ **Type-Safe** - Full TypeScript support with automatic type inference
9
- - ๐Ÿ“‹ **Zod Validation** - Built-in request/response validation using Zod schemas
10
- - ๐Ÿ”Œ **Plugin System** - Extensible architecture with lifecycle hooks
11
- - ๐ŸŽฃ **Lifecycle Hooks** - Complete control over server and request/response lifecycle
12
- - ๐Ÿ”„ **Hot Reload** - Automatic server restart on file changes during development
13
- - ๐ŸŽฎ **Server Management** - Programmatic start, stop, and restart capabilities
14
- - ๐Ÿ“Š **Status Monitoring** - Built-in server status and runtime statistics
15
- - ๐Ÿ“ฆ **Zero Dependencies** - Only depends on Zod for validation
16
- - โšก **Fast** - Minimal overhead with efficient routing
7
+ - **Type-safe routing** with Zod schema validation
8
+ - **Lifecycle hooks** for middleware and plugins
9
+ - **Plugin system** for extending functionality
10
+ - **Built-in CORS support** via plugin
11
+ - **Fast performance** leveraging Bun's native HTTP server
17
12
 
18
- ## ๐Ÿš€ Quick Start
19
-
20
- ### Installation
13
+ ## Installation
21
14
 
22
15
  ```bash
23
- bun add bxo
16
+ bun install
24
17
  ```
25
18
 
26
- ### Basic Usage
19
+ ## Quick Start
27
20
 
28
21
  ```typescript
29
- import BXO, { z } from './index';
30
-
31
- const app = new BXO()
32
- .get('/', async (ctx) => {
33
- return { message: 'Hello, BXO!' };
34
- })
35
- .start(3000);
36
- ```
22
+ import BXO from "./src/index";
23
+ import { cors } from "./plugins";
37
24
 
38
- ## ๐Ÿ“š Documentation
25
+ const app = new BXO();
39
26
 
40
- ### HTTP Handlers
27
+ // Use CORS plugin
28
+ app.use(cors());
41
29
 
42
- BXO supports all standard HTTP methods with fluent chaining:
30
+ // Define routes
31
+ app.get("/", (ctx) => ctx.json({ message: "Hello World!" }));
43
32
 
44
- ```typescript
45
- const app = new BXO()
46
- // Simple handler
47
- .get('/simple', async (ctx) => {
48
- return { message: 'Hello World' };
49
- })
50
-
51
- // With validation
52
- .post('/users', async (ctx) => {
53
- // ctx.body is fully typed
54
- return { created: ctx.body };
55
- }, {
56
- body: z.object({
57
- name: z.string(),
58
- email: z.string().email()
59
- })
60
- })
61
-
62
- // Path parameters
63
- .get('/users/:id', async (ctx) => {
64
- // ctx.params.id is typed as UUID string
65
- return { user: { id: ctx.params.id } };
66
- }, {
67
- params: z.object({
68
- id: z.string().uuid()
69
- }),
70
- query: z.object({
71
- include: z.string().optional()
72
- })
73
- })
74
-
75
- // All HTTP methods supported
76
- .put('/users/:id', handler)
77
- .delete('/users/:id', handler)
78
- .patch('/users/:id', handler);
33
+ app.start();
79
34
  ```
80
35
 
81
- ### Context Object
82
-
83
- The context object (`ctx`) provides access to request data and response configuration:
36
+ ## Lifecycle Hooks
84
37
 
85
- ```typescript
86
- interface Context<TConfig> {
87
- params: InferredParamsType; // Path parameters
88
- query: InferredQueryType; // Query string parameters
89
- body: InferredBodyType; // Request body
90
- headers: InferredHeadersType; // Request headers
91
- request: Request; // Original Request object
92
- set: { // Response configuration
93
- status?: number;
94
- headers?: Record<string, string>;
95
- };
96
- status: (code: number, data?: any) => any; // Type-safe status method
97
- user?: any; // Added by auth plugin
98
- [key: string]: any; // Extended by plugins
99
- }
100
- ```
38
+ BXO provides powerful lifecycle hooks that allow you to intercept and modify requests and responses at different stages:
101
39
 
102
- ### Type-Safe Status Method
103
-
104
- BXO provides a type-safe `ctx.status()` method similar to Elysia, which allows you to set HTTP status codes and return data in one call:
40
+ ### beforeRequest
41
+ Runs before any route processing. Can modify the request or return a response to short-circuit processing.
105
42
 
106
43
  ```typescript
107
- // Simple usage
108
- app.get('/hello', (ctx) => {
109
- return ctx.status(200, { message: 'Hello World' });
110
- });
111
-
112
- // With response validation
113
- app.get('/user/:id', (ctx) => {
114
- const userId = ctx.params.id;
115
-
116
- if (userId === 'not-found') {
117
- // TypeScript suggests 404 as valid status
118
- return ctx.status(404, { error: 'User not found' });
119
- }
120
-
121
- // TypeScript suggests 200 as valid status
122
- return ctx.status(200, { user: { id: userId, name: 'John Doe' } });
123
- }, {
124
- response: {
125
- 200: z.object({
126
- user: z.object({
127
- id: z.string(),
128
- name: z.string()
129
- })
130
- }),
131
- 404: z.object({
132
- error: z.string()
133
- })
134
- }
135
- });
136
-
137
- // POST with validation and status responses
138
- app.post('/users', (ctx) => {
139
- const { name, email } = ctx.body;
140
-
141
- if (!name || !email) {
142
- return ctx.status(400, { error: 'Missing required fields' });
143
- }
144
-
145
- return ctx.status(201, {
146
- success: true,
147
- user: { id: 1, name, email }
148
- });
149
- }, {
150
- body: z.object({
151
- name: z.string(),
152
- email: z.string().email()
153
- }),
154
- response: {
155
- 201: z.object({
156
- success: z.boolean(),
157
- user: z.object({
158
- id: z.number(),
159
- name: z.string(),
160
- email: z.string()
161
- })
162
- }),
163
- 400: z.object({
164
- error: z.string()
165
- })
166
- }
44
+ app.beforeRequest(async (req) => {
45
+ console.log(`${req.method} ${req.url}`);
46
+ return req; // Continue with request
167
47
  });
168
48
  ```
169
49
 
170
- **Key Features:**
171
- - **Type Safety**: Status codes are suggested based on your response configuration
172
- - **Data Validation**: Return data is validated against the corresponding schema
173
- - **Autocomplete**: TypeScript provides autocomplete for valid status codes
174
- - **Return Type Inference**: Return types are properly inferred from schemas
175
-
176
- ### Validation Configuration
177
-
178
- Each route can specify validation schemas for different parts of the request:
50
+ ### afterRequest
51
+ Runs after route processing but before the response is sent. Can modify the final response.
179
52
 
180
53
  ```typescript
181
- const config = {
182
- params: z.object({ id: z.string().uuid() }),
183
- query: z.object({
184
- page: z.coerce.number().default(1),
185
- limit: z.coerce.number().max(100).default(10)
186
- }),
187
- body: z.object({
188
- name: z.string().min(1),
189
- email: z.string().email()
190
- }),
191
- headers: z.object({
192
- 'content-type': z.literal('application/json')
193
- })
194
- };
195
-
196
- app.post('/api/users/:id', async (ctx) => {
197
- // All properties are fully typed based on schemas
198
- const { id } = ctx.params; // string (UUID)
199
- const { page, limit } = ctx.query; // number, number
200
- const { name, email } = ctx.body; // string, string
201
- }, config);
54
+ app.afterRequest(async (req, res) => {
55
+ res.headers.set("X-Response-Time", Date.now().toString());
56
+ return res;
57
+ });
202
58
  ```
203
59
 
204
- ## ๐Ÿ”Œ Plugin System
205
-
206
- BXO has a powerful plugin system with lifecycle hooks. Plugins can be either middleware-style plugins or full BXO instances. Middleware plugins are separate modules imported from `./plugins` and are executed in the order they are added.
207
-
208
- ### Available Plugins
209
-
210
- #### CORS Plugin
60
+ ### beforeResponse
61
+ Runs after the route handler but before response headers are merged. Useful for modifying response metadata.
211
62
 
212
63
  ```typescript
213
- import { cors } from './plugins';
214
-
215
- app.use(cors({
216
- origin: ['http://localhost:3000', 'https://example.com'],
217
- methods: ['GET', 'POST', 'PUT', 'DELETE'],
218
- allowedHeaders: ['Content-Type', 'Authorization'],
219
- credentials: true,
220
- maxAge: 86400
221
- }));
64
+ app.beforeResponse(async (res) => {
65
+ res.headers.set("X-Custom-Header", "value");
66
+ return res;
67
+ });
222
68
  ```
223
69
 
224
- **Features:**
225
- - **Origin Header Support**: Standard CORS origin header handling
226
- - **Referer Header Fallback**: Automatically falls back to Referer header when Origin is not present
227
- - **Origin Precedence**: When both Origin and Referer are present, Origin takes precedence
228
- - **Invalid URL Handling**: Gracefully handles invalid Referer URLs
229
- - **Flexible Origin Configuration**: Supports string, array, boolean, or wildcard (`*`) origins
230
-
231
- #### Logger Plugin
70
+ ### onError
71
+ Runs when an error occurs during request processing. Can return a custom error response.
232
72
 
233
73
  ```typescript
234
- import { logger } from './plugins';
235
-
236
- app.use(logger({
237
- format: 'simple', // 'simple' | 'detailed' | 'json'
238
- includeBody: false, // Log request/response bodies
239
- includeHeaders: false // Log headers
240
- }));
74
+ app.onError(async (error, req) => {
75
+ console.error(`Error: ${error.message}`);
76
+ return new Response("Internal Server Error", { status: 500 });
77
+ });
241
78
  ```
242
79
 
243
- #### Authentication Plugin
80
+ ## Plugins
244
81
 
245
- ```typescript
246
- import { auth, createJWT } from './plugins';
247
-
248
- app.use(auth({
249
- type: 'jwt', // 'jwt' | 'bearer' | 'apikey'
250
- secret: 'your-secret-key',
251
- exclude: ['/login', '/health'], // Skip auth for these paths
252
- verify: async (token, ctx) => {
253
- // Custom token verification
254
- return { user: 'data' };
255
- }
256
- }));
82
+ ### CORS Plugin
257
83
 
258
- // Create JWT tokens
259
- const token = createJWT(
260
- { userId: 123, role: 'admin' },
261
- 'secret',
262
- 3600 // expires in 1 hour
263
- );
264
- ```
265
-
266
- #### Rate Limiting Plugin
84
+ The CORS plugin provides comprehensive Cross-Origin Resource Sharing support:
267
85
 
268
86
  ```typescript
269
- import { rateLimit } from './plugins';
270
-
271
- app.use(rateLimit({
272
- max: 100, // Max requests
273
- window: 60, // Time window in seconds
274
- exclude: ['/health'], // Skip rate limiting for these paths
275
- keyGenerator: (ctx) => { // Custom key generation
276
- return ctx.request.headers.get('x-api-key') || 'default';
277
- },
278
- message: 'Too many requests',
279
- statusCode: 429
87
+ import { cors } from "./plugins";
88
+
89
+ app.use(cors({
90
+ origin: ["http://localhost:3000", "https://myapp.com"],
91
+ methods: ["GET", "POST", "PUT", "DELETE"],
92
+ credentials: true
280
93
  }));
281
94
  ```
282
95
 
283
96
  ### Creating Custom Plugins
284
97
 
285
- #### Middleware-Style Plugins (Recommended)
286
-
287
- ```typescript
288
- const customPlugin = {
289
- name: 'custom',
290
- onRequest: async (ctx) => {
291
- console.log('Before request processing');
292
- ctx.startTime = Date.now();
293
- },
294
- onResponse: async (ctx, response) => {
295
- console.log(`Request took ${Date.now() - ctx.startTime}ms`);
296
- return response;
297
- },
298
- onError: async (ctx, error) => {
299
- console.error('Request failed:', error.message);
300
- return { error: 'Custom error response' };
301
- }
302
- };
303
-
304
- app.use(customPlugin);
305
- ```
306
-
307
- #### Full BXO Instance Plugins
308
-
309
- You can also use full BXO instances as plugins, which will merge their routes and hooks:
310
-
311
- ```typescript
312
- const pluginApp = new BXO();
313
- pluginApp.get('/plugin-route', async (ctx) => {
314
- return { message: 'From plugin' };
315
- });
316
-
317
- app.use(pluginApp);
318
- ```
319
-
320
- ## ๐ŸŽฃ Lifecycle Hooks
321
-
322
- BXO provides comprehensive lifecycle hooks with a consistent before/after pattern for both server and request lifecycle:
323
-
324
- ### Server Lifecycle Hooks
98
+ Plugins are just BXO instances with lifecycle hooks:
325
99
 
326
100
  ```typescript
327
- app
328
- .onBeforeStart(() => {
329
- console.log('๐Ÿ”ง Preparing to start server...');
330
- })
331
- .onAfterStart(() => {
332
- console.log('โœ… Server fully started and ready!');
333
- })
334
- .onBeforeStop(() => {
335
- console.log('๐Ÿ”ง Preparing to stop server...');
336
- })
337
- .onAfterStop(() => {
338
- console.log('โœ… Server fully stopped!');
339
- })
340
- .onBeforeRestart(() => {
341
- console.log('๐Ÿ”ง Preparing to restart server...');
342
- })
343
- .onAfterRestart(() => {
344
- console.log('โœ… Server restart completed!');
345
- });
346
- ```
347
-
348
- ### Request Lifecycle Hooks
349
-
350
- ```typescript
351
- app
352
- .onRequest((ctx) => {
353
- console.log(`๐Ÿ“จ ${ctx.request.method} ${ctx.request.url}`);
354
- })
355
- .onResponse((ctx, response) => {
356
- console.log(`๐Ÿ“ค Response sent`);
357
- return response; // Can modify response
358
- })
359
- .onError((ctx, error) => {
360
- console.error(`๐Ÿ’ฅ Error:`, error.message);
361
- return { error: 'Something went wrong' }; // Can provide custom error response
101
+ function loggingPlugin() {
102
+ const plugin = new BXO();
103
+
104
+ plugin.beforeRequest(async (req) => {
105
+ console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
106
+ return req;
362
107
  });
363
- ```
364
-
365
- ## ๐Ÿ”„ Hot Reload & Server Management
366
-
367
- BXO includes built-in hot reload and comprehensive server management capabilities:
368
-
369
- ### Hot Reload
370
-
371
- ```typescript
372
- const app = new BXO();
373
-
374
- // Enable hot reload - server will restart when files change
375
- app.enableHotReload(['./']); // Watch current directory
376
-
377
- // Hot reload will automatically restart the server when:
378
- // - Any .ts or .js file changes in watched directories
379
- // - Server lifecycle hooks are properly executed during restart
380
- ```
381
-
382
- ### Server Management
383
-
384
- ```typescript
385
- const app = new BXO();
386
-
387
- // Start server
388
- await app.start(3000, 'localhost');
389
-
390
- // Check if server is running
391
- if (app.isServerRunning()) {
392
- console.log('Server is running!');
108
+
109
+ return plugin;
393
110
  }
394
111
 
395
- // Get server information
396
- const info = app.getServerInfo();
397
- console.log(info); // { running: true, hotReload: true, watchedFiles: ['./'] }
398
-
399
- // Restart server programmatically
400
- await app.restart(3000, 'localhost');
401
-
402
- // Stop server gracefully
403
- await app.stop();
404
-
405
- // Backward compatibility - listen() still works
406
- await app.listen(3000); // Same as app.start(3000)
112
+ app.use(loggingPlugin());
407
113
  ```
408
114
 
409
- ### Custom Serve Options
115
+ ## Route Validation
410
116
 
411
- BXO allows you to extend the native Bun serve options, giving you full control over the server configuration while maintaining the framework's functionality:
117
+ Define Zod schemas for request validation:
412
118
 
413
119
  ```typescript
414
- // Basic serve options
415
- const app = new BXO({
416
- serve: {
417
- port: 3000,
418
- hostname: "0.0.0.0", // Listen on all interfaces
419
- }
420
- });
421
-
422
- // With TLS/HTTPS options
423
- const app = new BXO({
424
- serve: {
425
- port: 443,
426
- hostname: "localhost",
427
- // tls: {
428
- // cert: Bun.file("cert.pem"),
429
- // key: Bun.file("key.pem"),
430
- // }
431
- }
432
- });
120
+ import { z } from "bxo";
433
121
 
434
- // With development options
435
- const app = new BXO({
436
- serve: {
437
- port: 5000,
438
- development: true, // Enable development mode
439
- }
122
+ const UserSchema = z.object({
123
+ name: z.string().min(1),
124
+ email: z.string().email()
440
125
  });
441
126
 
442
- // With custom error handling
443
- const app = new BXO({
444
- serve: {
445
- port: 6000,
446
- error: (error) => {
447
- console.error("Custom error handler:", error);
448
- return new Response("Something went wrong", { status: 500 });
449
- }
450
- }
451
- });
452
-
453
- // With custom fetch handler (extends framework functionality)
454
- const app = new BXO({
455
- serve: {
456
- port: 4000,
457
- // You can override the fetch handler if needed
458
- // fetch: (request, server) => {
459
- // // Your custom logic here
460
- // // You can still call the framework's handler
461
- // return app.requestHandler.handleRequest(request, server);
462
- // }
463
- }
127
+ app.post("/users", async (ctx) => {
128
+ const user = ctx.body; // Already validated by UserSchema
129
+ return ctx.json({ id: 1, ...user });
130
+ }, {
131
+ body: UserSchema
464
132
  });
465
133
  ```
466
134
 
467
- **Available Serve Options:**
468
- - `port` - Server port (default: 3000)
469
- - `hostname` - Server hostname (default: 'localhost')
470
- - `development` - Enable development mode
471
- - `tls` - TLS/HTTPS configuration
472
- - `error` - Custom error handler
473
- - `fetch` - Custom fetch handler (overrides framework's handler)
474
- - `websocket` - WebSocket configuration
475
- - And all other [Bun.serve options](https://bun.sh/docs/api/http#bun-serve)
476
-
477
- The framework will merge your serve options with its own defaults, ensuring that BXO's routing, middleware, and WebSocket functionality continue to work while allowing you to customize the server behavior.
478
-
479
- ### Development vs Production
480
-
481
- ```typescript
482
- const app = new BXO();
483
-
484
- if (process.env.NODE_ENV === 'development') {
485
- // Enable hot reload in development
486
- app.enableHotReload(['./src', './routes']);
487
- }
488
-
489
- // Add server management endpoints for development
490
- if (process.env.NODE_ENV === 'development') {
491
- app.post('/dev/restart', async (ctx) => {
492
- setTimeout(() => app.restart(3000), 100);
493
- return { message: 'Server restart initiated' };
494
- });
495
-
496
- app.get('/dev/status', async (ctx) => {
497
- return {
498
- ...app.getServerInfo(),
499
- uptime: process.uptime(),
500
- memory: process.memoryUsage()
501
- };
502
- });
503
- }
504
- ```
505
-
506
- ## ๐ŸŒŸ Complete Example
507
-
508
- ```typescript
509
- import BXO, { z } from './index';
510
- import { cors, logger, auth, rateLimit, createJWT } from './plugins';
511
-
512
- const app = new BXO();
513
-
514
- // Enable hot reload for development
515
- app.enableHotReload(['./']);
516
-
517
- // Add plugins
518
- app
519
- .use(logger({ format: 'simple' }))
520
- .use(cors({
521
- origin: ['http://localhost:3000'],
522
- credentials: true
523
- }))
524
- .use(rateLimit({
525
- max: 100,
526
- window: 60,
527
- exclude: ['/health']
528
- }))
529
- .use(auth({
530
- type: 'jwt',
531
- secret: 'your-secret-key',
532
- exclude: ['/', '/login', '/health']
533
- }));
534
-
535
- // Comprehensive lifecycle hooks
536
- app
537
- .onBeforeStart(() => console.log('๐Ÿ”ง Preparing server startup...'))
538
- .onAfterStart(() => console.log('โœ… Server ready!'))
539
- .onBeforeRestart(() => console.log('๐Ÿ”„ Restarting server...'))
540
- .onAfterRestart(() => console.log('โœ… Server restarted!'))
541
- .onError((ctx, error) => ({
542
- error: 'Internal server error',
543
- timestamp: new Date().toISOString()
544
- }));
545
-
546
- // Routes
547
- app
548
- .get('/health', async () => ({
549
- status: 'ok',
550
- timestamp: new Date().toISOString(),
551
- server: app.getServerInfo()
552
- }))
553
-
554
- .post('/login', async (ctx) => {
555
- const { username, password } = ctx.body;
556
-
557
- if (username === 'admin' && password === 'password') {
558
- const token = createJWT(
559
- { username, role: 'admin' },
560
- 'your-secret-key'
561
- );
562
- return { token, user: { username, role: 'admin' } };
563
- }
564
-
565
- ctx.set.status = 401;
566
- return { error: 'Invalid credentials' };
567
- }, {
568
- body: z.object({
569
- username: z.string(),
570
- password: z.string()
571
- })
572
- })
573
-
574
- .get('/users/:id', async (ctx) => {
575
- return {
576
- user: {
577
- id: ctx.params.id,
578
- include: ctx.query.include
579
- }
580
- };
581
- }, {
582
- params: z.object({ id: z.string().uuid() }),
583
- query: z.object({ include: z.string().optional() })
584
- })
585
-
586
- .post('/users', async (ctx) => {
587
- return { created: ctx.body };
588
- }, {
589
- body: z.object({
590
- name: z.string(),
591
- email: z.string().email()
592
- })
593
- })
594
-
595
- .get('/protected', async (ctx) => {
596
- // ctx.user available from auth plugin
597
- return {
598
- message: 'Protected resource',
599
- user: ctx.user
600
- };
601
- })
602
-
603
- // Server management endpoints
604
- .post('/restart', async (ctx) => {
605
- setTimeout(() => app.restart(3000), 100);
606
- return { message: 'Server restart initiated' };
607
- })
608
-
609
- .get('/status', async (ctx) => {
610
- return {
611
- ...app.getServerInfo(),
612
- uptime: process.uptime(),
613
- memory: process.memoryUsage()
614
- };
615
- });
616
-
617
- // Start server with hot reload
618
- app.start(3000);
619
- ```
620
-
621
- ## ๐Ÿงช Testing Endpoints
622
-
623
- With the example server running, test these endpoints:
135
+ ## Running
624
136
 
625
137
  ```bash
626
- # Health check
627
- curl http://localhost:3000/health
628
-
629
- # Login to get token
630
- curl -X POST http://localhost:3000/login \
631
- -H "Content-Type: application/json" \
632
- -d '{"username": "admin", "password": "password"}'
633
-
634
- # Create user
635
- curl -X POST http://localhost:3000/users \
636
- -H "Content-Type: application/json" \
637
- -d '{"name": "John Doe", "email": "john@example.com"}'
638
-
639
- # Get user with validation
640
- curl "http://localhost:3000/users/123e4567-e89b-12d3-a456-426614174000?include=profile"
641
-
642
- # Access protected route (use token from login)
643
- curl http://localhost:3000/protected \
644
- -H "Authorization: Bearer YOUR_JWT_TOKEN"
645
-
646
- # Check server status
647
- curl http://localhost:3000/status
648
-
649
- # Restart server programmatically
650
- curl -X POST http://localhost:3000/restart
138
+ bun run ./src/index.ts
651
139
  ```
652
140
 
653
- ## ๐Ÿ“– API Reference
654
-
655
- ### BXO Class Methods
656
-
657
- #### HTTP Methods
658
- - `get(path, handler, config?)` - Handle GET requests
659
- - `post(path, handler, config?)` - Handle POST requests
660
- - `put(path, handler, config?)` - Handle PUT requests
661
- - `delete(path, handler, config?)` - Handle DELETE requests
662
- - `patch(path, handler, config?)` - Handle PATCH requests
663
-
664
- #### Plugins & Hooks
665
- - `use(plugin)` - Add a plugin
666
- - `onBeforeStart(handler)` - Before server start hook
667
- - `onAfterStart(handler)` - After server start hook
668
- - `onBeforeStop(handler)` - Before server stop hook
669
- - `onAfterStop(handler)` - After server stop hook
670
- - `onBeforeRestart(handler)` - Before server restart hook
671
- - `onAfterRestart(handler)` - After server restart hook
672
- - `onRequest(handler)` - Global request hook
673
- - `onResponse(handler)` - Global response hook
674
- - `onError(handler)` - Global error hook
675
-
676
- #### Server Management
677
- - `start(port?, hostname?)` - Start the server
678
- - `stop()` - Stop the server gracefully
679
- - `restart(port?, hostname?)` - Restart the server
680
- - `listen(port?, hostname?)` - Start the server (backward compatibility)
681
- - `isServerRunning()` - Check if server is running
682
- - `getServerInfo()` - Get server status information
683
-
684
- #### Hot Reload
685
- - `enableHotReload(watchPaths?)` - Enable hot reload with file watching
686
-
687
- ### Route Configuration
688
-
689
- ```typescript
690
- interface RouteConfig {
691
- params?: z.ZodSchema<any>; // Path parameter validation
692
- query?: z.ZodSchema<any>; // Query string validation
693
- body?: z.ZodSchema<any>; // Request body validation
694
- headers?: z.ZodSchema<any>; // Header validation
695
- }
696
- ```
697
-
698
- ### Plugin Interface
699
-
700
- ```typescript
701
- interface Plugin {
702
- name?: string;
703
- onRequest?: (ctx: Context) => Promise<void> | void;
704
- onResponse?: (ctx: Context, response: any) => Promise<any> | any;
705
- onError?: (ctx: Context, error: Error) => Promise<any> | any;
706
- }
707
- ```
708
-
709
- ## ๐Ÿ› ๏ธ Development
710
-
711
- ### Running the Example
141
+ Or run the CORS example:
712
142
 
713
143
  ```bash
714
- # Run with hot reload enabled
715
- bun run example.ts
716
-
717
- # The server will automatically restart when you edit any .ts/.js files!
718
- ```
719
-
720
- ### Project Structure
721
-
722
- ```
723
- bxo/
724
- โ”œโ”€โ”€ index.ts # Main BXO framework
725
- โ”œโ”€โ”€ plugins/
726
- โ”‚ โ”œโ”€โ”€ index.ts # Plugin exports
727
- โ”‚ โ”œโ”€โ”€ cors.ts # CORS plugin
728
- โ”‚ โ”œโ”€โ”€ logger.ts # Logger plugin
729
- โ”‚ โ”œโ”€โ”€ auth.ts # Authentication plugin
730
- โ”‚ โ””โ”€โ”€ ratelimit.ts # Rate limiting plugin
731
- โ”œโ”€โ”€ example.ts # Usage example
732
- โ”œโ”€โ”€ package.json
733
- โ””โ”€โ”€ README.md
144
+ bun run ./example/cors-example.ts
734
145
  ```
735
146
 
736
- ## ๐Ÿค Contributing
737
-
738
- BXO is designed to be simple and extensible. Contributions are welcome!
739
-
740
- ## ๐Ÿ“„ License
147
+ ## Examples
741
148
 
742
- MIT License - feel free to use BXO in your projects!
149
+ Check out the `example/` directory for more usage examples:
743
150
 
744
- ---
151
+ - `cors-example.ts` - Demonstrates CORS plugin and lifecycle hooks
152
+ - `index.ts` - Basic routing example
745
153
 
746
- Built with โค๏ธ for the Bun ecosystem
154
+ This project was created using `bun init` in bun v1.2.3. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.