feat: implement logging enhancements; add projectId and queryId to log entity; update query and logger services for improved logging; refactor query execution to support call stack tracking
This commit is contained in:
31
src/migrations/1760199448968-logsPerQuery.ts
Normal file
31
src/migrations/1760199448968-logsPerQuery.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
||||||
|
|
||||||
|
export class LogsPerQuery1760199448968 implements MigrationInterface {
|
||||||
|
name = "LogsPerQuery1760199448968";
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` ADD \`projectId\` varchar(36) NULL`
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` ADD \`queryId\` varchar(36) NULL`
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` ADD CONSTRAINT \`FK_0c0ad31dd4033de83a2c47f2c82\` FOREIGN KEY (\`projectId\`) REFERENCES \`project\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` ADD CONSTRAINT \`FK_7867d6fbda5d177a3727cedece3\` FOREIGN KEY (\`queryId\`) REFERENCES \`query\`(\`id\`) ON DELETE NO ACTION ON UPDATE NO ACTION`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` DROP FOREIGN KEY \`FK_7867d6fbda5d177a3727cedece3\``
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE \`log\` DROP FOREIGN KEY \`FK_0c0ad31dd4033de83a2c47f2c82\``
|
||||||
|
);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`log\` DROP COLUMN \`queryId\``);
|
||||||
|
await queryRunner.query(`ALTER TABLE \`log\` DROP COLUMN \`projectId\``);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ import {
|
|||||||
import { Database } from "../../databaseManager/entities/database.entity";
|
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";
|
||||||
|
|
||||||
@Entity("project")
|
@Entity("project")
|
||||||
export class Project {
|
export class Project {
|
||||||
@ -29,6 +30,9 @@ export class Project {
|
|||||||
@JoinColumn()
|
@JoinColumn()
|
||||||
database: Database;
|
database: Database;
|
||||||
|
|
||||||
|
@OneToMany(() => Log, (log) => log.project)
|
||||||
|
logs: Log[];
|
||||||
|
|
||||||
@OneToMany(() => Query, (query) => query.project)
|
@OneToMany(() => Query, (query) => query.project)
|
||||||
queries: Query[];
|
queries: Query[];
|
||||||
|
|
||||||
|
|||||||
@ -5,10 +5,11 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
Param,
|
Param,
|
||||||
Post,
|
Post,
|
||||||
|
Req,
|
||||||
Res,
|
Res,
|
||||||
UseGuards,
|
UseGuards,
|
||||||
} from "@nestjs/common";
|
} from "@nestjs/common";
|
||||||
import { Response } from "express";
|
import { Response, Request } from "express";
|
||||||
import { QueryHandlerService } from "../handler/query.handler.service";
|
import { QueryHandlerService } from "../handler/query.handler.service";
|
||||||
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
||||||
import { QueryExecuterService } from "../executer/query.executer.service";
|
import { QueryExecuterService } from "../executer/query.executer.service";
|
||||||
@ -16,6 +17,7 @@ import { QueryGuard } from "src/query/guards/query.guard";
|
|||||||
import { LoggerService } from "../logger/logger.service";
|
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";
|
||||||
|
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
export abstract class BaseQueryController {
|
export abstract class BaseQueryController {
|
||||||
@ -52,7 +54,8 @@ export abstract class BaseQueryController {
|
|||||||
@Param("id") id: string,
|
@Param("id") id: string,
|
||||||
@Body() query: Record<string, any>,
|
@Body() query: Record<string, any>,
|
||||||
@Headers() headers: Record<string, any>,
|
@Headers() headers: Record<string, any>,
|
||||||
@Res() res: Response
|
@Res() res: Response,
|
||||||
|
@Req() req: Request & { query: Query }
|
||||||
) {
|
) {
|
||||||
let queryResult: QueryResponse;
|
let queryResult: QueryResponse;
|
||||||
const loggerTraceId =
|
const loggerTraceId =
|
||||||
@ -68,7 +71,7 @@ export abstract class BaseQueryController {
|
|||||||
response: null,
|
response: null,
|
||||||
content: [],
|
content: [],
|
||||||
},
|
},
|
||||||
{ content: "", type: TLogType.info, timeStamp: new Date().getTime() }
|
{ content: `Query ${id} started`, type: TLogType.info }
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -90,7 +93,7 @@ export abstract class BaseQueryController {
|
|||||||
timeStamp: new Date().getTime(),
|
timeStamp: new Date().getTime(),
|
||||||
});
|
});
|
||||||
log.endTime = new Date().getTime();
|
log.endTime = new Date().getTime();
|
||||||
await this.loggerService.create(log.traceId, log);
|
await this.loggerService.create(log.traceId, log, req.query);
|
||||||
res.status(500).send({ error: "Internal Server Error" });
|
res.status(500).send({ error: "Internal Server Error" });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -100,7 +103,11 @@ export abstract class BaseQueryController {
|
|||||||
const res = JSON.parse(JSON.stringify(queryResult));
|
const res = JSON.parse(JSON.stringify(queryResult));
|
||||||
delete res.log;
|
delete res.log;
|
||||||
queryResult.log.response = res;
|
queryResult.log.response = res;
|
||||||
await this.loggerService.create(queryResult.log.traceId, queryResult.log);
|
await this.loggerService.create(
|
||||||
|
queryResult.log.traceId,
|
||||||
|
queryResult.log,
|
||||||
|
req.query
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(queryResult?.statusCode || 200);
|
res.status(queryResult?.statusCode || 200);
|
||||||
|
|||||||
@ -1,5 +1,12 @@
|
|||||||
import { Project } from "../../project/entities/project.entity";
|
import { Project } from "../../project/entities/project.entity";
|
||||||
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
import {
|
||||||
|
Column,
|
||||||
|
Entity,
|
||||||
|
ManyToOne,
|
||||||
|
OneToMany,
|
||||||
|
PrimaryGeneratedColumn,
|
||||||
|
} from "typeorm";
|
||||||
|
import { Log } from "../logger/entities/log.entity";
|
||||||
|
|
||||||
@Entity("query")
|
@Entity("query")
|
||||||
export class Query {
|
export class Query {
|
||||||
@ -9,6 +16,9 @@ export class Query {
|
|||||||
@ManyToOne(() => Project, (project) => project.queries)
|
@ManyToOne(() => Project, (project) => project.queries)
|
||||||
project: Project;
|
project: Project;
|
||||||
|
|
||||||
|
@OneToMany(() => Log, (log) => log.query)
|
||||||
|
logs: Log[];
|
||||||
|
|
||||||
@Column({ type: "longtext" })
|
@Column({ type: "longtext" })
|
||||||
source: string;
|
source: string;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { RedisNodeService } from "./../../redisManager/redisNode/redis.node.service";
|
import { RedisNodeService } from "./../../redisManager/redisNode/redis.node.service";
|
||||||
import { Inject, Injectable, Logger } from "@nestjs/common";
|
import { Inject, Injectable } from "@nestjs/common";
|
||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import { Query } from "../entities/query.entity";
|
import { Query } from "../entities/query.entity";
|
||||||
import { Repository } from "typeorm";
|
import { Repository } from "typeorm";
|
||||||
@ -62,6 +62,11 @@ export class QueryExecuterService {
|
|||||||
headers: Record<string, any> = {},
|
headers: Record<string, any> = {},
|
||||||
cookies: Record<string, any> = {}
|
cookies: Record<string, any> = {}
|
||||||
): Promise<QueryResponse> {
|
): Promise<QueryResponse> {
|
||||||
|
LoggerService.log(log, {
|
||||||
|
content: `Queueing query ${token}`,
|
||||||
|
type: TLogType.info,
|
||||||
|
});
|
||||||
|
|
||||||
const job = await this.queryQueue.add(
|
const job = await this.queryQueue.add(
|
||||||
`${new Date().getTime()}_${token}`,
|
`${new Date().getTime()}_${token}`,
|
||||||
{
|
{
|
||||||
@ -85,6 +90,7 @@ export class QueryExecuterService {
|
|||||||
async runQuery(
|
async runQuery(
|
||||||
token: string,
|
token: string,
|
||||||
queryData: any,
|
queryData: any,
|
||||||
|
callStack: number = 0,
|
||||||
headers: Record<string, any> = {},
|
headers: Record<string, any> = {},
|
||||||
cookies: Record<string, any> = {},
|
cookies: Record<string, any> = {},
|
||||||
log: TLog = null
|
log: TLog = null
|
||||||
@ -95,6 +101,10 @@ export class QueryExecuterService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!query) {
|
if (!query) {
|
||||||
|
LoggerService.log(log, {
|
||||||
|
content: `Query with id ${token} not found`,
|
||||||
|
type: TLogType.error,
|
||||||
|
});
|
||||||
throw new Error("Query not found");
|
throw new Error("Query not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +115,17 @@ export class QueryExecuterService {
|
|||||||
cookies["x-session-id"] = session.sessionId;
|
cookies["x-session-id"] = session.sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
const vm = await this.createVm(query, log, cookies["x-session-id"]);
|
LoggerService.log(log, {
|
||||||
|
content: `Running query ${query.id}`,
|
||||||
|
type: TLogType.info,
|
||||||
|
});
|
||||||
|
|
||||||
|
const vm = await this.createVm(
|
||||||
|
query,
|
||||||
|
log,
|
||||||
|
callStack,
|
||||||
|
cookies["x-session-id"]
|
||||||
|
);
|
||||||
const result = await vm.runScript(
|
const result = await vm.runScript(
|
||||||
this.clearImports(query.source),
|
this.clearImports(query.source),
|
||||||
queryData,
|
queryData,
|
||||||
@ -126,10 +146,20 @@ export class QueryExecuterService {
|
|||||||
).sessionId;
|
).sessionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoggerService.log(log, {
|
||||||
|
content: `Query ${query.id} executed successfully`,
|
||||||
|
type: TLogType.info,
|
||||||
|
});
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async createVm(query: Query, log: TLog, sessionId: string = null) {
|
private async createVm(
|
||||||
|
query: Query,
|
||||||
|
log: TLog,
|
||||||
|
callStack: number,
|
||||||
|
sessionId: string = null
|
||||||
|
): Promise<Vm> {
|
||||||
const imports = this.parseImports(query.source);
|
const imports = this.parseImports(query.source);
|
||||||
const importsParsed = imports.map((imp) => {
|
const importsParsed = imports.map((imp) => {
|
||||||
const item = imp.split("/");
|
const item = imp.split("/");
|
||||||
@ -172,15 +202,18 @@ export class QueryExecuterService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const vm = new Vm({
|
const vm = new Vm(
|
||||||
memoryLimit: 128,
|
{
|
||||||
timeLimit: BigInt(100e9),
|
memoryLimit: 128,
|
||||||
cpuTimeLimit: BigInt(5e9),
|
timeLimit: BigInt(100e9),
|
||||||
modules: modules,
|
cpuTimeLimit: BigInt(5e9),
|
||||||
plugins: plugins,
|
modules: modules,
|
||||||
functions: functions,
|
plugins: plugins,
|
||||||
log,
|
functions: functions,
|
||||||
});
|
log,
|
||||||
|
},
|
||||||
|
callStack
|
||||||
|
);
|
||||||
|
|
||||||
return await vm.init();
|
return await vm.init();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm";
|
||||||
import { TLog } from "../logger.types";
|
import { TLog } from "../logger.types";
|
||||||
|
import { Project } from "../../../project/entities/project.entity";
|
||||||
|
import { Query } from "../../../query/entities/query.entity";
|
||||||
|
|
||||||
@Entity()
|
@Entity()
|
||||||
export class Log {
|
export class Log {
|
||||||
@ -18,6 +20,12 @@ export class Log {
|
|||||||
})
|
})
|
||||||
content: TLog;
|
content: TLog;
|
||||||
|
|
||||||
|
@ManyToOne(() => Project, (project) => project.logs)
|
||||||
|
project: Project;
|
||||||
|
|
||||||
|
@ManyToOne(() => Query, (query) => query.logs)
|
||||||
|
query: Query;
|
||||||
|
|
||||||
@Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
|
@Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
|
||||||
createdAt: Date;
|
createdAt: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,15 @@
|
|||||||
import { Body, Controller, Get, Inject, Post, UseGuards } from "@nestjs/common";
|
import {
|
||||||
|
Body,
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Inject,
|
||||||
|
Param,
|
||||||
|
Post,
|
||||||
|
UseGuards,
|
||||||
|
} 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";
|
||||||
|
|
||||||
@Controller("logger")
|
@Controller("logger")
|
||||||
@UseGuards(ApiTokenGuard)
|
@UseGuards(ApiTokenGuard)
|
||||||
@ -10,13 +19,14 @@ export class LoggerController {
|
|||||||
private readonly loggerService: LoggerService
|
private readonly loggerService: LoggerService
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get("/:traceId")
|
@Get("/:id/:traceId")
|
||||||
getByTraceId(@Inject("traceId") traceId: string) {
|
getByTraceId(@Param("traceId") traceId: string) {
|
||||||
return this.loggerService.findByTraceId(traceId);
|
return this.loggerService.findByTraceId(traceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Post("/find")
|
@Post("/:id/findAll")
|
||||||
find(
|
findAll(
|
||||||
|
@Param("id") projectId: string,
|
||||||
@Body()
|
@Body()
|
||||||
body: {
|
body: {
|
||||||
traceId?: string;
|
traceId?: string;
|
||||||
@ -27,6 +37,23 @@ export class LoggerController {
|
|||||||
offset: number;
|
offset: number;
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
return this.loggerService.find(body);
|
return this.loggerService.findByProjectId(projectId, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Post("/:id/find")
|
||||||
|
@UseGuards(QueryGuard)
|
||||||
|
find(
|
||||||
|
@Param("id") _id: string,
|
||||||
|
@Body()
|
||||||
|
body: {
|
||||||
|
traceId?: string;
|
||||||
|
fromDate?: Date;
|
||||||
|
toDate?: Date;
|
||||||
|
url?: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
return this.loggerService.find(_id, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { Log } from "./entities/log.entity";
|
|||||||
import { InjectRepository } from "@nestjs/typeorm";
|
import { InjectRepository } from "@nestjs/typeorm";
|
||||||
import { Repository } from "typeorm";
|
import { Repository } from "typeorm";
|
||||||
import { TLog, TLogLine } from "./logger.types";
|
import { TLog, TLogLine } from "./logger.types";
|
||||||
|
import { Query } from "../entities/query.entity";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LoggerService {
|
export class LoggerService {
|
||||||
@ -11,8 +12,13 @@ export class LoggerService {
|
|||||||
private readonly logRepository: Repository<Log>
|
private readonly logRepository: Repository<Log>
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async create(traceId: string, content: TLog): Promise<Log> {
|
async create(traceId: string, content: TLog, query: Query): Promise<Log> {
|
||||||
const log = this.logRepository.create({ traceId, content });
|
const log = this.logRepository.create({
|
||||||
|
traceId,
|
||||||
|
content,
|
||||||
|
query,
|
||||||
|
project: query.project,
|
||||||
|
});
|
||||||
return await this.logRepository.save(log);
|
return await this.logRepository.save(log);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -20,14 +26,14 @@ export class LoggerService {
|
|||||||
return await this.logRepository.find({ where: { traceId } });
|
return await this.logRepository.find({ where: { traceId } });
|
||||||
}
|
}
|
||||||
|
|
||||||
async find(data: {
|
private prepareQuery(data: {
|
||||||
traceId?: string;
|
traceId?: string;
|
||||||
fromDate?: Date;
|
fromDate?: Date;
|
||||||
toDate?: Date;
|
toDate?: Date;
|
||||||
url?: string;
|
url?: string;
|
||||||
limit: number;
|
limit: number;
|
||||||
offset: number;
|
offset: number;
|
||||||
}): Promise<Log[]> {
|
}) {
|
||||||
const query = this.logRepository.createQueryBuilder("log");
|
const query = this.logRepository.createQueryBuilder("log");
|
||||||
|
|
||||||
if (data.traceId) {
|
if (data.traceId) {
|
||||||
@ -37,21 +43,57 @@ export class LoggerService {
|
|||||||
if (data.fromDate) {
|
if (data.fromDate) {
|
||||||
query.andWhere("log.createdAt >= :fromDate", { fromDate: data.fromDate });
|
query.andWhere("log.createdAt >= :fromDate", { fromDate: data.fromDate });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.toDate) {
|
if (data.toDate) {
|
||||||
query.andWhere("log.createdAt <= :toDate", { toDate: data.toDate });
|
query.andWhere("log.createdAt <= :toDate", { toDate: data.toDate });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.url) {
|
if (data.url) {
|
||||||
query.andWhere("log.content LIKE :url", { url: `%${data.url}%` });
|
query.andWhere("log.content LIKE :url", { url: `%${data.url}%` });
|
||||||
}
|
}
|
||||||
|
|
||||||
query.skip(data.offset).take(data.limit).orderBy("log.createdAt", "DESC");
|
query.skip(data.offset).take(data.limit).orderBy("log.createdAt", "DESC");
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
async findByProjectId(
|
||||||
|
projectId: string,
|
||||||
|
data: {
|
||||||
|
traceId?: string;
|
||||||
|
fromDate?: Date;
|
||||||
|
toDate?: Date;
|
||||||
|
url?: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
}
|
||||||
|
): Promise<Log[]> {
|
||||||
|
const query = this.prepareQuery(data);
|
||||||
|
query.where("log.projectId = :projectId", { projectId });
|
||||||
|
|
||||||
return await query.getMany();
|
return await query.getMany();
|
||||||
}
|
}
|
||||||
|
|
||||||
static log(logStack: TLog, log: TLog | TLogLine): TLog {
|
async find(
|
||||||
|
queryId: string,
|
||||||
|
data: {
|
||||||
|
traceId?: string;
|
||||||
|
fromDate?: Date;
|
||||||
|
toDate?: Date;
|
||||||
|
url?: string;
|
||||||
|
limit: number;
|
||||||
|
offset: number;
|
||||||
|
}
|
||||||
|
): Promise<Log[]> {
|
||||||
|
const query = this.prepareQuery(data);
|
||||||
|
query.where("log.queryId = :queryId", { queryId });
|
||||||
|
|
||||||
|
return await query.getMany();
|
||||||
|
}
|
||||||
|
|
||||||
|
static log(logStack: TLog, log: TLogLine): TLog {
|
||||||
|
if (!log.timeStamp) {
|
||||||
|
log.timeStamp = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
logStack.content.push(log);
|
logStack.content.push(log);
|
||||||
return logStack;
|
return logStack;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,12 +10,12 @@ export enum TLogType {
|
|||||||
export type TLogLine = {
|
export type TLogLine = {
|
||||||
content: string;
|
content: string;
|
||||||
type: TLogType;
|
type: TLogType;
|
||||||
timeStamp: number;
|
timeStamp?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface TLog {
|
export interface TLog {
|
||||||
traceId: string;
|
traceId: string;
|
||||||
content: (TLogLine | TLog)[];
|
content: TLogLine[];
|
||||||
payload?: any;
|
payload?: any;
|
||||||
headers: Record<string, string | string[] | undefined>;
|
headers: Record<string, string | string[] | undefined>;
|
||||||
cookies: Record<string, string>;
|
cookies: Record<string, string>;
|
||||||
|
|||||||
@ -24,6 +24,7 @@ export class QueryProcessor extends WorkerHost {
|
|||||||
return await this.queryExecuterService.runQuery(
|
return await this.queryExecuterService.runQuery(
|
||||||
token,
|
token,
|
||||||
queryData,
|
queryData,
|
||||||
|
0,
|
||||||
headers,
|
headers,
|
||||||
cookies,
|
cookies,
|
||||||
log
|
log
|
||||||
|
|||||||
@ -5,9 +5,11 @@ export abstract class Plugin {
|
|||||||
protected log: TLog;
|
protected log: TLog;
|
||||||
protected cookies: Record<string, string>;
|
protected cookies: Record<string, string>;
|
||||||
protected headers: Record<string, string>;
|
protected headers: Record<string, string>;
|
||||||
|
protected callStack: number;
|
||||||
|
|
||||||
constructor(name: string, protected methods: string[] = []) {
|
constructor(name: string, protected methods: string[] = []) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.callStack = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
getName(): string {
|
getName(): string {
|
||||||
@ -26,6 +28,10 @@ export abstract class Plugin {
|
|||||||
this.headers = headers;
|
this.headers = headers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setCallStack(callStack: number) {
|
||||||
|
this.callStack = callStack;
|
||||||
|
}
|
||||||
|
|
||||||
setCookies(cookies: Record<string, string>) {
|
setCookies(cookies: Record<string, string>) {
|
||||||
this.cookies = cookies;
|
this.cookies = cookies;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ export class QueryPlugin extends Plugin {
|
|||||||
return await this.QueryExecuterService.runQuery(
|
return await this.QueryExecuterService.runQuery(
|
||||||
id,
|
id,
|
||||||
data,
|
data,
|
||||||
|
this.callStack + 1,
|
||||||
this.headers,
|
this.headers,
|
||||||
this.cookies,
|
this.cookies,
|
||||||
this.log
|
this.log
|
||||||
|
|||||||
@ -19,18 +19,28 @@ export class Vm {
|
|||||||
private log: TLog;
|
private log: TLog;
|
||||||
private headers?: Record<string, string>;
|
private headers?: Record<string, string>;
|
||||||
private cookies?: Record<string, string>;
|
private cookies?: Record<string, string>;
|
||||||
|
private callStack = 0;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
configs: {
|
||||||
|
memoryLimit: number;
|
||||||
|
timeLimit?: bigint;
|
||||||
|
cpuTimeLimit?: bigint;
|
||||||
|
modules: VModule[];
|
||||||
|
plugins: Plugin[];
|
||||||
|
functions: string[];
|
||||||
|
log: TLog;
|
||||||
|
headers?: Record<string, string>;
|
||||||
|
cookies?: Record<string, string>;
|
||||||
|
},
|
||||||
|
callStack = 0
|
||||||
|
) {
|
||||||
|
this.callStack = callStack;
|
||||||
|
|
||||||
|
if (this.callStack > 5) {
|
||||||
|
throw new Error("Maximum call stack size exceeded");
|
||||||
|
}
|
||||||
|
|
||||||
constructor(configs: {
|
|
||||||
memoryLimit: number;
|
|
||||||
timeLimit?: bigint;
|
|
||||||
cpuTimeLimit?: bigint;
|
|
||||||
modules: VModule[];
|
|
||||||
plugins: Plugin[];
|
|
||||||
functions: string[];
|
|
||||||
log: TLog;
|
|
||||||
headers?: Record<string, string>;
|
|
||||||
cookies?: Record<string, string>;
|
|
||||||
}) {
|
|
||||||
this.memoryLimit = configs.memoryLimit;
|
this.memoryLimit = configs.memoryLimit;
|
||||||
this.modules = configs.modules;
|
this.modules = configs.modules;
|
||||||
this.plugins = configs.plugins;
|
this.plugins = configs.plugins;
|
||||||
@ -71,6 +81,7 @@ export class Vm {
|
|||||||
plugin.setLog(this.log);
|
plugin.setLog(this.log);
|
||||||
plugin.setHeaders(this.headers);
|
plugin.setHeaders(this.headers);
|
||||||
plugin.setCookies(this.cookies);
|
plugin.setCookies(this.cookies);
|
||||||
|
plugin.setCallStack(this.callStack);
|
||||||
const result = await plugin[method](...args);
|
const result = await plugin[method](...args);
|
||||||
|
|
||||||
if (result && result.log) {
|
if (result && result.log) {
|
||||||
|
|||||||
@ -6,7 +6,6 @@ import "plugin/db";
|
|||||||
import "plugin/axios";
|
import "plugin/axios";
|
||||||
import "plugin/session";
|
import "plugin/session";
|
||||||
import "plugin/query";
|
import "plugin/query";
|
||||||
import { query } from "express";
|
|
||||||
|
|
||||||
function createSQL(id) {
|
function createSQL(id) {
|
||||||
return squel.select().from("test").where("id = ?", id).toString();
|
return squel.select().from("test").where("id = ?", id).toString();
|
||||||
|
|||||||
Reference in New Issue
Block a user