Merge pull request 'feat: implement project settings management with CRUD operations and caching' (#11) from projectSettings into develop
All checks were successful
Deploy to Testing Server / Deploy to Testing Environment (push) Successful in 32s
All checks were successful
Deploy to Testing Server / Deploy to Testing Environment (push) Successful in 32s
Reviewed-on: http://192.168.0.16:3000/lborv/few-line-engine/pulls/11 Reviewed-by: jana <comite11@inbox.lv>
This commit is contained in:
21
src/migrations/1760377023483-projectSettings.ts
Normal file
21
src/migrations/1760377023483-projectSettings.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class ProjectSettings1760377023483 implements MigrationInterface {
|
||||||
|
name = "ProjectSettings1760377023483";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE TABLE \`projectSetting\` (\`id\` varchar(36) NOT NULL, \`key\` varchar(255) NOT NULL, \`value\` text NOT NULL, \`projectId\` varchar(36) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB`
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`projectSetting\` ADD CONSTRAINT \`FK_8dfaf9c1ebbadb7af024e72e871\` FOREIGN KEY (\`projectId\`) REFERENCES \`project\`(\`id\`) ON DELETE CASCADE ON UPDATE NO ACTION`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`projectSetting\` DROP FOREIGN KEY \`FK_8dfaf9c1ebbadb7af024e72e871\``
|
||||||
|
);
|
||||||
|
await queryRunner.query(`DROP TABLE \`projectSetting\``);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -14,6 +14,7 @@ import { Database } from "../../databaseManager/entities/database.entity";
|
|||||||
import { FunctionEntity } from "../../query/entities/function.entity";
|
import { FunctionEntity } from "../../query/entities/function.entity";
|
||||||
import { RedisNode } from "../../redisManager/entities/redis.node.entity";
|
import { RedisNode } from "../../redisManager/entities/redis.node.entity";
|
||||||
import { Log } from "../../query/logger/entities/log.entity";
|
import { Log } from "../../query/logger/entities/log.entity";
|
||||||
|
import { ProjectSetting } from "../settings/entities/project.setting.entity";
|
||||||
|
|
||||||
@Entity("project")
|
@Entity("project")
|
||||||
export class Project {
|
export class Project {
|
||||||
@ -39,6 +40,9 @@ export class Project {
|
|||||||
@OneToMany(() => FunctionEntity, (functionEntity) => functionEntity.project)
|
@OneToMany(() => FunctionEntity, (functionEntity) => functionEntity.project)
|
||||||
functions: FunctionEntity[];
|
functions: FunctionEntity[];
|
||||||
|
|
||||||
|
@OneToMany(() => ProjectSetting, (setting) => setting.project)
|
||||||
|
settings: ProjectSetting[];
|
||||||
|
|
||||||
@ManyToMany(() => RedisNode, (redisNode) => redisNode.projects)
|
@ManyToMany(() => RedisNode, (redisNode) => redisNode.projects)
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
redisNodes: RedisNode[];
|
redisNodes: RedisNode[];
|
||||||
|
|||||||
@ -1,14 +1,26 @@
|
|||||||
import { Body, Controller, Inject, Put, UseGuards } from "@nestjs/common";
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Inject,
|
||||||
|
Put,
|
||||||
|
Req,
|
||||||
|
UseGuards,
|
||||||
|
} from "@nestjs/common";
|
||||||
import { ProjectService } from "./project.service";
|
import { ProjectService } from "./project.service";
|
||||||
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||||
import { AdminGuard } from "src/api/guards/admin.guard";
|
import { AdminGuard } from "src/api/guards/admin.guard";
|
||||||
|
import { ProjectSettingService } from "./settings/project.setting.service";
|
||||||
|
|
||||||
@Controller("project")
|
@Controller("project")
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
export class ProjectController {
|
export class ProjectController {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(ProjectService)
|
@Inject(ProjectService)
|
||||||
private readonly projectService: ProjectService
|
private readonly projectService: ProjectService,
|
||||||
|
@Inject(ProjectSettingService)
|
||||||
|
private readonly projectSettingService: ProjectSettingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Put("create")
|
@Put("create")
|
||||||
@ -21,4 +33,29 @@ export class ProjectController {
|
|||||||
createProjectWithoutDB(@Body() body: { name: string }) {
|
createProjectWithoutDB(@Body() body: { name: string }) {
|
||||||
return this.projectService.create(body.name, false);
|
return this.projectService.create(body.name, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Put("settings/create")
|
||||||
|
createSetting(
|
||||||
|
@Body() body: { key: string; value: string },
|
||||||
|
@Req() req: Request & { apiToken: { id: string } }
|
||||||
|
) {
|
||||||
|
return this.projectSettingService.create(
|
||||||
|
req.apiToken.id,
|
||||||
|
body.key,
|
||||||
|
body.value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("settings/delete")
|
||||||
|
deleteSetting(
|
||||||
|
@Body() body: { key: string },
|
||||||
|
@Req() req: Request & { apiToken: { id: string } }
|
||||||
|
) {
|
||||||
|
return this.projectSettingService.delete(req.apiToken.id, body.key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get("settings")
|
||||||
|
getAllSettings(@Req() req: Request & { apiToken: { id: string } }) {
|
||||||
|
return this.projectSettingService.getAll(req.apiToken.id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,16 +6,18 @@ import { ProjectController } from "./project.controller";
|
|||||||
import { ApiModule } from "src/api/api.module";
|
import { ApiModule } from "src/api/api.module";
|
||||||
import { RedisModule } from "src/redis/redis.module";
|
import { RedisModule } from "src/redis/redis.module";
|
||||||
import { DatabaseManagerModule } from "src/databaseManager/database.manager.module";
|
import { DatabaseManagerModule } from "src/databaseManager/database.manager.module";
|
||||||
|
import { ProjectSetting } from "./settings/entities/project.setting.entity";
|
||||||
|
import { ProjectSettingService } from "./settings/project.setting.service";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
forwardRef(() => ApiModule),
|
forwardRef(() => ApiModule),
|
||||||
forwardRef(() => RedisModule),
|
forwardRef(() => RedisModule),
|
||||||
forwardRef(() => DatabaseManagerModule),
|
forwardRef(() => DatabaseManagerModule),
|
||||||
TypeOrmModule.forFeature([Project]),
|
TypeOrmModule.forFeature([Project, ProjectSetting]),
|
||||||
],
|
],
|
||||||
controllers: [ProjectController],
|
controllers: [ProjectController],
|
||||||
providers: [ProjectService],
|
providers: [ProjectService, ProjectSettingService],
|
||||||
exports: [ProjectService],
|
exports: [ProjectService, ProjectSettingService],
|
||||||
})
|
})
|
||||||
export class ProjectModule {}
|
export class ProjectModule {}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import { Repository } from "typeorm";
|
|||||||
import { Project } from "./entities/project.entity";
|
import { Project } from "./entities/project.entity";
|
||||||
import { RedisClient } from "src/redis/redis.service";
|
import { RedisClient } from "src/redis/redis.service";
|
||||||
import { DatabaseManagerService } from "src/databaseManager/database/database.manager.service";
|
import { DatabaseManagerService } from "src/databaseManager/database/database.manager.service";
|
||||||
|
import { ProjectSettingService } from "./settings/project.setting.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService {
|
export class ProjectService {
|
||||||
@ -13,9 +14,23 @@ export class ProjectService {
|
|||||||
@Inject(RedisClient)
|
@Inject(RedisClient)
|
||||||
private readonly redisClient: RedisClient,
|
private readonly redisClient: RedisClient,
|
||||||
@Inject(forwardRef(() => DatabaseManagerService))
|
@Inject(forwardRef(() => DatabaseManagerService))
|
||||||
private readonly databaseManagerService: DatabaseManagerService
|
private readonly databaseManagerService: DatabaseManagerService,
|
||||||
|
@Inject(ProjectSettingService)
|
||||||
|
private readonly projectSettingService: ProjectSettingService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
|
async createDefaultSettings(projectId: string) {
|
||||||
|
const defaultSettings = [{ key: "sessionTTL", value: "3600" }];
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
defaultSettings.map((setting) =>
|
||||||
|
this.projectSettingService.create(projectId, setting.key, setting.value)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
async create(name: string, createDatabase: boolean = true) {
|
async create(name: string, createDatabase: boolean = true) {
|
||||||
const project = this.projectRepository.create({ name });
|
const project = this.projectRepository.create({ name });
|
||||||
const projectSaved = await this.projectRepository.save(project);
|
const projectSaved = await this.projectRepository.save(project);
|
||||||
@ -24,6 +39,9 @@ export class ProjectService {
|
|||||||
await this.databaseManagerService.createDatabase(projectSaved.id);
|
await this.databaseManagerService.createDatabase(projectSaved.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.createDefaultSettings(projectSaved.id);
|
||||||
|
await this.redisClient.set(`project_${projectSaved.id}`, projectSaved, 300);
|
||||||
|
|
||||||
return projectSaved;
|
return projectSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
19
src/project/settings/entities/project.setting.entity.ts
Normal file
19
src/project/settings/entities/project.setting.entity.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||||
|
import { Project } from "../../entities/project.entity";
|
||||||
|
|
||||||
|
@Entity("projectSetting")
|
||||||
|
export class ProjectSetting {
|
||||||
|
@PrimaryGeneratedColumn("uuid")
|
||||||
|
id: string;
|
||||||
|
|
||||||
|
@ManyToOne(() => Project, (project) => project.settings, {
|
||||||
|
onDelete: "CASCADE",
|
||||||
|
})
|
||||||
|
project: Project;
|
||||||
|
|
||||||
|
@Column({ type: "varchar", length: 255, nullable: false })
|
||||||
|
key: string;
|
||||||
|
|
||||||
|
@Column({ type: "text", nullable: false })
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
112
src/project/settings/project.setting.service.ts
Normal file
112
src/project/settings/project.setting.service.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { Inject, Injectable } from "@nestjs/common";
|
||||||
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
|
import { Repository } from "typeorm";
|
||||||
|
import { ProjectSetting } from "./entities/project.setting.entity";
|
||||||
|
import { RedisClient } from "src/redis/redis.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class ProjectSettingService {
|
||||||
|
constructor(
|
||||||
|
@InjectRepository(ProjectSetting)
|
||||||
|
private readonly projectSettingRepository: Repository<ProjectSetting>,
|
||||||
|
@Inject(RedisClient)
|
||||||
|
private readonly redisClient: RedisClient
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async updateCache(projectId: string) {
|
||||||
|
const settings = await this.projectSettingRepository.find({
|
||||||
|
where: { project: { id: projectId } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const settingsObject = settings.reduce((obj, setting) => {
|
||||||
|
obj[setting.key] = setting.value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
await this.redisClient.set(
|
||||||
|
`project_settings_${projectId}`,
|
||||||
|
settingsObject,
|
||||||
|
300
|
||||||
|
);
|
||||||
|
|
||||||
|
return settingsObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key: string, projectId: string) {
|
||||||
|
const cached = await this.redisClient.get(`project_settings_${projectId}`);
|
||||||
|
|
||||||
|
if (cached && key in cached) {
|
||||||
|
return cached[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const setting = await this.projectSettingRepository.findOne({
|
||||||
|
where: { project: { id: projectId }, key },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (setting) {
|
||||||
|
return setting.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getAll(projectId: string) {
|
||||||
|
const cached = await this.redisClient.get(`project_settings_${projectId}`);
|
||||||
|
|
||||||
|
if (cached) {
|
||||||
|
return cached;
|
||||||
|
}
|
||||||
|
|
||||||
|
const settings = await this.projectSettingRepository.find({
|
||||||
|
where: { project: { id: projectId } },
|
||||||
|
});
|
||||||
|
|
||||||
|
const settingsObject = settings.reduce((obj, setting) => {
|
||||||
|
obj[setting.key] = setting.value;
|
||||||
|
return obj;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
await this.redisClient.set(
|
||||||
|
`project_settings_${projectId}`,
|
||||||
|
settingsObject,
|
||||||
|
300
|
||||||
|
);
|
||||||
|
|
||||||
|
return settingsObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(projectId: string, key: string, value: string) {
|
||||||
|
const existingSetting = await this.projectSettingRepository.findOne({
|
||||||
|
where: { project: { id: projectId }, key },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingSetting) {
|
||||||
|
existingSetting.value = value;
|
||||||
|
await this.projectSettingRepository.save(existingSetting);
|
||||||
|
|
||||||
|
return await this.updateCache(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
const newSetting = this.projectSettingRepository.create({
|
||||||
|
key,
|
||||||
|
value,
|
||||||
|
project: { id: projectId },
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.projectSettingRepository.save(newSetting);
|
||||||
|
|
||||||
|
return await this.updateCache(projectId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(projectId: string, key: string) {
|
||||||
|
const setting = await this.projectSettingRepository.findOne({
|
||||||
|
where: { project: { id: projectId }, key },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (setting) {
|
||||||
|
await this.projectSettingRepository.remove(setting);
|
||||||
|
}
|
||||||
|
|
||||||
|
return await this.updateCache(projectId);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -18,6 +18,7 @@ import { LoggerService } from "../logger/logger.service";
|
|||||||
import { TLogType } from "../logger/logger.types";
|
import { TLogType } from "../logger/logger.types";
|
||||||
import { QueryResponse } from "src/vm/vm.constants";
|
import { QueryResponse } from "src/vm/vm.constants";
|
||||||
import { Query } from "../entities/query.entity";
|
import { Query } from "../entities/query.entity";
|
||||||
|
import { Token } from "src/api/entities/token.entity";
|
||||||
|
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
export abstract class BaseQueryController {
|
export abstract class BaseQueryController {
|
||||||
@ -34,9 +35,16 @@ export abstract class BaseQueryController {
|
|||||||
|
|
||||||
@Post("create")
|
@Post("create")
|
||||||
async createQuery(
|
async createQuery(
|
||||||
@Body() queryData: { projectToken: string; source: string }
|
@Req() req: Request & { apiToken: Token },
|
||||||
|
@Body() queryData: { source: string }
|
||||||
) {
|
) {
|
||||||
return this.queryHandlerService.createQuery(queryData, this.getIsCommand());
|
return this.queryHandlerService.createQuery(
|
||||||
|
{
|
||||||
|
...queryData,
|
||||||
|
projectToken: req?.apiToken.project.id,
|
||||||
|
},
|
||||||
|
this.getIsCommand()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("update/:id")
|
@Post("update/:id")
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import { FunctionService } from "src/query/function/function.service";
|
|||||||
import { SessionService } from "../session/session.service";
|
import { SessionService } from "../session/session.service";
|
||||||
import { TLog, TLogType } from "../logger/logger.types";
|
import { TLog, TLogType } from "../logger/logger.types";
|
||||||
import { LoggerService } from "../logger/logger.service";
|
import { LoggerService } from "../logger/logger.service";
|
||||||
|
import { ProjectSettingService } from "src/project/settings/project.setting.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueryExecuterService {
|
export class QueryExecuterService {
|
||||||
@ -31,6 +32,7 @@ export class QueryExecuterService {
|
|||||||
readonly databaseManagerService: DatabaseManagerService,
|
readonly databaseManagerService: DatabaseManagerService,
|
||||||
readonly redisNodeService: RedisNodeService,
|
readonly redisNodeService: RedisNodeService,
|
||||||
readonly sessionService: SessionService,
|
readonly sessionService: SessionService,
|
||||||
|
readonly projectSettingService: ProjectSettingService,
|
||||||
@InjectQueue(QUEUE_NAMES.QUERY) private queryQueue: Queue
|
@InjectQueue(QUEUE_NAMES.QUERY) private queryQueue: Queue
|
||||||
) {
|
) {
|
||||||
this.queueEvents = new QueueEvents(this.queryQueue.name);
|
this.queueEvents = new QueueEvents(this.queryQueue.name);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { Controller, Inject, Post, UseGuards } from "@nestjs/common";
|
import { Controller, Inject, Post, Req, UseGuards } from "@nestjs/common";
|
||||||
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||||
import { FunctionService } from "./function.service";
|
import { FunctionService } from "./function.service";
|
||||||
|
import { Token } from "src/api/entities/token.entity";
|
||||||
|
|
||||||
@Controller("functions")
|
@Controller("functions")
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
@ -11,12 +12,19 @@ export class FunctionController {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Post("create")
|
@Post("create")
|
||||||
async createFunction(projectId: string, name: string, source: string) {
|
async createFunction(
|
||||||
return this.functionService.create(projectId, name, source);
|
@Req() req: Request & { apiToken: Token },
|
||||||
|
name: string,
|
||||||
|
source: string
|
||||||
|
) {
|
||||||
|
return this.functionService.create(req.apiToken.project.id, name, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("delete")
|
@Post("delete")
|
||||||
async deleteFunction(projectId: string, name: string) {
|
async deleteFunction(
|
||||||
return this.functionService.deleteFunction(projectId, name);
|
@Req() req: Request & { apiToken: Token },
|
||||||
|
name: string
|
||||||
|
) {
|
||||||
|
return this.functionService.deleteFunction(req.apiToken.project.id, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,8 @@ import { SessionService } from "./session/session.service";
|
|||||||
import { Log } from "./logger/entities/log.entity";
|
import { Log } from "./logger/entities/log.entity";
|
||||||
import { LoggerService } from "./logger/logger.service";
|
import { LoggerService } from "./logger/logger.service";
|
||||||
import { LoggerController } from "./logger/logger.controller";
|
import { LoggerController } from "./logger/logger.controller";
|
||||||
|
import { ProjectSettingService } from "src/project/settings/project.setting.service";
|
||||||
|
import { ProjectSetting } from "src/project/settings/entities/project.setting.entity";
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
@ -27,7 +29,7 @@ import { LoggerController } from "./logger/logger.controller";
|
|||||||
forwardRef(() => QueueModule),
|
forwardRef(() => QueueModule),
|
||||||
forwardRef(() => RedisModule),
|
forwardRef(() => RedisModule),
|
||||||
forwardRef(() => RedisManagerModule),
|
forwardRef(() => RedisManagerModule),
|
||||||
TypeOrmModule.forFeature([Query, FunctionEntity, Log]),
|
TypeOrmModule.forFeature([Query, FunctionEntity, Log, ProjectSetting]),
|
||||||
],
|
],
|
||||||
controllers: [
|
controllers: [
|
||||||
QueryController,
|
QueryController,
|
||||||
@ -41,12 +43,14 @@ import { LoggerController } from "./logger/logger.controller";
|
|||||||
LoggerService,
|
LoggerService,
|
||||||
QueryHandlerService,
|
QueryHandlerService,
|
||||||
FunctionService,
|
FunctionService,
|
||||||
|
ProjectSettingService,
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
QueryExecuterService,
|
QueryExecuterService,
|
||||||
TypeOrmModule,
|
TypeOrmModule,
|
||||||
QueryHandlerService,
|
QueryHandlerService,
|
||||||
LoggerService,
|
LoggerService,
|
||||||
|
ProjectSettingService,
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class QueryModule {}
|
export class QueryModule {}
|
||||||
|
|||||||
@ -1,9 +1,15 @@
|
|||||||
import { Inject, Injectable } from "@nestjs/common";
|
import { Inject, Injectable } from "@nestjs/common";
|
||||||
|
import { ProjectSettingService } from "src/project/settings/project.setting.service";
|
||||||
import { RedisClient } from "src/redis/redis.service";
|
import { RedisClient } from "src/redis/redis.service";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SessionService {
|
export class SessionService {
|
||||||
constructor(@Inject(RedisClient) private readonly redisClient: RedisClient) {}
|
constructor(
|
||||||
|
@Inject(RedisClient)
|
||||||
|
private readonly redisClient: RedisClient,
|
||||||
|
@Inject(ProjectSettingService)
|
||||||
|
private readonly projectSettingService: ProjectSettingService
|
||||||
|
) {}
|
||||||
|
|
||||||
private generateSessionId(length: number = 16): string {
|
private generateSessionId(length: number = 16): string {
|
||||||
const characters =
|
const characters =
|
||||||
@ -16,6 +22,11 @@ export class SessionService {
|
|||||||
return `${result}_${new Date().getTime()}`;
|
return `${result}_${new Date().getTime()}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getSessionTTL(projectId: string): Promise<number> {
|
||||||
|
const ttl = await this.projectSettingService.get("sessionTTL", projectId);
|
||||||
|
return ttl ? parseInt(ttl) : 3600;
|
||||||
|
}
|
||||||
|
|
||||||
async create(prefix: string): Promise<{ sessionId: string }> {
|
async create(prefix: string): Promise<{ sessionId: string }> {
|
||||||
const sessionId = this.generateSessionId();
|
const sessionId = this.generateSessionId();
|
||||||
await this.set(sessionId, prefix, {
|
await this.set(sessionId, prefix, {
|
||||||
@ -33,7 +44,11 @@ export class SessionService {
|
|||||||
const data = await this.redisClient.get(`${prefix}:${sessionId}`);
|
const data = await this.redisClient.get(`${prefix}:${sessionId}`);
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
await this.redisClient.set(`${prefix}:${sessionId}`, data, 3600);
|
await this.redisClient.set(
|
||||||
|
`${prefix}:${sessionId}`,
|
||||||
|
data,
|
||||||
|
await this.getSessionTTL(prefix)
|
||||||
|
);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +56,11 @@ export class SessionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async set(sessionId: string, prefix: string, data: any): Promise<void> {
|
async set(sessionId: string, prefix: string, data: any): Promise<void> {
|
||||||
await this.redisClient.set(`${prefix}:${sessionId}`, data, 3600);
|
await this.redisClient.set(
|
||||||
|
`${prefix}:${sessionId}`,
|
||||||
|
data,
|
||||||
|
await this.getSessionTTL(prefix)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async delete(sessionId: string, prefix: string): Promise<void> {
|
async delete(sessionId: string, prefix: string): Promise<void> {
|
||||||
|
|||||||
29
src/vm/plugins/settings.plugin.ts
Normal file
29
src/vm/plugins/settings.plugin.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { Query } from "src/query/entities/query.entity";
|
||||||
|
import { Plugin } from "../plugin.class";
|
||||||
|
import { QueryExecuterService } from "src/query/executer/query.executer.service";
|
||||||
|
|
||||||
|
export class SettingsPlugin extends Plugin {
|
||||||
|
constructor(
|
||||||
|
name: string,
|
||||||
|
private query: Query,
|
||||||
|
private queryExecuterService: QueryExecuterService
|
||||||
|
) {
|
||||||
|
super(name, ["get"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static async init(query: Query, queryExecuterService: QueryExecuterService) {
|
||||||
|
return new SettingsPlugin("settings", query, queryExecuterService);
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(property: string): Promise<any> {
|
||||||
|
const settings =
|
||||||
|
await this.queryExecuterService.projectSettingService.getAll(
|
||||||
|
this.query.project.id
|
||||||
|
);
|
||||||
|
return settings[property];
|
||||||
|
}
|
||||||
|
|
||||||
|
onFinish() {
|
||||||
|
// No resources to clean up
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,6 +6,7 @@ import { AxiosPlugin } from "./plugins/axios.plugin";
|
|||||||
import { RedisPlugin } from "./plugins/redis.plugin";
|
import { RedisPlugin } from "./plugins/redis.plugin";
|
||||||
import { SessionPlugin } from "./plugins/session.plugin";
|
import { SessionPlugin } from "./plugins/session.plugin";
|
||||||
import { TLog } from "src/query/logger/logger.types";
|
import { TLog } from "src/query/logger/logger.types";
|
||||||
|
import { SettingsPlugin } from "./plugins/settings.plugin";
|
||||||
|
|
||||||
export const registeredPlugins = {
|
export const registeredPlugins = {
|
||||||
db: async (service: QueryExecuterService, query: Query) => {
|
db: async (service: QueryExecuterService, query: Query) => {
|
||||||
@ -32,6 +33,9 @@ export const registeredPlugins = {
|
|||||||
|
|
||||||
return RedisPlugin.init("redis", redisConnection, query.project.id);
|
return RedisPlugin.init("redis", redisConnection, query.project.id);
|
||||||
},
|
},
|
||||||
|
settings: async (service: QueryExecuterService, query: Query) => {
|
||||||
|
return SettingsPlugin.init(query, service);
|
||||||
|
},
|
||||||
session: async (
|
session: async (
|
||||||
service: QueryExecuterService,
|
service: QueryExecuterService,
|
||||||
query: Query,
|
query: Query,
|
||||||
|
|||||||
Reference in New Issue
Block a user