bxo 0.0.5-dev.43 → 0.0.5-dev.45

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/index.ts CHANGED
@@ -136,7 +136,7 @@ interface BXOOptions {
136
136
  // Plugin interface for middleware-style plugins
137
137
  interface Plugin {
138
138
  name?: string;
139
- onRequest?: (ctx: Context) => Promise<void> | void;
139
+ onRequest?: (ctx: Context) => Promise<Response | void> | Response | void;
140
140
  onResponse?: (ctx: Context, response: any) => Promise<any> | any;
141
141
  onError?: (ctx: Context, error: Error) => Promise<any> | any;
142
142
  }
@@ -153,7 +153,7 @@ export default class BXO {
153
153
  onAfterRestart?: (instance: BXO) => Promise<void> | void;
154
154
  onBeforeStop?: (instance: BXO) => Promise<void> | void;
155
155
  onAfterStop?: (instance: BXO) => Promise<void> | void;
156
- onRequest?: (ctx: Context, instance: BXO) => Promise<void> | void;
156
+ onRequest?: (ctx: Context, instance: BXO) => Promise<Response | void> | Response | void;
157
157
  onResponse?: (ctx: Context, response: any, instance: BXO) => Promise<any> | any;
158
158
  onError?: (ctx: Context, error: Error, instance: BXO) => Promise<any> | any;
159
159
  } = {};
@@ -721,6 +721,84 @@ export default class BXO {
721
721
  return new Response('WebSocket upgrade failed', { status: 400 });
722
722
  }
723
723
 
724
+ // Handle OPTIONS requests for CORS preflight before route matching
725
+ if (method === 'OPTIONS') {
726
+ // Create a minimal context for OPTIONS requests
727
+ const ctx: Context = {
728
+ params: {},
729
+ query: {},
730
+ body: {},
731
+ headers: this.parseHeaders(request.headers),
732
+ cookies: {},
733
+ path: pathname,
734
+ request,
735
+ set: {},
736
+ status: ((code: number, data?: any) => {
737
+ ctx.set.status = code;
738
+ return data;
739
+ }) as any,
740
+ redirect: ((location: string, status: number = 302) => {
741
+ ctx.set.redirect = { location, status };
742
+ const responseHeaders: Record<string, string> = {
743
+ Location: location,
744
+ ...(ctx.set.headers || {})
745
+ };
746
+ return new Response(null, {
747
+ status,
748
+ headers: responseHeaders
749
+ });
750
+ }) as any,
751
+ clearRedirect: (() => {
752
+ delete ctx.set.redirect;
753
+ if (ctx.set.headers) {
754
+ for (const key of Object.keys(ctx.set.headers)) {
755
+ if (key.toLowerCase() === 'location') {
756
+ delete ctx.set.headers[key];
757
+ }
758
+ }
759
+ }
760
+ if (typeof ctx.set.status === 'number' && ctx.set.status >= 300 && ctx.set.status < 400) {
761
+ delete ctx.set.status;
762
+ }
763
+ }) as any
764
+ };
765
+
766
+ // Run middleware onRequest hooks for OPTIONS requests
767
+ for (const plugin of this.middleware) {
768
+ if (plugin.onRequest) {
769
+ const result = await plugin.onRequest(ctx);
770
+ // If middleware returns a response, return it immediately
771
+ if (result instanceof Response) {
772
+ return result;
773
+ }
774
+ }
775
+ }
776
+
777
+ // Run global onRequest hook
778
+ if (this.hooks.onRequest) {
779
+ const result = await this.hooks.onRequest(ctx, this);
780
+ if (result instanceof Response) {
781
+ return result;
782
+ }
783
+ }
784
+
785
+ // Run BXO instance onRequest hooks
786
+ for (const bxoInstance of this.plugins) {
787
+ if (bxoInstance.hooks.onRequest) {
788
+ const result = await bxoInstance.hooks.onRequest(ctx, this);
789
+ if (result instanceof Response) {
790
+ return result;
791
+ }
792
+ }
793
+ }
794
+
795
+ // If no middleware handled the OPTIONS request, return a default response
796
+ return new Response(null, {
797
+ status: 204,
798
+ headers: ctx.set.headers || {}
799
+ });
800
+ }
801
+
724
802
  const matchResult = this.matchRoute(method, pathname);
725
803
  if (!matchResult) {
726
804
  return new Response('Not Found', { status: 404 });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bxo",
3
3
  "module": "index.ts",
4
- "version": "0.0.5-dev.43",
4
+ "version": "0.0.5-dev.45",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "exports": {
package/plugins/cors.ts CHANGED
@@ -60,6 +60,7 @@ export function cors(options: CORSOptions = {}): Plugin {
60
60
  return {
61
61
  name: 'cors',
62
62
  onRequest: async (ctx) => {
63
+ console.log('onRequest', ctx.request.method);
63
64
  // Handle preflight OPTIONS requests
64
65
  if (ctx.request.method === 'OPTIONS') {
65
66
  const requestOrigin = getRequestOrigin(ctx.request);
@@ -77,6 +78,12 @@ export function cors(options: CORSOptions = {}): Plugin {
77
78
  if (credentials) {
78
79
  ctx.set.headers['Access-Control-Allow-Credentials'] = 'true';
79
80
  }
81
+
82
+ // Return a proper Response for OPTIONS requests
83
+ return new Response(null, {
84
+ status: 204,
85
+ headers: ctx.set.headers
86
+ });
80
87
  }
81
88
  },
82
89
  onResponse: async (ctx, response) => {