@zanobijs/core 1.1.1-beta.0 → 1.2.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/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [1.2.0-beta.0](https://github.com/devdroide/ZanobiJS/compare/v1.1.1-beta.0...v1.2.0-beta.0) (2025-05-28)
7
+
8
+ ### Features
9
+
10
+ - **core,test:** Added the ability to use useClass and useFactory as providers ([bff63e2](https://github.com/devdroide/ZanobiJS/commit/bff63e2d73fa03ef72f38b3c7c6f5a51ad9ddf80))
11
+ - **core,test:** Added type validation to prevent errors in providers with useClass ([6e64d3b](https://github.com/devdroide/ZanobiJS/commit/6e64d3b6a46965ad9affa697980b6862b1ae8be0))
12
+ - **core:** ✨ new provider with useClass ([668d981](https://github.com/devdroide/ZanobiJS/commit/668d981890e2a43f615ae8f78f025e3c33db9707))
13
+
6
14
  ## [1.1.1-beta.0](https://github.com/devdroide/ZanobiJS/compare/v1.1.0...v1.1.1-beta.0) (2025-05-27)
7
15
 
8
16
  **Note:** Version bump only for package @zanobijs/core
@@ -1,3 +1,4 @@
1
1
  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
+ export declare const PROVIDER_INVALID_MODULE_ERROR: (entity: string, moduleName: string) => string;
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CONTAINER_RESOLUTION_ENTITY_ERROR = exports.CONTAINER_RESOLUTION_ERROR = exports.MODULE_INVALID_ANNOTATION_ERROR = void 0;
3
+ exports.PROVIDER_INVALID_MODULE_ERROR = exports.CONTAINER_RESOLUTION_ENTITY_ERROR = exports.CONTAINER_RESOLUTION_ERROR = exports.MODULE_INVALID_ANNOTATION_ERROR = void 0;
4
4
  const MODULE_INVALID_ANNOTATION_ERROR = () => 'The class must have an annotation @Module()';
5
5
  exports.MODULE_INVALID_ANNOTATION_ERROR = MODULE_INVALID_ANNOTATION_ERROR;
6
6
  const CONTAINER_RESOLUTION_ERROR = (entity, resolutionError) => `${resolutionError} please review '${entity}' and its dependencies.`;
7
7
  exports.CONTAINER_RESOLUTION_ERROR = CONTAINER_RESOLUTION_ERROR;
8
8
  const CONTAINER_RESOLUTION_ENTITY_ERROR = (entity) => `Please check that the entity '${entity}' exists and is registered in @modulo`;
9
9
  exports.CONTAINER_RESOLUTION_ENTITY_ERROR = CONTAINER_RESOLUTION_ENTITY_ERROR;
10
+ const PROVIDER_INVALID_MODULE_ERROR = (entity, moduleName) => `Please check that ${entity} located in the @module ${moduleName} exists and is @Injectable().`;
11
+ exports.PROVIDER_INVALID_MODULE_ERROR = PROVIDER_INVALID_MODULE_ERROR;
@@ -0,0 +1,12 @@
1
+ import { RuntimeException } from '@zanobijs/common/exceptions/runtime.exception';
2
+ /**
3
+ * Excepción lanzada cuando una clase Modulo no tiene un provedor definido correctamente
4
+ * de @zanobijs/common
5
+ *
6
+ * @remarks
7
+ * Esta clase extiende la base `RuntimeException`de @zanobijs/common
8
+ * para proporcionar detalles adicionales específicos a esquemas de módulos inválidos.
9
+ */
10
+ export declare class InvalidProviderModuleException extends RuntimeException {
11
+ constructor(entity: string, moduleName: string, detail: string);
12
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.InvalidProviderModuleException = void 0;
4
+ const runtime_exception_1 = require("@zanobijs/common/exceptions/runtime.exception");
5
+ const constant_message_1 = require("./constant.message");
6
+ /**
7
+ * Excepción lanzada cuando una clase Modulo no tiene un provedor definido correctamente
8
+ * de @zanobijs/common
9
+ *
10
+ * @remarks
11
+ * Esta clase extiende la base `RuntimeException`de @zanobijs/common
12
+ * para proporcionar detalles adicionales específicos a esquemas de módulos inválidos.
13
+ */
14
+ class InvalidProviderModuleException extends runtime_exception_1.RuntimeException {
15
+ constructor(entity, moduleName, detail) {
16
+ super((0, constant_message_1.PROVIDER_INVALID_MODULE_ERROR)(entity, moduleName), detail);
17
+ }
18
+ }
19
+ exports.InvalidProviderModuleException = InvalidProviderModuleException;
@@ -8,7 +8,8 @@ export type Constructor<T> = {
8
8
  */
9
9
  export declare class Injector {
10
10
  private module;
11
- private listProviders;
11
+ private readonly listProviders;
12
+ private readonly listProvidersClass;
12
13
  private metadata;
13
14
  private logger;
14
15
  private moduleName;
@@ -18,7 +19,7 @@ export declare class Injector {
18
19
  * @param {Module} module - El módulo debe tener el decorador `@Module`
19
20
  * para poderlo procesar.
20
21
  */
21
- constructor(module: TClass, listProviders: Map<string, any>);
22
+ constructor(module: TClass, listProviders: Map<string, any>, listProvidersClass: Map<string, any>);
22
23
  /**
23
24
  * Este método privado recorre el array de los servicios del modulo para
24
25
  * buscar los proveedores tipo objeto a injectar y los almacena en una
@@ -27,8 +28,8 @@ export declare class Injector {
27
28
  */
28
29
  private scanProviders;
29
30
  /**
30
- * Método para obtener un objeto con los parámetros(key) y valores(useValue)
31
- * que se inyectarán en la clase (target) mediante asClass().inject().
31
+ * Método para obtener un objeto con los parámetros(key) y valores(useValue, useClass, useFactory)
32
+ * que se inyectarán en la clase (target).
32
33
  *
33
34
  * @param { TClass} target - La clase objetivo.
34
35
  * @returns {object} - Objeto con datos a inyectar.
@@ -44,27 +45,25 @@ export declare class Injector {
44
45
  * @param {any} target - La clase objetivo.
45
46
  * @returns - El injector configurado.
46
47
  */
47
- getInjectorClass(target: any): {
48
- interface: any;
48
+ getInjectorClass(target: TClass): {
49
+ interface: TClass;
49
50
  injectionMode?: import("awilix").InjectionModeType;
50
51
  injector?: import("awilix").InjectorFunction;
51
- setLifetime(lifetime: import("awilix").LifetimeType): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
52
- setInjectionMode(mode: import("awilix").InjectionModeType): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
53
- singleton(): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
54
- scoped(): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
55
- transient(): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
56
- proxy(): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
57
- classic(): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
58
- inject(injector: import("awilix").InjectorFunction): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
59
- resolve<U extends object>(container: import("awilix").AwilixContainer<U>): object;
52
+ setLifetime(lifetime: import("awilix").LifetimeType): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
53
+ setInjectionMode(mode: import("awilix").InjectionModeType): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
54
+ singleton(): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
55
+ scoped(): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
56
+ transient(): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
57
+ proxy(): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
58
+ classic(): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
59
+ inject(injector: import("awilix").InjectorFunction): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
60
+ resolve<U extends object>(container: import("awilix").AwilixContainer<U>): any;
60
61
  name?: string;
61
62
  lifetime?: import("awilix").LifetimeType;
62
- register?: (...args: any[]) => import("awilix").Resolver<object>;
63
+ register?: (...args: any[]) => import("awilix").Resolver<any>;
63
64
  isLeakSafe?: boolean;
64
- dispose?: import("awilix").Disposer<object>;
65
- disposer(dispose: import("awilix").Disposer<object>): import("awilix").BuildResolver<object> & import("awilix").DisposableResolver<object>;
65
+ dispose?: import("awilix").Disposer<any>;
66
+ disposer(dispose: import("awilix").Disposer<any>): import("awilix").BuildResolver<any> & import("awilix").DisposableResolver<any>;
66
67
  };
67
68
  getAllProvider(): Map<string, any>;
68
- getInjectProvider(provider: any): import("awilix").Resolver<any>;
69
- funtionInjectData(injectData: any): () => any;
70
69
  }
@@ -12,6 +12,7 @@ const awilix_1 = require("awilix");
12
12
  class Injector {
13
13
  module;
14
14
  listProviders;
15
+ listProvidersClass;
15
16
  metadata;
16
17
  logger;
17
18
  moduleName = '';
@@ -21,12 +22,13 @@ class Injector {
21
22
  * @param {Module} module - El módulo debe tener el decorador `@Module`
22
23
  * para poderlo procesar.
23
24
  */
24
- constructor(module, listProviders) {
25
+ constructor(module, listProviders, listProvidersClass) {
25
26
  this.metadata = metadata_1.Metadata.getInstance();
26
27
  this.logger = (0, utils_1.Logger)();
27
28
  this.moduleName = module.name;
28
29
  this.module = module;
29
30
  this.listProviders = listProviders;
31
+ this.listProvidersClass = listProvidersClass;
30
32
  this.scanProviders();
31
33
  }
32
34
  /**
@@ -39,14 +41,42 @@ class Injector {
39
41
  this.logger.debug('Injector - Scan provider to module:', this.moduleName);
40
42
  const { services } = this.metadata.getMetadataModule(this.module);
41
43
  services.forEach((service) => {
42
- if (typeof service === 'object')
43
- this.listProviders.set(service.provider, service.useValue);
44
+ if (typeof service === 'object' && typeof service.provider === 'string') {
45
+ const key = service.provider;
46
+ if (service.useClass) {
47
+ this.listProvidersClass.set(key, service.useClass);
48
+ }
49
+ else if (service.useFactory) {
50
+ this.listProviders.set(key, (0, awilix_1.asFunction)(service.useFactory).scoped());
51
+ }
52
+ else {
53
+ this.listProviders.set(key, (0, awilix_1.asValue)(service.useValue));
54
+ }
55
+ }
56
+ if (typeof service === 'object' && (0, shared_utils_1.isClass)(service.provider)) {
57
+ let useExample = false;
58
+ const key = service.provider.name;
59
+ if (service.useClass && (0, shared_utils_1.isClass)(service.useClass)) {
60
+ this.listProvidersClass.set(key, service.useClass);
61
+ }
62
+ else {
63
+ useExample = true;
64
+ this.logger.important(`You are trying to inject the ${key} provider`, `but it is not possible to add it because using useFactory or useValue`);
65
+ }
66
+ if (useExample) {
67
+ this.logger.debug('Example ✅', '{ provider: UserClassRepository, useClass: UserClassImplementation }');
68
+ this.logger.debug('Example ❌', '{ provider: UserClassRepository, useClass: () => { return "text" }}');
69
+ this.logger.debug('Example ❌', '{ provider: UserClassRepository, useFactory: () => { return "text" }}');
70
+ this.logger.debug('Example ❌', '{ provider: UserClassRepository, useValue: "Text" }');
71
+ }
72
+ }
44
73
  });
45
74
  this.logger.debug('Injector - list provider', this.listProviders);
75
+ this.logger.debug('Injector - list provider type class', this.listProvidersClass);
46
76
  }
47
77
  /**
48
- * Método para obtener un objeto con los parámetros(key) y valores(useValue)
49
- * que se inyectarán en la clase (target) mediante asClass().inject().
78
+ * Método para obtener un objeto con los parámetros(key) y valores(useValue, useClass, useFactory)
79
+ * que se inyectarán en la clase (target).
50
80
  *
51
81
  * @param { TClass} target - La clase objetivo.
52
82
  * @returns {object} - Objeto con datos a inyectar.
@@ -58,8 +88,8 @@ class Injector {
58
88
  for (const key of dInject.keys()) {
59
89
  if (this.listProviders.has(key)) {
60
90
  const paramName = dInject.get(key);
61
- const useValue = this.listProviders.get(key);
62
- injectData[paramName] = useValue;
91
+ const provider = this.listProviders.get(key);
92
+ injectData[paramName] = provider;
63
93
  }
64
94
  else {
65
95
  this.logger.important(`You are trying to inject @INJECT('${key}') into '${target.name}'`, `but the provider '${key}' and its value are not registered in '${this.moduleName}' or any other previously loaded modules`);
@@ -83,7 +113,7 @@ class Injector {
83
113
  let injector = (0, awilix_1.asClass)(target).scoped();
84
114
  if (!(0, shared_utils_1.isEmpty)(injectData)) {
85
115
  this.logger.debug(`Inject - list dependencies to inject of ${target.name}:`, injectData);
86
- injector = injector.inject(this.funtionInjectData(injectData));
116
+ injector = injector.inject(() => injectData);
87
117
  }
88
118
  return {
89
119
  ...injector,
@@ -93,13 +123,5 @@ class Injector {
93
123
  getAllProvider() {
94
124
  return this.listProviders;
95
125
  }
96
- getInjectProvider(provider) {
97
- return typeof provider.value === 'function'
98
- ? (0, awilix_1.asFunction)(provider.value).scoped()
99
- : (0, awilix_1.asValue)(provider.value);
100
- }
101
- funtionInjectData(injectData) {
102
- return () => injectData;
103
- }
104
126
  }
105
127
  exports.Injector = Injector;
@@ -12,7 +12,8 @@ export declare class Module {
12
12
  private dependenciesClass;
13
13
  private metadata;
14
14
  private types;
15
- private listProviders;
15
+ private readonly listProviders;
16
+ private readonly listProvidersClass;
16
17
  /**
17
18
  * Constructor del módulo.
18
19
  */
@@ -42,6 +43,11 @@ export declare class Module {
42
43
  * @private
43
44
  */
44
45
  private registerEntities;
46
+ /**
47
+ * Registra entidades que se escanearon en dentro de proveedores para se reemplazar otra clase.
48
+ * @private
49
+ */
50
+ private registerEntitiesFromProvider;
45
51
  /**
46
52
  * Agrupación de dependencias para alias
47
53
  *
@@ -8,6 +8,7 @@ const utils_1 = require("@zanobijs/common/utils");
8
8
  const injector_1 = require("./injector");
9
9
  const metadata_1 = require("../metadata");
10
10
  const exceptions_1 = require("../exceptions");
11
+ const invalidProvider_module_exception_1 = require("../exceptions/invalidProvider.module.exception");
11
12
  /**
12
13
  * Módulo para gestionar la configuración y el registro de controladores, servicios y dependencias.
13
14
  */
@@ -21,6 +22,7 @@ class Module {
21
22
  metadata;
22
23
  types = ['controller', 'service'];
23
24
  listProviders = new Map();
25
+ listProvidersClass = new Map();
24
26
  /**
25
27
  * Constructor del módulo.
26
28
  */
@@ -36,7 +38,7 @@ class Module {
36
38
  if (this.metadata.isTypeModule(module)) {
37
39
  this.module = module;
38
40
  this.logger.debug('Module - Setup - Create Injector to module:', module.name);
39
- this.injector = new injector_1.Injector(module, this.listProviders);
41
+ this.injector = new injector_1.Injector(module, this.listProviders, this.listProvidersClass);
40
42
  }
41
43
  else {
42
44
  throw new exceptions_1.InvalidModuleAnnotationException();
@@ -50,6 +52,7 @@ class Module {
50
52
  this.registerAllProviders();
51
53
  this.getMetadataModule();
52
54
  this.registerDependencies();
55
+ this.registerEntitiesFromProvider();
53
56
  this.registerDependenciesToAlias();
54
57
  }
55
58
  /**
@@ -74,7 +77,7 @@ class Module {
74
77
  */
75
78
  registerEntities(entityType) {
76
79
  const entities = this.config[entityType];
77
- this.logger.debug('Module - ..... searching for entities type ', entityType);
80
+ this.logger.debug('Module - searching for entities type:', entityType);
78
81
  if (entities && entities.length > 0) {
79
82
  const registeredEntities = entities
80
83
  .filter((target) => {
@@ -96,6 +99,35 @@ class Module {
96
99
  this.logger.debug('Module - Does not have entities of that type', entityType);
97
100
  }
98
101
  }
102
+ /**
103
+ * Registra entidades que se escanearon en dentro de proveedores para se reemplazar otra clase.
104
+ * @private
105
+ */
106
+ registerEntitiesFromProvider() {
107
+ this.logger.debug('Module - searching for entities from provider');
108
+ for (const [key, value] of this.listProvidersClass) {
109
+ try {
110
+ this.logger.debug('Module - Entity provider', `<<< ${key} >>>`);
111
+ const type = this.metadata.determineType(value);
112
+ if (!this.types.includes(type)) {
113
+ throw new Error('The type used in the provider useClass property is not valid');
114
+ }
115
+ this.groupDependenciesForAlias(value);
116
+ const targetName = (0, shared_utils_1.unCapitalize)(value.name);
117
+ const targetProviderName = (0, shared_utils_1.unCapitalize)(key);
118
+ const registerProviderWithEntities = {
119
+ [value.name]: this.injector.getInjectorClass(value),
120
+ [targetName]: (0, awilix_1.aliasTo)(value.name),
121
+ [key]: (0, awilix_1.aliasTo)(value.name),
122
+ [targetProviderName]: (0, awilix_1.aliasTo)(value.name),
123
+ };
124
+ Object.assign(this.registerClass, registerProviderWithEntities);
125
+ }
126
+ catch (error) {
127
+ throw new invalidProvider_module_exception_1.InvalidProviderModuleException(value.name, this.module.name, error.message);
128
+ }
129
+ }
130
+ }
99
131
  /**
100
132
  * Agrupación de dependencias para alias
101
133
  *
@@ -110,7 +142,7 @@ class Module {
110
142
  */
111
143
  groupDependenciesForAlias(target) {
112
144
  const dependencies = this.metadata.getClassDependencies(target);
113
- this.logger.debug(`Module - List dependecies to group by${target.name}`, dependencies);
145
+ this.logger.debug(`Module - List dependecies to group by ${target.name}`, dependencies);
114
146
  if (dependencies && !(0, shared_utils_1.isEmpty)(dependencies)) {
115
147
  this.dependenciesClass = [...this.dependenciesClass, ...dependencies];
116
148
  }
@@ -136,11 +168,7 @@ class Module {
136
168
  this.logger.debug('Module - Register list provider:', this.module.name);
137
169
  const listProviders = this.injector.getAllProvider();
138
170
  listProviders.forEach((value, key) => {
139
- const providerInject = this.injector.getInjectProvider({
140
- key,
141
- value,
142
- });
143
- this.registerClass[key] = providerInject;
171
+ this.registerClass[key] = value;
144
172
  });
145
173
  }
146
174
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zanobijs/core",
3
- "version": "1.1.1-beta.0",
3
+ "version": "1.2.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>",
@@ -29,5 +29,5 @@
29
29
  "peerDependencies": {
30
30
  "@zanobijs/common": "*"
31
31
  },
32
- "gitHead": "5194cbeb7a6e41341f99dbc57f39150d741372a8"
32
+ "gitHead": "fab2cf615b0fb46a1bd4867b6985c1ad2d88d130"
33
33
  }