inviton-backduck 1.0.0
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/LICENSE +21 -0
- package/README.md +302 -0
- package/dist/apidoc/api-doc-generator.d.ts +58 -0
- package/dist/apidoc/api-doc-generator.d.ts.map +1 -0
- package/dist/apidoc/api-doc-generator.js +201 -0
- package/dist/apidoc/api-doc-generator.js.map +1 -0
- package/dist/apidoc/config.d.ts +153 -0
- package/dist/apidoc/config.d.ts.map +1 -0
- package/dist/apidoc/config.js +254 -0
- package/dist/apidoc/config.js.map +1 -0
- package/dist/apidoc/controller-parser.d.ts +208 -0
- package/dist/apidoc/controller-parser.d.ts.map +1 -0
- package/dist/apidoc/controller-parser.js +686 -0
- package/dist/apidoc/controller-parser.js.map +1 -0
- package/dist/apidoc/html-generator.d.ts +290 -0
- package/dist/apidoc/html-generator.d.ts.map +1 -0
- package/dist/apidoc/html-generator.js +2295 -0
- package/dist/apidoc/html-generator.js.map +1 -0
- package/dist/apidoc/index.d.ts +20 -0
- package/dist/apidoc/index.d.ts.map +1 -0
- package/dist/apidoc/index.js +16 -0
- package/dist/apidoc/index.js.map +1 -0
- package/dist/apidoc/openapi-builder.d.ts +169 -0
- package/dist/apidoc/openapi-builder.d.ts.map +1 -0
- package/dist/apidoc/openapi-builder.js +634 -0
- package/dist/apidoc/openapi-builder.js.map +1 -0
- package/dist/apidoc/parameterGeneratorRegistry.d.ts +20 -0
- package/dist/apidoc/parameterGeneratorRegistry.d.ts.map +1 -0
- package/dist/apidoc/parameterGeneratorRegistry.js +6 -0
- package/dist/apidoc/parameterGeneratorRegistry.js.map +1 -0
- package/dist/apidoc/test-type-resolver.d.ts +2 -0
- package/dist/apidoc/test-type-resolver.d.ts.map +1 -0
- package/dist/apidoc/test-type-resolver.js +6 -0
- package/dist/apidoc/test-type-resolver.js.map +1 -0
- package/dist/apidoc/type-resolver.d.ts +266 -0
- package/dist/apidoc/type-resolver.d.ts.map +1 -0
- package/dist/apidoc/type-resolver.js +1226 -0
- package/dist/apidoc/type-resolver.js.map +1 -0
- package/dist/apidoc/verify-type-resolution.d.ts +3 -0
- package/dist/apidoc/verify-type-resolution.d.ts.map +1 -0
- package/dist/apidoc/verify-type-resolution.js +29 -0
- package/dist/apidoc/verify-type-resolution.js.map +1 -0
- package/dist/bun/bunRouter.d.ts +70 -0
- package/dist/bun/bunRouter.d.ts.map +1 -0
- package/dist/bun/bunRouter.js +324 -0
- package/dist/bun/bunRouter.js.map +1 -0
- package/dist/bun/bunServer.d.ts +72 -0
- package/dist/bun/bunServer.d.ts.map +1 -0
- package/dist/bun/bunServer.js +218 -0
- package/dist/bun/bunServer.js.map +1 -0
- package/dist/bun/bunStaticFiles.d.ts +76 -0
- package/dist/bun/bunStaticFiles.d.ts.map +1 -0
- package/dist/bun/bunStaticFiles.js +251 -0
- package/dist/bun/bunStaticFiles.js.map +1 -0
- package/dist/bun/index.d.ts +7 -0
- package/dist/bun/index.d.ts.map +1 -0
- package/dist/bun/index.js +7 -0
- package/dist/bun/index.js.map +1 -0
- package/dist/data-contracts.d.ts +132 -0
- package/dist/data-contracts.d.ts.map +1 -0
- package/dist/data-contracts.js +2 -0
- package/dist/data-contracts.js.map +1 -0
- package/dist/decorators.d.ts +75 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +101 -0
- package/dist/decorators.js.map +1 -0
- package/dist/express/expressFrontendRouter.d.ts +17 -0
- package/dist/express/expressFrontendRouter.d.ts.map +1 -0
- package/dist/express/expressFrontendRouter.js +33 -0
- package/dist/express/expressFrontendRouter.js.map +1 -0
- package/dist/express/expressRouter.d.ts +25 -0
- package/dist/express/expressRouter.d.ts.map +1 -0
- package/dist/express/expressRouter.js +150 -0
- package/dist/express/expressRouter.js.map +1 -0
- package/dist/express/index.d.ts +6 -0
- package/dist/express/index.d.ts.map +1 -0
- package/dist/express/index.js +6 -0
- package/dist/express/index.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +52 -0
- package/dist/index.js.map +1 -0
- package/dist/router.d.ts +162 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +350 -0
- package/dist/router.js.map +1 -0
- package/dist/runtime-detect.d.ts +20 -0
- package/dist/runtime-detect.d.ts.map +1 -0
- package/dist/runtime-detect.js +20 -0
- package/dist/runtime-detect.js.map +1 -0
- package/dist/server.d.ts +126 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +181 -0
- package/dist/server.js.map +1 -0
- package/dist/utils.d.ts +83 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +157 -0
- package/dist/utils.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun.serve() wrapper for running the server under Bun runtime
|
|
3
|
+
*/
|
|
4
|
+
import BunStaticFiles from './bunStaticFiles';
|
|
5
|
+
/**
|
|
6
|
+
* Class for managing a Bun HTTP server with full functionality
|
|
7
|
+
*/
|
|
8
|
+
export default class BunServer {
|
|
9
|
+
server;
|
|
10
|
+
options;
|
|
11
|
+
nativeRoutes;
|
|
12
|
+
staticFiles;
|
|
13
|
+
/** Fallback routers for regex-based routes (SSR, frontend SPAs, etc.) */
|
|
14
|
+
fallbackRouters = [];
|
|
15
|
+
constructor(options) {
|
|
16
|
+
this.options = options;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create and start a new BunServer instance
|
|
20
|
+
*/
|
|
21
|
+
static async create(options) {
|
|
22
|
+
const instance = new BunServer(options);
|
|
23
|
+
await instance.initialize();
|
|
24
|
+
return instance;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Initialize the server (async setup)
|
|
28
|
+
*/
|
|
29
|
+
async initialize() {
|
|
30
|
+
const { BunRouter } = await import('./bunRouter');
|
|
31
|
+
// Merge all API routes into Bun-native routes object for O(1) lookup
|
|
32
|
+
const allRoutes = [];
|
|
33
|
+
for (const [basePath, universalRouter,] of Object.entries(this.options.apiRoutes)) {
|
|
34
|
+
try {
|
|
35
|
+
const bunRouter = await universalRouter.buildBun(basePath);
|
|
36
|
+
allRoutes.push(...bunRouter.routes);
|
|
37
|
+
console.log(`[Bun] Registered ${bunRouter.routes.length} routes for ${basePath}`);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
console.error(`[Bun] Failed to register routes for ${basePath}:`, error);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// Convert to Bun-native routes for optimized radix tree routing
|
|
44
|
+
// Pass CORS config so API routes handle CORS directly (native routes bypass fetch handler)
|
|
45
|
+
const corsConfig = this.options.corsOrigins && this.options.corsOrigins.length > 0
|
|
46
|
+
? {
|
|
47
|
+
origins: this.options.corsOrigins,
|
|
48
|
+
credentials: true,
|
|
49
|
+
methods: [
|
|
50
|
+
'GET',
|
|
51
|
+
'POST',
|
|
52
|
+
'PUT',
|
|
53
|
+
'DELETE',
|
|
54
|
+
'PATCH',
|
|
55
|
+
'OPTIONS',
|
|
56
|
+
],
|
|
57
|
+
allowedHeaders: [
|
|
58
|
+
'Content-Type',
|
|
59
|
+
'Authorization',
|
|
60
|
+
'X-Requested-With',
|
|
61
|
+
'Accept',
|
|
62
|
+
'Cache-Control',
|
|
63
|
+
],
|
|
64
|
+
}
|
|
65
|
+
: undefined;
|
|
66
|
+
this.nativeRoutes = new BunRouter(allRoutes).toBunNativeRoutes(corsConfig);
|
|
67
|
+
console.log(`[Bun] Total API routes registered: ${Object.keys(this.nativeRoutes).length}`);
|
|
68
|
+
// Initialize static file handler and merge into native routes
|
|
69
|
+
this.staticFiles = new BunStaticFiles(this.options.staticFiles || []);
|
|
70
|
+
if (this.options.staticFiles && this.options.staticFiles.length > 0) {
|
|
71
|
+
// Merge static file routes into native routes for O(1) lookup
|
|
72
|
+
const staticRoutes = this.staticFiles.toBunNativeRoutes();
|
|
73
|
+
Object.assign(this.nativeRoutes, staticRoutes);
|
|
74
|
+
console.log(`[Bun] Static file routes: ${Object.keys(staticRoutes).join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
// Build fallback routers (SSR, frontend SPAs, etc.)
|
|
77
|
+
if (this.options.fallbackRouters) {
|
|
78
|
+
for (const router of this.options.fallbackRouters) {
|
|
79
|
+
const bunRouter = await router.buildBun();
|
|
80
|
+
this.fallbackRouters.push(bunRouter);
|
|
81
|
+
}
|
|
82
|
+
console.log(`[Bun] Fallback routers: ${this.fallbackRouters.length}`);
|
|
83
|
+
}
|
|
84
|
+
// Start server
|
|
85
|
+
this.server = this.createServer();
|
|
86
|
+
if (this.options.onStart) {
|
|
87
|
+
this.options.onStart();
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get the server port
|
|
92
|
+
*/
|
|
93
|
+
get port() {
|
|
94
|
+
return this.server.port;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get the server hostname
|
|
98
|
+
*/
|
|
99
|
+
get hostname() {
|
|
100
|
+
return this.server.hostname;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Stop the server
|
|
104
|
+
*/
|
|
105
|
+
stop() {
|
|
106
|
+
console.log('[Bun] Stopping server...');
|
|
107
|
+
this.server.stop();
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Create and start the Bun server
|
|
111
|
+
* Uses Bun's native routes object for O(1) radix tree routing
|
|
112
|
+
*/
|
|
113
|
+
createServer() {
|
|
114
|
+
const { port, hostname = 'localhost', corsOrigins = [], onError } = this.options;
|
|
115
|
+
return Bun.serve({
|
|
116
|
+
port,
|
|
117
|
+
hostname,
|
|
118
|
+
// Bun-native routes for optimized API routing (radix tree, ~15% faster)
|
|
119
|
+
routes: this.nativeRoutes,
|
|
120
|
+
// Fallback for routes not in native routes (SSR, frontend SPA with regex patterns)
|
|
121
|
+
fetch: async (request, _server) => {
|
|
122
|
+
const url = new URL(request.url);
|
|
123
|
+
const method = request.method;
|
|
124
|
+
const pathname = url.pathname;
|
|
125
|
+
// 1. Handle CORS preflight first
|
|
126
|
+
if (method === 'OPTIONS') {
|
|
127
|
+
return this.createCorsPreflightResponse(corsOrigins, request);
|
|
128
|
+
}
|
|
129
|
+
// 2. Try fallback routers in order (SSR, frontend SPAs, etc.)
|
|
130
|
+
for (const router of this.fallbackRouters) {
|
|
131
|
+
const response = await router.handle(request);
|
|
132
|
+
if (response) {
|
|
133
|
+
return this.addCorsHeaders(response, corsOrigins, request);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// 3. No route found - 404
|
|
137
|
+
return this.addCorsHeaders(new Response(JSON.stringify({
|
|
138
|
+
success: false,
|
|
139
|
+
message: 'Not found',
|
|
140
|
+
path: pathname,
|
|
141
|
+
}), {
|
|
142
|
+
status: 404,
|
|
143
|
+
headers: { 'content-type': 'application/json' },
|
|
144
|
+
}), corsOrigins, request);
|
|
145
|
+
},
|
|
146
|
+
error: (error) => {
|
|
147
|
+
console.error('[Bun] Server error:', error);
|
|
148
|
+
if (onError) {
|
|
149
|
+
onError(error);
|
|
150
|
+
}
|
|
151
|
+
return new Response(JSON.stringify({
|
|
152
|
+
success: false,
|
|
153
|
+
message: 'Internal server error',
|
|
154
|
+
}), {
|
|
155
|
+
status: 500,
|
|
156
|
+
headers: { 'content-type': 'application/json' },
|
|
157
|
+
});
|
|
158
|
+
},
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Create CORS preflight response
|
|
163
|
+
*/
|
|
164
|
+
createCorsPreflightResponse(origins, request) {
|
|
165
|
+
const requestOrigin = request.headers.get('origin');
|
|
166
|
+
const allowOrigin = origins.length > 0
|
|
167
|
+
? (origins.includes(requestOrigin || '') ? requestOrigin : origins[0])
|
|
168
|
+
: '*';
|
|
169
|
+
return new Response(null, {
|
|
170
|
+
status: 204,
|
|
171
|
+
headers: {
|
|
172
|
+
'Access-Control-Allow-Origin': allowOrigin || '*',
|
|
173
|
+
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
|
|
174
|
+
'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Requested-With, Accept, Cache-Control',
|
|
175
|
+
'Access-Control-Allow-Credentials': 'true',
|
|
176
|
+
'Access-Control-Max-Age': '86400',
|
|
177
|
+
},
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Add CORS headers to response
|
|
182
|
+
*/
|
|
183
|
+
addCorsHeaders(response, origins, request) {
|
|
184
|
+
if (origins.length === 0) {
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
const requestOrigin = request.headers.get('origin');
|
|
188
|
+
if (!requestOrigin) {
|
|
189
|
+
return response;
|
|
190
|
+
}
|
|
191
|
+
const allowOrigin = origins.includes(requestOrigin) ? requestOrigin : null;
|
|
192
|
+
if (!allowOrigin) {
|
|
193
|
+
return response;
|
|
194
|
+
}
|
|
195
|
+
const headers = new Headers(response.headers);
|
|
196
|
+
headers.set('Access-Control-Allow-Origin', allowOrigin);
|
|
197
|
+
headers.set('Access-Control-Allow-Credentials', 'true');
|
|
198
|
+
return new Response(response.body, {
|
|
199
|
+
status: response.status,
|
|
200
|
+
statusText: response.statusText,
|
|
201
|
+
headers,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Add CORS headers to response (static utility)
|
|
206
|
+
*/
|
|
207
|
+
static withCors(response, origin) {
|
|
208
|
+
const headers = new Headers(response.headers);
|
|
209
|
+
headers.set('Access-Control-Allow-Origin', origin || '*');
|
|
210
|
+
headers.set('Access-Control-Allow-Credentials', 'true');
|
|
211
|
+
return new Response(response.body, {
|
|
212
|
+
status: response.status,
|
|
213
|
+
statusText: response.statusText,
|
|
214
|
+
headers,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=bunServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunServer.js","sourceRoot":"","sources":["../../src/bun/bunServer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static file serving for Bun runtime
|
|
3
|
+
*/
|
|
4
|
+
export interface StaticFileConfig {
|
|
5
|
+
/** URL path pattern(s) to match */
|
|
6
|
+
urlPath: string | string[];
|
|
7
|
+
/** File system path to serve from */
|
|
8
|
+
fsPath: string;
|
|
9
|
+
/** Cache control header (default: no-cache for dev, 1 year for production) */
|
|
10
|
+
cacheControl?: string;
|
|
11
|
+
/** Whether to enable gzip/brotli compression for text files */
|
|
12
|
+
compress?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** Bun-native route handler type */
|
|
15
|
+
type BunNativeHandler = (req: Request) => Response | Promise<Response>;
|
|
16
|
+
/** Static file routes for Bun.serve() */
|
|
17
|
+
export type BunStaticRoutes = Record<string, BunNativeHandler>;
|
|
18
|
+
/**
|
|
19
|
+
* Class for serving static files in Bun runtime
|
|
20
|
+
*/
|
|
21
|
+
export default class BunStaticFiles {
|
|
22
|
+
private static readonly CACHE_TTL_MS;
|
|
23
|
+
private static readonly COMPRESSIBLE_EXTENSIONS;
|
|
24
|
+
private fileCache;
|
|
25
|
+
private configs;
|
|
26
|
+
constructor(configs: StaticFileConfig[]);
|
|
27
|
+
/**
|
|
28
|
+
* Build Bun-native routes for static files
|
|
29
|
+
* Uses wildcard patterns for efficient matching
|
|
30
|
+
*/
|
|
31
|
+
toBunNativeRoutes(): BunStaticRoutes;
|
|
32
|
+
/**
|
|
33
|
+
* Normalize paths and remove duplicates
|
|
34
|
+
* Handles Express compatibility paths like ['/assets', '/assets/']
|
|
35
|
+
*/
|
|
36
|
+
private normalizeAndDeduplicatePaths;
|
|
37
|
+
/**
|
|
38
|
+
* Handle a request for static files (fallback for fetch handler)
|
|
39
|
+
* Returns null if no matching static file found
|
|
40
|
+
*/
|
|
41
|
+
handle(request: Request): Promise<Response | null>;
|
|
42
|
+
/**
|
|
43
|
+
* Clear the file cache
|
|
44
|
+
*/
|
|
45
|
+
clearCache(): void;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a URL path matches the static file pattern
|
|
48
|
+
*/
|
|
49
|
+
private matchesStaticPath;
|
|
50
|
+
/**
|
|
51
|
+
* Get relative file path from URL
|
|
52
|
+
*/
|
|
53
|
+
private getRelativeFilePath;
|
|
54
|
+
/**
|
|
55
|
+
* Determine if file should be compressed based on extension
|
|
56
|
+
*/
|
|
57
|
+
private shouldCompress;
|
|
58
|
+
/**
|
|
59
|
+
* Get content type for file extension
|
|
60
|
+
*/
|
|
61
|
+
private getContentType;
|
|
62
|
+
/**
|
|
63
|
+
* Serve a static file for Bun
|
|
64
|
+
*/
|
|
65
|
+
private serveStaticFile;
|
|
66
|
+
/**
|
|
67
|
+
* Serve a specific file
|
|
68
|
+
*/
|
|
69
|
+
private serveFile;
|
|
70
|
+
/**
|
|
71
|
+
* Create response with appropriate compression
|
|
72
|
+
*/
|
|
73
|
+
private createFileResponse;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
76
|
+
//# sourceMappingURL=bunStaticFiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunStaticFiles.d.ts","sourceRoot":"","sources":["../../src/bun/bunStaticFiles.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,MAAM,WAAW,gBAAgB;IAChC,mCAAmC;IACnC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC3B,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAYD,oCAAoC;AACpC,KAAK,gBAAgB,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEvE,yCAAyC;AACzC,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAE/D;;GAEG;AACH,MAAM,CAAC,OAAO,OAAO,cAAc;IAClC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAS;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAQ7C;IAEF,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,OAAO,CAAqB;gBAExB,OAAO,EAAE,gBAAgB,EAAE;IAIvC;;;OAGG;IACH,iBAAiB,IAAI,eAAe;IA+BpC;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IAiBpC;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;IAmBxD;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAkBzB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACH,OAAO,CAAC,cAAc;IActB;;OAEG;YACW,eAAe;IA2D7B;;OAEG;YACW,SAAS;IAwDvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CA6B1B"}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static file serving for Bun runtime
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import mime from 'mime-types';
|
|
7
|
+
/**
|
|
8
|
+
* Class for serving static files in Bun runtime
|
|
9
|
+
*/
|
|
10
|
+
export default class BunStaticFiles {
|
|
11
|
+
static CACHE_TTL_MS = 60000; // 1 minute cache TTL
|
|
12
|
+
static COMPRESSIBLE_EXTENSIONS = [
|
|
13
|
+
'js',
|
|
14
|
+
'css',
|
|
15
|
+
'html',
|
|
16
|
+
'json',
|
|
17
|
+
'svg',
|
|
18
|
+
'txt',
|
|
19
|
+
'xml',
|
|
20
|
+
];
|
|
21
|
+
fileCache = new Map();
|
|
22
|
+
configs;
|
|
23
|
+
constructor(configs) {
|
|
24
|
+
this.configs = configs;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build Bun-native routes for static files
|
|
28
|
+
* Uses wildcard patterns for efficient matching
|
|
29
|
+
*/
|
|
30
|
+
toBunNativeRoutes() {
|
|
31
|
+
const routes = {};
|
|
32
|
+
for (const config of this.configs) {
|
|
33
|
+
// Normalize and deduplicate paths
|
|
34
|
+
const urlPaths = Array.isArray(config.urlPath) ? config.urlPath : [config.urlPath];
|
|
35
|
+
const normalizedPaths = this.normalizeAndDeduplicatePaths(urlPaths);
|
|
36
|
+
for (const basePath of normalizedPaths) {
|
|
37
|
+
// Create wildcard route pattern for Bun (e.g., "/assets-eshop/*")
|
|
38
|
+
const routePattern = `${basePath}/*`;
|
|
39
|
+
// Skip if route already exists (from another config)
|
|
40
|
+
if (routes[routePattern]) {
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
routes[routePattern] = async (request) => {
|
|
44
|
+
const response = await this.serveStaticFile(request, config, basePath);
|
|
45
|
+
return response || new Response('Not Found', { status: 404 });
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return routes;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Normalize paths and remove duplicates
|
|
53
|
+
* Handles Express compatibility paths like ['/assets', '/assets/']
|
|
54
|
+
*/
|
|
55
|
+
normalizeAndDeduplicatePaths(paths) {
|
|
56
|
+
const normalized = new Set();
|
|
57
|
+
for (const p of paths) {
|
|
58
|
+
// Remove trailing slashes and wildcards for normalization
|
|
59
|
+
let clean = p.replace(/\/+$/, '').replace(/\/?\*.*$/, '');
|
|
60
|
+
// Ensure leading slash
|
|
61
|
+
if (!clean.startsWith('/')) {
|
|
62
|
+
clean = `/${clean}`;
|
|
63
|
+
}
|
|
64
|
+
normalized.add(clean);
|
|
65
|
+
}
|
|
66
|
+
return Array.from(normalized);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Handle a request for static files (fallback for fetch handler)
|
|
70
|
+
* Returns null if no matching static file found
|
|
71
|
+
*/
|
|
72
|
+
async handle(request) {
|
|
73
|
+
for (const config of this.configs) {
|
|
74
|
+
const urlPaths = Array.isArray(config.urlPath) ? config.urlPath : [config.urlPath];
|
|
75
|
+
const normalizedPaths = this.normalizeAndDeduplicatePaths(urlPaths);
|
|
76
|
+
for (const basePath of normalizedPaths) {
|
|
77
|
+
const response = await this.serveStaticFile(request, config, basePath);
|
|
78
|
+
if (response) {
|
|
79
|
+
return response;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Clear the file cache
|
|
87
|
+
*/
|
|
88
|
+
clearCache() {
|
|
89
|
+
this.fileCache.clear();
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check if a URL path matches the static file pattern
|
|
93
|
+
*/
|
|
94
|
+
matchesStaticPath(urlPath, patterns) {
|
|
95
|
+
const patternList = Array.isArray(patterns) ? patterns : [patterns];
|
|
96
|
+
for (const pattern of patternList) {
|
|
97
|
+
// Handle wildcard patterns like /assets-eshop/*all
|
|
98
|
+
if (pattern.includes('*')) {
|
|
99
|
+
const basePattern = pattern.replace(/\/?\*.*$/, '');
|
|
100
|
+
if (urlPath.startsWith(basePattern)) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
else if (urlPath === pattern || urlPath.startsWith(`${pattern}/`)) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get relative file path from URL
|
|
112
|
+
*/
|
|
113
|
+
getRelativeFilePath(urlPath, patterns) {
|
|
114
|
+
const patternList = Array.isArray(patterns) ? patterns : [patterns];
|
|
115
|
+
for (const pattern of patternList) {
|
|
116
|
+
const basePattern = pattern.replace(/\/?\*.*$/, '');
|
|
117
|
+
if (urlPath.startsWith(basePattern)) {
|
|
118
|
+
return urlPath.slice(basePattern.length) || '/';
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return urlPath;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Determine if file should be compressed based on extension
|
|
125
|
+
*/
|
|
126
|
+
shouldCompress(ext) {
|
|
127
|
+
return BunStaticFiles.COMPRESSIBLE_EXTENSIONS.includes(ext.toLowerCase());
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Get content type for file extension
|
|
131
|
+
*/
|
|
132
|
+
getContentType(ext) {
|
|
133
|
+
const mimeType = mime.lookup(ext);
|
|
134
|
+
if (mimeType) {
|
|
135
|
+
// Add charset for text types
|
|
136
|
+
if (mimeType.startsWith('text/') || mimeType.includes('javascript') || mimeType.includes('json')) {
|
|
137
|
+
return `${mimeType}; charset=utf-8`;
|
|
138
|
+
}
|
|
139
|
+
return mimeType;
|
|
140
|
+
}
|
|
141
|
+
return 'application/octet-stream';
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Serve a static file for Bun
|
|
145
|
+
*/
|
|
146
|
+
async serveStaticFile(request, config, basePath) {
|
|
147
|
+
const url = new URL(request.url);
|
|
148
|
+
const urlPath = url.pathname;
|
|
149
|
+
// If basePath is provided (from native routes), use it directly
|
|
150
|
+
// Otherwise, check if path matches config patterns
|
|
151
|
+
if (basePath) {
|
|
152
|
+
if (!urlPath.startsWith(basePath)) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else if (!this.matchesStaticPath(urlPath, config.urlPath)) {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
// Get relative file path
|
|
160
|
+
const relativePath = basePath
|
|
161
|
+
? urlPath.slice(basePath.length) || '/'
|
|
162
|
+
: this.getRelativeFilePath(urlPath, config.urlPath);
|
|
163
|
+
const filePath = path.join(config.fsPath, relativePath.split('?')[0]);
|
|
164
|
+
// Security: prevent directory traversal
|
|
165
|
+
const resolvedPath = path.resolve(filePath);
|
|
166
|
+
const resolvedBase = path.resolve(config.fsPath);
|
|
167
|
+
if (!resolvedPath.startsWith(resolvedBase)) {
|
|
168
|
+
return new Response('Forbidden', { status: 403 });
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
// Check if file exists
|
|
172
|
+
const stat = fs.statSync(resolvedPath);
|
|
173
|
+
if (stat.isDirectory()) {
|
|
174
|
+
// Try index.html for directories
|
|
175
|
+
const indexPath = path.join(resolvedPath, 'index.html');
|
|
176
|
+
if (fs.existsSync(indexPath)) {
|
|
177
|
+
return this.serveFile(request, indexPath, config);
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return this.serveFile(request, resolvedPath, config);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Serve a specific file
|
|
189
|
+
*/
|
|
190
|
+
async serveFile(request, filePath, config) {
|
|
191
|
+
const ext = path.extname(filePath).slice(1).toLowerCase();
|
|
192
|
+
const contentType = this.getContentType(ext);
|
|
193
|
+
// Check cache
|
|
194
|
+
const cacheKey = filePath;
|
|
195
|
+
const cached = this.fileCache.get(cacheKey);
|
|
196
|
+
const stat = fs.statSync(filePath);
|
|
197
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
198
|
+
if (cached && cached.mtime === stat.mtimeMs && Date.now() - cached.mtime < BunStaticFiles.CACHE_TTL_MS) {
|
|
199
|
+
return this.createFileResponse(request, cached, contentType, config);
|
|
200
|
+
}
|
|
201
|
+
// Read file
|
|
202
|
+
const content = fs.readFileSync(filePath);
|
|
203
|
+
// Create cache entry
|
|
204
|
+
const cacheEntry = {
|
|
205
|
+
content,
|
|
206
|
+
contentType,
|
|
207
|
+
mtime: stat.mtimeMs,
|
|
208
|
+
};
|
|
209
|
+
// Compress if needed
|
|
210
|
+
if (config.compress !== false && this.shouldCompress(ext)) {
|
|
211
|
+
try {
|
|
212
|
+
// Use Bun's native gzip
|
|
213
|
+
cacheEntry.compressed = {
|
|
214
|
+
gzip: Bun.gzipSync(content),
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
// Compression failed, serve uncompressed
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Store in cache
|
|
222
|
+
this.fileCache.set(cacheKey, cacheEntry);
|
|
223
|
+
return this.createFileResponse(request, cacheEntry, contentType, config);
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Create response with appropriate compression
|
|
227
|
+
*/
|
|
228
|
+
createFileResponse(request, cached, contentType, config) {
|
|
229
|
+
const acceptEncoding = request.headers.get('accept-encoding') || '';
|
|
230
|
+
const headers = {
|
|
231
|
+
'Content-Type': contentType,
|
|
232
|
+
};
|
|
233
|
+
// Set cache control
|
|
234
|
+
if (config.cacheControl) {
|
|
235
|
+
headers['Cache-Control'] = config.cacheControl;
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// Default: cache for 1 year for hashed assets, no-cache for others
|
|
239
|
+
const hasHash = /\.[a-f0-9]{8,}\./i.test(request.url);
|
|
240
|
+
headers['Cache-Control'] = hasHash ? 'public, max-age=31536000, immutable' : 'no-cache';
|
|
241
|
+
}
|
|
242
|
+
// Try to serve compressed version
|
|
243
|
+
if (cached.compressed?.gzip && acceptEncoding.includes('gzip')) {
|
|
244
|
+
headers['Content-Encoding'] = 'gzip';
|
|
245
|
+
headers.Vary = 'Accept-Encoding';
|
|
246
|
+
return new Response(cached.compressed.gzip, { headers });
|
|
247
|
+
}
|
|
248
|
+
return new Response(cached.content, { headers });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=bunStaticFiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunStaticFiles.js","sourceRoot":"","sources":["../../src/bun/bunStaticFiles.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bun runtime utilities - barrel export
|
|
3
|
+
*/
|
|
4
|
+
export { type BunCorsConfig, type BunNativeRoutes, type BunRouteDefinition, BunRouter } from './bunRouter';
|
|
5
|
+
export { default as BunServer, type BunServerOptions } from './bunServer';
|
|
6
|
+
export { default as BunStaticFiles, type BunStaticRoutes, type StaticFileConfig } from './bunStaticFiles';
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/bun/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,KAAK,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bun/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC3G,OAAO,EAAE,OAAO,IAAI,SAAS,EAAyB,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,cAAc,EAA+C,MAAM,kBAAkB,CAAC"}
|