diff --git a/package.json b/package.json index 84cb8af..cd877c7 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "source-map-support": "^0.5.20", "ts-loader": "^9.2.3", "ts-node": "^10.0.0", - "tsconfig-paths": "^4.1.0", + "tsconfig-paths": "^4.2.0", "typescript": "^4.7.4" } } diff --git a/src/api/api.module.ts b/src/api/api.module.ts index e65c2f3..55a94f5 100644 --- a/src/api/api.module.ts +++ b/src/api/api.module.ts @@ -1,10 +1,10 @@ import { Module } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; import { Token } from "./entities/token.entity"; -import { ProjectModule } from "src/project/project.module"; +import { ProjectModule } from "../project/project.module"; import { ApiService } from "./api.service"; import { ApiController } from "./api.controller"; -import { Project } from "src/project/entities/project.entity"; +import { Project } from "../project/entities/project.entity"; @Module({ imports: [ProjectModule, TypeOrmModule.forFeature([Token, Project])], diff --git a/src/api/api.service.ts b/src/api/api.service.ts index 9ec0812..fbb9946 100644 --- a/src/api/api.service.ts +++ b/src/api/api.service.ts @@ -2,7 +2,7 @@ import { Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Token } from "./entities/token.entity"; import { Repository } from "typeorm"; -import { Project } from "src/project/entities/project.entity"; +import { Project } from "../project/entities/project.entity"; @Injectable() export class ApiService { diff --git a/src/api/entities/token.entity.ts b/src/api/entities/token.entity.ts index 8eef05d..e8cb483 100644 --- a/src/api/entities/token.entity.ts +++ b/src/api/entities/token.entity.ts @@ -1,4 +1,4 @@ -import { Project } from "src/project/entities/project.entity"; +import { Project } from "../../project/entities/project.entity"; import { Column, Entity, ManyToOne, PrimaryGeneratedColumn } from "typeorm"; @Entity("token") diff --git a/src/app/app.module.ts b/src/app/app.module.ts index ebd0384..45df325 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,8 +1,8 @@ import { Module } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; import { ConfigModule } from "@nestjs/config"; -import { TestModule } from "src/test/test.module"; -import { ApiModule } from "src/api/api.module"; +import { TestModule } from "../test/test.module"; +import { ApiModule } from "../api/api.module"; @Module({ imports: [ diff --git a/src/migrations/1758118369785-Query.ts b/src/migrations/1758118369785-Query.ts new file mode 100644 index 0000000..aca5d65 --- /dev/null +++ b/src/migrations/1758118369785-Query.ts @@ -0,0 +1,51 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Query1758118369785 implements MigrationInterface { + name = "Query1758118369785"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE \`project\` (\`token\` varchar(36) NOT NULL, \`name\` varchar(255) NOT NULL, PRIMARY KEY (\`token\`)) ENGINE=InnoDB` + ); + await queryRunner.query( + `CREATE TABLE \`module\` (\`id\` varchar(36) NOT NULL, \`sourcePath\` varchar(255) NOT NULL, \`name\` varchar(255) NOT NULL, \`isInjectable\` tinyint NOT NULL DEFAULT '1', PRIMARY KEY (\`id\`)) ENGINE=InnoDB` + ); + await queryRunner.query( + `CREATE TABLE \`query\` (\`id\` varchar(36) NOT NULL, \`source\` longtext NOT NULL, \`isActive\` tinyint NOT NULL DEFAULT '1', \`projectToken\` varchar(36) NULL, PRIMARY KEY (\`id\`)) ENGINE=InnoDB` + ); + await queryRunner.query(`ALTER TABLE \`token\` DROP PRIMARY KEY`); + await queryRunner.query(`ALTER TABLE \`token\` DROP COLUMN \`id\``); + await queryRunner.query( + `ALTER TABLE \`token\` ADD \`token\` varchar(36) NOT NULL PRIMARY KEY` + ); + await queryRunner.query( + `ALTER TABLE \`token\` ADD \`projectToken\` varchar(36) NULL` + ); + await queryRunner.query( + `ALTER TABLE \`token\` ADD CONSTRAINT \`FK_f0bc174c878df5e005c38fe05bd\` FOREIGN KEY (\`projectToken\`) REFERENCES \`project\`(\`token\`) ON DELETE NO ACTION ON UPDATE NO ACTION` + ); + await queryRunner.query( + `ALTER TABLE \`query\` ADD CONSTRAINT \`FK_f58429a7d32fbb51ead8c4daf0a\` FOREIGN KEY (\`projectToken\`) REFERENCES \`project\`(\`token\`) ON DELETE NO ACTION ON UPDATE NO ACTION` + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE \`query\` DROP FOREIGN KEY \`FK_f58429a7d32fbb51ead8c4daf0a\`` + ); + await queryRunner.query( + `ALTER TABLE \`token\` DROP FOREIGN KEY \`FK_f0bc174c878df5e005c38fe05bd\`` + ); + await queryRunner.query( + `ALTER TABLE \`token\` DROP COLUMN \`projectToken\`` + ); + await queryRunner.query(`ALTER TABLE \`token\` DROP COLUMN \`token\``); + await queryRunner.query( + `ALTER TABLE \`token\` ADD \`id\` varchar(36) NOT NULL` + ); + await queryRunner.query(`ALTER TABLE \`token\` ADD PRIMARY KEY (\`id\`)`); + await queryRunner.query(`DROP TABLE \`query\``); + await queryRunner.query(`DROP TABLE \`module\``); + await queryRunner.query(`DROP TABLE \`project\``); + } +} diff --git a/src/project/entities/project.entity.ts b/src/project/entities/project.entity.ts index 0af2a7a..f1c36e9 100644 --- a/src/project/entities/project.entity.ts +++ b/src/project/entities/project.entity.ts @@ -1,5 +1,5 @@ -import { Token } from "src/api/entities/token.entity"; -import { Query } from "src/query/entities/query.enitity"; +import { Token } from "../../api/entities/token.entity"; +import { Query } from "../../query/entities/query.entity"; import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from "typeorm"; @Entity("project") diff --git a/src/query/entities/module.entity.ts b/src/query/entities/module.entity.ts index 23c2bd0..08357e6 100644 --- a/src/query/entities/module.entity.ts +++ b/src/query/entities/module.entity.ts @@ -1,8 +1,8 @@ import { Column, Entity, ManyToMany, PrimaryGeneratedColumn } from "typeorm"; -import { Query } from "./query.enitity"; +import { Query } from "./query.entity"; @Entity("module") -export class Module { +export class VMModule { @PrimaryGeneratedColumn("uuid") id: string; diff --git a/src/query/entities/query.enitity.ts b/src/query/entities/query.entity.ts similarity index 66% rename from src/query/entities/query.enitity.ts rename to src/query/entities/query.entity.ts index dc601d1..0f472cd 100644 --- a/src/query/entities/query.enitity.ts +++ b/src/query/entities/query.entity.ts @@ -1,4 +1,4 @@ -import { Project } from "src/project/entities/project.entity"; +import { Project } from "../../project/entities/project.entity"; import { Column, Entity, @@ -6,7 +6,7 @@ import { ManyToOne, PrimaryGeneratedColumn, } from "typeorm"; -import { Module } from "./module.entity"; +import { VMModule } from "./module.entity"; @Entity("query") export class Query { @@ -22,6 +22,6 @@ export class Query { @Column({ type: "tinyint", default: 1 }) isActive: number; - @ManyToMany(() => Module, (module) => module.queries) - modules: Module[]; + @ManyToMany(() => VMModule, (module) => module.queries) + modules: VMModule[]; } diff --git a/src/query/executer/query.executer.service.ts b/src/query/executer/query.executer.service.ts index 1deee2f..ad7383a 100644 --- a/src/query/executer/query.executer.service.ts +++ b/src/query/executer/query.executer.service.ts @@ -1,9 +1,9 @@ import { Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; -import { Query } from "../entities/query.enitity"; +import { Query } from "../entities/query.entity"; import { Repository } from "typeorm"; -import { Vm } from "src/vm/vm.class"; -import { Module } from "src/vm/module.class"; +import { Vm } from "../../vm/vm.class"; +import { VModule } from "../../vm/module.class"; @Injectable() export class QueryExecuterService { @@ -23,6 +23,10 @@ export class QueryExecuterService { const vm = this.createVm(query); + vm.setFunction("result", (result: string) => { + console.log("Query Result:", result); + }); + await vm.runScript(query.source); // Here you would add the logic to actually execute the query @@ -34,7 +38,7 @@ export class QueryExecuterService { return new Vm({ memoryLimit: 5, modules: query.modules.map((module) => { - return new Module(module.name, module.sourcePath); + return new VModule(module.name, module.sourcePath); }), }); } diff --git a/src/query/query.module.ts b/src/query/query.module.ts index 80a83f0..c7734d5 100644 --- a/src/query/query.module.ts +++ b/src/query/query.module.ts @@ -1,8 +1,15 @@ import { Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { Query } from "./entities/query.entity"; +import { VMModule } from "./entities/module.entity"; +import { QueryExecuterController } from "./executer/query.executer.controller"; +import { QueryHandlerController } from "./handler/query.handler.controller"; +import { QueryExecuterService } from "./executer/query.executer.service"; +import { QueryHandlerService } from "./handler/query.handler.service"; @Module({ - imports: [], - controllers: [], - providers: [], + imports: [TypeOrmModule.forFeature([Query, VMModule])], + controllers: [QueryExecuterController, QueryHandlerController], + providers: [QueryExecuterService, QueryHandlerService], }) export class QueryModule {} diff --git a/src/vm/module.class.ts b/src/vm/module.class.ts index d58a1ff..d3fd91e 100644 --- a/src/vm/module.class.ts +++ b/src/vm/module.class.ts @@ -1,6 +1,6 @@ import * as fs from "fs"; -export class Module { +export class VModule { private name: string; private source: string; diff --git a/src/vm/vm.class.ts b/src/vm/vm.class.ts index 0144413..a7bfcba 100644 --- a/src/vm/vm.class.ts +++ b/src/vm/vm.class.ts @@ -1,13 +1,13 @@ import * as ivm from "isolated-vm"; -import { Module } from "./module.class"; +import { VModule } from "./module.class"; export class Vm { private memoryLimit: number; - private modules: Module[]; + private modules: VModule[]; private context: any; private jail: any; - constructor(configs: { memoryLimit: number; modules: Module[] }) { + constructor(configs: { memoryLimit: number; modules: VModule[] }) { this.memoryLimit = configs.memoryLimit; this.modules = configs.modules; } @@ -24,6 +24,10 @@ export class Vm { } } + setFunction(name: string, func: (...args) => any) { + this.jail.setSync(name, func); + } + async runScript(script: string) { const compiledScript = await this.context.isolate.compileScript(script); return compiledScript.run(this.context); diff --git a/tsconfig.json b/tsconfig.json index 95f5641..111e130 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,9 @@ "sourceMap": true, "outDir": "./dist", "baseUrl": "./", + "paths": { + "src/*": ["src/*"] + }, "incremental": true, "skipLibCheck": true, "strictNullChecks": false, diff --git a/yarn.lock b/yarn.lock index 992f758..7eba317 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3451,7 +3451,7 @@ tsconfig-paths-webpack-plugin@4.0.1: enhanced-resolve "^5.7.0" tsconfig-paths "^4.1.2" -tsconfig-paths@4.2.0, tsconfig-paths@^4.1.0, tsconfig-paths@^4.1.2: +tsconfig-paths@4.2.0, tsconfig-paths@^4.1.2, tsconfig-paths@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==