@obisey/nest 0.1.21 → 0.1.23

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.
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Adapters - Agnóstico de BD
3
+ *
4
+ * Patrón: Cada BD tiene su carpeta con adapters específicos
5
+ * - sequelize/ → Adapters para Sequelize ORM
6
+ * - drizzle/ → Adapters para Drizzle (futuro)
7
+ * - prisma/ → Adapters para Prisma (futuro)
8
+ *
9
+ * Cada adapter transforma PropertyDTO/RelationDTO → BD-specific config
10
+ */
11
+ export * from './sequelize';
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ /**
3
+ * Adapters - Agnóstico de BD
4
+ *
5
+ * Patrón: Cada BD tiene su carpeta con adapters específicos
6
+ * - sequelize/ → Adapters para Sequelize ORM
7
+ * - drizzle/ → Adapters para Drizzle (futuro)
8
+ * - prisma/ → Adapters para Prisma (futuro)
9
+ *
10
+ * Cada adapter transforma PropertyDTO/RelationDTO → BD-specific config
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
24
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
25
+ };
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ __exportStar(require("./sequelize"), exports);
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Sequelize Adapters
3
+ * Agnósticos de BD, específicos para Sequelize
4
+ */
5
+ export { PropertyAdapter, type PropertyDTO, type SequelizeColumnConfig } from './property.adapter';
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ /**
3
+ * Sequelize Adapters
4
+ * Agnósticos de BD, específicos para Sequelize
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.PropertyAdapter = void 0;
8
+ var property_adapter_1 = require("./property.adapter");
9
+ Object.defineProperty(exports, "PropertyAdapter", { enumerable: true, get: function () { return property_adapter_1.PropertyAdapter; } });
@@ -0,0 +1,79 @@
1
+ /**
2
+ * PropertyAdapter para Sequelize
3
+ * Maneja tipado de propiedades agnósticamente
4
+ *
5
+ * RESPUESTA BAJO:
6
+ * - Convertir PropertyDTO → ColumnConfig (Sequelize)
7
+ * - Convertir PropertyDTO → TypeScriptType
8
+ * - Manejar types especiales (JSON, ENUM, ARRAY)
9
+ *
10
+ * @example
11
+ * const prop = { name: 'email', type: 'STRING', nullable: true }
12
+ * const column = PropertyAdapter.column(prop)
13
+ * // Returns: "@Column({ type: DataType.STRING, allowNull: true, field: 'email' })"
14
+ */
15
+ /**
16
+ * DTO que recibe el adapter (estructura de API)
17
+ */
18
+ export interface PropertyDTO {
19
+ name: string;
20
+ type: 'STRING' | 'INTEGER' | 'FLOAT' | 'DECIMAL' | 'DATE' | 'BOOLEAN' | 'JSON' | 'TEXT' | 'ENUM' | 'ARRAY';
21
+ nullable?: boolean;
22
+ primaryKey?: boolean;
23
+ autoIncrement?: boolean;
24
+ unique?: boolean;
25
+ defaultValue?: string | number | boolean;
26
+ enumValues?: string[];
27
+ decimals?: number;
28
+ precision?: number;
29
+ length?: number;
30
+ }
31
+ /**
32
+ * Config que devuelve el adapter (para usar en template)
33
+ */
34
+ export interface SequelizeColumnConfig {
35
+ decorator: string;
36
+ tsType: string;
37
+ tsFieldType: string;
38
+ }
39
+ /**
40
+ * PropertyAdapter - Transforma PropertyDTO → SequelizeColumnConfig
41
+ */
42
+ export declare class PropertyAdapter {
43
+ /**
44
+ * Convierte tipo de dato API → DataType de Sequelize (string)
45
+ * @example 'STRING' → 'DataType.STRING'
46
+ */
47
+ private static mapToSequelizeType;
48
+ /**
49
+ * Convierte tipo de dato API → Tipo TypeScript
50
+ * @example 'STRING' → 'string', 'INTEGER' → 'number'
51
+ */
52
+ private static mapToTypeScriptType;
53
+ /**
54
+ * Genera el decorador @Column con todas las opciones
55
+ */
56
+ private static generateColumnDecorator;
57
+ /**
58
+ * Método principal: Convierte PropertyDTO → SequelizeColumnConfig
59
+ * Esto es lo que usan los templates
60
+ */
61
+ static column(prop: PropertyDTO): SequelizeColumnConfig;
62
+ /**
63
+ * Getter para solo el decorador (para templates simples)
64
+ */
65
+ static getDecorator(prop: PropertyDTO): string;
66
+ /**
67
+ * Getter para solo el tipo TypeScript
68
+ */
69
+ static getTsType(prop: PropertyDTO): string;
70
+ /**
71
+ * Getter para solo el tipo TypeScript con ?
72
+ */
73
+ static getTsFieldType(prop: PropertyDTO): string;
74
+ }
75
+ /**
76
+ * Export default para facilitar uso en templates
77
+ * @example <%= adapter.column(property) %>
78
+ */
79
+ export default PropertyAdapter;
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ /**
3
+ * PropertyAdapter para Sequelize
4
+ * Maneja tipado de propiedades agnósticamente
5
+ *
6
+ * RESPUESTA BAJO:
7
+ * - Convertir PropertyDTO → ColumnConfig (Sequelize)
8
+ * - Convertir PropertyDTO → TypeScriptType
9
+ * - Manejar types especiales (JSON, ENUM, ARRAY)
10
+ *
11
+ * @example
12
+ * const prop = { name: 'email', type: 'STRING', nullable: true }
13
+ * const column = PropertyAdapter.column(prop)
14
+ * // Returns: "@Column({ type: DataType.STRING, allowNull: true, field: 'email' })"
15
+ */
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.PropertyAdapter = void 0;
18
+ /**
19
+ * PropertyAdapter - Transforma PropertyDTO → SequelizeColumnConfig
20
+ */
21
+ class PropertyAdapter {
22
+ /**
23
+ * Convierte tipo de dato API → DataType de Sequelize (string)
24
+ * @example 'STRING' → 'DataType.STRING'
25
+ */
26
+ static mapToSequelizeType(type, prop) {
27
+ const typeMap = {
28
+ STRING: 'DataType.STRING',
29
+ INTEGER: 'DataType.INTEGER',
30
+ FLOAT: 'DataType.FLOAT',
31
+ DECIMAL: `DataType.DECIMAL(${prop.precision || 10}, ${prop.decimals || 2})`,
32
+ DATE: 'DataType.DATE',
33
+ BOOLEAN: 'DataType.BOOLEAN',
34
+ JSON: 'DataType.JSON',
35
+ TEXT: 'DataType.TEXT',
36
+ ENUM: `DataType.ENUM(${prop.enumValues?.map((e) => `'${e}'`).join(', ') || ''})`,
37
+ ARRAY: 'DataType.ARRAY(DataType.STRING)', // Default array de strings
38
+ };
39
+ return typeMap[type] || 'DataType.STRING';
40
+ }
41
+ /**
42
+ * Convierte tipo de dato API → Tipo TypeScript
43
+ * @example 'STRING' → 'string', 'INTEGER' → 'number'
44
+ */
45
+ static mapToTypeScriptType(type) {
46
+ const typeMap = {
47
+ STRING: 'string',
48
+ INTEGER: 'number',
49
+ FLOAT: 'number',
50
+ DECIMAL: 'number',
51
+ DATE: 'Date',
52
+ BOOLEAN: 'boolean',
53
+ JSON: 'any',
54
+ TEXT: 'string',
55
+ ENUM: 'string',
56
+ ARRAY: 'string[]',
57
+ };
58
+ return typeMap[type] || 'string';
59
+ }
60
+ /**
61
+ * Genera el decorador @Column con todas las opciones
62
+ */
63
+ static generateColumnDecorator(prop, sequelizeType) {
64
+ const options = [`type: ${sequelizeType}`];
65
+ // Field mapping (si es distinto al nombre)
66
+ options.push(`field: '${prop.name}'`);
67
+ // Nullable
68
+ if (prop.nullable) {
69
+ options.push('allowNull: true');
70
+ }
71
+ else {
72
+ options.push('allowNull: false');
73
+ }
74
+ // Primary key
75
+ if (prop.primaryKey) {
76
+ options.push('primaryKey: true');
77
+ }
78
+ // Auto increment
79
+ if (prop.autoIncrement) {
80
+ options.push('autoIncrement: true');
81
+ }
82
+ // Unique
83
+ if (prop.unique) {
84
+ options.push('unique: true');
85
+ }
86
+ // Default value
87
+ if (prop.defaultValue !== undefined && prop.defaultValue !== null) {
88
+ const defaultValue = typeof prop.defaultValue === 'string' ? `'${prop.defaultValue}'` : prop.defaultValue;
89
+ options.push(`defaultValue: ${defaultValue}`);
90
+ }
91
+ return `@Column({ ${options.join(', ')} })`;
92
+ }
93
+ /**
94
+ * Método principal: Convierte PropertyDTO → SequelizeColumnConfig
95
+ * Esto es lo que usan los templates
96
+ */
97
+ static column(prop) {
98
+ const sequelizeType = this.mapToSequelizeType(prop.type, prop);
99
+ const tsType = this.mapToTypeScriptType(prop.type);
100
+ // Campo TypeScript con ? si es nullable
101
+ const tsFieldType = prop.nullable ? `${tsType}?` : tsType;
102
+ return {
103
+ decorator: this.generateColumnDecorator(prop, sequelizeType),
104
+ tsType,
105
+ tsFieldType,
106
+ };
107
+ }
108
+ /**
109
+ * Getter para solo el decorador (para templates simples)
110
+ */
111
+ static getDecorator(prop) {
112
+ const sequelizeType = this.mapToSequelizeType(prop.type, prop);
113
+ return this.generateColumnDecorator(prop, sequelizeType);
114
+ }
115
+ /**
116
+ * Getter para solo el tipo TypeScript
117
+ */
118
+ static getTsType(prop) {
119
+ return this.mapToTypeScriptType(prop.type);
120
+ }
121
+ /**
122
+ * Getter para solo el tipo TypeScript con ?
123
+ */
124
+ static getTsFieldType(prop) {
125
+ const tsType = this.mapToTypeScriptType(prop.type);
126
+ return prop.nullable ? `${tsType}?` : tsType;
127
+ }
128
+ }
129
+ exports.PropertyAdapter = PropertyAdapter;
130
+ /**
131
+ * Export default para facilitar uso en templates
132
+ * @example <%= adapter.column(property) %>
133
+ */
134
+ exports.default = PropertyAdapter;
package/conexion.d.ts CHANGED
@@ -0,0 +1,25 @@
1
+ import { Sequelize } from 'sequelize-typescript';
2
+ /**
3
+ * Configuración de conexión a BD por tenant (emisor/receptor).
4
+ * El emisor (Global/Nucleus) expone un mapa IdEmpresa → ConexionProps.
5
+ */
6
+ export interface ConexionProps {
7
+ nombre: string;
8
+ id: string | number;
9
+ database: string;
10
+ username: string;
11
+ password: string;
12
+ host: string;
13
+ port: number;
14
+ dominios?: Array<{
15
+ nombre: string;
16
+ }>;
17
+ }
18
+ /**
19
+ * Clase de conexión por tenant. El app la usa vía CONEXION_FACTORY:
20
+ * { provide: CONEXION_FACTORY, useValue: (config) => new Conexion(config, [Model1, Model2, ...]) }
21
+ * Los providers generados (X_REPOSITORY) inyectan CONEXION_FACTORY y ReceptorService.
22
+ */
23
+ export declare class Conexion extends Sequelize {
24
+ constructor(config: ConexionProps, models?: any[]);
25
+ }
package/conexion.js CHANGED
@@ -1,32 +1,25 @@
1
- // import { Sequelize } from 'sequelize-typescript';
2
- // interface Dominio {
3
- // nombre: string;
4
- // }
5
- // export interface ConexionProps {
6
- // nombre: string;
7
- // id: string | number;
8
- // database: string;
9
- // username: string;
10
- // password: string;
11
- // host: string;
12
- // port: number;
13
- // dominios: Dominio[];
14
- // }
15
- // export class Conexion extends Sequelize {
16
- // constructor({ host, port, username, password, database }) {
17
- // super({
18
- // dialect: 'mysql',
19
- // host,
20
- // port,
21
- // username,
22
- // password,
23
- // database,
24
- // // logging : true,
25
- // logging: false,
26
- // sync: {
27
- // force: true,
28
- // alter: true,
29
- // },
30
- // });
31
- // }
32
- // }
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Conexion = void 0;
4
+ const sequelize_typescript_1 = require("sequelize-typescript");
5
+ /**
6
+ * Clase de conexión por tenant. El app la usa vía CONEXION_FACTORY:
7
+ * { provide: CONEXION_FACTORY, useValue: (config) => new Conexion(config, [Model1, Model2, ...]) }
8
+ * Los providers generados (X_REPOSITORY) inyectan CONEXION_FACTORY y ReceptorService.
9
+ */
10
+ class Conexion extends sequelize_typescript_1.Sequelize {
11
+ constructor(config, models = []) {
12
+ super({
13
+ dialect: 'mysql',
14
+ host: config.host,
15
+ port: config.port,
16
+ username: config.username,
17
+ password: config.password,
18
+ database: config.database,
19
+ repositoryMode: true,
20
+ models: models.length ? models : undefined,
21
+ logging: false,
22
+ });
23
+ }
24
+ }
25
+ exports.Conexion = Conexion;
package/index.d.ts CHANGED
@@ -9,7 +9,10 @@ export * from './prototipos/utils/activarRedis';
9
9
  export * from './prototipos/utils/formarInclude';
10
10
  export * from './prototipos/utils/formarorder';
11
11
  export * from './prototipos/utils/formarwhere';
12
+ export * from './prototipos/utils/getModelId';
12
13
  export * from './assets/http-exception.filter';
13
14
  export * from './assets/tokens';
14
15
  export * from './types';
15
16
  export * from './fecha';
17
+ export * from './conexion';
18
+ export * from './receptor.service';
package/index.js CHANGED
@@ -26,7 +26,10 @@ __exportStar(require("./prototipos/utils/activarRedis"), exports);
26
26
  __exportStar(require("./prototipos/utils/formarInclude"), exports);
27
27
  __exportStar(require("./prototipos/utils/formarorder"), exports);
28
28
  __exportStar(require("./prototipos/utils/formarwhere"), exports);
29
+ __exportStar(require("./prototipos/utils/getModelId"), exports);
29
30
  __exportStar(require("./assets/http-exception.filter"), exports);
30
31
  __exportStar(require("./assets/tokens"), exports);
31
32
  __exportStar(require("./types"), exports);
32
33
  __exportStar(require("./fecha"), exports);
34
+ __exportStar(require("./conexion"), exports);
35
+ __exportStar(require("./receptor.service"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@obisey/nest",
3
- "version": "0.1.21",
3
+ "version": "0.1.23",
4
4
  "description": "NestJS utilities and base classes by Obisey",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -35,12 +35,15 @@
35
35
  "@types/sequelize": "^4.28.20",
36
36
  "cache-manager": "^7.0.0",
37
37
  "cache-manager-redis-store": "^3.0.1",
38
+ "express": "^5.0.0",
38
39
  "graphql": "^16.0.0",
39
40
  "ioredis": "^5.6.1",
40
41
  "reflect-metadata": "^0.2.2",
41
42
  "sequelize": "^6.37.7",
42
43
  "sequelize-typescript": "^2.1.6",
43
- "typescript": "^5.8.3",
44
- "express": "^5.0.0"
44
+ "typescript": "^5.8.3"
45
+ },
46
+ "dependencies": {
47
+ "dayjs": "^1.11.19"
45
48
  }
46
49
  }
@@ -10,6 +10,7 @@ const cifrado_1 = require("./utils/cifrado");
10
10
  const keyInterface_1 = require("./utils/keyInterface");
11
11
  exports.redis_on = true;
12
12
  const paginar_1 = require("./utils/paginar");
13
+ const getModelId_1 = require("./utils/getModelId");
13
14
  var isDev = false;
14
15
  var stringifWhere = (where) => (0, lodash_1.isObject)(where)
15
16
  ? JSON.stringify(Object.entries(where).reduce((ac, [a, v]) => {
@@ -127,7 +128,19 @@ function BaseService(modelo) {
127
128
  ...key,
128
129
  include,
129
130
  where,
130
- }), (cache) => Promise.resolve(cache.map((n) => new repository.sequelize.models[(0, lodash_1.capitalize)(modelo)](JSON.parse(n)))), //Revisar
131
+ }), (cache) => Promise.resolve(cache.map((n) => {
132
+ const parsed = JSON.parse(n);
133
+ console.log(`[OBISEY-NEST CACHE HIT] ${modelo}:`, {
134
+ cached: parsed,
135
+ modelName: (0, lodash_1.capitalize)(modelo),
136
+ });
137
+ const instance = new repository.sequelize.models[(0, lodash_1.capitalize)(modelo)](parsed);
138
+ console.log(`[OBISEY-NEST DESERIALIZED] ${modelo}:`, {
139
+ id: instance.id,
140
+ hasId: 'id' in instance,
141
+ });
142
+ return instance;
143
+ })), //Revisar
131
144
  (resultado) => Promise.resolve(resultado.map((n) => n.get({ plain: true }))), //transformar
132
145
  () => new Promise((resolve) => {
133
146
  resolve(repository.findAll(value)); //Pedir
@@ -151,7 +164,7 @@ function BaseService(modelo) {
151
164
  resolve(undefined);
152
165
  }), //observar
153
166
  (__, resultado) => {
154
- return this.redis.hSet(nkey, peticion, JSON.stringify(resultado.map((n) => n.id)));
167
+ return this.redis.hSet(nkey, peticion, JSON.stringify(resultado.map((n) => (0, getModelId_1.getModelId)(n))));
155
168
  });
156
169
  await (0, paginar_1.paginar)(this.cacheManager, key.IdEmpresa, pagina, modelo, resultado.map((n) => n.get({ plain: true })));
157
170
  // if (isDev)
@@ -160,6 +173,7 @@ function BaseService(modelo) {
160
173
  // 'paginacion',
161
174
  // cache,
162
175
  // );
176
+ console.log(`[BUSCAR-TODOS-RESULT] modelo=${modelo} items=${resultado.length} cache=${cache}`);
163
177
  resolve(resultado ? resultado : []);
164
178
  }
165
179
  catch (err) {
@@ -1 +1 @@
1
- export declare function onRedis(datos: any, si?: boolean): any;
1
+ export declare function onRedis(datos: any, si?: boolean): boolean;
@@ -1,4 +1,4 @@
1
- export declare const formarInclude: (include: any, mapa: any, tipo: any, conexion: any, required?: boolean) => Promise<any>;
1
+ export declare const formarInclude: (include: any, mapa: any, tipo: any, conexion: any, required?: boolean) => any;
2
2
  declare class FilterBasic {
3
3
  is: string;
4
4
  }
@@ -1 +1 @@
1
- export declare const formarWhere: (where: any) => any;
1
+ export declare const formarWhere: (where: any) => {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Obtiene el id de una instancia Sequelize o de un objeto plano.
3
+ * Usa get({ plain: true }) en modelos para evitar shadowing (ej. field: 'Id').
4
+ */
5
+ export declare function getModelId(instance: any): number | undefined;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getModelId = getModelId;
4
+ /**
5
+ * Obtiene el id de una instancia Sequelize o de un objeto plano.
6
+ * Usa get({ plain: true }) en modelos para evitar shadowing (ej. field: 'Id').
7
+ */
8
+ function getModelId(instance) {
9
+ if (instance == null)
10
+ return undefined;
11
+ const plain = typeof instance.get === 'function'
12
+ ? instance.get({ plain: true })
13
+ : instance;
14
+ const id = plain?.id ?? plain?.Id ?? plain?.['ID'];
15
+ const n = Number(id);
16
+ return Number.isNaN(n) ? undefined : n;
17
+ }
@@ -0,0 +1,38 @@
1
+ import { HttpService } from '@nestjs/axios';
2
+ import type { ConexionProps } from './conexion';
3
+ export declare const RECEPTOR_OPTIONS = "RECEPTOR_OPTIONS";
4
+ /** Token para inyectar la factory (config) => Conexion. El app provee: useValue: (config) => new Conexion(config, [todos los modelos]) */
5
+ export declare const CONEXION_FACTORY = "CONEXION_FACTORY";
6
+ export interface ReceptorServiceOptions {
7
+ /** URL base del emisor (Global/Nucleus), ej. http://localhost:4302 */
8
+ globalUrl: string;
9
+ /** Ruta del endpoint emisor, ej. /global/emisor */
10
+ emisorPath?: string;
11
+ }
12
+ export declare class ReceptorService {
13
+ private readonly request;
14
+ private readonly httpService;
15
+ private readonly options?;
16
+ private conexionesActivas;
17
+ constructor(request: any, httpService: HttpService, options?: ReceptorServiceOptions);
18
+ private getGlobalUrl;
19
+ private getEmisorPath;
20
+ /**
21
+ * Obtiene el mapa de configuraciones de BD desde el emisor (Global).
22
+ */
23
+ obtenerConfiguraciones(): Promise<Record<string, ConexionProps>>;
24
+ /**
25
+ * Resuelve IdEmpresa para el request actual (session o host → dominios).
26
+ */
27
+ obtenerIdEmpresa(data?: Record<string, ConexionProps>): Promise<string | null>;
28
+ /**
29
+ * Devuelve la conexión para el request actual. Cachea por IdEmpresa.
30
+ * @param req - request (opcional si ya inyectado en el servicio)
31
+ * @param factoryOrClass - factory (config) => T o clase new (config) => T (ej. Conexion de @obisey/nest)
32
+ */
33
+ buscar<T = any>(req: {
34
+ req?: any;
35
+ headers?: Record<string, string>;
36
+ session?: any;
37
+ }, factoryOrClass: ((config: ConexionProps) => T) | (new (config: ConexionProps) => T)): Promise<T | null>;
38
+ }
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ReceptorService = exports.CONEXION_FACTORY = exports.RECEPTOR_OPTIONS = void 0;
16
+ /**
17
+ * ReceptorService: conexión dinámica centralizada por request.
18
+ * Obtiene config de BDs desde el emisor (Global/Nucleus), resuelve IdEmpresa
19
+ * por session o host, cachea conexiones por tenant y devuelve la Conexion
20
+ * para el request actual.
21
+ *
22
+ * Uso: en el provider de cada entidad dinámica:
23
+ * useFactory: async (req, receptor: ReceptorService) => {
24
+ * const conexion = await receptor.buscar(req, Conexion);
25
+ * return { repository: conexion.getRepository(Entity), conexion };
26
+ * },
27
+ * inject: [REQUEST, ReceptorService],
28
+ */
29
+ const common_1 = require("@nestjs/common");
30
+ const core_1 = require("@nestjs/core");
31
+ const axios_1 = require("@nestjs/axios");
32
+ exports.RECEPTOR_OPTIONS = 'RECEPTOR_OPTIONS';
33
+ /** Token para inyectar la factory (config) => Conexion. El app provee: useValue: (config) => new Conexion(config, [todos los modelos]) */
34
+ exports.CONEXION_FACTORY = 'CONEXION_FACTORY';
35
+ let ReceptorService = class ReceptorService {
36
+ constructor(request, httpService, options) {
37
+ this.request = request;
38
+ this.httpService = httpService;
39
+ this.options = options;
40
+ this.conexionesActivas = new Map();
41
+ }
42
+ getGlobalUrl() {
43
+ return this.options?.globalUrl ?? process.env.GLOBAL_URL ?? 'http://localhost:4302';
44
+ }
45
+ getEmisorPath() {
46
+ return this.options?.emisorPath ?? '/global/emisor';
47
+ }
48
+ /**
49
+ * Obtiene el mapa de configuraciones de BD desde el emisor (Global).
50
+ */
51
+ async obtenerConfiguraciones() {
52
+ const url = `${this.getGlobalUrl()}${this.getEmisorPath()}`;
53
+ try {
54
+ const res = await this.httpService.get(url).toPromise();
55
+ return res?.data ?? {};
56
+ }
57
+ catch (err) {
58
+ console.error('[ReceptorService] Error obteniendo config desde emisor:', url, err);
59
+ return {};
60
+ }
61
+ }
62
+ /**
63
+ * Resuelve IdEmpresa para el request actual (session o host → dominios).
64
+ */
65
+ async obtenerIdEmpresa(data) {
66
+ const req = this.request?.req ?? this.request;
67
+ let IdEmpresa = req?.session?.IdEmpresa ?? req?.headers?.['x-empresa-id'] ?? null;
68
+ if (IdEmpresa)
69
+ return String(IdEmpresa);
70
+ const host = req?.headers?.['host'];
71
+ if (!host || !data)
72
+ return null;
73
+ const key = Object.keys(data).find((k) => data[k].dominios?.some((d) => d.nombre === host));
74
+ return key ?? null;
75
+ }
76
+ /**
77
+ * Devuelve la conexión para el request actual. Cachea por IdEmpresa.
78
+ * @param req - request (opcional si ya inyectado en el servicio)
79
+ * @param factoryOrClass - factory (config) => T o clase new (config) => T (ej. Conexion de @obisey/nest)
80
+ */
81
+ async buscar(req, factoryOrClass) {
82
+ const data = await this.obtenerConfiguraciones();
83
+ const r = req?.req ?? req ?? this.request;
84
+ let IdEmpresa = r?.session?.IdEmpresa ?? r?.headers?.['x-empresa-id'] ?? null;
85
+ if (!IdEmpresa && r?.headers?.host && data) {
86
+ IdEmpresa = Object.keys(data).find((k) => data[k].dominios?.some((d) => d.nombre === r.headers.host)) ?? null;
87
+ }
88
+ if (!IdEmpresa)
89
+ return null;
90
+ IdEmpresa = String(IdEmpresa);
91
+ const cached = this.conexionesActivas.get(IdEmpresa);
92
+ if (cached)
93
+ return cached;
94
+ const config = data[IdEmpresa];
95
+ if (!config) {
96
+ console.warn('[ReceptorService] No hay config para IdEmpresa:', IdEmpresa);
97
+ return null;
98
+ }
99
+ const conn = typeof factoryOrClass === 'function' && factoryOrClass.length === 1
100
+ ? factoryOrClass(config)
101
+ : new factoryOrClass(config);
102
+ this.conexionesActivas.set(IdEmpresa, conn);
103
+ return conn;
104
+ }
105
+ };
106
+ exports.ReceptorService = ReceptorService;
107
+ exports.ReceptorService = ReceptorService = __decorate([
108
+ (0, common_1.Injectable)(),
109
+ __param(0, (0, common_1.Inject)(core_1.REQUEST)),
110
+ __param(2, (0, common_1.Optional)()),
111
+ __param(2, (0, common_1.Inject)(exports.RECEPTOR_OPTIONS)),
112
+ __metadata("design:paramtypes", [Object, axios_1.HttpService, Object])
113
+ ], ReceptorService);