.
This commit is contained in:
parent
9e9ddcceb3
commit
0065c4d4d3
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -53,7 +53,7 @@
|
|||||||
"command": "pnpm run dev --filter=server",
|
"command": "pnpm run dev --filter=server",
|
||||||
"skipFiles": ["<node_internals>/**"],
|
"skipFiles": ["<node_internals>/**"],
|
||||||
"env": {
|
"env": {
|
||||||
"NODE_OPTIONS": "--inspect"
|
"NODE_OPTIONS": "--inspect=0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -44,9 +44,6 @@ export function createApp(): Application {
|
|||||||
next();
|
next();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Registrar rutas de la API
|
|
||||||
// app.use("/api/v1", v1Routes());
|
|
||||||
|
|
||||||
// Gestión global de errores.
|
// Gestión global de errores.
|
||||||
// Siempre al final de la cadena de middlewares
|
// Siempre al final de la cadena de middlewares
|
||||||
// y después de las rutas.
|
// y después de las rutas.
|
||||||
|
|||||||
@ -1,66 +0,0 @@
|
|||||||
import * as glob from "glob";
|
|
||||||
import * as path from "path";
|
|
||||||
import { DataTypes } from "sequelize";
|
|
||||||
import { sequelize } from "./database";
|
|
||||||
import { logger } from "@rdx/logger";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 🔹 Registra todos los modelos en Sequelize
|
|
||||||
*/
|
|
||||||
export const registerModels = async () => {
|
|
||||||
const cwd = path.resolve(`${__dirname}/../`);
|
|
||||||
const models: { [key: string]: any } = {};
|
|
||||||
|
|
||||||
// Opciones para buscar los modelos
|
|
||||||
const globOptions = {
|
|
||||||
cwd,
|
|
||||||
nocase: true,
|
|
||||||
nodir: true,
|
|
||||||
absolute: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
logger.info(`🔎 Searching models in: ${cwd}`);
|
|
||||||
|
|
||||||
// Buscamos los ficheros que terminen en .model.js o .model.ts
|
|
||||||
glob.sync("**/*.model.{js,ts}", globOptions).forEach((file) => {
|
|
||||||
//logger.info(`📄 File >> ${file}...`);
|
|
||||||
const modelDef = require(path.join(file)).default;
|
|
||||||
const model = typeof modelDef === "function" ? modelDef(sequelize, DataTypes) : false;
|
|
||||||
|
|
||||||
if (model) {
|
|
||||||
models[model.name] = model;
|
|
||||||
logger.info(`🔸 Model >> ${model.name} (${file})`);
|
|
||||||
} else {
|
|
||||||
logger.info(`🚫 No model`);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Asociaciones y hooks de los modelos, si existen
|
|
||||||
for (const modelName in models) {
|
|
||||||
const model = models[modelName];
|
|
||||||
if (model.associate) {
|
|
||||||
model.associate(sequelize, models);
|
|
||||||
}
|
|
||||||
if (model.hooks) {
|
|
||||||
model.hooks(sequelize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("❌ Error registering models:", error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Sincronizamos DB en modo desarrollo
|
|
||||||
if (process.env.NODE_ENV !== "production") {
|
|
||||||
await sequelize.sync({ force: false, alter: true });
|
|
||||||
logger.info(`✔️${" "}Database synchronized successfully.`);
|
|
||||||
} else {
|
|
||||||
logger.warning("⚠️ Running in production mode - Skipping database sync.");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
logger.error("❌ Error synchronizing database:", error);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -1,6 +1,5 @@
|
|||||||
import { logger } from "@rdx/logger";
|
import { logger } from "@rdx/logger";
|
||||||
import { ModelInitializer } from "@rdx/modules";
|
import { ModelInitializer, ModuleParams } from "@rdx/modules";
|
||||||
import { Sequelize } from "sequelize";
|
|
||||||
|
|
||||||
const registeredModels: Map<string, any> = new Map();
|
const registeredModels: Map<string, any> = new Map();
|
||||||
const initializedModels = new Set<string>();
|
const initializedModels = new Set<string>();
|
||||||
@ -8,22 +7,23 @@ const initializedModels = new Set<string>();
|
|||||||
/**
|
/**
|
||||||
* 🔹 Registra todos los modelos en Sequelize
|
* 🔹 Registra todos los modelos en Sequelize
|
||||||
*/
|
*/
|
||||||
export const registerModel = (models: ModelInitializer[], database: Sequelize) => {
|
export const registerModel = (models: ModelInitializer[], params: ModuleParams) => {
|
||||||
for (const initModelFn of models) {
|
for (const initModelFn of models) {
|
||||||
const model = initModelFn(database);
|
const model = initModelFn();
|
||||||
if (model) {
|
if (model) {
|
||||||
registeredModels.set(model.name, model);
|
registeredModels.set(model.name, model);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initModels = async (sequelize: Sequelize) => {
|
export const initModels = async (params: ModuleParams) => {
|
||||||
registeredModels.forEach((_, name) => loadModel(name, sequelize));
|
registeredModels.forEach((_, name) => loadModel(name, params));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Sincronizamos DB en modo desarrollo
|
// Sincronizamos DB en modo desarrollo
|
||||||
|
const { database } = params;
|
||||||
if (process.env.NODE_ENV !== "production") {
|
if (process.env.NODE_ENV !== "production") {
|
||||||
await sequelize.sync({ force: false, alter: true });
|
await database.sync({ force: false, alter: true });
|
||||||
logger.info(`✔️${" "}Database synchronized successfully.`);
|
logger.info(`✔️${" "}Database synchronized successfully.`);
|
||||||
} else {
|
} else {
|
||||||
logger.warning("⚠️ Running in production mode - Skipping database sync.");
|
logger.warning("⚠️ Running in production mode - Skipping database sync.");
|
||||||
@ -34,19 +34,21 @@ export const initModels = async (sequelize: Sequelize) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const loadModel = (name: string, sequelize: Sequelize) => {
|
export const loadModel = (name: string, params: ModuleParams) => {
|
||||||
if (initializedModels.has(name)) return;
|
if (initializedModels.has(name)) return;
|
||||||
|
|
||||||
const model = registeredModels.get(name);
|
const model = registeredModels.get(name);
|
||||||
if (!model) throw new Error(`❌ Model "${name}" not found.`);
|
if (!model) throw new Error(`❌ Model "${name}" not found.`);
|
||||||
|
|
||||||
|
const { database } = params;
|
||||||
|
|
||||||
// Asociaciones y hooks de los modelos, si existen
|
// Asociaciones y hooks de los modelos, si existen
|
||||||
if (model.associate) {
|
if (model.associate) {
|
||||||
model.associate(sequelize);
|
model.associate(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model.hooks) {
|
if (model.hooks) {
|
||||||
model.hooks(sequelize);
|
model.hooks(database);
|
||||||
}
|
}
|
||||||
|
|
||||||
initializedModels.add(name);
|
initializedModels.add(name);
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
import { logger } from "@rdx/logger";
|
import { logger } from "@rdx/logger";
|
||||||
import { IModuleServer } from "@rdx/modules";
|
import { IModuleServer, ModuleParams } from "@rdx/modules";
|
||||||
import { Application } from "express";
|
|
||||||
import { Sequelize } from "sequelize";
|
|
||||||
import { initModels, registerModel } from "./model-loader";
|
import { initModels, registerModel } from "./model-loader";
|
||||||
import { registerService } from "./service-registry";
|
import { registerService } from "./service-registry";
|
||||||
|
|
||||||
@ -15,14 +13,14 @@ export function registerModule(pkg: IModuleServer) {
|
|||||||
registeredModules.set(pkg.metadata.name, pkg);
|
registeredModules.set(pkg.metadata.name, pkg);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function initModules(app: Application, database: Sequelize) {
|
export function initModules(params: ModuleParams) {
|
||||||
registeredModules.forEach((_, name) => {
|
registeredModules.forEach((_, name) => {
|
||||||
loadModule(name, app, database);
|
loadModule(name, params);
|
||||||
});
|
});
|
||||||
initModels(database);
|
initModels(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadModule = (name: string, app: Application, database: Sequelize) => {
|
const loadModule = (name: string, params: ModuleParams) => {
|
||||||
if (initializedModules.has(name)) return;
|
if (initializedModules.has(name)) return;
|
||||||
|
|
||||||
const pkg = registeredModules.get(name);
|
const pkg = registeredModules.get(name);
|
||||||
@ -30,16 +28,16 @@ const loadModule = (name: string, app: Application, database: Sequelize) => {
|
|||||||
|
|
||||||
// Resolver dependencias primero
|
// Resolver dependencias primero
|
||||||
const deps = pkg.metadata.dependencies || [];
|
const deps = pkg.metadata.dependencies || [];
|
||||||
deps.forEach((dep) => loadModule(dep, app, database));
|
deps.forEach((dep) => loadModule(dep, params));
|
||||||
|
|
||||||
// Inicializar el module
|
// Inicializar el module
|
||||||
pkg.init(app);
|
pkg.init(params);
|
||||||
|
|
||||||
const pkgApi = pkg.registerDependencies?.();
|
const pkgApi = pkg.registerDependencies?.(params);
|
||||||
|
|
||||||
// Registrar modelos de Sequelize, si los expone
|
// Registrar modelos de Sequelize, si los expone
|
||||||
if (pkgApi?.models) {
|
if (pkgApi?.models) {
|
||||||
registerModel(pkgApi.models, database);
|
registerModel(pkgApi.models, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Registrar sus servicios, si los expone
|
// Registrar sus servicios, si los expone
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import http from "http";
|
|||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { createApp } from "./app";
|
import { createApp } from "./app";
|
||||||
import { ENV } from "./config";
|
import { ENV } from "./config";
|
||||||
import { connectToDatabase, sequelize } from "./config/database";
|
import { connectToDatabase, sequelize as database } from "./config/database";
|
||||||
import { initModules } from "./core/helpers";
|
import { initModules } from "./core/helpers";
|
||||||
import { registerModules } from "./modules";
|
import { registerModules } from "./modules";
|
||||||
|
|
||||||
@ -68,11 +68,12 @@ const serverConnection = (conn: any) => {
|
|||||||
//const sequelizeConn = createSequelizeAdapter();
|
//const sequelizeConn = createSequelizeAdapter();
|
||||||
//const firebirdConn = createFirebirdAdapter();
|
//const firebirdConn = createFirebirdAdapter();
|
||||||
|
|
||||||
// Registrar paquetes de la aplicación
|
|
||||||
registerModules();
|
registerModules();
|
||||||
|
|
||||||
const app = createApp();
|
const app = createApp();
|
||||||
|
|
||||||
|
// Registrar paquetes de la aplicación
|
||||||
|
|
||||||
// Crea el servidor HTTP
|
// Crea el servidor HTTP
|
||||||
const server = http
|
const server = http
|
||||||
.createServer(app)
|
.createServer(app)
|
||||||
@ -125,7 +126,7 @@ process.on("uncaughtException", (error: Error) => {
|
|||||||
// initStructure(sequelizeConn.connection);
|
// initStructure(sequelizeConn.connection);
|
||||||
// insertUsers();
|
// insertUsers();
|
||||||
|
|
||||||
initModules(app, sequelize);
|
initModules({ app, database: database, baseRoutePath: "/api/v1" });
|
||||||
|
|
||||||
server.listen(currentState.port, () => {
|
server.listen(currentState.port, () => {
|
||||||
logger.info("To shut down your server, press <CTRL> + C at any time");
|
logger.info("To shut down your server, press <CTRL> + C at any time");
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
/* import { getService } from "@apps/server/src/core/service-registry"; */
|
/* import { getService } from "@apps/server/src/core/service-registry"; */
|
||||||
import { logger } from "@rdx/logger";
|
import { logger } from "@rdx/logger";
|
||||||
import { IModuleServer } from "@rdx/modules";
|
import { IModuleServer, ModuleParams } from "@rdx/modules";
|
||||||
import { Application } from "express";
|
import { initInvoiceModel, invoicesRouter } from "./intrastructure";
|
||||||
import { initInvoiceModel } from "./intrastructure";
|
|
||||||
|
|
||||||
export const invoicesModule: IModuleServer = {
|
export const invoicesModule: IModuleServer = {
|
||||||
metadata: {
|
metadata: {
|
||||||
@ -10,15 +9,16 @@ export const invoicesModule: IModuleServer = {
|
|||||||
version: "1.0.0",
|
version: "1.0.0",
|
||||||
dependencies: [],
|
dependencies: [],
|
||||||
},
|
},
|
||||||
init(app: Application) {
|
init(params: ModuleParams) {
|
||||||
// const contacts = getService<ContactsService>("contacts");
|
// const contacts = getService<ContactsService>("contacts");
|
||||||
//invoicesRouter(app);
|
invoicesRouter(params);
|
||||||
logger.info("🚀 Invoices module initialized");
|
logger.info({ message: "🚀 Invoices module initialized", label: "invoices" });
|
||||||
},
|
},
|
||||||
registerDependencies() {
|
registerDependencies(params) {
|
||||||
logger.info("🚀 Invoices module dependencies registered");
|
const { database } = params;
|
||||||
|
logger.info({ message: "🚀 Invoices module dependencies registered", label: "invoices" });
|
||||||
return {
|
return {
|
||||||
models: [(sequelize) => initInvoiceModel(sequelize)],
|
models: [() => initInvoiceModel(database)],
|
||||||
services: {
|
services: {
|
||||||
getInvoice: () => {},
|
getInvoice: () => {},
|
||||||
/*...*/
|
/*...*/
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { Express } from "express";
|
|
||||||
import {
|
import {
|
||||||
buildGetInvoiceController,
|
buildGetInvoiceController,
|
||||||
buildListInvoicesController,
|
buildListInvoicesController,
|
||||||
@ -7,10 +6,17 @@ import {
|
|||||||
|
|
||||||
import { buildCreateInvoiceController } from "#/server/presentation/controllers/create-invoice";
|
import { buildCreateInvoiceController } from "#/server/presentation/controllers/create-invoice";
|
||||||
import { validateAndParseBody } from "@rdx/core";
|
import { validateAndParseBody } from "@rdx/core";
|
||||||
import { NextFunction, Request, Response, Router } from "express";
|
import { ModuleParams } from "@rdx/modules";
|
||||||
|
import { Application, NextFunction, Request, Response, Router } from "express";
|
||||||
import { Sequelize } from "sequelize";
|
import { Sequelize } from "sequelize";
|
||||||
|
|
||||||
export const invoicesRouter = (app: Express, database: Sequelize) => {
|
export const invoicesRouter = (params: ModuleParams) => {
|
||||||
|
const { app, database, baseRoutePath } = params as {
|
||||||
|
app: Application;
|
||||||
|
database: Sequelize;
|
||||||
|
baseRoutePath: string;
|
||||||
|
};
|
||||||
|
|
||||||
const routes: Router = Router({ mergeParams: true });
|
const routes: Router = Router({ mergeParams: true });
|
||||||
|
|
||||||
routes.get(
|
routes.get(
|
||||||
@ -62,5 +68,5 @@ export const invoicesRouter = (app: Express, database: Sequelize) => {
|
|||||||
}
|
}
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
app.use("/invoices", routes);
|
app.use(`${baseRoutePath}/invoices`, routes);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
//Contrato para los Modules backend (Node.js)
|
//Contrato para los Modules backend (Node.js)
|
||||||
|
|
||||||
import { Application } from "express";
|
import { ModuleDependencies, ModuleMetadata, ModuleParams } from "./types";
|
||||||
import { ModuleDependencies, ModuleMetadata } from "./types";
|
|
||||||
|
|
||||||
export interface IModuleServer {
|
export interface IModuleServer {
|
||||||
metadata: ModuleMetadata;
|
metadata: ModuleMetadata;
|
||||||
init(app: Application): void;
|
init(params: ModuleParams): void;
|
||||||
registerDependencies?(): ModuleDependencies;
|
registerDependencies?(params: ModuleParams): ModuleDependencies;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,10 @@
|
|||||||
// Contiene tipos comunes entre cliente y servidor
|
// Contiene tipos comunes entre cliente y servidor
|
||||||
|
|
||||||
import { Sequelize } from "sequelize";
|
export type ModuleParams = {
|
||||||
|
[key: string]: any;
|
||||||
|
};
|
||||||
|
|
||||||
export type ModelInitializer = (sequelize: Sequelize) => any;
|
export type ModelInitializer = () => any;
|
||||||
|
|
||||||
export interface ModuleMetadata {
|
export interface ModuleMetadata {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
Reference in New Issue
Block a user