1
This commit is contained in:
@@ -1,14 +1,23 @@
|
||||
import { pathToFileURL } from 'node:url';
|
||||
|
||||
import { createApp } from './app.js';
|
||||
import { type AppConfig,loadConfig } from './config.js';
|
||||
import { type AppConfig, loadConfig } from './config.js';
|
||||
import type { AppContext } from './context.js';
|
||||
import { createDatabase } from './db.js';
|
||||
import { createLogger } from './logging.js';
|
||||
import { AuthIdentityRepository } from './repositories/authIdentityRepository.js';
|
||||
import { AuthAuditLogRepository } from './repositories/authAuditLogRepository.js';
|
||||
import { AuthRiskBlockRepository } from './repositories/authRiskBlockRepository.js';
|
||||
import { RuntimeRepository } from './repositories/runtimeRepository.js';
|
||||
import { SmsAuthEventRepository } from './repositories/smsAuthEventRepository.js';
|
||||
import { UserRepository } from './repositories/userRepository.js';
|
||||
import { UserSessionRepository } from './repositories/userSessionRepository.js';
|
||||
import { CustomWorldSessionStore } from './services/customWorldSessionStore.js';
|
||||
import { UpstreamLlmClient } from './services/llmClient.js';
|
||||
import { CaptchaChallengeStore } from './services/captchaChallengeStore.js';
|
||||
import { createSmsVerificationService } from './services/smsVerificationService.js';
|
||||
import { createWechatAuthService } from './services/wechatAuthService.js';
|
||||
import { WechatAuthStateStore } from './services/wechatAuthStateStore.js';
|
||||
|
||||
function resolveListenTarget(serverAddr: string) {
|
||||
const trimmed = serverAddr.trim();
|
||||
@@ -41,24 +50,57 @@ function resolveListenTarget(serverAddr: string) {
|
||||
};
|
||||
}
|
||||
|
||||
export function createAppContext(config: AppConfig = loadConfig()) {
|
||||
function describeDatabase(databaseUrl: string) {
|
||||
if (databaseUrl.startsWith('pg-mem://')) {
|
||||
return {
|
||||
database_engine: 'pg-mem',
|
||||
database_name: databaseUrl.slice('pg-mem://'.length) || 'memory',
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL(databaseUrl);
|
||||
return {
|
||||
database_engine: url.protocol.replace(/:$/u, ''),
|
||||
database_host: url.hostname,
|
||||
database_port: Number(url.port || 5432),
|
||||
database_name: url.pathname.replace(/^\/+/u, '') || 'postgres',
|
||||
};
|
||||
} catch {
|
||||
return {
|
||||
database_engine: 'postgresql',
|
||||
database_target: 'configured',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export async function createAppContext(config: AppConfig = loadConfig()) {
|
||||
const logger = createLogger(config);
|
||||
const db = createDatabase(config);
|
||||
const db = await createDatabase(config);
|
||||
const context: AppContext = {
|
||||
config,
|
||||
logger,
|
||||
db,
|
||||
userRepository: new UserRepository(db),
|
||||
authIdentityRepository: new AuthIdentityRepository(db),
|
||||
authAuditLogRepository: new AuthAuditLogRepository(db),
|
||||
authRiskBlockRepository: new AuthRiskBlockRepository(db),
|
||||
smsAuthEventRepository: new SmsAuthEventRepository(db),
|
||||
userSessionRepository: new UserSessionRepository(db),
|
||||
runtimeRepository: new RuntimeRepository(db),
|
||||
llmClient: new UpstreamLlmClient(config, logger),
|
||||
customWorldSessions: new CustomWorldSessionStore(),
|
||||
smsVerificationService: createSmsVerificationService(config, logger),
|
||||
wechatAuthService: createWechatAuthService(config, logger),
|
||||
wechatAuthStates: new WechatAuthStateStore(),
|
||||
captchaChallenges: new CaptchaChallengeStore(),
|
||||
};
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const context = createAppContext();
|
||||
const context = await createAppContext();
|
||||
const app = createApp(context);
|
||||
const { host, port } = resolveListenTarget(context.config.serverAddr);
|
||||
const server = app.listen(port, host, () => {
|
||||
@@ -66,17 +108,29 @@ async function main() {
|
||||
{
|
||||
host,
|
||||
port,
|
||||
sqlite_path: context.config.sqlitePath,
|
||||
...describeDatabase(context.config.databaseUrl),
|
||||
},
|
||||
'server-node started',
|
||||
);
|
||||
});
|
||||
|
||||
let shuttingDown = false;
|
||||
const shutdown = () => {
|
||||
if (shuttingDown) {
|
||||
return;
|
||||
}
|
||||
shuttingDown = true;
|
||||
context.logger.info('server-node shutting down');
|
||||
server.close(() => {
|
||||
context.db.close();
|
||||
process.exit(0);
|
||||
void context.db
|
||||
.close()
|
||||
.then(() => {
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((error) => {
|
||||
context.logger.error({ err: error }, 'failed to close database');
|
||||
process.exit(1);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
@@ -89,5 +143,8 @@ const isEntryPoint =
|
||||
import.meta.url === pathToFileURL(process.argv[1]).href;
|
||||
|
||||
if (isEntryPoint) {
|
||||
void main();
|
||||
void main().catch((error) => {
|
||||
console.error(error);
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user