@onebun/core 0.2.1 → 0.2.2
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/package.json +1 -1
- package/src/application/application.test.ts +36 -0
- package/src/application/application.ts +70 -6
- package/src/application/multi-service-application.ts +2 -0
- package/src/application/multi-service.types.ts +1 -1
- package/src/decorators/decorators.test.ts +63 -12
- package/src/decorators/decorators.ts +113 -7
- package/src/docs-examples.test.ts +793 -8
- package/src/index.ts +9 -0
- package/src/module/controller.ts +96 -10
- package/src/module/index.ts +2 -1
- package/src/module/lifecycle.ts +13 -0
- package/src/module/middleware.ts +76 -0
- package/src/module/module.test.ts +138 -1
- package/src/module/module.ts +127 -2
- package/src/types.ts +142 -0
package/src/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { BaseMiddleware } from './module/middleware';
|
|
1
2
|
import type { Type } from 'arktype';
|
|
2
3
|
import type { Effect, Layer } from 'effect';
|
|
3
4
|
|
|
@@ -12,6 +13,31 @@ import type { Logger, LoggerOptions } from '@onebun/logger';
|
|
|
12
13
|
*/
|
|
13
14
|
export type OneBunRequest = import('bun').BunRequest;
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* A middleware class constructor.
|
|
18
|
+
*
|
|
19
|
+
* Pass class references (not instances) to `@UseMiddleware()`,
|
|
20
|
+
* `ApplicationOptions.middleware`, and `OnModuleConfigure.configureMiddleware()`.
|
|
21
|
+
* The framework will instantiate them once at startup with DI support.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```typescript
|
|
25
|
+
* @UseMiddleware(AuthMiddleware)
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
+
export type MiddlewareClass = new (...args: any[]) => BaseMiddleware;
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Resolved middleware function — a bound `use()` method of an instantiated
|
|
33
|
+
* `BaseMiddleware`. Used internally by the execution pipeline.
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export type ResolvedMiddleware = (
|
|
37
|
+
req: OneBunRequest,
|
|
38
|
+
next: () => Promise<OneBunResponse>,
|
|
39
|
+
) => Promise<OneBunResponse> | OneBunResponse;
|
|
40
|
+
|
|
15
41
|
/**
|
|
16
42
|
* HTTP Response type used in OneBun controllers.
|
|
17
43
|
* Standard Web API Response.
|
|
@@ -50,6 +76,37 @@ export interface ModuleProviders {
|
|
|
50
76
|
exports?: Function[];
|
|
51
77
|
}
|
|
52
78
|
|
|
79
|
+
/**
|
|
80
|
+
* Interface for modules that configure middleware.
|
|
81
|
+
* Implement this interface on your `@Module()` class to apply middleware
|
|
82
|
+
* to all controllers within the module (including imported child modules).
|
|
83
|
+
*
|
|
84
|
+
* Module-level middleware runs after global middleware but before
|
|
85
|
+
* controller-level and route-level middleware.
|
|
86
|
+
*
|
|
87
|
+
* Execution order: global → module → controller → route → handler
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```typescript
|
|
91
|
+
* @Module({
|
|
92
|
+
* controllers: [UserController],
|
|
93
|
+
* imports: [AuthModule],
|
|
94
|
+
* })
|
|
95
|
+
* export class UserModule implements OnModuleConfigure {
|
|
96
|
+
* configureMiddleware(): MiddlewareClass[] {
|
|
97
|
+
* return [TenantMiddleware, AuditMiddleware];
|
|
98
|
+
* }
|
|
99
|
+
* }
|
|
100
|
+
* ```
|
|
101
|
+
*/
|
|
102
|
+
export interface OnModuleConfigure {
|
|
103
|
+
/**
|
|
104
|
+
* Return an array of middleware class constructors to apply to all controllers
|
|
105
|
+
* in this module and its imported child modules.
|
|
106
|
+
*/
|
|
107
|
+
configureMiddleware(): MiddlewareClass[];
|
|
108
|
+
}
|
|
109
|
+
|
|
53
110
|
/**
|
|
54
111
|
* Module instance interface
|
|
55
112
|
*/
|
|
@@ -98,6 +155,19 @@ export interface ModuleInstance {
|
|
|
98
155
|
* Get service instance by class
|
|
99
156
|
*/
|
|
100
157
|
getServiceByClass?<T>(serviceClass: new (...args: unknown[]) => T): T | undefined;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Get accumulated module-level middleware (resolved bound functions)
|
|
161
|
+
* for a given controller class.
|
|
162
|
+
* Includes middleware from ancestor modules (root → child → … → owner module).
|
|
163
|
+
*/
|
|
164
|
+
getModuleMiddleware?(controllerClass: Function): Function[];
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Resolve middleware class constructors into bound `use()` functions
|
|
168
|
+
* using this module's DI scope (services + logger + config).
|
|
169
|
+
*/
|
|
170
|
+
resolveMiddleware?(classes: Function[]): Function[];
|
|
101
171
|
}
|
|
102
172
|
|
|
103
173
|
/**
|
|
@@ -128,6 +198,14 @@ export interface ApplicationOptions {
|
|
|
128
198
|
*/
|
|
129
199
|
host?: string;
|
|
130
200
|
|
|
201
|
+
/**
|
|
202
|
+
* Maximum idle time (in seconds) before the server closes a connection.
|
|
203
|
+
* A connection is idle when no data is sent or received.
|
|
204
|
+
* Set to 0 to disable the timeout entirely.
|
|
205
|
+
* @defaultValue 120
|
|
206
|
+
*/
|
|
207
|
+
idleTimeout?: number;
|
|
208
|
+
|
|
131
209
|
/**
|
|
132
210
|
* Base path prefix for all routes
|
|
133
211
|
* @example '/api/v1'
|
|
@@ -342,6 +420,25 @@ export interface ApplicationOptions {
|
|
|
342
420
|
*/
|
|
343
421
|
docs?: DocsApplicationOptions;
|
|
344
422
|
|
|
423
|
+
/**
|
|
424
|
+
* Application-wide middleware applied to every route before module-level,
|
|
425
|
+
* controller-level and route-level middleware. Useful for cross-cutting
|
|
426
|
+
* concerns like request logging, authentication, CORS, or request validation.
|
|
427
|
+
*
|
|
428
|
+
* Pass class constructors (not instances). The framework will instantiate
|
|
429
|
+
* them once at startup with full DI support from the root module.
|
|
430
|
+
*
|
|
431
|
+
* Execution order: global → module → controller → route → handler
|
|
432
|
+
*
|
|
433
|
+
* @example
|
|
434
|
+
* ```typescript
|
|
435
|
+
* const app = new OneBunApplication(AppModule, {
|
|
436
|
+
* middleware: [CorsMiddleware, RequestIdMiddleware],
|
|
437
|
+
* });
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
middleware?: MiddlewareClass[];
|
|
441
|
+
|
|
345
442
|
/**
|
|
346
443
|
* Enable graceful shutdown on SIGTERM/SIGINT
|
|
347
444
|
* When enabled, the application will cleanly shutdown on process signals,
|
|
@@ -588,6 +685,26 @@ export interface ResponseSchemaMetadata {
|
|
|
588
685
|
description?: string;
|
|
589
686
|
}
|
|
590
687
|
|
|
688
|
+
/**
|
|
689
|
+
* Options for HTTP method decorators (@Get, @Post, @Put, @Delete, @Patch, etc.)
|
|
690
|
+
*/
|
|
691
|
+
export interface RouteOptions {
|
|
692
|
+
/**
|
|
693
|
+
* Per-request idle timeout in seconds.
|
|
694
|
+
* Overrides the global `idleTimeout` from `ApplicationOptions` for this route.
|
|
695
|
+
* Set to 0 to disable the timeout entirely (useful for long-running requests).
|
|
696
|
+
* @example
|
|
697
|
+
* ```typescript
|
|
698
|
+
* @Get('/long-task', { timeout: 300 }) // 5 minutes
|
|
699
|
+
* async longTask() { ... }
|
|
700
|
+
*
|
|
701
|
+
* @Get('/stream', { timeout: 0 }) // no timeout
|
|
702
|
+
* async stream() { ... }
|
|
703
|
+
* ```
|
|
704
|
+
*/
|
|
705
|
+
timeout?: number;
|
|
706
|
+
}
|
|
707
|
+
|
|
591
708
|
/**
|
|
592
709
|
* Route metadata
|
|
593
710
|
*/
|
|
@@ -602,6 +719,11 @@ export interface RouteMetadata {
|
|
|
602
719
|
* Key is HTTP status code (e.g., 200, 201, 404)
|
|
603
720
|
*/
|
|
604
721
|
responseSchemas?: ResponseSchemaMetadata[];
|
|
722
|
+
/**
|
|
723
|
+
* Per-request idle timeout in seconds.
|
|
724
|
+
* When set, calls `server.timeout(req, seconds)` for this route.
|
|
725
|
+
*/
|
|
726
|
+
timeout?: number;
|
|
605
727
|
}
|
|
606
728
|
|
|
607
729
|
/**
|
|
@@ -610,6 +732,11 @@ export interface RouteMetadata {
|
|
|
610
732
|
export interface ControllerMetadata {
|
|
611
733
|
path: string;
|
|
612
734
|
routes: RouteMetadata[];
|
|
735
|
+
/**
|
|
736
|
+
* Controller-level middleware class constructors applied to all routes.
|
|
737
|
+
* Set by applying @UseMiddleware() as a class decorator.
|
|
738
|
+
*/
|
|
739
|
+
middleware?: MiddlewareClass[];
|
|
613
740
|
}
|
|
614
741
|
|
|
615
742
|
// ============================================================================
|
|
@@ -662,6 +789,21 @@ export interface SseOptions {
|
|
|
662
789
|
* at this interval to keep the connection alive.
|
|
663
790
|
*/
|
|
664
791
|
heartbeat?: number;
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* Callback invoked when the client disconnects or aborts the SSE connection.
|
|
795
|
+
* Useful for cleanup logic when using `controller.sse()` programmatically.
|
|
796
|
+
*
|
|
797
|
+
* For `@Sse()` decorator usage, prefer `try/finally` in the generator instead.
|
|
798
|
+
*
|
|
799
|
+
* @example
|
|
800
|
+
* ```typescript
|
|
801
|
+
* return this.sse(this.generateEvents(), {
|
|
802
|
+
* onAbort: () => this.eventService.unsubscribe(),
|
|
803
|
+
* });
|
|
804
|
+
* ```
|
|
805
|
+
*/
|
|
806
|
+
onAbort?: () => void;
|
|
665
807
|
}
|
|
666
808
|
|
|
667
809
|
/**
|