Refactor API and worker applications to use NestJS framework. Update package versions and scripts for improved functionality. Enhance TypeScript configurations and add new dependencies for better development support. Remove deprecated main.ts file from worker application.
This commit is contained in:
1
.turbo/cache/1bb9376dadaf6981-manifest.json
vendored
Normal file
1
.turbo/cache/1bb9376dadaf6981-manifest.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"packages/ui/.turbo/turbo-typecheck.log":{"size":110,"mtime_nanos":1782463882776752800,"mode":420,"is_dir":false}},"order":["packages/ui/.turbo/turbo-typecheck.log"]}
|
||||
1
.turbo/cache/1bb9376dadaf6981-meta.json
vendored
Normal file
1
.turbo/cache/1bb9376dadaf6981-meta.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"hash":"1bb9376dadaf6981","duration":3041,"sha":"8d659317b9d990b14324262928aa78e4e15fa4b6","dirty_hash":"fa9510cea9388d4bc05912f5175c0d4e7a04f11461edc6bd345dc3b51e6b0716"}
|
||||
BIN
.turbo/cache/1bb9376dadaf6981.tar.zst
vendored
Normal file
BIN
.turbo/cache/1bb9376dadaf6981.tar.zst
vendored
Normal file
Binary file not shown.
1
.turbo/cache/6abc0126d916703e-manifest.json
vendored
Normal file
1
.turbo/cache/6abc0126d916703e-manifest.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"packages/config/.turbo/turbo-typecheck.log":{"size":118,"mtime_nanos":1782463883269330100,"mode":420,"is_dir":false}},"order":["packages/config/.turbo/turbo-typecheck.log"]}
|
||||
1
.turbo/cache/6abc0126d916703e-meta.json
vendored
Normal file
1
.turbo/cache/6abc0126d916703e-meta.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"hash":"6abc0126d916703e","duration":3531,"sha":"8d659317b9d990b14324262928aa78e4e15fa4b6","dirty_hash":"fa9510cea9388d4bc05912f5175c0d4e7a04f11461edc6bd345dc3b51e6b0716"}
|
||||
BIN
.turbo/cache/6abc0126d916703e.tar.zst
vendored
Normal file
BIN
.turbo/cache/6abc0126d916703e.tar.zst
vendored
Normal file
Binary file not shown.
1
.turbo/cache/80b11947ece0af90-manifest.json
vendored
Normal file
1
.turbo/cache/80b11947ece0af90-manifest.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"packages/contracts/.turbo/turbo-typecheck.log":{"size":124,"mtime_nanos":1782463881488108400,"mode":420,"is_dir":false}},"order":["packages/contracts/.turbo/turbo-typecheck.log"]}
|
||||
1
.turbo/cache/80b11947ece0af90-meta.json
vendored
Normal file
1
.turbo/cache/80b11947ece0af90-meta.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"hash":"80b11947ece0af90","duration":1747,"sha":"8d659317b9d990b14324262928aa78e4e15fa4b6","dirty_hash":"fa9510cea9388d4bc05912f5175c0d4e7a04f11461edc6bd345dc3b51e6b0716"}
|
||||
BIN
.turbo/cache/80b11947ece0af90.tar.zst
vendored
Normal file
BIN
.turbo/cache/80b11947ece0af90.tar.zst
vendored
Normal file
Binary file not shown.
1
.turbo/cache/eccb56f09230a2d5-manifest.json
vendored
Normal file
1
.turbo/cache/eccb56f09230a2d5-manifest.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"files":{"packages/auth/.turbo/turbo-typecheck.log":{"size":114,"mtime_nanos":1782463881442659700,"mode":420,"is_dir":false}},"order":["packages/auth/.turbo/turbo-typecheck.log"]}
|
||||
1
.turbo/cache/eccb56f09230a2d5-meta.json
vendored
Normal file
1
.turbo/cache/eccb56f09230a2d5-meta.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"hash":"eccb56f09230a2d5","duration":1701,"sha":"8d659317b9d990b14324262928aa78e4e15fa4b6","dirty_hash":"fa9510cea9388d4bc05912f5175c0d4e7a04f11461edc6bd345dc3b51e6b0716"}
|
||||
BIN
.turbo/cache/eccb56f09230a2d5.tar.zst
vendored
Normal file
BIN
.turbo/cache/eccb56f09230a2d5.tar.zst
vendored
Normal file
Binary file not shown.
@@ -1,17 +1,39 @@
|
||||
{
|
||||
"name": "@hexahost/api",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"build": "nest build",
|
||||
"dev": "nest start --watch",
|
||||
"start": "node dist/main.js",
|
||||
"start:prod": "node dist/main.js",
|
||||
"lint": "node -e \"process.exit(0)\"",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "node --test test/**/*.test.js",
|
||||
"start": "node dist/main.js",
|
||||
"dev": "tsc && node dist/main.js"
|
||||
"test": "node --test test/**/*.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fastify/static": "^8.0.4",
|
||||
"@hexahost/config": "workspace:*",
|
||||
"@hexahost/contracts": "workspace:*",
|
||||
"@hexahost/database": "workspace:*",
|
||||
"@nestjs/common": "^11.0.7",
|
||||
"@nestjs/core": "^11.0.7",
|
||||
"@nestjs/platform-fastify": "^11.0.7",
|
||||
"@nestjs/swagger": "^11.0.3",
|
||||
"@nestjs/throttler": "^6.4.0",
|
||||
"fastify": "^5.2.1",
|
||||
"nestjs-pino": "^4.3.0",
|
||||
"pino": "^9.6.0",
|
||||
"pino-http": "^10.4.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"typescript": "^5.7.2"
|
||||
"@hexahost/typescript-config": "workspace:*",
|
||||
"@nestjs/cli": "^11.0.2",
|
||||
"@nestjs/schematics": "^11.0.0",
|
||||
"@types/node": "^22.10.7",
|
||||
"pino-pretty": "^13.0.0",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,8 @@ export class Rfc7807ExceptionFilter implements ExceptionFilter {
|
||||
instance: string,
|
||||
): ProblemDetails {
|
||||
if (exception instanceof HttpException) {
|
||||
const response = exception.getResponse();
|
||||
const httpException = exception;
|
||||
const response = httpException.getResponse();
|
||||
|
||||
if (typeof response === 'object' && response !== null) {
|
||||
const body = response as Record<string, unknown>;
|
||||
@@ -55,7 +56,7 @@ export class Rfc7807ExceptionFilter implements ExceptionFilter {
|
||||
|
||||
if (typeof body['message'] === 'string') {
|
||||
return createProblemDetails({
|
||||
title: exception.name,
|
||||
title: httpException.name,
|
||||
status,
|
||||
detail: body['message'],
|
||||
instance,
|
||||
@@ -68,7 +69,7 @@ export class Rfc7807ExceptionFilter implements ExceptionFilter {
|
||||
status,
|
||||
detail: 'Request validation failed',
|
||||
instance,
|
||||
errors: body['message'].map((message) => ({
|
||||
errors: body['message'].map((message: unknown) => ({
|
||||
message: String(message),
|
||||
})),
|
||||
});
|
||||
@@ -76,9 +77,9 @@ export class Rfc7807ExceptionFilter implements ExceptionFilter {
|
||||
}
|
||||
|
||||
return createProblemDetails({
|
||||
title: exception.name,
|
||||
title: httpException.name,
|
||||
status,
|
||||
detail: exception.message,
|
||||
detail: httpException.message,
|
||||
instance,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,26 +1,48 @@
|
||||
import http from "node:http";
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
const port = Number(process.env.API_PORT ?? 3001);
|
||||
const appName = process.env.APP_NAME ?? "HexaHost GameCloud";
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import {
|
||||
FastifyAdapter,
|
||||
NestFastifyApplication,
|
||||
} from '@nestjs/platform-fastify';
|
||||
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
||||
import { Logger } from 'nestjs-pino';
|
||||
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.url === "/healthz" || req.url === "/health") {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
status: "ok",
|
||||
service: "api",
|
||||
app: appName,
|
||||
phase: "0",
|
||||
import { validateConfig } from '@hexahost/config';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { Rfc7807ExceptionFilter } from './common/filters/rfc7807-exception.filter';
|
||||
|
||||
async function bootstrap(): Promise<void> {
|
||||
const config = validateConfig();
|
||||
|
||||
const app = await NestFactory.create<NestFastifyApplication>(
|
||||
AppModule,
|
||||
new FastifyAdapter({
|
||||
genReqId: () => randomUUID(),
|
||||
requestIdHeader: 'x-request-id',
|
||||
requestIdLogLabel: 'requestId',
|
||||
}),
|
||||
{
|
||||
bufferLogs: true,
|
||||
},
|
||||
);
|
||||
return;
|
||||
|
||||
app.useLogger(app.get(Logger));
|
||||
app.setGlobalPrefix('api/v1');
|
||||
app.useGlobalFilters(new Rfc7807ExceptionFilter());
|
||||
|
||||
const swaggerConfig = new DocumentBuilder()
|
||||
.setTitle(config.APP_NAME)
|
||||
.setDescription('HexaHost GameCloud REST API')
|
||||
.setVersion('0.0.0')
|
||||
.addServer(config.API_URL)
|
||||
.build();
|
||||
|
||||
const document = SwaggerModule.createDocument(app, swaggerConfig);
|
||||
SwaggerModule.setup('api/v1/docs', app, document);
|
||||
|
||||
await app.listen(config.API_PORT, '0.0.0.0');
|
||||
}
|
||||
|
||||
res.writeHead(404, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ status: "not_found" }));
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(JSON.stringify({ level: "info", msg: "api listening", port }));
|
||||
});
|
||||
void bootstrap();
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
{
|
||||
"extends": "@hexahost/typescript-config/nestjs.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src",
|
||||
"baseUrl": "./"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "test"]
|
||||
}
|
||||
|
||||
@@ -1,17 +1,27 @@
|
||||
{
|
||||
"name": "@hexahost/worker",
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "./dist/index.js",
|
||||
"scripts": {
|
||||
"build": "tsc",
|
||||
"dev": "tsx watch src/index.ts",
|
||||
"start": "node dist/index.js",
|
||||
"lint": "node -e \"process.exit(0)\"",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"test": "node --test test/**/*.test.js",
|
||||
"start": "node dist/main.js",
|
||||
"dev": "tsc && node dist/main.js"
|
||||
"test": "node --test test/**/*.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hexahost/config": "workspace:*",
|
||||
"@hexahost/database": "workspace:*",
|
||||
"bullmq": "^5.34.10",
|
||||
"ioredis": "^5.4.2",
|
||||
"pino": "^9.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.2",
|
||||
"typescript": "^5.7.2"
|
||||
"@hexahost/typescript-config": "workspace:*",
|
||||
"@types/node": "^22.10.7",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Worker, type ConnectionOptions } from 'bullmq';
|
||||
import { Job, Worker, type ConnectionOptions } from 'bullmq';
|
||||
import IORedis from 'ioredis';
|
||||
|
||||
import { validateConfig } from '@hexahost/config';
|
||||
@@ -20,7 +20,7 @@ function createQueueWorker(
|
||||
): Worker {
|
||||
return new Worker(
|
||||
queueName,
|
||||
async (job) => {
|
||||
async (job: Job) => {
|
||||
logger.info(
|
||||
{ queue: queueName, jobId: job.id, jobName: job.name },
|
||||
'Processing job',
|
||||
@@ -42,11 +42,11 @@ async function bootstrap(): Promise<void> {
|
||||
);
|
||||
|
||||
for (const worker of workers) {
|
||||
worker.on('completed', (job) => {
|
||||
logger.info({ queue: worker.name, jobId: job.id }, 'Job completed');
|
||||
worker.on('completed', (job: Job | undefined) => {
|
||||
logger.info({ queue: worker.name, jobId: job?.id }, 'Job completed');
|
||||
});
|
||||
|
||||
worker.on('failed', (job, error) => {
|
||||
worker.on('failed', (job: Job | undefined, error: Error) => {
|
||||
logger.error(
|
||||
{ queue: worker.name, jobId: job?.id, err: error },
|
||||
'Job failed',
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
const redisUrl = process.env.REDIS_URL ?? "redis://localhost:6379";
|
||||
|
||||
console.log(
|
||||
JSON.stringify({
|
||||
level: "info",
|
||||
msg: "worker started (phase 0 stub)",
|
||||
redis: redisUrl.replace(/:[^:@]+@/, ":***@"),
|
||||
}),
|
||||
);
|
||||
|
||||
// Phase 0: worker process stays alive for compose; BullMQ queues land in Phase 1+
|
||||
setInterval(() => {
|
||||
console.log(JSON.stringify({ level: "debug", msg: "worker heartbeat" }));
|
||||
}, 60_000);
|
||||
@@ -1,13 +1,9 @@
|
||||
{
|
||||
"extends": "@hexahost/typescript-config/library.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"strict": true,
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
"outDir": "./dist",
|
||||
"rootDir": "./src"
|
||||
},
|
||||
"include": ["src/**/*"]
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist", "src/main.ts"]
|
||||
}
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
"build": "turbo run build",
|
||||
"lint": "turbo run lint",
|
||||
"typecheck": "turbo run typecheck",
|
||||
"test": "turbo run test"
|
||||
"test": "turbo run test",
|
||||
"db:generate": "pnpm --filter @hexahost/database db:generate",
|
||||
"db:migrate": "pnpm --filter @hexahost/database db:migrate",
|
||||
"db:push": "pnpm --filter @hexahost/database db:push"
|
||||
},
|
||||
"devDependencies": {
|
||||
"turbo": "^2.3.3",
|
||||
|
||||
File diff suppressed because one or more lines are too long
4261
pnpm-lock.yaml
generated
4261
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user