@navios/core 0.1.8 → 0.1.10
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/dist/_tsup-dts-rollup.d.mts +46 -2
- package/dist/_tsup-dts-rollup.d.ts +46 -2
- package/dist/chunk-Z2AVZ4BT.mjs +65 -0
- package/dist/index.d.mts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +3346 -16
- package/dist/index.mjs +219 -52
- package/dist/multipart-23QO76VV.mjs +3120 -0
- package/package.json +4 -3
- package/src/decorators/endpoint.decorator.mts +1 -1
- package/src/decorators/header.decorator.mts +7 -1
- package/src/decorators/http-code.decorator.mts +6 -1
- package/src/decorators/index.mts +2 -0
- package/src/decorators/multipart.decorator.mts +100 -0
- package/src/decorators/stream.decorator.mts +81 -0
- package/src/metadata/endpoint.metadata.mts +9 -3
- package/src/metadata/module.metadata.mts +1 -1
- package/src/navios.application.mts +30 -0
- package/src/services/controller-adapter.service.mts +130 -3
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@navios/core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "Oleksandr Hanzha",
|
|
6
6
|
"email": "alex@granted.name"
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"main": "./dist/index.js",
|
|
16
16
|
"module": "./dist/index.mjs",
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@navios/common": "^0.1.
|
|
18
|
+
"@navios/common": "^0.1.3",
|
|
19
19
|
"zod": "^3.23.8"
|
|
20
20
|
},
|
|
21
21
|
"exports": {
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"./package.json": "./package.json"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@
|
|
35
|
+
"@fastify/multipart": "^9.0.3",
|
|
36
|
+
"@navios/common": "^0.1.3",
|
|
36
37
|
"tsx": "^4.19.4",
|
|
37
38
|
"typescript": "^5.8.3",
|
|
38
39
|
"zod": "^3.24.4"
|
|
@@ -90,7 +90,7 @@ export function Endpoint<
|
|
|
90
90
|
}
|
|
91
91
|
// @ts-expect-error We don't need to set correctly in the metadata
|
|
92
92
|
endpointMetadata.config = config
|
|
93
|
-
endpointMetadata.type = EndpointType.
|
|
93
|
+
endpointMetadata.type = EndpointType.Endpoint
|
|
94
94
|
endpointMetadata.classMethod = target.name
|
|
95
95
|
endpointMetadata.httpMethod = config.method
|
|
96
96
|
endpointMetadata.url = config.url
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { HttpHeader } from 'fastify/types/utils.js'
|
|
2
2
|
|
|
3
|
-
import { getEndpointMetadata } from '../metadata/index.mjs'
|
|
3
|
+
import { EndpointType, getEndpointMetadata } from '../metadata/index.mjs'
|
|
4
4
|
|
|
5
5
|
export function Header(name: HttpHeader, value: string | number | string[]) {
|
|
6
6
|
return <T extends Function>(
|
|
@@ -11,6 +11,12 @@ export function Header(name: HttpHeader, value: string | number | string[]) {
|
|
|
11
11
|
throw new Error('[Navios] Header decorator can only be used on methods.')
|
|
12
12
|
}
|
|
13
13
|
const metadata = getEndpointMetadata(target, context)
|
|
14
|
+
if (metadata.type === EndpointType.Stream) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
'[Navios] HttpCode decorator cannot be used on stream endpoints.',
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
metadata.headers[name] = value
|
|
15
21
|
|
|
16
22
|
return target
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getEndpointMetadata } from '../metadata/index.mjs'
|
|
1
|
+
import { EndpointType, getEndpointMetadata } from '../metadata/index.mjs'
|
|
2
2
|
|
|
3
3
|
export function HttpCode(code: number) {
|
|
4
4
|
return <T extends Function>(
|
|
@@ -11,6 +11,11 @@ export function HttpCode(code: number) {
|
|
|
11
11
|
)
|
|
12
12
|
}
|
|
13
13
|
const metadata = getEndpointMetadata(target, context)
|
|
14
|
+
if (metadata.type === EndpointType.Stream) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
'[Navios] HttpCode decorator cannot be used on stream endpoints.',
|
|
17
|
+
)
|
|
18
|
+
}
|
|
14
19
|
metadata.successStatusCode = code
|
|
15
20
|
|
|
16
21
|
return target
|
package/src/decorators/index.mts
CHANGED
|
@@ -3,4 +3,6 @@ export * from './endpoint.decorator.mjs'
|
|
|
3
3
|
export * from './header.decorator.mjs'
|
|
4
4
|
export * from './http-code.decorator.mjs'
|
|
5
5
|
export * from './module.decorator.mjs'
|
|
6
|
+
export * from './multipart.decorator.mjs'
|
|
7
|
+
export * from './stream.decorator.mjs'
|
|
6
8
|
export * from './use-guards.decorator.mjs'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BaseEndpointConfig,
|
|
3
|
+
EndpointFunctionArgs,
|
|
4
|
+
HttpMethod,
|
|
5
|
+
} from '@navios/common'
|
|
6
|
+
import type { AnyZodObject, z, ZodType } from 'zod'
|
|
7
|
+
|
|
8
|
+
import { ZodDiscriminatedUnion } from 'zod'
|
|
9
|
+
|
|
10
|
+
import { EndpointType, getEndpointMetadata } from '../metadata/index.mjs'
|
|
11
|
+
|
|
12
|
+
export type MultipartParams<
|
|
13
|
+
EndpointDeclaration extends {
|
|
14
|
+
config: BaseEndpointConfig<any, any, any, any, any>
|
|
15
|
+
},
|
|
16
|
+
Url extends string = EndpointDeclaration['config']['url'],
|
|
17
|
+
QuerySchema = EndpointDeclaration['config']['querySchema'],
|
|
18
|
+
> = QuerySchema extends AnyZodObject
|
|
19
|
+
? EndpointDeclaration['config']['requestSchema'] extends ZodType
|
|
20
|
+
? EndpointFunctionArgs<
|
|
21
|
+
Url,
|
|
22
|
+
QuerySchema,
|
|
23
|
+
EndpointDeclaration['config']['requestSchema']
|
|
24
|
+
>
|
|
25
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
26
|
+
: EndpointDeclaration['config']['requestSchema'] extends ZodType
|
|
27
|
+
? EndpointFunctionArgs<
|
|
28
|
+
Url,
|
|
29
|
+
undefined,
|
|
30
|
+
EndpointDeclaration['config']['requestSchema']
|
|
31
|
+
>
|
|
32
|
+
: EndpointFunctionArgs<Url, undefined, undefined>
|
|
33
|
+
|
|
34
|
+
export type MultipartResult<
|
|
35
|
+
EndpointDeclaration extends {
|
|
36
|
+
config: BaseEndpointConfig<any, any, any, any, any>
|
|
37
|
+
},
|
|
38
|
+
> =
|
|
39
|
+
EndpointDeclaration['config']['responseSchema'] extends ZodDiscriminatedUnion<
|
|
40
|
+
any,
|
|
41
|
+
infer Options
|
|
42
|
+
>
|
|
43
|
+
? Promise<z.input<Options[number]>>
|
|
44
|
+
: Promise<z.input<EndpointDeclaration['config']['responseSchema']>>
|
|
45
|
+
|
|
46
|
+
export function Multipart<
|
|
47
|
+
Method extends HttpMethod = HttpMethod,
|
|
48
|
+
Url extends string = string,
|
|
49
|
+
QuerySchema = undefined,
|
|
50
|
+
ResponseSchema extends ZodType = ZodType,
|
|
51
|
+
RequestSchema = ZodType,
|
|
52
|
+
>(endpoint: {
|
|
53
|
+
config: BaseEndpointConfig<
|
|
54
|
+
Method,
|
|
55
|
+
Url,
|
|
56
|
+
QuerySchema,
|
|
57
|
+
ResponseSchema,
|
|
58
|
+
RequestSchema
|
|
59
|
+
>
|
|
60
|
+
}) {
|
|
61
|
+
return (
|
|
62
|
+
target: (
|
|
63
|
+
params: QuerySchema extends AnyZodObject
|
|
64
|
+
? RequestSchema extends ZodType
|
|
65
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
|
|
66
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
67
|
+
: RequestSchema extends ZodType
|
|
68
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema>
|
|
69
|
+
: EndpointFunctionArgs<Url, undefined, undefined>,
|
|
70
|
+
) => Promise<z.input<ResponseSchema>>,
|
|
71
|
+
context: ClassMethodDecoratorContext,
|
|
72
|
+
) => {
|
|
73
|
+
if (typeof target !== 'function') {
|
|
74
|
+
throw new Error(
|
|
75
|
+
'[Navios] Endpoint decorator can only be used on functions.',
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
if (context.kind !== 'method') {
|
|
79
|
+
throw new Error(
|
|
80
|
+
'[Navios] Endpoint decorator can only be used on methods.',
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
const config = endpoint.config
|
|
84
|
+
if (context.metadata) {
|
|
85
|
+
let endpointMetadata = getEndpointMetadata(target, context)
|
|
86
|
+
if (endpointMetadata.config && endpointMetadata.config.url) {
|
|
87
|
+
throw new Error(
|
|
88
|
+
`[Navios] Endpoint ${config.method} ${config.url} already exists. Please use a different method or url.`,
|
|
89
|
+
)
|
|
90
|
+
}
|
|
91
|
+
// @ts-expect-error We don't need to set correctly in the metadata
|
|
92
|
+
endpointMetadata.config = config
|
|
93
|
+
endpointMetadata.type = EndpointType.Multipart
|
|
94
|
+
endpointMetadata.classMethod = target.name
|
|
95
|
+
endpointMetadata.httpMethod = config.method
|
|
96
|
+
endpointMetadata.url = config.url
|
|
97
|
+
}
|
|
98
|
+
return target
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
BaseStreamConfig,
|
|
3
|
+
EndpointFunctionArgs,
|
|
4
|
+
HttpMethod,
|
|
5
|
+
} from '@navios/common'
|
|
6
|
+
import type { FastifyReply } from 'fastify'
|
|
7
|
+
import type { AnyZodObject, ZodType } from 'zod'
|
|
8
|
+
|
|
9
|
+
import { EndpointType, getEndpointMetadata } from '../metadata/index.mjs'
|
|
10
|
+
|
|
11
|
+
export type StreamParams<
|
|
12
|
+
EndpointDeclaration extends {
|
|
13
|
+
config: BaseStreamConfig<any, any, any, any>
|
|
14
|
+
},
|
|
15
|
+
Url extends string = EndpointDeclaration['config']['url'],
|
|
16
|
+
QuerySchema = EndpointDeclaration['config']['querySchema'],
|
|
17
|
+
> = QuerySchema extends AnyZodObject
|
|
18
|
+
? EndpointDeclaration['config']['requestSchema'] extends ZodType
|
|
19
|
+
? EndpointFunctionArgs<
|
|
20
|
+
Url,
|
|
21
|
+
QuerySchema,
|
|
22
|
+
EndpointDeclaration['config']['requestSchema']
|
|
23
|
+
>
|
|
24
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
25
|
+
: EndpointDeclaration['config']['requestSchema'] extends ZodType
|
|
26
|
+
? EndpointFunctionArgs<
|
|
27
|
+
Url,
|
|
28
|
+
undefined,
|
|
29
|
+
EndpointDeclaration['config']['requestSchema']
|
|
30
|
+
>
|
|
31
|
+
: EndpointFunctionArgs<Url, undefined, undefined>
|
|
32
|
+
|
|
33
|
+
export function Stream<
|
|
34
|
+
Method extends HttpMethod = HttpMethod,
|
|
35
|
+
Url extends string = string,
|
|
36
|
+
QuerySchema = undefined,
|
|
37
|
+
RequestSchema = ZodType,
|
|
38
|
+
>(endpoint: {
|
|
39
|
+
config: BaseStreamConfig<Method, Url, QuerySchema, RequestSchema>
|
|
40
|
+
}) {
|
|
41
|
+
return (
|
|
42
|
+
target: (
|
|
43
|
+
params: QuerySchema extends AnyZodObject
|
|
44
|
+
? RequestSchema extends ZodType
|
|
45
|
+
? EndpointFunctionArgs<Url, QuerySchema, RequestSchema>
|
|
46
|
+
: EndpointFunctionArgs<Url, QuerySchema, undefined>
|
|
47
|
+
: RequestSchema extends ZodType
|
|
48
|
+
? EndpointFunctionArgs<Url, undefined, RequestSchema>
|
|
49
|
+
: EndpointFunctionArgs<Url, undefined, undefined>,
|
|
50
|
+
reply: FastifyReply,
|
|
51
|
+
) => Promise<void>,
|
|
52
|
+
context: ClassMethodDecoratorContext,
|
|
53
|
+
) => {
|
|
54
|
+
if (typeof target !== 'function') {
|
|
55
|
+
throw new Error(
|
|
56
|
+
'[Navios] Endpoint decorator can only be used on functions.',
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
if (context.kind !== 'method') {
|
|
60
|
+
throw new Error(
|
|
61
|
+
'[Navios] Endpoint decorator can only be used on methods.',
|
|
62
|
+
)
|
|
63
|
+
}
|
|
64
|
+
const config = endpoint.config
|
|
65
|
+
if (context.metadata) {
|
|
66
|
+
let endpointMetadata = getEndpointMetadata(target, context)
|
|
67
|
+
if (endpointMetadata.config && endpointMetadata.config.url) {
|
|
68
|
+
throw new Error(
|
|
69
|
+
`[Navios] Endpoint ${config.method} ${config.url} already exists. Please use a different method or url.`,
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
// @ts-expect-error We don't need to set correctly in the metadata
|
|
73
|
+
endpointMetadata.config = config
|
|
74
|
+
endpointMetadata.type = EndpointType.Stream
|
|
75
|
+
endpointMetadata.classMethod = target.name
|
|
76
|
+
endpointMetadata.httpMethod = config.method
|
|
77
|
+
endpointMetadata.url = config.url
|
|
78
|
+
}
|
|
79
|
+
return target
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BaseEndpointConfig,
|
|
3
|
+
BaseStreamConfig,
|
|
4
|
+
HttpMethod,
|
|
5
|
+
} from '@navios/common'
|
|
2
6
|
import type { HttpHeader } from 'fastify/types/utils.js'
|
|
3
7
|
|
|
4
8
|
import type { CanActivate } from '../interfaces/index.mjs'
|
|
@@ -11,7 +15,9 @@ export const EndpointMetadataKey = Symbol('EndpointMetadataKey')
|
|
|
11
15
|
|
|
12
16
|
export enum EndpointType {
|
|
13
17
|
Unknown = 'unknown',
|
|
14
|
-
|
|
18
|
+
Endpoint = 'endpoint',
|
|
19
|
+
Stream = 'stream',
|
|
20
|
+
Multipart = 'multipart',
|
|
15
21
|
Handler = 'handler',
|
|
16
22
|
}
|
|
17
23
|
|
|
@@ -22,7 +28,7 @@ export interface EndpointMetadata {
|
|
|
22
28
|
type: EndpointType
|
|
23
29
|
headers: Partial<Record<HttpHeader, number | string | string[] | undefined>>
|
|
24
30
|
httpMethod: HttpMethod
|
|
25
|
-
config: BaseEndpointConfig | null
|
|
31
|
+
config: BaseEndpointConfig | BaseStreamConfig | null
|
|
26
32
|
guards: Set<
|
|
27
33
|
ClassTypeWithInstance<CanActivate> | InjectionToken<CanActivate, undefined>
|
|
28
34
|
>
|
|
@@ -50,7 +50,7 @@ export function extractModuleMetadata(target: ClassType): ModuleMetadata {
|
|
|
50
50
|
const metadata = target[ModuleMetadataKey] as ModuleMetadata | undefined
|
|
51
51
|
if (!metadata) {
|
|
52
52
|
throw new Error(
|
|
53
|
-
|
|
53
|
+
`[Navios] Module metadata not found for ${target.name}. Make sure to use @Module decorator.`,
|
|
54
54
|
)
|
|
55
55
|
}
|
|
56
56
|
return metadata
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { FastifyCorsOptions } from '@fastify/cors'
|
|
2
|
+
import type { FastifyMultipartOptions } from '@fastify/multipart'
|
|
2
3
|
import type {
|
|
3
4
|
FastifyInstance,
|
|
4
5
|
FastifyListenOptions,
|
|
@@ -50,6 +51,7 @@ export class NaviosApplication {
|
|
|
50
51
|
})
|
|
51
52
|
private server: FastifyInstance | null = null
|
|
52
53
|
private corsOptions: FastifyCorsOptions | null = null
|
|
54
|
+
private multipartOptions: FastifyMultipartOptions | true | null = null
|
|
53
55
|
private globalPrefix: string | null = null
|
|
54
56
|
|
|
55
57
|
private appModule: ClassTypeWithInstance<NaviosModule> | null = null
|
|
@@ -81,6 +83,10 @@ export class NaviosApplication {
|
|
|
81
83
|
await this.server.register(cors, this.corsOptions)
|
|
82
84
|
}
|
|
83
85
|
|
|
86
|
+
if (this.multipartOptions) {
|
|
87
|
+
await this.configureMultipart(this.server, this.multipartOptions)
|
|
88
|
+
}
|
|
89
|
+
|
|
84
90
|
await this.initModules()
|
|
85
91
|
await this.server.ready()
|
|
86
92
|
|
|
@@ -147,6 +153,26 @@ export class NaviosApplication {
|
|
|
147
153
|
})
|
|
148
154
|
}
|
|
149
155
|
|
|
156
|
+
async configureMultipart(
|
|
157
|
+
server: FastifyInstance,
|
|
158
|
+
options: FastifyMultipartOptions | true,
|
|
159
|
+
): Promise<void> {
|
|
160
|
+
if (options) {
|
|
161
|
+
try {
|
|
162
|
+
const multipartModule = await import('@fastify/multipart')
|
|
163
|
+
await server.register(
|
|
164
|
+
multipartModule.default,
|
|
165
|
+
typeof options === 'object' ? options : {},
|
|
166
|
+
)
|
|
167
|
+
} catch (error) {
|
|
168
|
+
this.logger.error(
|
|
169
|
+
`@fastify/multipart is not installed. Please install it.`,
|
|
170
|
+
)
|
|
171
|
+
throw error
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
150
176
|
private async initModules() {
|
|
151
177
|
const modules = this.moduleLoader.getAllModules()
|
|
152
178
|
const promises: PromiseLike<any>[] = []
|
|
@@ -183,6 +209,10 @@ export class NaviosApplication {
|
|
|
183
209
|
this.corsOptions = options
|
|
184
210
|
}
|
|
185
211
|
|
|
212
|
+
enableMultipart(options: FastifyMultipartOptions) {
|
|
213
|
+
this.multipartOptions = options
|
|
214
|
+
}
|
|
215
|
+
|
|
186
216
|
setGlobalPrefix(prefix: string) {
|
|
187
217
|
this.globalPrefix = prefix
|
|
188
218
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import type { BaseEndpointConfig } from '@navios/common'
|
|
1
2
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
|
|
2
3
|
import type { ZodTypeProvider } from 'fastify-type-provider-zod'
|
|
4
|
+
import type { AnyZodObject } from 'zod'
|
|
3
5
|
|
|
4
6
|
import { NaviosException } from '@navios/common'
|
|
5
7
|
|
|
8
|
+
import { ZodArray } from 'zod'
|
|
9
|
+
|
|
6
10
|
import type { EndpointMetadata, ModuleMetadata } from '../metadata/index.mjs'
|
|
7
11
|
import type { ClassType } from '../service-locator/index.mjs'
|
|
8
12
|
|
|
@@ -94,12 +98,12 @@ export class ControllerAdapterService {
|
|
|
94
98
|
return {}
|
|
95
99
|
}
|
|
96
100
|
const { querySchema, requestSchema, responseSchema } =
|
|
97
|
-
endpointMetadata.config
|
|
101
|
+
endpointMetadata.config as BaseEndpointConfig
|
|
98
102
|
const schema: Record<string, any> = {}
|
|
99
103
|
if (querySchema) {
|
|
100
104
|
schema.querystring = querySchema
|
|
101
105
|
}
|
|
102
|
-
if (requestSchema) {
|
|
106
|
+
if (requestSchema && endpointMetadata.type !== EndpointType.Multipart) {
|
|
103
107
|
schema.body = requestSchema
|
|
104
108
|
}
|
|
105
109
|
if (responseSchema) {
|
|
@@ -122,12 +126,24 @@ export class ControllerAdapterService {
|
|
|
122
126
|
`Unknown endpoint type ${endpointMetadata.type} for ${controller.name}:${endpointMetadata.classMethod}`,
|
|
123
127
|
)
|
|
124
128
|
throw new NaviosException('Unknown endpoint type')
|
|
125
|
-
case EndpointType.
|
|
129
|
+
case EndpointType.Endpoint:
|
|
126
130
|
return this.provideHandlerForConfig(
|
|
127
131
|
controller,
|
|
128
132
|
executionContext,
|
|
129
133
|
endpointMetadata,
|
|
130
134
|
)
|
|
135
|
+
case EndpointType.Stream:
|
|
136
|
+
return this.provideHandlerForStream(
|
|
137
|
+
controller,
|
|
138
|
+
executionContext,
|
|
139
|
+
endpointMetadata,
|
|
140
|
+
)
|
|
141
|
+
case EndpointType.Multipart:
|
|
142
|
+
return this.provideHandlerForMultipart(
|
|
143
|
+
controller,
|
|
144
|
+
executionContext,
|
|
145
|
+
endpointMetadata,
|
|
146
|
+
)
|
|
131
147
|
case EndpointType.Handler:
|
|
132
148
|
this.logger.error('Not implemented yet')
|
|
133
149
|
throw new NaviosException('Not implemented yet')
|
|
@@ -174,4 +190,115 @@ export class ControllerAdapterService {
|
|
|
174
190
|
}
|
|
175
191
|
}
|
|
176
192
|
}
|
|
193
|
+
|
|
194
|
+
private provideHandlerForStream(
|
|
195
|
+
controller: ClassType,
|
|
196
|
+
executionContext: ExecutionContext,
|
|
197
|
+
endpointMetadata: EndpointMetadata,
|
|
198
|
+
): (request: FastifyRequest, reply: FastifyReply) => Promise<void> {
|
|
199
|
+
return async (request, reply) => {
|
|
200
|
+
getServiceLocator().registerInstance(Request, request)
|
|
201
|
+
getServiceLocator().registerInstance(Reply, reply)
|
|
202
|
+
getServiceLocator().registerInstance(
|
|
203
|
+
ExecutionContextToken,
|
|
204
|
+
executionContext,
|
|
205
|
+
)
|
|
206
|
+
executionContext.provideRequest(request)
|
|
207
|
+
executionContext.provideReply(reply)
|
|
208
|
+
const controllerInstance = await inject(controller)
|
|
209
|
+
try {
|
|
210
|
+
const { query, params, body } = request
|
|
211
|
+
const argument: Record<string, any> = {}
|
|
212
|
+
if (query && Object.keys(query).length > 0) {
|
|
213
|
+
argument.params = query
|
|
214
|
+
}
|
|
215
|
+
if (params && Object.keys(params).length > 0) {
|
|
216
|
+
argument.urlParams = params
|
|
217
|
+
}
|
|
218
|
+
if (body) {
|
|
219
|
+
argument.data = body
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await controllerInstance[endpointMetadata.classMethod](argument, reply)
|
|
223
|
+
} finally {
|
|
224
|
+
getServiceLocator().removeInstance(Request)
|
|
225
|
+
getServiceLocator().removeInstance(Reply)
|
|
226
|
+
getServiceLocator().removeInstance(ExecutionContextToken)
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
private provideHandlerForMultipart(
|
|
232
|
+
controller: ClassType,
|
|
233
|
+
executionContext: ExecutionContext,
|
|
234
|
+
endpointMetadata: EndpointMetadata,
|
|
235
|
+
): (request: FastifyRequest, reply: FastifyReply) => Promise<void> {
|
|
236
|
+
const config = endpointMetadata.config as BaseEndpointConfig
|
|
237
|
+
const requestSchema = config.requestSchema as unknown as AnyZodObject
|
|
238
|
+
const shape = requestSchema._def.shape()
|
|
239
|
+
return async (request, reply) => {
|
|
240
|
+
getServiceLocator().registerInstance(Request, request)
|
|
241
|
+
getServiceLocator().registerInstance(Reply, reply)
|
|
242
|
+
getServiceLocator().registerInstance(
|
|
243
|
+
ExecutionContextToken,
|
|
244
|
+
executionContext,
|
|
245
|
+
)
|
|
246
|
+
executionContext.provideRequest(request)
|
|
247
|
+
executionContext.provideReply(reply)
|
|
248
|
+
const controllerInstance = await inject(controller)
|
|
249
|
+
try {
|
|
250
|
+
const parts = request.parts()
|
|
251
|
+
const { query, params } = request
|
|
252
|
+
const argument: Record<string, any> = {}
|
|
253
|
+
if (query && Object.keys(query).length > 0) {
|
|
254
|
+
argument.params = query
|
|
255
|
+
}
|
|
256
|
+
if (params && Object.keys(params).length > 0) {
|
|
257
|
+
argument.urlParams = params
|
|
258
|
+
}
|
|
259
|
+
const req: Record<string, any> = {}
|
|
260
|
+
for await (const part of parts) {
|
|
261
|
+
if (!shape[part.fieldname]) {
|
|
262
|
+
throw new NaviosException(
|
|
263
|
+
`Invalid field name ${part.fieldname} for multipart request`,
|
|
264
|
+
)
|
|
265
|
+
}
|
|
266
|
+
const schema = shape[part.fieldname]
|
|
267
|
+
if (part.type === 'file') {
|
|
268
|
+
const file = new File([await part.toBuffer()], part.filename, {
|
|
269
|
+
type: part.mimetype,
|
|
270
|
+
})
|
|
271
|
+
if (schema instanceof ZodArray) {
|
|
272
|
+
if (!req[part.fieldname]) {
|
|
273
|
+
req[part.fieldname] = []
|
|
274
|
+
}
|
|
275
|
+
req[part.fieldname].push(file)
|
|
276
|
+
} else {
|
|
277
|
+
req[part.fieldname] = file
|
|
278
|
+
}
|
|
279
|
+
} else {
|
|
280
|
+
if (schema instanceof ZodArray) {
|
|
281
|
+
if (!req[part.fieldname]) {
|
|
282
|
+
req[part.fieldname] = []
|
|
283
|
+
}
|
|
284
|
+
req[part.fieldname].push(part.value)
|
|
285
|
+
} else {
|
|
286
|
+
req[part.fieldname] = part.value
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
argument.body = requestSchema.parse(req)
|
|
291
|
+
const result =
|
|
292
|
+
await controllerInstance[endpointMetadata.classMethod](argument)
|
|
293
|
+
reply
|
|
294
|
+
.status(endpointMetadata.successStatusCode)
|
|
295
|
+
.headers(endpointMetadata.headers)
|
|
296
|
+
.send(result)
|
|
297
|
+
} finally {
|
|
298
|
+
getServiceLocator().removeInstance(Request)
|
|
299
|
+
getServiceLocator().removeInstance(Reply)
|
|
300
|
+
getServiceLocator().removeInstance(ExecutionContextToken)
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
177
304
|
}
|