@navios/core 0.1.14 → 0.2.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/dist/_tsup-dts-rollup.d.mts +185 -434
- package/dist/_tsup-dts-rollup.d.ts +185 -434
- package/dist/index.d.mts +62 -46
- package/dist/index.d.ts +62 -46
- package/dist/index.js +482 -1328
- package/dist/index.mjs +484 -1292
- package/package.json +3 -2
- package/src/adapters/endpoint-adapter.service.mts +72 -0
- package/src/adapters/handler-adapter.interface.mts +21 -0
- package/src/adapters/index.mts +4 -0
- package/src/adapters/multipart-adapter.service.mts +131 -0
- package/src/adapters/stream-adapter.service.mts +91 -0
- package/src/attribute.factory.mts +14 -14
- package/src/config/config.provider.mts +16 -12
- package/src/decorators/controller.decorator.mts +3 -8
- package/src/decorators/endpoint.decorator.mts +7 -3
- package/src/decorators/header.decorator.mts +1 -6
- package/src/decorators/http-code.decorator.mts +1 -6
- package/src/decorators/module.decorator.mts +16 -21
- package/src/decorators/multipart.decorator.mts +7 -3
- package/src/decorators/stream.decorator.mts +7 -3
- package/src/decorators/use-guards.decorator.mts +3 -2
- package/src/index.mts +2 -1
- package/src/logger/console-logger.service.mts +3 -2
- package/src/logger/logger.factory.mts +4 -5
- package/src/logger/logger.service.mts +2 -2
- package/src/metadata/controller.metadata.mts +6 -5
- package/src/metadata/{endpoint.metadata.mts → handler.metadata.mts} +18 -28
- package/src/metadata/index.mts +1 -2
- package/src/metadata/module.metadata.mts +3 -2
- package/src/navios.application.mts +12 -12
- package/src/navios.factory.mts +4 -2
- package/src/services/controller-adapter.service.mts +65 -245
- package/src/services/execution-context.mts +4 -3
- package/src/services/guard-runner.service.mts +4 -6
- package/src/services/module-loader.service.mts +4 -2
- package/src/tokens/application.token.mts +1 -1
- package/src/tokens/execution-context.token.mts +2 -1
- package/src/tokens/reply.token.mts +1 -1
- package/src/tokens/request.token.mts +1 -1
- package/src/metadata/injectable.metadata.mts +0 -11
- package/src/service-locator/__tests__/injectable.spec.mts +0 -171
- package/src/service-locator/__tests__/injection-token.spec.mts +0 -124
- package/src/service-locator/decorators/get-injectable-token.mts +0 -19
- package/src/service-locator/decorators/index.mts +0 -2
- package/src/service-locator/decorators/injectable.decorator.mts +0 -64
- package/src/service-locator/enums/index.mts +0 -1
- package/src/service-locator/enums/injectable-scope.enum.mts +0 -10
- package/src/service-locator/errors/errors.enum.mts +0 -8
- package/src/service-locator/errors/factory-not-found.mts +0 -8
- package/src/service-locator/errors/factory-token-not-resolved.mts +0 -10
- package/src/service-locator/errors/index.mts +0 -7
- package/src/service-locator/errors/instance-destroying.mts +0 -8
- package/src/service-locator/errors/instance-expired.mts +0 -8
- package/src/service-locator/errors/instance-not-found.mts +0 -8
- package/src/service-locator/errors/unknown-error.mts +0 -15
- package/src/service-locator/event-emitter.mts +0 -107
- package/src/service-locator/index.mts +0 -15
- package/src/service-locator/inject.mts +0 -28
- package/src/service-locator/injection-token.mts +0 -92
- package/src/service-locator/injector.mts +0 -18
- package/src/service-locator/interfaces/factory.interface.mts +0 -3
- package/src/service-locator/override.mts +0 -22
- package/src/service-locator/proxy-service-locator.mts +0 -99
- package/src/service-locator/resolve-service.mts +0 -46
- package/src/service-locator/service-locator-abstract-factory-context.mts +0 -23
- package/src/service-locator/service-locator-event-bus.mts +0 -96
- package/src/service-locator/service-locator-instance-holder.mts +0 -63
- package/src/service-locator/service-locator-manager.mts +0 -89
- package/src/service-locator/service-locator.mts +0 -535
- package/src/service-locator/sync-injector.mts +0 -52
|
@@ -1,23 +1,20 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClassType } from '@navios/di'
|
|
2
2
|
import type { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify'
|
|
3
3
|
import type { ZodTypeProvider } from 'fastify-type-provider-zod'
|
|
4
|
-
import type { AnyZodObject } from 'zod'
|
|
5
4
|
|
|
6
|
-
import { NaviosException } from '@navios/common'
|
|
7
|
-
|
|
8
|
-
import { ZodArray } from 'zod'
|
|
9
|
-
|
|
10
|
-
import type { EndpointMetadata, ModuleMetadata } from '../metadata/index.mjs'
|
|
11
|
-
import type { ClassType } from '../service-locator/index.mjs'
|
|
12
|
-
|
|
13
|
-
import { Logger } from '../logger/index.mjs'
|
|
14
|
-
import { EndpointType, extractControllerMetadata } from '../metadata/index.mjs'
|
|
15
5
|
import {
|
|
16
|
-
|
|
6
|
+
getGlobalServiceLocator,
|
|
17
7
|
inject,
|
|
18
8
|
Injectable,
|
|
9
|
+
InjectionToken,
|
|
19
10
|
syncInject,
|
|
20
|
-
} from '
|
|
11
|
+
} from '@navios/di'
|
|
12
|
+
|
|
13
|
+
import type { HandlerAdapterInterface } from '../adapters/index.mjs'
|
|
14
|
+
import type { ModuleMetadata } from '../metadata/index.mjs'
|
|
15
|
+
|
|
16
|
+
import { Logger } from '../logger/index.mjs'
|
|
17
|
+
import { extractControllerMetadata } from '../metadata/index.mjs'
|
|
21
18
|
import { ExecutionContextToken, Reply, Request } from '../tokens/index.mjs'
|
|
22
19
|
import { ExecutionContext } from './execution-context.mjs'
|
|
23
20
|
import { GuardRunnerService } from './guard-runner.service.mjs'
|
|
@@ -29,32 +26,51 @@ export class ControllerAdapterService {
|
|
|
29
26
|
context: ControllerAdapterService.name,
|
|
30
27
|
})
|
|
31
28
|
|
|
32
|
-
setupController(
|
|
29
|
+
async setupController(
|
|
33
30
|
controller: ClassType,
|
|
34
31
|
instance: FastifyInstance,
|
|
35
32
|
moduleMetadata: ModuleMetadata,
|
|
36
|
-
)
|
|
33
|
+
) {
|
|
37
34
|
const controllerMetadata = extractControllerMetadata(controller)
|
|
38
35
|
for (const endpoint of controllerMetadata.endpoints) {
|
|
39
|
-
const { classMethod, url, httpMethod } = endpoint
|
|
36
|
+
const { classMethod, url, httpMethod, adapterToken } = endpoint
|
|
40
37
|
|
|
41
|
-
if (!url) {
|
|
38
|
+
if (!url || !adapterToken) {
|
|
42
39
|
throw new Error(
|
|
43
40
|
`[Navios] Malformed Endpoint ${controller.name}:${classMethod}`,
|
|
44
41
|
)
|
|
45
42
|
}
|
|
43
|
+
const adapter = await inject(
|
|
44
|
+
adapterToken as InjectionToken<HandlerAdapterInterface>,
|
|
45
|
+
)
|
|
46
46
|
const executionContext = new ExecutionContext(
|
|
47
47
|
moduleMetadata,
|
|
48
48
|
controllerMetadata,
|
|
49
49
|
endpoint,
|
|
50
50
|
)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
51
|
+
const hasSchema = adapter.hasSchema?.(endpoint) ?? false
|
|
52
|
+
if (hasSchema) {
|
|
53
|
+
instance.withTypeProvider<ZodTypeProvider>().route({
|
|
54
|
+
method: httpMethod,
|
|
55
|
+
url: url.replaceAll('$', ':'),
|
|
56
|
+
schema: adapter.provideSchema?.(endpoint) ?? {},
|
|
57
|
+
preHandler: this.providePreHandler(executionContext),
|
|
58
|
+
handler: this.wrapHandler(
|
|
59
|
+
executionContext,
|
|
60
|
+
adapter.provideHandler(controller, executionContext, endpoint),
|
|
61
|
+
),
|
|
62
|
+
})
|
|
63
|
+
} else {
|
|
64
|
+
instance.route({
|
|
65
|
+
method: httpMethod,
|
|
66
|
+
url: url.replaceAll('$', ':'),
|
|
67
|
+
preHandler: this.providePreHandler(executionContext),
|
|
68
|
+
handler: this.wrapHandler(
|
|
69
|
+
executionContext,
|
|
70
|
+
adapter.provideHandler(controller, executionContext, endpoint),
|
|
71
|
+
),
|
|
72
|
+
})
|
|
73
|
+
}
|
|
58
74
|
|
|
59
75
|
this.logger.debug(
|
|
60
76
|
`Registered ${httpMethod} ${url} for ${controller.name}:${classMethod}`,
|
|
@@ -65,239 +81,43 @@ export class ControllerAdapterService {
|
|
|
65
81
|
providePreHandler(executionContext: ExecutionContext) {
|
|
66
82
|
const guards = this.guardRunner.makeContext(executionContext)
|
|
67
83
|
return guards.size > 0
|
|
68
|
-
?
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
ExecutionContextToken,
|
|
73
|
-
executionContext,
|
|
74
|
-
)
|
|
75
|
-
executionContext.provideRequest(request)
|
|
76
|
-
executionContext.provideReply(reply)
|
|
77
|
-
let canActivate = true
|
|
78
|
-
try {
|
|
84
|
+
? this.wrapHandler(
|
|
85
|
+
executionContext,
|
|
86
|
+
async (request: FastifyRequest, reply: FastifyReply) => {
|
|
87
|
+
let canActivate = true
|
|
79
88
|
canActivate = await this.guardRunner.runGuards(
|
|
80
89
|
guards,
|
|
81
90
|
executionContext,
|
|
82
91
|
)
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
if (!canActivate) {
|
|
89
|
-
return reply
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
: undefined
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
private provideSchemaForConfig(endpointMetadata: EndpointMetadata) {
|
|
96
|
-
if (!endpointMetadata.config) {
|
|
97
|
-
this.logger.warn(`No config found for endpoint ${endpointMetadata.url}`)
|
|
98
|
-
return {}
|
|
99
|
-
}
|
|
100
|
-
const { querySchema, requestSchema, responseSchema } =
|
|
101
|
-
endpointMetadata.config as BaseEndpointConfig
|
|
102
|
-
const schema: Record<string, any> = {}
|
|
103
|
-
if (querySchema) {
|
|
104
|
-
schema.querystring = querySchema
|
|
105
|
-
}
|
|
106
|
-
if (requestSchema && endpointMetadata.type !== EndpointType.Multipart) {
|
|
107
|
-
schema.body = requestSchema
|
|
108
|
-
}
|
|
109
|
-
if (responseSchema) {
|
|
110
|
-
schema.response = {
|
|
111
|
-
200: responseSchema,
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
return schema
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
private provideHandler(
|
|
119
|
-
controller: ClassType,
|
|
120
|
-
executionContext: ExecutionContext,
|
|
121
|
-
endpointMetadata: EndpointMetadata,
|
|
122
|
-
): (request: FastifyRequest, reply: FastifyReply) => Promise<void> {
|
|
123
|
-
switch (endpointMetadata.type) {
|
|
124
|
-
case EndpointType.Unknown:
|
|
125
|
-
this.logger.error(
|
|
126
|
-
`Unknown endpoint type ${endpointMetadata.type} for ${controller.name}:${endpointMetadata.classMethod}`,
|
|
127
|
-
)
|
|
128
|
-
throw new NaviosException('Unknown endpoint type')
|
|
129
|
-
case EndpointType.Endpoint:
|
|
130
|
-
return this.provideHandlerForConfig(
|
|
131
|
-
controller,
|
|
132
|
-
executionContext,
|
|
133
|
-
endpointMetadata,
|
|
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,
|
|
92
|
+
if (!canActivate) {
|
|
93
|
+
return reply
|
|
94
|
+
}
|
|
95
|
+
},
|
|
146
96
|
)
|
|
147
|
-
|
|
148
|
-
this.logger.error('Not implemented yet')
|
|
149
|
-
throw new NaviosException('Not implemented yet')
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
private provideHandlerForConfig(
|
|
154
|
-
controller: ClassType,
|
|
155
|
-
executionContext: ExecutionContext,
|
|
156
|
-
endpointMetadata: EndpointMetadata,
|
|
157
|
-
): (request: FastifyRequest, reply: FastifyReply) => Promise<void> {
|
|
158
|
-
return async (request, reply) => {
|
|
159
|
-
getServiceLocator().registerInstance(Request, request)
|
|
160
|
-
getServiceLocator().registerInstance(Reply, reply)
|
|
161
|
-
getServiceLocator().registerInstance(
|
|
162
|
-
ExecutionContextToken,
|
|
163
|
-
executionContext,
|
|
164
|
-
)
|
|
165
|
-
executionContext.provideRequest(request)
|
|
166
|
-
executionContext.provideReply(reply)
|
|
167
|
-
const controllerInstance = await inject(controller)
|
|
168
|
-
try {
|
|
169
|
-
const { query, params, body } = request
|
|
170
|
-
const argument: Record<string, any> = {}
|
|
171
|
-
if (query && Object.keys(query).length > 0) {
|
|
172
|
-
argument.params = query
|
|
173
|
-
}
|
|
174
|
-
if (params && Object.keys(params).length > 0) {
|
|
175
|
-
argument.urlParams = params
|
|
176
|
-
}
|
|
177
|
-
if (body) {
|
|
178
|
-
argument.data = body
|
|
179
|
-
}
|
|
180
|
-
const result =
|
|
181
|
-
await controllerInstance[endpointMetadata.classMethod](argument)
|
|
182
|
-
reply
|
|
183
|
-
.status(endpointMetadata.successStatusCode)
|
|
184
|
-
.headers(endpointMetadata.headers)
|
|
185
|
-
.send(result)
|
|
186
|
-
} finally {
|
|
187
|
-
getServiceLocator().removeInstance(Request)
|
|
188
|
-
getServiceLocator().removeInstance(Reply)
|
|
189
|
-
getServiceLocator().removeInstance(ExecutionContextToken)
|
|
190
|
-
}
|
|
191
|
-
}
|
|
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
|
-
}
|
|
97
|
+
: undefined
|
|
229
98
|
}
|
|
230
99
|
|
|
231
|
-
private
|
|
232
|
-
controller: ClassType,
|
|
100
|
+
private wrapHandler(
|
|
233
101
|
executionContext: ExecutionContext,
|
|
234
|
-
|
|
235
|
-
)
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
getServiceLocator().registerInstance(Reply, reply)
|
|
242
|
-
getServiceLocator().registerInstance(
|
|
243
|
-
ExecutionContextToken,
|
|
244
|
-
executionContext,
|
|
245
|
-
)
|
|
102
|
+
handler: (request: FastifyRequest, reply: FastifyReply) => Promise<void>,
|
|
103
|
+
) {
|
|
104
|
+
const locator = getGlobalServiceLocator()
|
|
105
|
+
return async (request: FastifyRequest, reply: FastifyReply) => {
|
|
106
|
+
locator.storeInstance(request, Request)
|
|
107
|
+
locator.storeInstance(reply, Reply)
|
|
108
|
+
locator.storeInstance(executionContext, ExecutionContextToken)
|
|
246
109
|
executionContext.provideRequest(request)
|
|
247
110
|
executionContext.provideReply(reply)
|
|
248
|
-
const controllerInstance = await inject(controller)
|
|
249
111
|
try {
|
|
250
|
-
|
|
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.data = 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)
|
|
112
|
+
return await handler(request, reply)
|
|
297
113
|
} finally {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
114
|
+
Promise.all([
|
|
115
|
+
locator.removeInstance(Request),
|
|
116
|
+
locator.removeInstance(Reply),
|
|
117
|
+
locator.removeInstance(ExecutionContextToken),
|
|
118
|
+
]).catch((err) => {
|
|
119
|
+
this.logger.warn(`Error removing instances: ${err}`)
|
|
120
|
+
})
|
|
301
121
|
}
|
|
302
122
|
}
|
|
303
123
|
}
|
|
@@ -2,7 +2,7 @@ import type { FastifyReply, FastifyRequest } from 'fastify'
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
ControllerMetadata,
|
|
5
|
-
|
|
5
|
+
HandlerMetadata,
|
|
6
6
|
ModuleMetadata,
|
|
7
7
|
} from '../metadata/index.mjs'
|
|
8
8
|
|
|
@@ -12,7 +12,7 @@ export class ExecutionContext {
|
|
|
12
12
|
constructor(
|
|
13
13
|
private readonly module: ModuleMetadata,
|
|
14
14
|
private readonly controller: ControllerMetadata,
|
|
15
|
-
private readonly handler:
|
|
15
|
+
private readonly handler: HandlerMetadata,
|
|
16
16
|
) {}
|
|
17
17
|
getModule(): ModuleMetadata {
|
|
18
18
|
return this.module
|
|
@@ -22,7 +22,7 @@ export class ExecutionContext {
|
|
|
22
22
|
return this.controller
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
getHandler():
|
|
25
|
+
getHandler(): HandlerMetadata {
|
|
26
26
|
return this.handler
|
|
27
27
|
}
|
|
28
28
|
|
|
@@ -47,6 +47,7 @@ export class ExecutionContext {
|
|
|
47
47
|
provideRequest(request: FastifyRequest): void {
|
|
48
48
|
this.request = request
|
|
49
49
|
}
|
|
50
|
+
|
|
50
51
|
provideReply(reply: FastifyReply): void {
|
|
51
52
|
this.reply = reply
|
|
52
53
|
}
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
+
import type { ClassTypeWithInstance } from '@navios/di'
|
|
2
|
+
|
|
3
|
+
import { inject, Injectable, InjectionToken } from '@navios/di'
|
|
4
|
+
|
|
1
5
|
import type { CanActivate } from '../interfaces/index.mjs'
|
|
2
|
-
import type { ClassTypeWithInstance } from '../service-locator/index.mjs'
|
|
3
6
|
import type { ExecutionContext } from './execution-context.mjs'
|
|
4
7
|
|
|
5
8
|
import { HttpException } from '../exceptions/index.mjs'
|
|
6
|
-
import {
|
|
7
|
-
inject,
|
|
8
|
-
Injectable,
|
|
9
|
-
InjectionToken,
|
|
10
|
-
} from '../service-locator/index.mjs'
|
|
11
9
|
|
|
12
10
|
@Injectable()
|
|
13
11
|
export class GuardRunnerService {
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import type { ClassTypeWithInstance } from '@navios/di'
|
|
2
|
+
|
|
3
|
+
import { inject, Injectable, syncInject } from '@navios/di'
|
|
4
|
+
|
|
1
5
|
import type { NaviosModule } from '../interfaces/index.mjs'
|
|
2
6
|
import type { ModuleMetadata } from '../metadata/index.mjs'
|
|
3
|
-
import type { ClassTypeWithInstance } from '../service-locator/index.mjs'
|
|
4
7
|
|
|
5
8
|
import { Logger } from '../logger/index.mjs'
|
|
6
9
|
import { extractModuleMetadata } from '../metadata/index.mjs'
|
|
7
|
-
import { inject, Injectable, syncInject } from '../service-locator/index.mjs'
|
|
8
10
|
|
|
9
11
|
@Injectable()
|
|
10
12
|
export class ModuleLoaderService {
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
InjectableScope,
|
|
3
|
-
InjectableType,
|
|
4
|
-
InjectionToken,
|
|
5
|
-
} from '../index.mjs'
|
|
6
|
-
|
|
7
|
-
export interface InjectableMetadata<Instance = any, Schema = any> {
|
|
8
|
-
type: InjectableType
|
|
9
|
-
scope: InjectableScope
|
|
10
|
-
token: InjectionToken<Instance, Schema>
|
|
11
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from 'vitest'
|
|
2
|
-
import { z } from 'zod'
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
getInjectableToken,
|
|
6
|
-
Injectable,
|
|
7
|
-
InjectableType,
|
|
8
|
-
} from '../decorators/index.mjs'
|
|
9
|
-
import { InjectableScope } from '../enums/index.mjs'
|
|
10
|
-
import { syncInject } from '../index.mjs'
|
|
11
|
-
import { inject } from '../inject.mjs'
|
|
12
|
-
import { InjectionToken } from '../injection-token.mjs'
|
|
13
|
-
import { getServiceLocator } from '../injector.mjs'
|
|
14
|
-
|
|
15
|
-
describe('Injectable decorator', () => {
|
|
16
|
-
it('should work with class', async () => {
|
|
17
|
-
@Injectable()
|
|
18
|
-
class Test {}
|
|
19
|
-
|
|
20
|
-
const value = await inject(Test)
|
|
21
|
-
expect(value).toBeInstanceOf(Test)
|
|
22
|
-
})
|
|
23
|
-
|
|
24
|
-
it('should work with inner inject', async () => {
|
|
25
|
-
@Injectable()
|
|
26
|
-
class Test {
|
|
27
|
-
makeFoo() {
|
|
28
|
-
return 'foo'
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
@Injectable()
|
|
33
|
-
class Test2 {
|
|
34
|
-
fooMaker = inject(Test)
|
|
35
|
-
|
|
36
|
-
async makeFoo() {
|
|
37
|
-
const fooMaker = await this.fooMaker
|
|
38
|
-
return fooMaker.makeFoo()
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
const value = await inject(Test2)
|
|
43
|
-
expect(value).toBeInstanceOf(Test2)
|
|
44
|
-
const result = await value.makeFoo()
|
|
45
|
-
expect(result).toBe('foo')
|
|
46
|
-
})
|
|
47
|
-
|
|
48
|
-
it('should work with factory', async () => {
|
|
49
|
-
@Injectable({ type: InjectableType.Factory })
|
|
50
|
-
class Test {
|
|
51
|
-
create() {
|
|
52
|
-
return 'foo'
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const value = await inject(Test)
|
|
57
|
-
expect(value).toBe('foo')
|
|
58
|
-
})
|
|
59
|
-
it('should work with request scope', async () => {
|
|
60
|
-
@Injectable({
|
|
61
|
-
scope: InjectableScope.Instance,
|
|
62
|
-
type: InjectableType.Factory,
|
|
63
|
-
})
|
|
64
|
-
class Test {
|
|
65
|
-
create() {
|
|
66
|
-
return Date.now()
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const value = await inject(Test)
|
|
71
|
-
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
72
|
-
const value2 = await inject(Test)
|
|
73
|
-
expect(value).not.toBe(value2)
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
it('should work with injection token', async () => {
|
|
77
|
-
const token = InjectionToken.create('Test')
|
|
78
|
-
|
|
79
|
-
@Injectable({ token })
|
|
80
|
-
class Test {}
|
|
81
|
-
|
|
82
|
-
const value = await inject(token)
|
|
83
|
-
expect(value).toBeInstanceOf(Test)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('should work with injection token and schema', async () => {
|
|
87
|
-
class TestFoo {
|
|
88
|
-
constructor(public readonly foo: string) {}
|
|
89
|
-
}
|
|
90
|
-
const token = InjectionToken.create(
|
|
91
|
-
TestFoo,
|
|
92
|
-
z.object({
|
|
93
|
-
foo: z.string(),
|
|
94
|
-
}),
|
|
95
|
-
)
|
|
96
|
-
|
|
97
|
-
@Injectable({ token, type: InjectableType.Factory })
|
|
98
|
-
class Test {
|
|
99
|
-
create(ctx: any, args: { foo: string }) {
|
|
100
|
-
return new TestFoo(args.foo)
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const value = await inject(token, { foo: 'bar' })
|
|
105
|
-
const differentValue = await inject(token, { foo: 'baz' })
|
|
106
|
-
const sameValue = await inject(token, { foo: 'bar' })
|
|
107
|
-
expect(value).toBeInstanceOf(TestFoo)
|
|
108
|
-
expect(value.foo).toBe('bar')
|
|
109
|
-
expect(differentValue).toBeInstanceOf(TestFoo)
|
|
110
|
-
expect(differentValue.foo).toBe('baz')
|
|
111
|
-
expect(value).not.toBe(differentValue)
|
|
112
|
-
expect(value).toBe(sameValue)
|
|
113
|
-
})
|
|
114
|
-
it('should work with invalidation', async () => {
|
|
115
|
-
@Injectable()
|
|
116
|
-
class Test {
|
|
117
|
-
value = Date.now()
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
@Injectable()
|
|
121
|
-
class Test2 {
|
|
122
|
-
test = inject(Test)
|
|
123
|
-
|
|
124
|
-
async makeFoo() {
|
|
125
|
-
const test = await this.test
|
|
126
|
-
return test.value
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
const identifier = getServiceLocator().getInstanceIdentifier(
|
|
130
|
-
getInjectableToken(Test),
|
|
131
|
-
undefined,
|
|
132
|
-
)
|
|
133
|
-
const inst1 = await inject(Test2)
|
|
134
|
-
expect(inst1).toBeInstanceOf(Test2)
|
|
135
|
-
const result1 = await inst1.makeFoo()
|
|
136
|
-
const inst2 = await inject(Test2)
|
|
137
|
-
expect(inst1).toBe(inst2)
|
|
138
|
-
const result2 = await inst2.makeFoo()
|
|
139
|
-
await getServiceLocator().invalidate(identifier)
|
|
140
|
-
await new Promise((resolve) => setTimeout(resolve, 10))
|
|
141
|
-
const inst3 = await inject(Test2)
|
|
142
|
-
expect(inst1).not.toBe(inst3)
|
|
143
|
-
const result3 = await inst3.makeFoo()
|
|
144
|
-
expect(result1).not.toBe(result3)
|
|
145
|
-
expect(result2).not.toBe(result3)
|
|
146
|
-
expect(result1).toBe(result2)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('should work with syncInject', async () => {
|
|
150
|
-
@Injectable()
|
|
151
|
-
class Test {
|
|
152
|
-
value = Date.now()
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
@Injectable()
|
|
156
|
-
class Test2 {
|
|
157
|
-
test = syncInject(Test)
|
|
158
|
-
|
|
159
|
-
makeFoo() {
|
|
160
|
-
return this.test.value
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
const inst1 = await inject(Test2)
|
|
164
|
-
expect(inst1).toBeInstanceOf(Test2)
|
|
165
|
-
const result1 = inst1.makeFoo()
|
|
166
|
-
const inst2 = await inject(Test2)
|
|
167
|
-
expect(inst1).toBe(inst2)
|
|
168
|
-
const result2 = await inst2.makeFoo()
|
|
169
|
-
expect(result1).toBe(result2)
|
|
170
|
-
})
|
|
171
|
-
})
|