Refactoring
This commit is contained in:
parent
11ca9cdb5e
commit
7ff6165882
22 changed files with 172 additions and 327 deletions
3
server/.vscode/settings.json
vendored
Normal file
3
server/.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"cSpell.words": ["fileupload", "Metadatas", "readir"]
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import express from "express";
|
||||
import { Routes } from "../interfaces/router";
|
||||
import cors from "cors";
|
||||
import fileUpload from "express-fileupload";
|
||||
import { Routes } from "../interfaces/router";
|
||||
import { Server } from "socket.io";
|
||||
import { createServer } from "http";
|
||||
import { SocketSubscriber } from "./socket_controller";
|
||||
import { dirname } from "path";
|
||||
import fileUpload from "express-fileupload";
|
||||
import { SetLastActivePipelineToRealTimeServiceScenario } from "../scenarios/set_active_pipeline_to_realtime_service_scenario";
|
||||
import { CheckAndCreateStaticFilesFolderUseCase } from "../usecases/check_and_create_static_files_folder_usecase";
|
||||
import { DataBaseConnectUseCase } from "../usecases/database_connect_usecase";
|
||||
|
@ -13,7 +13,7 @@ import { TypedEvent } from "../helpers/typed_event";
|
|||
|
||||
export enum ServerStatus {
|
||||
init = "init",
|
||||
finished = "finshed",
|
||||
finished = "finished",
|
||||
error = "error",
|
||||
}
|
||||
export enum Environment {
|
||||
|
|
8
server/src/core/extensions/buffer.ts
Normal file
8
server/src/core/extensions/buffer.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export const BufferExtensions = () => {
|
||||
if (Buffer.joinBuffers === undefined) {
|
||||
Buffer.prototype.joinBuffers = function (buffers: Array<Buffer>, delimiter = " ") {
|
||||
const d = Buffer.from(delimiter);
|
||||
return buffers.reduce((prev, b) => Buffer.concat([prev, d, b]));
|
||||
};
|
||||
}
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
import { ArrayExtensions } from "./array";
|
||||
import { BufferExtensions } from "./buffer";
|
||||
import { StringExtensions } from "./string";
|
||||
|
||||
declare global {
|
||||
|
@ -10,6 +11,9 @@ declare global {
|
|||
isEmpty(): boolean;
|
||||
isNotEmpty(): boolean;
|
||||
}
|
||||
interface BufferConstructor {
|
||||
joinBuffers(buffers: Array<Buffer>, delimiter?: string);
|
||||
}
|
||||
interface String {
|
||||
isEmpty(): boolean;
|
||||
isNotEmpty(): boolean;
|
||||
|
@ -21,4 +25,5 @@ declare global {
|
|||
export const extensions = () => {
|
||||
ArrayExtensions();
|
||||
StringExtensions();
|
||||
BufferExtensions();
|
||||
};
|
||||
|
|
|
@ -8,8 +8,19 @@ export interface Disposable {
|
|||
|
||||
export class TypedEvent<T> {
|
||||
private listeners: Listener<T>[] = [];
|
||||
|
||||
public listenersOnces: Listener<T>[] = [];
|
||||
|
||||
waitedEvent(predicate: (e: T) => boolean) {
|
||||
return new Promise<T>((resolve, _reject) => {
|
||||
this.on((e) => {
|
||||
const isContinueWatching = predicate(e);
|
||||
if (!isContinueWatching) {
|
||||
resolve(e);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
on = (listener: Listener<T>): Disposable => {
|
||||
this.listeners.push(listener);
|
||||
return {
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// export class Payload<T>{
|
||||
// model: T | undefined
|
||||
// query:string | undefined
|
||||
// setModel(model:T){
|
||||
// this.model = model
|
||||
// }
|
||||
// setQuery(query:string){
|
||||
// this.query = query
|
||||
// }
|
||||
// isEmpty(){
|
||||
// return this.model != undefined || this.query != undefined
|
||||
// }
|
||||
// }
|
43
server/src/core/repository/file_system_repository.ts
Normal file
43
server/src/core/repository/file_system_repository.ts
Normal file
|
@ -0,0 +1,43 @@
|
|||
import * as fs from "fs";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
export class FileSystemRepository {
|
||||
public createDir = promisify(fs.mkdir);
|
||||
public lsStat = promisify(fs.lstat);
|
||||
public writeFileAsync = promisify(fs.writeFile);
|
||||
public dirIsExists = promisify(fs.exists);
|
||||
public stat = promisify(fs.stat);
|
||||
public readFileAsync = promisify(fs.readFile);
|
||||
public readdir = promisify(fs.readdir);
|
||||
|
||||
async readFileAtBuffer(path: string): Promise<Buffer> {
|
||||
if ((await this.lsStat(path)).isDirectory()) {
|
||||
return (
|
||||
await this.readdir(path, {
|
||||
encoding: "buffer",
|
||||
})
|
||||
).reduce((accumulator, currentValue) => Buffer.joinBuffers([accumulator, currentValue]), Buffer.from(""));
|
||||
}
|
||||
return await this.readFileAsync(path);
|
||||
}
|
||||
|
||||
readDirRecursive(path: string, filesToDir: string[] = []): string[] {
|
||||
const files = fs.readdirSync(path);
|
||||
files.forEach((file) => {
|
||||
let filePath = "";
|
||||
if (path[path.length - 1] !== "/") {
|
||||
filePath = `${path}/${file}`;
|
||||
} else {
|
||||
filePath = `${path}${file}`;
|
||||
}
|
||||
|
||||
const stats = fs.statSync(filePath);
|
||||
if (stats.isDirectory()) {
|
||||
this.readDirRecursive(filePath, filesToDir);
|
||||
} else {
|
||||
filesToDir.push(file);
|
||||
}
|
||||
});
|
||||
return filesToDir;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
import * as fs from "fs";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
export const readFileAsync = promisify(fs.readFile);
|
||||
export const readdir = promisify(fs.readdir);
|
||||
export const stat = promisify(fs.stat);
|
||||
export const lsStat = promisify(fs.lstat);
|
||||
export const createDir = promisify(fs.mkdir);
|
||||
export const dirIsExists = promisify(fs.exists);
|
||||
|
||||
export const writeFileAsync = promisify(fs.writeFile);
|
||||
|
||||
export function readDirRecursive(path: string, filesToDir: string[] = []) {
|
||||
const files = fs.readdirSync(path);
|
||||
files.forEach((file) => {
|
||||
let filePath = "";
|
||||
if (path[path.length - 1] !== "/") {
|
||||
filePath = `${path}/${file}`;
|
||||
} else {
|
||||
filePath = `${path}${file}`;
|
||||
}
|
||||
|
||||
const stats = fs.statSync(filePath);
|
||||
if (stats.isDirectory()) {
|
||||
readDirRecursive(filePath, filesToDir);
|
||||
} else {
|
||||
filesToDir.push(file);
|
||||
}
|
||||
});
|
||||
return filesToDir;
|
||||
}
|
|
@ -27,7 +27,7 @@ export class ExecutorProgramService
|
|||
|
||||
private async workerExecuted(command: string, workerType: WorkerType, args: Array<string> | undefined = undefined) {
|
||||
cluster.setupPrimary({
|
||||
exec: "/Users/idontsudo/Desktop/testdeck-mocha-seed/server/build/src/core/helpers/worker_computed.js",
|
||||
exec: __dirname + "/../helpers/worker_computed.js",
|
||||
});
|
||||
|
||||
const worker = cluster.fork();
|
||||
|
@ -45,17 +45,21 @@ export class ExecutorProgramService
|
|||
worker.send(workerDataExec);
|
||||
worker.on("message", (e) => {
|
||||
const spawnError = SpawnError.isError(e);
|
||||
|
||||
if (spawnError instanceof SpawnError) {
|
||||
this.emit(Result.error(spawnError));
|
||||
return;
|
||||
}
|
||||
|
||||
const executorResult = ExecutorResult.isExecutorResult(e);
|
||||
|
||||
if (executorResult instanceof ExecutorResult) {
|
||||
this.emit(Result.ok(executorResult));
|
||||
return;
|
||||
}
|
||||
|
||||
const execError = ExecError.isExecError(e);
|
||||
|
||||
if (execError instanceof ExecError) {
|
||||
this.emit(Result.error(execError));
|
||||
return;
|
||||
|
@ -78,6 +82,7 @@ export class ExecutorProgramService
|
|||
return;
|
||||
}
|
||||
this.workerExecuted(command, WorkerType.SPAWN, args);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,23 +5,7 @@ import { BinaryLike } from "crypto";
|
|||
import { EventsFileChanger, MetaDataFileManagerModel } from "../models/meta_data_file_manager_model";
|
||||
import { Result } from "../helpers/result";
|
||||
import { TypedEvent } from "../helpers/typed_event";
|
||||
import { lsStat, readFileAsync, readdir, stat } from "../repository/fs";
|
||||
|
||||
function joinBuffers(buffers: Array<Buffer>, delimiter = " ") {
|
||||
const d = Buffer.from(delimiter);
|
||||
return buffers.reduce((prev, b) => Buffer.concat([prev, d, b]));
|
||||
}
|
||||
|
||||
async function readFileAtBuffer(path: string): Promise<Buffer> {
|
||||
if ((await lsStat(path)).isDirectory()) {
|
||||
return (
|
||||
await readdir(path, {
|
||||
encoding: "buffer",
|
||||
})
|
||||
).reduce((accumulator, currentValue) => joinBuffers([accumulator, currentValue]), Buffer.from(""));
|
||||
}
|
||||
return await readFileAsync(path);
|
||||
}
|
||||
import { FileSystemRepository } from "../repository/file_system_repository";
|
||||
|
||||
function md5(content: Buffer | BinaryLike): Promise<string> {
|
||||
return new Promise((resolve, _reject) => {
|
||||
|
@ -41,12 +25,14 @@ export class FilesChangeNotifierService
|
|||
extends TypedEvent<Result<Error, IHashesCache>>
|
||||
implements IFilesChangeNotifierService
|
||||
{
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
watcher!: fs.FSWatcher;
|
||||
directory: string;
|
||||
constructor(directory: string) {
|
||||
super();
|
||||
this.directory = directory;
|
||||
this.init();
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
hashes: IHashesCache = {};
|
||||
async init() {
|
||||
|
@ -56,18 +42,18 @@ export class FilesChangeNotifierService
|
|||
}
|
||||
}
|
||||
async setHash(file: string) {
|
||||
const data = await readFileAsync(file);
|
||||
const data = await this.fileSystemRepository.readFileAsync(file);
|
||||
const md5Current = await md5(data);
|
||||
|
||||
this.hashes[file] = new MetaDataFileManagerModel(file, md5Current, EventsFileChanger.static);
|
||||
this.emit(Result.ok(this.hashes));
|
||||
}
|
||||
async getFiles(dir: string): Promise<string | any[]> {
|
||||
const subdirs = await readdir(dir);
|
||||
const subdirs = await new FileSystemRepository().readdir(dir);
|
||||
const files = await Promise.all(
|
||||
subdirs.map(async (subdir) => {
|
||||
const res = resolve(dir, subdir);
|
||||
return (await stat(res)).isDirectory() ? this.getFiles(res) : res;
|
||||
return (await this.fileSystemRepository.stat(res)).isDirectory() ? this.getFiles(res) : res;
|
||||
})
|
||||
);
|
||||
return files.reduce((a: string | any[], f: any) => a.concat(f), []);
|
||||
|
@ -85,7 +71,7 @@ export class FilesChangeNotifierService
|
|||
fsWait = false;
|
||||
}, 100);
|
||||
try {
|
||||
const file = await readFileAtBuffer(filePath);
|
||||
const file = await this.fileSystemRepository.readFileAtBuffer(filePath);
|
||||
const md5Current = await md5(file);
|
||||
if (md5Current === md5Previous) {
|
||||
return;
|
||||
|
|
|
@ -45,71 +45,55 @@ export class StackService extends TypedEvent<Iteration[]> implements IStackServi
|
|||
return processMetaData;
|
||||
}
|
||||
public async call() {
|
||||
let inc = 0;
|
||||
|
||||
for await (const el of this.callStack!) {
|
||||
await this.execStack(inc, el);
|
||||
inc += 1;
|
||||
this.callStack.map(async (el, index) => {
|
||||
await this.execStack(index, el);
|
||||
this.emit(this.callStack);
|
||||
}
|
||||
});
|
||||
}
|
||||
async execStack(stackNumber: number, stackLayer: Iteration): Promise<void | boolean> {
|
||||
const executorService = new ExecutorProgramService(this.path);
|
||||
executorService.call(stackLayer.process.process.type, stackLayer.process.process.command);
|
||||
|
||||
executorService.on((e) => {
|
||||
console.log(e);
|
||||
});
|
||||
const filesChangeNotifierService = new FilesChangeNotifierService(this.path);
|
||||
|
||||
filesChangeNotifierService.call();
|
||||
const result = await this.waitEvent<Result<ExecError | SpawnError, ExecutorResult>>(executorService);
|
||||
await delay(100);
|
||||
if (result.isSuccess()) {
|
||||
this.callStack[stackNumber].result = result.value;
|
||||
this.callStack[stackNumber].hashes = filesChangeNotifierService.hashes;
|
||||
|
||||
const triggerResult = await this.triggerExec(stackLayer.process.trigger, stackNumber);
|
||||
triggerResult.fold(
|
||||
(s) => {
|
||||
s;
|
||||
},
|
||||
(e) => {
|
||||
e;
|
||||
const result = await executorService.waitedEvent((event: Result<ExecError | SpawnError, ExecutorResult>) => {
|
||||
event.map((value) => {
|
||||
if (value.event === EXEC_EVENT.END) {
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
await delay(100);
|
||||
result.map(async (el) => {
|
||||
this.callStack.at(stackNumber).result = el;
|
||||
this.callStack.at(stackNumber).hashes = filesChangeNotifierService.hashes;
|
||||
(await this.triggerExec(stackLayer.process.trigger, stackNumber)).map(() => {
|
||||
filesChangeNotifierService.cancel();
|
||||
});
|
||||
});
|
||||
|
||||
filesChangeNotifierService.cancel();
|
||||
return;
|
||||
}
|
||||
public waitEvent<T>(stream: TypedEvent<T>): Promise<T> {
|
||||
const promise = new Promise<T>((resolve, reject) => {
|
||||
const addListener = () => {
|
||||
stream.on((e) => {
|
||||
const event = e as Result<ExecError | SpawnError, ExecutorResult>;
|
||||
event.fold(
|
||||
(s) => {
|
||||
if (s.event === EXEC_EVENT.END) {
|
||||
resolve(e);
|
||||
}
|
||||
},
|
||||
(e) => {
|
||||
reject(e);
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
addListener();
|
||||
});
|
||||
return promise;
|
||||
}
|
||||
private async triggerExec(trigger: Trigger | null, stackNumber: number): Promise<Result<boolean, boolean>> {
|
||||
if (trigger !== null) {
|
||||
const hashes = this.callStack[stackNumber].hashes;
|
||||
|
||||
if (hashes != null) {
|
||||
return await new TriggerService(trigger, hashes, this.path).call();
|
||||
private async triggerExec(trigger: Trigger | null, stackNumber: number): Promise<Result<Error, void>> {
|
||||
try {
|
||||
if (trigger !== null) {
|
||||
const hashes = this.callStack[stackNumber].hashes;
|
||||
|
||||
if (hashes != null) {
|
||||
await new TriggerService(trigger, hashes, this.path).call();
|
||||
}
|
||||
throw new Error("Hashes is null");
|
||||
}
|
||||
throw new Error("Hashes is null");
|
||||
return Result.ok();
|
||||
} catch (error) {
|
||||
return Result.error(error);
|
||||
}
|
||||
return Result.ok();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
import { App } from "../controllers/app";
|
||||
import { dirIsExists } from "../repository/fs";
|
||||
import { FileSystemRepository } from "../repository/file_system_repository";
|
||||
import { CreateFolderUseCase } from "./crete_folder_usecase";
|
||||
|
||||
export class CheckAndCreateStaticFilesFolderUseCase {
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
|
||||
constructor() {
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
call = async (): Promise<void> => {
|
||||
if (await dirIsExists(App.staticFilesStoreDir())) {
|
||||
if (await this.fileSystemRepository.dirIsExists(App.staticFilesStoreDir())) {
|
||||
return;
|
||||
}
|
||||
const createFolderUseCase = await new CreateFolderUseCase().call(App.staticFilesStoreDir());
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import { Result } from "../helpers/result";
|
||||
import { writeFileAsync } from "../repository/fs";
|
||||
import { FileSystemRepository } from "../repository/file_system_repository";
|
||||
|
||||
export class CreateFileUseCase {
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
constructor() {
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
async call(path: string, buffer: Buffer): Promise<Result<Error, void>> {
|
||||
try {
|
||||
await writeFileAsync(path, buffer);
|
||||
await this.fileSystemRepository.writeFileAsync(path, buffer);
|
||||
return Result.ok();
|
||||
} catch (err) {
|
||||
return Result.error(err as Error);
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import { Result } from "../helpers/result";
|
||||
import { dirIsExists, createDir } from "../repository/fs";
|
||||
import { FileSystemRepository } from "../repository/file_system_repository";
|
||||
|
||||
export class CreateFolderUseCase {
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
constructor() {
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
call = async (path: string): Promise<Result<Error, string>> => {
|
||||
try {
|
||||
if (await dirIsExists(path)) {
|
||||
if (await this.fileSystemRepository.dirIsExists(path)) {
|
||||
return Result.error(new Error("createFolderUseCase create dir "));
|
||||
}
|
||||
await createDir(path);
|
||||
await this.fileSystemRepository.createDir(path);
|
||||
|
||||
return Result.ok("ok");
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
import { IsMongoId, IsEnum } from "class-validator";
|
||||
import { Schema, model } from "mongoose";
|
||||
import { TriggerModel, triggerSchema } from "../triggers/trigger_model";
|
||||
import { schemaProcess } from "../process/process_model";
|
||||
import { StackGenerateType } from "../../core/models/process_model";
|
||||
|
||||
export const PipelineSchema = new Schema({
|
||||
process: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: schemaProcess,
|
||||
autopopulate: true,
|
||||
default: null,
|
||||
},
|
||||
trigger: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: triggerSchema,
|
||||
autopopulate: true,
|
||||
default: null,
|
||||
},
|
||||
command: {
|
||||
type: String,
|
||||
},
|
||||
}).plugin(require("mongoose-autopopulate"));
|
||||
|
||||
export const schemaPipeline = "Pipeline";
|
||||
|
||||
export const PipelineDBModel = model<PipelineModel>(schemaPipeline, PipelineSchema);
|
||||
|
||||
export class PipelineModel {
|
||||
@IsMongoId()
|
||||
public process: PipelineModel;
|
||||
|
||||
@IsMongoId()
|
||||
//TODO(IDONTSUDO):NEED OPTION DECORATOR??
|
||||
public trigger: TriggerModel;
|
||||
|
||||
public env = null;
|
||||
|
||||
@IsEnum(StackGenerateType)
|
||||
public stackGenerateType: StackGenerateType;
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
import { IsString, IsOptional, IsEnum, IsNumber, IsBoolean } from "class-validator";
|
||||
import { Schema, model } from "mongoose";
|
||||
import { IProcess, IssueType } from "../../core/models/process_model";
|
||||
import { EXEC_TYPE } from "../../core/models/exec_error_model";
|
||||
|
||||
export const ProcessSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
command: {
|
||||
type: String,
|
||||
},
|
||||
isGenerating: {
|
||||
type: String,
|
||||
},
|
||||
isLocaleCode: {
|
||||
type: String,
|
||||
},
|
||||
issueType: {
|
||||
type: String,
|
||||
},
|
||||
timeout: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
commit: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
export const schemaProcess = "Process";
|
||||
|
||||
export const ProcessDBModel = model<IProcess>(schemaProcess, ProcessSchema);
|
||||
|
||||
export class ProcessModel implements IProcess {
|
||||
@IsEnum(EXEC_TYPE)
|
||||
public type: EXEC_TYPE;
|
||||
|
||||
@IsString()
|
||||
public command: string;
|
||||
|
||||
@IsBoolean()
|
||||
public isGenerating: boolean;
|
||||
|
||||
@IsBoolean()
|
||||
public isLocaleCode: boolean;
|
||||
|
||||
@IsEnum(IssueType)
|
||||
public issueType: IssueType;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
public timeout?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
public commit?: string;
|
||||
}
|
|
@ -16,12 +16,10 @@ export class ProjectInstancePresentation extends CrudController<
|
|||
});
|
||||
super.post(new CreateNewProjectInstanceScenario().call);
|
||||
|
||||
super.subRoutes = [
|
||||
{
|
||||
method: "POST",
|
||||
subUrl: "upload",
|
||||
fn: new UploadCadFileToProjectScenario(),
|
||||
},
|
||||
];
|
||||
this.subRoutes.push({
|
||||
method: "POST",
|
||||
subUrl: "upload",
|
||||
fn: new UploadCadFileToProjectScenario(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
import { Schema, model } from "mongoose";
|
||||
import { PipelineModel, schemaPipeline } from "../pipelines/pipeline_model";
|
||||
import { IsMongoId, IsString } from "class-validator";
|
||||
|
||||
export interface IProjectModel {
|
||||
pipelines: [PipelineModel];
|
||||
rootDir: string;
|
||||
}
|
||||
|
||||
export const ProjectSchema = new Schema({
|
||||
pipelines: {
|
||||
type: Array<Schema.Types.ObjectId>,
|
||||
ref: schemaPipeline,
|
||||
autopopulate: true,
|
||||
default: null,
|
||||
},
|
||||
rootDir: {
|
||||
type: String,
|
||||
},
|
||||
}).plugin(require("mongoose-autopopulate"));
|
||||
|
||||
const schema = "Projects";
|
||||
|
||||
export const ProjectDBModel = model<IProjectModel>(schema, ProjectSchema);
|
||||
|
||||
export class ProjectModel implements IProjectModel {
|
||||
@IsMongoId()
|
||||
pipelines: [PipelineModel];
|
||||
@IsString()
|
||||
rootDir: string;
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
import { IsArray, IsOptional, IsEnum} from "class-validator";
|
||||
import { Schema, model } from "mongoose";
|
||||
|
||||
export interface ITriggerModel {
|
||||
_id?: string;
|
||||
type: string;
|
||||
value: string[];
|
||||
}
|
||||
|
||||
export const TriggerSchema = new Schema({
|
||||
type: {
|
||||
type: String,
|
||||
require: true,
|
||||
},
|
||||
value: {
|
||||
type: Array,
|
||||
require: true,
|
||||
},
|
||||
});
|
||||
|
||||
export const triggerSchema = "Trigger";
|
||||
|
||||
export const TriggerDBModel = model<ITriggerModel>(triggerSchema, TriggerSchema);
|
||||
|
||||
export enum TriggerType {
|
||||
PROCESS = "PROCESS",
|
||||
FILE = "FILE",
|
||||
}
|
||||
|
||||
export class TriggerModel implements ITriggerModel {
|
||||
@IsOptional()
|
||||
public _id: string;
|
||||
@IsEnum(TriggerType)
|
||||
public type: TriggerType;
|
||||
@IsArray()
|
||||
public value: string[];
|
||||
}
|
||||
|
||||
export interface Trigger {
|
||||
type: TriggerType;
|
||||
value: string[];
|
||||
}
|
||||
|
|
@ -1,13 +1,14 @@
|
|||
import { CrudController } from "../../core/controllers/crud_controller";
|
||||
import { TriggerDBModel } from "./models/trigger_database_model";
|
||||
import { TriggerModelValidationModel as TriggerValidationMode } from "./models/trigger_validation_model";
|
||||
import { TriggerModelValidationModel } from "./models/trigger_validation_model";
|
||||
|
||||
export class TriggerPresentation extends CrudController<TriggerValidationMode, typeof TriggerDBModel> {
|
||||
export class TriggerPresentation extends CrudController<TriggerModelValidationModel, typeof TriggerDBModel> {
|
||||
constructor() {
|
||||
super({
|
||||
url: "trigger",
|
||||
validationModel: TriggerValidationMode,
|
||||
validationModel: TriggerModelValidationModel,
|
||||
databaseModel: TriggerDBModel,
|
||||
});
|
||||
}
|
||||
}
|
||||
"".isEmpty();
|
||||
|
|
|
@ -3,19 +3,23 @@ import { StackService } from "../../src/core/services/stack_service";
|
|||
import { delay } from "../../src/core/helpers/delay";
|
||||
import { assert, dirname__ } from "../test";
|
||||
import { mockSimplePipeline } from "../model/mock_pipelines";
|
||||
import { readDirRecursive } from "../../src/core/repository/fs";
|
||||
import { FileSystemRepository } from "../../src/core/repository/file_system_repository";
|
||||
import { CreateFolderUseCase } from "../../src/core/usecases/crete_folder_usecase";
|
||||
|
||||
abstract class IStackServiceTest {
|
||||
abstract test(): Promise<boolean>;
|
||||
}
|
||||
|
||||
class SimpleTestStackServiceTest extends StackService implements IStackServiceTest {
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
constructor() {
|
||||
super(mockSimplePipeline, dirname__ + "/context/");
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
async test(): Promise<boolean> {
|
||||
await this.call();
|
||||
const testResult = readDirRecursive(this.path).equals(["1.txt", "test.txt"], true);
|
||||
console.log(this.path);
|
||||
const testResult = this.fileSystemRepository.readDirRecursive(this.path).equals(["1.txt", "test.txt"], true);
|
||||
await delay(100);
|
||||
rmSync(this.path + "example/", { recursive: true });
|
||||
return testResult;
|
||||
|
@ -24,12 +28,15 @@ class SimpleTestStackServiceTest extends StackService implements IStackServiceTe
|
|||
|
||||
export class StackServiceTest {
|
||||
dirName: string;
|
||||
|
||||
fileSystemRepository: FileSystemRepository;
|
||||
constructor(dirName: string) {
|
||||
this.dirName = dirName;
|
||||
this.fileSystemRepository = new FileSystemRepository();
|
||||
}
|
||||
public async test() {
|
||||
const tests = [new SimpleTestStackServiceTest()];
|
||||
await new CreateFolderUseCase().call(this.dirName + "/context/");
|
||||
|
||||
for await (const el of tests) {
|
||||
assert((await el.test()) === true, el.constructor.name);
|
||||
await delay(3000);
|
||||
|
|
|
@ -37,24 +37,23 @@ const init = async () => {
|
|||
|
||||
const unitTest = async () => {
|
||||
await init();
|
||||
await new ExecutorProgramServiceTest(dirname__).test();
|
||||
await new FilesChangerTest(dirname__).test();
|
||||
await new StackServiceTest(dirname__ + "/context/").test();
|
||||
await new TriggerServiceTest().test();
|
||||
await new CreateDataBaseModelUseCaseTest().test();
|
||||
await new CreateDataBaseModelUseCaseTest().test();
|
||||
await new DeleteDataBaseModelUseCaseTest().test();
|
||||
await new ReadDataBaseModelUseCaseTest().test();
|
||||
await new UpdateDataBaseModelUseCaseTest().test();
|
||||
// await new PipelineRealTimeServiceTest().test()
|
||||
for await (const usecase of tests) {
|
||||
testCore.assert(await new usecase().test(), usecase.name);
|
||||
}
|
||||
// await new ExecutorProgramServiceTest(dirname__).test();
|
||||
// await new FilesChangerTest(dirname__).test();
|
||||
await new StackServiceTest(dirname__).test();
|
||||
// await new TriggerServiceTest().test();
|
||||
// await new CreateDataBaseModelUseCaseTest().test();
|
||||
// await new CreateDataBaseModelUseCaseTest().test();
|
||||
// await new DeleteDataBaseModelUseCaseTest().test();
|
||||
// await new ReadDataBaseModelUseCaseTest().test();
|
||||
// await new UpdateDataBaseModelUseCaseTest().test();
|
||||
|
||||
// for await (const usecase of tests) {
|
||||
// testCore.assert(await new usecase().test(), usecase.name);
|
||||
// }
|
||||
};
|
||||
const presentationCrudControllers = [new TriggerPresentation()];
|
||||
const e2eTest = async () => {
|
||||
const app = new App(httpRoutes, [], Environment.E2E_TEST);
|
||||
app.listen();
|
||||
await new Promise((resolve, reject) => {
|
||||
app.on(async (e) => {
|
||||
if (e === ServerStatus.finished) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue