reestructurar en paquetes
This commit is contained in:
parent
6a674a60ec
commit
180a708956
@ -1,3 +1,5 @@
|
||||
import { sequelize } from "config/database";
|
||||
import { initPackages } from "core/package-loader";
|
||||
import dotenv from "dotenv";
|
||||
import express, { Application } from "express";
|
||||
import helmet from "helmet";
|
||||
@ -5,7 +7,6 @@ import responseTime from "response-time";
|
||||
import { authProvider } from "./contexts/auth/infraestructure";
|
||||
import { logger } from "./core/common/infrastructure/logger";
|
||||
import { globalErrorHandler } from "./core/common/presentation";
|
||||
import { v1Routes } from "./routes";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@ -47,7 +48,8 @@ export function createApp(): Application {
|
||||
});
|
||||
|
||||
// Registrar rutas de la API
|
||||
app.use("/api/v1", v1Routes());
|
||||
// app.use("/api/v1", v1Routes());
|
||||
initPackages(app, sequelize);
|
||||
|
||||
// Gestión global de errores.
|
||||
// Siempre al final de la cadena de middlewares
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { logger } from "core/common/infrastructure/logger";
|
||||
import dotenv from "dotenv";
|
||||
import { Sequelize } from "sequelize";
|
||||
import { registerModels } from "./register-models";
|
||||
|
||||
dotenv.config();
|
||||
|
||||
@ -40,7 +39,7 @@ export const sequelize = new Sequelize(
|
||||
export async function connectToDatabase(): Promise<void> {
|
||||
try {
|
||||
await sequelize.authenticate();
|
||||
await registerModels();
|
||||
//await registerModels();
|
||||
logger.info(`✔️${" "}Database connection established successfully.`);
|
||||
} catch (error) {
|
||||
logger.error("❌ Unable to connect to the database:", error);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { sequelize } from "@config/database";
|
||||
import { Transaction } from "sequelize";
|
||||
import { sequelize } from "../../../../config/database";
|
||||
import { TransactionManager } from "../database";
|
||||
|
||||
export class SequelizeTransactionManager extends TransactionManager {
|
||||
|
||||
55
apps/server/src/core/package-loader.ts
Normal file
55
apps/server/src/core/package-loader.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { IPackageServer } from "@libs/package";
|
||||
import { Express } from "express";
|
||||
import { Sequelize } from "sequelize";
|
||||
import { registerService } from "./service-registry";
|
||||
|
||||
const registeredPackages: Map<string, IPackageServer> = new Map();
|
||||
const initializedPackages = new Set<string>();
|
||||
|
||||
export function registerPackage(pkg: IPackageServer) {
|
||||
if (registeredPackages.has(pkg.metadata.name)) {
|
||||
throw new Error(`❌ Paquete "${pkg.metadata.name}" ya registrado.`);
|
||||
}
|
||||
registeredPackages.set(pkg.metadata.name, pkg);
|
||||
}
|
||||
|
||||
export function initPackages(app: Express, sequelize: Sequelize) {
|
||||
for (const [name] of registeredPackages) {
|
||||
loadPackage(name, app, sequelize);
|
||||
}
|
||||
}
|
||||
|
||||
function loadPackage(name: string, app: Express, sequelize: Sequelize) {
|
||||
if (initializedPackages.has(name)) return;
|
||||
|
||||
const pkg = registeredPackages.get(name);
|
||||
if (!pkg) throw new Error(`❌ Paquete "${name}" no encontrado.`);
|
||||
|
||||
// Resolver dependencias primero
|
||||
const deps = pkg.metadata.dependencies || [];
|
||||
deps.forEach((dep) => loadPackage(dep, app, sequelize));
|
||||
|
||||
// Inicializar el package
|
||||
pkg.init(app);
|
||||
|
||||
const pkgApi = pkg.registerDependencies?.();
|
||||
|
||||
// Registrar modelos de Sequelize, si los expone
|
||||
|
||||
if (pkgApi?.models) {
|
||||
for (const initModelFn of pkgApi.models) {
|
||||
initModelFn(sequelize);
|
||||
}
|
||||
}
|
||||
|
||||
// Registrar sus servicios, si los expone
|
||||
if (pkgApi?.services) {
|
||||
const services = pkgApi.services;
|
||||
if (services && typeof services === "object") {
|
||||
registerService(pkg.metadata.name, services);
|
||||
}
|
||||
}
|
||||
|
||||
initializedPackages.add(name);
|
||||
console.log(`✅ Paquete "${name}" inicializado.`);
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
import { Application } from "express";
|
||||
import { IPlugin } from "./plugin.interface";
|
||||
|
||||
const plugins: IPlugin[] = [];
|
||||
|
||||
export function registerPlugin(plugin: IPlugin) {
|
||||
plugins.push(plugin);
|
||||
}
|
||||
|
||||
export function initPlugins(app: Application) {
|
||||
plugins.forEach((plugin) => plugin.init(app));
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
import { Application } from "express";
|
||||
|
||||
export interface PluginMetadata {
|
||||
name: string;
|
||||
version: string;
|
||||
description?: string;
|
||||
|
||||
/**
|
||||
* Lista de nombres de plugins requeridos por este plugin.
|
||||
*/
|
||||
dependencies?: string[];
|
||||
}
|
||||
|
||||
export interface IPlugin {
|
||||
metadata: PluginMetadata;
|
||||
init(app: Application): void;
|
||||
registerDependencies?(): void;
|
||||
}
|
||||
36
apps/server/src/core/service-registry.ts
Normal file
36
apps/server/src/core/service-registry.ts
Normal file
@ -0,0 +1,36 @@
|
||||
const services: Record<string, any> = {};
|
||||
|
||||
/**
|
||||
* Registra un objeto de servicio (API) bajo un nombre.
|
||||
*/
|
||||
export function registerService(name: string, api: any) {
|
||||
if (services[name]) {
|
||||
throw new Error(`❌ Servicio "${name}" ya fue registrado.`);
|
||||
}
|
||||
services[name] = api;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recupera un servicio registrado, con tipado opcional.
|
||||
*/
|
||||
export function getService<T = any>(name: string): T {
|
||||
const service = services[name];
|
||||
if (!service) {
|
||||
throw new Error(`❌ Servicio "${name}" no encontrado.`);
|
||||
}
|
||||
return service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Permite saber si un servicio fue registrado.
|
||||
*/
|
||||
export function hasService(name: string): boolean {
|
||||
return !!services[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Devuelve todos los servicios (para depuración o tests).
|
||||
*/
|
||||
export function listServices(): string[] {
|
||||
return Object.keys(services);
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
import http from "http";
|
||||
import { DateTime } from "luxon";
|
||||
import { registerPackages } from "packages";
|
||||
import { createApp } from "./app";
|
||||
import { ENV } from "./config";
|
||||
import { connectToDatabase } from "./config/database";
|
||||
@ -66,6 +67,9 @@ const serverConnection = (conn: any) => {
|
||||
//const sequelizeConn = createSequelizeAdapter();
|
||||
//const firebirdConn = createFirebirdAdapter();
|
||||
|
||||
// Cargar paquetes de la aplicación
|
||||
registerPackages();
|
||||
|
||||
// Crea el servidor HTTP
|
||||
const server = http
|
||||
.createServer(createApp())
|
||||
|
||||
8
apps/server/src/packages.ts
Normal file
8
apps/server/src/packages.ts
Normal file
@ -0,0 +1,8 @@
|
||||
// apps/server/src/plugins.ts
|
||||
//import { ContactsPackage } from '@packages/contacts/server';
|
||||
//import { InvoicesPackage } from '@packages/invoices/server';
|
||||
|
||||
export const registerPackages = () => {
|
||||
//registerPackage(ContactsPackage);
|
||||
//registerPackage(InvoicesPackage);
|
||||
};
|
||||
@ -8,10 +8,11 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"baseUrl": "src",
|
||||
"paths": {
|
||||
"@shared/*": ["../../packages/shared/*"],
|
||||
"@common/*": ["common/*"],
|
||||
"@contexts/*": ["contexts/*"],
|
||||
"@config/*": ["config/*"]
|
||||
"@libs/*": ["../../../libs/*"],
|
||||
"@packages/*": ["../../../packages/*"]
|
||||
/*"@common/*": ["common/*"],*/
|
||||
/*"@config/*": ["config/*"]*/
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
//Contrato para los packages backend (Node.js)
|
||||
|
||||
import { Express } from "express";
|
||||
import { PackageMetadata } from "./types";
|
||||
import { PackageDependencies, PackageMetadata } from "./types";
|
||||
|
||||
export interface IPackageServer {
|
||||
metadata: PackageMetadata;
|
||||
init(app: Express): void;
|
||||
registerDependencies?(): void;
|
||||
registerDependencies?(): PackageDependencies;
|
||||
}
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
"@types/react": "^19.1.2",
|
||||
"express": "^4.18.2",
|
||||
"react": "^18.3.1",
|
||||
"sequelize": "^6.37.5",
|
||||
"typescript": "*"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,17 @@
|
||||
// Contiene tipos comunes entre cliente y servidor
|
||||
|
||||
import { Model, Sequelize } from "sequelize";
|
||||
|
||||
type ModelInitializer = (sequelize: Sequelize) => typeof Model;
|
||||
|
||||
export interface PackageMetadata {
|
||||
name: string;
|
||||
version: string;
|
||||
description?: string;
|
||||
dependencies?: string[];
|
||||
}
|
||||
|
||||
export interface PackageDependencies {
|
||||
models?: ModelInitializer[];
|
||||
services?: { [key: string]: any };
|
||||
}
|
||||
|
||||
30
packages/invoices/server/index.ts
Normal file
30
packages/invoices/server/index.ts
Normal file
@ -0,0 +1,30 @@
|
||||
/* import { getService } from "@apps/server/src/core/service-registry"; */
|
||||
import { IPackageServer } from "@libs/package";
|
||||
//import initInvoiceModel from './models/contact.model';
|
||||
|
||||
export const InvoicesPackage: IPackageServer = {
|
||||
metadata: {
|
||||
name: "invoices",
|
||||
version: "1.0.0",
|
||||
dependencies: ["contacts"],
|
||||
},
|
||||
init(app) {
|
||||
// const contacts = getService<ContactsService>("contacts");
|
||||
|
||||
app.get("/invoices", (req, res) => {
|
||||
// const customer = await contacts.getContactById('123');
|
||||
res.send("Aquí van las facturas");
|
||||
});
|
||||
},
|
||||
registerDependencies() {
|
||||
return {
|
||||
models: [
|
||||
/*initInvoiceModel*/
|
||||
],
|
||||
services: {
|
||||
getInvoice: () => {},
|
||||
/*...*/
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
@ -283,6 +283,9 @@ importers:
|
||||
react:
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
sequelize:
|
||||
specifier: ^6.37.5
|
||||
version: 6.37.7(mysql2@3.14.0)
|
||||
typescript:
|
||||
specifier: '*'
|
||||
version: 5.7.3
|
||||
|
||||
Loading…
Reference in New Issue
Block a user