@zanobijs/core 1.2.0-beta.2 → 2.0.0-beta.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/lib/cjs/exceptions/circularModuleImport.exception.js +21 -0
- package/{exceptions → lib/cjs/exceptions}/constant.message.js +10 -6
- package/{exceptions → lib/cjs/exceptions}/invalid.module.exception.js +8 -7
- package/lib/cjs/exceptions/invalidProvider.module.exception.js +20 -0
- package/lib/cjs/exceptions/missingInjectToken.exception.js +20 -0
- package/{exceptions → lib/cjs/exceptions}/resolution.exception.js +11 -10
- package/lib/cjs/factory.js +213 -0
- package/lib/cjs/index.js +30 -0
- package/lib/cjs/injector/injector.js +141 -0
- package/{injector → lib/cjs/injector}/module.js +28 -26
- package/{metadata.js → lib/cjs/metadata.js} +31 -21
- package/lib/esm/exceptions/circularModuleImport.exception.js +19 -0
- package/lib/esm/exceptions/constant.message.js +8 -0
- package/lib/esm/exceptions/invalid.module.exception.js +18 -0
- package/lib/esm/exceptions/invalidProvider.module.exception.js +18 -0
- package/lib/esm/exceptions/missingInjectToken.exception.js +18 -0
- package/lib/esm/exceptions/resolution.exception.js +37 -0
- package/lib/esm/factory.js +210 -0
- package/lib/esm/index.js +9 -0
- package/{injector → lib/esm/injector}/injector.js +30 -17
- package/lib/esm/injector/module.js +213 -0
- package/lib/esm/metadata.js +164 -0
- package/lib/esm/package.json +1 -0
- package/lib/types/exceptions/circularModuleImport.exception.d.ts +13 -0
- package/{exceptions → lib/types/exceptions}/constant.message.d.ts +2 -0
- package/lib/types/exceptions/index.d.ts +6 -0
- package/lib/types/exceptions/missingInjectToken.exception.d.ts +12 -0
- package/lib/types/factory.d.ts +106 -0
- package/lib/types/index.d.ts +4 -0
- package/{injector → lib/types/injector}/injector.d.ts +2 -0
- package/{metadata.d.ts → lib/types/metadata.d.ts} +8 -1
- package/package.json +20 -4
- package/CHANGELOG.md +0 -332
- package/LICENSE +0 -33
- package/exceptions/index.d.ts +0 -2
- package/exceptions/index.js +0 -5
- package/exceptions/invalidProvider.module.exception.js +0 -19
- package/factory.d.ts +0 -55
- package/factory.js +0 -120
- package/index.d.ts +0 -3
- package/index.js +0 -8
- package/injector/index.js +0 -5
- package/interfaces/factory.interface.js +0 -2
- package/interfaces/globals.interface.js +0 -2
- package/interfaces/index.js +0 -5
- package/tsconfig.build.json +0 -17
- /package/{exceptions → lib/types/exceptions}/invalid.module.exception.d.ts +0 -0
- /package/{exceptions → lib/types/exceptions}/invalidProvider.module.exception.d.ts +0 -0
- /package/{exceptions → lib/types/exceptions}/resolution.exception.d.ts +0 -0
- /package/{injector → lib/types/injector}/index.d.ts +0 -0
- /package/{injector → lib/types/injector}/module.d.ts +0 -0
- /package/{interfaces → lib/types/interfaces}/factory.interface.d.ts +0 -0
- /package/{interfaces → lib/types/interfaces}/globals.interface.d.ts +0 -0
- /package/{interfaces → lib/types/interfaces}/index.d.ts +0 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { aliasTo } from 'awilix';
|
|
3
|
+
import { isClass, unCapitalize, isEmpty } from '@zanobijs/common/utils/shared.utils';
|
|
4
|
+
import { Logger } from '@zanobijs/common/utils';
|
|
5
|
+
import { Injector } from './injector.js';
|
|
6
|
+
import { Metadata } from '../metadata.js';
|
|
7
|
+
import { InvalidModuleAnnotationException } from '../exceptions/invalid.module.exception.js';
|
|
8
|
+
import { InvalidProviderModuleException } from '../exceptions/invalidProvider.module.exception.js';
|
|
9
|
+
import '@zanobijs/common/exceptions/runtime.exception';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Módulo para gestionar la configuración y el registro de
|
|
13
|
+
* controladores, servicios, proveedores y dependencias.
|
|
14
|
+
*/
|
|
15
|
+
class Module {
|
|
16
|
+
config;
|
|
17
|
+
module;
|
|
18
|
+
logger;
|
|
19
|
+
injector;
|
|
20
|
+
registerClass = {};
|
|
21
|
+
dependenciesClass = [];
|
|
22
|
+
metadata;
|
|
23
|
+
types = ['controller', 'service'];
|
|
24
|
+
listProviders = new Map();
|
|
25
|
+
listProvidersClass = new Map();
|
|
26
|
+
/**
|
|
27
|
+
* Constructor del módulo.
|
|
28
|
+
*/
|
|
29
|
+
constructor() {
|
|
30
|
+
this.logger = Logger();
|
|
31
|
+
this.metadata = Metadata.getInstance();
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Configura el módulo con la información proporcionada.
|
|
35
|
+
* @param {any} module - Módulo a configurar.
|
|
36
|
+
*/
|
|
37
|
+
setup(module) {
|
|
38
|
+
if (this.metadata.isTypeModule(module)) {
|
|
39
|
+
this.module = module;
|
|
40
|
+
this.logger.debug('Module - Setup - Create Injector to module:', module.name);
|
|
41
|
+
this.injector = new Injector(this.module, this.listProviders, this.listProvidersClass);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
throw new InvalidModuleAnnotationException();
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/** Metodo de exposicion para escarnear proveedores y obtener
|
|
48
|
+
* la metadata del modulo que esta confirgurado(Setup) en ese momento
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
scan() {
|
|
52
|
+
this.injector.scanProviders();
|
|
53
|
+
this.getMetadataModule();
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Este metodo incializa una serie de pasos dentro de los cuales son:
|
|
57
|
+
* obtener la metada del modulo configurado actualmente, busca y registra
|
|
58
|
+
* las dependencias de las entidades (controladores y servicios), registra
|
|
59
|
+
* las dependencias de los proveedores que son tipo entidad (clase abst a clase)
|
|
60
|
+
* y registra las dependecias con alias cuando sus nombres no son iguales
|
|
61
|
+
* @public
|
|
62
|
+
*/
|
|
63
|
+
initialize() {
|
|
64
|
+
this.logger.debug('Module - Initialize:', this.module.name);
|
|
65
|
+
this.getMetadataModule();
|
|
66
|
+
this.registerDependenciesFromEntity();
|
|
67
|
+
this.registerEntitiesFromProvider();
|
|
68
|
+
this.registerDependenciesToAlias();
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Extrae los metadatos del módulo usando reflect-metadata.
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
getMetadataModule() {
|
|
75
|
+
this.config = this.metadata.getMetadataModule(this.module);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Registra las entidades de configuración en el módulo.
|
|
79
|
+
* @private
|
|
80
|
+
*/
|
|
81
|
+
registerDependenciesFromEntity() {
|
|
82
|
+
this.registerEntities('controllers');
|
|
83
|
+
this.registerEntities('services');
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* se encarga de filtrar los metadatos del modulo buscando si es controlador o servicio
|
|
87
|
+
* para luego buscar en los metadatos el nombre de la dependecia y de quien depende
|
|
88
|
+
* para se agrupado y agregarlos a la lista de clases a registrar en el contenedor.
|
|
89
|
+
* @param {('controllers' | 'services')} entityType - Tipo de entidad a registrar.
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
registerEntities(entityType) {
|
|
93
|
+
const entities = this.config[entityType];
|
|
94
|
+
this.logger.debug('Module - searching for entities type:', entityType);
|
|
95
|
+
if (entities && entities.length > 0) {
|
|
96
|
+
const registeredEntities = entities
|
|
97
|
+
.filter((target) => {
|
|
98
|
+
return (isClass(target) &&
|
|
99
|
+
this.types.includes(this.metadata.determineType(target)));
|
|
100
|
+
})
|
|
101
|
+
.map((target) => {
|
|
102
|
+
this.logger.debug('Module - Entity', `<<< ${target.name} >>>`);
|
|
103
|
+
this.groupDependenciesForAlias(target);
|
|
104
|
+
const targetName = unCapitalize(target.name);
|
|
105
|
+
return {
|
|
106
|
+
[target.name]: this.injector.getInjectorClass(target),
|
|
107
|
+
[targetName]: aliasTo(target.name),
|
|
108
|
+
};
|
|
109
|
+
});
|
|
110
|
+
Object.assign(this.registerClass, ...registeredEntities);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.logger.debug('Module - Does not have entities of that type', entityType);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Se encarga de recorrer la lista de proveedores que son tipo clase para
|
|
118
|
+
* luego buscar en los metadatos el nombre de la dependecia y de quien depende
|
|
119
|
+
* para se agrupado y agregarlos a la lista de clases a registrar en el contenedor.
|
|
120
|
+
* toma el proveedor que es nombre la clase o un token (nombre de pendencia)
|
|
121
|
+
* que va ser sustituida por la clase de useClass
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
registerEntitiesFromProvider() {
|
|
125
|
+
this.logger.debug('Module - searching for entities from provider');
|
|
126
|
+
for (const [key, value] of this.listProvidersClass) {
|
|
127
|
+
try {
|
|
128
|
+
this.logger.debug('Module - Entity provider', `<<< ${key} >>>`);
|
|
129
|
+
const type = this.metadata.determineType(value);
|
|
130
|
+
if (!this.types.includes(type)) {
|
|
131
|
+
throw new Error('The type used in the provider useClass property is not valid');
|
|
132
|
+
}
|
|
133
|
+
this.groupDependenciesForAlias(value);
|
|
134
|
+
const targetName = unCapitalize(value.name);
|
|
135
|
+
const targetProviderName = unCapitalize(key);
|
|
136
|
+
const registerProviderWithEntities = {
|
|
137
|
+
[value.name]: this.injector.getInjectorClass(value),
|
|
138
|
+
[targetName]: aliasTo(value.name),
|
|
139
|
+
[key]: aliasTo(value.name),
|
|
140
|
+
[targetProviderName]: aliasTo(value.name),
|
|
141
|
+
};
|
|
142
|
+
Object.assign(this.registerClass, registerProviderWithEntities);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
throw new InvalidProviderModuleException(value.name, this.module.name, error.message);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Agrupación de dependencias para alias
|
|
151
|
+
*
|
|
152
|
+
* Este método agrupa las dependencias de la clase utilizando el método
|
|
153
|
+
* `getClassDependencies` de la instancia `metadata`. Si la clase
|
|
154
|
+
* tiene dependencias y estas no están vacías, las añade a la propiedad
|
|
155
|
+
* `dependenciesClass` de la instancia actual para luego validar si existe
|
|
156
|
+
* alguna dependencia con un nombre diferente y asiganar un alias.
|
|
157
|
+
*
|
|
158
|
+
* @private
|
|
159
|
+
* @param {Function} target - La clase objetivo de la cual se quieren obtener las dependencias.
|
|
160
|
+
*/
|
|
161
|
+
groupDependenciesForAlias(target) {
|
|
162
|
+
const dependencies = this.metadata.getClassDependencies(target);
|
|
163
|
+
this.logger.debug(`Module - List dependecies to group by ${target.name}`, dependencies);
|
|
164
|
+
if (dependencies && !isEmpty(dependencies)) {
|
|
165
|
+
this.dependenciesClass = [...this.dependenciesClass, ...dependencies];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* recorre las dependencias agrupadas y registra con un alias
|
|
170
|
+
* aquellas que tienen nombres diferente a la que esta registrada.
|
|
171
|
+
*
|
|
172
|
+
* @private
|
|
173
|
+
* @example
|
|
174
|
+
* contructor(private serviceA: ServiceA) // parametro con nombre igual
|
|
175
|
+
* contructor(private sA: ServiceA) // parametro con nombre diferente
|
|
176
|
+
*/
|
|
177
|
+
registerDependenciesToAlias() {
|
|
178
|
+
this.logger.debug('Module - dependencies to register as candidates ', this.dependenciesClass);
|
|
179
|
+
this.dependenciesClass.forEach((dependency) => {
|
|
180
|
+
if (!this.registerClass[dependency.nameParameter]) {
|
|
181
|
+
this.registerClass[dependency.nameParameter] = aliasTo(dependency.nameClassContainer);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Toma el listado proveedores y los une al listado de clases que van
|
|
187
|
+
* a registrar en el contenedor (asValue y asFunction) para ser resueltos
|
|
188
|
+
*/
|
|
189
|
+
registerAllProviders() {
|
|
190
|
+
this.logger.debug('Module - Register list provider:', this.module.name);
|
|
191
|
+
const listProviders = this.injector.getAllProvider();
|
|
192
|
+
listProviders.forEach((value, key) => {
|
|
193
|
+
this.registerClass[key] = value;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Devuelve las importaciones del módulo.
|
|
198
|
+
* @returns {TClass[] | undefined} - Importaciones del módulo.
|
|
199
|
+
*/
|
|
200
|
+
getImports() {
|
|
201
|
+
return this.config.imports;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Devuelve las clases registradas en el módulo.
|
|
205
|
+
* @returns {any} - Clases registradas.
|
|
206
|
+
*/
|
|
207
|
+
getRegisterClass() {
|
|
208
|
+
this.logger.debug(`Module ${this.module.name} - List of candidate classes to register in container.`, this.registerClass);
|
|
209
|
+
return this.registerClass;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export { Module };
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { IS_EXPORT, IS_SERVICE, IS_CONTROLLER, IS_IMPORTS, IS_MODULE, MODULE_EXPORTS, MODULE_SERVICES, MODULE_CONTROLLERS, MODULE_IMPORTS, DEPENDENCIES_CLASS, DEPENDENCIES_PARAMETERS, DEPENDENCIES_INJECT, LIFETIME_CLASS } from '@zanobijs/common/utils/constants';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* La clase `Metadata` proporciona métodos para acceder y manipular
|
|
5
|
+
* metadatos relacionados con diversos componentes y módulos.
|
|
6
|
+
*/
|
|
7
|
+
class Metadata {
|
|
8
|
+
static instance;
|
|
9
|
+
metadataMap = {
|
|
10
|
+
[IS_MODULE]: 'module',
|
|
11
|
+
[IS_IMPORTS]: 'import',
|
|
12
|
+
[IS_CONTROLLER]: 'controller',
|
|
13
|
+
[IS_SERVICE]: 'service',
|
|
14
|
+
[IS_EXPORT]: 'export',
|
|
15
|
+
};
|
|
16
|
+
constructor() { }
|
|
17
|
+
/**
|
|
18
|
+
* Obtiene la instancia única (singleton) de `Metadata`.
|
|
19
|
+
*
|
|
20
|
+
* @returns La instancia única de `Metadata`.
|
|
21
|
+
*/
|
|
22
|
+
static getInstance() {
|
|
23
|
+
if (!this.instance) {
|
|
24
|
+
this.instance = new Metadata();
|
|
25
|
+
}
|
|
26
|
+
return this.instance;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Obtiene los metadatos de un módulo específico.
|
|
30
|
+
*
|
|
31
|
+
* @param { IModuleConfig } module - El módulo del cual obtener los metadatos.
|
|
32
|
+
* @returns Un objeto con los metadatos del módulo
|
|
33
|
+
* {imports, controllers ,services, exports }.
|
|
34
|
+
*/
|
|
35
|
+
getMetadataModule(module) {
|
|
36
|
+
return {
|
|
37
|
+
imports: Reflect.getMetadata(MODULE_IMPORTS, module),
|
|
38
|
+
controllers: Reflect.getMetadata(MODULE_CONTROLLERS, module),
|
|
39
|
+
services: Reflect.getMetadata(MODULE_SERVICES, module),
|
|
40
|
+
exports: Reflect.getMetadata(MODULE_EXPORTS, module),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Obtiene todas las dependencias asociadas con una clase.
|
|
45
|
+
*
|
|
46
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
47
|
+
* @returns Un objeto con las dependencias del target.
|
|
48
|
+
*/
|
|
49
|
+
getAllDependencies(target) {
|
|
50
|
+
return {
|
|
51
|
+
dClass: this.getClassDependencies(target),
|
|
52
|
+
dParam: this.getParameterDependencies(target),
|
|
53
|
+
dInject: this.getInjectionDependencies(target),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Obtiene las dependencias de clase asociadas con una clase.
|
|
58
|
+
*
|
|
59
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
60
|
+
* @returns Las dependencias de clase de la clase.
|
|
61
|
+
*/
|
|
62
|
+
getClassDependencies(target) {
|
|
63
|
+
return Reflect.getMetadata(DEPENDENCIES_CLASS, target);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Obtiene las dependencias de parámetro asociadas con una clase.
|
|
67
|
+
*
|
|
68
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
69
|
+
* @returns Las dependencias de parámetro de la clase.
|
|
70
|
+
*/
|
|
71
|
+
getParameterDependencies(target) {
|
|
72
|
+
return Reflect.getMetadata(DEPENDENCIES_PARAMETERS, target);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Obtiene las dependencias a inyectar asociadas con una clase.
|
|
76
|
+
*
|
|
77
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
78
|
+
* @returns Un Map con las dependencias a inyectar de la clase.
|
|
79
|
+
*/
|
|
80
|
+
getInjectionDependencies(target) {
|
|
81
|
+
return Reflect.getMetadata(DEPENDENCIES_INJECT, target) || new Map();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Obtiene el lifetime declarado en `@Injectable`/`@Controller` de una clase.
|
|
85
|
+
*
|
|
86
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
87
|
+
* @returns El lifetime de la clase. `'singleton'` si no se declaró ninguno.
|
|
88
|
+
*/
|
|
89
|
+
getLifetime(target) {
|
|
90
|
+
return Reflect.getMetadata(LIFETIME_CLASS, target) ?? 'singleton';
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Determina el tipo de una clase basado en sus metadatos.
|
|
94
|
+
*
|
|
95
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
96
|
+
* @returns Una cadena de texto que indica el tipo del clase segun el mapa de metadata.
|
|
97
|
+
* @throws {Error} Lanza un error si el tipo de la clase es desconocido.
|
|
98
|
+
*/
|
|
99
|
+
determineType(target) {
|
|
100
|
+
for (const key in this.metadataMap) {
|
|
101
|
+
if (this.hasMetadata(key, target)) {
|
|
102
|
+
return this.metadataMap[key];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
throw new Error(`${target.name} type is unknown`);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Verifica si una clase tiene un metadato específico.
|
|
109
|
+
*
|
|
110
|
+
* @param metadataKey - La llave del metadato a verificar.
|
|
111
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
112
|
+
* @returns Verdadero si el target tiene el metadato, falso en caso contrario.
|
|
113
|
+
*/
|
|
114
|
+
hasMetadata(metadataKey, target) {
|
|
115
|
+
return !!Reflect.getMetadata(metadataKey, target);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Verifica si una clase es de tipo "module".
|
|
119
|
+
*
|
|
120
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
121
|
+
* @returns Verdadero si el target es de tipo "module", falso en caso contrario.
|
|
122
|
+
*/
|
|
123
|
+
isTypeModule(target) {
|
|
124
|
+
return this.hasMetadata(IS_MODULE, target);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Verifica si una clase es de tipo "import".
|
|
128
|
+
*
|
|
129
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
130
|
+
* @returns Verdadero si el target es de tipo "import", falso en caso contrario.
|
|
131
|
+
*/
|
|
132
|
+
isTypeImport(target) {
|
|
133
|
+
return this.hasMetadata(IS_IMPORTS, target);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Verifica si una clase es de tipo "controller".
|
|
137
|
+
*
|
|
138
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
139
|
+
* @returns Verdadero si el target es de tipo "controller", falso en caso contrario.
|
|
140
|
+
*/
|
|
141
|
+
isTypeController(target) {
|
|
142
|
+
return this.hasMetadata(IS_CONTROLLER, target);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Verifica si una clase es de tipo "service".
|
|
146
|
+
*
|
|
147
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
148
|
+
* @returns Verdadero si el target es de tipo "service", falso en caso contrario.
|
|
149
|
+
*/
|
|
150
|
+
isTypeService(target) {
|
|
151
|
+
return this.hasMetadata(IS_SERVICE, target);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Verifica si una clase es de tipo "export".
|
|
155
|
+
*
|
|
156
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
157
|
+
* @returns Verdadero si el target es de tipo "export", falso en caso contrario.
|
|
158
|
+
*/
|
|
159
|
+
isTypeExports(target) {
|
|
160
|
+
return this.hasMetadata(IS_EXPORT, target);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export { Metadata };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "type": "module" }
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RuntimeException } from '@zanobijs/common/exceptions/runtime.exception';
|
|
2
|
+
/**
|
|
3
|
+
* Excepción lanzada cuando el grafo de `imports` entre módulos contiene un
|
|
4
|
+
* ciclo: un módulo importa, directa o indirectamente, a otro módulo que ya
|
|
5
|
+
* lo está importando a él.
|
|
6
|
+
*
|
|
7
|
+
* @remarks
|
|
8
|
+
* Esta clase extiende la base `RuntimeException` de @zanobijs/common
|
|
9
|
+
* para proporcionar detalles adicionales del error.
|
|
10
|
+
*/
|
|
11
|
+
export declare class CircularModuleImportException extends RuntimeException {
|
|
12
|
+
constructor(chain: string);
|
|
13
|
+
}
|
|
@@ -2,3 +2,5 @@ export declare const MODULE_INVALID_ANNOTATION_ERROR: () => string;
|
|
|
2
2
|
export declare const CONTAINER_RESOLUTION_ERROR: (entity: string, resolutionError: string) => string;
|
|
3
3
|
export declare const CONTAINER_RESOLUTION_ENTITY_ERROR: (entity: string) => string;
|
|
4
4
|
export declare const PROVIDER_INVALID_MODULE_ERROR: (entity: string, moduleName: string) => string;
|
|
5
|
+
export declare const MISSING_INJECT_TOKEN_ERROR: (token: string, targetName: string, moduleName: string) => string;
|
|
6
|
+
export declare const CIRCULAR_MODULE_IMPORT_ERROR: (chain: string) => string;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from './constant.message';
|
|
2
|
+
export * from './invalid.module.exception';
|
|
3
|
+
export * from './invalidProvider.module.exception';
|
|
4
|
+
export * from './missingInjectToken.exception';
|
|
5
|
+
export * from './circularModuleImport.exception';
|
|
6
|
+
export * from './resolution.exception';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RuntimeException } from '@zanobijs/common/exceptions/runtime.exception';
|
|
2
|
+
/**
|
|
3
|
+
* Excepción lanzada cuando un `@Inject(token)` no encuentra su provider
|
|
4
|
+
* registrado, ni en el módulo actual ni en ninguno de los módulos importados.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* Esta clase extiende la base `RuntimeException` de @zanobijs/common
|
|
8
|
+
* para proporcionar detalles adicionales del error.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MissingInjectTokenException extends RuntimeException {
|
|
11
|
+
constructor(token: string, targetName: string, moduleName: string);
|
|
12
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { AwilixContainer } from 'awilix';
|
|
3
|
+
import { ILoggerService } from '@zanobijs/common';
|
|
4
|
+
import { IFactoryOptions } from './interfaces';
|
|
5
|
+
import { TClass } from './interfaces/globals.interface';
|
|
6
|
+
/**
|
|
7
|
+
* Handle atado a un scope de `awilix` puntual (una copia liviana del
|
|
8
|
+
* contenedor raíz, ver `Factory.createRequestScope`). Resuelve entidades
|
|
9
|
+
* `singleton` desde el contenedor raíz (reusadas, gratis) y entidades
|
|
10
|
+
* `request` desde este scope (instancia nueva, se descarta con él).
|
|
11
|
+
*/
|
|
12
|
+
export declare class RequestScope {
|
|
13
|
+
private readonly container;
|
|
14
|
+
private readonly logger;
|
|
15
|
+
constructor(container: AwilixContainer<any>, logger: ILoggerService);
|
|
16
|
+
/**
|
|
17
|
+
* Resuelve y devuelve una instancia del scope teniendo en cuenta el
|
|
18
|
+
* nombre de la entidad proporcionada.
|
|
19
|
+
* @param {string} className - Nombre de la entidad a resolver.
|
|
20
|
+
* @returns {T} - Instancia resuelta.
|
|
21
|
+
*/
|
|
22
|
+
get<T>(className: string): T;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Factory es una clase que facilita la creación y configuración de
|
|
26
|
+
* contenedores de inyección de dependencias utilizando metadatos y
|
|
27
|
+
* la librería `awilix` para registrar y resolver entidades como:
|
|
28
|
+
* controladores y servicios.
|
|
29
|
+
*/
|
|
30
|
+
export declare class Factory {
|
|
31
|
+
private moduleHandler;
|
|
32
|
+
private registeredClasses;
|
|
33
|
+
private container;
|
|
34
|
+
private logger;
|
|
35
|
+
private options;
|
|
36
|
+
private readonly scannedModules;
|
|
37
|
+
private readonly processedModules;
|
|
38
|
+
constructor(appModule: TClass, options?: IFactoryOptions);
|
|
39
|
+
/**
|
|
40
|
+
* Se encarga de escaenear modulo por modulo los proveedores con el fin de luego
|
|
41
|
+
* poder ser registrados e inyectados en quien depende de ese proveedor
|
|
42
|
+
* @param {TClass} module - Módulo desde el que se escanearan los proveedores.
|
|
43
|
+
* @param {TClass[]} path - Cadena de módulos ancestros en la recursión actual,
|
|
44
|
+
* usada para detectar ciclos de imports.
|
|
45
|
+
* @private
|
|
46
|
+
* @throws {CircularModuleImportException} Si `module` ya está en `path`.
|
|
47
|
+
*/
|
|
48
|
+
private scanProviderModule;
|
|
49
|
+
/**
|
|
50
|
+
* Se encarga tomar la lista de proveedores y registralos para luego se resueltos
|
|
51
|
+
* cuando el usuario lo solicite
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
private registerProviderScanedModules;
|
|
55
|
+
/**
|
|
56
|
+
* Procesa modulo por modulos registrando los controladores, servicios y proveedores,
|
|
57
|
+
* estos se le irá inyectando sus dependecias resueltas para ser usados por el usuario
|
|
58
|
+
* @param {TClass} module - Módulo desde el que se registrarán las clases.
|
|
59
|
+
* @private
|
|
60
|
+
*
|
|
61
|
+
* @remarks
|
|
62
|
+
* No repite la detección de ciclos: `scanProviderModule` ya recorrió este
|
|
63
|
+
* mismo grafo de imports antes (misma metadata, mismas aristas) y habría
|
|
64
|
+
* lanzado `CircularModuleImportException` si existiera uno. Solo se
|
|
65
|
+
* deduplica por módulo (`processedModules`) para el caso de diamante.
|
|
66
|
+
*/
|
|
67
|
+
private processClassModule;
|
|
68
|
+
/**
|
|
69
|
+
* Crea el contenedor de inyección de dependencias y registra el listado de
|
|
70
|
+
* controladores, servicio y proveedores que se ha venido creando a parti de escaneos
|
|
71
|
+
* y registros de clases.
|
|
72
|
+
* @returns {Factory} - Instancia actual de la fábrica.
|
|
73
|
+
*/
|
|
74
|
+
create(): Factory;
|
|
75
|
+
/**
|
|
76
|
+
* Resuelve y devuelve una instancia del contenedor
|
|
77
|
+
* teniendo en cuenta el nombre de la entidad proporcionada.
|
|
78
|
+
* @param {string} className - Nombre de la entidad a resolver.
|
|
79
|
+
* @returns {T} - Instancia resuelta.
|
|
80
|
+
* @throws {ContainerResolutionEntityException | ContainerResolutionException}
|
|
81
|
+
* Si `awilix` no logra resolver la entidad o alguna de sus dependencias.
|
|
82
|
+
* @throws Propaga sin modificar cualquier otro error (p. ej. uno lanzado por
|
|
83
|
+
* el propio constructor de la clase que se está resolviendo).
|
|
84
|
+
*/
|
|
85
|
+
get<T>(className: string): T;
|
|
86
|
+
/**
|
|
87
|
+
* Crea una copia liviana del contenedor raíz para usar durante una
|
|
88
|
+
* única invocación/petición (Lambda, Azure Function, request HTTP...).
|
|
89
|
+
*
|
|
90
|
+
* Las entidades `singleton` se reusan tal cual desde el contenedor raíz
|
|
91
|
+
* (cero costo). Las entidades con `lifetime: 'request'` (ver `@Injectable`)
|
|
92
|
+
* se resuelven de cero dentro de este scope y se descartan junto con él.
|
|
93
|
+
*
|
|
94
|
+
* @returns {RequestScope} - Handle atado a este scope puntual.
|
|
95
|
+
*/
|
|
96
|
+
createRequestScope(): RequestScope;
|
|
97
|
+
/**
|
|
98
|
+
* Se encarga de evaluar las opciones para ver si o no aplica y realizar lo correspondiente
|
|
99
|
+
*
|
|
100
|
+
* `ZANOBIJS_LOGGER`/`ZANOBIJS_LOGGER_USER` son pensadas para poder prenderse/apagarse
|
|
101
|
+
* desde la configuración de despliegue (variables de entorno de Lambda/contenedor) sin
|
|
102
|
+
* tocar código ni redeployar. Por eso, si el operador ya las configuró externamente,
|
|
103
|
+
* NO se pisan — `options` solo aplica como default cuando la variable no existe.
|
|
104
|
+
*/
|
|
105
|
+
private evaluateOptions;
|
|
106
|
+
}
|
|
@@ -33,6 +33,8 @@ export declare class Injector {
|
|
|
33
33
|
*
|
|
34
34
|
* @param { TClass} target - La clase objetivo.
|
|
35
35
|
* @returns {object} - Objeto con datos a inyectar.
|
|
36
|
+
* @throws {MissingInjectTokenException} Si un `@Inject(token)` de `target` no tiene
|
|
37
|
+
* su provider registrado en este módulo ni en ninguno de los módulos importados.
|
|
36
38
|
*/
|
|
37
39
|
getInjectData(target: TClass): object;
|
|
38
40
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IModuleConfig } from '@zanobijs/common';
|
|
1
|
+
import { ClassLifetime, IModuleConfig } from '@zanobijs/common';
|
|
2
2
|
import { TClass } from './interfaces';
|
|
3
3
|
/**
|
|
4
4
|
* La clase `Metadata` proporciona métodos para acceder y manipular
|
|
@@ -54,6 +54,13 @@ export declare class Metadata {
|
|
|
54
54
|
* @returns Un Map con las dependencias a inyectar de la clase.
|
|
55
55
|
*/
|
|
56
56
|
getInjectionDependencies(target: TClass): Map<string, string>;
|
|
57
|
+
/**
|
|
58
|
+
* Obtiene el lifetime declarado en `@Injectable`/`@Controller` de una clase.
|
|
59
|
+
*
|
|
60
|
+
* @param { TClass } target - La función/clase objetivo.
|
|
61
|
+
* @returns El lifetime de la clase. `'singleton'` si no se declaró ninguno.
|
|
62
|
+
*/
|
|
63
|
+
getLifetime(target: TClass): ClassLifetime;
|
|
57
64
|
/**
|
|
58
65
|
* Determina el tipo de una clase basado en sus metadatos.
|
|
59
66
|
*
|
package/package.json
CHANGED
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zanobijs/core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0-beta.0",
|
|
4
4
|
"description": "Zanobi - modern, small, powerful node.js lambda framework (@core)",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "John Edison Cortes Rivera [Devdroide] <johne.aplicativos@gmail.com>",
|
|
7
7
|
"license": "ZanobiJS Usage License \n\n Review the LICENSE file.\n\n Revise el archivo de LICENCIA.",
|
|
8
|
-
"
|
|
8
|
+
"main": "./lib/cjs/index.js",
|
|
9
|
+
"module": "./lib/esm/index.js",
|
|
10
|
+
"typings": "./lib/types/index.d.ts",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./lib/types/index.d.ts",
|
|
14
|
+
"import": "./lib/esm/index.js",
|
|
15
|
+
"require": "./lib/cjs/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"lib"
|
|
20
|
+
],
|
|
9
21
|
"repository": {
|
|
10
22
|
"type": "git",
|
|
11
23
|
"url": "git+https://github.com/devdroide/ZanobiJS.git",
|
|
@@ -24,10 +36,14 @@
|
|
|
24
36
|
"homepage": "https://github.com/devdroide/ZanobiJS#readme",
|
|
25
37
|
"dependencies": {
|
|
26
38
|
"awilix": "10.0.2",
|
|
27
|
-
"reflect-metadata": "^0.1.13"
|
|
39
|
+
"reflect-metadata": "^0.1.13",
|
|
40
|
+
"tslib": "^2.8.1"
|
|
28
41
|
},
|
|
29
42
|
"peerDependencies": {
|
|
30
43
|
"@zanobijs/common": "*"
|
|
31
44
|
},
|
|
32
|
-
"
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">= 22.13.0"
|
|
47
|
+
},
|
|
48
|
+
"gitHead": "201c1b2c289b80d94fcc899dc087b1d95de801d7"
|
|
33
49
|
}
|