Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion .github/workflows/labeler.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,17 @@ name: 'Pull Request Labeler'
on:
# Важно: target позволяет работать в PR из форков
pull_request_target:
types: [opened, synchronize]
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
inputs:
pr_number:
description: 'PR Number'
required: true
type: number

concurrency:
group: ${{ github.workflow }}-${{ github.event.number }}
cancel-in-progress: true

jobs:
label:
Expand All @@ -12,6 +22,12 @@ jobs:
pull-requests: write
runs-on: ubuntu-latest
steps:
- name: Checkout head branch
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0

- name: Ensure Labels Exist
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
4 changes: 2 additions & 2 deletions libs/bootstrap/src/setups/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
} from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { WinstonModule, utilities } from 'nest-winston';
import { Observable, throwError } from 'rxjs';
import { throwError } from 'rxjs';
import { tap, catchError } from 'rxjs/operators';
import { format, transports } from 'winston';

Expand Down Expand Up @@ -39,7 +39,7 @@
private readonly logger = new Logger('HTTP');
private readonly sensitiveFields = ['password', 'token', 'access', 'refresh', 'code', 'secret'];

intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
intercept(context: ExecutionContext, next: CallHandler) {
const request = context.switchToHttp().getRequest<FastifyRequest>();
const startTime = Date.now();

Expand Down Expand Up @@ -105,7 +105,7 @@

const cleanData = structuredClone(data) as Record<string, unknown>;

return Object.keys(cleanData).reduce<Record<string, unknown>>((acc, key) => {

Check warning on line 108 in libs/bootstrap/src/setups/logger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

`Array#reduce()` is not allowed. Prefer other types of loop for readability

Check warning on line 108 in libs/bootstrap/src/setups/logger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

`Array#reduce()` is not allowed. Prefer other types of loop for readability
const isSensitive = this.sensitiveFields.some((field) =>
key.toLowerCase().includes(field),
);
Expand Down Expand Up @@ -224,5 +224,5 @@
* Additional contextual data for debugging (e.g., Zod validation issues, DB error details).
* @type {any}
*/
readonly error_details?: any;

Check warning on line 227 in libs/bootstrap/src/setups/logger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type

Check warning on line 227 in libs/bootstrap/src/setups/logger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type
};
11 changes: 8 additions & 3 deletions libs/database/src/interfaces/module.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
import type { Options } from 'postgres';
import type { Options, PostgresType } from 'postgres';

export interface DatabaseModuleOptions {
/**
Expand All @@ -24,7 +24,9 @@
* @see https://github.com/porsager/postgres#options
* @example { max: 20, idle_timeout: 30, connect_timeout: 5 }
*/
readonly pool?: Options<any>;
readonly pool?: Options<{
[key: string]: PostgresType<any>;

Check warning on line 28 in libs/database/src/interfaces/module.interface.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type

Check warning on line 28 in libs/database/src/interfaces/module.interface.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type
}>;

/**
* Включение или выключение логирования SQL-запросов в консоль через NestJS Logger.
Expand All @@ -47,6 +49,8 @@
readonly migrationsPath?: string;
}

export type DatabaseSchema = Record<string, unknown>;

/**
* Тип для внедрения Drizzle ORM в репозитории.
* Использует драйвер postgres-js под капотом.
Expand All @@ -59,4 +63,5 @@
*
* @template TSchema - Тип вашей схемы данных (например, `typeof schema`).
*/
export type DatabaseService<TSchema extends Record<string, unknown>> = PostgresJsDatabase<TSchema>;
export type DatabaseService<TSchema extends DatabaseSchema = DatabaseSchema> =
PostgresJsDatabase<TSchema>;
2 changes: 1 addition & 1 deletion libs/database/src/migration.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class MigrationService implements OnModuleInit {

constructor(
@Inject(DATABASE_SERVICE)
private readonly db: DatabaseService<any>,
private readonly db: DatabaseService,
@Inject(MODULE_OPTIONS_TOKEN)
private readonly options: typeof OPTIONS_TYPE,
) {}
Expand Down
2 changes: 1 addition & 1 deletion libs/health/src/controller/health.controlller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

describe('HealthController', () => {
let controller: HealthController;
let healthServiceMock: { readonly getHealthData: ReturnType<typeof vi.fn> };
let healthServiceMock: { getHealthData: ReturnType<typeof vi.fn> };

const SERVICE_NAME = 'MyService';

Expand All @@ -14,7 +14,7 @@
getHealthData: vi.fn(),
};

controller = new HealthController(healthServiceMock as any);

Check warning on line 17 in libs/health/src/controller/health.controlller.spec.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type

Check warning on line 17 in libs/health/src/controller/health.controlller.spec.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Unexpected any. Specify a different type

vi.spyOn(Logger.prototype, 'error').mockImplementation(() => {});
});
Expand Down
103 changes: 56 additions & 47 deletions libs/imagor/src/utils/imagor-path-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,93 +62,102 @@ export class ImagorPathBuilder {
return parts.join('/');
}

// TODO will fix that shit
// eslint-disable-next-line sonarjs/cognitive-complexity
private serializeAllFilters(f: Filters): string {
const s: string[] = [];
const segments: string[] = [];

this.addBasicFilters(f, segments);
this.addAdjustmentFilters(f, segments);
this.addEffectFilters(f, segments);
this.addTransformationFilters(f, segments);
this.addWatermarkFilter(f, segments);

return segments.length ? `filters:${segments.join(':')}` : '';
}

private addBasicFilters(f: Filters, segments: string[]): void {
if (f.quality) {
s.push(`quality(${f.quality})`);
segments.push(`quality(${f.quality})`);
}
if (f.format) {
s.push(`format(${f.format})`);
segments.push(`format(${f.format})`);
}
if (f.autojpg) {
s.push('autojpg()');
segments.push('autojpg()');
}
if (f.strip_exif) {
s.push('strip_exif()');
segments.push('strip_exif()');
}
if (f.strip_icc) {
s.push('strip_icc()');
segments.push('strip_icc()');
}
if (f.no_upscale) {
segments.push('no_upscale()');
}
if (f.max_bytes) {
segments.push(`max_bytes(${f.max_bytes})`);
}
}

private addAdjustmentFilters(f: Filters, segments: string[]): void {
if (f.brightness !== undefined) {
s.push(`brightness(${f.brightness})`);
segments.push(`brightness(${f.brightness})`);
}
if (f.contrast !== undefined) {
s.push(`contrast(${f.contrast})`);
segments.push(`contrast(${f.contrast})`);
}
if (f.grayscale) {
s.push('grayscale()');
segments.push('grayscale()');
}
if (f.proportion !== undefined) {
s.push(`proportion(${f.proportion})`);
segments.push(`proportion(${f.proportion})`);
}
if (f.rgb) {
s.push(`rgb(${f.rgb.r},${f.rgb.g},${f.rgb.b})`);
segments.push(`rgb(${f.rgb.r},${f.rgb.g},${f.rgb.b})`);
}
}

private addEffectFilters(f: Filters, segments: string[]): void {
if (f.blur) {
const b = f.blur;
s.push(typeof b === 'number' ? `blur(${b})` : `blur(${b.radius},${b.sigma || 0})`);
segments.push(
typeof f.blur === 'number'
? `blur(${f.blur})`
: `blur(${f.blur.radius},${f.blur.sigma ?? 0})`,
);
}
if (f.sharpen) {
s.push(`sharpen(${f.sharpen.amount},${f.sharpen.radius},${f.sharpen.threshold})`);
}
if (f.noise) {
s.push(`noise(${f.noise})`);
const { amount, radius, threshold } = f.sharpen;
segments.push(`sharpen(${amount},${radius},${threshold})`);
}
if (f.rotate) {
s.push(`rotate(${f.rotate})`);
if (f.noise !== undefined) {
segments.push(`noise(${f.noise})`);
}
}

private addTransformationFilters(f: Filters, segments: string[]): void {
if (f.rotate !== undefined) {
segments.push(`rotate(${f.rotate})`);
}
if (f.fill) {
s.push(`fill(${f.fill})`);
segments.push(`fill(${f.fill})`);
}
if (f.background_color) {
s.push(`background_color(${f.background_color})`);
segments.push(`background_color(${f.background_color})`);
}

if (f.watermark) {
const w = f.watermark;
const params = [
w.image,
w.x ?? 0,
w.y ?? 0,
w.alpha ?? 0,
w.w_ratio ?? 0,
w.h_ratio ?? 0,
];
s.push(`watermark(${params.join(',')})`);
}

if (f.focal) {
s.push(`focal(${f.focal.x}x${f.focal.y})`);
segments.push(`focal(${f.focal.x}x${f.focal.y})`);
}
if (f.round_corner) {
s.push(
`round_corner(${f.round_corner.radius}${f.round_corner.color ? `,${f.round_corner.color}` : ''})`,
);
const { radius, color } = f.round_corner;
segments.push(`round_corner(${radius}${color ? `,${color}` : ''})`);
}
}

if (f.max_bytes) {
s.push(`max_bytes(${f.max_bytes})`);
}
if (f.no_upscale) {
s.push('no_upscale()');
private addWatermarkFilter(f: Filters, segments: string[]): void {
if (!f.watermark) {
return;
}

return s.length ? `filters:${s.join(':')}` : '';
const { image, x = 0, y = 0, alpha = 0, w_ratio = 0, h_ratio = 0 } = f.watermark;
segments.push(`watermark(${image},${x},${y},${alpha},${w_ratio},${h_ratio})`);
}
}
7 changes: 3 additions & 4 deletions src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { MediaModule } from '@core/media';
import { ConfigModule } from '@libs/config';
import { DatabaseModule, DatabaseHealthService } from '@libs/database';
import { HealthModule } from '@libs/health';
Expand All @@ -14,12 +15,11 @@ import { ICacheService } from '@shared/adapters/cache/ports';
import { MailModule } from '@shared/adapters/mail';
import { GlobalExceptionFilter } from '@shared/error';
import { ZodValidationInterceptor } from '@shared/interceptors';
import { MediaModule } from '@shared/media';
import { ZodValidationPipe } from 'nestjs-zod';

import { AreaModule } from './area';
import { AuthModule } from './auth/auth.module';
import { ProjectsModule } from './projects';
import { ProjectModule } from './project';
import * as schema from './shared/entities';
import { TeamsModule } from './teams';
import { UserModule } from './user';
Expand All @@ -34,7 +34,6 @@ import { UserModule } from './user';
schema,
schemaName: cfg.getOrThrow('DB_SCHEMA'),
logging: true,
// runMigrations: false,
}),
}),
BullModule.forRootAsync({
Expand All @@ -54,7 +53,7 @@ import { UserModule } from './user';
AuthModule,
UserModule,
TeamsModule,
ProjectsModule,
ProjectModule,
AreaModule,
MetricsModule,
HealthModule.registerAsync({
Expand Down
3 changes: 2 additions & 1 deletion src/area/application/area.facade.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ReordersStatesDto,
CreateAreaDto,
UpdateAreaDto,
QueryParamsDto,
} from './dtos';
import {
CreateAreaUseCase,
Expand Down Expand Up @@ -78,7 +79,7 @@ export class AreaFacade {
return this.getStateDetailQ.execute(slug, stateId, userId);
}

public async getStates(slug: string, query: unknown, userId: string) {
public async getStates(slug: string, query: QueryParamsDto, userId: string) {
return this.getStatesQ.execute(slug, userId, query);
}

Expand Down
2 changes: 1 addition & 1 deletion src/area/application/controllers/area/swagger.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import { ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiBody } from '@nestjs/swagger';
import { ActionResponse } from '@shared/dtos';
import {
ApiUnauthorized,
ApiNotFound,
Expand All @@ -9,6 +8,7 @@
ApiConflict,
} from '@shared/error';
import { ZOD_RESPONSE_TOKEN } from '@shared/interceptors';
import { ActionResponse } from '@shared/schemas';

import { CreateAreaDto, UpdateAreaDto, AreaResponse, AreasResponse } from '../../dtos';

Expand All @@ -32,8 +32,8 @@
ApiParam({
name: 'slug',
type: 'string',
description: 'Slug проекта',

Check warning on line 35 in src/area/application/controllers/area/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 6 times

Check warning on line 35 in src/area/application/controllers/area/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 6 times
example: 'super-project',

Check warning on line 36 in src/area/application/controllers/area/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 6 times

Check warning on line 36 in src/area/application/controllers/area/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 6 times
}),
ApiBody({
type: CreateAreaDto.Output,
Expand Down
27 changes: 2 additions & 25 deletions src/area/application/controllers/state/controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Body, Delete, Get, Param, Patch, Post, Query } from '@nestjs/common';
import { ApiBaseController, GetUserId, Public } from '@shared/decorators';

import { AreaFacade } from '../../area.facade';
import { CreateStateDto, ReordersStatesDto, UpdateStateDto } from '../../dtos';
import { CreateStateDto, QueryParamsDto, ReordersStatesDto, UpdateStateDto } from '../../dtos';

import {
CreateStateSwagger,
Expand All @@ -24,31 +24,8 @@ export class StateController {
async getAll(
@Param('slug') slug: string,
@GetUserId() userId: string,
// TODO: ADD SCHEMA, AT DTO, AND VALIDATE WITH CONTRACT
@Query('hidden') hidden?: boolean,
@Query('counts') counts?: boolean,
@Query('my') my?: boolean,
@Query('category') category?: string,
@Query('overdue') overdue?: boolean,
@Query('orderBy') orderBy?: 'order' | 'title' | 'tasksCount' | 'createdAt',
@Query('order') order?: 'asc' | 'desc',
@Query('page') page?: number,
@Query('offset') offset?: number,
@Query('limit') limit?: number,
@Query() query: QueryParamsDto,
) {
const query = {
hidden,
counts,
my,
category,
overdue,
order,
limit,
offset,
page,
orderBy,
};

return this.facade.getStates(slug, query, userId);
}

Expand Down
2 changes: 1 addition & 1 deletion src/area/application/controllers/state/swagger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { applyDecorators, SetMetadata } from '@nestjs/common';
import { ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiBody } from '@nestjs/swagger';
import { ApiListQuery } from '@shared/decorators';
import { ActionResponse } from '@shared/dtos';
import {
ApiUnauthorized,
ApiNotFound,
Expand All @@ -10,6 +9,7 @@
ApiConflict,
} from '@shared/error';
import { ZOD_RESPONSE_TOKEN } from '@shared/interceptors';
import { ActionResponse } from '@shared/schemas';

import {
CreateStateDto,
Expand All @@ -35,8 +35,8 @@
ApiParam({
name: 'slug',
type: 'string',
description: 'Slug проекта',

Check warning on line 38 in src/area/application/controllers/state/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 7 times

Check warning on line 38 in src/area/application/controllers/state/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 7 times
example: 'super-project',

Check warning on line 39 in src/area/application/controllers/state/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 7 times

Check warning on line 39 in src/area/application/controllers/state/swagger.ts

View workflow job for this annotation

GitHub Actions / Lint & Test

Define a constant instead of duplicating this literal 7 times
}),
ApiQuery({
name: 'hidden',
Expand Down
2 changes: 1 addition & 1 deletion src/area/application/dtos/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from './states.dto';
export * from './state.dto';
export * from './area.dto';
Loading
Loading