bxo 0.0.5-dev.43 → 0.0.5-dev.44

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/package.json +1 -1
  2. package/plugins/example.ts +173 -0
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.44",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "exports": {
@@ -0,0 +1,173 @@
1
+ import type { Plugin } from '../index';
2
+
3
+ // Example 1: Simple logging plugin
4
+ export function logger(): Plugin {
5
+ return {
6
+ name: 'logger',
7
+ onRequest: async (ctx) => {
8
+ console.log(`[${new Date().toISOString()}] ${ctx.request.method} ${ctx.path}`);
9
+ },
10
+ onResponse: async (ctx, response) => {
11
+ if (response instanceof Response) {
12
+ console.log(`[${new Date().toISOString()}] ${ctx.request.method} ${ctx.path} - ${response.status}`);
13
+ }
14
+ return response;
15
+ },
16
+ onError: async (ctx, error) => {
17
+ console.error(`[${new Date().toISOString()}] Error in ${ctx.request.method} ${ctx.path}:`, error);
18
+ }
19
+ };
20
+ }
21
+
22
+ // Example 2: Authentication plugin
23
+ export function auth(secret: string): Plugin {
24
+ return {
25
+ name: 'auth',
26
+ onRequest: async (ctx) => {
27
+ const token = ctx.headers.authorization?.replace('Bearer ', '');
28
+
29
+ if (!token) {
30
+ throw new Response(JSON.stringify({ error: 'No token provided' }), {
31
+ status: 401,
32
+ headers: { 'Content-Type': 'application/json' }
33
+ });
34
+ }
35
+
36
+ // Simple token validation (replace with your actual logic)
37
+ if (token !== secret) {
38
+ throw new Response(JSON.stringify({ error: 'Invalid token' }), {
39
+ status: 401,
40
+ headers: { 'Content-Type': 'application/json' }
41
+ });
42
+ }
43
+
44
+ // Add user info to context
45
+ (ctx as any).user = { id: 'user-123', token };
46
+ }
47
+ };
48
+ }
49
+
50
+ // Example 3: Request timing plugin
51
+ export function timing(): Plugin {
52
+ return {
53
+ name: 'timing',
54
+ onRequest: async (ctx) => {
55
+ (ctx as any).startTime = Date.now();
56
+ },
57
+ onResponse: async (ctx, response) => {
58
+ const startTime = (ctx as any).startTime;
59
+ if (startTime) {
60
+ const duration = Date.now() - startTime;
61
+ console.log(`Request to ${ctx.path} took ${duration}ms`);
62
+
63
+ // Add timing header to response
64
+ if (response instanceof Response) {
65
+ const newResponse = new Response(response.body, {
66
+ status: response.status,
67
+ statusText: response.statusText,
68
+ headers: new Headers(response.headers)
69
+ });
70
+ newResponse.headers.set('X-Response-Time', `${duration}ms`);
71
+ return newResponse;
72
+ }
73
+ }
74
+ return response;
75
+ }
76
+ };
77
+ }
78
+
79
+ // Example 4: Request ID plugin
80
+ export function requestId(): Plugin {
81
+ return {
82
+ name: 'requestId',
83
+ onRequest: async (ctx) => {
84
+ const requestId = crypto.randomUUID();
85
+ (ctx as any).requestId = requestId;
86
+
87
+ // Add request ID to response headers
88
+ ctx.set.headers = {
89
+ ...ctx.set.headers,
90
+ 'X-Request-ID': requestId
91
+ };
92
+ }
93
+ };
94
+ }
95
+
96
+ // Example 5: Conditional plugin (only applies to certain paths)
97
+ export function conditionalAuth(secret: string, paths: string[]): Plugin {
98
+ return {
99
+ name: 'conditionalAuth',
100
+ onRequest: async (ctx) => {
101
+ // Only apply auth to specified paths
102
+ if (!paths.some(path => ctx.path.startsWith(path))) {
103
+ return; // Skip authentication for this path
104
+ }
105
+
106
+ const token = ctx.headers.authorization?.replace('Bearer ', '');
107
+
108
+ if (!token || token !== secret) {
109
+ throw new Response(JSON.stringify({ error: 'Authentication required' }), {
110
+ status: 401,
111
+ headers: { 'Content-Type': 'application/json' }
112
+ });
113
+ }
114
+ }
115
+ };
116
+ }
117
+
118
+ // Example 6: Response transformation plugin
119
+ export function responseTransformer(): Plugin {
120
+ return {
121
+ name: 'responseTransformer',
122
+ onResponse: async (ctx, response) => {
123
+ // Only transform JSON responses
124
+ if (response instanceof Response) {
125
+ const contentType = response.headers.get('content-type');
126
+ if (contentType?.includes('application/json')) {
127
+ try {
128
+ const data = await response.json();
129
+
130
+ // Transform the response data
131
+ const transformed = {
132
+ success: true,
133
+ data,
134
+ timestamp: new Date().toISOString(),
135
+ path: ctx.path
136
+ };
137
+
138
+ return new Response(JSON.stringify(transformed), {
139
+ status: response.status,
140
+ headers: response.headers
141
+ });
142
+ } catch (error) {
143
+ // If response is not JSON, return as-is
144
+ return response;
145
+ }
146
+ }
147
+ }
148
+
149
+ return response;
150
+ }
151
+ };
152
+ }
153
+
154
+ // Example 7: Error handling plugin
155
+ export function errorHandler(): Plugin {
156
+ return {
157
+ name: 'errorHandler',
158
+ onError: async (ctx, error) => {
159
+ console.error(`Error in ${ctx.request.method} ${ctx.path}:`, error);
160
+
161
+ // Return a standardized error response
162
+ return new Response(JSON.stringify({
163
+ error: 'Internal Server Error',
164
+ message: error.message,
165
+ timestamp: new Date().toISOString(),
166
+ path: ctx.path
167
+ }), {
168
+ status: 500,
169
+ headers: { 'Content-Type': 'application/json' }
170
+ });
171
+ }
172
+ };
173
+ }