Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b77f7e42c | |||
| 9e79b44bdb | |||
| 7fad278d31 | |||
| 776d8a8187 | |||
| e4b29a918f | |||
| 4acd59b482 | |||
| 84c48dd482 | |||
| bbc378dc95 | |||
| 5d596832d6 | |||
| 3a1249615e | |||
| 0ac6b7db6f | |||
| 9080f193c1 | |||
| 1a2d7b20c0 | |||
| e1fce6d11d | |||
| 1d5160e60e | |||
| 038f2f8605 | |||
| 91ad421b8d | |||
| ee5ad66759 | |||
| f7b775f87b | |||
| 6992041429 |
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "lib/sdk"]
|
||||||
|
path = lib/sdk
|
||||||
|
url = http://192.168.0.16:3000/lborv/few-line-sdk.git
|
||||||
1
lib/sdk
Submodule
1
lib/sdk
Submodule
Submodule lib/sdk added at 4b8c6753ef
@ -3,6 +3,7 @@ import {
|
|||||||
Controller,
|
Controller,
|
||||||
Delete,
|
Delete,
|
||||||
Inject,
|
Inject,
|
||||||
|
Param,
|
||||||
Post,
|
Post,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
@ -28,8 +29,8 @@ export class ApiController {
|
|||||||
return this.apiService.generateToken(body.id);
|
return this.apiService.generateToken(body.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete("token/revoke")
|
@Delete("token/revoke/:token")
|
||||||
revokeToken(@Body() body: { token: string }) {
|
revokeToken(@Param("token") token: string) {
|
||||||
return this.apiService.revokeToken(body.token);
|
return this.apiService.revokeToken(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/migrations/1760548310371-projectmeta.ts
Normal file
15
src/migrations/1760548310371-projectmeta.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class Projectmeta1760548310371 implements MigrationInterface {
|
||||||
|
name = "Projectmeta1760548310371";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`project\` ADD \`meta\` longtext NULL`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`ALTER TABLE \`project\` DROP COLUMN \`meta\``);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/project/constants.ts
Normal file
11
src/project/constants.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
type item = {
|
||||||
|
id: string;
|
||||||
|
path: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TMeta = {
|
||||||
|
migrations: item[];
|
||||||
|
queries: item[];
|
||||||
|
functions: item[];
|
||||||
|
settings: item[];
|
||||||
|
};
|
||||||
@ -15,6 +15,7 @@ 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";
|
import { ProjectSetting } from "../settings/entities/project.setting.entity";
|
||||||
|
import { TMeta } from "../constants";
|
||||||
|
|
||||||
@Entity("project")
|
@Entity("project")
|
||||||
export class Project {
|
export class Project {
|
||||||
@ -43,6 +44,16 @@ export class Project {
|
|||||||
@OneToMany(() => ProjectSetting, (setting) => setting.project)
|
@OneToMany(() => ProjectSetting, (setting) => setting.project)
|
||||||
settings: ProjectSetting[];
|
settings: ProjectSetting[];
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: "longtext",
|
||||||
|
nullable: true,
|
||||||
|
transformer: {
|
||||||
|
to: (value: TMeta) => JSON.stringify(value),
|
||||||
|
from: (value: string) => JSON.parse(value) as TMeta,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
meta: TMeta;
|
||||||
|
|
||||||
@ManyToMany(() => RedisNode, (redisNode) => redisNode.projects)
|
@ManyToMany(() => RedisNode, (redisNode) => redisNode.projects)
|
||||||
@JoinTable()
|
@JoinTable()
|
||||||
redisNodes: RedisNode[];
|
redisNodes: RedisNode[];
|
||||||
|
|||||||
@ -4,6 +4,8 @@ import {
|
|||||||
Delete,
|
Delete,
|
||||||
Get,
|
Get,
|
||||||
Inject,
|
Inject,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
Put,
|
Put,
|
||||||
Req,
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
@ -11,7 +13,9 @@ import {
|
|||||||
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 { Request } from "express";
|
||||||
import { ProjectSettingService } from "./settings/project.setting.service";
|
import { ProjectSettingService } from "./settings/project.setting.service";
|
||||||
|
import { TMeta } from "./constants";
|
||||||
|
|
||||||
@Controller("project")
|
@Controller("project")
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
@ -24,10 +28,26 @@ export class ProjectController {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Put("create")
|
@Put("create")
|
||||||
|
@UseGuards(AdminGuard)
|
||||||
createProject(@Body() body: { name: string }) {
|
createProject(@Body() body: { name: string }) {
|
||||||
return this.projectService.create(body.name);
|
return this.projectService.create(body.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Get("details")
|
||||||
|
getProjectDetails(
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } }
|
||||||
|
) {
|
||||||
|
return this.projectService.getProjectDetails(req.apiToken.project.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post("update/meta")
|
||||||
|
updateProjectMeta(
|
||||||
|
@Body() body: { meta: TMeta },
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } }
|
||||||
|
) {
|
||||||
|
return this.projectService.updateMeta(req.apiToken.project.id, body.meta);
|
||||||
|
}
|
||||||
|
|
||||||
@Put("create-without-db")
|
@Put("create-without-db")
|
||||||
@UseGuards(AdminGuard)
|
@UseGuards(AdminGuard)
|
||||||
createProjectWithoutDB(@Body() body: { name: string }) {
|
createProjectWithoutDB(@Body() body: { name: string }) {
|
||||||
@ -46,12 +66,12 @@ export class ProjectController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Delete("settings/delete")
|
@Delete("settings/delete/:key")
|
||||||
deleteSetting(
|
deleteSetting(
|
||||||
@Body() body: { key: string },
|
@Param("key") key: string,
|
||||||
@Req() req: Request & { apiToken: { id: string } }
|
@Req() req: Request & { apiToken: { id: string } }
|
||||||
) {
|
) {
|
||||||
return this.projectSettingService.delete(req.apiToken.id, body.key);
|
return this.projectSettingService.delete(req.apiToken.id, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Get("settings")
|
@Get("settings")
|
||||||
@ -63,6 +83,5 @@ export class ProjectController {
|
|||||||
@UseGuards(AdminGuard)
|
@UseGuards(AdminGuard)
|
||||||
getAllApiTokens(@Req() req: Request & { apiToken: { id: string } }) {
|
getAllApiTokens(@Req() req: Request & { apiToken: { id: string } }) {
|
||||||
return this.projectService.getAllApiTokens(req.apiToken.id);
|
return this.projectService.getAllApiTokens(req.apiToken.id);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ 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";
|
import { ProjectSettingService } from "./settings/project.setting.service";
|
||||||
|
import { TMeta } from "./constants";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ProjectService {
|
export class ProjectService {
|
||||||
@ -45,6 +46,33 @@ export class ProjectService {
|
|||||||
return projectSaved;
|
return projectSaved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateMeta(projectId: string, meta: TMeta) {
|
||||||
|
return this.projectRepository.update({ id: projectId }, { meta });
|
||||||
|
}
|
||||||
|
|
||||||
|
async getProjectDetails(projectId: string) {
|
||||||
|
const project = await this.projectRepository.findOne({
|
||||||
|
where: { id: projectId },
|
||||||
|
relations: [
|
||||||
|
"database",
|
||||||
|
"database.migrations",
|
||||||
|
"queries",
|
||||||
|
"functions",
|
||||||
|
"settings",
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
migrations: project?.database?.migrations || [],
|
||||||
|
queries: project?.queries || [],
|
||||||
|
functions: project?.functions || [],
|
||||||
|
settings: project?.settings || [],
|
||||||
|
meta: project?.meta || null,
|
||||||
|
name: project?.name || "",
|
||||||
|
id: project?.id || "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async findById(id: string) {
|
async findById(id: string) {
|
||||||
const cached = await this.redisClient.get(`project_${id}`);
|
const cached = await this.redisClient.get(`project_${id}`);
|
||||||
|
|
||||||
@ -76,7 +104,7 @@ export class ProjectService {
|
|||||||
redisNodes: redisNodeId,
|
redisNodes: redisNodeId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAllApiTokens(projectId: string) {
|
async getAllApiTokens(projectId: string) {
|
||||||
const project = await this.projectRepository.findOne({
|
const project = await this.projectRepository.findOne({
|
||||||
where: { id: projectId },
|
where: { id: projectId },
|
||||||
@ -84,4 +112,13 @@ export class ProjectService {
|
|||||||
});
|
});
|
||||||
return project?.apiTokens || [];
|
return project?.apiTokens || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getProjectInfo(projectId: string) {
|
||||||
|
const project = await this.projectRepository.findOne({
|
||||||
|
where: { id: projectId },
|
||||||
|
relations: ["queries", "apiTokens", "functions", "settings"],
|
||||||
|
});
|
||||||
|
|
||||||
|
return project;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,8 @@ 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";
|
import { Token } from "src/api/entities/token.entity";
|
||||||
|
import { QueryPublicGuard } from "../guards/query-public";
|
||||||
|
|
||||||
@UseGuards(ApiTokenGuard)
|
|
||||||
export abstract class BaseQueryController {
|
export abstract class BaseQueryController {
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(QueryHandlerService)
|
@Inject(QueryHandlerService)
|
||||||
@ -34,9 +34,11 @@ export abstract class BaseQueryController {
|
|||||||
protected abstract getIsCommand(): boolean;
|
protected abstract getIsCommand(): boolean;
|
||||||
|
|
||||||
@Post("create")
|
@Post("create")
|
||||||
|
@UseGuards(ApiTokenGuard)
|
||||||
async createQuery(
|
async createQuery(
|
||||||
@Req() req: Request & { apiToken: Token },
|
@Req() req: Request & { apiToken: Token },
|
||||||
@Body() queryData: { source: string }
|
@Body()
|
||||||
|
queryData: { source: string; isTypescript?: number; isPublic?: number }
|
||||||
) {
|
) {
|
||||||
return this.queryHandlerService.createQuery(
|
return this.queryHandlerService.createQuery(
|
||||||
{
|
{
|
||||||
@ -48,23 +50,26 @@ export abstract class BaseQueryController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post("update/:id")
|
@Post("update/:id")
|
||||||
@UseGuards(QueryGuard)
|
@UseGuards(ApiTokenGuard, QueryGuard)
|
||||||
async updateQuery(
|
async updateQuery(
|
||||||
@Body() updateData: Partial<{ source: string }>,
|
@Body()
|
||||||
|
updateData: Partial<{
|
||||||
|
source: string;
|
||||||
|
isTypescript?: number;
|
||||||
|
isPublic?: number;
|
||||||
|
}>,
|
||||||
@Param("id") id: string
|
@Param("id") id: string
|
||||||
) {
|
) {
|
||||||
return this.queryHandlerService.updateQuery(id, updateData);
|
return this.queryHandlerService.updateQuery(id, updateData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/run/:id")
|
private async run(
|
||||||
@UseGuards(QueryGuard)
|
id: string,
|
||||||
async runQuery(
|
query: Record<string, any>,
|
||||||
@Param("id") id: string,
|
headers: Record<string, any>,
|
||||||
@Body() query: Record<string, any>,
|
res: Response,
|
||||||
@Headers() headers: Record<string, any>,
|
req: Request & { query: Query }
|
||||||
@Res() res: Response,
|
): Promise<QueryResponse> {
|
||||||
@Req() req: Request & { query: Query }
|
|
||||||
) {
|
|
||||||
let queryResult: QueryResponse;
|
let queryResult: QueryResponse;
|
||||||
const loggerTraceId =
|
const loggerTraceId =
|
||||||
headers["x-trace-id"] || LoggerService.generateTraceId();
|
headers["x-trace-id"] || LoggerService.generateTraceId();
|
||||||
@ -143,8 +148,32 @@ export abstract class BaseQueryController {
|
|||||||
res.send(queryResult?.response || null);
|
res.send(queryResult?.response || null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Post("/run-public/:id")
|
||||||
|
@UseGuards(QueryPublicGuard)
|
||||||
|
async runPublicQuery(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Body() query: Record<string, any>,
|
||||||
|
@Headers() headers: Record<string, any>,
|
||||||
|
@Res() res: Response,
|
||||||
|
@Req() req: Request & { query: Query }
|
||||||
|
) {
|
||||||
|
return this.run(id, query, headers, res, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post("/run/:id")
|
||||||
|
@UseGuards(ApiTokenGuard, QueryGuard)
|
||||||
|
async runQuery(
|
||||||
|
@Param("id") id: string,
|
||||||
|
@Body() query: Record<string, any>,
|
||||||
|
@Headers() headers: Record<string, any>,
|
||||||
|
@Res() res: Response,
|
||||||
|
@Req() req: Request & { query: Query }
|
||||||
|
) {
|
||||||
|
return this.run(id, query, headers, res, req);
|
||||||
|
}
|
||||||
|
|
||||||
@Delete("/delete/:id")
|
@Delete("/delete/:id")
|
||||||
@UseGuards(QueryGuard)
|
@UseGuards(ApiTokenGuard, QueryGuard)
|
||||||
async deleteQuery(@Param("id") id: string) {
|
async deleteQuery(@Param("id") id: string) {
|
||||||
return this.queryHandlerService.deleteQuery(id);
|
return this.queryHandlerService.deleteQuery(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,4 +27,10 @@ export class Query {
|
|||||||
|
|
||||||
@Column({ type: "tinyint", default: 0 })
|
@Column({ type: "tinyint", default: 0 })
|
||||||
isCommand: number;
|
isCommand: number;
|
||||||
|
|
||||||
|
@Column({ type: "tinyint", default: 0 })
|
||||||
|
isTypescript: number;
|
||||||
|
|
||||||
|
@Column({ type: "tinyint", default: 0 })
|
||||||
|
isPublic: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,6 +19,7 @@ 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";
|
import { ProjectSettingService } from "src/project/settings/project.setting.service";
|
||||||
|
import ts from "typescript";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class QueryExecuterService {
|
export class QueryExecuterService {
|
||||||
@ -89,6 +90,14 @@ export class QueryExecuterService {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private compileTypeScript(tsCode: string) {
|
||||||
|
const jsCode = ts.transpileModule(tsCode, {
|
||||||
|
compilerOptions: { module: ts.ModuleKind.CommonJS },
|
||||||
|
}).outputText;
|
||||||
|
|
||||||
|
return jsCode;
|
||||||
|
}
|
||||||
|
|
||||||
async runQuery(
|
async runQuery(
|
||||||
token: string,
|
token: string,
|
||||||
queryData: any,
|
queryData: any,
|
||||||
@ -122,17 +131,19 @@ export class QueryExecuterService {
|
|||||||
type: TLogType.info,
|
type: TLogType.info,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let script = this.clearImports(query.source);
|
||||||
|
|
||||||
|
if (query.isTypescript) {
|
||||||
|
script = this.compileTypeScript(script);
|
||||||
|
}
|
||||||
|
|
||||||
const vm = await this.createVm(
|
const vm = await this.createVm(
|
||||||
query,
|
query,
|
||||||
log,
|
log,
|
||||||
callStack,
|
callStack,
|
||||||
cookies["x-session-id"]
|
cookies["x-session-id"]
|
||||||
);
|
);
|
||||||
const result = await vm.runScript(
|
const result = await vm.runScript(script, queryData, headers);
|
||||||
this.clearImports(query.source),
|
|
||||||
queryData,
|
|
||||||
headers
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!this.checkResponse(result)) {
|
if (!this.checkResponse(result)) {
|
||||||
throw new Error(`Error initializing VM: ${JSON.stringify(result)}`);
|
throw new Error(`Error initializing VM: ${JSON.stringify(result)}`);
|
||||||
|
|||||||
@ -1,4 +1,12 @@
|
|||||||
import { Controller, Inject, Post, Req, UseGuards } from "@nestjs/common";
|
import {
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Inject,
|
||||||
|
Param,
|
||||||
|
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";
|
import { Token } from "src/api/entities/token.entity";
|
||||||
@ -20,10 +28,10 @@ export class FunctionController {
|
|||||||
return this.functionService.create(req.apiToken.project.id, name, source);
|
return this.functionService.create(req.apiToken.project.id, name, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("delete")
|
@Delete("delete/:name")
|
||||||
async deleteFunction(
|
async deleteFunction(
|
||||||
@Req() req: Request & { apiToken: Token },
|
@Req() req: Request & { apiToken: Token },
|
||||||
name: string
|
@Param("name") name: string
|
||||||
) {
|
) {
|
||||||
return this.functionService.deleteFunction(req.apiToken.project.id, name);
|
return this.functionService.deleteFunction(req.apiToken.project.id, name);
|
||||||
}
|
}
|
||||||
|
|||||||
44
src/query/guards/query-public.ts
Normal file
44
src/query/guards/query-public.ts
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
import {
|
||||||
|
CanActivate,
|
||||||
|
ExecutionContext,
|
||||||
|
Inject,
|
||||||
|
Injectable,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from "@nestjs/common";
|
||||||
|
import { QueryHandlerService } from "src/query/handler/query.handler.service";
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class QueryPublicGuard implements CanActivate {
|
||||||
|
constructor(
|
||||||
|
@Inject(QueryHandlerService)
|
||||||
|
private readonly queryHandlerService: QueryHandlerService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
|
||||||
|
const queryId = request.params?.id;
|
||||||
|
|
||||||
|
if (!queryId) {
|
||||||
|
throw new UnauthorizedException("Query ID is required");
|
||||||
|
}
|
||||||
|
|
||||||
|
const query = await this.queryHandlerService.getQueryById(queryId);
|
||||||
|
|
||||||
|
if (!query) {
|
||||||
|
throw new UnauthorizedException("Query not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query.isActive) {
|
||||||
|
throw new UnauthorizedException("Query is inactive");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (query.isPublic !== 1) {
|
||||||
|
throw new UnauthorizedException("Query is not public");
|
||||||
|
}
|
||||||
|
|
||||||
|
request.query = query;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -31,7 +31,6 @@ export class QueryHandlerService {
|
|||||||
delete queryData.projectToken;
|
delete queryData.projectToken;
|
||||||
|
|
||||||
const query = this.queryRepository.create(queryData);
|
const query = this.queryRepository.create(queryData);
|
||||||
|
|
||||||
await this.queryRepository.save(query);
|
await this.queryRepository.save(query);
|
||||||
|
|
||||||
return query;
|
return query;
|
||||||
@ -64,9 +63,9 @@ export class QueryHandlerService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this.redisClient.del(`query_${id}`);
|
await this.redisClient.del(`query_${id}`);
|
||||||
|
|
||||||
Object.assign(query, updateData);
|
Object.assign(query, updateData);
|
||||||
return this.queryRepository.save(query);
|
|
||||||
|
return await this.queryRepository.save(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteQuery(id: string) {
|
async deleteQuery(id: string) {
|
||||||
|
|||||||
@ -5,11 +5,14 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
|
Req,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { LoggerService } from "./logger.service";
|
import { LoggerService } from "./logger.service";
|
||||||
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||||
import { QueryGuard } from "../guards/query.guard";
|
import { QueryGuard } from "../guards/query.guard";
|
||||||
|
import { Token } from "src/api/entities/token.entity";
|
||||||
|
import { Query } from "../entities/query.entity";
|
||||||
|
|
||||||
@Controller("logger")
|
@Controller("logger")
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
@ -19,14 +22,17 @@ export class LoggerController {
|
|||||||
private readonly loggerService: LoggerService
|
private readonly loggerService: LoggerService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get("/:id/:traceId")
|
@Get("/:traceId")
|
||||||
getByTraceId(@Param("traceId") traceId: string) {
|
getByTraceId(
|
||||||
return this.loggerService.findByTraceId(traceId);
|
@Req() req: Request & { apiToken: Token },
|
||||||
|
@Param("traceId") traceId: string
|
||||||
|
) {
|
||||||
|
return this.loggerService.findByTraceId(req.apiToken.project.id, traceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/:id/findAll")
|
@Post("/findAll")
|
||||||
findAll(
|
findAll(
|
||||||
@Param("id") projectId: string,
|
@Req() req: Request & { apiToken: Token },
|
||||||
@Body()
|
@Body()
|
||||||
body: {
|
body: {
|
||||||
traceId?: string;
|
traceId?: string;
|
||||||
@ -37,13 +43,13 @@ export class LoggerController {
|
|||||||
offset: number;
|
offset: number;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
return this.loggerService.findByProjectId(projectId, body);
|
return this.loggerService.findByProjectId(req.apiToken.project.id, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/:id/find")
|
@Post("/find")
|
||||||
@UseGuards(QueryGuard)
|
@UseGuards(QueryGuard)
|
||||||
find(
|
find(
|
||||||
@Param("id") _id: string,
|
@Req() req: Request & { query: Query },
|
||||||
@Body()
|
@Body()
|
||||||
body: {
|
body: {
|
||||||
traceId?: string;
|
traceId?: string;
|
||||||
@ -54,6 +60,6 @@ export class LoggerController {
|
|||||||
offset: number;
|
offset: number;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
return this.loggerService.find(_id, body);
|
return this.loggerService.find(req.query.id, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,8 +22,15 @@ export class LoggerService {
|
|||||||
return await this.logRepository.save(log);
|
return await this.logRepository.save(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
async findByTraceId(traceId: string): Promise<Log[]> {
|
async findByTraceId(projectId: string, traceId: string): Promise<Log[]> {
|
||||||
return await this.logRepository.find({ where: { traceId } });
|
return await this.logRepository.find({
|
||||||
|
where: {
|
||||||
|
traceId,
|
||||||
|
project: {
|
||||||
|
id: projectId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private prepareQuery(data: {
|
private prepareQuery(data: {
|
||||||
|
|||||||
59
src/query/session/session.controller.ts
Normal file
59
src/query/session/session.controller.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Delete,
|
||||||
|
Get,
|
||||||
|
Inject,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
Put,
|
||||||
|
Req,
|
||||||
|
UseGuards,
|
||||||
|
} from "@nestjs/common";
|
||||||
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||||
|
import { SessionService } from "./session.service";
|
||||||
|
|
||||||
|
@Controller("session")
|
||||||
|
@UseGuards(ApiTokenGuard)
|
||||||
|
export class SessionController {
|
||||||
|
constructor(
|
||||||
|
@Inject(SessionService)
|
||||||
|
private readonly sessionService: SessionService
|
||||||
|
) {}
|
||||||
|
|
||||||
|
@Get("get/:sessionId")
|
||||||
|
getSession(
|
||||||
|
@Param("sessionId") sessionId: string,
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } }
|
||||||
|
) {
|
||||||
|
return this.sessionService.get(sessionId, req.apiToken.project.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Delete("delete/:sessionId")
|
||||||
|
deleteSession(
|
||||||
|
@Param("sessionId") sessionId: string,
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } }
|
||||||
|
) {
|
||||||
|
return this.sessionService.delete(sessionId, req.apiToken.project.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post("create")
|
||||||
|
createSession(
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } }
|
||||||
|
) {
|
||||||
|
return this.sessionService.create(req.apiToken.project.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Put("set/:sessionId")
|
||||||
|
setSession(
|
||||||
|
@Param("sessionId") sessionId: string,
|
||||||
|
@Req() req: Request & { apiToken: { project: { id: string } } },
|
||||||
|
@Body() body: { data: any }
|
||||||
|
) {
|
||||||
|
return this.sessionService.set(
|
||||||
|
sessionId,
|
||||||
|
req.apiToken.project.id,
|
||||||
|
body.data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -56,9 +56,20 @@ export class SessionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async set(sessionId: string, prefix: string, data: any): Promise<void> {
|
async set(sessionId: string, prefix: string, data: any): Promise<void> {
|
||||||
|
const existingSession = await this.redisClient.get(
|
||||||
|
`${prefix}:${sessionId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!existingSession) {
|
||||||
|
throw new Error("Session not found");
|
||||||
|
}
|
||||||
|
|
||||||
await this.redisClient.set(
|
await this.redisClient.set(
|
||||||
`${prefix}:${sessionId}`,
|
`${prefix}:${sessionId}`,
|
||||||
data,
|
{
|
||||||
|
...existingSession,
|
||||||
|
...data,
|
||||||
|
},
|
||||||
await this.getSessionTTL(prefix)
|
await this.getSessionTTL(prefix)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user