formatting code upload project instance to files
This commit is contained in:
parent
ce4c98ff13
commit
a0b4f00f47
65 changed files with 399 additions and 748 deletions
|
@ -19,24 +19,16 @@ export class CrudController<V, D> extends CoreHttpController<V> {
|
|||
}
|
||||
init() {
|
||||
if (this.routes["POST"] === null) {
|
||||
this.routes["POST"] = new CreateDataBaseModelUseCase<D>(
|
||||
this.dataBaseModel
|
||||
).call;
|
||||
this.routes["POST"] = new CreateDataBaseModelUseCase<D>(this.dataBaseModel).call;
|
||||
}
|
||||
if (this.routes["GET"] === null) {
|
||||
this.routes["GET"] = new PaginationDataBaseModelUseCase<D>(
|
||||
this.dataBaseModel
|
||||
).call;
|
||||
this.routes["GET"] = new PaginationDataBaseModelUseCase<D>(this.dataBaseModel).call;
|
||||
}
|
||||
if (this.routes["DELETE"] === null) {
|
||||
this.routes["DELETE"] = new DeleteDataBaseModelUseCase<D>(
|
||||
this.dataBaseModel
|
||||
).call;
|
||||
this.routes["DELETE"] = new DeleteDataBaseModelUseCase<D>(this.dataBaseModel).call;
|
||||
}
|
||||
if (this.routes["PUT"] === null) {
|
||||
this.routes["PUT"] = new UpdateDataBaseModelUseCase<V, D>(
|
||||
this.dataBaseModel
|
||||
).call;
|
||||
this.routes["PUT"] = new UpdateDataBaseModelUseCase<V, D>(this.dataBaseModel).call;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,15 +3,7 @@ import { Result } from "../helper/result";
|
|||
import { Router, Request, Response } from "express";
|
||||
import { IRouteModel, Routes } from "../interfaces/router";
|
||||
|
||||
export type Method =
|
||||
| "all"
|
||||
| "get"
|
||||
| "post"
|
||||
| "put"
|
||||
| "delete"
|
||||
| "patch"
|
||||
| "options"
|
||||
| "head";
|
||||
export type Method = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head";
|
||||
|
||||
export type ResponseBase = Promise<Result<any, any>>;
|
||||
|
||||
|
@ -75,7 +67,7 @@ export class CoreHttpController<V> implements ICoreHttpController {
|
|||
return;
|
||||
},
|
||||
(err) => {
|
||||
res.status(400).json(err);
|
||||
res.status(400).json({ error: String(err) });
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
@ -83,61 +75,46 @@ export class CoreHttpController<V> implements ICoreHttpController {
|
|||
call(): Routes {
|
||||
if (this.subRoutes.isNotEmpty()) {
|
||||
this.subRoutes.map((el) => {
|
||||
this.router[el.method](
|
||||
this.mainURL + "/" + el.subUrl,
|
||||
async (req, res) => {
|
||||
if (el.fn instanceof CallbackStrategyWithValidationModel) {
|
||||
// TODO(IDONTSUDO):
|
||||
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 CallbackStrategyWithEmpty) {
|
||||
await this.responseHelper(res, el.fn.call());
|
||||
this.router[el.method](this.mainURL + "/" + el.subUrl, async (req, res) => {
|
||||
if (el.fn instanceof CallbackStrategyWithValidationModel) {
|
||||
// TODO(IDONTSUDO):
|
||||
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 CallbackStrategyWithEmpty) {
|
||||
await this.responseHelper(res, el.fn.call());
|
||||
return;
|
||||
}
|
||||
|
||||
if (el.fn instanceof CallbackStrategyWithFileUpload) {
|
||||
if (req["files"] === undefined) {
|
||||
res.status(400).json("need files to form-data request");
|
||||
return;
|
||||
}
|
||||
|
||||
if (el.fn instanceof CallbackStrategyWithFileUpload) {
|
||||
if (req["files"] === undefined) {
|
||||
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 (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 (this.routes["POST"] != null) {
|
||||
this.router.post(
|
||||
this.mainURL,
|
||||
validationModelMiddleware(this.validationModel),
|
||||
(req, res) =>
|
||||
this.requestResponseController<V>(req, res, this.routes["POST"])
|
||||
this.router.post(this.mainURL, validationModelMiddleware(this.validationModel), (req, res) =>
|
||||
this.requestResponseController<V>(req, res, this.routes["POST"])
|
||||
);
|
||||
}
|
||||
if (this.routes["DELETE"] != null) {
|
||||
|
@ -146,17 +123,12 @@ export class CoreHttpController<V> implements ICoreHttpController {
|
|||
);
|
||||
}
|
||||
if (this.routes["PUT"] != null) {
|
||||
this.router.put(
|
||||
this.mainURL,
|
||||
validationModelMiddleware(this.validationModel),
|
||||
(req, res) =>
|
||||
this.requestResponseController<V>(req, res, this.routes["PUT"])
|
||||
this.router.put(this.mainURL, validationModelMiddleware(this.validationModel), (req, res) =>
|
||||
this.requestResponseController<V>(req, res, this.routes["PUT"])
|
||||
);
|
||||
}
|
||||
if (this.routes["GET"] != null) {
|
||||
this.router.get(this.mainURL, (req, res) =>
|
||||
this.requestResponseController<V>(req, res, this.routes["GET"])
|
||||
);
|
||||
this.router.get(this.mainURL, (req, res) => this.requestResponseController<V>(req, res, this.routes["GET"]));
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -193,7 +165,7 @@ export class CoreHttpController<V> implements ICoreHttpController {
|
|||
return;
|
||||
},
|
||||
(err) => {
|
||||
res.status(400).json(err);
|
||||
res.status(400).json({ error: String(err) });
|
||||
return;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -8,4 +8,3 @@ export class SocketSubscriber<T> {
|
|||
this.event = event;
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ declare global {
|
|||
interface String {
|
||||
isEmpty(): boolean;
|
||||
isNotEmpty(): boolean;
|
||||
fixToPath(): string;
|
||||
lastElement(): string;
|
||||
}
|
||||
}
|
||||
export const extensions = () => {
|
||||
|
|
|
@ -11,4 +11,21 @@ export const StringExtensions = () => {
|
|||
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;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
export function delay(ms: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable @typescript-eslint/ban-types */
|
||||
/* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */
|
||||
/* eslint-disable @typescript-eslint/no-namespace */
|
||||
|
||||
|
||||
function isAsyncFn(fn: Function) {
|
||||
return fn.constructor.name === "AsyncFunction";
|
||||
|
@ -17,7 +16,6 @@ interface SyncThenable {
|
|||
then<Fn extends () => any>(cb: Fn): SyncThenable;
|
||||
}
|
||||
|
||||
|
||||
function syncThenable(): SyncThenable {
|
||||
function then<Fn extends () => Promise<any>>(cb: Fn): ReturnType<Fn>;
|
||||
function then<Fn extends () => any>(cb: Fn): SyncThenable;
|
||||
|
@ -36,11 +34,7 @@ function syncThenable(): SyncThenable {
|
|||
};
|
||||
}
|
||||
|
||||
function forEachValueThunkOrPromise<T>(
|
||||
items: unknown[],
|
||||
execFn: (value: T) => boolean,
|
||||
foldFn: () => unknown
|
||||
) {
|
||||
function forEachValueThunkOrPromise<T>(items: unknown[], execFn: (value: T) => boolean, foldFn: () => unknown) {
|
||||
let shouldBreak = false;
|
||||
|
||||
const result: any = items.reduce((prev: { then: Function }, valueOrThunk) => {
|
||||
|
@ -56,8 +50,7 @@ function forEachValueThunkOrPromise<T>(
|
|||
}
|
||||
}
|
||||
|
||||
const valueOrPromise =
|
||||
typeof valueOrThunk === "function" ? valueOrThunk() : valueOrThunk;
|
||||
const valueOrPromise = typeof valueOrThunk === "function" ? valueOrThunk() : valueOrThunk;
|
||||
|
||||
if (valueOrPromise instanceof Promise) {
|
||||
return valueOrPromise.then(run);
|
||||
|
@ -76,11 +69,9 @@ function forEachValueThunkOrPromise<T>(
|
|||
});
|
||||
}
|
||||
|
||||
export type Result<
|
||||
ErrorType,
|
||||
OkType,
|
||||
RollbackFn extends RollbackFunction = any
|
||||
> = Ok<ErrorType, OkType, RollbackFn> | Err<ErrorType, OkType, RollbackFn>;
|
||||
export type Result<ErrorType, OkType, RollbackFn extends RollbackFunction = any> =
|
||||
| Ok<ErrorType, OkType, RollbackFn>
|
||||
| Err<ErrorType, OkType, RollbackFn>;
|
||||
|
||||
interface IResult<ErrorType, OkType> {
|
||||
isSuccess(): this is Ok<ErrorType, OkType, any>;
|
||||
|
@ -93,14 +84,8 @@ interface IResult<ErrorType, OkType> {
|
|||
|
||||
inspect(): string;
|
||||
|
||||
fold<R>(
|
||||
onSuccess: (value: OkType) => R,
|
||||
onFailure: (error: ErrorType) => R
|
||||
): R;
|
||||
fold<R>(
|
||||
onSuccess: (value: OkType) => Promise<R>,
|
||||
onFailure: (error: ErrorType) => Promise<R>
|
||||
): Promise<R>;
|
||||
fold<R>(onSuccess: (value: OkType) => R, onFailure: (error: ErrorType) => R): R;
|
||||
fold<R>(onSuccess: (value: OkType) => Promise<R>, onFailure: (error: ErrorType) => Promise<R>): Promise<R>;
|
||||
|
||||
getOrDefault(defaultValue: OkType): OkType;
|
||||
|
||||
|
@ -111,37 +96,17 @@ interface IResult<ErrorType, OkType> {
|
|||
|
||||
map<T>(
|
||||
fn: (value: OkType) => Promise<T>
|
||||
): Promise<
|
||||
JoinErrorTypes<
|
||||
ErrorType,
|
||||
T extends Result<any, any, any> ? T : Result<Error, T, any>
|
||||
>
|
||||
>;
|
||||
): Promise<JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>>;
|
||||
map<T>(
|
||||
fn: (value: OkType) => T
|
||||
): 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>>;
|
||||
|
||||
rollback(): Result<Error, void> | Promise<Result<Error, void>>;
|
||||
}
|
||||
|
||||
type InferErrorType<T extends Result<any, any, any>> = T extends Result<
|
||||
infer Errortype,
|
||||
any,
|
||||
any
|
||||
>
|
||||
? Errortype
|
||||
: never;
|
||||
type InferErrorType<T extends Result<any, any, any>> = T extends Result<infer Errortype, any, any> ? Errortype : never;
|
||||
|
||||
type InferOkType<T extends Result<any, any, any>> = T extends Result<
|
||||
any,
|
||||
infer OkType,
|
||||
any
|
||||
>
|
||||
? OkType
|
||||
: never;
|
||||
type InferOkType<T extends Result<any, any, any>> = T extends Result<any, infer OkType, any> ? OkType : never;
|
||||
|
||||
type JoinErrorTypes<ErrorType, B extends Result<any, any, any>> = Result<
|
||||
ErrorType | InferErrorType<B>,
|
||||
|
@ -150,15 +115,11 @@ type JoinErrorTypes<ErrorType, B extends Result<any, any, any>> = Result<
|
|||
>;
|
||||
|
||||
type ExtractErrorTypes<Tuple extends any[]> = {
|
||||
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any>
|
||||
? InferErrorType<Tuple[Index]>
|
||||
: never;
|
||||
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> ? InferErrorType<Tuple[Index]> : never;
|
||||
}[number];
|
||||
|
||||
type MapResultTupleToOkTypeTuple<Tuple extends any[]> = {
|
||||
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any>
|
||||
? InferOkType<Tuple[Index]>
|
||||
: never;
|
||||
[Index in keyof Tuple]: Tuple[Index] extends Result<any, any, any> ? InferOkType<Tuple[Index]> : never;
|
||||
};
|
||||
|
||||
type RollbackFunction = (() => void) | (() => Promise<void>);
|
||||
|
@ -174,11 +135,7 @@ type HasAsyncRollbackFunction<T extends any[]> = {
|
|||
: true;
|
||||
|
||||
type UnwrapThunks<T extends any[]> = {
|
||||
[Index in keyof T]: T[Index] extends () => Promise<infer U>
|
||||
? U
|
||||
: T[Index] extends () => infer U
|
||||
? U
|
||||
: T[Index];
|
||||
[Index in keyof T]: T[Index] extends () => Promise<infer U> ? U : T[Index] extends () => infer U ? U : T[Index];
|
||||
};
|
||||
|
||||
type HasAsyncThunk<T extends any[]> = {
|
||||
|
@ -187,32 +144,17 @@ type HasAsyncThunk<T extends any[]> = {
|
|||
? false
|
||||
: true;
|
||||
|
||||
type PromiseReturnType<T extends (...args: any) => any> = T extends (
|
||||
...args: any
|
||||
) => Promise<infer U>
|
||||
? U
|
||||
: never;
|
||||
type PromiseReturnType<T extends (...args: any) => any> = T extends (...args: any) => Promise<infer U> ? U : never;
|
||||
|
||||
export namespace Result {
|
||||
export function ok<
|
||||
ErrorType extends unknown,
|
||||
OkType,
|
||||
RollbackFn extends RollbackFunction = any
|
||||
>(
|
||||
export function ok<ErrorType extends unknown, OkType, RollbackFn extends RollbackFunction = any>(
|
||||
value?: OkType,
|
||||
rollbackFn?: RollbackFn
|
||||
): Result<ErrorType, OkType, RollbackFn> {
|
||||
return new Ok<ErrorType, OkType, RollbackFn>(
|
||||
value || null!,
|
||||
rollbackFn
|
||||
) as any;
|
||||
return new Ok<ErrorType, OkType, RollbackFn>(value || null!, rollbackFn) as any;
|
||||
}
|
||||
|
||||
export function error<
|
||||
ErrorType extends unknown,
|
||||
OkType extends unknown,
|
||||
RollbackFn extends RollbackFunction = any
|
||||
>(
|
||||
export function error<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction = any>(
|
||||
error: ErrorType,
|
||||
rollbackFn?: RollbackFn
|
||||
): Result<ErrorType, OkType, RollbackFn> {
|
||||
|
@ -223,9 +165,7 @@ export namespace Result {
|
|||
? Result<E | InferErrorType<T>, InferOkType<T>, never>
|
||||
: Result<E, T, never>;
|
||||
|
||||
export function safe<T>(
|
||||
fn: () => Promise<T>
|
||||
): Promise<SafeReturnType<Error, T>>;
|
||||
export function safe<T>(fn: () => Promise<T>): Promise<SafeReturnType<Error, T>>;
|
||||
export function safe<T>(fn: () => T): SafeReturnType<Error, T>;
|
||||
export function safe<ErrorType, T>(
|
||||
err: ErrorType | (new (...args: any[]) => ErrorType),
|
||||
|
@ -263,29 +203,21 @@ export namespace Result {
|
|||
.catch((caughtError) => error(getError(caughtError)));
|
||||
}
|
||||
|
||||
return isResult(resultOrPromise)
|
||||
? resultOrPromise
|
||||
: Result.ok(resultOrPromise);
|
||||
return isResult(resultOrPromise) ? resultOrPromise : Result.ok(resultOrPromise);
|
||||
} catch (caughtError) {
|
||||
return error(getError(caughtError as Error));
|
||||
}
|
||||
}
|
||||
|
||||
type CombineResult<
|
||||
T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]
|
||||
> = Result<
|
||||
type CombineResult<T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]> = Result<
|
||||
ExtractErrorTypes<UnwrapThunks<T>>,
|
||||
MapResultTupleToOkTypeTuple<UnwrapThunks<T>>,
|
||||
HasAsyncRollbackFunction<T> extends true ? () => Promise<void> : () => void
|
||||
>;
|
||||
|
||||
export function combine<
|
||||
T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]
|
||||
>(
|
||||
export function combine<T extends (unknown | (() => unknown) | (() => Promise<unknown>))[]>(
|
||||
...items: T
|
||||
): HasAsyncThunk<T> extends true
|
||||
? Promise<CombineResult<T>>
|
||||
: CombineResult<T> {
|
||||
): HasAsyncThunk<T> extends true ? Promise<CombineResult<T>> : CombineResult<T> {
|
||||
if (!items.length) {
|
||||
throw new Error("Expected at least 1 argument");
|
||||
}
|
||||
|
@ -332,9 +264,7 @@ export namespace Result {
|
|||
|
||||
export function wrap<Fn extends (...args: any) => Promise<any>>(
|
||||
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>(
|
||||
fn: Fn
|
||||
): (...args: Parameters<Fn>) => Result<Error, ReturnType<Fn>, never>;
|
||||
|
@ -344,9 +274,7 @@ export namespace Result {
|
|||
const resultOrPromise = fn(...args);
|
||||
|
||||
if (resultOrPromise instanceof Promise) {
|
||||
return resultOrPromise
|
||||
.then((okValue) => Result.ok(okValue))
|
||||
.catch((err) => error(err));
|
||||
return resultOrPromise.then((okValue) => Result.ok(okValue)).catch((err) => error(err));
|
||||
}
|
||||
|
||||
return ok(resultOrPromise);
|
||||
|
@ -357,11 +285,8 @@ export namespace Result {
|
|||
}
|
||||
}
|
||||
|
||||
abstract class Base<
|
||||
ErrorType extends unknown,
|
||||
OkType extends unknown,
|
||||
RollbackFn extends RollbackFunction
|
||||
> implements IResult<ErrorType, OkType>
|
||||
abstract class Base<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction>
|
||||
implements IResult<ErrorType, OkType>
|
||||
{
|
||||
constructor(protected readonly rollbackFn?: RollbackFn) {}
|
||||
|
||||
|
@ -388,14 +313,8 @@ abstract class Base<
|
|||
return this.toString();
|
||||
}
|
||||
|
||||
fold<R>(
|
||||
onSuccess: (value: OkType) => R,
|
||||
onFailure: (error: ErrorType) => R
|
||||
): R;
|
||||
fold<R>(
|
||||
onSuccess: (value: OkType) => Promise<R>,
|
||||
onFailure: (error: ErrorType) => Promise<R>
|
||||
): Promise<R>;
|
||||
fold<R>(onSuccess: (value: OkType) => 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) {
|
||||
if (this.isFailure()) {
|
||||
return onFailure(this.error);
|
||||
|
@ -439,18 +358,10 @@ abstract class Base<
|
|||
|
||||
map<T>(
|
||||
fn: (value: OkType) => Promise<T>
|
||||
): Promise<
|
||||
JoinErrorTypes<
|
||||
ErrorType,
|
||||
T extends Result<any, any, any> ? T : Result<Error, T, any>
|
||||
>
|
||||
>;
|
||||
): Promise<JoinErrorTypes<ErrorType, T extends Result<any, any, any> ? T : Result<Error, T, any>>>;
|
||||
map<T>(
|
||||
fn: (value: OkType) => T
|
||||
): 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(fn: any) {
|
||||
if (this.isFailure()) {
|
||||
return isAsyncFn(fn) ? Promise.resolve(this) : this;
|
||||
|
@ -474,11 +385,11 @@ abstract class Base<
|
|||
}
|
||||
}
|
||||
|
||||
class Ok<
|
||||
ErrorType extends unknown,
|
||||
OkType extends unknown,
|
||||
RollbackFn extends RollbackFunction
|
||||
> extends Base<ErrorType, OkType, RollbackFn> {
|
||||
class Ok<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction> extends Base<
|
||||
ErrorType,
|
||||
OkType,
|
||||
RollbackFn
|
||||
> {
|
||||
public readonly value: OkType;
|
||||
|
||||
constructor(val: OkType, rollbackFn?: RollbackFn) {
|
||||
|
@ -503,11 +414,11 @@ class Ok<
|
|||
}
|
||||
}
|
||||
|
||||
class Err<
|
||||
ErrorType extends unknown,
|
||||
OkType extends unknown,
|
||||
RollbackFn extends RollbackFunction
|
||||
> extends Base<ErrorType, OkType, RollbackFn> {
|
||||
class Err<ErrorType extends unknown, OkType extends unknown, RollbackFn extends RollbackFunction> extends Base<
|
||||
ErrorType,
|
||||
OkType,
|
||||
RollbackFn
|
||||
> {
|
||||
public readonly error: ErrorType;
|
||||
|
||||
constructor(err: ErrorType, rollbackFn?: RollbackFn) {
|
||||
|
|
|
@ -1,49 +1,42 @@
|
|||
export interface Listener<T> {
|
||||
(event: T): any;
|
||||
(event: T): any;
|
||||
}
|
||||
|
||||
export interface Disposable {
|
||||
dispose():void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
|
||||
export class TypedEvent<T> {
|
||||
private listeners: Listener<T>[] = [];
|
||||
public listenersOnces: Listener<T>[] = [];
|
||||
private listeners: Listener<T>[] = [];
|
||||
public listenersOnces: Listener<T>[] = [];
|
||||
|
||||
on = (listener: Listener<T>): Disposable => {
|
||||
this.listeners.push(listener);
|
||||
return {
|
||||
dispose: () => this.off(listener),
|
||||
};
|
||||
on = (listener: Listener<T>): Disposable => {
|
||||
this.listeners.push(listener);
|
||||
return {
|
||||
dispose: () => this.off(listener),
|
||||
};
|
||||
};
|
||||
|
||||
once = (listener: Listener<T>): void => {
|
||||
this.listenersOnces.push(listener);
|
||||
};
|
||||
once = (listener: Listener<T>): void => {
|
||||
this.listenersOnces.push(listener);
|
||||
};
|
||||
|
||||
off = (listener: Listener<T>) => {
|
||||
const callbackIndex = this.listeners.indexOf(
|
||||
listener
|
||||
);
|
||||
if (callbackIndex > -1)
|
||||
this.listeners.splice(callbackIndex, 1);
|
||||
};
|
||||
off = (listener: Listener<T>) => {
|
||||
const callbackIndex = this.listeners.indexOf(listener);
|
||||
if (callbackIndex > -1) this.listeners.splice(callbackIndex, 1);
|
||||
};
|
||||
|
||||
emit = (event: T) => {
|
||||
|
||||
this.listeners.forEach((listener) =>
|
||||
listener(event)
|
||||
);
|
||||
emit = (event: T) => {
|
||||
this.listeners.forEach((listener) => listener(event));
|
||||
|
||||
if (this.listenersOnces.length > 0) {
|
||||
const toCall = this.listenersOnces;
|
||||
this.listenersOnces = [];
|
||||
toCall.forEach((listener) => listener(event));
|
||||
}
|
||||
};
|
||||
if (this.listenersOnces.length > 0) {
|
||||
const toCall = this.listenersOnces;
|
||||
this.listenersOnces = [];
|
||||
toCall.forEach((listener) => listener(event));
|
||||
}
|
||||
};
|
||||
|
||||
pipe = (te: TypedEvent<T>): Disposable => {
|
||||
return this.on((e) => te.emit(e));
|
||||
};
|
||||
}
|
||||
pipe = (te: TypedEvent<T>): Disposable => {
|
||||
return this.on((e) => te.emit(e));
|
||||
};
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ export interface WorkerDataExec {
|
|||
command: string;
|
||||
execPath: string;
|
||||
type: WorkerType;
|
||||
cliArgs:Array<string> | undefined
|
||||
cliArgs: Array<string> | undefined;
|
||||
}
|
||||
|
||||
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) {
|
||||
process.send({
|
||||
type: EXEC_TYPE.SPAWN.toString(),
|
||||
event: EXEC_EVENT.END.toString(),
|
||||
data:null
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
process.on("uncaughtException", (error) => {
|
||||
if (process.send) {
|
||||
process.send({
|
||||
|
@ -50,26 +50,21 @@ process.on("message", async (message) => {
|
|||
});
|
||||
} else if (workerData.type == WorkerType.EXEC) {
|
||||
try {
|
||||
const result = await exec(workerData.command, {
|
||||
const result = await exec(workerData.command, {
|
||||
cwd: workerData.execPath,
|
||||
});
|
||||
if (process.send) {
|
||||
process.send(
|
||||
new ExecutorResult(EXEC_TYPE.EXEC, EXEC_EVENT.END, result)
|
||||
);
|
||||
process.send(new ExecutorResult(EXEC_TYPE.EXEC, EXEC_EVENT.END, result));
|
||||
}
|
||||
} catch (error) {
|
||||
if (process.send) {
|
||||
process.send(new ExecError(workerData.command, error ));
|
||||
if (process.send) {
|
||||
process.send(new ExecError(workerData.command, error));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
async function exec(
|
||||
cmd: string,
|
||||
opts: cp.ExecOptions & { trim?: boolean } = {}
|
||||
): Promise<string> {
|
||||
async function exec(cmd: string, opts: cp.ExecOptions & { trim?: boolean } = {}): Promise<string> {
|
||||
return new Promise((c, e) => {
|
||||
cp.exec(cmd, { env: process.env, ...opts }, (err, stdout) => {
|
||||
return err ? e(err) : c(opts.trim ? stdout.trim() : stdout);
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// export class Payload<T>{
|
||||
// model: T | undefined
|
||||
// query:string | undefined
|
||||
|
@ -11,4 +10,4 @@
|
|||
// isEmpty(){
|
||||
// return this.model != undefined || this.query != undefined
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -9,6 +9,3 @@ export interface IRouteModel {
|
|||
url: string;
|
||||
databaseModel: any;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -7,9 +7,7 @@ export const validationMiddleware = (
|
|||
whitelist = true,
|
||||
forbidNonWhitelisted = true
|
||||
): RequestHandler => {
|
||||
// TODO:(IDONTSUDO) need TOKEN
|
||||
// return nextTick
|
||||
return (req, res, next) => {
|
||||
|
||||
}
|
||||
// TODO:(IDONTSUDO) need TOKEN
|
||||
// return nextTick
|
||||
return (req, res, next) => {};
|
||||
};
|
||||
|
|
|
@ -1,30 +1,28 @@
|
|||
import { plainToInstance } from 'class-transformer';
|
||||
import { validate, ValidationError } from 'class-validator';
|
||||
import { RequestHandler } from 'express';
|
||||
|
||||
import { plainToInstance } from "class-transformer";
|
||||
import { validate, ValidationError } from "class-validator";
|
||||
import { RequestHandler } from "express";
|
||||
|
||||
export const validationModelMiddleware = (
|
||||
type: any,
|
||||
value = 'body',
|
||||
value = "body",
|
||||
skipMissingProperties = false,
|
||||
whitelist = true,
|
||||
forbidNonWhitelisted = true,
|
||||
forbidNonWhitelisted = true
|
||||
): RequestHandler => {
|
||||
return (req, res, next) => {
|
||||
|
||||
if(type === null && type == undefined){
|
||||
next()
|
||||
return
|
||||
if (type === null && type == undefined) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const model = plainToInstance(type, req[value]);
|
||||
validate(model, { skipMissingProperties, whitelist, forbidNonWhitelisted }).then((errors: ValidationError[]) => {
|
||||
if (errors.length > 0) {
|
||||
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(', ');
|
||||
return res.status(400).json(message)
|
||||
const message = errors.map((error: ValidationError) => Object.values(error.constraints)).join(", ");
|
||||
return res.status(400).json(message);
|
||||
} else {
|
||||
req['model'] = model
|
||||
req["model"] = model;
|
||||
next();
|
||||
}
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -3,18 +3,22 @@ export class ActivePipeline {
|
|||
projectUUID?: string | null;
|
||||
lastProcessCompleteCount: number | null;
|
||||
error: any;
|
||||
path: string;
|
||||
constructor(
|
||||
pipelineIsRunning: boolean,
|
||||
lastProcessCompleteCount: number | null,
|
||||
error: any,
|
||||
path: string | null,
|
||||
projectUUID?: string | null
|
||||
) {
|
||||
this.pipelineIsRunning = pipelineIsRunning;
|
||||
this.projectUUID = projectUUID;
|
||||
this.lastProcessCompleteCount = lastProcessCompleteCount;
|
||||
this.error = error;
|
||||
this.path = path;
|
||||
}
|
||||
|
||||
static empty() {
|
||||
return new ActivePipeline(false, null, null, null);
|
||||
return new ActivePipeline(false, null, null, null, null);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,16 +30,8 @@ export class SpawnError extends Error {
|
|||
this.unixTime = Date.now();
|
||||
}
|
||||
static isError(errorType: any): SpawnError | void {
|
||||
if (
|
||||
"command" in errorType &&
|
||||
"error" in errorType &&
|
||||
"execPath" in errorType
|
||||
) {
|
||||
return new SpawnError(
|
||||
errorType.command,
|
||||
errorType.execPath,
|
||||
errorType.error
|
||||
);
|
||||
if ("command" in errorType && "error" in errorType && "execPath" in errorType) {
|
||||
return new SpawnError(errorType.command, errorType.execPath, errorType.error);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export class MetaDataFileManagerModel {
|
|||
this.event = event;
|
||||
this.unixTime = Date.now();
|
||||
}
|
||||
|
||||
|
||||
public get timeString(): string {
|
||||
const date = new Date(this.unixTime * 1000);
|
||||
const hours = date.getHours();
|
||||
|
|
|
@ -8,6 +8,8 @@ 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) => {
|
||||
|
|
|
@ -11,7 +11,7 @@ abstract class IExecutorProgramService {
|
|||
}
|
||||
|
||||
export class ExecutorProgramService
|
||||
extends TypedEvent<Result<ExecError | SpawnError, ExecutorResult>>
|
||||
extends TypedEvent<Result<ExecError | SpawnError, ExecutorResult>>
|
||||
implements IExecutorProgramService
|
||||
{
|
||||
static event = "ExecutorProgramService";
|
||||
|
@ -25,11 +25,7 @@ export class ExecutorProgramService
|
|||
this.maxTime = maxTime;
|
||||
}
|
||||
|
||||
private async workerExecuted(
|
||||
command: string,
|
||||
workerType: WorkerType,
|
||||
args: Array<string> | undefined = undefined
|
||||
) {
|
||||
private async workerExecuted(command: string, workerType: WorkerType, args: Array<string> | undefined = undefined) {
|
||||
cluster.setupPrimary({
|
||||
exec: "./src/core/helper/worker_computed",
|
||||
});
|
||||
|
@ -69,21 +65,13 @@ export class ExecutorProgramService
|
|||
setTimeout(() => {
|
||||
this.worker.kill();
|
||||
this.emit(
|
||||
Result.error(
|
||||
WorkerType.EXEC
|
||||
? new ExecError(command, "timeout err")
|
||||
: new SpawnError(command, "timeout err")
|
||||
)
|
||||
Result.error(WorkerType.EXEC ? new ExecError(command, "timeout err") : new SpawnError(command, "timeout err"))
|
||||
);
|
||||
}, this.maxTime!);
|
||||
}
|
||||
}
|
||||
|
||||
public async call(
|
||||
type: EXEC_TYPE,
|
||||
command: string,
|
||||
args: Array<string> | undefined = undefined
|
||||
): Promise<void> {
|
||||
public async call(type: EXEC_TYPE, command: string, args: Array<string> | undefined = undefined): Promise<void> {
|
||||
if (type == EXEC_TYPE.EXEC) {
|
||||
this.workerExecuted(command, WorkerType.EXEC);
|
||||
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
import * as fs from "fs";
|
||||
import { resolve } from "node:path";
|
||||
|
||||
import { createHash } from "node:crypto";
|
||||
import "reflect-metadata";
|
||||
import { BinaryLike } from "crypto";
|
||||
import {
|
||||
EventsFileChanger,
|
||||
MetaDataFileManagerModel,
|
||||
} from "../model/meta_data_file_manager_model";
|
||||
import { EventsFileChanger, MetaDataFileManagerModel } from "../model/meta_data_file_manager_model";
|
||||
import { Result } from "../helper/result";
|
||||
import { TypedEvent } from "../helper/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]));
|
||||
|
@ -25,10 +18,7 @@ async function readFileAtBuffer(path: string): Promise<Buffer> {
|
|||
await readdir(path, {
|
||||
encoding: "buffer",
|
||||
})
|
||||
).reduce(
|
||||
(accumulator, currentValue) => joinBuffers([accumulator, currentValue]),
|
||||
Buffer.from("")
|
||||
);
|
||||
).reduce((accumulator, currentValue) => joinBuffers([accumulator, currentValue]), Buffer.from(""));
|
||||
}
|
||||
return await readFileAsync(path);
|
||||
}
|
||||
|
@ -47,7 +37,6 @@ export abstract class IFilesChangeNotifierService {
|
|||
abstract directory: string;
|
||||
}
|
||||
|
||||
|
||||
export class FilesChangeNotifierService
|
||||
extends TypedEvent<Result<Error, IHashesCache>>
|
||||
implements IFilesChangeNotifierService
|
||||
|
@ -70,11 +59,7 @@ export class FilesChangeNotifierService
|
|||
const data = await readFileAsync(file);
|
||||
const md5Current = await md5(data);
|
||||
|
||||
this.hashes[file] = new MetaDataFileManagerModel(
|
||||
file,
|
||||
md5Current,
|
||||
EventsFileChanger.static
|
||||
);
|
||||
this.hashes[file] = new MetaDataFileManagerModel(file, md5Current, EventsFileChanger.static);
|
||||
this.emit(Result.ok(this.hashes));
|
||||
}
|
||||
async getFiles(dir: string): Promise<string | any[]> {
|
||||
|
@ -92,46 +77,31 @@ export class FilesChangeNotifierService
|
|||
try {
|
||||
let md5Previous: string | null = null;
|
||||
let fsWait: NodeJS.Timeout | boolean = false;
|
||||
const watcher = fs.watch(
|
||||
this.directory,
|
||||
{ recursive: true },
|
||||
async (_e, filename) => {
|
||||
const filePath = this.directory + filename;
|
||||
if (filename) {
|
||||
if (fsWait) return;
|
||||
fsWait = setTimeout(() => {
|
||||
fsWait = false;
|
||||
}, 100);
|
||||
try {
|
||||
const file = await readFileAtBuffer(filePath);
|
||||
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 watcher = fs.watch(this.directory, { recursive: true }, async (_e, filename) => {
|
||||
const filePath = this.directory + filename;
|
||||
if (filename) {
|
||||
if (fsWait) return;
|
||||
fsWait = setTimeout(() => {
|
||||
fsWait = false;
|
||||
}, 100);
|
||||
try {
|
||||
const file = await readFileAtBuffer(filePath);
|
||||
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);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
this.watcher = watcher;
|
||||
return Result.ok(true);
|
||||
} catch (error) {
|
||||
|
|
|
@ -3,19 +3,17 @@ import { ExecError } from "../model/exec_error_model";
|
|||
import { ExecutorResult } from "../model/executor_result";
|
||||
import { ActivePipeline } from "../model/active_pipeline_model";
|
||||
import { IPipeline } from "../model/process_model";
|
||||
import { Iteration, StackService } from "./stack_service";
|
||||
import { Iteration } from "./stack_service";
|
||||
|
||||
export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
|
||||
status: ActivePipeline;
|
||||
pipelineModels?: IPipeline[];
|
||||
path: string;
|
||||
constructor() {
|
||||
super();
|
||||
this.init();
|
||||
}
|
||||
private init(): void {
|
||||
this.status = ActivePipeline.empty();
|
||||
|
||||
}
|
||||
pipelineSubscriber = (iterations: Iteration[]): void => {
|
||||
if (this.status["lastProcessCompleteCount"] === 0) {
|
||||
|
@ -56,25 +54,18 @@ export class PipelineRealTimeService extends TypedEvent<ActivePipeline> {
|
|||
}
|
||||
}
|
||||
pipelineCompleted() {
|
||||
const pipelineIsCompleted =
|
||||
this.status.lastProcessCompleteCount === this.pipelineModels?.length;
|
||||
const pipelineIsCompleted = this.status.lastProcessCompleteCount === this.pipelineModels?.length;
|
||||
if (pipelineIsCompleted) {
|
||||
this.status.pipelineIsRunning = false;
|
||||
}
|
||||
}
|
||||
setPipelineDependency(
|
||||
pipelineModels: IPipeline[],
|
||||
path: string,
|
||||
projectUUID: string
|
||||
) {
|
||||
setPipelineDependency(pipelineModels: IPipeline[], path: string, projectUUID: string) {
|
||||
this.pipelineModels = pipelineModels;
|
||||
this.path = path;
|
||||
this.status["projectUUID"] = projectUUID;
|
||||
this.status["path"] = path;
|
||||
}
|
||||
runPipeline(): void {
|
||||
|
||||
// const stack = new StackService(this.pipelineModels, this.path);
|
||||
|
||||
// this.status["pipelineIsRunning"] = true;
|
||||
// stack.on(this.pipelineSubscriber);
|
||||
// stack.call();
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import {
|
||||
FilesChangeNotifierService,
|
||||
IHashesCache,
|
||||
} from "./files_change_notifier_service";
|
||||
import { FilesChangeNotifierService, IHashesCache } from "./files_change_notifier_service";
|
||||
import { IPipeline } from "../model/process_model";
|
||||
import { ExecutorProgramService } from "./executor_program_service";
|
||||
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;
|
||||
}
|
||||
|
||||
export class StackService
|
||||
extends TypedEvent<Iteration[]>
|
||||
implements IStackService
|
||||
{
|
||||
export class StackService extends TypedEvent<Iteration[]> implements IStackService {
|
||||
callStack: Iteration[];
|
||||
path: string;
|
||||
constructor(processed: IPipeline[], path: string) {
|
||||
|
@ -47,11 +41,7 @@ export class StackService
|
|||
}
|
||||
}
|
||||
private commandHandler(processMetaData: IPipeline) {
|
||||
processMetaData.process.command = processMetaData.process.command.replace(
|
||||
"$PATH",
|
||||
this.path
|
||||
);
|
||||
console.log(processMetaData.process.command)
|
||||
processMetaData.process.command = processMetaData.process.command.replace("$PATH", this.path);
|
||||
return processMetaData;
|
||||
}
|
||||
public async call() {
|
||||
|
@ -63,34 +53,21 @@ export class StackService
|
|||
this.emit(this.callStack);
|
||||
}
|
||||
}
|
||||
async execStack(
|
||||
stackNumber: number,
|
||||
stackLayer: Iteration
|
||||
): Promise<void | boolean> {
|
||||
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.call(stackLayer.process.process.type, stackLayer.process.process.command);
|
||||
|
||||
const filesChangeNotifierService = new FilesChangeNotifierService(
|
||||
this.path
|
||||
);
|
||||
const filesChangeNotifierService = new FilesChangeNotifierService(this.path);
|
||||
|
||||
filesChangeNotifierService.call();
|
||||
const result = await this.waitEvent<
|
||||
Result<ExecError | SpawnError, ExecutorResult>
|
||||
>(executorService);
|
||||
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
|
||||
);
|
||||
const triggerResult = await this.triggerExec(stackLayer.process.trigger, stackNumber);
|
||||
triggerResult.fold(
|
||||
(s) => {
|
||||
s;
|
||||
|
@ -125,10 +102,7 @@ export class StackService
|
|||
});
|
||||
return promise;
|
||||
}
|
||||
private async triggerExec(
|
||||
trigger: Trigger | null,
|
||||
stackNumber: number
|
||||
): Promise<Result<boolean, boolean>> {
|
||||
private async triggerExec(trigger: Trigger | null, stackNumber: number): Promise<Result<boolean, boolean>> {
|
||||
if (trigger !== null) {
|
||||
const hashes = this.callStack[stackNumber].hashes;
|
||||
|
||||
|
|
|
@ -35,11 +35,7 @@ export class TriggerErrorReport extends Error {
|
|||
hashes: IHashesCache;
|
||||
trigger: string | Trigger;
|
||||
processOutput: any;
|
||||
constructor(
|
||||
hashes: IHashesCache,
|
||||
trigger: string | Trigger,
|
||||
processOutput?: any
|
||||
) {
|
||||
constructor(hashes: IHashesCache, trigger: string | Trigger, processOutput?: any) {
|
||||
super();
|
||||
this.hashes = hashes;
|
||||
this.trigger = trigger;
|
||||
|
@ -123,9 +119,7 @@ export class TriggerService extends TypedEvent<TriggerCallResult> {
|
|||
})
|
||||
);
|
||||
}
|
||||
private reportTriggerTypeProcess(
|
||||
triggerResult: Array<TriggerSuccessResult>
|
||||
): TriggerCallResult {
|
||||
private reportTriggerTypeProcess(triggerResult: Array<TriggerSuccessResult>): TriggerCallResult {
|
||||
return new TriggerCallResult(
|
||||
triggerResult.map((el) => {
|
||||
if (el.status) {
|
||||
|
|
|
@ -3,20 +3,17 @@ import { dirIsExists } from "../repository/fs";
|
|||
import { CreateFolderUseCase } from "./crete_folder_usecase";
|
||||
|
||||
export class CheckAndCreateStaticFilesFolderUseCase {
|
||||
call = async (): Promise<void> => {
|
||||
if (await dirIsExists(App.staticFilesStoreDir())) {
|
||||
return;
|
||||
call = async (): Promise<void> => {
|
||||
if (await dirIsExists(App.staticFilesStoreDir())) {
|
||||
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);
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,9 +8,7 @@ export class CreateDataBaseModelUseCase<V> {
|
|||
this.databaseModel = model;
|
||||
}
|
||||
|
||||
call = async (
|
||||
validationModel: V
|
||||
): Promise<Result<Error, ICreateObjectDataBase>> => {
|
||||
call = async (validationModel: V): Promise<Result<Error, ICreateObjectDataBase>> => {
|
||||
try {
|
||||
const result = new this.databaseModel(validationModel);
|
||||
|
||||
|
|
13
server/src/core/usecases/create_file_usecase.ts
Normal file
13
server/src/core/usecases/create_file_usecase.ts
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,11 +4,11 @@ import { dirIsExists, createDir } from "../repository/fs";
|
|||
export class CreateFolderUseCase {
|
||||
call = async (path: string): Promise<Result<Error, string>> => {
|
||||
try {
|
||||
if (await dirIsExists(path)) {
|
||||
if (await dirIsExists(path)) {
|
||||
return Result.error(new Error("createFolderUseCase create dir "));
|
||||
}
|
||||
await createDir(path);
|
||||
|
||||
|
||||
return Result.ok("ok");
|
||||
} catch (error) {
|
||||
return Result.error(error as Error);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { Result } from "../helper/result";
|
||||
import { Result } from "../helper/result";
|
||||
|
||||
export class DeleteDataBaseModelUseCase<D> {
|
||||
databaseModel: D | any;
|
||||
databaseModel: D | any;
|
||||
constructor(model) {
|
||||
this.databaseModel = model;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,7 @@ export class PaginationDataBaseModelUseCase<D> {
|
|||
this.perPage = perPage;
|
||||
}
|
||||
|
||||
call = async (
|
||||
pageNumber: number
|
||||
): Promise<Result<Error, [D]>> => {
|
||||
call = async (pageNumber: number): Promise<Result<Error, [D]>> => {
|
||||
try {
|
||||
const page = Math.max(0, pageNumber);
|
||||
const model = this.databaseModel as any;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
import { Result } from "../helper/result";
|
||||
|
||||
export class ReadByIdDataBaseModelUseCase<D> {
|
||||
|
@ -9,10 +8,8 @@ export class ReadByIdDataBaseModelUseCase<D> {
|
|||
}
|
||||
call = async (id: string): Promise<Result<Error, D>> => {
|
||||
try {
|
||||
const r = this.databaseModel as any;
|
||||
|
||||
const model = await r.findById(id);
|
||||
return Result.ok(model);
|
||||
const dbModel = this.databaseModel as any;
|
||||
return Result.ok(await dbModel.findById(id));
|
||||
} catch (error) {
|
||||
return Result.error(error);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ import { Result } from "../helper/result";
|
|||
|
||||
export class SearchDataBaseModelUseCase<T> {
|
||||
model: any;
|
||||
|
||||
|
||||
constructor(model: any) {
|
||||
this.model = model;
|
||||
}
|
||||
|
|
|
@ -1,26 +1,21 @@
|
|||
import {
|
||||
IProjectInstanceModel,
|
||||
ProjectInstanceDbModel,
|
||||
} from "../../features/project_instance/project_instance_model";
|
||||
import { IProjectInstanceModel, ProjectInstanceDbModel } from "../../features/project_instance/project_instance_model";
|
||||
|
||||
import { pipelineRealTimeService } from "../../features/realtime/realtime_presentation";
|
||||
import { App } from "../controllers/app";
|
||||
import { CreateFolderUseCase } from "./crete_folder_usecase";
|
||||
import { SearchDataBaseModelUseCase } from "./search_database_model_usecase";
|
||||
|
||||
export class SetLastActivePipelineToRealTimeServiceUseCase {
|
||||
call = async (): Promise<void> => {
|
||||
const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>(
|
||||
ProjectInstanceDbModel
|
||||
).call({
|
||||
const result = await new SearchDataBaseModelUseCase<IProjectInstanceModel>(ProjectInstanceDbModel).call({
|
||||
isActive: true,
|
||||
});
|
||||
|
||||
if (result.isSuccess()) {
|
||||
const projectModel = result.value.project;
|
||||
pipelineRealTimeService.setPipelineDependency(
|
||||
projectModel.pipelines,
|
||||
App.staticFilesStoreDir() + projectModel.rootDir + "/",
|
||||
projectModel._id
|
||||
);
|
||||
const projectModel = result.value;
|
||||
const projectPath = App.staticFilesStoreDir() + result.value.rootDir + "/";
|
||||
await new CreateFolderUseCase().call(projectPath);
|
||||
pipelineRealTimeService.setPipelineDependency(projectModel.project.pipelines, projectPath, projectModel._id);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -17,7 +17,14 @@ export class UpdateDataBaseModelUseCase<D, T extends uuid> {
|
|||
}
|
||||
const databaseModel = this.databaseModel as any;
|
||||
const model = await databaseModel.findById(updateModel._id);
|
||||
if (model === null) {
|
||||
throw new Error(
|
||||
`we can’t find the model in the database with ID:${updateModel._id} collection: ${databaseModel.modelName}`
|
||||
);
|
||||
}
|
||||
|
||||
Object.assign(model, updateModel);
|
||||
|
||||
await model.save();
|
||||
return Result.ok(model as T);
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
import { IsMongoId, IsOptional, ValidateNested } from "class-validator";
|
||||
import { Schema, model } from "mongoose";
|
||||
import {
|
||||
IPipeline,
|
||||
IProcess,
|
||||
StackGenerateType,
|
||||
} from "../../core/model/process_model";
|
||||
import { IPipeline, IProcess, StackGenerateType } from "../../core/model/process_model";
|
||||
import { TriggerModel, triggerSchema } from "../triggers/trigger_model";
|
||||
import { ProcessModel, schemaProcess } from "../process/process_model";
|
||||
import { Type } from "class-transformer";
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { CrudController } from "../../core/controllers/crud_controller";
|
||||
import { PipelineDBModel, PipelineValidationModel } from "./pipeline_model";
|
||||
|
||||
export class PipelinePresentation extends CrudController<
|
||||
PipelineValidationModel,
|
||||
typeof PipelineDBModel
|
||||
> {
|
||||
export class PipelinePresentation extends CrudController<PipelineValidationModel, typeof PipelineDBModel> {
|
||||
constructor() {
|
||||
super({
|
||||
url: "pipeline",
|
||||
|
|
|
@ -1,10 +1,4 @@
|
|||
import {
|
||||
IsString,
|
||||
IsOptional,
|
||||
IsEnum,
|
||||
IsNumber,
|
||||
IsBoolean,
|
||||
} from "class-validator";
|
||||
import { IsString, IsOptional, IsEnum, IsNumber, IsBoolean } from "class-validator";
|
||||
import { Schema, model } from "mongoose";
|
||||
import { IProcess, IssueType } from "../../core/model/process_model";
|
||||
import { EXEC_TYPE } from "../../core/model/exec_error_model";
|
||||
|
@ -48,7 +42,7 @@ export class ProcessModel implements IProcess {
|
|||
|
||||
@IsString()
|
||||
public description: string;
|
||||
|
||||
|
||||
@IsString()
|
||||
public command: string;
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { CrudController } from "../../core/controllers/crud_controller";
|
||||
import { ProcessDBModel, ProcessModel } from "./process_model";
|
||||
|
||||
export class ProcessPresentation extends CrudController<
|
||||
ProcessModel,
|
||||
typeof ProcessDBModel
|
||||
> {
|
||||
export class ProcessPresentation extends CrudController<ProcessModel, typeof ProcessDBModel> {
|
||||
constructor() {
|
||||
super({
|
||||
url: "process",
|
||||
|
|
|
@ -2,29 +2,20 @@ import { App } from "../../core/controllers/app";
|
|||
import { Result } from "../../core/helper/result";
|
||||
import { CreateDataBaseModelUseCase } from "../../core/usecases/create_database_model_usecase";
|
||||
import { CreateFolderUseCase } from "../../core/usecases/crete_folder_usecase";
|
||||
import {
|
||||
ProjectInstanceDbModel,
|
||||
ProjectInstanceValidationModel,
|
||||
} from "./project_instance_model";
|
||||
import { ProjectInstanceDbModel, ProjectInstanceValidationModel } from "./project_instance_model";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
|
||||
export class CreateNewProjectInstanceScenario {
|
||||
call = async (
|
||||
model: ProjectInstanceValidationModel
|
||||
): Promise<Result<Error, any>> => {
|
||||
call = async (model: ProjectInstanceValidationModel): Promise<Result<Error, any>> => {
|
||||
try {
|
||||
const folderName = uuidv4() + "/";
|
||||
const createFolderUseCase = await new CreateFolderUseCase().call(
|
||||
App.staticFilesStoreDir() + folderName
|
||||
);
|
||||
const createFolderUseCase = await new CreateFolderUseCase().call(App.staticFilesStoreDir() + folderName);
|
||||
if (createFolderUseCase.isFailure()) {
|
||||
return createFolderUseCase.forward();
|
||||
}
|
||||
model.rootDir = folderName;
|
||||
|
||||
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(
|
||||
ProjectInstanceDbModel
|
||||
).call(model);
|
||||
const createDataBaseModelUseCase = await new CreateDataBaseModelUseCase(ProjectInstanceDbModel).call(model);
|
||||
|
||||
if (createDataBaseModelUseCase.isFailure()) {
|
||||
return createDataBaseModelUseCase.forward();
|
||||
|
|
|
@ -3,6 +3,7 @@ import { IProjectModel, projectSchema } from "../projects/projects_model";
|
|||
import { IsMongoId, IsOptional, IsString } from "class-validator";
|
||||
|
||||
export interface IProjectInstanceModel {
|
||||
_id: string;
|
||||
project: IProjectModel;
|
||||
description: string;
|
||||
rootDir: string;
|
||||
|
@ -30,10 +31,7 @@ export const ProjectInstanceSchema = new Schema({
|
|||
|
||||
export const schemaProjectInstance = "instance_project";
|
||||
|
||||
export const ProjectInstanceDbModel = model<IProjectInstanceModel>(
|
||||
schemaProjectInstance,
|
||||
ProjectInstanceSchema
|
||||
);
|
||||
export const ProjectInstanceDbModel = model<IProjectInstanceModel>(schemaProjectInstance, ProjectInstanceSchema);
|
||||
|
||||
export class ProjectInstanceValidationModel {
|
||||
@IsMongoId()
|
||||
|
|
|
@ -1,15 +1,7 @@
|
|||
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 {
|
||||
ProjectInstanceDbModel,
|
||||
ProjectInstanceValidationModel,
|
||||
} from "./project_instance_model";
|
||||
import { UploadCadFileToProjectUseCase } from "./upload_file_to_project_usecase";
|
||||
import { ProjectInstanceDbModel, ProjectInstanceValidationModel } from "./project_instance_model";
|
||||
import { UploadCadFileToProjectScenario } from "./upload_file_to_to_project_scenario";
|
||||
|
||||
export class ProjectInstancePresentation extends CrudController<
|
||||
ProjectInstanceValidationModel,
|
||||
|
@ -27,14 +19,8 @@ export class ProjectInstancePresentation extends CrudController<
|
|||
{
|
||||
method: "post",
|
||||
subUrl: "upload",
|
||||
fn: new TestUseCase(),
|
||||
fn: new UploadCadFileToProjectScenario(),
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
class TestUseCase extends CallbackStrategyWithEmpty {
|
||||
async call(): ResponseBase {
|
||||
return Result.ok(200);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ export interface IProjectModel {
|
|||
pipelines: [PipelineValidationModel];
|
||||
rootDir: string;
|
||||
description: string;
|
||||
isActive:boolean;
|
||||
isActive: boolean;
|
||||
}
|
||||
|
||||
export const ProjectSchema = new Schema({
|
||||
|
@ -35,5 +35,4 @@ export class ProjectValidationModel {
|
|||
public pipelines: [string];
|
||||
@IsString()
|
||||
public description: string;
|
||||
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { CrudController } from "../../core/controllers/crud_controller";
|
||||
import { ProjectDBModel, ProjectValidationModel } from "./projects_model";
|
||||
|
||||
export class ProjectsPresentation extends CrudController<
|
||||
ProjectValidationModel,
|
||||
typeof ProjectDBModel
|
||||
> {
|
||||
export class ProjectsPresentation extends CrudController<ProjectValidationModel, typeof ProjectDBModel> {
|
||||
constructor() {
|
||||
super({
|
||||
url: "project",
|
||||
|
|
|
@ -3,7 +3,7 @@ import { CoreHttpController } from "../../core/controllers/http_controller";
|
|||
import { PipelineRealTimeService } from "../../core/services/pipeline_real_time_service";
|
||||
import { RunInstancePipelineUseCase } from "./usecases/run_instance_pipeline_usecase";
|
||||
import { PipelineStatusUseCase } from "./usecases/pipeline_status_usecase";
|
||||
|
||||
|
||||
export const pipelineRealTimeService = new PipelineRealTimeService();
|
||||
|
||||
export class RealTimeValidationModel {
|
||||
|
@ -11,7 +11,6 @@ export class RealTimeValidationModel {
|
|||
public id: string;
|
||||
}
|
||||
|
||||
|
||||
export class RealTimePresentation extends CoreHttpController<RealTimeValidationModel> {
|
||||
constructor() {
|
||||
super({
|
||||
|
@ -21,6 +20,5 @@ export class RealTimePresentation extends CoreHttpController<RealTimeValidationM
|
|||
});
|
||||
super.post(new RunInstancePipelineUseCase().call);
|
||||
super.get(new PipelineStatusUseCase().call);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,13 @@ import { pipelineRealTimeService } from "../realtime_presentation";
|
|||
export class PipelineStatusUseCase {
|
||||
async call(): Promise<Result<Error, ActivePipeline>> {
|
||||
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) {
|
||||
return Result.error(error as Error);
|
||||
}
|
||||
|
|
|
@ -2,41 +2,32 @@ import { App } from "../../../core/controllers/app";
|
|||
import { Result } from "../../../core/helper/result";
|
||||
import { ReadByIdDataBaseModelUseCase } from "../../../core/usecases/read_by_id_database_model_usecase";
|
||||
import { UpdateDataBaseModelUseCase } from "../../../core/usecases/update_database_model_usecase";
|
||||
import {
|
||||
IProjectInstanceModel,
|
||||
ProjectInstanceDbModel,
|
||||
} from "../../project_instance/project_instance_model";
|
||||
import {
|
||||
RealTimeValidationModel,
|
||||
pipelineRealTimeService,
|
||||
} from "../realtime_presentation";
|
||||
import { IProjectInstanceModel, ProjectInstanceDbModel } from "../../project_instance/project_instance_model";
|
||||
import { RealTimeValidationModel, pipelineRealTimeService } from "../realtime_presentation";
|
||||
|
||||
export class RunInstancePipelineUseCase {
|
||||
async call(model: RealTimeValidationModel): Promise<Result<Error, any>> {
|
||||
const { id } = model;
|
||||
|
||||
const readByIdDataBaseModelUseCase =
|
||||
await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
|
||||
ProjectInstanceDbModel
|
||||
).call(id);
|
||||
const readByIdDataBaseModelUseCase = await new ReadByIdDataBaseModelUseCase<IProjectInstanceModel>(
|
||||
ProjectInstanceDbModel
|
||||
).call(id);
|
||||
|
||||
if (readByIdDataBaseModelUseCase.isFailure()) {
|
||||
return readByIdDataBaseModelUseCase.forward();
|
||||
}
|
||||
|
||||
const projectModel = readByIdDataBaseModelUseCase.value.project;
|
||||
const projectModel = readByIdDataBaseModelUseCase.value;
|
||||
projectModel.isActive = true;
|
||||
|
||||
const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase<
|
||||
IProjectInstanceModel,
|
||||
any
|
||||
>(ProjectInstanceDbModel).call(projectModel);
|
||||
const updateDataBaseModelUseCase = await new UpdateDataBaseModelUseCase<IProjectInstanceModel, any>(
|
||||
ProjectInstanceDbModel
|
||||
).call(projectModel);
|
||||
|
||||
if (updateDataBaseModelUseCase.isFailure()) {
|
||||
return updateDataBaseModelUseCase.forward();
|
||||
}
|
||||
pipelineRealTimeService.setPipelineDependency(
|
||||
projectModel.pipelines,
|
||||
projectModel.project.pipelines,
|
||||
App.staticFilesStoreDir() + projectModel.rootDir + "/",
|
||||
projectModel._id
|
||||
);
|
||||
|
|
|
@ -24,10 +24,7 @@ export const TriggerSchema = new Schema({
|
|||
|
||||
export const triggerSchema = "Trigger";
|
||||
|
||||
export const TriggerDBModel = model<ITriggerModel>(
|
||||
triggerSchema,
|
||||
TriggerSchema
|
||||
);
|
||||
export const TriggerDBModel = model<ITriggerModel>(triggerSchema, TriggerSchema);
|
||||
|
||||
export enum TriggerType {
|
||||
PROCESS = "PROCESS",
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
import { TriggerDBModel, TriggerModel } from "./trigger_model";
|
||||
import { CrudController } from "../../core/controllers/crud_controller";
|
||||
|
||||
export class TriggerPresentation extends CrudController<
|
||||
TriggerModel,
|
||||
typeof TriggerDBModel
|
||||
> {
|
||||
export class TriggerPresentation extends CrudController<TriggerModel, typeof TriggerDBModel> {
|
||||
constructor() {
|
||||
super({
|
||||
url: "trigger",
|
||||
|
|
|
@ -6,13 +6,10 @@ import { TriggerPresentation } from "./features/triggers/triggers_presentation";
|
|||
import { ProjectsPresentation } from "./features/projects/projects_presentation";
|
||||
import { PipelinePresentation } from "./features/pipelines/pipeline_presentation";
|
||||
import { ProcessPresentation } from "./features/process/process_presentation";
|
||||
import {
|
||||
RealTimePresentation,
|
||||
pipelineRealTimeService,
|
||||
} from "./features/realtime/realtime_presentation";
|
||||
import { RealTimePresentation, pipelineRealTimeService } from "./features/realtime/realtime_presentation";
|
||||
import { extensions } from "./core/extensions/extensions";
|
||||
import { ProjectInstancePresentation } from "./features/project_instance/project_instance_presentation";
|
||||
|
||||
|
||||
extensions();
|
||||
|
||||
const httpRoutes: Routes[] = [
|
||||
|
@ -24,8 +21,6 @@ const httpRoutes: Routes[] = [
|
|||
new ProjectInstancePresentation(),
|
||||
].map((el) => el.call());
|
||||
|
||||
const socketSubscribers = [
|
||||
new SocketSubscriber(pipelineRealTimeService, "realtime"),
|
||||
];
|
||||
const socketSubscribers = [new SocketSubscriber(pipelineRealTimeService, "realtime")];
|
||||
|
||||
new App(httpRoutes, socketSubscribers).listen();
|
||||
|
|
|
@ -3,10 +3,9 @@ import { delay } from "../../src/core/helper/delay";
|
|||
import { Result } from "../../src/core/helper/result";
|
||||
import { TypedEvent } from "../../src/core/helper/typed_event";
|
||||
|
||||
|
||||
export const before = async () =>{
|
||||
await mongoose.connection.dropDatabase()
|
||||
}
|
||||
export const before = async () => {
|
||||
await mongoose.connection.dropDatabase();
|
||||
};
|
||||
|
||||
export class TestCore {
|
||||
allTests = 0;
|
||||
|
@ -33,17 +32,14 @@ export class TestCore {
|
|||
console.log("\x1b[32m", "=============");
|
||||
|
||||
if (this.allTests - this.testOk === 0) {
|
||||
console.log(
|
||||
"\x1b[32m",
|
||||
`✅ All test success! ${this.allTests}/${this.testOk}`
|
||||
);
|
||||
console.log("\x1b[32m", `✅ All test success! ${this.allTests}/${this.testOk}`);
|
||||
return;
|
||||
}
|
||||
if (this.testErr !== 0) {
|
||||
console.log("\x1b[31m", "❌ test error:" + String(this.testErr));
|
||||
console.log("\x1b[32m", `✅ test success! ${this.testOk}`);
|
||||
}
|
||||
await before()
|
||||
await before();
|
||||
};
|
||||
resultTest = async (
|
||||
eventClass: TypedEvent<Result<any, any>> | any,
|
||||
|
@ -54,24 +50,20 @@ export class TestCore {
|
|||
) => {
|
||||
let testIsOk = false;
|
||||
eventClass.call(...args);
|
||||
const listener = eventClass.on(
|
||||
(e: {
|
||||
fold: (arg0: (_s: any) => void, arg1: (_e: any) => void) => void;
|
||||
}) => {
|
||||
e.fold(
|
||||
() => {
|
||||
if (isOk) {
|
||||
testIsOk = true;
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if (!isOk) {
|
||||
testIsOk = true;
|
||||
}
|
||||
const listener = eventClass.on((e: { fold: (arg0: (_s: any) => void, arg1: (_e: any) => void) => void }) => {
|
||||
e.fold(
|
||||
() => {
|
||||
if (isOk) {
|
||||
testIsOk = true;
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
},
|
||||
() => {
|
||||
if (!isOk) {
|
||||
testIsOk = true;
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
await delay(delayTime);
|
||||
this.assert(testIsOk, testName);
|
||||
listener.dispose();
|
||||
|
|
|
@ -1,17 +1,15 @@
|
|||
|
||||
|
||||
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')
|
||||
},2000)
|
||||
setTimeout(() =>{
|
||||
console.log('log end')
|
||||
}, 5000)
|
||||
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");
|
||||
}, 2000);
|
||||
setTimeout(() => {
|
||||
console.log("log end");
|
||||
}, 5000);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
const seconds = 1000 * 10
|
||||
setTimeout(()=>{
|
||||
console.log(200)
|
||||
}, seconds)
|
||||
const seconds = 1000 * 10;
|
||||
setTimeout(() => {
|
||||
console.log(200);
|
||||
}, seconds);
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
import { EXEC_TYPE } from "../../src/core/model/exec_error_model";
|
||||
import {
|
||||
IPipeline,
|
||||
IssueType,
|
||||
StackGenerateType,
|
||||
} from "../../src/core/model/process_model";
|
||||
import { IPipeline, IssueType, StackGenerateType } from "../../src/core/model/process_model";
|
||||
import { TriggerType } from "../../src/features/triggers/trigger_model";
|
||||
|
||||
export const mockSimplePipeline:IPipeline[] = [
|
||||
export const mockSimplePipeline: IPipeline[] = [
|
||||
{
|
||||
process: {
|
||||
type: EXEC_TYPE.EXEC,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Schema, model } from "mongoose";
|
||||
|
||||
export interface ITestModel{
|
||||
export interface ITestModel {
|
||||
_id?: string;
|
||||
result: string;
|
||||
}
|
||||
|
@ -12,4 +12,3 @@ export const TestSchema = new Schema({
|
|||
const schema = "Test";
|
||||
|
||||
export const TestDBModel = model<ITestModel>(schema, TestSchema);
|
||||
|
|
@ -15,12 +15,8 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
|
|||
await this.logWriteAndEventEndTypeSpawn();
|
||||
};
|
||||
private async logWriteAndEventEndTypeSpawn() {
|
||||
const executorProgramService = await new ExecutorProgramService(
|
||||
dirname__ + "/"
|
||||
);
|
||||
executorProgramService.call(EXEC_TYPE.SPAWN, "node", [
|
||||
"./mocks/log_code",
|
||||
]);
|
||||
const executorProgramService = await new ExecutorProgramService(dirname__ + "/");
|
||||
executorProgramService.call(EXEC_TYPE.SPAWN, "node", ["./mocks/log_code"]);
|
||||
const test = TestCore.instance;
|
||||
let testIsOk = false;
|
||||
let logEvent = false;
|
||||
|
@ -29,24 +25,17 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
|
|||
if (e.isSuccess()) {
|
||||
const executorResult = e.value as ExecutorResult;
|
||||
if (logEvent == false) {
|
||||
logEvent =
|
||||
executorResult.data != null && executorResult.data != undefined;
|
||||
logEvent = executorResult.data != null && executorResult.data != undefined;
|
||||
}
|
||||
testIsOk = executorResult.event == "END" && logEvent;
|
||||
}
|
||||
});
|
||||
await delay(8000);
|
||||
test.assert(
|
||||
testIsOk,
|
||||
"ExecutorProgramService EXEC_TYPE.SPAWN end event and log write"
|
||||
);
|
||||
test.assert(testIsOk, "ExecutorProgramService EXEC_TYPE.SPAWN end event and log write");
|
||||
}
|
||||
private async logWriteAndEventEndTestTypeExec() {
|
||||
const executorProgramService = await new ExecutorProgramService(dirname__);
|
||||
executorProgramService.call(
|
||||
EXEC_TYPE.EXEC,
|
||||
"node ./test/mocks/log_code"
|
||||
);
|
||||
executorProgramService.call(EXEC_TYPE.EXEC, "node ./test/mocks/log_code");
|
||||
const test = TestCore.instance;
|
||||
executorProgramService.on((e) => {
|
||||
if (e.isSuccess()) {
|
||||
|
@ -61,10 +50,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
|
|||
}
|
||||
private async longTimeCancelTest() {
|
||||
const executorProgramService = await new ExecutorProgramService("", 1000);
|
||||
executorProgramService.call(
|
||||
EXEC_TYPE.EXEC,
|
||||
"node ./test/mocks/long_code"
|
||||
);
|
||||
executorProgramService.call(EXEC_TYPE.EXEC, "node ./test/mocks/long_code");
|
||||
await delay(1500);
|
||||
const worker = executorProgramService.worker as Worker;
|
||||
const test = TestCore.instance;
|
||||
|
|
|
@ -26,10 +26,7 @@ export class FilesChangerTest extends FilesChangeNotifierService {
|
|||
await delay(2000);
|
||||
fs.writeFileSync(this.filePath, this.data());
|
||||
await delay(1000);
|
||||
this.hashUnitEqualTo(
|
||||
EventsFileChanger.create,
|
||||
"FilesChangeNotifierService create file"
|
||||
);
|
||||
this.hashUnitEqualTo(EventsFileChanger.create, "FilesChangeNotifierService create file");
|
||||
|
||||
this.cancel();
|
||||
}
|
||||
|
@ -39,28 +36,19 @@ export class FilesChangerTest extends FilesChangeNotifierService {
|
|||
await delay(1000);
|
||||
fs.writeFileSync(this.filePath, this.data() + "132");
|
||||
await delay(500);
|
||||
this.hashUnitEqualTo(
|
||||
EventsFileChanger.update,
|
||||
"FilesChangeNotifierService update file"
|
||||
);
|
||||
this.hashUnitEqualTo(EventsFileChanger.update, "FilesChangeNotifierService update file");
|
||||
this.cancel();
|
||||
}
|
||||
public async initFile() {
|
||||
this.init();
|
||||
await delay(500);
|
||||
this.hashUnitEqualTo(
|
||||
EventsFileChanger.static,
|
||||
"FilesChangeNotifierService init file"
|
||||
);
|
||||
this.hashUnitEqualTo(EventsFileChanger.static, "FilesChangeNotifierService init file");
|
||||
}
|
||||
public async deleteFile() {
|
||||
this.call();
|
||||
fs.unlinkSync(this.filePath);
|
||||
await delay(1000);
|
||||
this.hashUnitEqualTo(
|
||||
EventsFileChanger.delete,
|
||||
"FilesChangeNotifierService delete file"
|
||||
);
|
||||
this.hashUnitEqualTo(EventsFileChanger.delete, "FilesChangeNotifierService delete file");
|
||||
this.cancel();
|
||||
}
|
||||
public async notExistsDirectory() {
|
||||
|
|
|
@ -9,20 +9,13 @@ abstract class IStackServiceTest {
|
|||
abstract test(): Promise<boolean>;
|
||||
}
|
||||
|
||||
|
||||
class SimpleTestStackServiceTest
|
||||
extends StackService
|
||||
implements IStackServiceTest
|
||||
{
|
||||
class SimpleTestStackServiceTest extends StackService implements IStackServiceTest {
|
||||
constructor() {
|
||||
super(mockSimplePipeline, dirname__ + "/context/");
|
||||
}
|
||||
async test(): Promise<boolean> {
|
||||
await this.call();
|
||||
const testResult = readDirRecursive(this.path).equals(
|
||||
["1.txt", "test.txt"],
|
||||
true
|
||||
);
|
||||
const testResult = readDirRecursive(this.path).equals(["1.txt", "test.txt"], true);
|
||||
await delay(100);
|
||||
rmSync(this.path + "example/", { recursive: true });
|
||||
return testResult;
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
import {
|
||||
EventsFileChanger,
|
||||
MetaDataFileManagerModel,
|
||||
} from "../../src/core/model/meta_data_file_manager_model";
|
||||
|
||||
import { EventsFileChanger, MetaDataFileManagerModel } from "../../src/core/model/meta_data_file_manager_model";
|
||||
|
||||
import { TriggerService } from "../../src/core/services/trigger_service";
|
||||
import { TriggerType } from "../../src/features/triggers/trigger_model";
|
||||
import { assert } from "../test";
|
||||
|
@ -17,11 +14,7 @@ class TriggerServiceFileOkTest extends TriggerService implements TriggerTest {
|
|||
value: ["context"],
|
||||
},
|
||||
{
|
||||
"/context/": new MetaDataFileManagerModel(
|
||||
"",
|
||||
"",
|
||||
EventsFileChanger.create
|
||||
),
|
||||
"/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
|
||||
},
|
||||
""
|
||||
);
|
||||
|
@ -32,10 +25,7 @@ class TriggerServiceFileOkTest extends TriggerService implements TriggerTest {
|
|||
return r.isSuccess();
|
||||
}
|
||||
}
|
||||
class TriggerServiceFileErrorTest
|
||||
extends TriggerService
|
||||
implements TriggerTest
|
||||
{
|
||||
class TriggerServiceFileErrorTest extends TriggerService implements TriggerTest {
|
||||
constructor() {
|
||||
super(
|
||||
{
|
||||
|
@ -44,11 +34,7 @@ class TriggerServiceFileErrorTest
|
|||
},
|
||||
{
|
||||
"/ctx/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
|
||||
"/context/": new MetaDataFileManagerModel(
|
||||
"",
|
||||
"",
|
||||
EventsFileChanger.create
|
||||
),
|
||||
"/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
|
||||
},
|
||||
|
||||
""
|
||||
|
@ -60,10 +46,7 @@ class TriggerServiceFileErrorTest
|
|||
return r.isFailure();
|
||||
}
|
||||
}
|
||||
class TriggerServiceProcessOkTest
|
||||
extends TriggerService
|
||||
implements TriggerTest
|
||||
{
|
||||
class TriggerServiceProcessOkTest extends TriggerService implements TriggerTest {
|
||||
constructor() {
|
||||
super(
|
||||
{
|
||||
|
@ -77,11 +60,7 @@ class TriggerServiceProcessOkTest
|
|||
],
|
||||
},
|
||||
{
|
||||
"/context/": new MetaDataFileManagerModel(
|
||||
"",
|
||||
"",
|
||||
EventsFileChanger.create
|
||||
),
|
||||
"/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
|
||||
},
|
||||
""
|
||||
);
|
||||
|
@ -92,10 +71,7 @@ class TriggerServiceProcessOkTest
|
|||
}
|
||||
}
|
||||
|
||||
class TriggerServiceProcessErrorTest
|
||||
extends TriggerService
|
||||
implements TriggerTest
|
||||
{
|
||||
class TriggerServiceProcessErrorTest extends TriggerService implements TriggerTest {
|
||||
constructor() {
|
||||
super(
|
||||
{
|
||||
|
@ -109,11 +85,7 @@ class TriggerServiceProcessErrorTest
|
|||
],
|
||||
},
|
||||
{
|
||||
"/context/": new MetaDataFileManagerModel(
|
||||
"",
|
||||
"",
|
||||
EventsFileChanger.create
|
||||
),
|
||||
"/context/": new MetaDataFileManagerModel("", "", EventsFileChanger.create),
|
||||
},
|
||||
""
|
||||
);
|
||||
|
|
|
@ -19,7 +19,6 @@ const testCore = TestCore.instance;
|
|||
export const dirname__: string = dirname(__filename);
|
||||
export const assert = testCore.assert;
|
||||
export const resultTest = testCore.resultTest;
|
||||
|
||||
|
||||
const tests = [
|
||||
CreateDataBaseModelUseCaseTest,
|
||||
|
|
|
@ -5,9 +5,7 @@ export class PaginationDataBaseModelUseCaseTest {
|
|||
async test() {
|
||||
let testIsSuccess = false;
|
||||
await (
|
||||
await new PaginationDataBaseModelUseCase<ITestModel>(TestDBModel, 1).call(
|
||||
1
|
||||
)
|
||||
await new PaginationDataBaseModelUseCase<ITestModel>(TestDBModel, 1).call(1)
|
||||
).fold(
|
||||
(s) => {
|
||||
testIsSuccess = s.length === 1;
|
||||
|
|
|
@ -6,20 +6,15 @@ export class ReadDataBaseModelUseCaseTest {
|
|||
async test() {
|
||||
let testIsSuccess = false;
|
||||
|
||||
const result = await new CreateDataBaseModelUseCase<ITestModel>(
|
||||
TestDBModel
|
||||
).call({
|
||||
const result = await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
|
||||
result: "test",
|
||||
});
|
||||
await result.fold(
|
||||
async (s) => {
|
||||
const r = await new ReadByIdDataBaseModelUseCase<ITestModel>(
|
||||
TestDBModel
|
||||
).call(s.id);
|
||||
const r = await new ReadByIdDataBaseModelUseCase<ITestModel>(TestDBModel).call(s.id);
|
||||
await r.fold(
|
||||
(_s1) => {
|
||||
testIsSuccess = true;
|
||||
|
||||
},
|
||||
(_e) => {}
|
||||
);
|
||||
|
|
|
@ -6,18 +6,14 @@ export class UpdateDataBaseModelUseCaseTest {
|
|||
async test() {
|
||||
let testIsSuccess = false;
|
||||
|
||||
const model = await new CreateDataBaseModelUseCase<ITestModel>(
|
||||
TestDBModel
|
||||
).call({
|
||||
const model = await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
|
||||
result: "test",
|
||||
});
|
||||
await model.fold(
|
||||
async (s) => {
|
||||
(
|
||||
await new UpdateDataBaseModelUseCase<any, ITestModel>(
|
||||
TestDBModel
|
||||
).call({
|
||||
_id:s.id,
|
||||
await new UpdateDataBaseModelUseCase<any, ITestModel>(TestDBModel).call({
|
||||
_id: s.id,
|
||||
result: "complete",
|
||||
})
|
||||
).fold(
|
||||
|
|
|
@ -1,5 +1 @@
|
|||
создание инстанца [ OK ]
|
||||
получение всех инастанцев проектов и изменнение их [ OK ]
|
||||
запуск инастанца проекта? [ OK ]
|
||||
|
||||
загрузка FILE [ ]
|
||||
[ ]
|
Loading…
Add table
Add a link
Reference in a new issue