Skip to content

Commit 848d7d8

Browse files
author
Artem
committed
#RI-3775 rework ClientMetadata decorators, fix tests
1 parent 71efe71 commit 848d7d8

35 files changed

+404
-465
lines changed

redisinsight/api/src/__mocks__/databases.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import { mockIORedisClient } from 'src/__mocks__/redis';
77
import { mockSentinelMasterDto } from 'src/__mocks__/redis-sentinel';
88
import { pick } from 'lodash';
99
import { RedisDatabaseInfoResponse } from 'src/modules/database/dto/redis-info.dto';
10-
import { ClientMetadata } from 'src/modules/redis/models/client-metadata';
11-
import { AppTool } from 'src/models';
1210
import { DatabaseOverview } from 'src/modules/database/models/database-overview';
1311

1412
export const mockDatabaseId = 'a77b23c1-7816-4ea4-b61f-d37795a0f805-db-id';
@@ -115,11 +113,6 @@ export const mockClusterDatabaseWithTlsAuthEntity = Object.assign(new DatabaseEn
115113
nodes: JSON.stringify(mockClusterNodes),
116114
});
117115

118-
export const mockClientMetadata: ClientMetadata = {
119-
databaseId: mockDatabase.id,
120-
namespace: AppTool.Common,
121-
};
122-
123116
export const mockDatabaseOverview: DatabaseOverview = {
124117
version: '6.2.4',
125118
usedMemory: 1,
Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,56 @@
1-
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
1+
import { BadRequestException, createParamDecorator, ExecutionContext } from '@nestjs/common';
22
import { plainToClass } from 'class-transformer';
33
import { ClientContext, ClientMetadata } from 'src/common/models';
44
import { sessionFromRequestFactory } from 'src/common/decorators';
5-
import { API_PARAM_CLI_CLIENT_ID, API_PARAM_DATABASE_ID } from 'src/common/constants';
5+
import { Validator } from 'class-validator';
6+
import { API_PARAM_DATABASE_ID } from 'src/common/constants';
67

7-
export interface IClientMetadataDecoratorOptions {
8-
paramPath?: string,
9-
queryPath?: string,
10-
bodyPath?: string,
8+
const validator = new Validator();
9+
10+
export interface IClientMetadataParamOptions {
11+
databaseIdParam?: string,
12+
uniqueIdParam?: string,
1113
context?: ClientContext,
12-
uniqueId?: string,
1314
}
1415

15-
export const clientMetadataFromRequestFactory = (options: IClientMetadataDecoratorOptions, ctx: ExecutionContext) => {
16-
const opts: IClientMetadataDecoratorOptions = {
16+
export const clientMetadataParamFactory = (
17+
options: IClientMetadataParamOptions,
18+
ctx: ExecutionContext,
19+
): ClientMetadata => {
20+
const opts: IClientMetadataParamOptions = {
1721
context: ClientContext.Common,
22+
databaseIdParam: API_PARAM_DATABASE_ID,
1823
...options,
1924
};
2025

21-
const request = ctx.switchToHttp().getRequest();
26+
const req = ctx.switchToHttp().getRequest();
2227

2328
let databaseId;
24-
if (opts.paramPath) {
25-
databaseId = request.params?.[opts.paramPath];
26-
} else if (opts.queryPath) {
27-
// TBD
28-
} else if (opts.bodyPath) {
29-
// TBD
29+
if (opts?.databaseIdParam) {
30+
databaseId = req.params?.[opts.databaseIdParam];
3031
}
3132

32-
// todo: add validation
33-
if (!databaseId) {
34-
// todo: define proper error
35-
throw new Error('No databaseId found');
33+
let uniqueId;
34+
if (opts?.uniqueIdParam) {
35+
uniqueId = req.params?.[opts.uniqueIdParam];
3636
}
3737

38-
return plainToClass(ClientMetadata, {
38+
const clientMetadata = plainToClass(ClientMetadata, {
3939
session: sessionFromRequestFactory(undefined, ctx),
4040
databaseId,
41-
context: opts.context,
42-
uniqueId: opts.uniqueId,
41+
uniqueId,
42+
context: opts?.context || ClientContext.Common,
4343
});
44-
};
45-
46-
export const ClientMetadataFromRequest = createParamDecorator(clientMetadataFromRequestFactory);
4744

48-
export const browserClientMetadataFactory = (
49-
param = API_PARAM_DATABASE_ID,
50-
ctx: ExecutionContext,
51-
): ClientMetadata => clientMetadataFromRequestFactory({
52-
paramPath: param,
53-
context: ClientContext.Browser,
54-
}, ctx);
55-
56-
export const BrowserClientMetadata = createParamDecorator(browserClientMetadataFactory);
45+
const errors = validator.validateSync(clientMetadata, {
46+
whitelist: false, // we need this to allow additional fields if needed for flexibility
47+
});
5748

58-
export const cliClientMetadataFactory = (
59-
options = { databaseParam: API_PARAM_DATABASE_ID, uuidParam: API_PARAM_CLI_CLIENT_ID },
60-
ctx: ExecutionContext,
61-
): ClientMetadata => {
62-
const request = ctx.switchToHttp().getRequest();
49+
if (errors?.length) {
50+
throw new BadRequestException(Object.values(errors[0].constraints) || 'Bad request');
51+
}
6352

64-
// todo: add validation
65-
return clientMetadataFromRequestFactory({
66-
paramPath: options.databaseParam,
67-
context: ClientContext.CLI,
68-
uniqueId: request.params?.[options.uuidParam],
69-
}, ctx);
53+
return clientMetadata;
7054
};
7155

72-
export const CliClientMetadata = createParamDecorator(cliClientMetadataFactory);
56+
export const ClientMetadataParam = createParamDecorator(clientMetadataParamFactory);
Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
1-
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
1+
import { BadRequestException, createParamDecorator, ExecutionContext } from '@nestjs/common';
2+
import { Validator } from 'class-validator';
23
import { plainToClass } from 'class-transformer';
34
import { Session } from 'src/common/models';
45

6+
const validator = new Validator();
7+
58
export const sessionFromRequestFactory = (data: unknown, ctx: ExecutionContext): Session => {
69
const request = ctx.switchToHttp().getRequest();
710

8-
return plainToClass(Session, request.session);
11+
const session = plainToClass(Session, request.session);
12+
13+
const errors = validator.validateSync(session, {
14+
whitelist: false, // we need this to allow additional fields if needed for flexibility
15+
});
16+
17+
if (errors?.length) {
18+
throw new BadRequestException(Object.values(errors[0].constraints) || 'Bad request');
19+
}
20+
21+
return session;
922
};
1023

1124
export const SessionFromRequest = createParamDecorator(sessionFromRequestFactory);

redisinsight/api/src/common/models/client-metadata.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
import { Session } from 'src/common/models/session';
2+
import { Type } from 'class-transformer';
3+
import {
4+
IsEnum, IsNotEmpty, IsOptional, IsString,
5+
} from 'class-validator';
26

37
export enum ClientContext {
48
Common = 'Common',
@@ -8,11 +12,19 @@ export enum ClientContext {
812
}
913

1014
export class ClientMetadata {
15+
@IsNotEmpty()
16+
@Type(() => Session)
1117
session: Session;
1218

19+
@IsNotEmpty()
20+
@IsString()
1321
databaseId: string;
1422

23+
@IsNotEmpty()
24+
@IsEnum(ClientContext)
1525
context: ClientContext;
1626

27+
@IsOptional()
28+
@IsString()
1729
uniqueId?: string;
1830
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1+
import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
2+
13
export interface ISession {
24
userId: string;
35
sessionId: string;
46
uniqueId?: string;
57
}
68

79
export class Session implements ISession {
10+
@IsNotEmpty()
11+
@IsString()
812
userId: string;
913

14+
@IsNotEmpty()
15+
@IsString()
1016
sessionId: string;
1117

18+
@IsOptional()
19+
@IsString()
1220
uniqueId?: string;
1321
}

redisinsight/api/src/modules/browser/controllers/hash/hash.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
} from '@nestjs/swagger';
1212
import { ApiRedisParams } from 'src/decorators/api-redis-params.decorator';
1313
import { BaseController } from 'src/modules/browser/controllers/base.controller';
14-
import { ApiQueryRedisStringEncoding, BrowserClientMetadata } from 'src/common/decorators';
14+
import { BrowserClientMetadata } from 'src/modules/browser/decorators/browser-client-metadata.decorator';
15+
import { ApiQueryRedisStringEncoding } from 'src/common/decorators';
1516
import { ClientMetadata } from 'src/common/models';
1617
import {
1718
AddFieldsToHashDto,

redisinsight/api/src/modules/browser/controllers/keys/keys.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ import { KeysBusinessService } from 'src/modules/browser/services/keys-business/
1313
import { ApiRedisParams } from 'src/decorators/api-redis-params.decorator';
1414
import { RedisService } from 'src/modules/redis/redis.service';
1515
import { BaseController } from 'src/modules/browser/controllers/base.controller';
16-
import { ApiQueryRedisStringEncoding, BrowserClientMetadata } from 'src/common/decorators';
16+
import { BrowserClientMetadata } from 'src/modules/browser/decorators/browser-client-metadata.decorator';
17+
import { ApiQueryRedisStringEncoding } from 'src/common/decorators';
1718
import { ClientMetadata } from 'src/common/models';
1819
import {
1920
DeleteKeysDto,

redisinsight/api/src/modules/browser/controllers/list/list.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ import {
3030
DeleteListElementsResponse,
3131
PushListElementsResponse,
3232
} from 'src/modules/browser/dto';
33-
import { ApiQueryRedisStringEncoding, BrowserClientMetadata } from 'src/common/decorators';
33+
import { BrowserClientMetadata } from 'src/modules/browser/decorators/browser-client-metadata.decorator';
34+
import { ApiQueryRedisStringEncoding } from 'src/common/decorators';
3435
import { BaseController } from 'src/modules/browser/controllers/base.controller';
3536
import { ClientMetadata } from 'src/common/models';
3637
import { ListBusinessService } from '../../services/list-business/list-business.service';

redisinsight/api/src/modules/browser/controllers/redisearch/redisearch.controller.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import {
1111
ApiTags,
1212
} from '@nestjs/swagger';
1313
import { ApiRedisParams } from 'src/decorators/api-redis-params.decorator';
14-
import { ApiQueryRedisStringEncoding, BrowserClientMetadata } from 'src/common/decorators';
14+
import { BrowserClientMetadata } from 'src/modules/browser/decorators/browser-client-metadata.decorator';
15+
import { ApiQueryRedisStringEncoding } from 'src/common/decorators';
1516
import { BaseController } from 'src/modules/browser/controllers/base.controller';
1617
import {
1718
CreateRedisearchIndexDto,

redisinsight/api/src/modules/browser/controllers/rejson-rl/rejson-rl.controller.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import {
1919
} from 'src/modules/browser/dto';
2020
import { RejsonRlBusinessService } from 'src/modules/browser/services/rejson-rl-business/rejson-rl-business.service';
2121
import { ApiRedisInstanceOperation } from 'src/decorators/api-redis-instance-operation.decorator';
22-
import { BrowserClientMetadata } from 'src/common/decorators';
22+
import { BrowserClientMetadata } from 'src/modules/browser/decorators/browser-client-metadata.decorator';
2323
import { ClientMetadata } from 'src/common/models';
2424

2525
@ApiTags('REJSON-RL')

0 commit comments

Comments
 (0)