@sentzunhat/zacatl
Version:
A modular, high-performance TypeScript microservice framework for Node.js, featuring layered architecture, dependency injection, and robust validation for building scalable APIs and distributed systems.
113 lines • 3.86 kB
JavaScript
import { CustomError, InternalServerError } from '../../../error/index.js';
import { ExpressApiAdapter, FastifyApiAdapter } from './api/adapters/index.js';
import { ApiServer } from './api/api-server.js';
import { DatabaseServer } from './database/database-server.js';
import { ExpressPageAdapter, FastifyPageAdapter } from './page/adapters/index.js';
import { PageServer } from './page/page-server.js';
import { ServerVendor } from './types/server-config.js';
export class Server {
config;
apiAdapter;
pageAdapter;
apiServer;
pageServer;
databaseServer;
constructor(config) {
this.config = config;
const adapters = this.createAdapters(config.server);
this.apiAdapter = adapters.api;
this.pageAdapter = adapters.page;
this.initializeServers();
}
createAdapters(config) {
if (config.vendor === ServerVendor.FASTIFY) {
const instance = config.instance;
return {
api: new FastifyApiAdapter(instance),
page: new FastifyPageAdapter(instance),
};
}
else if (config.vendor === ServerVendor.EXPRESS) {
const instance = config.instance;
return {
api: new ExpressApiAdapter(instance),
page: new ExpressPageAdapter(instance),
};
}
else {
throw new InternalServerError({
message: `Unsupported server vendor: ${config.vendor}`,
reason: 'Server vendor must be Fastify or Express',
component: 'Server',
operation: 'createAdapters',
metadata: { vendor: config.vendor },
});
}
}
initializeServers() {
this.apiServer = new ApiServer(this.config.server, this.apiAdapter);
this.pageServer = new PageServer(this.config, this.pageAdapter);
if (this.config.databases.length > 0) {
this.databaseServer = new DatabaseServer(this.config.name, this.config.databases);
}
}
async configureDatabases() {
if (this.databaseServer) {
await this.databaseServer.configure();
}
}
async registerEntrypoints(entryPoints) {
if (this.apiServer) {
await this.apiServer.registerEntrypoints(entryPoints);
}
}
getApiAdapter() {
return this.apiAdapter;
}
getPageAdapter() {
return this.pageAdapter;
}
getApiServer() {
return this.apiServer;
}
getPageServer() {
return this.pageServer;
}
getDatabaseServer() {
return this.databaseServer;
}
async start(options) {
try {
await this.configureDatabases();
if (this.pageServer) {
await this.pageServer.configure();
}
if (!this.apiServer) {
throw new InternalServerError({
message: 'ApiServer not initialized',
reason: 'ApiServer failed to initialize',
component: 'Server',
operation: 'start',
});
}
const port = options?.port ?? this.config.port;
await this.apiServer.listen(port);
}
catch (error) {
throw new CustomError({
message: `failed to start service "${this.config.name}"`,
code: 500,
reason: 'service start failed',
error: error,
metadata: {
service: {
name: this.config.name,
vendor: this.config.server.vendor,
type: this.config.server.type,
},
},
});
}
}
}
//# sourceMappingURL=server.js.map