137 lines
3.8 KiB
TypeScript
137 lines
3.8 KiB
TypeScript
import {
|
|
Body,
|
|
Delete,
|
|
Headers,
|
|
Inject,
|
|
Param,
|
|
Post,
|
|
Res,
|
|
UseGuards,
|
|
} from "@nestjs/common";
|
|
import { Response } from "express";
|
|
import { QueryHandlerService } from "../handler/query.handler.service";
|
|
import { ApiTokenGuard } from "src/api/guards/api-token.guard";
|
|
import { QueryExecuterService } from "../executer/query.executer.service";
|
|
import { QueryGuard } from "src/query/guards/query.guard";
|
|
import { LoggerService } from "../logger/logger.service";
|
|
import { TLogType } from "../logger/logger.types";
|
|
import { QueryResponse } from "src/vm/vm.constants";
|
|
|
|
@UseGuards(ApiTokenGuard)
|
|
export abstract class BaseQueryController {
|
|
constructor(
|
|
@Inject(QueryHandlerService)
|
|
protected readonly queryHandlerService: QueryHandlerService,
|
|
@Inject(QueryExecuterService)
|
|
protected readonly queryExecuterService: QueryExecuterService,
|
|
@Inject(LoggerService)
|
|
protected readonly loggerService: LoggerService
|
|
) {}
|
|
|
|
protected abstract getIsCommand(): boolean;
|
|
|
|
@Post("create")
|
|
async createQuery(
|
|
@Body() queryData: { projectToken: string; source: string }
|
|
) {
|
|
return this.queryHandlerService.createQuery(queryData, this.getIsCommand());
|
|
}
|
|
|
|
@Post("update/:id")
|
|
@UseGuards(QueryGuard)
|
|
async updateQuery(
|
|
@Body() updateData: Partial<{ source: string }>,
|
|
@Param("id") id: string
|
|
) {
|
|
return this.queryHandlerService.updateQuery(id, updateData);
|
|
}
|
|
|
|
@Post("/run/:id")
|
|
@UseGuards(QueryGuard)
|
|
async runQuery(
|
|
@Param("id") id: string,
|
|
@Body() query: Record<string, any>,
|
|
@Headers() headers: Record<string, any>,
|
|
@Res() res: Response
|
|
) {
|
|
let queryResult: QueryResponse;
|
|
const loggerTraceId =
|
|
headers["x-trace-id"] || LoggerService.generateTraceId();
|
|
const log = LoggerService.log(
|
|
{
|
|
traceId: loggerTraceId,
|
|
startTime: new Date().getTime(),
|
|
payload: query,
|
|
headers: headers,
|
|
cookies: headers.cookie,
|
|
url: `/run/${id}`,
|
|
response: null,
|
|
content: [],
|
|
},
|
|
{ content: "", type: TLogType.info, timeStamp: new Date().getTime() }
|
|
);
|
|
|
|
try {
|
|
queryResult = await this.queryExecuterService.runQueryQueued(
|
|
id,
|
|
query,
|
|
log,
|
|
headers,
|
|
headers.cookie.split("; ").reduce((acc, cookie) => {
|
|
const [key, value] = cookie.split("=");
|
|
acc[key] = value;
|
|
return acc;
|
|
}, {})
|
|
);
|
|
} catch (error) {
|
|
log.content.push({
|
|
content: `Query execution failed: ${error.message}`,
|
|
type: TLogType.error,
|
|
timeStamp: new Date().getTime(),
|
|
});
|
|
log.endTime = new Date().getTime();
|
|
await this.loggerService.create(log.traceId, log);
|
|
res.status(500).send({ error: "Internal Server Error" });
|
|
return;
|
|
}
|
|
|
|
if (queryResult?.log) {
|
|
queryResult.log.endTime = new Date().getTime();
|
|
const res = JSON.parse(JSON.stringify(queryResult));
|
|
delete res.log;
|
|
queryResult.log.response = res;
|
|
await this.loggerService.create(queryResult.log.traceId, queryResult.log);
|
|
}
|
|
|
|
res.status(queryResult?.statusCode || 200);
|
|
|
|
if (queryResult?.cookies) {
|
|
for (const [key, value] of Object.entries(queryResult?.cookies || {})) {
|
|
res.cookie(key, value);
|
|
}
|
|
}
|
|
|
|
if (
|
|
queryResult?.redirect ||
|
|
(queryResult?.statusCode === 302 &&
|
|
queryResult?.headers &&
|
|
queryResult?.headers["Location"])
|
|
) {
|
|
res.redirect(queryResult?.redirect || queryResult?.headers["Location"]);
|
|
return;
|
|
}
|
|
|
|
for (const [key, value] of Object.entries(queryResult?.headers || {})) {
|
|
res.setHeader(key, value);
|
|
}
|
|
|
|
res.send(queryResult?.response || null);
|
|
}
|
|
|
|
@Delete("/delete/:id")
|
|
@UseGuards(QueryGuard)
|
|
async deleteQuery(@Param("id") id: string) {
|
|
return this.queryHandlerService.deleteQuery(id);
|
|
}
|
|
}
|