bxo 0.0.4 → 0.0.5-dev.1

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 (2) hide show
  1. package/index.ts +66 -4
  2. package/package.json +1 -1
package/index.ts CHANGED
@@ -9,6 +9,7 @@ interface RouteConfig {
9
9
  query?: z.ZodSchema<any>;
10
10
  body?: z.ZodSchema<any>;
11
11
  headers?: z.ZodSchema<any>;
12
+ response?: z.ZodSchema<any>;
12
13
  }
13
14
 
14
15
  // Context type that's fully typed based on the route configuration
@@ -59,6 +60,7 @@ export default class BXO {
59
60
  private isRunning: boolean = false;
60
61
  private hotReloadEnabled: boolean = false;
61
62
  private watchedFiles: Set<string> = new Set();
63
+ private watchedExclude: Set<string> = new Set();
62
64
 
63
65
  constructor() { }
64
66
 
@@ -338,6 +340,20 @@ export default class BXO {
338
340
  }
339
341
  }
340
342
 
343
+ // Validate response against schema if provided
344
+ if (route.config?.response && !(response instanceof Response)) {
345
+ try {
346
+ response = this.validateData(route.config.response, response);
347
+ } catch (validationError) {
348
+ // Response validation failed
349
+ const errorMessage = validationError instanceof Error ? validationError.message : 'Response validation failed';
350
+ return new Response(JSON.stringify({ error: `Response validation error: ${errorMessage}` }), {
351
+ status: 500,
352
+ headers: { 'Content-Type': 'application/json' }
353
+ });
354
+ }
355
+ }
356
+
341
357
  // Convert response to Response object
342
358
  if (response instanceof Response) {
343
359
  return response;
@@ -394,12 +410,49 @@ export default class BXO {
394
410
  }
395
411
 
396
412
  // Hot reload functionality
397
- enableHotReload(watchPaths: string[] = ['./']): this {
413
+ enableHotReload(watchPaths: string[] = ['./'], excludePatterns: string[] = []): this {
398
414
  this.hotReloadEnabled = true;
399
415
  watchPaths.forEach(path => this.watchedFiles.add(path));
416
+ excludePatterns.forEach(pattern => this.watchedExclude.add(pattern));
400
417
  return this;
401
418
  }
402
419
 
420
+ private shouldExcludeFile(filename: string): boolean {
421
+ for (const pattern of this.watchedExclude) {
422
+ // Handle exact match
423
+ if (pattern === filename) {
424
+ return true;
425
+ }
426
+
427
+ // Handle directory patterns (e.g., "node_modules/", "dist/")
428
+ if (pattern.endsWith('/')) {
429
+ if (filename.startsWith(pattern) || filename.includes(`/${pattern}`)) {
430
+ return true;
431
+ }
432
+ }
433
+
434
+ // Handle wildcard patterns (e.g., "*.log", "temp*")
435
+ if (pattern.includes('*')) {
436
+ const regex = new RegExp(pattern.replace(/\*/g, '.*'));
437
+ if (regex.test(filename)) {
438
+ return true;
439
+ }
440
+ }
441
+
442
+ // Handle file extension patterns (e.g., ".log", ".tmp")
443
+ if (pattern.startsWith('.') && filename.endsWith(pattern)) {
444
+ return true;
445
+ }
446
+
447
+ // Handle substring matches for directories
448
+ if (filename.includes(pattern)) {
449
+ return true;
450
+ }
451
+ }
452
+
453
+ return false;
454
+ }
455
+
403
456
  private async setupFileWatcher(port: number, hostname: string): Promise<void> {
404
457
  if (!this.hotReloadEnabled) return;
405
458
 
@@ -409,11 +462,19 @@ export default class BXO {
409
462
  try {
410
463
  fs.watch(watchPath, { recursive: true }, async (eventType: string, filename: string) => {
411
464
  if (filename && (filename.endsWith('.ts') || filename.endsWith('.js'))) {
465
+ // Check if file should be excluded
466
+ if (this.shouldExcludeFile(filename)) {
467
+ return;
468
+ }
469
+
412
470
  console.log(`🔄 File changed: ${filename}, restarting server...`);
413
471
  await this.restart(port, hostname);
414
472
  }
415
473
  });
416
474
  console.log(`👀 Watching ${watchPath} for changes...`);
475
+ if (this.watchedExclude.size > 0) {
476
+ console.log(`🚫 Excluding patterns: ${Array.from(this.watchedExclude).join(', ')}`);
477
+ }
417
478
  } catch (error) {
418
479
  console.warn(`⚠️ Could not watch ${watchPath}:`, error);
419
480
  }
@@ -535,11 +596,12 @@ export default class BXO {
535
596
  return this.isRunning;
536
597
  }
537
598
 
538
- getServerInfo(): { running: boolean; hotReload: boolean; watchedFiles: string[] } {
599
+ getServerInfo(): { running: boolean; hotReload: boolean; watchedFiles: string[]; excludePatterns: string[] } {
539
600
  return {
540
601
  running: this.isRunning,
541
602
  hotReload: this.hotReloadEnabled,
542
- watchedFiles: Array.from(this.watchedFiles)
603
+ watchedFiles: Array.from(this.watchedFiles),
604
+ excludePatterns: Array.from(this.watchedExclude)
543
605
  };
544
606
  }
545
607
  }
@@ -552,4 +614,4 @@ const error = (error: Error, status: number = 500) => {
552
614
  export { z, error };
553
615
 
554
616
  // Export types for external use
555
- export type { RouteConfig };
617
+ export type { RouteConfig, Handler };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bxo",
3
3
  "module": "index.ts",
4
- "version": "0.0.4",
4
+ "version": "0.0.5-dev.1",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "devDependencies": {