@navios/core 0.1.1 → 0.1.3
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/index.d.mts +358 -287
- package/dist/index.d.ts +358 -287
- package/dist/index.js +872 -641
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +861 -641
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/config/config-service.interface.mts +16 -0
- package/src/config/config.provider.mts +62 -0
- package/src/config/config.service.mts +69 -0
- package/src/config/index.mts +5 -0
- package/src/config/types.mts +58 -0
- package/src/config/utils/helpers.mts +23 -0
- package/src/config/utils/index.mts +1 -0
- package/src/decorators/endpoint.decorator.mts +7 -2
- package/src/decorators/header.decorator.mts +18 -0
- package/src/decorators/http-code.decorator.mts +18 -0
- package/src/decorators/index.mts +2 -0
- package/src/index.mts +1 -0
- package/src/logger/logger.service.mts +0 -1
- package/src/logger/pino-wrapper.mts +6 -5
- package/src/metadata/endpoint.metadata.mts +13 -0
- package/src/navios.application.mts +36 -1
- package/src/service-locator/proxy-service-locator.mts +28 -9
- package/src/service-locator/service-locator.mts +9 -1
- package/src/services/controller-adapter.service.mts +116 -71
package/package.json
CHANGED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Path, PathValue } from './types.mjs'
|
|
2
|
+
|
|
3
|
+
export interface ConfigService<Config = Record<string, unknown>> {
|
|
4
|
+
getConfig: () => Config
|
|
5
|
+
get: <Key extends Path<Config>>(key: Key) => PathValue<Config, Key> | null
|
|
6
|
+
|
|
7
|
+
getOrDefault: <Key extends Path<Config>>(
|
|
8
|
+
key: Key,
|
|
9
|
+
defaultValue: PathValue<Config, Key>,
|
|
10
|
+
) => PathValue<Config, Key>
|
|
11
|
+
|
|
12
|
+
getOrThrow: <Key extends Path<Config>>(
|
|
13
|
+
key: Key,
|
|
14
|
+
errorMessage?: string,
|
|
15
|
+
) => PathValue<Config, Key>
|
|
16
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
|
|
3
|
+
import type { ConfigService } from './config-service.interface.mjs'
|
|
4
|
+
|
|
5
|
+
import { Logger } from '../logger/index.mjs'
|
|
6
|
+
import {
|
|
7
|
+
getInjectableToken,
|
|
8
|
+
inject,
|
|
9
|
+
Injectable,
|
|
10
|
+
InjectableType,
|
|
11
|
+
InjectionToken,
|
|
12
|
+
} from '../service-locator/index.mjs'
|
|
13
|
+
import { ConfigServiceInstance } from './config.service.mjs'
|
|
14
|
+
|
|
15
|
+
export const ConfigProviderInjectionToken = 'ConfigProvider'
|
|
16
|
+
|
|
17
|
+
export const ConfigProviderOptions = z.object({
|
|
18
|
+
load: z.function(),
|
|
19
|
+
})
|
|
20
|
+
export const ConfigProvider = InjectionToken.create<
|
|
21
|
+
ConfigService,
|
|
22
|
+
typeof ConfigProviderOptions
|
|
23
|
+
>(ConfigProviderInjectionToken, ConfigProviderOptions)
|
|
24
|
+
|
|
25
|
+
@Injectable({
|
|
26
|
+
token: ConfigProvider,
|
|
27
|
+
type: InjectableType.Factory,
|
|
28
|
+
})
|
|
29
|
+
export class ConfigProviderFactory {
|
|
30
|
+
logger = inject(Logger, {
|
|
31
|
+
context: 'ConfigService',
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
async create(ctx: any, args: z.infer<typeof ConfigProviderOptions>) {
|
|
35
|
+
const { load } = args
|
|
36
|
+
const logger = await this.logger
|
|
37
|
+
try {
|
|
38
|
+
const config = await load()
|
|
39
|
+
|
|
40
|
+
return new ConfigServiceInstance(config, logger)
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error('Error loading config', error)
|
|
43
|
+
throw error
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function makeConfigToken<Config extends Record<string, unknown>>(
|
|
49
|
+
options: z.input<typeof ConfigProviderOptions>,
|
|
50
|
+
): InjectionToken<ConfigService<Config>> {
|
|
51
|
+
@Injectable({
|
|
52
|
+
type: InjectableType.Factory,
|
|
53
|
+
})
|
|
54
|
+
class ConfigServiceImpl {
|
|
55
|
+
configService = inject(ConfigProvider, options)
|
|
56
|
+
|
|
57
|
+
create() {
|
|
58
|
+
return this.configService
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return getInjectableToken(ConfigServiceImpl)
|
|
62
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { NaviosException } from '@navios/common'
|
|
2
|
+
|
|
3
|
+
import type { LoggerService } from '../logger/index.mjs'
|
|
4
|
+
import type { ConfigService } from './config-service.interface.mjs'
|
|
5
|
+
import type { Path, PathValue } from './types.mjs'
|
|
6
|
+
|
|
7
|
+
export class ConfigServiceInstance<Config = Record<string, unknown>>
|
|
8
|
+
implements ConfigService<Config>
|
|
9
|
+
{
|
|
10
|
+
constructor(
|
|
11
|
+
private config: Config = {} as Config,
|
|
12
|
+
private logger: LoggerService,
|
|
13
|
+
) {}
|
|
14
|
+
|
|
15
|
+
getConfig(): Config {
|
|
16
|
+
return this.config
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get<Key extends Path<Config>>(key: Key): PathValue<Config, Key> | null {
|
|
20
|
+
try {
|
|
21
|
+
const parts = String(key).split('.')
|
|
22
|
+
let value: any = this.config
|
|
23
|
+
|
|
24
|
+
for (const part of parts) {
|
|
25
|
+
if (
|
|
26
|
+
value === null ||
|
|
27
|
+
value === undefined ||
|
|
28
|
+
typeof value !== 'object'
|
|
29
|
+
) {
|
|
30
|
+
return null
|
|
31
|
+
}
|
|
32
|
+
value = value[part]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return (value as PathValue<Config, Key>) ?? null
|
|
36
|
+
} catch (error) {
|
|
37
|
+
this.logger.debug?.(
|
|
38
|
+
`Failed to get config value for key ${String(key)}`,
|
|
39
|
+
error,
|
|
40
|
+
)
|
|
41
|
+
return null
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
getOrDefault<Key extends Path<Config>>(
|
|
46
|
+
key: Key,
|
|
47
|
+
defaultValue: PathValue<Config, Key>,
|
|
48
|
+
): PathValue<Config, Key> {
|
|
49
|
+
const value = this.get(key)
|
|
50
|
+
return value !== null ? value : defaultValue
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getOrThrow<Key extends Path<Config>>(
|
|
54
|
+
key: Key,
|
|
55
|
+
errorMessage?: string,
|
|
56
|
+
): PathValue<Config, Key> {
|
|
57
|
+
const value = this.get(key)
|
|
58
|
+
|
|
59
|
+
if (value === null) {
|
|
60
|
+
const message =
|
|
61
|
+
errorMessage ||
|
|
62
|
+
`Configuration value for key "${String(key)}" is not defined`
|
|
63
|
+
this.logger.error(message)
|
|
64
|
+
throw new NaviosException(message)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return value
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluates to `true` if `T` is `any`. `false` otherwise.
|
|
3
|
+
* (c) https://stackoverflow.com/a/68633327/5290447
|
|
4
|
+
*/
|
|
5
|
+
type IsAny<T> = unknown extends T
|
|
6
|
+
? [keyof T] extends [never]
|
|
7
|
+
? false
|
|
8
|
+
: true
|
|
9
|
+
: false
|
|
10
|
+
|
|
11
|
+
type ExcludedParts =
|
|
12
|
+
| 'services'
|
|
13
|
+
| 'mailer'
|
|
14
|
+
| 'aws'
|
|
15
|
+
| 'computedTimeRates'
|
|
16
|
+
| 'aiModelsRates'
|
|
17
|
+
type ExcludedKeys = 'computedTimeRates' | 'aiModelsRates' | 'aiModel'
|
|
18
|
+
|
|
19
|
+
export type PathImpl<T, Key extends keyof T> = Key extends string
|
|
20
|
+
? Key extends ExcludedKeys
|
|
21
|
+
? never
|
|
22
|
+
: IsAny<T[Key]> extends true
|
|
23
|
+
? never
|
|
24
|
+
: T[Key] extends string
|
|
25
|
+
? never
|
|
26
|
+
: T[Key] extends any[]
|
|
27
|
+
? never
|
|
28
|
+
: T[Key] extends Record<string, any>
|
|
29
|
+
? Key extends ExcludedParts
|
|
30
|
+
? `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}`
|
|
31
|
+
:
|
|
32
|
+
| `${Key}.${PathImpl<T[Key], Exclude<keyof T[Key], keyof any[]>> & string}`
|
|
33
|
+
| `${Key}.${Exclude<keyof T[Key], keyof any[]> & string}`
|
|
34
|
+
: never
|
|
35
|
+
: never
|
|
36
|
+
|
|
37
|
+
export type PathImpl2<T> = PathImpl<T, keyof T> | keyof T
|
|
38
|
+
|
|
39
|
+
export type Path<T> = keyof T extends string
|
|
40
|
+
? PathImpl2<T> extends infer P
|
|
41
|
+
? P extends string | keyof T
|
|
42
|
+
? P
|
|
43
|
+
: keyof T
|
|
44
|
+
: keyof T
|
|
45
|
+
: never
|
|
46
|
+
|
|
47
|
+
export type PathValue<
|
|
48
|
+
T,
|
|
49
|
+
P extends Path<T>,
|
|
50
|
+
> = P extends `${infer Key}.${infer Rest}`
|
|
51
|
+
? Key extends keyof T
|
|
52
|
+
? Rest extends Path<T[Key]>
|
|
53
|
+
? PathValue<T[Key], Rest>
|
|
54
|
+
: never
|
|
55
|
+
: never
|
|
56
|
+
: P extends keyof T
|
|
57
|
+
? T[P]
|
|
58
|
+
: never
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { env } from 'node:process'
|
|
2
|
+
|
|
3
|
+
export function envInt(
|
|
4
|
+
key: keyof NodeJS.ProcessEnv,
|
|
5
|
+
defaultValue: number,
|
|
6
|
+
): number {
|
|
7
|
+
const envKey = env[key] || process.env[key]
|
|
8
|
+
|
|
9
|
+
return envKey ? parseInt(envKey as string, 10) : defaultValue
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function envString<
|
|
13
|
+
DefaultValue extends string | undefined,
|
|
14
|
+
Ensured = DefaultValue extends string ? true : false,
|
|
15
|
+
>(
|
|
16
|
+
key: keyof NodeJS.ProcessEnv,
|
|
17
|
+
defaultValue?: DefaultValue,
|
|
18
|
+
): Ensured extends true ? string : string | undefined {
|
|
19
|
+
return (env[key] ||
|
|
20
|
+
process.env[key] ||
|
|
21
|
+
defaultValue ||
|
|
22
|
+
undefined) as Ensured extends true ? string : string | undefined
|
|
23
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './helpers.mjs'
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BaseEndpointConfig,
|
|
3
|
+
EndpointFunctionArgs,
|
|
4
|
+
HttpMethod,
|
|
5
|
+
} from '@navios/common'
|
|
2
6
|
import type { AnyZodObject, z, ZodType } from 'zod'
|
|
3
7
|
|
|
4
|
-
import { getEndpointMetadata } from '../metadata/index.mjs'
|
|
8
|
+
import { EndpointType, getEndpointMetadata } from '../metadata/index.mjs'
|
|
5
9
|
|
|
6
10
|
export type EndpointParams<
|
|
7
11
|
EndpointDeclaration extends {
|
|
@@ -72,6 +76,7 @@ export function Endpoint<
|
|
|
72
76
|
}
|
|
73
77
|
// @ts-expect-error We don't need to set correctly in the metadata
|
|
74
78
|
endpointMetadata.config = config
|
|
79
|
+
endpointMetadata.type = EndpointType.Config
|
|
75
80
|
endpointMetadata.classMethod = target.name
|
|
76
81
|
endpointMetadata.httpMethod = config.method
|
|
77
82
|
endpointMetadata.url = config.url
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HttpHeader } from 'fastify/types/utils.js'
|
|
2
|
+
|
|
3
|
+
import { getEndpointMetadata } from '../metadata/index.mjs'
|
|
4
|
+
|
|
5
|
+
export function Header(name: HttpHeader, value: string | number | string[]) {
|
|
6
|
+
return <T extends Function>(
|
|
7
|
+
target: T,
|
|
8
|
+
context: ClassMethodDecoratorContext,
|
|
9
|
+
) => {
|
|
10
|
+
if (context.kind !== 'method') {
|
|
11
|
+
throw new Error('[Navios] Header decorator can only be used on methods.')
|
|
12
|
+
}
|
|
13
|
+
const metadata = getEndpointMetadata(target, context)
|
|
14
|
+
metadata.headers[name] = value
|
|
15
|
+
|
|
16
|
+
return target
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getEndpointMetadata } from '../metadata/index.mjs'
|
|
2
|
+
|
|
3
|
+
export function HttpCode(code: number) {
|
|
4
|
+
return <T extends Function>(
|
|
5
|
+
target: T,
|
|
6
|
+
context: ClassMethodDecoratorContext,
|
|
7
|
+
) => {
|
|
8
|
+
if (context.kind !== 'method') {
|
|
9
|
+
throw new Error(
|
|
10
|
+
'[Navios] HttpCode decorator can only be used on methods.',
|
|
11
|
+
)
|
|
12
|
+
}
|
|
13
|
+
const metadata = getEndpointMetadata(target, context)
|
|
14
|
+
metadata.successStatusCode = code
|
|
15
|
+
|
|
16
|
+
return target
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/decorators/index.mts
CHANGED
package/src/index.mts
CHANGED
|
@@ -184,7 +184,6 @@ export class LoggerInstance implements LoggerService {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
static overrideLogger(logger: LoggerService | LogLevel[] | boolean) {
|
|
187
|
-
console.log(logger)
|
|
188
187
|
if (Array.isArray(logger)) {
|
|
189
188
|
LoggerInstance.logLevels = logger
|
|
190
189
|
return this.staticInstanceRef?.setLogLevels?.(logger)
|
|
@@ -20,8 +20,9 @@ export class PinoWrapper {
|
|
|
20
20
|
this.logger.warn(message, ...optionalParams)
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
info(
|
|
24
|
-
|
|
23
|
+
info() {
|
|
24
|
+
// We don't want to populate the logs with the original fastify logs
|
|
25
|
+
// this.logger.debug?.('INFO', message, ...optionalParams)
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
debug(message: any, ...optionalParams: any[]) {
|
|
@@ -32,7 +33,7 @@ export class PinoWrapper {
|
|
|
32
33
|
this.logger.verbose?.(message, ...optionalParams)
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
silent(
|
|
36
|
+
silent() {
|
|
36
37
|
// noop
|
|
37
38
|
}
|
|
38
39
|
|
|
@@ -56,8 +57,8 @@ export class PinoWrapper {
|
|
|
56
57
|
}
|
|
57
58
|
const levels = LoggerInstance['logLevels']
|
|
58
59
|
if (levels) {
|
|
59
|
-
return levels
|
|
60
|
+
return levels.find((level) => level !== 'verbose')
|
|
60
61
|
}
|
|
61
|
-
return '
|
|
62
|
+
return 'warn'
|
|
62
63
|
}
|
|
63
64
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { BaseEndpointConfig, HttpMethod } from '@navios/common'
|
|
2
|
+
import type { HttpHeader } from 'fastify/types/utils.js'
|
|
2
3
|
|
|
3
4
|
import type { CanActivate } from '../interfaces/index.mjs'
|
|
4
5
|
import type {
|
|
@@ -8,9 +9,18 @@ import type {
|
|
|
8
9
|
|
|
9
10
|
export const EndpointMetadataKey = Symbol('EndpointMetadataKey')
|
|
10
11
|
|
|
12
|
+
export enum EndpointType {
|
|
13
|
+
Unknown = 'unknown',
|
|
14
|
+
Config = 'config',
|
|
15
|
+
Handler = 'handler',
|
|
16
|
+
}
|
|
17
|
+
|
|
11
18
|
export interface EndpointMetadata {
|
|
12
19
|
classMethod: string
|
|
13
20
|
url: string
|
|
21
|
+
successStatusCode: number
|
|
22
|
+
type: EndpointType
|
|
23
|
+
headers: Partial<Record<HttpHeader, number | string | string[] | undefined>>
|
|
14
24
|
httpMethod: HttpMethod
|
|
15
25
|
config: BaseEndpointConfig | null
|
|
16
26
|
guards: Set<
|
|
@@ -52,6 +62,9 @@ export function getEndpointMetadata(
|
|
|
52
62
|
const newMetadata: EndpointMetadata = {
|
|
53
63
|
classMethod: target.name,
|
|
54
64
|
url: '',
|
|
65
|
+
successStatusCode: 200,
|
|
66
|
+
headers: {},
|
|
67
|
+
type: EndpointType.Unknown,
|
|
55
68
|
httpMethod: 'GET',
|
|
56
69
|
config: null,
|
|
57
70
|
guards: new Set<
|
|
@@ -16,6 +16,7 @@ import type { NaviosModule } from './interfaces/index.mjs'
|
|
|
16
16
|
import type { LoggerService, LogLevel } from './logger/index.mjs'
|
|
17
17
|
import type { ClassTypeWithInstance } from './service-locator/index.mjs'
|
|
18
18
|
|
|
19
|
+
import { HttpException } from './exceptions/index.mjs'
|
|
19
20
|
import { Logger, PinoWrapper } from './logger/index.mjs'
|
|
20
21
|
import {
|
|
21
22
|
getServiceLocator,
|
|
@@ -68,6 +69,7 @@ export class NaviosApplication {
|
|
|
68
69
|
}
|
|
69
70
|
await this.moduleLoader.loadModules(this.appModule)
|
|
70
71
|
this.server = await this.getFastifyInstance(this.options)
|
|
72
|
+
this.configureFastifyInstance(this.server)
|
|
71
73
|
getServiceLocator().registerInstance(Application, this.server)
|
|
72
74
|
// Add schema validator and serializer
|
|
73
75
|
this.server.setValidatorCompiler(validatorCompiler)
|
|
@@ -78,6 +80,7 @@ export class NaviosApplication {
|
|
|
78
80
|
}
|
|
79
81
|
|
|
80
82
|
await this.initModules()
|
|
83
|
+
await this.server.ready()
|
|
81
84
|
|
|
82
85
|
this.logger.debug('Navios application initialized')
|
|
83
86
|
}
|
|
@@ -110,6 +113,37 @@ export class NaviosApplication {
|
|
|
110
113
|
}
|
|
111
114
|
}
|
|
112
115
|
|
|
116
|
+
private configureFastifyInstance(fastifyInstance: FastifyInstance) {
|
|
117
|
+
fastifyInstance.setErrorHandler((error, request, reply) => {
|
|
118
|
+
if (error instanceof HttpException) {
|
|
119
|
+
return reply.status(error.statusCode).send(error.response)
|
|
120
|
+
} else {
|
|
121
|
+
const statusCode = error.statusCode || 500
|
|
122
|
+
const message = error.message || 'Internal Server Error'
|
|
123
|
+
const response = {
|
|
124
|
+
statusCode,
|
|
125
|
+
message,
|
|
126
|
+
error: error.name || 'InternalServerError',
|
|
127
|
+
}
|
|
128
|
+
this.logger.error(
|
|
129
|
+
`Error occurred: ${error.message} on ${request.url}`,
|
|
130
|
+
error,
|
|
131
|
+
)
|
|
132
|
+
return reply.status(statusCode).send(response)
|
|
133
|
+
}
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
fastifyInstance.setNotFoundHandler((req, reply) => {
|
|
137
|
+
const response = {
|
|
138
|
+
statusCode: 404,
|
|
139
|
+
message: 'Not Found',
|
|
140
|
+
error: 'NotFound',
|
|
141
|
+
}
|
|
142
|
+
this.logger.error(`Route not found: ${req.url}`)
|
|
143
|
+
return reply.status(404).send(response)
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
|
|
113
147
|
private async initModules() {
|
|
114
148
|
const modules = this.moduleLoader.getAllModules()
|
|
115
149
|
const promises: PromiseLike<any>[] = []
|
|
@@ -161,6 +195,7 @@ export class NaviosApplication {
|
|
|
161
195
|
if (!this.server) {
|
|
162
196
|
throw new Error('Server is not initialized. Call init() first.')
|
|
163
197
|
}
|
|
164
|
-
await this.server.listen(options)
|
|
198
|
+
const res = await this.server.listen(options)
|
|
199
|
+
this.logger.debug(`Navios is listening on ${res}`)
|
|
165
200
|
}
|
|
166
201
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AnyZodObject,
|
|
1
|
+
import type { AnyZodObject, output, z, ZodOptional } from 'zod'
|
|
2
2
|
|
|
3
3
|
import type { FactoryNotFound, UnknownError } from './index.mjs'
|
|
4
4
|
import type { InjectionToken } from './injection-token.mjs'
|
|
@@ -33,11 +33,17 @@ export class ProxyServiceLocator implements ServiceLocator {
|
|
|
33
33
|
): void {
|
|
34
34
|
return this.serviceLocator.registerAbstractFactory(token, factory)
|
|
35
35
|
}
|
|
36
|
-
public getInstance<
|
|
36
|
+
public getInstance<
|
|
37
|
+
Instance,
|
|
38
|
+
Schema extends AnyZodObject | ZodOptional<AnyZodObject> | undefined,
|
|
39
|
+
>(
|
|
37
40
|
token: InjectionToken<Instance, Schema>,
|
|
38
|
-
args: Schema extends AnyZodObject
|
|
41
|
+
args: Schema extends AnyZodObject
|
|
42
|
+
? z.input<Schema>
|
|
43
|
+
: Schema extends ZodOptional<AnyZodObject>
|
|
44
|
+
? z.input<Schema> | undefined
|
|
45
|
+
: undefined,
|
|
39
46
|
): Promise<[undefined, Instance] | [UnknownError | FactoryNotFound]> {
|
|
40
|
-
// @ts-expect-error
|
|
41
47
|
return this.ctx.inject(token, args).then(
|
|
42
48
|
(instance) => {
|
|
43
49
|
return [undefined, instance]
|
|
@@ -47,16 +53,29 @@ export class ProxyServiceLocator implements ServiceLocator {
|
|
|
47
53
|
},
|
|
48
54
|
)
|
|
49
55
|
}
|
|
50
|
-
public getOrThrowInstance<
|
|
56
|
+
public getOrThrowInstance<
|
|
57
|
+
Instance,
|
|
58
|
+
Schema extends AnyZodObject | ZodOptional<AnyZodObject> | undefined,
|
|
59
|
+
>(
|
|
51
60
|
token: InjectionToken<Instance, Schema>,
|
|
52
|
-
args: Schema extends AnyZodObject
|
|
61
|
+
args: Schema extends AnyZodObject
|
|
62
|
+
? z.input<Schema>
|
|
63
|
+
: Schema extends ZodOptional<AnyZodObject>
|
|
64
|
+
? z.input<Schema> | undefined
|
|
65
|
+
: undefined,
|
|
53
66
|
): Promise<Instance> {
|
|
54
|
-
// @ts-expect-error We need to pass the args to the ctx.inject method
|
|
55
67
|
return this.ctx.inject(token, args)
|
|
56
68
|
}
|
|
57
|
-
public getSyncInstance<
|
|
69
|
+
public getSyncInstance<
|
|
70
|
+
Instance,
|
|
71
|
+
Schema extends AnyZodObject | ZodOptional<AnyZodObject> | undefined,
|
|
72
|
+
>(
|
|
58
73
|
token: InjectionToken<Instance, Schema>,
|
|
59
|
-
args: Schema extends AnyZodObject
|
|
74
|
+
args: Schema extends AnyZodObject
|
|
75
|
+
? z.input<Schema>
|
|
76
|
+
: Schema extends ZodOptional<AnyZodObject>
|
|
77
|
+
? z.input<Schema> | undefined
|
|
78
|
+
: undefined,
|
|
60
79
|
): Instance | null {
|
|
61
80
|
return this.serviceLocator.getSyncInstance(token, args)
|
|
62
81
|
}
|
|
@@ -456,7 +456,15 @@ export class ServiceLocator {
|
|
|
456
456
|
makeInstanceName(token: InjectionToken<any, any>, args: any) {
|
|
457
457
|
let stringifiedArgs = args
|
|
458
458
|
? ':' +
|
|
459
|
-
JSON.stringify(args)
|
|
459
|
+
JSON.stringify(args, (_, value) => {
|
|
460
|
+
if (typeof value === 'function') {
|
|
461
|
+
return `function:${value.name}(${value.length})`
|
|
462
|
+
}
|
|
463
|
+
if (typeof value === 'symbol') {
|
|
464
|
+
return value.toString()
|
|
465
|
+
}
|
|
466
|
+
return value
|
|
467
|
+
})
|
|
460
468
|
.replaceAll(/"/g, '')
|
|
461
469
|
.replaceAll(/:/g, '=')
|
|
462
470
|
.replaceAll(/,/g, '|')
|