|
1
|
|
|
import { logger } from '@/core'; |
|
2
|
|
|
import { ExpressBean } from '@/ExpressBeansTypes'; |
|
3
|
|
|
|
|
4
|
|
|
function getSingleton<T>(singletonClass: T & ExpressBean): T & ExpressBean { |
|
5
|
|
|
if (singletonClass) { |
|
6
|
|
|
if (singletonClass._instance) { |
|
7
|
|
|
return singletonClass._instance; |
|
8
|
|
|
} |
|
9
|
|
|
const className = Reflect.getOwnPropertyDescriptor(singletonClass, 'name')?.value; |
|
10
|
|
|
if (!className) { |
|
11
|
|
|
throw new Error(`Cannot get instance for a class without name: ${JSON.stringify(singletonClass)}`); |
|
12
|
|
|
} |
|
13
|
|
|
throw new Error(`Cannot get instance from ${className}. Make sure that ${className} has @Bean as class decorator`); |
|
14
|
|
|
} |
|
15
|
|
|
|
|
16
|
|
|
if (!hasName(singletonClass)) { |
|
17
|
|
|
throw new Error(`Cannot get instance for ${JSON.stringify(singletonClass)}: it is not an ExpressBean`); |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
if (!isABean(singletonClass)) { |
|
21
|
|
|
const className = (singletonClass as any).name; |
|
22
|
|
|
throw new Error(`Cannot get instance from ${className}. Make sure that ${className} has @Bean as class decorator`); |
|
23
|
|
|
} |
|
24
|
|
|
|
|
25
|
|
|
const bean = singletonClass as unknown as ExpressBean; |
|
26
|
|
|
return bean._instance; |
|
27
|
|
|
} |
|
28
|
|
|
|
|
29
|
|
|
/** |
|
30
|
|
|
* Gets singleton instance by its static property |
|
31
|
|
|
* @decorator |
|
32
|
|
|
* @param singletonClass |
|
33
|
|
|
*/ |
|
34
|
|
|
export function InjectBean<T extends object>(singletonClass: NonNullable<T>) { |
|
35
|
|
|
return (_value: unknown, _context: ClassFieldDecoratorContext) => () => new Proxy<T>( |
|
36
|
|
|
singletonClass ?? {}, |
|
37
|
|
|
{ |
|
38
|
|
|
get: (target, property) => { |
|
39
|
|
|
if (property === '_beanUUID' || property === '_className') { |
|
40
|
|
|
return (target as ExpressBean)[property]; |
|
41
|
|
|
} |
|
42
|
|
|
const singletonInstance = getSingleton(singletonClass); |
|
43
|
|
|
const className = (singletonInstance as unknown as ExpressBean)._className; |
|
44
|
|
|
logger.debug(`proxying ${className}.${String(property)}`); |
|
45
|
|
|
return (singletonInstance as any)[property]; |
|
46
|
|
|
}, |
|
47
|
|
|
}, |
|
48
|
|
|
) as any; |
|
49
|
|
|
} |
|
50
|
|
|
|