feat: add nestjs api and worker skeletons

This commit is contained in:
Bastian Wagner
2026-08-17 13:18:24 +02:00
parent c23bda56a3
commit a08eecd4e3
17 changed files with 124 additions and 32 deletions

View File

@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class ApiModule {}

View File

@@ -0,0 +1,22 @@
import { Test, TestingModule } from '@nestjs/testing';
import { AppController } from './app.controller';
import { AppService } from './app.service';
describe('AppController', () => {
let appController: AppController;
beforeEach(async () => {
const app: TestingModule = await Test.createTestingModule({
controllers: [AppController],
providers: [AppService],
}).compile();
appController = app.get<AppController>(AppController);
});
describe('root', () => {
it('should return "Hello World!"', () => {
expect(appController.getHello()).toBe('Hello World!');
});
});
});

View File

@@ -0,0 +1,12 @@
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}

View File

@@ -0,0 +1,8 @@
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}

View File

@@ -0,0 +1,13 @@
import { NestFactory } from '@nestjs/core';
import { ApiModule } from './api.module';
export async function bootstrapApi(): Promise<void> {
const app = await NestFactory.create(ApiModule);
app.enableShutdownHooks();
app.setGlobalPrefix('api/v1');
await app.listen(3000, '0.0.0.0');
}
if (require.main === module) {
void bootstrapApi();
}

View File

@@ -0,0 +1,29 @@
import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { App } from 'supertest/types';
import { ApiModule } from './../src/api.module';
describe('ApiModule (e2e)', () => {
let app: INestApplication<App>;
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [ApiModule],
}).compile();
app = moduleFixture.createNestApplication();
await app.init();
});
it('/ (GET)', () => {
return request(app.getHttpServer())
.get('/')
.expect(200)
.expect('Hello World!');
});
afterEach(async () => {
await app.close();
});
});

View File

@@ -0,0 +1,9 @@
{
"moduleFileExtensions": ["js", "json", "ts"],
"rootDir": "../../..",
"testEnvironment": "node",
"testRegex": "apps/api/test/.*\\.e2e-spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
}
}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/api"
},
"exclude": ["node_modules", "dist", "test", "**/*.spec.ts"]
}

View File

@@ -0,0 +1,20 @@
import { INestApplicationContext, Type } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { WorkerModule } from './worker.module';
type ContextFactory = (
module: Type<unknown>,
) => Promise<INestApplicationContext>;
export async function bootstrapWorker(
createContext: ContextFactory = (module) =>
NestFactory.createApplicationContext(module),
): Promise<INestApplicationContext> {
const app = await createContext(WorkerModule);
app.enableShutdownHooks();
return app;
}
if (require.main === module) {
void bootstrapWorker();
}

View File

@@ -0,0 +1,16 @@
import { bootstrapWorker } from './main';
describe('bootstrapWorker', () => {
it('creates an application context without starting an HTTP listener', async () => {
const close = jest.fn().mockResolvedValue(undefined);
const enableShutdownHooks = jest.fn();
const appContext = { close, enableShutdownHooks };
const createContext = jest.fn().mockResolvedValue(appContext);
const app = await bootstrapWorker(createContext as never);
expect(createContext).toHaveBeenCalledTimes(1);
expect(enableShutdownHooks).toHaveBeenCalledTimes(1);
expect(app).toBe(appContext);
});
});

View File

@@ -0,0 +1,4 @@
import { Module } from '@nestjs/common';
@Module({})
export class WorkerModule {}

View File

@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": false,
"outDir": "../../dist/apps/worker"
},
"exclude": ["node_modules", "dist", "test", "**/*.spec.ts"]
}