@navios/core 0.7.1 → 0.9.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/CHANGELOG.md +78 -0
- package/lib/{index-DW9EPAE6.d.mts → index-D9MNh6Tx.d.mts} +534 -342
- package/lib/index-D9MNh6Tx.d.mts.map +1 -0
- package/lib/{index-pHp-dIGt.d.cts → index-Db1d3cwD.d.cts} +534 -342
- package/lib/index-Db1d3cwD.d.cts.map +1 -0
- package/lib/index.cjs +12 -3
- package/lib/index.d.cts +2 -2
- package/lib/index.d.mts +2 -2
- package/lib/index.mjs +3 -3
- package/lib/legacy-compat/index.cjs +1 -1
- package/lib/legacy-compat/index.cjs.map +1 -1
- package/lib/legacy-compat/index.d.cts +3 -3
- package/lib/legacy-compat/index.d.cts.map +1 -1
- package/lib/legacy-compat/index.d.mts +3 -3
- package/lib/legacy-compat/index.d.mts.map +1 -1
- package/lib/legacy-compat/index.mjs +1 -1
- package/lib/legacy-compat/index.mjs.map +1 -1
- package/lib/{src-QnxR5b7c.cjs → src-BRPtJ9fG.cjs} +474 -53
- package/lib/src-BRPtJ9fG.cjs.map +1 -0
- package/lib/{src-DyvCDuKO.mjs → src-Bo23RIo-.mjs} +454 -51
- package/lib/src-Bo23RIo-.mjs.map +1 -0
- package/lib/testing/index.cjs +346 -29
- package/lib/testing/index.cjs.map +1 -1
- package/lib/testing/index.d.cts +299 -63
- package/lib/testing/index.d.cts.map +1 -1
- package/lib/testing/index.d.mts +299 -63
- package/lib/testing/index.d.mts.map +1 -1
- package/lib/testing/index.mjs +347 -31
- package/lib/testing/index.mjs.map +1 -1
- package/lib/{use-guards.decorator-B6q_N0sf.cjs → use-guards.decorator-Bs8oDHOi.cjs} +29 -99
- package/lib/use-guards.decorator-Bs8oDHOi.cjs.map +1 -0
- package/lib/{use-guards.decorator-kZ3lNK8v.mjs → use-guards.decorator-CzVXuLkz.mjs} +23 -99
- package/lib/use-guards.decorator-CzVXuLkz.mjs.map +1 -0
- package/package.json +4 -4
- package/src/__tests__/controller-resolver.spec.mts +229 -0
- package/src/__tests__/controller.spec.mts +1 -1
- package/src/__tests__/testing-module.spec.mts +459 -0
- package/src/__tests__/unit-testing-module.spec.mts +424 -0
- package/src/decorators/controller.decorator.mts +29 -7
- package/src/decorators/endpoint.decorator.mts +60 -12
- package/src/decorators/module.decorator.mts +23 -5
- package/src/decorators/multipart.decorator.mts +67 -24
- package/src/decorators/stream.decorator.mts +65 -24
- package/src/interfaces/abstract-http-handler-adapter.interface.mts +31 -1
- package/src/legacy-compat/__type-tests__/legacy-decorators.spec-d.mts +2 -6
- package/src/legacy-compat/decorators/endpoint.decorator.mts +1 -1
- package/src/legacy-compat/decorators/multipart.decorator.mts +5 -5
- package/src/legacy-compat/decorators/stream.decorator.mts +5 -5
- package/src/logger/logger.service.mts +0 -2
- package/src/navios.application.mts +23 -9
- package/src/navios.environment.mts +3 -1
- package/src/navios.factory.mts +19 -18
- package/src/services/guard-runner.service.mts +46 -9
- package/src/services/index.mts +1 -0
- package/src/services/instance-resolver.service.mts +187 -0
- package/src/services/module-loader.service.mts +3 -2
- package/src/stores/request-id.store.mts +45 -3
- package/src/testing/index.mts +1 -0
- package/src/testing/testing-module.mts +255 -93
- package/src/testing/unit-testing-module.mts +298 -0
- package/src/tokens/index.mts +1 -0
- package/src/tokens/navios-options.token.mts +6 -0
- package/lib/index-DW9EPAE6.d.mts.map +0 -1
- package/lib/index-pHp-dIGt.d.cts.map +0 -1
- package/lib/src-DyvCDuKO.mjs.map +0 -1
- package/lib/src-QnxR5b7c.cjs.map +0 -1
- package/lib/use-guards.decorator-B6q_N0sf.cjs.map +0 -1
- package/lib/use-guards.decorator-kZ3lNK8v.mjs.map +0 -1
|
@@ -13,9 +13,9 @@ import { MultipartAdapterToken } from '../tokens/index.mjs'
|
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* Extracts the typed parameters for a multipart endpoint handler function.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* Similar to `EndpointParams`, but specifically for multipart/form-data endpoints.
|
|
18
|
-
*
|
|
18
|
+
*
|
|
19
19
|
* @typeParam EndpointDeclaration - The endpoint declaration from @navios/builder
|
|
20
20
|
*/
|
|
21
21
|
export type MultipartParams<
|
|
@@ -48,7 +48,7 @@ export type MultipartParams<
|
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Extracts the typed return value for a multipart endpoint handler function.
|
|
51
|
-
*
|
|
51
|
+
*
|
|
52
52
|
* @typeParam EndpointDeclaration - The endpoint declaration from @navios/builder
|
|
53
53
|
*/
|
|
54
54
|
export type MultipartResult<
|
|
@@ -64,13 +64,13 @@ export type MultipartResult<
|
|
|
64
64
|
|
|
65
65
|
/**
|
|
66
66
|
* Decorator that marks a method as a multipart/form-data endpoint.
|
|
67
|
-
*
|
|
67
|
+
*
|
|
68
68
|
* Use this decorator for endpoints that handle file uploads or form data.
|
|
69
69
|
* The endpoint must be defined using @navios/builder's `declareMultipart` method.
|
|
70
|
-
*
|
|
70
|
+
*
|
|
71
71
|
* @param endpoint - The multipart endpoint declaration from @navios/builder
|
|
72
72
|
* @returns A method decorator
|
|
73
|
-
*
|
|
73
|
+
*
|
|
74
74
|
* @example
|
|
75
75
|
* ```typescript
|
|
76
76
|
* const uploadFileEndpoint = api.declareMultipart({
|
|
@@ -79,7 +79,7 @@ export type MultipartResult<
|
|
|
79
79
|
* requestSchema: z.object({ file: z.instanceof(File) }),
|
|
80
80
|
* responseSchema: z.object({ url: z.string() }),
|
|
81
81
|
* })
|
|
82
|
-
*
|
|
82
|
+
*
|
|
83
83
|
* @Controller()
|
|
84
84
|
* export class FileController {
|
|
85
85
|
* @Multipart(uploadFileEndpoint)
|
|
@@ -91,6 +91,51 @@ export type MultipartResult<
|
|
|
91
91
|
* }
|
|
92
92
|
* ```
|
|
93
93
|
*/
|
|
94
|
+
export function Multipart<
|
|
95
|
+
Method extends HttpMethod = HttpMethod,
|
|
96
|
+
Url extends string = string,
|
|
97
|
+
QuerySchema = undefined,
|
|
98
|
+
ResponseSchema extends ZodType = ZodType,
|
|
99
|
+
RequestSchema = ZodType,
|
|
100
|
+
Params = QuerySchema extends ZodObject
|
|
101
|
+
? RequestSchema extends ZodType
|
|
102
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
103
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
104
|
+
: RequestSchema extends ZodType
|
|
105
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
106
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>,
|
|
107
|
+
>(endpoint: {
|
|
108
|
+
config: BaseEndpointConfig<
|
|
109
|
+
Method,
|
|
110
|
+
Url,
|
|
111
|
+
QuerySchema,
|
|
112
|
+
ResponseSchema,
|
|
113
|
+
RequestSchema
|
|
114
|
+
>
|
|
115
|
+
}): (
|
|
116
|
+
target: (
|
|
117
|
+
params: Params,
|
|
118
|
+
) => Promise<z.input<ResponseSchema>> | z.input<ResponseSchema>,
|
|
119
|
+
context: ClassMethodDecoratorContext,
|
|
120
|
+
) => void
|
|
121
|
+
export function Multipart<
|
|
122
|
+
Method extends HttpMethod = HttpMethod,
|
|
123
|
+
Url extends string = string,
|
|
124
|
+
QuerySchema = undefined,
|
|
125
|
+
ResponseSchema extends ZodType = ZodType,
|
|
126
|
+
RequestSchema = ZodType,
|
|
127
|
+
>(endpoint: {
|
|
128
|
+
config: BaseEndpointConfig<
|
|
129
|
+
Method,
|
|
130
|
+
Url,
|
|
131
|
+
QuerySchema,
|
|
132
|
+
ResponseSchema,
|
|
133
|
+
RequestSchema
|
|
134
|
+
>
|
|
135
|
+
}): (
|
|
136
|
+
target: () => Promise<z.input<ResponseSchema>> | z.input<ResponseSchema>,
|
|
137
|
+
context: ClassMethodDecoratorContext,
|
|
138
|
+
) => void
|
|
94
139
|
export function Multipart<
|
|
95
140
|
Method extends HttpMethod = HttpMethod,
|
|
96
141
|
Url extends string = string,
|
|
@@ -106,23 +151,21 @@ export function Multipart<
|
|
|
106
151
|
RequestSchema
|
|
107
152
|
>
|
|
108
153
|
}) {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
)
|
|
125
|
-
}
|
|
154
|
+
type Params = QuerySchema extends ZodObject
|
|
155
|
+
? RequestSchema extends ZodType
|
|
156
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
157
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
158
|
+
: RequestSchema extends ZodType
|
|
159
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
160
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>
|
|
161
|
+
|
|
162
|
+
type Handler =
|
|
163
|
+
| ((
|
|
164
|
+
params: Params,
|
|
165
|
+
) => Promise<z.input<ResponseSchema>> | z.input<ResponseSchema>)
|
|
166
|
+
| (() => Promise<z.input<ResponseSchema>> | z.input<ResponseSchema>)
|
|
167
|
+
|
|
168
|
+
return (target: Handler, context: ClassMethodDecoratorContext) => {
|
|
126
169
|
if (context.kind !== 'method') {
|
|
127
170
|
throw new Error(
|
|
128
171
|
'[Navios] Endpoint decorator can only be used on methods.',
|
|
@@ -11,9 +11,9 @@ import { StreamAdapterToken } from '../tokens/index.mjs'
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Extracts the typed parameters for a stream endpoint handler function.
|
|
14
|
-
*
|
|
14
|
+
*
|
|
15
15
|
* Similar to `EndpointParams`, but specifically for streaming endpoints.
|
|
16
|
-
*
|
|
16
|
+
*
|
|
17
17
|
* @typeParam EndpointDeclaration - The stream endpoint declaration from @navios/builder
|
|
18
18
|
*/
|
|
19
19
|
export type StreamParams<
|
|
@@ -46,20 +46,20 @@ export type StreamParams<
|
|
|
46
46
|
|
|
47
47
|
/**
|
|
48
48
|
* Decorator that marks a method as a streaming endpoint.
|
|
49
|
-
*
|
|
49
|
+
*
|
|
50
50
|
* Use this decorator for endpoints that stream data (e.g., file downloads, SSE).
|
|
51
51
|
* The endpoint must be defined using @navios/builder's `declareStream` method.
|
|
52
|
-
*
|
|
52
|
+
*
|
|
53
53
|
* @param endpoint - The stream endpoint declaration from @navios/builder
|
|
54
54
|
* @returns A method decorator
|
|
55
|
-
*
|
|
55
|
+
*
|
|
56
56
|
* @example
|
|
57
57
|
* ```typescript
|
|
58
58
|
* const downloadFileEndpoint = api.declareStream({
|
|
59
59
|
* method: 'get',
|
|
60
60
|
* url: '/files/$fileId',
|
|
61
61
|
* })
|
|
62
|
-
*
|
|
62
|
+
*
|
|
63
63
|
* @Controller()
|
|
64
64
|
* export class FileController {
|
|
65
65
|
* @Stream(downloadFileEndpoint)
|
|
@@ -70,6 +70,51 @@ export type StreamParams<
|
|
|
70
70
|
* }
|
|
71
71
|
* ```
|
|
72
72
|
*/
|
|
73
|
+
export function Stream<
|
|
74
|
+
Method extends HttpMethod = HttpMethod,
|
|
75
|
+
Url extends string = string,
|
|
76
|
+
QuerySchema = undefined,
|
|
77
|
+
RequestSchema = ZodType,
|
|
78
|
+
Params = QuerySchema extends ZodObject
|
|
79
|
+
? RequestSchema extends ZodType
|
|
80
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
81
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
82
|
+
: RequestSchema extends ZodType
|
|
83
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
84
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>,
|
|
85
|
+
>(endpoint: {
|
|
86
|
+
config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
|
|
87
|
+
}): (
|
|
88
|
+
target: (params: Params, reply: any) => any,
|
|
89
|
+
context: ClassMethodDecoratorContext,
|
|
90
|
+
) => void
|
|
91
|
+
// Bun doesn't support reply parameter
|
|
92
|
+
export function Stream<
|
|
93
|
+
Method extends HttpMethod = HttpMethod,
|
|
94
|
+
Url extends string = string,
|
|
95
|
+
QuerySchema = undefined,
|
|
96
|
+
RequestSchema = ZodType,
|
|
97
|
+
Params = QuerySchema extends ZodObject
|
|
98
|
+
? RequestSchema extends ZodType
|
|
99
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
100
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
101
|
+
: RequestSchema extends ZodType
|
|
102
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
103
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>,
|
|
104
|
+
>(endpoint: {
|
|
105
|
+
config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
|
|
106
|
+
}): (
|
|
107
|
+
target: (params: Params) => any,
|
|
108
|
+
context: ClassMethodDecoratorContext,
|
|
109
|
+
) => void
|
|
110
|
+
export function Stream<
|
|
111
|
+
Method extends HttpMethod = HttpMethod,
|
|
112
|
+
Url extends string = string,
|
|
113
|
+
QuerySchema = undefined,
|
|
114
|
+
RequestSchema = ZodType,
|
|
115
|
+
>(endpoint: {
|
|
116
|
+
config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
|
|
117
|
+
}): (target: () => any, context: ClassMethodDecoratorContext) => void
|
|
73
118
|
export function Stream<
|
|
74
119
|
Method extends HttpMethod = HttpMethod,
|
|
75
120
|
Url extends string = string,
|
|
@@ -78,24 +123,20 @@ export function Stream<
|
|
|
78
123
|
>(endpoint: {
|
|
79
124
|
config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
|
|
80
125
|
}) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
) =>
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
throw new Error(
|
|
96
|
-
'[Navios] Endpoint decorator can only be used on functions.',
|
|
97
|
-
)
|
|
98
|
-
}
|
|
126
|
+
type Params = QuerySchema extends ZodObject
|
|
127
|
+
? RequestSchema extends ZodType
|
|
128
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
129
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
130
|
+
: RequestSchema extends ZodType
|
|
131
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
132
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>
|
|
133
|
+
|
|
134
|
+
type Handler =
|
|
135
|
+
| ((params: Params, reply: any) => any)
|
|
136
|
+
| ((params: Params) => any)
|
|
137
|
+
| (() => any)
|
|
138
|
+
|
|
139
|
+
return (target: Handler, context: ClassMethodDecoratorContext) => {
|
|
99
140
|
if (context.kind !== 'method') {
|
|
100
141
|
throw new Error(
|
|
101
142
|
'[Navios] Endpoint decorator can only be used on methods.',
|
|
@@ -2,6 +2,36 @@ import type { ClassType, ScopedContainer } from '@navios/di'
|
|
|
2
2
|
|
|
3
3
|
import type { HandlerMetadata } from '../metadata/index.mjs'
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Static handler result - handler can be called without a scoped container.
|
|
7
|
+
* Used when the controller and all its dependencies are singletons.
|
|
8
|
+
*/
|
|
9
|
+
export type StaticHandler<TRequest = any, TReply = any> = {
|
|
10
|
+
isStatic: true
|
|
11
|
+
handler: (request: TRequest, reply: TReply) => Promise<any>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Dynamic handler result - handler requires a scoped container for resolution.
|
|
16
|
+
* Used when the controller or its dependencies need per-request resolution.
|
|
17
|
+
*/
|
|
18
|
+
export type DynamicHandler<TRequest = any, TReply = any> = {
|
|
19
|
+
isStatic: false
|
|
20
|
+
handler: (
|
|
21
|
+
scoped: ScopedContainer,
|
|
22
|
+
request: TRequest,
|
|
23
|
+
reply: TReply,
|
|
24
|
+
) => Promise<any>
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Handler result returned by provideHandler.
|
|
29
|
+
* Can be either static (pre-resolved) or dynamic (needs scoped container).
|
|
30
|
+
*/
|
|
31
|
+
export type HandlerResult<TRequest = any, TReply = any> =
|
|
32
|
+
| StaticHandler<TRequest, TReply>
|
|
33
|
+
| DynamicHandler<TRequest, TReply>
|
|
34
|
+
|
|
5
35
|
export interface AbstractHttpHandlerAdapterInterface {
|
|
6
36
|
prepareArguments?: (
|
|
7
37
|
handlerMetadata: HandlerMetadata<any>,
|
|
@@ -9,5 +39,5 @@ export interface AbstractHttpHandlerAdapterInterface {
|
|
|
9
39
|
provideHandler: (
|
|
10
40
|
controller: ClassType,
|
|
11
41
|
handlerMetadata: HandlerMetadata<any>,
|
|
12
|
-
) =>
|
|
42
|
+
) => Promise<HandlerResult>
|
|
13
43
|
}
|
|
@@ -138,9 +138,7 @@ describe('Legacy Decorators Type Safety', () => {
|
|
|
138
138
|
// - request.urlParams.userId: string | number
|
|
139
139
|
// - request.params.page: number
|
|
140
140
|
// - request.params.limit: number
|
|
141
|
-
expectTypeOf(request.urlParams.userId).toEqualTypeOf<
|
|
142
|
-
string | number
|
|
143
|
-
>()
|
|
141
|
+
expectTypeOf(request.urlParams.userId).toEqualTypeOf<string>()
|
|
144
142
|
expectTypeOf(request.params.page).toEqualTypeOf<number>()
|
|
145
143
|
expectTypeOf(request.params.limit).toEqualTypeOf<number>()
|
|
146
144
|
return {
|
|
@@ -270,9 +268,7 @@ describe('Legacy Decorators Type Safety', () => {
|
|
|
270
268
|
// - request.urlParams.fileId: string | number
|
|
271
269
|
// - request.params.page: number
|
|
272
270
|
// - request.params.limit: number
|
|
273
|
-
expectTypeOf(request.urlParams.fileId).toEqualTypeOf<
|
|
274
|
-
string | number
|
|
275
|
-
>()
|
|
271
|
+
expectTypeOf(request.urlParams.fileId).toEqualTypeOf<string>()
|
|
276
272
|
expectTypeOf(request.params.page).toEqualTypeOf<number>()
|
|
277
273
|
expectTypeOf(request.params.limit).toEqualTypeOf<number>()
|
|
278
274
|
}
|
|
@@ -92,7 +92,7 @@ export function Endpoint<
|
|
|
92
92
|
// @ts-expect-error - we don't need to type the value
|
|
93
93
|
const result = originalDecorator(typedDescriptor.value, context)
|
|
94
94
|
if (result !== typedDescriptor.value) {
|
|
95
|
-
typedDescriptor.value = result
|
|
95
|
+
typedDescriptor.value = result as any
|
|
96
96
|
}
|
|
97
97
|
return typedDescriptor
|
|
98
98
|
}
|
|
@@ -22,11 +22,11 @@ type MultipartMethodDescriptor<
|
|
|
22
22
|
(
|
|
23
23
|
params: QuerySchema extends ZodObject
|
|
24
24
|
? RequestSchema extends ZodType
|
|
25
|
-
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
|
|
26
|
-
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
25
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
26
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
27
27
|
: RequestSchema extends ZodType
|
|
28
|
-
? EndpointFunctionArgs<Url, undefined, RequestSchema>
|
|
29
|
-
: EndpointFunctionArgs<Url, undefined, undefined>,
|
|
28
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
29
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>,
|
|
30
30
|
) => Promise<z.input<ResponseSchema>>
|
|
31
31
|
>
|
|
32
32
|
|
|
@@ -86,7 +86,7 @@ export function Multipart<
|
|
|
86
86
|
// @ts-expect-error - we don't need to type the value
|
|
87
87
|
const result = originalDecorator(descriptor.value, context)
|
|
88
88
|
if (result !== descriptor.value) {
|
|
89
|
-
descriptor.value = result
|
|
89
|
+
descriptor.value = result as any
|
|
90
90
|
}
|
|
91
91
|
return descriptor
|
|
92
92
|
}
|
|
@@ -21,11 +21,11 @@ type StreamMethodDescriptor<
|
|
|
21
21
|
(
|
|
22
22
|
params: QuerySchema extends ZodObject
|
|
23
23
|
? RequestSchema extends ZodType
|
|
24
|
-
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
|
|
25
|
-
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
24
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema, true>
|
|
25
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined, true>
|
|
26
26
|
: RequestSchema extends ZodType
|
|
27
|
-
? EndpointFunctionArgs<Url, undefined, RequestSchema>
|
|
28
|
-
: EndpointFunctionArgs<Url, undefined, undefined>,
|
|
27
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema, true>
|
|
28
|
+
: EndpointFunctionArgs<Url, undefined, undefined, true>,
|
|
29
29
|
reply: any,
|
|
30
30
|
) => Promise<void>
|
|
31
31
|
>
|
|
@@ -69,7 +69,7 @@ export function Stream<
|
|
|
69
69
|
// @ts-expect-error - we don't need to type the value
|
|
70
70
|
const result = originalDecorator(descriptor.value, context)
|
|
71
71
|
if (result !== descriptor.value) {
|
|
72
|
-
descriptor.value = result
|
|
72
|
+
descriptor.value = result as any
|
|
73
73
|
}
|
|
74
74
|
return descriptor
|
|
75
75
|
}
|
|
@@ -60,8 +60,6 @@ export class LoggerInstance implements LoggerService {
|
|
|
60
60
|
optionalParams = this.context
|
|
61
61
|
? optionalParams.concat(this.context)
|
|
62
62
|
: optionalParams
|
|
63
|
-
console.log('log', message, optionalParams)
|
|
64
|
-
console.log('localInstance', this.localInstance)
|
|
65
63
|
this.localInstance?.log(message, ...optionalParams)
|
|
66
64
|
}
|
|
67
65
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ClassTypeWithInstance } from '@navios/di'
|
|
1
|
+
import type { ClassTypeWithInstance, Registry } from '@navios/di'
|
|
2
2
|
|
|
3
3
|
import { Container, inject, Injectable } from '@navios/di'
|
|
4
4
|
|
|
@@ -19,9 +19,9 @@ import { ModuleLoaderService } from './services/index.mjs'
|
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* Options for configuring the Navios application context.
|
|
22
|
-
* These options control
|
|
22
|
+
* These options control the application configuration.
|
|
23
23
|
*/
|
|
24
|
-
export interface
|
|
24
|
+
export interface NaviosApplicationOptions {
|
|
25
25
|
/**
|
|
26
26
|
* Specifies the logger to use. Pass `false` to turn off logging.
|
|
27
27
|
*
|
|
@@ -31,18 +31,18 @@ export interface NaviosApplicationContextOptions {
|
|
|
31
31
|
*/
|
|
32
32
|
logger?: LoggerService | LogLevel[] | false
|
|
33
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Specifies a custom registry to use. Useful for testing.
|
|
36
|
+
* If not provided, a new Registry will be created.
|
|
37
|
+
*/
|
|
38
|
+
registry?: Registry
|
|
39
|
+
|
|
34
40
|
/**
|
|
35
41
|
* Specifies a custom container to use. Useful for testing.
|
|
36
42
|
* If not provided, a new Container will be created.
|
|
37
43
|
*/
|
|
38
44
|
container?: Container
|
|
39
|
-
}
|
|
40
45
|
|
|
41
|
-
/**
|
|
42
|
-
* Complete options for creating a Navios application.
|
|
43
|
-
* Extends NaviosApplicationContextOptions with adapter configuration.
|
|
44
|
-
*/
|
|
45
|
-
export interface NaviosApplicationOptions extends NaviosApplicationContextOptions {
|
|
46
46
|
/**
|
|
47
47
|
* HTTP adapter environment(s) to use for the application.
|
|
48
48
|
* Can be a single adapter or an array of adapters.
|
|
@@ -55,6 +55,20 @@ export interface NaviosApplicationOptions extends NaviosApplicationContextOption
|
|
|
55
55
|
* ```
|
|
56
56
|
*/
|
|
57
57
|
adapter: NaviosEnvironmentOptions | NaviosEnvironmentOptions[]
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Whether to validate response schemas.
|
|
61
|
+
* When `false`, response schema validation is skipped for better performance.
|
|
62
|
+
* @default true
|
|
63
|
+
*/
|
|
64
|
+
validateResponses?: boolean
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Whether to enable request ID propagation via AsyncLocalStorage.
|
|
68
|
+
* When `true`, request IDs are available via `getRequestId()` throughout the request.
|
|
69
|
+
* @default false
|
|
70
|
+
*/
|
|
71
|
+
enableRequestId?: boolean
|
|
58
72
|
}
|
|
59
73
|
|
|
60
74
|
/**
|
|
@@ -17,7 +17,9 @@ export class NaviosEnvironment {
|
|
|
17
17
|
setupHttpEnvironment(
|
|
18
18
|
tokens: Map<InjectionToken<any, undefined>, AnyInjectableType>,
|
|
19
19
|
) {
|
|
20
|
-
|
|
20
|
+
for (const [token, value] of tokens) {
|
|
21
|
+
this.httpTokens.set(token, value)
|
|
22
|
+
}
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
getHttpToken(token: InjectionToken<any, undefined>) {
|
package/src/navios.factory.mts
CHANGED
|
@@ -4,17 +4,16 @@ import type {
|
|
|
4
4
|
InjectionToken,
|
|
5
5
|
} from '@navios/di'
|
|
6
6
|
|
|
7
|
-
import { Container
|
|
7
|
+
import { Container } from '@navios/di'
|
|
8
8
|
|
|
9
9
|
import type { NaviosModule } from './interfaces/index.mjs'
|
|
10
|
-
import type {
|
|
11
|
-
NaviosApplicationContextOptions,
|
|
12
|
-
NaviosApplicationOptions,
|
|
13
|
-
} from './navios.application.mjs'
|
|
10
|
+
import type { NaviosApplicationOptions } from './navios.application.mjs'
|
|
14
11
|
|
|
15
12
|
import { ConsoleLogger, isNil, LoggerOutput } from './logger/index.mjs'
|
|
16
13
|
import { NaviosApplication } from './navios.application.mjs'
|
|
17
14
|
import { NaviosEnvironment } from './navios.environment.mjs'
|
|
15
|
+
import { setRequestIdEnabled } from './stores/index.mjs'
|
|
16
|
+
import { NaviosOptionsToken } from './tokens/index.mjs'
|
|
18
17
|
|
|
19
18
|
/**
|
|
20
19
|
* Factory class for creating and configuring Navios applications.
|
|
@@ -81,7 +80,16 @@ export class NaviosFactory {
|
|
|
81
80
|
adapter: [],
|
|
82
81
|
},
|
|
83
82
|
) {
|
|
84
|
-
const container = options.container ?? new Container()
|
|
83
|
+
const container = options.container ?? new Container(options.registry)
|
|
84
|
+
|
|
85
|
+
// Set request ID flag early, before any adapters are registered
|
|
86
|
+
if (options.enableRequestId === true) {
|
|
87
|
+
setRequestIdEnabled(true)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Store options in container for DI access by adapters
|
|
91
|
+
container.addInstance(NaviosOptionsToken, options)
|
|
92
|
+
|
|
85
93
|
await this.registerLoggerConfiguration(container, options)
|
|
86
94
|
const adapters = Array.isArray(options.adapter)
|
|
87
95
|
? options.adapter
|
|
@@ -109,28 +117,21 @@ export class NaviosFactory {
|
|
|
109
117
|
|
|
110
118
|
private static async registerLoggerConfiguration(
|
|
111
119
|
container: Container,
|
|
112
|
-
options:
|
|
120
|
+
options: NaviosApplicationOptions,
|
|
113
121
|
) {
|
|
114
122
|
const { logger } = options
|
|
115
|
-
if (Array.isArray(logger) || isNil(logger)) {
|
|
123
|
+
if (Array.isArray(logger) || isNil(logger) || options.enableRequestId) {
|
|
116
124
|
const loggerInstance = (await container.get(
|
|
117
125
|
LoggerOutput,
|
|
118
126
|
)) as ConsoleLogger
|
|
119
127
|
loggerInstance?.setup({
|
|
120
|
-
logLevels: logger,
|
|
128
|
+
logLevels: Array.isArray(logger) ? logger : undefined,
|
|
129
|
+
requestId: options.enableRequestId ?? false,
|
|
121
130
|
})
|
|
122
131
|
return
|
|
123
132
|
}
|
|
124
133
|
if ((logger as boolean) !== true && !isNil(logger)) {
|
|
125
|
-
container
|
|
126
|
-
.getServiceLocator()
|
|
127
|
-
.getManager()
|
|
128
|
-
.storeCreatedHolder(
|
|
129
|
-
LoggerOutput.toString(),
|
|
130
|
-
logger,
|
|
131
|
-
InjectableType.Class,
|
|
132
|
-
InjectableScope.Singleton,
|
|
133
|
-
)
|
|
134
|
+
container.addInstance(LoggerOutput, logger)
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
}
|
|
@@ -20,6 +20,11 @@ export class GuardRunnerService {
|
|
|
20
20
|
private readonly logger = inject(Logger, {
|
|
21
21
|
context: GuardRunnerService.name,
|
|
22
22
|
})
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Runs guards that need to be resolved from a scoped container.
|
|
26
|
+
* Use this when guards have request-scoped dependencies.
|
|
27
|
+
*/
|
|
23
28
|
async runGuards(
|
|
24
29
|
allGuards: Set<
|
|
25
30
|
| ClassTypeWithInstance<CanActivate>
|
|
@@ -28,16 +33,48 @@ export class GuardRunnerService {
|
|
|
28
33
|
executionContext: AbstractExecutionContext,
|
|
29
34
|
context: ScopedContainer,
|
|
30
35
|
) {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
// Reverse order: module guards run first, then controller, then endpoint
|
|
37
|
+
const guardsArray = Array.from(allGuards).reverse()
|
|
38
|
+
|
|
39
|
+
// Resolve all guards in parallel
|
|
40
|
+
const guardInstances = await Promise.all(
|
|
41
|
+
guardsArray.map(async (guard) => {
|
|
42
|
+
const guardInstance = await context.get(
|
|
43
|
+
guard as InjectionToken<CanActivate, undefined>,
|
|
39
44
|
)
|
|
40
|
-
|
|
45
|
+
if (!guardInstance.canActivate) {
|
|
46
|
+
throw new Error(
|
|
47
|
+
`[Navios] Guard ${guard.name as string} does not implement canActivate()`,
|
|
48
|
+
)
|
|
49
|
+
}
|
|
50
|
+
return guardInstance
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return this.executeGuards(guardInstances, executionContext)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Runs pre-resolved guard instances.
|
|
59
|
+
* Use this when all guards are singletons and have been pre-resolved at startup.
|
|
60
|
+
*/
|
|
61
|
+
async runGuardsStatic(
|
|
62
|
+
guardInstances: CanActivate[],
|
|
63
|
+
executionContext: AbstractExecutionContext,
|
|
64
|
+
) {
|
|
65
|
+
return this.executeGuards(guardInstances, executionContext)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Shared guard execution logic.
|
|
70
|
+
* Iterates through guard instances and calls canActivate on each.
|
|
71
|
+
*/
|
|
72
|
+
private async executeGuards(
|
|
73
|
+
guardInstances: CanActivate[],
|
|
74
|
+
executionContext: AbstractExecutionContext,
|
|
75
|
+
): Promise<boolean> {
|
|
76
|
+
let canActivate = true
|
|
77
|
+
for (const guardInstance of guardInstances) {
|
|
41
78
|
try {
|
|
42
79
|
canActivate = await guardInstance.canActivate(executionContext)
|
|
43
80
|
if (!canActivate) {
|
package/src/services/index.mts
CHANGED