Skip to content

Commit

Permalink
refactore
Browse files Browse the repository at this point in the history
  • Loading branch information
ZigBalthazar committed Dec 7, 2024
1 parent 524cd7a commit 6fdec1b
Show file tree
Hide file tree
Showing 27 changed files with 9,118 additions and 265 deletions.
227 changes: 55 additions & 172 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@nestjs/core": "^10.3.0",
"@nestjs/jwt": "^10.2.0",
"@nestjs/microservices": "^10.4.7",
"@nestjs/mongoose": "^10.1.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.0",
"@nestjs/schedule": "^4.1.1",
Expand All @@ -50,6 +51,8 @@
"jsonwebtoken": "^9.0.2",
"lodash": "^4.17.21",
"mime-types": "^2.1.35",
"mongodb": "^6.11.0",
"mongoose": "^8.8.4",
"morgan": "^1.10.0",
"nestjs-cls": "^3.6.0",
"nestjs-i18n": "^10.4.0",
Expand All @@ -63,6 +66,7 @@
"swagger-ui-express": "^5.0.0",
"ts-proto": "^2.2.7",
"tslib": "^2.6.2",
"typeorm": "^0.3.20",
"uuid": "^9.0.1"
},
"devDependencies": {
Expand Down
27 changes: 15 additions & 12 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common';
import './boilerplate.polyfill';

import type { MiddlewareConsumer, NestModule } from '@nestjs/common';
import { Module, RequestMethod } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';

import { JsonBodyMiddleware } from './middlewares/json-body.middleware';
import { RawBodyMiddleware } from './middlewares/raw-body.middleware';
import AuthModule from './modules/auth/auth.module';
import { ServicesConfigModule } from './modules/config/config.module';
import HealthModule from './modules/health/health.module';
import ServiceRegistryModule from './modules/service-registry/service-registry.module';
import { SubscriptionsModule } from './modules/subscriptions/subscriptions.module';
import { UserModule } from './modules/users/user.module';
import { SharedModule } from './shared/shared.module';
import { SubscriptionsModule } from './modules/subscriptions/subscriptions.module';
import { RawBodyMiddleware } from './middlewares/raw-body.middleware';
import { JsonBodyMiddleware } from './middlewares/json-body.middleware';

@Module({
imports: [
Expand All @@ -29,13 +32,13 @@ import { JsonBodyMiddleware } from './middlewares/json-body.middleware';
})
export class AppModule implements NestModule {
public configure(consumer: MiddlewareConsumer): void {
consumer
.apply(RawBodyMiddleware)
.forRoutes({
path: '/subscriptions/webhook',
method: RequestMethod.POST,
})
.apply(JsonBodyMiddleware)
.forRoutes('*');
consumer
.apply(RawBodyMiddleware)
.forRoutes({
path: '/subscriptions/webhook',
method: RequestMethod.POST,
})
.apply(JsonBodyMiddleware)
.forRoutes('*');
}
}
75 changes: 75 additions & 0 deletions src/boilerplate.polyfill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* eslint-disable canonical/no-use-extend-native */
/* eslint-disable @typescript-eslint/naming-convention,sonarjs/cognitive-complexity */

import { compact, map } from 'lodash';
import type { ObjectLiteral } from 'typeorm';

import type { AbstractEntity } from './common/abstract.entity';
import type { AbstractDto } from './common/dto/abstract.dto';
import type { KeyOfType } from './types';

declare global {
interface Array<T> {
toDtos<Dto extends AbstractDto>(this: T[], options?: unknown): Dto[];
toGrpces<K>(this: T[]): K[];
}
}

declare module 'http' {
interface IncomingHttpHeaders {
'x-org-id'?: string;
'x-user-info'?: string;
authorization?: string;
}
}

declare module 'typeorm' {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
interface QueryBuilder<Entity> {
searchByString(q: string, columnNames: string[]): this;
}

interface SelectQueryBuilder<Entity> {
leftJoinAndSelect<AliasEntity extends AbstractEntity, A extends string>(
this: SelectQueryBuilder<Entity>,
property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`,
alias: string,
condition?: string,
parameters?: ObjectLiteral,
): this;

leftJoin<AliasEntity extends AbstractEntity, A extends string>(
this: SelectQueryBuilder<Entity>,
property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`,
alias: string,
condition?: string,
parameters?: ObjectLiteral,
): this;

innerJoinAndSelect<AliasEntity extends AbstractEntity, A extends string>(
this: SelectQueryBuilder<Entity>,
property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`,
alias: string,
condition?: string,
parameters?: ObjectLiteral,
): this;

innerJoin<AliasEntity extends AbstractEntity, A extends string>(
this: SelectQueryBuilder<Entity>,
property: `${A}.${Exclude<KeyOfType<AliasEntity, AbstractEntity>, symbol>}`,
alias: string,
condition?: string,
parameters?: ObjectLiteral,
): this;
}
}

Array.prototype.toDtos = function <Entity extends AbstractEntity<Dto>, Dto extends AbstractDto>(
options?: unknown,
): Dto[] {
return compact(map<Entity, Dto>(this as Entity[], (item) => item.toDto(options as never)));
};

Array.prototype.toGrpces = function <T extends { toGrpc: () => K }, K>(): K[] {
return compact(map<T, K>(this as T[], (item) => item.toGrpc()));
};
78 changes: 78 additions & 0 deletions src/common/abstract.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { Injectable } from '@nestjs/common';
import type { DeepPartial, FindManyOptions, FindOneOptions, FindOptionsWhere, ObjectLiteral } from 'typeorm';
import { MongoRepository } from 'typeorm';

@Injectable()
export abstract class AbstractRepository<T extends ObjectLiteral> {
constructor(protected readonly repository: MongoRepository<T>) {}

/**
* Find all entities with optional filtering.
* @param options - Query options
*/
async findAll(options?: FindManyOptions<T>): Promise<T[]> {
return this.repository.find({ ...options });
}

/**
* Find one entity based on criteria.
* @param options - Query options
*/
async findOne(options: FindOneOptions<T>): Promise<T | null> {
return this.repository.findOne({ ...options });
}

/**
* Find an entity by its ID.
* @param id - ID of the entity
*/
async findById(id: string | number): Promise<T | null> {
return this.repository.findOne({
where: { id } as unknown as FindOptionsWhere<T>, // Cast the where clause to match the entity type
});
}

/**
* Save a single entity or multiple entities.
* @param data - Entity or entities to save
*/
async save(data: DeepPartial<T>): Promise<T> {
return this.repository.save(data);
}

/**
* Delete an entity by ID.
* @param id - ID of the entity to delete
*/
async deleteById(id: string | number): Promise<void> {
await this.repository.delete(id);
}

/**
* Count entities matching given criteria.
* @param options - Query options
*/
async count(options?: FindManyOptions<T>): Promise<number> {
return this.repository.count({ ...options });
}

/**
* Soft delete an entity by ID (if entity supports soft deletes).
* @param id - ID of the entity
*/
async softDeleteById(id: string | number): Promise<void> {
await this.repository.softDelete(id);
}

/**
* Restore a soft-deleted entity by ID.
* @param id - ID of the entity
*/
async restoreById(id: string | number): Promise<void> {
await this.repository.restore(id);
}

create(entityLike: DeepPartial<T>) {
return this.repository.create(entityLike);
}
}
2 changes: 0 additions & 2 deletions src/common/dto/abstract.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@ export class AbstractDto {
@ApiProperty()
id: string;

@ApiProperty()
createdAt: Date;

@ApiProperty()
updatedAt: Date;

constructor(entity: AbstractEntity, options?: { excludeFields?: boolean }) {
Expand Down
2 changes: 1 addition & 1 deletion src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ async function bootstrap() {
onLoadPackageDefinition: (pkg, server) => {
new ReflectionService(pkg).addToServer(server);

Check failure on line 66 in src/main.ts

View workflow job for this annotation

GitHub Actions / ESLint

src/main.ts#L66

Unsafe argument of type `any` assigned to a parameter of type `PackageDefinition` (@typescript-eslint/no-unsafe-argument)

Check failure on line 66 in src/main.ts

View workflow job for this annotation

GitHub Actions / ESLint

src/main.ts#L66

Unsafe argument of type `any` assigned to a parameter of type `Pick<Server, "addService">` (@typescript-eslint/no-unsafe-argument)
},
package: 'kraken', // TODO: consider making this dynamic
package: 'kraken',
protoPath: configService.grpcConfig.protoPath,
url: `localhost:${configService.grpcConfig.port}`,
},
Expand Down
11 changes: 6 additions & 5 deletions src/middlewares/json-body.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { Request, Response } from 'express';
import type { NestMiddleware } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import * as bodyParser from 'body-parser';
import { Injectable, NestMiddleware } from '@nestjs/common';
import type { Request, Response } from 'express';

@Injectable()
export class JsonBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.json()(req, res, next);
}
use(req: Request, res: Response, next: () => any) {

Check failure on line 8 in src/middlewares/json-body.middleware.ts

View workflow job for this annotation

GitHub Actions / ESLint

src/middlewares/json-body.middleware.ts#L8

Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)
bodyParser.json()(req, res, next);
}
}
11 changes: 6 additions & 5 deletions src/middlewares/raw-body.middleware.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Injectable, NestMiddleware } from '@nestjs/common';
import type { Request, Response } from 'express';
import type { NestMiddleware } from '@nestjs/common';
import { Injectable } from '@nestjs/common';
import * as bodyParser from 'body-parser';
import type { Request, Response } from 'express';

@Injectable()
export class RawBodyMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: () => any) {
bodyParser.raw({type: '*/*'})(req, res, next);
}
use(req: Request, res: Response, next: () => any) {

Check failure on line 8 in src/middlewares/raw-body.middleware.ts

View workflow job for this annotation

GitHub Actions / ESLint

src/middlewares/raw-body.middleware.ts#L8

Unexpected any. Specify a different type (@typescript-eslint/no-explicit-any)
bodyParser.raw({ type: '*/*' })(req, res, next);
}
}
1 change: 1 addition & 0 deletions src/modules/config/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class ConfigService {

async update(props: UpdateConfigDto) {
let config = await this.getConfig();

if (!config) {
config = this.configRepo.create(props);
}
Expand Down
36 changes: 15 additions & 21 deletions src/modules/config/dto/config.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { IsArray, IsOptional, IsString } from 'class-validator';

import { AbstractDto } from '../../../common/dto/abstract.dto';
import type { ConfigEntity } from '../entities/config.entity';
import { RetentionDto } from './retention.dto';
import { FeesDto } from './fees.dto';
import { RetentionDto } from './retention.dto';

export class ConfigDto extends AbstractDto {
@ApiProperty()
Expand Down Expand Up @@ -98,26 +98,20 @@ export class ConfigDto extends AbstractDto {
time: e.retention?.time,
};
this.fees = {
admission: e.fees?.admission?.map((a) => {
return {
amount: a.amount,
unit: a.unit,
};
}),
publication: e.fees?.publication?.map((p) => {
return {
amount: p.amount,
kinds: p.kinds,
unit: p.unit,
};
}),
subscription: e.fees?.subscription?.map((s) => {
return {
amount: s.amount,
period: s.period,
unit: s.unit,
};
}),
admission: e.fees?.admission?.map((a) => ({
amount: a.amount,
unit: a.unit,
})),
publication: e.fees?.publication?.map((p) => ({
amount: p.amount,
kinds: p.kinds,
unit: p.unit,
})),
subscription: e.fees?.subscription?.map((s) => ({
amount: s.amount,
period: s.period,
unit: s.unit,
})),
};
}
}
2 changes: 1 addition & 1 deletion src/modules/config/dto/retention.dto.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NumberFieldOptional, StringFieldOptional } from '../../../../src/decorators';
import { NumberFieldOptional } from '../../../../src/decorators';

export class RetentionDto {
@NumberFieldOptional()
Expand Down
2 changes: 1 addition & 1 deletion src/modules/config/entities/config.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { Column, Entity } from 'typeorm';

import { AbstractEntity } from '../../../../src/common/abstract.entity';
import { ConfigDto } from '../dto/config.dto';
import { RetentionEntity } from './retention.entity';
import { FeesEntity } from './fees.entity';
import { RetentionEntity } from './retention.entity';

@Entity('config')
export class ConfigEntity extends AbstractEntity<ConfigDto> {
Expand Down
1 change: 0 additions & 1 deletion src/modules/config/entities/retention.entity.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Column } from 'typeorm';


export class RetentionEntity {
@Column()
time?: number;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { KrakenServiceRegistryServiceControllerMethods, ServiceTypeEnum } from '
import { ServiceType } from '../enums/service-types.enum';
import ServiceRegistryService from '../services/service-registry.service';

@KrakenServiceRegistryServiceControllerMethods()
@Controller()
@KrakenServiceRegistryServiceControllerMethods()
export class ServiceRegistryGrpcController {
constructor(private readonly serviceRegistryService: ServiceRegistryService) {}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { Controller, Get } from '@nestjs/common';
import { ApiTags } from '@nestjs/swagger';

import type RegisterServiceRegistryDto from '../dtos/service-registry-register.dto';
import ServiceRegistryService from '../services/service-registry.service';
import { ApiTags } from '@nestjs/swagger';

@Controller('service-registry')
@ApiTags("service-registry")
@ApiTags('service-registry')
export default class ServiceRegistryController {
constructor(private readonly serviceRegistryService: ServiceRegistryService) {}

Expand All @@ -14,4 +15,8 @@ export default class ServiceRegistryController {

return services.map((s) => s.toDto());
}

async registerService(props: RegisterServiceRegistryDto) {
await this.serviceRegistryService.register(props);
}
}
Loading

0 comments on commit 6fdec1b

Please sign in to comment.