formatting code upload project instance to files

This commit is contained in:
IDONTSUDO 2023-11-28 18:34:41 +03:00
parent ce4c98ff13
commit a0b4f00f47
65 changed files with 399 additions and 748 deletions

View file

@ -15,9 +15,6 @@
"*ui": false, "*ui": false,
"*ui.*": false "*ui.*": false
}, },
"cSpell.words": [ "cSpell.words": ["antd", "fileupload", "uuidv"],
"antd", "editor.rulers": [100]
"fileupload", }
"uuidv"
]
}

View file

@ -19,24 +19,16 @@ export class CrudController<V, D> extends CoreHttpController<V> {
} }
init() { init() {
if (this.routes["POST"] === null) { if (this.routes["POST"] === null) {
this.routes["POST"] = new CreateDataBaseModelUseCase<D>( this.routes["POST"] = new CreateDataBaseModelUseCase<D>(this.dataBaseModel).call;
this.dataBaseModel
).call;
} }
if (this.routes["GET"] === null) { if (this.routes["GET"] === null) {
this.routes["GET"] = new PaginationDataBaseModelUseCase<D>( this.routes["GET"] = new PaginationDataBaseModelUseCase<D>(this.dataBaseModel).call;
this.dataBaseModel
).call;
} }
if (this.routes["DELETE"] === null) { if (this.routes["DELETE"] === null) {
this.routes["DELETE"] = new DeleteDataBaseModelUseCase<D>( this.routes["DELETE"] = new DeleteDataBaseModelUseCase<D>(this.dataBaseModel).call;
this.dataBaseModel
).call;
} }
if (this.routes["PUT"] === null) { if (this.routes["PUT"] === null) {
this.routes["PUT"] = new UpdateDataBaseModelUseCase<V, D>( this.routes["PUT"] = new UpdateDataBaseModelUseCase<V, D>(this.dataBaseModel).call;
this.dataBaseModel
).call;
} }
} }
} }

View file

@ -3,15 +3,7 @@ import { Result } from "../helper/result";
import { Router, Request, Response } from "express"; import { Router, Request, Response } from "express";
import { IRouteModel, Routes } from "../interfaces/router"; import { IRouteModel, Routes } from "../interfaces/router";
export type Method = export type Method = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
| "all"
| "get"
| "post"
| "put"
| "delete"
| "patch"
| "options"
| "head";
export type ResponseBase = Promise<Result<any, any>>; export type ResponseBase = Promise<Result<any, any>>;
@ -75,7 +67,7 @@ export class CoreHttpController<V> implements ICoreHttpController {
return; return;
}, },
(err) => { (err) => {
res.status(400).json(err); res.status(400).json({ error: String(err) });
return; return;
} }
); );
@ -83,61 +75,46 @@ export class CoreHttpController<V> implements ICoreHttpController {
call(): Routes { call(): Routes {
if (this.subRoutes.isNotEmpty()) { if (this.subRoutes.isNotEmpty()) {
this.subRoutes.map((el) => { this.subRoutes.map((el) => {
this.router[el.method]( this.router[el.method](this.mainURL + "/" + el.subUrl, async (req, res) => {
this.mainURL + "/" + el.subUrl, if (el.fn instanceof CallbackStrategyWithValidationModel) {
async (req, res) => { // TODO(IDONTSUDO):
if (el.fn instanceof CallbackStrategyWithValidationModel) { throw Error("needs to be implimed");
// TODO(IDONTSUDO): }
throw Error("needs to be implimed"); if (el.fn instanceof CallbackStrategyWithIdQuery) {
} throw Error("needs to be implimed");
if (el.fn instanceof CallbackStrategyWithIdQuery) { }
throw Error("needs to be implimed"); if (el.fn instanceof CallBackStrategyWithQueryPage) {
} throw Error("needs to be implimed");
if (el.fn instanceof CallBackStrategyWithQueryPage) { }
throw Error("needs to be implimed"); if (el.fn instanceof CallbackStrategyWithEmpty) {
} await this.responseHelper(res, el.fn.call());
if (el.fn instanceof CallbackStrategyWithEmpty) { return;
await this.responseHelper(res, el.fn.call()); }
if (el.fn instanceof CallbackStrategyWithFileUpload) {
if (req["files"] === undefined) {
res.status(400).json("need files to form-data request");
return; return;
} }
if (req["files"]["file"] === undefined) {
if (el.fn instanceof CallbackStrategyWithFileUpload) { res.status(400).json("need file to form data request");
if (req["files"] === undefined) { return;
res.status(400).json("need files to form-data request");
return;
}
if (req["files"]["file"] === undefined) {
res.status(400).json("need file to form data request");
return;
}
if (el.fn instanceof CallbackStrategyWithFileUpload) {
if (
!el.fn.checkingFileExpression.test(
req["files"]["file"]["name"]
)
) {
res
.status(400)
.json(
"a file with this extension is expected: " +
String(el.fn.checkingFileExpression)
);
return;
}
}
await this.responseHelper(res, el.fn.call(req["files"]["file"]));
} }
if (el.fn instanceof CallbackStrategyWithFileUpload) {
if (!el.fn.checkingFileExpression.test(req["files"]["file"]["name"])) {
res.status(400).json("a file with this extension is expected: " + String(el.fn.checkingFileExpression));
return;
}
}
await this.responseHelper(res, el.fn.call(req["files"]["file"]));
} }
); });
}); });
} }
if (this.routes["POST"] != null) { if (this.routes["POST"] != null) {
this.router.post( this.router.post(this.mainURL, validationModelMiddleware(this.validationModel), (req, res) =>
this.mainURL, this.requestResponseController<V>(req, res, this.routes["POST"])
validationModelMiddleware(this.validationModel),
(req, res) =>
this.requestResponseController<V>(req, res, this.routes["POST"])
); );
} }
if (this.routes["DELETE"] != null) { if (this.routes["DELETE"] != null) {
@ -146,17 +123,12 @@ export class CoreHttpController<V> implements ICoreHttpController {
); );
} }
if (this.routes["PUT"] != null) { if (this.routes["PUT"] != null) {
this.router.put( this.router.put(this.mainURL, validationModelMiddleware(this.validationModel), (req, res) =>
this.mainURL, this.requestResponseController<V>(req, res, this.routes["PUT"])
validationModelMiddleware(this.validationModel),
(req, res) =>
this.requestResponseController<V>(req, res, this.routes["PUT"])
); );
} }
if (this.routes["GET"] != null) { if (this.routes["GET"] != null) {
this.router.get(this.mainURL, (req, res) => this.router.get(this.mainURL, (req, res) => this.requestResponseController<V>(req, res, this.routes["GET"]));
this.requestResponseController<V>(req, res, this.routes["GET"])
);
} }
return { return {
@ -193,7 +165,7 @@ export class CoreHttpController<V> implements ICoreHttpController {
return; return;
}, },
(err) => { (err) => {
res.status(400).json(err); res.status(400).json({ error: String(err) });
return; return;
} }
); );

View file

@ -8,4 +8,3 @@ export class SocketSubscriber<T> {
this.event = event; this.event = event;
} }
} }

View file

@ -12,6 +12,8 @@ declare global {
interface String { interface String {
isEmpty(): boolean; isEmpty(): boolean;
isNotEmpty(): boolean; isNotEmpty(): boolean;
fixToPath(): string;
lastElement(): string;
} }
} }
export const extensions = () => { export const extensions = () => {

View file

@ -11,4 +11,21 @@ export const StringExtensions = () => {
return this.length !== 0; return this.length !== 0;
}; };
} }
if ("".lastElement === undefined) {
String.prototype.lastElement = function () {
return this[this.length - 1];
};
}
if ("".fixToPath === undefined) {
// eslint-disable-next-line no-extend-native
String.prototype.fixToPath = function () {
// eslint-disable-next-line @typescript-eslint/no-this-alias
let result = this;
const symbolPath = "/";
if (this.lastElement != symbolPath) {
result = result.slice(0, -1);
}
return result;
};
}
}; };

View file

@ -1,3 +1,3 @@
export function delay(ms: number) { export function delay(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms)); return new Promise((resolve) => setTimeout(resolve, ms));
} }

View file

@ -1,7 +1,6 @@
/* eslint-disable @typescript-eslint/ban-types */ /* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */ /* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */
/* eslint-disable @typescript-eslint/no-namespace */ /* eslint-disable @typescript-eslint/no-namespace */
function isAsyncFn(fn: Function) { function isAsyncFn(fn: Function) {
return fn.constructor.name === "AsyncFunction"; return fn.constructor.name === "AsyncFunction";
@ -17,7 +16,6 @@ interface SyncThenable {
then<Fn extends () => any>(cb: Fn): SyncThenable; then<Fn extends () => any>(cb: Fn): SyncThenable;
} }
function syncThenable(): SyncThenable { function syncThenable(): SyncThenable {
function then<Fn extends () => Promise<any>>(cb: Fn): ReturnType<Fn>; function then<Fn extends () => Promise<any>>(cb: Fn): ReturnType<Fn>;
function then<Fn extends () => any>(cb: Fn): SyncThenable; function then<Fn extends () => any>(cb: Fn): SyncThenable;
@ -36,11 +34,7 @@ function syncThenable(): SyncThenable {
}; };
} }
function forEachValueThunkOrPromise<T>( function forEachValueThunkOrPromise<T>(items: unknown[], execFn: (value: T) => boolean, foldFn: () => unknown) {
items: unknown[],
execFn: (value: T) => boolean,
foldFn: () => unknown
) {
let shouldBreak = false; let shouldBreak = false;
const result: any = items.reduce((prev: { then: Function }, valueOrThunk) => { const result: any = items.reduce((prev: { then: Function }, valueOrThunk) => {
@ -56,8 +50,7 @@ function forEachValueThunkOrPromise<T>(
} }
} }
const valueOrPromise = const valueOrPromise = typeof valueOrThunk === "function" ? valueOrThunk() : valueOrThunk;
typeof valueOrThunk === "function" ? valueOrThunk() : valueOrThunk;
if (valueOrPromise instanceof Promise) { if (valueOrPromise instanceof Promise) {
return valueOrPromise.then(run); return valueOrPromise.then(run);
@ -76,11 +69,9 @@ function forEachValueThunkOrPromise<T>(
}); });
} }
export type Result< export type Result<ErrorType, OkType, RollbackFn extends RollbackFunction = any> =
ErrorType, | Ok<ErrorType, OkType, RollbackFn>
OkType, | Err<ErrorType, OkType, RollbackFn>;
RollbackFn extends RollbackFunction = any
> = Ok<ErrorType, OkType, RollbackFn> | Err<ErrorType, OkType, RollbackFn>;
interface IResult<ErrorType, OkType> { interface IResult<ErrorType, OkType> {
isSuccess(): this is Ok<ErrorType, OkType, any>; isSuccess(): this is Ok<ErrorType, OkType, any>;
@ -93,14 +84,8 @@ interface IResult<ErrorType, OkType> {
inspect(): string; inspect(): string;
fold<R>( fold<R>(onSuccess: (value: OkType) => R, onFailure: (error: ErrorType) => R): R;
onSuccess: (value: OkType) => R, fold<R>(onSuccess: (value: OkType) => Promise<R>, onFailure: (error: ErrorType) => Promise<R>): Promise<R>;
onFailure: (error: ErrorType) => R
): R;
fold<R>(
onSuccess: (value: OkType) => Promise<R>,
onFailure: (error: ErrorType) => Promise<R>
): Promise<R>;
getOrDefault(defaultValue: OkType): OkType; getOrDefault(defaultValue: OkType): OkType;
@ -111,37 +96,17 @@ interface IResult<ErrorType, OkType> {
map<T>( map<T>(
fn: (value: OkType) => Promise<T> fn: (value: OkType) => Promise<T>
): Promise< ): Promise<JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>>;
JoinErrorTypes<
ErrorType,
T extends Result<any, any, any> ? T : Result<Error, T, any>
>
>;
map<T>( map<T>(
fn: (value: OkType) => T fn: (value: OkType) => T
): JoinErrorTypes< ): JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>;
ErrorType,
T extends Result<any, any, any> ? T : Result<Error, T, any>
>;
rollback(): Result<Error, void> | Promise<Result<Error, void>>; rollback(): Result<Error, void> | Promise<Result<Error, void>>;
} }
type InferErrorType<T extends Result<any, any, any>> = T extends Result< type InferErrorType<T extends Result<any, any, any>> = T extends Result<infer Errortype, any, any> ? Errortype : never;
infer Errortype,
any,
any
>
? Errortype
: never;
type InferOkType<T extends Result<any, any, any>> = T extends Result< type InferOkType<T extends Result<any, any, any>> = T extends Result<any, infer OkType, any> ? OkType : never;
any,
infer OkType,
any
>
? OkType
: never;
type JoinErrorTypes<ErrorType, B extends Result<any, any, any>> = Result< type JoinErrorTypes<ErrorType, B extends Result<any, any, any>> = Result<
ErrorType | InferErrorType<B>, ErrorType | InferErrorType<B>,
@ -150,15 +115,11 @@ type JoinErrorTypes<ErrorType, B extends Result<any, any, any>> = Result<
>; >;
type ExtractErrorTypes<Tuple extends any[]> = { type ExtractErrorTypes<Tuple extends any[]> = {
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> [Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> ? InferErrorType<Tuple[Index]> : never;
? InferErrorType<Tuple[Index]>
: never;
}[number]; }[number];
type MapResultTupleToOkTypeTuple<Tuple extends any[]> = { type MapResultTupleToOkTypeTuple<Tuple extends any[]> = {
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> [Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> ? InferOkType<Tuple[Index]> : never;
? InferOkType<Tuple[Index]>
: never;
}; };
type RollbackFunction = (() => void) | (() => Promise<void>); type RollbackFunction = (() => void) | (() => Promise<void>);
@ -174,11 +135,7 @@ type HasAsyncRollbackFunction<T extends any[]> = {
: true; : true;
type UnwrapThunks<T extends any[]> = { type UnwrapThunks<T extends any[]> = {
[Index in keyof T]: T[Index] extends () => Promise<infer U> [Index in keyof T]: T[Index] extends () => Promise<infer U> ? U : T[Index] extends () => infer U ? U : T[Index];
? U
: T[Index] extends () => infer U
? U
: T[Index];
}; };
type HasAsyncThunk<T extends any[]> = { type HasAsyncThunk<T extends any[]> = {
@ -187,32 +144,17 @@ type HasAsyncThunk<T extends any[]> = {
? false ? false
: true; : true;
type PromiseReturnType<T extends (...args: any) => any> = T extends ( type PromiseReturnType<T extends (...args: any) => any> = T extends (...args: any) => Promise<infer U> ? U : never;
...args: any
) => Promise<infer U>
? U
: never;
export namespace Result { export namespace Result {
export function ok< export function ok<ErrorType extends unknown, OkType, RollbackFn extends RollbackFunction = any>(
ErrorType extends unknown,
OkType,
RollbackFn extends RollbackFunction = any
>(
value?: OkType, value?: OkType,
rollbackFn?: RollbackFn rollbackFn?: RollbackFn
): Result<ErrorType, OkType, RollbackFn> { ): Result<ErrorType, OkType, RollbackFn> {
return new Ok<ErrorType, OkType, RollbackFn>( return new Ok<ErrorType, OkType, RollbackFn>(value || null!, rollbackFn) as any;
value || null!,
rollbackFn
) as any;
} }
export function error< export function error<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction = any>(
ErrorType extends unknown,
OkType extends unknown,
RollbackFn extends RollbackFunction = any
>(
error: ErrorType, error: ErrorType,
rollbackFn?: RollbackFn rollbackFn?: RollbackFn
): Result<ErrorType, OkType, RollbackFn> { ): Result<ErrorType, OkType, RollbackFn> {
@ -223,9 +165,7 @@ export namespace Result {
? Result<E | InferErrorType<T>, InferOkType<T>, never> ? Result<E | InferErrorType<T>, InferOkType<T>, never>
: Result<E, T, never>; : Result<E, T, never>;
export function safe<T>( export function safe<T>(fn: () => Promise<T>): Promise<SafeReturnType<Error, T>>;
fn: () => Promise<T>
): Promise<SafeReturnType<Error, T>>;
export function safe<T>(fn: () => T): SafeReturnType<Error, T>; export function safe<T>(fn: () => T): SafeReturnType<Error, T>;
export function safe<ErrorType, T>( export function safe<ErrorType, T>(
err: ErrorType | (new (...args: any[]) => ErrorType), err: ErrorType | (new (...args: any[]) => ErrorType),
@ -263,29 +203,21 @@ export namespace Result {
.catch((caughtError) => error(getError(caughtError))); .catch((caughtError) => error(getError(caughtError)));
} }
return isResult(resultOrPromise) return isResult(resultOrPromise) ? resultOrPromise : Result.ok(resultOrPromise);
? resultOrPromise
: Result.ok(resultOrPromise);
} catch (caughtError) { } catch (caughtError) {
return error(getError(caughtError as Error)); return error(getError(caughtError as Error));
} }
} }
type CombineResult< type CombineResult<T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]> = Result<
T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]
> = Result<
ExtractErrorTypes<UnwrapThunks<T>>, ExtractErrorTypes<UnwrapThunks<T>>,
MapResultTupleToOkTypeTuple<UnwrapThunks<T>>, MapResultTupleToOkTypeTuple<UnwrapThunks<T>>,
HasAsyncRollbackFunction<T> extends true ? () => Promise<void> : () => void HasAsyncRollbackFunction<T> extends true ? () => Promise<void> : () => void
>; >;
export function combine< export function combine<T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]>(
T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]
>(
...items: T ...items: T
): HasAsyncThunk<T> extends true ): HasAsyncThunk<T> extends true ? Promise<CombineResult<T>> : CombineResult<T> {
? Promise<CombineResult<T>>
: CombineResult<T> {
if (!items.length) { if (!items.length) {
throw new Error("Expected at least 1 argument"); throw new Error("Expected at least 1 argument");
} }
@ -332,9 +264,7 @@ export namespace Result {
export function wrap<Fn extends (...args: any) => Promise<any>>( export function wrap<Fn extends (...args: any) => Promise<any>>(
fn: Fn fn: Fn
): ( ): (...args: Parameters<Fn>) => Promise<Result<Error, PromiseReturnType<Fn>, never>>;
...args: Parameters<Fn>
) => Promise<Result<Error, PromiseReturnType<Fn>, never>>;
export function wrap<Fn extends (...args: any) => any>( export function wrap<Fn extends (...args: any) => any>(
fn: Fn fn: Fn
): (...args: Parameters<Fn>) => Result<Error, ReturnType<Fn>, never>; ): (...args: Parameters<Fn>) => Result<Error, ReturnType<Fn>, never>;
@ -344,9 +274,7 @@ export namespace Result {
const resultOrPromise = fn(...args); const resultOrPromise = fn(...args);
if (resultOrPromise instanceof Promise) { if (resultOrPromise instanceof Promise) {
return resultOrPromise return resultOrPromise.then((okValue) => Result.ok(okValue)).catch((err) => error(err));
.then((okValue) => Result.ok(okValue))
.catch((err) => error(err));
} }
return ok(resultOrPromise); return ok(resultOrPromise);
@ -357,11 +285,8 @@ export namespace Result {
} }
} }
abstract class Base< abstract class Base<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction>
ErrorType extends unknown, implements IResult<ErrorType, OkType>
OkType extends unknown,
RollbackFn extends RollbackFunction
> implements IResult<ErrorType, OkType>
{ {
constructor(protected readonly rollbackFn?: RollbackFn) {} constructor(protected readonly rollbackFn?: RollbackFn) {}
@ -388,14 +313,8 @@ abstract class Base<
return this.toString(); return this.toString();
} }
fold<R>( fold<R>(onSuccess: (value: OkType) => R, onFailure: (error: ErrorType) => R): R;
onSuccess: (value: OkType) => R, fold<R>(onSuccess: (value: OkType) => Promise<R>, onFailure: (error: ErrorType) => Promise<R>): Promise<R>;
onFailure: (error: ErrorType) => R
): R;
fold<R>(
onSuccess: (value: OkType) => Promise<R>,
onFailure: (error: ErrorType) => Promise<R>
): Promise<R>;
fold(onSuccess: any, onFailure: any) { fold(onSuccess: any, onFailure: any) {
if (this.isFailure()) { if (this.isFailure()) {
return onFailure(this.error); return onFailure(this.error);
@ -439,18 +358,10 @@ abstract class Base<
map<T>( map<T>(
fn: (value: OkType) => Promise<T> fn: (value: OkType) => Promise<T>
): Promise< ): Promise<JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>>;
JoinErrorTypes<
ErrorType,
T extends Result<any, any, any> ? T : Result<Error, T, any>
>
>;
map<T>( map<T>(
fn: (value: OkType) => T fn: (value: OkType) => T
): JoinErrorTypes< ): JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>;
ErrorType,
T extends Result<any, any, any> ? T : Result<Error, T, any>
>;
map(fn: any) { map(fn: any) {
if (this.isFailure()) { if (this.isFailure()) {
return isAsyncFn(fn) ? Promise.resolve(this) : this; return isAsyncFn(fn) ? Promise.resolve(this) : this;
@ -474,11 +385,11 @@ abstract class Base<
} }
} }
class Ok< class Ok<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction> extends Base<
ErrorType extends unknown, ErrorType,
OkType extends unknown, OkType,
RollbackFn extends RollbackFunction RollbackFn
> extends Base<ErrorType, OkType, RollbackFn> { > {
public readonly value: OkType; public readonly value: OkType;
constructor(val: OkType, rollbackFn?: RollbackFn) { constructor(val: OkType, rollbackFn?: RollbackFn) {
@ -503,11 +414,11 @@ class Ok<
} }
} }
class Err< class Err<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction> extends Base<
ErrorType extends unknown, ErrorType,
OkType extends unknown, OkType,
RollbackFn extends RollbackFunction RollbackFn
> extends Base<ErrorType, OkType, RollbackFn> { > {
public readonly error: ErrorType; public readonly error: ErrorType;
constructor(err: ErrorType, rollbackFn?: RollbackFn) { constructor(err: ErrorType, rollbackFn?: RollbackFn) {

View file

@ -1,49 +1,42 @@
export interface Listener<T> { export interface Listener<T> {
(event: T): any; (event: T): any;
} }
export interface Disposable { export interface Disposable {
dispose():void; dispose(): void;
} }
export class TypedEvent<T> { export class TypedEvent<T> {
private listeners: Listener<T>[] = []; private listeners: Listener<T>[] = [];
public listenersOnces: Listener<T>[] = []; public listenersOnces: Listener<T>[] = [];
on = (listener: Listener<T>): Disposable => { on = (listener: Listener<T>): Disposable => {
this.listeners.push(listener); this.listeners.push(listener);
return { return {
dispose: () => this.off(listener), dispose: () => this.off(listener),
};
}; };
};
once = (listener: Listener<T>): void => { once = (listener: Listener<T>): void => {
this.listenersOnces.push(listener); this.listenersOnces.push(listener);
}; };
off = (listener: Listener<T>) => { off = (listener: Listener<T>) => {
const callbackIndex = this.listeners.indexOf( const callbackIndex = this.listeners.indexOf(listener);
listener if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
); };
if (callbackIndex > -1)
this.listeners.splice(callbackIndex, 1);
};
emit = (event: T) => { emit = (event: T) => {
this.listeners.forEach((listener) => listener(event));
this.listeners.forEach((listener) =>
listener(event)
);
if (this.listenersOnces.length > 0) { if (this.listenersOnces.length > 0) {
const toCall = this.listenersOnces; const toCall = this.listenersOnces;
this.listenersOnces = []; this.listenersOnces = [];
toCall.forEach((listener) => listener(event)); toCall.forEach((listener) => listener(event));
} }
}; };
pipe = (te: TypedEvent<T>): Disposable => { pipe = (te: TypedEvent<T>): Disposable => {
return this.on((e) => te.emit(e)); return this.on((e) => te.emit(e));
}; };
} }

View file

@ -11,7 +11,7 @@ export interface WorkerDataExec {
command: string; command: string;
execPath: string; execPath: string;
type: WorkerType; type: WorkerType;
cliArgs:Array<string> | undefined cliArgs: Array<string> | undefined;
} }
process.on("message", async (message) => { process.on("message", async (message) => {
@ -30,15 +30,15 @@ process.on("message", async (message) => {
}); });
} }
}); });
subprocess.on('close', (_code) =>{ subprocess.on("close", (_code) => {
if (process.send) { if (process.send) {
process.send({ process.send({
type: EXEC_TYPE.SPAWN.toString(), type: EXEC_TYPE.SPAWN.toString(),
event: EXEC_EVENT.END.toString(), event: EXEC_EVENT.END.toString(),
data:null data: null,
}); });
} }
}) });
process.on("uncaughtException", (error) => { process.on("uncaughtException", (error) => {
if (process.send) { if (process.send) {
process.send({ process.send({
@ -50,26 +50,21 @@ process.on("message", async (message) => {
}); });
} else if (workerData.type == WorkerType.EXEC) { } else if (workerData.type == WorkerType.EXEC) {
try { try {
const result = await exec(workerData.command, { const result = await exec(workerData.command, {
cwd: workerData.execPath, cwd: workerData.execPath,
}); });
if (process.send) { if (process.send) {
process.send( process.send(new ExecutorResult(EXEC_TYPE.EXEC, EXEC_EVENT.END, result));
new ExecutorResult(EXEC_TYPE.EXEC, EXEC_EVENT.END, result)
);
} }
} catch (error) { } catch (error) {
if (process.send) { if (process.send) {
process.send(new ExecError(workerData.command, error )); process.send(new ExecError(workerData.command, error));
} }
} }
} }
}); });
async function exec( async function exec(cmd: string, opts: cp.ExecOptions & { trim?: boolean } = {}): Promise<string> {
cmd: string,
opts: cp.ExecOptions & { trim?: boolean } = {}
): Promise<string> {
return new Promise((c, e) => { return new Promise((c, e) => {
cp.exec(cmd, { env: process.env, ...opts }, (err, stdout) => { cp.exec(cmd, { env: process.env, ...opts }, (err, stdout) => {
return err ? e(err) : c(opts.trim ? stdout.trim() : stdout); return err ? e(err) : c(opts.trim ? stdout.trim() : stdout);

View file

@ -1,4 +1,3 @@
// export class Payload<T>{ // export class Payload<T>{
// model: T | undefined // model: T | undefined
// query:string | undefined // query:string | undefined
@ -11,4 +10,4 @@
// isEmpty(){ // isEmpty(){
// return this.model != undefined || this.query != undefined // return this.model != undefined || this.query != undefined
// } // }
// } // }

View file

@ -9,6 +9,3 @@ export interface IRouteModel {
url: string; url: string;
databaseModel: any; databaseModel: any;
} }

View file

@ -7,9 +7,7 @@ export const validationMiddleware = (
whitelist = true, whitelist = true,
forbidNonWhitelisted = true forbidNonWhitelisted = true
): RequestHandler => { ): RequestHandler => {
// TODO:(IDONTSUDO) need TOKEN // TODO:(IDONTSUDO) need TOKEN
// return nextTick // return nextTick
return (req, res, next) => { return (req, res, next) => {};
}
}; };

View file

@ -1,30 +1,28 @@
import { plainToInstance } from 'class-transformer'; import { plainToInstance } from "class-transformer";
import { validate, ValidationError } from 'class-validator'; import { validate, ValidationError } from "class-validator";
import { RequestHandler } from 'express'; import { RequestHandler } from "express";
export const validationModelMiddleware = ( export const validationModelMiddleware = (
type: any, type: any,
value = 'body', value = "body",
skipMissingProperties = false, skipMissingProperties = false,
whitelist = true, whitelist = true,
forbidNonWhitelisted = true, forbidNonWhitelisted = true
): RequestHandler => { ): RequestHandler => {
return (req, res, next) => { return (req, res, next) => {
if (type === null && type == undefined) {
if(type === null && type == undefined){ next();
next() return;
return
} }
const model = plainToInstance(type, req[value]); const model = plainToInstance(type, req[value]);
validate(model, { skipMissingProperties, whitelist, forbidNonWhitelisted }).then((errors: ValidationError[]) => { validate(model, { skipMissingProperties, whitelist, forbidNonWhitelisted }).then((errors: ValidationError[]) => {
if (errors.length > 0) { if (errors.length > 0) {
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(', '); const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(", ");
return res.status(400).json(message) return res.status(400).json(message);
} else { } else {
req['model'] = model req["model"] = model;
next(); next();
} }
}); });
}; };
}; };

View file

@ -3,18 +3,22 @@ export class ActivePipeline {
projectUUID?: string | null; projectUUID?: string | null;
lastProcessCompleteCount: number | null; lastProcessCompleteCount: number | null;
error: any; error: any;
path: string;
constructor( constructor(
pipelineIsRunning: boolean, pipelineIsRunning: boolean,
lastProcessCompleteCount: number | null, lastProcessCompleteCount: number | null,
error: any, error: any,
path: string | null,
projectUUID?: string | null projectUUID?: string | null
) { ) {
this.pipelineIsRunning = pipelineIsRunning; this.pipelineIsRunning = pipelineIsRunning;
this.projectUUID = projectUUID; this.projectUUID = projectUUID;
this.lastProcessCompleteCount = lastProcessCompleteCount; this.lastProcessCompleteCount = lastProcessCompleteCount;
this.error = error; this.error = error;
this.path = path;
} }
static empty() { static empty() {
return new ActivePipeline(false, null, null, null); return new ActivePipeline(false, null, null, null, null);
} }
} }

View file

@ -30,16 +30,8 @@ export class SpawnError extends Error {
this.unixTime = Date.now(); this.unixTime = Date.now();
} }
static isError(errorType: any): SpawnError | void { static isError(errorType: any): SpawnError | void {
if ( if ("command" in errorType && "error" in errorType && "execPath" in errorType) {
"command" in errorType && return new SpawnError(errorType.command, errorType.execPath, errorType.error);
"error" in errorType &&
"execPath" in errorType
) {
return new SpawnError(
errorType.command,
errorType.execPath,
errorType.error
);
} }
return; return;
} }

View file

@ -17,7 +17,7 @@ export class MetaDataFileManagerModel {
this.event = event; this.event = event;
this.unixTime = Date.now(); this.unixTime = Date.now();
} }
public get timeString(): string { public get timeString(): string {
const date = new Date(this.unixTime * 1000); const date = new Date(this.unixTime * 1000);
const hours = date.getHours(); const hours = date.getHours();

View file

@ -8,6 +8,8 @@ export const lsStat = promisify(fs.lstat);
export const createDir = promisify(fs.mkdir); export const createDir = promisify(fs.mkdir);
export const dirIsExists = promisify(fs.exists); export const dirIsExists = promisify(fs.exists);
export const writeFileAsync = promisify(fs.writeFile);
export function readDirRecursive(path: string, filesToDir: string[] = []) { export function readDirRecursive(path: string, filesToDir: string[] = []) {
const files = fs.readdirSync(path); const files = fs.readdirSync(path);
files.forEach((file) => { files.forEach((file) => {

View file

@ -11,7 +11,7 @@ abstract class IExecutorProgramService {
} }
export class ExecutorProgramService export class ExecutorProgramService
extends TypedEvent<Result<ExecError | SpawnError, ExecutorResult>> extends TypedEvent<Result<ExecError | SpawnError, ExecutorResult>>
implements IExecutorProgramService implements IExecutorProgramService
{ {
static event = "ExecutorProgramService"; static event = "ExecutorProgramService";
@ -25,11 +25,7 @@ export class ExecutorProgramService
this.maxTime = maxTime; this.maxTime = maxTime;
} }
private async workerExecuted( private async workerExecuted(command: string, workerType: WorkerType, args: Array<string> | undefined = undefined) {
command: string,
workerType: WorkerType,
args: Array<string> | undefined = undefined
) {
cluster.setupPrimary({ cluster.setupPrimary({
exec: "./src/core/helper/worker_computed", exec: "./src/core/helper/worker_computed",
}); });
@ -69,21 +65,13 @@ export class ExecutorProgramService
setTimeout(() => { setTimeout(() => {
this.worker.kill(); this.worker.kill();
this.emit( this.emit(
Result.error( Result.error(WorkerType.EXEC ? new ExecError(command, "timeout err") : new SpawnError(command, "timeout err"))
WorkerType.EXEC
? new ExecError(command, "timeout err")
: new SpawnError(command, "timeout err")
)
); );
}, this.maxTime!); }, this.maxTime!);
} }
} }
public async call( public async call(type: EXEC_TYPE, command: string, args: Array<string> | undefined = undefined): Promise<void> {
type: EXEC_TYPE,
command: string,
args: Array<string> | undefined = undefined
): Promise<void> {
if (type == EXEC_TYPE.EXEC) { if (type == EXEC_TYPE.EXEC) {
this.workerExecuted(command, WorkerType.EXEC); this.workerExecuted(command, WorkerType.EXEC);

View file

@ -1,19 +1,12 @@
import * as fs from "fs"; import * as fs from "fs";
import { resolve } from "node:path"; import { resolve } from "node:path";
import { createHash } from "node:crypto"; import { createHash } from "node:crypto";
import "reflect-metadata";
import { BinaryLike } from "crypto"; import { BinaryLike } from "crypto";
import { import { EventsFileChanger, MetaDataFileManagerModel } from "../model/meta_data_file_manager_model";
EventsFileChanger,
MetaDataFileManagerModel,
} from "../model/meta_data_file_manager_model";
import { Result } from "../helper/result"; import { Result } from "../helper/result";
import { TypedEvent } from "../helper/typed_event"; import { TypedEvent } from "../helper/typed_event";
import { lsStat, readFileAsync, readdir, stat } from "../repository/fs"; import { lsStat, readFileAsync, readdir, stat } from "../repository/fs";
function joinBuffers(buffers: Array<Buffer>, delimiter = " ") { function joinBuffers(buffers: Array<Buffer>, delimiter = " ") {
const d = Buffer.from(delimiter); const d = Buffer.from(delimiter);
return buffers.reduce((prev, b) => Buffer.concat([prev, d, b])); return buffers.reduce((prev, b) => Buffer.concat([prev, d, b]));
@ -25,10 +18,7 @@ async function readFileAtBuffer(path: string): Promise<Buffer> {
await readdir(path, { await readdir(path, {
encoding: "buffer", encoding: "buffer",
}) })
).reduce( ).reduce((accumulator, currentValue) => joinBuffers([accumulator, currentValue]), Buffer.from(""));
(accumulator, currentValue) => joinBuffers([accumulator, currentValue]),
Buffer.from("")
);
} }
return await readFileAsync(path); return await readFileAsync(path);
} }
@ -47,7 +37,6 @@ export abstract class IFilesChangeNotifierService {
abstract directory: string; abstract directory: string;
} }
export class FilesChangeNotifierService export class FilesChangeNotifierService
extends TypedEvent<Result<Error, IHashesCache>> extends TypedEvent<Result<Error, IHashesCache>>
implements IFilesChangeNotifierService implements IFilesChangeNotifierService
@ -70,11 +59,7 @@ export class FilesChangeNotifierService
const data = await readFileAsync(file); const data = await readFileAsync(file);
const md5Current = await md5(data); const md5Current = await md5(data);
this.hashes[file] = new MetaDataFileManagerModel( this.hashes[file] = new MetaDataFileManagerModel(file, md5Current, EventsFileChanger.static);
file,
md5Current,
EventsFileChanger.static
);
this.emit(Result.ok(this.hashes)); this.emit(Result.ok(this.hashes));
} }
async getFiles(dir: string): Promise<string | any[]> { async getFiles(dir: string): Promise<string | any[]> {
@ -92,46 +77,31 @@ export class FilesChangeNotifierService
try { try {
let md5Previous: string | null = null; let md5Previous: string | null = null;
let fsWait: NodeJS.Timeout | boolean = false; let fsWait: NodeJS.Timeout | boolean = false;
const watcher = fs.watch( const watcher = fs.watch(this.directory, { recursive: true }, async (_e, filename) => {
this.directory, const filePath = this.directory + filename;
{ recursive: true }, if (filename) {
async (_e, filename) => { if (fsWait) return;
const filePath = this.directory + filename; fsWait = setTimeout(() => {
if (filename) { fsWait = false;
if (fsWait) return; }, 100);
fsWait = setTimeout(() => { try {
fsWait = false; const file = await readFileAtBuffer(filePath);
}, 100); const md5Current = await md5(file);
try { if (md5Current === md5Previous) {
const file = await readFileAtBuffer(filePath); return;
const md5Current = await md5(file);
if (md5Current === md5Previous) {
return;
}
const status =
this.hashes[filePath] === undefined
? EventsFileChanger.create
: EventsFileChanger.update;
const model = new MetaDataFileManagerModel(
filePath,
md5Current,
status
);
this.hashes[filePath] = model;
md5Previous = md5Current;
this.emit(Result.ok(this.hashes));
} catch (error) {
this.emit(Result.ok(this.hashes));
this.hashes[filePath] = new MetaDataFileManagerModel(
filePath,
null,
EventsFileChanger.delete
);
} }
const status = this.hashes[filePath] === undefined ? EventsFileChanger.create : EventsFileChanger.update;
const model = new MetaDataFileManagerModel(filePath, md5Current, status);
this.hashes[filePath] = model;
md5Previous = md5Current;
this.emit(Result.ok(this.hashes));
} catch (error) {
this.emit(Result.ok(this.hashes));
this.hashes[filePath] = new MetaDataFileManagerModel(filePath, null, EventsFileChanger.delete);
} }
} }
); });
this.watcher = watcher; this.watcher = watcher;
return Result.ok(true); return Result.ok(true);
} catch (error) { } catch (error) {

View file

@ -3,19 +3,17 @@ import { ExecError } from "../model/exec_error_model";
import { ExecutorResult } from "../model/executor_result"; import { ExecutorResult } from "../model/executor_result";
import { ActivePipeline } from "../model/active_pipeline_model"; import { ActivePipeline } from "../model/active_pipeline_model";
import { IPipeline } from "../model/process_model"; import { IPipeline } from "../model/process_model";
import { Iteration, StackService } from "./stack_service"; import { Iteration } from "./stack_service";
export class PipelineRealTimeService extends TypedEvent<ActivePipeline> { export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
status: ActivePipeline; status: ActivePipeline;
pipelineModels?: IPipeline[]; pipelineModels?: IPipeline[];
path: string;
constructor() { constructor() {
super(); super();
this.init(); this.init();
} }
private init(): void { private init(): void {
this.status = ActivePipeline.empty(); this.status = ActivePipeline.empty();
} }
pipelineSubscriber = (iterations: Iteration[]): void => { pipelineSubscriber = (iterations: Iteration[]): void => {
if (this.status["lastProcessCompleteCount"] === 0) { if (this.status["lastProcessCompleteCount"] === 0) {
@ -56,25 +54,18 @@ export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
} }
} }
pipelineCompleted() { pipelineCompleted() {
const pipelineIsCompleted = const pipelineIsCompleted = this.status.lastProcessCompleteCount === this.pipelineModels?.length;
this.status.lastProcessCompleteCount === this.pipelineModels?.length;
if (pipelineIsCompleted) { if (pipelineIsCompleted) {
this.status.pipelineIsRunning = false; this.status.pipelineIsRunning = false;
} }
} }
setPipelineDependency( setPipelineDependency(pipelineModels: IPipeline[], path: string, projectUUID: string) {
pipelineModels: IPipeline[],
path: string,
projectUUID: string
) {
this.pipelineModels = pipelineModels; this.pipelineModels = pipelineModels;
this.path = path;
this.status["projectUUID"] = projectUUID; this.status["projectUUID"] = projectUUID;
this.status["path"] = path;
} }
runPipeline(): void { runPipeline(): void {
// const stack = new StackService(this.pipelineModels, this.path); // const stack = new StackService(this.pipelineModels, this.path);
// this.status["pipelineIsRunning"] = true; // this.status["pipelineIsRunning"] = true;
// stack.on(this.pipelineSubscriber); // stack.on(this.pipelineSubscriber);
// stack.call(); // stack.call();

View file

@ -1,7 +1,4 @@
import { import { FilesChangeNotifierService, IHashesCache } from "./files_change_notifier_service";
FilesChangeNotifierService,
IHashesCache,
} from "./files_change_notifier_service";
import { IPipeline } from "../model/process_model"; import { IPipeline } from "../model/process_model";
import { ExecutorProgramService } from "./executor_program_service"; import { ExecutorProgramService } from "./executor_program_service";
import { EXEC_EVENT, ExecError, SpawnError } from "../model/exec_error_model"; import { EXEC_EVENT, ExecError, SpawnError } from "../model/exec_error_model";
@ -24,10 +21,7 @@ export abstract class IStackService {
abstract init(processed: IPipeline[], path: string): void; abstract init(processed: IPipeline[], path: string): void;
} }
export class StackService export class StackService extends TypedEvent<Iteration[]> implements IStackService {
extends TypedEvent<Iteration[]>
implements IStackService
{
callStack: Iteration[]; callStack: Iteration[];
path: string; path: string;
constructor(processed: IPipeline[], path: string) { constructor(processed: IPipeline[], path: string) {
@ -47,11 +41,7 @@ export class StackService
} }
} }
private commandHandler(processMetaData: IPipeline) { private commandHandler(processMetaData: IPipeline) {
processMetaData.process.command = processMetaData.process.command.replace( processMetaData.process.command = processMetaData.process.command.replace("$PATH", this.path);
"$PATH",
this.path
);
console.log(processMetaData.process.command)
return processMetaData; return processMetaData;
} }
public async call() { public async call() {
@ -63,34 +53,21 @@ export class StackService
this.emit(this.callStack); this.emit(this.callStack);
} }
} }
async execStack( async execStack(stackNumber: number, stackLayer: Iteration): Promise<void | boolean> {
stackNumber: number,
stackLayer: Iteration
): Promise<void | boolean> {
const executorService = new ExecutorProgramService(this.path); const executorService = new ExecutorProgramService(this.path);
executorService.call( executorService.call(stackLayer.process.process.type, stackLayer.process.process.command);
stackLayer.process.process.type,
stackLayer.process.process.command
);
const filesChangeNotifierService = new FilesChangeNotifierService( const filesChangeNotifierService = new FilesChangeNotifierService(this.path);
this.path
);
filesChangeNotifierService.call(); filesChangeNotifierService.call();
const result = await this.waitEvent< const result = await this.waitEvent<Result<ExecError | SpawnError, ExecutorResult>>(executorService);
Result<ExecError | SpawnError, ExecutorResult>
>(executorService);
await delay(100); await delay(100);
if (result.isSuccess()) { if (result.isSuccess()) {
this.callStack[stackNumber].result = result.value; this.callStack[stackNumber].result = result.value;
this.callStack[stackNumber].hashes = filesChangeNotifierService.hashes; this.callStack[stackNumber].hashes = filesChangeNotifierService.hashes;
const triggerResult = await this.triggerExec( const triggerResult = await this.triggerExec(stackLayer.process.trigger, stackNumber);
stackLayer.process.trigger,
stackNumber
);
triggerResult.fold( triggerResult.fold(
(s) => { (s) => {
s; s;
@ -125,10 +102,7 @@ export class StackService
}); });
return promise; return promise;
} }
private async triggerExec( private async triggerExec(trigger: Trigger | null, stackNumber: number): Promise<Result<boolean, boolean>> {
trigger: Trigger | null,
stackNumber: number
): Promise<Result<boolean, boolean>> {
if (trigger !== null) { if (trigger !== null) {
const hashes = this.callStack[stackNumber].hashes; const hashes = this.callStack[stackNumber].hashes;

View file

@ -35,11 +35,7 @@ export class TriggerErrorReport extends Error {
hashes: IHashesCache; hashes: IHashesCache;
trigger: string | Trigger; trigger: string | Trigger;
processOutput: any; processOutput: any;
constructor( constructor(hashes: IHashesCache, trigger: string | Trigger, processOutput?: any) {
hashes: IHashesCache,
trigger: string | Trigger,
processOutput?: any
) {
super(); super();
this.hashes = hashes; this.hashes = hashes;
this.trigger = trigger; this.trigger = trigger;
@ -123,9 +119,7 @@ export class TriggerService extends TypedEvent<TriggerCallResult> {
}) })
); );
} }
private reportTriggerTypeProcess( private reportTriggerTypeProcess(triggerResult: Array<TriggerSuccessResult>): TriggerCallResult {
triggerResult: Array<TriggerSuccessResult>
): TriggerCallResult {
return new TriggerCallResult( return new TriggerCallResult(
triggerResult.map((el) => { triggerResult.map((el) => {
if (el.status) { if (el.status) {

View file

@ -3,20 +3,17 @@ import { dirIsExists } from "../repository/fs";
import { CreateFolderUseCase } from "./crete_folder_usecase"; import { CreateFolderUseCase } from "./crete_folder_usecase";
export class CheckAndCreateStaticFilesFolderUseCase { export class CheckAndCreateStaticFilesFolderUseCase {
call = async (): Promise<void> => { call = async (): Promise<void> => {
if (await dirIsExists(App.staticFilesStoreDir())) { if (await dirIsExists(App.staticFilesStoreDir())) {
return; return;
}
const createFolderUseCase = await new CreateFolderUseCase().call(App.staticFilesStoreDir());
createFolderUseCase.fold(
(_s) => {},
(e) => {
console.log(e);
} }
const createFolderUseCase = await new CreateFolderUseCase().call( );
App.staticFilesStoreDir() };
); }
createFolderUseCase.fold(
(_s) => {},
(e) => {
console.log(e);
}
);
};
}

View file

@ -8,9 +8,7 @@ export class CreateDataBaseModelUseCase<V> {
this.databaseModel = model; this.databaseModel = model;
} }
call = async ( call = async (validationModel: V): Promise<Result<Error, ICreateObjectDataBase>> => {
validationModel: V
): Promise<Result<Error, ICreateObjectDataBase>> => {
try { try {
const result = new this.databaseModel(validationModel); const result = new this.databaseModel(validationModel);

View file

@ -0,0 +1,13 @@
import { Result } from "../helper/result";
import { writeFileAsync } from "../repository/fs";
export class CreateFileUseCase {
async call(path: string, buffer: Buffer): Promise<Result<Error, void>> {
try {
await writeFileAsync(path, buffer);
return Result.ok();
} catch (err) {
return Result.error(err as Error);
}
}
}

View file

@ -4,11 +4,11 @@ import { dirIsExists, createDir } from "../repository/fs";
export class CreateFolderUseCase { export class CreateFolderUseCase {
call = async (path: string): Promise<Result<Error, string>> => { call = async (path: string): Promise<Result<Error, string>> => {
try { try {
if (await dirIsExists(path)) { if (await dirIsExists(path)) {
return Result.error(new Error("createFolderUseCase create dir ")); return Result.error(new Error("createFolderUseCase create dir "));
} }
await createDir(path); await createDir(path);
return Result.ok("ok"); return Result.ok("ok");
} catch (error) { } catch (error) {
return Result.error(error as Error); return Result.error(error as Error);

View file

@ -1,7 +1,7 @@
import { Result } from "../helper/result"; import { Result } from "../helper/result";
export class DeleteDataBaseModelUseCase<D> { export class DeleteDataBaseModelUseCase<D> {
databaseModel: D | any; databaseModel: D | any;
constructor(model) { constructor(model) {
this.databaseModel = model; this.databaseModel = model;
} }

View file

@ -9,9 +9,7 @@ export class PaginationDataBaseModelUseCase<D> {
this.perPage = perPage; this.perPage = perPage;
} }
call = async ( call = async (pageNumber: number): Promise<Result<Error, [D]>> => {
pageNumber: number
): Promise<Result<Error, [D]>> => {
try { try {
const page = Math.max(0, pageNumber); const page = Math.max(0, pageNumber);
const model = this.databaseModel as any; const model = this.databaseModel as any;

View file

@ -1,4 +1,3 @@
import { Result } from "../helper/result"; import { Result } from "../helper/result";
export class ReadByIdDataBaseModelUseCase<D> { export class ReadByIdDataBaseModelUseCase<D> {
@ -9,10 +8,8 @@ export class ReadByIdDataBaseModelUseCase<D> {
} }
call = async (id: string): Promise<Result<Error, D>> => { call = async (id: string): Promise<Result<Error, D>> => {
try { try {
const r = this.databaseModel as any; const dbModel = this.databaseModel as any;
return Result.ok(await dbModel.findById(id));
const model = await r.findById(id);
return Result.ok(model);
} catch (error) { } catch (error) {
return Result.error(error); return Result.error(error);
} }

View file

@ -2,7 +2,7 @@ import { Result } from "../helper/result";
export class SearchDataBaseModelUseCase<T> { export class SearchDataBaseModelUseCase<T> {
model: any; model: any;
constructor(model: any) { constructor(model: any) {
this.model = model; this.model = model;
} }

View file

@ -1,26 +1,21 @@
import { import { IProjectInstanceModel, ProjectInstanceDbModel } from "../../features/project_instance/project_instance_model";
IProjectInstanceModel,
ProjectInstanceDbModel,
} from "../../features/project_instance/project_instance_model";
import { pipelineRealTimeService } from "../../features/realtime/realtime_presentation"; import { pipelineRealTimeService } from "../../features/realtime/realtime_presentation";
import { App } from "../controllers/app"; import { App } from "../controllers/app";
import { CreateFolderUseCase } from "./crete_folder_usecase";
import { SearchDataBaseModelUseCase } from "./search_database_model_usecase"; import { SearchDataBaseModelUseCase } from "./search_database_model_usecase";
export class SetLastActivePipelineToRealTimeServiceUseCase { export class SetLastActivePipelineToRealTimeServiceUseCase {
call = async (): Promise<void> => { call = async (): Promise<void> => {
const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>( const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>(ProjectInstanceDbModel).call({
ProjectInstanceDbModel
).call({
isActive: true, isActive: true,
}); });
if (result.isSuccess()) { if (result.isSuccess()) {
const projectModel = result.value.project; const projectModel = result.value;
pipelineRealTimeService.setPipelineDependency( const projectPath = App.staticFilesStoreDir() + result.value.rootDir + "/";
projectModel.pipelines, await new CreateFolderUseCase().call(projectPath);
App.staticFilesStoreDir() + projectModel.rootDir + "/", pipelineRealTimeService.setPipelineDependency(projectModel.project.pipelines, projectPath, projectModel._id);
projectModel._id
);
} }
}; };
} }

View file

@ -17,7 +17,14 @@ export class UpdateDataBaseModelUseCase<D, T extends uuid> {
} }
const databaseModel = this.databaseModel as any; const databaseModel = this.databaseModel as any;
const model = await databaseModel.findById(updateModel._id); const model = await databaseModel.findById(updateModel._id);
if (model === null) {
throw new Error(
`we cant find the model in the database with ID:${updateModel._id} collection: ${databaseModel.modelName}`
);
}
Object.assign(model, updateModel); Object.assign(model, updateModel);
await model.save(); await model.save();
return Result.ok(model as T); return Result.ok(model as T);
} catch (error) { } catch (error) {

View file

@ -1,10 +1,6 @@
import { IsMongoId, IsOptional, ValidateNested } from "class-validator"; import { IsMongoId, IsOptional, ValidateNested } from "class-validator";
import { Schema, model } from "mongoose"; import { Schema, model } from "mongoose";
import { import { IPipeline, IProcess, StackGenerateType } from "../../core/model/process_model";
IPipeline,
IProcess,
StackGenerateType,
} from "../../core/model/process_model";
import { TriggerModel, triggerSchema } from "../triggers/trigger_model"; import { TriggerModel, triggerSchema } from "../triggers/trigger_model";
import { ProcessModel, schemaProcess } from "../process/process_model"; import { ProcessModel, schemaProcess } from "../process/process_model";
import { Type } from "class-transformer"; import { Type } from "class-transformer";

View file

@ -1,10 +1,7 @@
import { CrudController } from "../../core/controllers/crud_controller"; import { CrudController } from "../../core/controllers/crud_controller";
import { PipelineDBModel, PipelineValidationModel } from "./pipeline_model"; import { PipelineDBModel, PipelineValidationModel } from "./pipeline_model";
export class PipelinePresentation extends CrudController< export class PipelinePresentation extends CrudController<PipelineValidationModel, typeof PipelineDBModel> {
PipelineValidationModel,
typeof PipelineDBModel
> {
constructor() { constructor() {
super({ super({
url: "pipeline", url: "pipeline",

View file

@ -1,10 +1,4 @@
import { import { IsString, IsOptional, IsEnum, IsNumber, IsBoolean } from "class-validator";
IsString,
IsOptional,
IsEnum,
IsNumber,
IsBoolean,
} from "class-validator";
import { Schema, model } from "mongoose"; import { Schema, model } from "mongoose";
import { IProcess, IssueType } from "../../core/model/process_model"; import { IProcess, IssueType } from "../../core/model/process_model";
import { EXEC_TYPE } from "../../core/model/exec_error_model"; import { EXEC_TYPE } from "../../core/model/exec_error_model";
@ -48,7 +42,7 @@ export class ProcessModel implements IProcess {
@IsString() @IsString()
public description: string; public description: string;
@IsString() @IsString()
public command: string; public command: string;

View file

@ -1,10 +1,7 @@
import { CrudController } from "../../core/controllers/crud_controller"; import { CrudController } from "../../core/controllers/crud_controller";
import { ProcessDBModel, ProcessModel } from "./process_model"; import { ProcessDBModel, ProcessModel } from "./process_model";
export class ProcessPresentation extends CrudController< export class ProcessPresentation extends CrudController<ProcessModel, typeof ProcessDBModel> {
ProcessModel,
typeof ProcessDBModel
> {
constructor() { constructor() {
super({ super({
url: "process", url: "process",

View file

@ -2,29 +2,20 @@ import { App } from "../../core/controllers/app";
import { Result } from "../../core/helper/result"; import { Result } from "../../core/helper/result";
import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase"; import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase";
import { CreateFolderUseCase } from "../../core/usecases/crete_folder_usecase"; import { CreateFolderUseCase } from "../../core/usecases/crete_folder_usecase";
import { import { ProjectInstanceDbModel, ProjectInstanceValidationModel } from "./project_instance_model";
ProjectInstanceDbModel,
ProjectInstanceValidationModel,
} from "./project_instance_model";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
export class CreateNewProjectInstanceScenario { export class CreateNewProjectInstanceScenario {
call = async ( call = async (model: ProjectInstanceValidationModel): Promise<Result<Error, any>> => {
model: ProjectInstanceValidationModel
): Promise<Result<Error, any>> => {
try { try {
const folderName = uuidv4() + "/"; const folderName = uuidv4() + "/";
const createFolderUseCase = await new CreateFolderUseCase().call( const createFolderUseCase = await new CreateFolderUseCase().call(App.staticFilesStoreDir() + folderName);
App.staticFilesStoreDir() + folderName
);
if (createFolderUseCase.isFailure()) { if (createFolderUseCase.isFailure()) {
return createFolderUseCase.forward(); return createFolderUseCase.forward();
} }
model.rootDir = folderName; model.rootDir = folderName;
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase( const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(ProjectInstanceDbModel).call(model);
ProjectInstanceDbModel
).call(model);
if (createDataBaseModelUseCase.isFailure()) { if (createDataBaseModelUseCase.isFailure()) {
return createDataBaseModelUseCase.forward(); return createDataBaseModelUseCase.forward();

View file

@ -3,6 +3,7 @@ import { IProjectModel, projectSchema } from "../projects/projects_model";
import { IsMongoId, IsOptional, IsString } from "class-validator"; import { IsMongoId, IsOptional, IsString } from "class-validator";
export interface IProjectInstanceModel { export interface IProjectInstanceModel {
_id: string;
project: IProjectModel; project: IProjectModel;
description: string; description: string;
rootDir: string; rootDir: string;
@ -30,10 +31,7 @@ export const ProjectInstanceSchema = new Schema({
export const schemaProjectInstance = "instance_project"; export const schemaProjectInstance = "instance_project";
export const ProjectInstanceDbModel = model<IProjectInstanceModel>( export const ProjectInstanceDbModel = model<IProjectInstanceModel>(schemaProjectInstance, ProjectInstanceSchema);
schemaProjectInstance,
ProjectInstanceSchema
);
export class ProjectInstanceValidationModel { export class ProjectInstanceValidationModel {
@IsMongoId() @IsMongoId()

View file

@ -1,15 +1,7 @@
import { CrudController } from "../../core/controllers/crud_controller"; import { CrudController } from "../../core/controllers/crud_controller";
import {
CallbackStrategyWithEmpty,
ResponseBase,
} from "../../core/controllers/http_controller";
import { Result } from "../../core/helper/result";
import { CreateNewProjectInstanceScenario } from "./create_new_project_scenario"; import { CreateNewProjectInstanceScenario } from "./create_new_project_scenario";
import { import { ProjectInstanceDbModel, ProjectInstanceValidationModel } from "./project_instance_model";
ProjectInstanceDbModel, import { UploadCadFileToProjectScenario } from "./upload_file_to_to_project_scenario";
ProjectInstanceValidationModel,
} from "./project_instance_model";
import { UploadCadFileToProjectUseCase } from "./upload_file_to_project_usecase";
export class ProjectInstancePresentation extends CrudController< export class ProjectInstancePresentation extends CrudController<
ProjectInstanceValidationModel, ProjectInstanceValidationModel,
@ -27,14 +19,8 @@ export class ProjectInstancePresentation extends CrudController<
{ {
method: "post", method: "post",
subUrl: "upload", subUrl: "upload",
fn: new TestUseCase(), fn: new UploadCadFileToProjectScenario(),
}, },
]; ];
} }
} }
class TestUseCase extends CallbackStrategyWithEmpty {
async call(): ResponseBase {
return Result.ok(200);
}
}

View file

@ -1,13 +0,0 @@
import {
CallbackStrategyWithFileUpload,
ResponseBase,
} from "../../core/controllers/http_controller";
import { Result } from "../../core/helper/result";
export class UploadCadFileToProjectUseCase extends CallbackStrategyWithFileUpload {
checkingFileExpression: RegExp = RegExp('.FCStd')
async call(file: File): ResponseBase {
return Result.ok("200");
}
}

View file

@ -0,0 +1,28 @@
import { App } from "../../core/controllers/app";
import { CallbackStrategyWithFileUpload, ResponseBase } from "../../core/controllers/http_controller";
import { Result } from "../../core/helper/result";
import { CreateFileUseCase } from "../../core/usecases/create_file_usecase";
import { PipelineStatusUseCase } from "../realtime/usecases/pipeline_status_usecase";
export interface IFile extends File {
data: Buffer;
}
export class UploadCadFileToProjectScenario extends CallbackStrategyWithFileUpload {
checkingFileExpression: RegExp = RegExp(".pages");
async call(file: IFile): ResponseBase {
const pipelineStatusUseCase = await new PipelineStatusUseCase().call();
if (pipelineStatusUseCase.isFailure()) {
return pipelineStatusUseCase.forward();
}
const projectFolder = pipelineStatusUseCase.value.path;
// TODO:
const createFileUseCase = await new CreateFileUseCase().call(projectFolder + file.name, file.data);
if (createFileUseCase.isFailure()) {
return createFileUseCase.forward();
}
return Result.ok("ok");
}
}

View file

@ -7,7 +7,7 @@ export interface IProjectModel {
pipelines: [PipelineValidationModel]; pipelines: [PipelineValidationModel];
rootDir: string; rootDir: string;
description: string; description: string;
isActive:boolean; isActive: boolean;
} }
export const ProjectSchema = new Schema({ export const ProjectSchema = new Schema({
@ -35,5 +35,4 @@ export class ProjectValidationModel {
public pipelines: [string]; public pipelines: [string];
@IsString() @IsString()
public description: string; public description: string;
} }

View file

@ -1,10 +1,7 @@
import { CrudController } from "../../core/controllers/crud_controller"; import { CrudController } from "../../core/controllers/crud_controller";
import { ProjectDBModel, ProjectValidationModel } from "./projects_model"; import { ProjectDBModel, ProjectValidationModel } from "./projects_model";
export class ProjectsPresentation extends CrudController< export class ProjectsPresentation extends CrudController<ProjectValidationModel, typeof ProjectDBModel> {
ProjectValidationModel,
typeof ProjectDBModel
> {
constructor() { constructor() {
super({ super({
url: "project", url: "project",

View file

@ -3,7 +3,7 @@ import { CoreHttpController } from "../../core/controllers/http_controller";
import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service"; import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service";
import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase"; import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase";
import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase"; import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase";
export const pipelineRealTimeService = new PipelineRealTimeService(); export const pipelineRealTimeService = new PipelineRealTimeService();
export class RealTimeValidationModel { export class RealTimeValidationModel {
@ -11,7 +11,6 @@ export class RealTimeValidationModel {
public id: string; public id: string;
} }
export class RealTimePresentation extends CoreHttpController<RealTimeValidationModel> { export class RealTimePresentation extends CoreHttpController<RealTimeValidationModel> {
constructor() { constructor() {
super({ super({
@ -21,6 +20,5 @@ export class RealTimePresentation extends CoreHttpController<RealTimeValidationM
}); });
super.post(new RunInstancePipelineUseCase().call); super.post(new RunInstancePipelineUseCase().call);
super.get(new PipelineStatusUseCase().call); super.get(new PipelineStatusUseCase().call);
} }
} }

View file

@ -5,7 +5,13 @@ import { pipelineRealTimeService } from "../realtime_presentation";
export class PipelineStatusUseCase { export class PipelineStatusUseCase {
async call(): Promise<Result<Error, ActivePipeline>> { async call(): Promise<Result<Error, ActivePipeline>> {
try { try {
return Result.ok(pipelineRealTimeService.status); const status = pipelineRealTimeService.status;
if (status.projectUUID !== null) {
return Result.ok(status);
}
if (status.projectUUID === null) {
return Result.error(new Error("pipelineRealTimeService does not have an active project instance"));
}
} catch (error) { } catch (error) {
return Result.error(error as Error); return Result.error(error as Error);
} }

View file

@ -2,41 +2,32 @@ import { App } from "../../../core/controllers/app";
import { Result } from "../../../core/helper/result"; import { Result } from "../../../core/helper/result";
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase"; import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase"; import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase";
import { import { IProjectInstanceModel, ProjectInstanceDbModel } from "../../project_instance/project_instance_model";
IProjectInstanceModel, import { RealTimeValidationModel, pipelineRealTimeService } from "../realtime_presentation";
ProjectInstanceDbModel,
} from "../../project_instance/project_instance_model";
import {
RealTimeValidationModel,
pipelineRealTimeService,
} from "../realtime_presentation";
export class RunInstancePipelineUseCase { export class RunInstancePipelineUseCase {
async call(model: RealTimeValidationModel): Promise<Result<Error, any>> { async call(model: RealTimeValidationModel): Promise<Result<Error, any>> {
const { id } = model; const { id } = model;
const readByIdDataBaseModelUseCase = await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
const readByIdDataBaseModelUseCase = ProjectInstanceDbModel
await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>( ).call(id);
ProjectInstanceDbModel
).call(id);
if (readByIdDataBaseModelUseCase.isFailure()) { if (readByIdDataBaseModelUseCase.isFailure()) {
return readByIdDataBaseModelUseCase.forward(); return readByIdDataBaseModelUseCase.forward();
} }
const projectModel = readByIdDataBaseModelUseCase.value.project; const projectModel = readByIdDataBaseModelUseCase.value;
projectModel.isActive = true; projectModel.isActive = true;
const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase< const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase<IProjectInstanceModel, any>(
IProjectInstanceModel, ProjectInstanceDbModel
any ).call(projectModel);
>(ProjectInstanceDbModel).call(projectModel);
if (updateDataBaseModelUseCase.isFailure()) { if (updateDataBaseModelUseCase.isFailure()) {
return updateDataBaseModelUseCase.forward(); return updateDataBaseModelUseCase.forward();
} }
pipelineRealTimeService.setPipelineDependency( pipelineRealTimeService.setPipelineDependency(
projectModel.pipelines, projectModel.project.pipelines,
App.staticFilesStoreDir() + projectModel.rootDir + "/", App.staticFilesStoreDir() + projectModel.rootDir + "/",
projectModel._id projectModel._id
); );

View file

@ -24,10 +24,7 @@ export const TriggerSchema = new Schema({
export const triggerSchema = "Trigger"; export const triggerSchema = "Trigger";
export const TriggerDBModel = model<ITriggerModel>( export const TriggerDBModel = model<ITriggerModel>(triggerSchema, TriggerSchema);
triggerSchema,
TriggerSchema
);
export enum TriggerType { export enum TriggerType {
PROCESS = "PROCESS", PROCESS = "PROCESS",

View file

@ -1,10 +1,7 @@
import { TriggerDBModel, TriggerModel } from "./trigger_model"; import { TriggerDBModel, TriggerModel } from "./trigger_model";
import { CrudController } from "../../core/controllers/crud_controller"; import { CrudController } from "../../core/controllers/crud_controller";
export class TriggerPresentation extends CrudController< export class TriggerPresentation extends CrudController<TriggerModel, typeof TriggerDBModel> {
TriggerModel,
typeof TriggerDBModel
> {
constructor() { constructor() {
super({ super({
url: "trigger", url: "trigger",

View file

@ -6,13 +6,10 @@ import { TriggerPresentation } from "./features/triggers/triggers_presentation";
import { ProjectsPresentation } from "./features/projects/projects_presentation"; import { ProjectsPresentation } from "./features/projects/projects_presentation";
import { PipelinePresentation } from "./features/pipelines/pipeline_presentation"; import { PipelinePresentation } from "./features/pipelines/pipeline_presentation";
import { ProcessPresentation } from "./features/process/process_presentation"; import { ProcessPresentation } from "./features/process/process_presentation";
import { import { RealTimePresentation, pipelineRealTimeService } from "./features/realtime/realtime_presentation";
RealTimePresentation,
pipelineRealTimeService,
} from "./features/realtime/realtime_presentation";
import { extensions } from "./core/extensions/extensions"; import { extensions } from "./core/extensions/extensions";
import { ProjectInstancePresentation } from "./features/project_instance/project_instance_presentation"; import { ProjectInstancePresentation } from "./features/project_instance/project_instance_presentation";
extensions(); extensions();
const httpRoutes: Routes[] = [ const httpRoutes: Routes[] = [
@ -24,8 +21,6 @@ const httpRoutes: Routes[] = [
new ProjectInstancePresentation(), new ProjectInstancePresentation(),
].map((el) => el.call()); ].map((el) => el.call());
const socketSubscribers = [ const socketSubscribers = [new SocketSubscriber(pipelineRealTimeService, "realtime")];
new SocketSubscriber(pipelineRealTimeService, "realtime"),
];
new App(httpRoutes, socketSubscribers).listen(); new App(httpRoutes, socketSubscribers).listen();

View file

@ -3,10 +3,9 @@ import { delay } from "../../src/core/helper/delay";
import { Result } from "../../src/core/helper/result"; import { Result } from "../../src/core/helper/result";
import { TypedEvent } from "../../src/core/helper/typed_event"; import { TypedEvent } from "../../src/core/helper/typed_event";
export const before = async () => {
export const before = async () =>{ await mongoose.connection.dropDatabase();
await mongoose.connection.dropDatabase() };
}
export class TestCore { export class TestCore {
allTests = 0; allTests = 0;
@ -33,17 +32,14 @@ export class TestCore {
console.log("\x1b[32m", "============="); console.log("\x1b[32m", "=============");
if (this.allTests - this.testOk === 0) { if (this.allTests - this.testOk === 0) {
console.log( console.log("\x1b[32m", `✅ All test success! ${this.allTests}/${this.testOk}`);
"\x1b[32m",
`✅ All test success! ${this.allTests}/${this.testOk}`
);
return; return;
} }
if (this.testErr !== 0) { if (this.testErr !== 0) {
console.log("\x1b[31m", "❌ test error:" + String(this.testErr)); console.log("\x1b[31m", "❌ test error:" + String(this.testErr));
console.log("\x1b[32m", `✅ test success! ${this.testOk}`); console.log("\x1b[32m", `✅ test success! ${this.testOk}`);
} }
await before() await before();
}; };
resultTest = async ( resultTest = async (
eventClass: TypedEvent<Result<any, any>> | any, eventClass: TypedEvent<Result<any, any>> | any,
@ -54,24 +50,20 @@ export class TestCore {
) => { ) => {
let testIsOk = false; let testIsOk = false;
eventClass.call(...args); eventClass.call(...args);
const listener = eventClass.on( const listener = eventClass.on((e: { fold: (arg0: (_s: any) => void, arg1: (_e: any) => void) => void }) => {
(e: { e.fold(
fold: (arg0: (_s: any) => void, arg1: (_e: any) => void) => void; () => {
}) => { if (isOk) {
e.fold( testIsOk = true;
() => {
if (isOk) {
testIsOk = true;
}
},
() => {
if (!isOk) {
testIsOk = true;
}
} }
); },
} () => {
); if (!isOk) {
testIsOk = true;
}
}
);
});
await delay(delayTime); await delay(delayTime);
this.assert(testIsOk, testName); this.assert(testIsOk, testName);
listener.dispose(); listener.dispose();

View file

@ -1,17 +1,15 @@
setTimeout(() => {
console.log("log");
setTimeout(() =>{ console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') console.log("log");
console.log('log') }, 2000);
console.log('log') setTimeout(() => {
},2000) console.log("log end");
setTimeout(() =>{ }, 5000);
console.log('log end')
}, 5000)

View file

@ -1,4 +1,4 @@
const seconds = 1000 * 10 const seconds = 1000 * 10;
setTimeout(()=>{ setTimeout(() => {
console.log(200) console.log(200);
}, seconds) }, seconds);

View file

@ -1,12 +1,8 @@
import { EXEC_TYPE } from "../../src/core/model/exec_error_model"; import { EXEC_TYPE } from "../../src/core/model/exec_error_model";
import { import { IPipeline, IssueType, StackGenerateType } from "../../src/core/model/process_model";
IPipeline,
IssueType,
StackGenerateType,
} from "../../src/core/model/process_model";
import { TriggerType } from "../../src/features/triggers/trigger_model"; import { TriggerType } from "../../src/features/triggers/trigger_model";
export const mockSimplePipeline:IPipeline[] = [ export const mockSimplePipeline: IPipeline[] = [
{ {
process: { process: {
type: EXEC_TYPE.EXEC, type: EXEC_TYPE.EXEC,

View file

@ -1,6 +1,6 @@
import { Schema, model } from "mongoose"; import { Schema, model } from "mongoose";
export interface ITestModel{ export interface ITestModel {
_id?: string; _id?: string;
result: string; result: string;
} }
@ -12,4 +12,3 @@ export const TestSchema = new Schema({
const schema = "Test"; const schema = "Test";
export const TestDBModel = model<ITestModel>(schema, TestSchema); export const TestDBModel = model<ITestModel>(schema, TestSchema);

View file

@ -15,12 +15,8 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
await this.logWriteAndEventEndTypeSpawn(); await this.logWriteAndEventEndTypeSpawn();
}; };
private async logWriteAndEventEndTypeSpawn() { private async logWriteAndEventEndTypeSpawn() {
const executorProgramService = await new ExecutorProgramService( const executorProgramService = await new ExecutorProgramService(dirname__ + "/");
dirname__ + "/" executorProgramService.call(EXEC_TYPE.SPAWN, "node", ["./mocks/log_code"]);
);
executorProgramService.call(EXEC_TYPE.SPAWN, "node", [
"./mocks/log_code",
]);
const test = TestCore.instance; const test = TestCore.instance;
let testIsOk = false; let testIsOk = false;
let logEvent = false; let logEvent = false;
@ -29,24 +25,17 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
if (e.isSuccess()) { if (e.isSuccess()) {
const executorResult = e.value as ExecutorResult; const executorResult = e.value as ExecutorResult;
if (logEvent == false) { if (logEvent == false) {
logEvent = logEvent = executorResult.data != null && executorResult.data != undefined;
executorResult.data != null && executorResult.data != undefined;
} }
testIsOk = executorResult.event == "END" && logEvent; testIsOk = executorResult.event == "END" && logEvent;
} }
}); });
await delay(8000); await delay(8000);
test.assert( test.assert(testIsOk, "ExecutorProgramService EXEC_TYPE.SPAWN end event and log write");
testIsOk,
"ExecutorProgramService EXEC_TYPE.SPAWN end event and log write"
);
} }
private async logWriteAndEventEndTestTypeExec() { private async logWriteAndEventEndTestTypeExec() {
const executorProgramService = await new ExecutorProgramService(dirname__); const executorProgramService = await new ExecutorProgramService(dirname__);
executorProgramService.call( executorProgramService.call(EXEC_TYPE.EXEC, "node ./test/mocks/log_code");
EXEC_TYPE.EXEC,
"node ./test/mocks/log_code"
);
const test = TestCore.instance; const test = TestCore.instance;
executorProgramService.on((e) => { executorProgramService.on((e) => {
if (e.isSuccess()) { if (e.isSuccess()) {
@ -61,10 +50,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
} }
private async longTimeCancelTest() { private async longTimeCancelTest() {
const executorProgramService = await new ExecutorProgramService("", 1000); const executorProgramService = await new ExecutorProgramService("", 1000);
executorProgramService.call( executorProgramService.call(EXEC_TYPE.EXEC, "node ./test/mocks/long_code");
EXEC_TYPE.EXEC,
"node ./test/mocks/long_code"
);
await delay(1500); await delay(1500);
const worker = executorProgramService.worker as Worker; const worker = executorProgramService.worker as Worker;
const test = TestCore.instance; const test = TestCore.instance;

View file

@ -26,10 +26,7 @@ export class FilesChangerTest extends FilesChangeNotifierService {
await delay(2000); await delay(2000);
fs.writeFileSync(this.filePath, this.data()); fs.writeFileSync(this.filePath, this.data());
await delay(1000); await delay(1000);
this.hashUnitEqualTo( this.hashUnitEqualTo(EventsFileChanger.create, "FilesChangeNotifierService create file");
EventsFileChanger.create,
"FilesChangeNotifierService create file"
);
this.cancel(); this.cancel();
} }
@ -39,28 +36,19 @@ export class FilesChangerTest extends FilesChangeNotifierService {
await delay(1000); await delay(1000);
fs.writeFileSync(this.filePath, this.data() + "132"); fs.writeFileSync(this.filePath, this.data() + "132");
await delay(500); await delay(500);
this.hashUnitEqualTo( this.hashUnitEqualTo(EventsFileChanger.update, "FilesChangeNotifierService update file");
EventsFileChanger.update,
"FilesChangeNotifierService update file"
);
this.cancel(); this.cancel();
} }
public async initFile() { public async initFile() {
this.init(); this.init();
await delay(500); await delay(500);
this.hashUnitEqualTo( this.hashUnitEqualTo(EventsFileChanger.static, "FilesChangeNotifierService init file");
EventsFileChanger.static,
"FilesChangeNotifierService init file"
);
} }
public async deleteFile() { public async deleteFile() {
this.call(); this.call();
fs.unlinkSync(this.filePath); fs.unlinkSync(this.filePath);
await delay(1000); await delay(1000);
this.hashUnitEqualTo( this.hashUnitEqualTo(EventsFileChanger.delete, "FilesChangeNotifierService delete file");
EventsFileChanger.delete,
"FilesChangeNotifierService delete file"
);
this.cancel(); this.cancel();
} }
public async notExistsDirectory() { public async notExistsDirectory() {

View file

@ -9,20 +9,13 @@ abstract class IStackServiceTest {
abstract test(): Promise<boolean>; abstract test(): Promise<boolean>;
} }
class SimpleTestStackServiceTest extends StackService implements IStackServiceTest {
class SimpleTestStackServiceTest
extends StackService
implements IStackServiceTest
{
constructor() { constructor() {
super(mockSimplePipeline, dirname__ + "/context/"); super(mockSimplePipeline, dirname__ + "/context/");
} }
async test(): Promise<boolean> { async test(): Promise<boolean> {
await this.call(); await this.call();
const testResult = readDirRecursive(this.path).equals( const testResult = readDirRecursive(this.path).equals(["1.txt", "test.txt"], true);
["1.txt", "test.txt"],
true
);
await delay(100); await delay(100);
rmSync(this.path + "example/", { recursive: true }); rmSync(this.path + "example/", { recursive: true });
return testResult; return testResult;

View file

@ -1,8 +1,5 @@
import { import { EventsFileChanger, MetaDataFileManagerModel } from "../../src/core/model/meta_data_file_manager_model";
EventsFileChanger,
MetaDataFileManagerModel,
} from "../../src/core/model/meta_data_file_manager_model";
import { TriggerService } from "../../src/core/services/trigger_service"; import { TriggerService } from "../../src/core/services/trigger_service";
import { TriggerType } from "../../src/features/triggers/trigger_model"; import { TriggerType } from "../../src/features/triggers/trigger_model";
import { assert } from "../test"; import { assert } from "../test";
@ -17,11 +14,7 @@ class TriggerServiceFileOkTest extends TriggerService implements TriggerTest {
value: ["context"], value: ["context"],
}, },
{ {
"/context/": new MetaDataFileManagerModel( "/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
"",
"",
EventsFileChanger.create
),
}, },
"" ""
); );
@ -32,10 +25,7 @@ class TriggerServiceFileOkTest extends TriggerService implements TriggerTest {
return r.isSuccess(); return r.isSuccess();
} }
} }
class TriggerServiceFileErrorTest class TriggerServiceFileErrorTest extends TriggerService implements TriggerTest {
extends TriggerService
implements TriggerTest
{
constructor() { constructor() {
super( super(
{ {
@ -44,11 +34,7 @@ class TriggerServiceFileErrorTest
}, },
{ {
"/ctx/": new MetaDataFileManagerModel("", "", EventsFileChanger.create), "/ctx/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
"/context/": new MetaDataFileManagerModel( "/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
"",
"",
EventsFileChanger.create
),
}, },
"" ""
@ -60,10 +46,7 @@ class TriggerServiceFileErrorTest
return r.isFailure(); return r.isFailure();
} }
} }
class TriggerServiceProcessOkTest class TriggerServiceProcessOkTest extends TriggerService implements TriggerTest {
extends TriggerService
implements TriggerTest
{
constructor() { constructor() {
super( super(
{ {
@ -77,11 +60,7 @@ class TriggerServiceProcessOkTest
], ],
}, },
{ {
"/context/": new MetaDataFileManagerModel( "/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
"",
"",
EventsFileChanger.create
),
}, },
"" ""
); );
@ -92,10 +71,7 @@ class TriggerServiceProcessOkTest
} }
} }
class TriggerServiceProcessErrorTest class TriggerServiceProcessErrorTest extends TriggerService implements TriggerTest {
extends TriggerService
implements TriggerTest
{
constructor() { constructor() {
super( super(
{ {
@ -109,11 +85,7 @@ class TriggerServiceProcessErrorTest
], ],
}, },
{ {
"/context/": new MetaDataFileManagerModel( "/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
"",
"",
EventsFileChanger.create
),
}, },
"" ""
); );

View file

@ -19,7 +19,6 @@ const testCore = TestCore.instance;
export const dirname__: string = dirname(__filename); export const dirname__: string = dirname(__filename);
export const assert = testCore.assert; export const assert = testCore.assert;
export const resultTest = testCore.resultTest; export const resultTest = testCore.resultTest;
const tests = [ const tests = [
CreateDataBaseModelUseCaseTest, CreateDataBaseModelUseCaseTest,

View file

@ -5,9 +5,7 @@ export class PaginationDataBaseModelUseCaseTest {
async test() { async test() {
let testIsSuccess = false; let testIsSuccess = false;
await ( await (
await new PaginationDataBaseModelUseCase<ITestModel>(TestDBModel, 1).call( await new PaginationDataBaseModelUseCase<ITestModel>(TestDBModel, 1).call(1)
1
)
).fold( ).fold(
(s) => { (s) => {
testIsSuccess = s.length === 1; testIsSuccess = s.length === 1;

View file

@ -6,20 +6,15 @@ export class ReadDataBaseModelUseCaseTest {
async test() { async test() {
let testIsSuccess = false; let testIsSuccess = false;
const result = await new CreateDataBaseModelUseCase<ITestModel>( const result = await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
TestDBModel
).call({
result: "test", result: "test",
}); });
await result.fold( await result.fold(
async (s) => { async (s) => {
const r = await new ReadByIdDataBaseModelUseCase<ITestModel>( const r = await new ReadByIdDataBaseModelUseCase<ITestModel>(TestDBModel).call(s.id);
TestDBModel
).call(s.id);
await r.fold( await r.fold(
(_s1) => { (_s1) => {
testIsSuccess = true; testIsSuccess = true;
}, },
(_e) => {} (_e) => {}
); );

View file

@ -6,18 +6,14 @@ export class UpdateDataBaseModelUseCaseTest {
async test() { async test() {
let testIsSuccess = false; let testIsSuccess = false;
const model = await new CreateDataBaseModelUseCase<ITestModel>( const model = await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
TestDBModel
).call({
result: "test", result: "test",
}); });
await model.fold( await model.fold(
async (s) => { async (s) => {
( (
await new UpdateDataBaseModelUseCase<any, ITestModel>( await new UpdateDataBaseModelUseCase<any, ITestModel>(TestDBModel).call({
TestDBModel _id: s.id,
).call({
_id:s.id,
result: "complete", result: "complete",
}) })
).fold( ).fold(

View file

@ -1,5 +1 @@
создание инстанца [ OK ] [ ]
получение всех инастанцев проектов и изменнение их [ OK ]
запуск инастанца проекта? [ OK ]
загрузка FILE [ ]

View file

@ -4,7 +4,6 @@ export class SocketRepository {
serverURL = "ws://localhost:4001"; serverURL = "ws://localhost:4001";
socket: Socket | undefined; socket: Socket | undefined;
async connect() { async connect() {
console.log('connect')
const socket = io(this.serverURL); const socket = io(this.serverURL);
this.socket = socket; this.socket = socket;
socket.connect(); socket.connect();