Skip to content

Commit

Permalink
new spec handle
Browse files Browse the repository at this point in the history
  • Loading branch information
NikhilShahi committed Aug 5, 2022
1 parent c16fe32 commit 46953e1
Show file tree
Hide file tree
Showing 6 changed files with 61 additions and 17 deletions.
12 changes: 10 additions & 2 deletions backend/models/api-endpoint.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { BaseEntity, Column, CreateDateColumn, Entity, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { BaseEntity, Column, CreateDateColumn, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, UpdateDateColumn } from "typeorm";
import { MatchedDataClass } from "./matched-data-class";
import { RestMethod } from "../src/enums";
import { OpenApiSpec } from "./openapi-spec";

@Entity()
export class ApiEndpoint extends BaseEntity {
Expand All @@ -19,7 +20,7 @@ export class ApiEndpoint extends BaseEntity {
@Column({ nullable: false })
host: string

@Column({ type: "integer"})
@Column({ type: "integer", default: 0})
totalCalls: number

@Column({ type: "enum", enum: RestMethod})
Expand All @@ -30,4 +31,11 @@ export class ApiEndpoint extends BaseEntity {

@OneToMany(() => MatchedDataClass, dataClass => dataClass.apiEndpoint)
sensitiveDataClasses: MatchedDataClass[]

@Column({ nullable: true })
openapiSpecName: string

@ManyToOne(() => OpenApiSpec)
@JoinColumn()
openapiSpec: OpenApiSpec
}
3 changes: 2 additions & 1 deletion backend/models/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ApiEndpoint } from "./api-endpoint";
import { MatchedDataClass } from "./matched-data-class";
import { ApiTrace } from "./api-trace";
import { OpenApiSpec } from "./openapi-spec";

export { ApiEndpoint, MatchedDataClass, ApiTrace }
export { ApiEndpoint, MatchedDataClass, ApiTrace, OpenApiSpec }
10 changes: 10 additions & 0 deletions backend/models/openapi-spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { BaseEntity, Entity, PrimaryColumn, Column } from "typeorm";

@Entity()
export class OpenApiSpec extends BaseEntity {
@PrimaryColumn()
name: string

@Column()
spec: string
}
14 changes: 13 additions & 1 deletion backend/src/api/spec/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,29 @@ import { JSONValue } from "../../types";
import { SpecService } from "../../services/spec";
import ApiResponseHandler from "../../api-response-handler";
import Error400BadRequest from "../../errors/error-400-bad-request";
import { AppDataSource } from "../../data-source";
import { OpenApiSpec } from "../../../models";

export const uploadNewSpecHandler = async (req: Request, res: Response) => {
try {
if (!req.file) {
throw new Error400BadRequest("No spec file found.");
}
const specFile = req.file;
const fileName = req.file.filename || req.file.fieldname;
if (!fileName) {
throw new Error400BadRequest("No filename provided.")
}
const openApiSpecRepository = AppDataSource.getRepository(OpenApiSpec);
const exisitingSpec = await openApiSpecRepository.findOneBy({ name: fileName });
if (exisitingSpec) {
throw new Error400BadRequest("Spec file already exists.");
}
const specObject: JSONValue = yaml.load(
specFile.buffer.toString()
) as JSONValue;
await SpecService.uploadNewSpec(specObject);
await SpecService.uploadNewSpec(specObject, fileName);
await ApiResponseHandler.success(res, null)
} catch (err) {
await ApiResponseHandler.error(res, err);
}
Expand Down
4 changes: 2 additions & 2 deletions backend/src/data-source.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import "dotenv/config";
import { DataSource } from "typeorm";
import { ApiEndpoint, MatchedDataClass, ApiTrace } from "../models";
import { ApiEndpoint, MatchedDataClass, ApiTrace, OpenApiSpec } from "../models";

export const AppDataSource = new DataSource({
type: "postgres",
url: process.env.DB_URL,
synchronize: true,
entities: [ApiEndpoint, MatchedDataClass, ApiTrace],
entities: [ApiEndpoint, MatchedDataClass, ApiTrace, OpenApiSpec],
migrations: [],
logging: false,
});
35 changes: 24 additions & 11 deletions backend/src/services/spec/index.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,47 @@
import { RestMethod } from "../../enums";
import { ApiEndpoint } from "../../../models";
import { ApiEndpoint, OpenApiSpec } from "../../../models";
import Error400BadRequest from "../../errors/error-400-bad-request";
import { JSONValue } from "../../types";
import { AppDataSource } from "../../data-source";

export class SpecService {
static async uploadNewSpec(specObject: JSONValue) {
const hosts: string[] = [];
const apiEndpoints: ApiEndpoint[] = [];
static async uploadNewSpec(specObject: JSONValue, fileName: string) {
const servers: any[] = specObject["servers"];
const paths: JSONValue = specObject["paths"];

if (!servers || servers?.length === 0) {
throw new Error400BadRequest("No servers found in spec file.");
}

const apiEndpointRepository = AppDataSource.getRepository(ApiEndpoint);
const openApiSpecRepository = AppDataSource.getRepository(OpenApiSpec);
let existingSpec = await openApiSpecRepository.findOneBy({ name: fileName });
if (!existingSpec) {
existingSpec = new OpenApiSpec();
existingSpec.name = fileName;
}
existingSpec.spec = JSON.stringify(specObject);
const pathKeys = Object.keys(paths);
pathKeys.forEach((path) => {
const methods = Object.keys(paths[path]);
methods.forEach((method) => {
servers.forEach((server) => {
if (server["url"]) {
servers.forEach(async (server) => {
const host = server["url"];
if (host) {
const methodEnum = method.toUpperCase() as RestMethod;
const apiEndpoint = new ApiEndpoint();
apiEndpoint.path = path;
apiEndpoint.method = methodEnum;
apiEndpoint.host = server["url"];
const existingEndpoint = await apiEndpointRepository.findOneBy({ path, method: methodEnum, host});
if (!existingEndpoint) {
const apiEndpoint = new ApiEndpoint();
apiEndpoint.path = path;
apiEndpoint.method = methodEnum;
apiEndpoint.host = host;
apiEndpoint.openapiSpecName = fileName;
await apiEndpointRepository.save(apiEndpoint);
}
}
});
});
});
console.log(hosts);
await openApiSpecRepository.save(existingSpec);
}
}

0 comments on commit 46953e1

Please sign in to comment.