MVP back end

This commit is contained in:
IDONTSUDO 2023-10-31 09:03:39 +00:00 committed by Igor Brylyov
parent 528b9f67d4
commit 889fc95c3d
51 changed files with 1048 additions and 426 deletions

36
.vscode/settings.json vendored
View file

@ -1,20 +1,24 @@
{
"files.exclude": {
"**/.git": false,
"**/.svn": false,
"**/.hg": false,
"**/CVS": false,
"**/__pycache__": false,
"test/*context.*": false,
"test/*mocks": false,
"test/*mocks.*": false,
"test/*test": false,
"test/*test.*": false,
"test/*test.js": false,
"test/*test.js.*": false,
"test/*todo": false,
"test/*todo.*": false,
"**/*.js": true,
"**/*.map": true
"server/build/src/core/*controllers.*": true,
"server/build/src/core/*di": true,
"server/build/src/core/*di.*": true,
"server/build/src/core/*extensions": true,
"server/build/src/core/*extensions.*": true,
"server/build/src/core/*helper": true,
"server/build/src/core/*helper.*": true,
"server/build/src/core/*interfaces": true,
"server/build/src/core/*interfaces.*": true,
"server/build/src/core/*middlewares": true,
"server/build/src/core/*middlewares.*": true,
"server/build/src/core/*model": true,
"server/build/src/core/*model.*": true,
"server/build/src/core/*services": true,
"server/build/src/core/*services.*": true,
"server/build/src/core/*usecases": true,
"server/build/src/core/*usecases.*": true,
"server/src/core/model/exec_error_model.js": true,
"**/*.map": true,
"**/*.js": true
}
}

2
server/.gitignore vendored
View file

@ -6,3 +6,5 @@ node_modules/
coverage
package-lock.json
.*.swp
build/
model_create.ts

View file

@ -1,18 +1,20 @@
{
"name": "step-by-step-server",
"version": "0.0.1",
"type": "module",
"description": "",
"main": "index.js",
"scripts": {
"pretest": "tsc",
"test": "node ./test/test.js",
"test:watch": "tsc-watch --onSuccess 'node ./test/test.js'"
"test": "ts-node ./build/test/test.js",
"test:watch": "tsc-watch --onSuccess 'ts-node ./build/test/test.js'",
"dev": "tsc-watch --onSuccess 'ts-node ./build/src/main.js'"
},
"author": "IDONTSUDO",
"devDependencies": {
"@testdeck/mocha": "latest",
"@types/chai": "latest",
"@types/cors": "^2.8.14",
"@types/express": "^4.17.18",
"@types/md5": "^2.3.2",
"@types/mocha": "latest",
"@types/node": "^20.4.8",
@ -23,20 +25,30 @@
"mocha": "latest",
"nyc": "latest",
"source-map-support": "latest",
"ts-node": "^10.9.1",
"tslint": "latest",
"typescript": "^5.1.6"
},
"dependencies": {
"@grpc/grpc-js": "^1.9.0",
"babel-register": "^6.26.0",
"class-transformer": "^0.5.1",
"class-validator": "^0.14.0",
"concurrently": "^8.2.0",
"cors": "^2.8.5",
"express": "^4.18.2",
"first-di": "^1.0.11",
"md5": "^2.3.0",
"mongoose": "^7.6.2",
"mongoose-autopopulate": "^1.1.0",
"node-watch": "^0.7.4",
"nodemon": "^3.0.1",
"reflect-metadata": "^0.1.13",
"socket.io": "^4.7.2",
"socket.io-client": "^4.7.2",
"spark-md5": "^3.0.2",
"ts-md5": "^1.3.1",
"tsc-watch": "^6.0.4"
"tsc-watch": "^6.0.4",
"typedi": "^0.10.0"
}
}

View file

@ -0,0 +1,82 @@
import express from "express";
import { Routes } from "../interfaces/router";
import cors from "cors";
import locator from "../di/register_di";
import { DevEnv, UnitTestEnv } from "../di/env";
import mongoose from "mongoose";
import http from "http";
// import { Server } from "socket.io";
export class App {
public app: express.Application;
public port: number;
public env: string;
public computedFolder: string;
// public io:
constructor(routes: Routes[], computedFolder: string) {
this.port = 3000;
this.env = "dev";
this.loadAppDependencies().then(() => {
this.app = express();
this.initializeMiddlewares();
this.initializeRoutes(routes);
this.computedFolder = computedFolder;
});
}
public listen() {
const httpServer = new http.Server(this.app);
// const io = new Server(httpServer);
httpServer.listen(this.port, () => {
console.info(`=================================`);
console.info(`======= ENV: ${this.env} =======`);
console.info(`🚀 HTTP http://localhost:${this.port}`);
console.info(`🚀 WS ws://localhost:${this.port}`);
console.info(`=================================`);
});
// io.on("connection", (socket) => {
// socket.on("disconnect", function (msg) {
// console.log("Disconnected");
// });
// });
// setInterval(function () {
// io.emit("goodbye");
// console.log(200);
// }, 1000);
}
public getServer() {
return this.app;
}
private initializeMiddlewares() {
this.app.use(cors());
this.app.use(express.json());
this.app.use(express.urlencoded({ extended: true }));
}
private initializeRoutes(routes: Routes[]) {
routes.forEach((route) => {
this.app.use("/", route.router);
});
}
async loadAppDependencies() {
await locator(
this.env == "development"
? new DevEnv(this.computedFolder)
: new UnitTestEnv(this.computedFolder)
);
mongoose
.connect("mongodb://127.0.0.1:27017/test")
.then(() => console.log("Connected!"))
.catch((e) => {
console.log("ERROR:", e);
});
}
}

View file

@ -0,0 +1,34 @@
import { IRouteModel } from "../interfaces/router";
import { CreateDataBaseModelUseCase } from "../usecases/create_database_model_usecase";
import { DeleteDataBaseModelUseCase } from "../usecases/delete_database_model_usecase";
import { PaginationDataBaseModelUseCase } from "../usecases/pagination_database_model_usecase";
import { UpdateDataBaseModelUseCase } from "../usecases/update_database_model_usecase";
import { CoreHttpController } from "./http_controller";
import mongoose from "mongoose";
export class CrudController<V, D> extends CoreHttpController<V> {
dataBaseModel: mongoose.Model<D>;
constructor(routerModel: IRouteModel) {
super(routerModel);
this.url = "/" + routerModel.url;
this.validationModel = routerModel.validationModel;
this.dataBaseModel = routerModel.databaseModel;
this.init();
}
init() {
this.routes["POST"] = new CreateDataBaseModelUseCase<D>(
this.dataBaseModel
).call;
this.routes["GET"] = new PaginationDataBaseModelUseCase<D>(
this.dataBaseModel
).call;
this.routes["DELETE"] = new DeleteDataBaseModelUseCase<D>(
this.dataBaseModel
).call;
this.routes["PUT"] = new UpdateDataBaseModelUseCase<V, D>(
this.dataBaseModel
).call;
}
}

View file

@ -0,0 +1,107 @@
import { validationModelMiddleware } from "../middlewares/validation_model";
import { Result } from "../helper/result";
import { Router, Request, Response } from "express";
import { IRouteModel, Routes } from "../interfaces/router";
export type CallBackFunction<T> = (a: T) => Promise<Result<any, any>>;
abstract class ICoreHttpController {
abstract url: string;
public router = Router();
abstract call(): Routes;
}
export class CoreHttpController<V> implements ICoreHttpController {
url: string;
validationModel: any;
routes = {
POST: null,
GET: null,
DELETE: null,
PUT: null,
};
public router = Router();
constructor(routerModel: IRouteModel) {
this.url = "/" + routerModel.url;
this.validationModel = routerModel.validationModel;
}
call(): Routes {
if (this.routes["POST"] != null) {
this.router.post(
this.url,
validationModelMiddleware(this.validationModel),
(req, res) =>
this.requestResponseController<V>(req, res, this.routes["POST"])
);
}
if (this.routes["DELETE"] != null) {
this.router.delete(this.url, (req, res) =>
this.requestResponseController<V>(req, res, this.routes["DELETE"])
);
}
if (this.routes["PUT"] != null) {
this.router.put(
this.url,
validationModelMiddleware(this.validationModel),
(req, res) =>
this.requestResponseController<V>(req, res, this.routes["PUT"])
);
}
if (this.routes["GET"] != null) {
this.router.get(this.url, (req, res) =>
this.requestResponseController<V>(req, res, this.routes["GET"])
);
}
return {
router: this.router,
};
}
public put(usecase: CallBackFunction<V>) {
this.routes["PUT"] = usecase;
}
public delete(usecase: CallBackFunction<V>) {
this.routes["DELETE"] = usecase;
}
private async requestResponseController<T>(
req: Request,
res: Response,
usecase: CallBackFunction<T>
) {
let payload = null;
if (req["model"] != undefined) {
payload = req.body as T;
}
if (req.query.page !== undefined) {
payload = String(req.query.page);
}
if (req.query.id !== undefined) {
payload = String(req.query.id);
}
(await usecase(payload)).fold(
(ok) => {
res.json(ok);
return;
},
(err) => {
res.status(400).json(err);
return;
}
);
}
public post(usecase: CallBackFunction<V>) {
this.routes["POST"] = usecase;
}
public get(usecase: CallBackFunction<V>) {
this.routes["GET"] = usecase;
}
}

View file

@ -0,0 +1,15 @@
// import path from "path";
// import { TypedEvent } from "../helper/typed_event";
// import { StackService } from "../services/stack_service";
// // TODO(IDONTSUDO): up to do
// class SocketController<T>{
// emitter:TypedEvent<T>;
// constructor(emitter:TypedEvent<T>, ){
// this.emitter = emitter
// }
// call = () =>{
// }
// }

View file

@ -1,6 +1,6 @@
import { reflection } from "first-di";
import { Service } from "typedi";
@reflection
@Service()
export class IEnv{
rootFolder!: string;
constructor(){
@ -14,7 +14,7 @@ export class IEnv{
}
}
@reflection
@Service()
export class DevEnv implements IEnv {
rootFolder:string;
constructor(rootFolder:string){
@ -28,8 +28,7 @@ export class DevEnv implements IEnv {
}
}
@reflection
@Service()
export class UnitTestEnv implements IEnv{
rootFolder:string;
constructor(rootFolder:string){

View file

@ -1,7 +1,6 @@
import { override } from "first-di";
import { DevEnv, IEnv, UnitTestEnv } from "./env.js";
import { MetaDataFileManagerModel } from "../model/meta_data_file_manager_model.js";
import { extensions } from "../extensions/extensions.js";
import { DevEnv, IEnv, UnitTestEnv } from "./env";
import { extensions } from "../extensions/extensions";
// import { Container, Service } from 'typedi';
export default function locator(env: IEnv) {
extensions();
@ -9,16 +8,16 @@ export default function locator(env: IEnv) {
registerRepository(env);
registerController(env);
registerService(env);
override(MetaDataFileManagerModel, MetaDataFileManagerModel);
// override(MetaDataFileManagerModel, MetaDataFileManagerModel);
}
const envRegister = (env: IEnv) => {
switch (env.toStringEnv()) {
case UnitTestEnv.env():
override(IEnv, UnitTestEnv);
// override(IEnv, UnitTestEnv);
return;
case "DevEnv":
override(IEnv, DevEnv);
// override(IEnv, DevEnv);
return;
}
};
@ -26,11 +25,11 @@ const envRegister = (env: IEnv) => {
const registerRepository = (env: IEnv) => {
switch (env.toStringEnv()) {
case UnitTestEnv.env():
override(IEnv, UnitTestEnv);
// override(IEnv, UnitTestEnv);
return;
case DevEnv.env():
override(IEnv, DevEnv);
// override(IEnv, DevEnv);
return;
}
};

View file

@ -1,5 +1,6 @@
import { ArrayEquals } from "./array.js";
import { ArrayEquals } from "./array";
export const extensions = () =>{
ArrayEquals()
}
}

View file

@ -1,248 +1 @@
const toStringTag: typeof Symbol.toStringTag =
typeof Symbol !== 'undefined' ? Symbol.toStringTag : ('@@toStringTag' as any);
class CancelablePromiseInternal<T = any> {
#internals: Internals;
#promise: Promise<T>;
[toStringTag] = 'CancelablePromise';
constructor({
executor = () => {},
internals = defaultInternals(),
promise = new Promise<T>((resolve, reject) =>
executor(resolve, reject, (onCancel) => {
internals.onCancelList.push(onCancel);
})
),
}: {
executor?: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
onCancel: (cancelHandler: () => void) => void
) => void;
internals?: Internals;
promise?: Promise<T>;
}) {
this.cancel = this.cancel.bind(this);
this.#internals = internals;
this.#promise =
promise ||
new Promise<T>((resolve, reject) =>
executor(resolve, reject, (onCancel) => {
internals.onCancelList.push(onCancel);
})
);
}
then<TResult1 = T, TResult2 = never>(
onfulfilled?:
| ((
value: T
) => TResult1 | PromiseLike<TResult1> | CancelablePromise<TResult1>)
| undefined
| null,
onrejected?:
| ((
reason: any
) => TResult2 | PromiseLike<TResult2> | CancelablePromise<TResult2>)
| undefined
| null
): CancelablePromise<TResult1 | TResult2> {
return makeCancelable<TResult1 | TResult2>(
this.#promise.then(
createCallback(onfulfilled, this.#internals),
createCallback(onrejected, this.#internals)
),
this.#internals
);
}
catch<TResult = never>(
onrejected?:
| ((
reason: any
) => TResult | PromiseLike<TResult> | CancelablePromise<TResult>)
| undefined
| null
): CancelablePromise<T | TResult> {
return makeCancelable<T | TResult>(
this.#promise.catch(createCallback(onrejected, this.#internals)),
this.#internals
);
}
finally(
onfinally?: (() => void) | undefined | null,
runWhenCanceled?: boolean
): CancelablePromise<T> {
if (runWhenCanceled) {
this.#internals.onCancelList.push(onfinally);
}
return makeCancelable<T>(
this.#promise.finally(
createCallback(() => {
if (onfinally) {
if (runWhenCanceled) {
this.#internals.onCancelList =
this.#internals.onCancelList.filter(
(callback) => callback !== onfinally
);
}
return onfinally();
}
}, this.#internals)
),
this.#internals
);
}
cancel(): void {
this.#internals.isCanceled = true;
const callbacks = this.#internals.onCancelList;
this.#internals.onCancelList = [];
for (const callback of callbacks) {
if (typeof callback === 'function') {
try {
callback();
} catch (err) {
console.error(err);
}
}
}
}
isCanceled(): boolean {
return this.#internals.isCanceled === true;
}
}
export class CancelablePromise<T = any> extends CancelablePromiseInternal<T> {
static all = function all(iterable: any) {
return makeAllCancelable(iterable, Promise.all(iterable));
} as CancelablePromiseOverloads['all'];
static allSettled = function allSettled(iterable: any) {
return makeAllCancelable(iterable, Promise.allSettled(iterable));
} as CancelablePromiseOverloads['allSettled'];
static any = function any(iterable: any) {
return makeAllCancelable(iterable, Promise.any(iterable));
} as CancelablePromiseOverloads['any'];
static race = function race(iterable) {
return makeAllCancelable(iterable, Promise.race(iterable));
} as CancelablePromiseOverloads['race'];
static resolve = function resolve(value) {
return cancelable(Promise.resolve(value));
} as CancelablePromiseOverloads['resolve'];
static reject = function reject(reason) {
return cancelable(Promise.reject(reason));
} as CancelablePromiseOverloads['reject'];
static isCancelable = isCancelablePromise;
constructor(
executor: (
resolve: (value: T | PromiseLike<T>) => void,
reject: (reason?: any) => void,
onCancel: (cancelHandler: () => void) => void
) => void
) {
super({ executor });
}
}
export default CancelablePromise;
export function cancelable<T = any>(promise: Promise<T>): CancelablePromise<T> {
return makeCancelable(promise, defaultInternals());
}
export function isCancelablePromise(promise: any): boolean {
return (
promise instanceof CancelablePromise ||
promise instanceof CancelablePromiseInternal
);
}
function createCallback(onResult: any, internals: Internals):any {
if (onResult) {
return (arg?: any) => {
if (!internals.isCanceled) {
const result = onResult(arg);
if (isCancelablePromise(result)) {
internals.onCancelList.push(result.cancel);
}
return result;
}
return arg;
};
}
}
function makeCancelable<T>(promise: Promise<T>, internals: Internals) {
return new CancelablePromiseInternal<T>({
internals,
promise,
}) as CancelablePromise<T>;
}
function makeAllCancelable(iterable: any, promise: Promise<any>) {
const internals = defaultInternals();
internals.onCancelList.push(() => {
for (const resolvable of iterable) {
if (isCancelablePromise(resolvable)) {
resolvable.cancel();
}
}
});
return new CancelablePromiseInternal({ internals, promise });
}
function defaultInternals(): Internals {
return { isCanceled: false, onCancelList: [] };
}
interface Internals {
isCanceled: boolean;
onCancelList: any[];
}
interface CancelablePromiseOverloads {
all<T extends readonly unknown[] | []>(
values: T
): CancelablePromise<{ -readonly [P in keyof T]: Awaited<T[P]> }>;
allSettled<T extends readonly unknown[] | []>(
values: T
): CancelablePromise<{
-readonly [P in keyof T]: PromiseSettledResult<Awaited<T[P]>>;
}>;
allSettled<T>(
values: Iterable<T | PromiseLike<T> | CancelablePromise<T>>
): CancelablePromise<PromiseSettledResult<Awaited<T>>[]>;
any<T extends readonly unknown[] | []>(
values: T
): CancelablePromise<Awaited<T[number]>>;
any<T>(
values: Iterable<T | PromiseLike<T> | CancelablePromise<T>>
): CancelablePromise<Awaited<T>>;
race<T extends readonly unknown[] | []>(
values: T
): CancelablePromise<Awaited<T[number]>>;
resolve(): CancelablePromise<void>;
resolve<T>(
value: T | PromiseLike<T> | CancelablePromise<T>
): CancelablePromise<T>;
reject<T = never>(reason?: any): CancelablePromise<T>;
}

View file

@ -1,6 +1,6 @@
import { EXEC_EVENT, EXEC_TYPE, ExecError } from "../model/exec_error_model.js";
import { EXEC_EVENT, EXEC_TYPE, ExecError } from "../model/exec_error_model";
import * as cp from "child_process";
import { ExecutorResult } from "../model/executor_result.js";
import { ExecutorResult } from "../model/executor_result";
export enum WorkerType {
EXEC = "EXEC",

View file

@ -0,0 +1,14 @@
// export class Payload<T>{
// model: T | undefined
// query:string | undefined
// setModel(model:T){
// this.model = model
// }
// setQuery(query:string){
// this.query = query
// }
// isEmpty(){
// return this.model != undefined || this.query != undefined
// }
// }

View file

@ -0,0 +1,3 @@
export interface ICreateObjectDataBase {
id: string;
}

View file

@ -0,0 +1,14 @@
import { Router } from "express";
export interface Routes {
router: Router;
}
export interface IRouteModel {
validationModel: any;
url: string;
databaseModel: any;
}

View file

@ -0,0 +1,12 @@
// import { RequestHandler } from "express";
// export const validationMiddleware = (
// type: any,
// value = 'body',
// skipMissingProperties = false,
// whitelist = true,
// forbidNonWhitelisted = true,
// ): RequestHandler => {
// }

View file

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

View file

@ -1,19 +1,18 @@
import { EXEC_EVENT, EXEC_TYPE } from "./exec_error_model.js";
import { EXEC_EVENT, EXEC_TYPE } from "./exec_error_model";
export class ExecutorResult {
type: EXEC_TYPE;
event: EXEC_EVENT;
data: any;
constructor(type: EXEC_TYPE, event: EXEC_EVENT, data: any) {
this.type = type;
this.event = event;
this.data = data;
type: EXEC_TYPE;
event: EXEC_EVENT;
data: any;
constructor(type: EXEC_TYPE, event: EXEC_EVENT, data: any) {
this.type = type;
this.event = event;
this.data = data;
}
static isExecutorResult(value: any): void | ExecutorResult {
if ("type" in value && "event" in value && "data" in value) {
return new ExecutorResult(value.type, value.event, value.data);
}
static isExecutorResult(value: any): void | ExecutorResult {
if ("type" in value && "event" in value && "data" in value) {
return new ExecutorResult(value.type, value.event, value.data);
}
return;
}
}
return;
}
}

View file

@ -1,16 +1,16 @@
import { EXEC_TYPE } from "./exec_error_model.js";
import { Trigger } from "../../features/triggers/trigger_model";
import { EXEC_TYPE } from "./exec_error_model";
export interface ProcessMetaData {
process: Process;
export interface IPipeline {
process: IProcess;
trigger: Trigger;
env: Env | null;
stackGenerateType:StackGenerateType;
stackGenerateType: StackGenerateType;
}
export enum StackGenerateType{
MAP = 'MAP',
SINGLETON = 'SINGLETON'
export enum StackGenerateType {
MAP = "MAP",
SINGLETON = "SINGLETON",
}
export interface Env {
@ -19,26 +19,17 @@ export interface Env {
isExtends: string;
}
export interface Process {
type: EXEC_TYPE;
export interface IProcess {
type: EXEC_TYPE;
command: string;
isGenerating: boolean;
isLocaleCode: boolean;
issueType: IssueType;
timeout?: number;
commit?:string | undefined;
commit?: string | undefined;
}
export enum IssueType {
WARNING = "WARNING",
ERROR = "ERROR",
}
export enum TriggerType {
PROCESS = "PROCESS",
FILE = "FILE",
}
export interface Trigger {
type: TriggerType;
value: string[];
}

View file

@ -1,10 +1,10 @@
import cluster, { Worker } from "node:cluster";
import { TypedEvent } from "../helper/typed_event.js";
import { Result } from "../helper/result.js";
import { WorkerDataExec, WorkerType } from "../helper/worker_computed.js";
import { delay } from "../helper/delay.js";
import { ExecutorResult } from "../model/executor_result.js";
import { EXEC_TYPE, ExecError, SpawnError } from "../model/exec_error_model.js";
import { TypedEvent } from "../helper/typed_event";
import { Result } from "../helper/result";
import { WorkerDataExec, WorkerType } from "../helper/worker_computed";
import { delay } from "../helper/delay";
import { ExecutorResult } from "../model/executor_result";
import { EXEC_TYPE, ExecError, SpawnError } from "../model/exec_error_model";
abstract class IExecutorProgramService {
abstract execPath: string;
@ -31,7 +31,7 @@ export class ExecutorProgramService
args: Array<string> | undefined = undefined
) {
cluster.setupPrimary({
exec: "./src/core/helper/worker_computed.js",
exec: "./src/core/helper/worker_computed",
});
const worker = cluster.fork();

View file

@ -7,16 +7,16 @@ import { BinaryLike } from "crypto";
import {
EventsFileChanger,
MetaDataFileManagerModel,
} from "../model/meta_data_file_manager_model.js";
import { Result } from "../helper/result.js";
import { TypedEvent } from "../helper/typed_event.js";
} from "../model/meta_data_file_manager_model";
import { Result } from "../helper/result";
import { TypedEvent } from "../helper/typed_event";
const readFileAsync = promisify(fs.readFile);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);
const lsStat = promisify(fs.lstat);
function joinBuffers(buffers, delimiter = " ") {
function joinBuffers(buffers: Array<Buffer>, delimiter = " ") {
const d = Buffer.from(delimiter);
return buffers.reduce((prev, b) => Buffer.concat([prev, d, b]));
}
@ -44,8 +44,6 @@ export interface IHashesCache {
[key: string]: MetaDataFileManagerModel;
}
export abstract class IFilesChangeNotifierService {
abstract directory: string;
}

View file

@ -1,43 +1,40 @@
import {
FilesChangeNotifierService,
IHashesCache,
} from "./files_change_notifier_service.js";
import { ProcessMetaData, Trigger } from "../model/process_model.js";
import { ExecutorProgramService } from "./executor_program_service.js";
import {
EXEC_EVENT,
ExecError,
SpawnError,
} from "../model/exec_error_model.js";
import { TypedEvent } from "../helper/typed_event.js";
import { Result } from "../helper/result.js";
import { ExecutorResult } from "../model/executor_result.js";
import { delay } from "../helper/delay.js";
import { TriggerErrorReport, TriggerService } from "./trigger_service.js";
} 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";
import { TypedEvent } from "../helper/typed_event";
import { Result } from "../helper/result";
import { ExecutorResult } from "../model/executor_result";
import { delay } from "../helper/delay";
import { TriggerService } from "./trigger_service";
import { Trigger } from "../../features/triggers/trigger_model";
export interface Iteration {
hashes: IHashesCache | null;
process: ProcessMetaData;
process: IPipeline;
result?: ExecError | SpawnError | ExecutorResult;
}
export abstract class IStackService {
abstract callStack: Iteration[];
abstract path: string;
abstract init(processed: ProcessMetaData[], path: string): void;
abstract init(processed: IPipeline[], path: string): void;
}
export class StackService extends TypedEvent<string> implements IStackService {
callStack: Iteration[];
path: string;
constructor(processed: ProcessMetaData[], path: string) {
constructor(processed: IPipeline[], path: string) {
super();
this.path = path;
this.callStack = [];
this.init(processed);
}
public init(processed: ProcessMetaData[]) {
public init(processed: IPipeline[]) {
for (let el of processed) {
el = this.commandHandler(el);
this.callStack.push({
@ -46,7 +43,7 @@ export class StackService extends TypedEvent<string> implements IStackService {
});
}
}
private commandHandler(processMetaData: ProcessMetaData) {
private commandHandler(processMetaData: IPipeline) {
processMetaData.process.command = processMetaData.process.command.replace(
"$PATH",
this.path
@ -91,10 +88,10 @@ export class StackService extends TypedEvent<string> implements IStackService {
);
triggerResult.fold(
(s) => {
s
s;
},
(e) => {
e;
e;
}
);
}

View file

@ -1,9 +1,9 @@
import { Trigger, TriggerType } from "../model/process_model.js";
import * as vm from "node:vm";
import { IHashesCache } from "./files_change_notifier_service.js";
import { EventsFileChanger } from "../model/meta_data_file_manager_model.js";
import { Result } from "../helper/result.js";
import { TypedEvent } from "../helper/typed_event.js";
import { IHashesCache } from "./files_change_notifier_service";
import { EventsFileChanger } from "../model/meta_data_file_manager_model";
import { Result } from "../helper/result";
import { TypedEvent } from "../helper/typed_event";
import { Trigger, TriggerType } from "../../features/triggers/trigger_model";
export class TriggerCallResult {
results: Array<TriggerSuccessResult | TriggerErrorReport>;
@ -47,7 +47,7 @@ export class TriggerErrorReport extends Error {
}
}
export class TriggerService extends TypedEvent<TriggerCallResult> {
context = {};
context: any = {};
constructor(trigger: Trigger, hashes: IHashesCache, path: string) {
super();
@ -61,8 +61,11 @@ export class TriggerService extends TypedEvent<TriggerCallResult> {
path: string;
hashes: IHashesCache;
trigger: Trigger;
private init(): void {
this.context["hashes"] = this.hashes;
if (this.context["hashes"] != undefined) {
this.context["hashes"] = this.hashes;
}
}
private getAllHashesDeleteWithouts(): string[] {
return Object.entries(this.hashes).map(([k, v]) => {

View file

@ -0,0 +1,22 @@
import { Result } from "../helper/result";
import { ICreateObjectDataBase } from "../interfaces/response";
export class CreateDataBaseModelUseCase<V> {
databaseModel: any;
constructor(model) {
this.databaseModel = model;
}
call = async (
validationModel: V
): Promise<Result<Error, ICreateObjectDataBase>> => {
try {
const result = new this.databaseModel(validationModel);
return Result.ok({ id: String((await result.save())._id) });
} catch (error) {
return Result.error(error);
}
};
}

View file

@ -0,0 +1,18 @@
import { Result } from "../helper/result";
export class DeleteDataBaseModelUseCase<D> {
databaseModel: D | any;
constructor(model) {
this.databaseModel = model;
}
call = async (id: string): Promise<Result<Error, boolean>> => {
try {
const model = new this.databaseModel({ _id: id });
await model.deleteOne();
return Result.ok(true);
} catch (error) {
return Result.error(error);
}
};
}

View file

@ -0,0 +1,28 @@
import { Result } from "../helper/result";
export class PaginationDataBaseModelUseCase<D> {
databaseModel: D;
perPage: number;
constructor(model: any, perPage = 10) {
this.databaseModel = model;
this.perPage = perPage;
}
call = async (
pageNumber: number
): Promise<Result<Error, [D]>> => {
try {
const page = Math.max(0, pageNumber);
const model = this.databaseModel as any;
return Result.ok(
await model
.find()
.limit(this.perPage)
.skip(this.perPage * page)
);
} catch (error) {
return Result.error(error);
}
};
}

View file

@ -0,0 +1,20 @@
import { Result } from "../helper/result";
export class ReadByIdDataBaseModelUseCase<D> {
databaseModel: D;
constructor(model) {
this.databaseModel = model;
}
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);
} catch (error) {
return Result.error(error);
}
};
}

View file

@ -0,0 +1,27 @@
import { Result } from "../helper/result";
interface uuid {
_id?: string;
}
export class UpdateDataBaseModelUseCase<D, T extends uuid> {
databaseModel: D;
constructor(databaseModel) {
this.databaseModel = databaseModel;
}
call = async (updateModel: T): Promise<Result<Error, T>> => {
try {
if (updateModel["_id"] === undefined) {
return Result.error(new Error("need _id at model body"));
}
const databaseModel = this.databaseModel as any;
const model = await databaseModel.findById(updateModel._id);
Object.assign(model, updateModel);
await model.save();
return Result.ok(model as T);
} catch (error) {
return Result.error(error);
}
};
}

View file

@ -0,0 +1,47 @@
import { IsMongoId, IsEnum } from "class-validator";
import { Schema, model } from "mongoose";
import { StackGenerateType } from "../../core/model/process_model";
import {
TriggerModel,
triggerSchema,
} from "../triggers/trigger_model";
import { schemaProcess } from "../process/process_model";
export const PipelineSchema = new Schema({
process: {
type: Schema.Types.ObjectId,
ref: schemaProcess,
autopopulate: true,
default: null,
},
trigger: {
type: Schema.Types.ObjectId,
ref: triggerSchema,
autopopulate: true,
default: null,
},
command: {
type: String,
},
}).plugin(require("mongoose-autopopulate"));
export const schemaPipeline = "Pipeline";
export const PipelineDBModel = model<PipelineModel>(
schemaPipeline,
PipelineSchema
);
export class PipelineModel {
@IsMongoId()
public process: PipelineModel;
@IsMongoId()
//TODO(IDONTSUDO):NEED OPTION DECORATOR??
public trigger: TriggerModel;
public env = null;
@IsEnum(StackGenerateType)
public stackGenerateType: StackGenerateType;
}

View file

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

View file

@ -0,0 +1,69 @@
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";
export const ProcessSchema = new Schema({
type: {
type: String,
},
command: {
type: String,
},
isGenerating: {
type: String,
},
isLocaleCode: {
type: String,
},
issueType: {
type: String,
},
timeout: {
type: Number,
default: null,
},
commit: {
type: String,
default: null,
},
});
export const schemaProcess = "Process";
export const ProcessDBModel = model<IProcess>(schemaProcess, ProcessSchema);
export class ProcessModel implements IProcess {
@IsEnum(EXEC_TYPE)
public type: EXEC_TYPE;
@IsString()
public command: string;
@IsBoolean()
public isGenerating: boolean;
@IsBoolean()
public isLocaleCode: boolean;
@IsEnum(IssueType)
public issueType: IssueType;
@IsOptional()
@IsNumber()
public timeout?: number;
@IsOptional()
@IsString()
public commit?: string;
}

View file

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

View file

@ -0,0 +1,31 @@
import { Schema, model } from "mongoose";
import { PipelineModel, schemaPipeline } from "../pipelines/pipeline_model";
import { IsMongoId, IsString } from "class-validator";
export interface IProjectModel {
pipelines: [PipelineModel];
rootDir: string;
}
export const ProjectSchema = new Schema({
pipelines: {
type: Array<Schema.Types.ObjectId>,
ref: schemaPipeline,
autopopulate: true,
default: null,
},
rootDir: {
type: String,
},
}).plugin(require("mongoose-autopopulate"));
const schema = "Projects";
export const ProjectDBModel = model<IProjectModel>(schema, ProjectSchema);
export class ProjectModel implements IProjectModel {
@IsMongoId()
pipelines: [PipelineModel];
@IsString()
rootDir: string;
}

View file

@ -0,0 +1,16 @@
// import { TriggerDBModel, TriggerModel } from "./trigger_model";
import { CrudController } from "../../core/controllers/crud_controller";
import { ProjectDBModel, ProjectModel } from "./projects_model";
export class ProjectsPresentation extends CrudController<
ProjectModel,
typeof ProjectDBModel
> {
constructor() {
super({
url: "project",
validationModel: ProjectModel,
databaseModel: ProjectDBModel,
});
}
}

View file

@ -0,0 +1,43 @@
import { IsArray, IsOptional, IsEnum} from "class-validator";
import { Schema, model } from "mongoose";
export interface ITriggerModel {
_id?: string;
type: string;
value: string[];
}
export const TriggerSchema = new Schema({
type: {
type: String,
require: true,
},
value: {
type: Array,
require: true,
},
});
export const triggerSchema = "Trigger";
export const TriggerDBModel = model<ITriggerModel>(triggerSchema, TriggerSchema);
export enum TriggerType {
PROCESS = "PROCESS",
FILE = "FILE",
}
export class TriggerModel implements ITriggerModel {
@IsOptional()
public _id: string;
@IsEnum(TriggerType)
public type: TriggerType;
@IsArray()
public value: string[];
}
export interface Trigger {
type: TriggerType;
value: string[];
}

View file

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

View file

@ -1 +0,0 @@
export {}

21
server/src/main.ts Normal file
View file

@ -0,0 +1,21 @@
import "reflect-metadata";
import { App } from "./core/controllers/app";
import { Routes } from "./core/interfaces/router";
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";
const httpRoutes: Routes[] = [
new TriggerPresentation(),
new ProjectsPresentation(),
new ProcessPresentation(),
new PipelinePresentation(),
].map((el) => el.call());
const computedFolder = "";
new App(httpRoutes, computedFolder).listen();

View file

@ -1,6 +1,12 @@
import { delay } from "../../src/core/helper/delay.js";
import mongoose from "mongoose";
import { delay } from "../../src/core/helper/delay";
import { Result } from "../../src/core/helper/result";
import { TypedEvent } from "../../src/core/helper/typed_event.js";
import { TypedEvent } from "../../src/core/helper/typed_event";
export const before = async () =>{
await mongoose.connection.dropDatabase()
}
export class TestCore {
allTests = 0;
@ -23,7 +29,7 @@ export class TestCore {
console.log("\x1b[31m", "❌ - " + testName);
};
testResult = () => {
testResult = async () => {
console.log("\x1b[32m", "=============");
if (this.allTests - this.testOk === 0) {
@ -37,6 +43,7 @@ export class TestCore {
console.log("\x1b[31m", "❌ test error:" + String(this.testErr));
console.log("\x1b[32m", `✅ test success! ${this.testOk}`);
}
await before()
};
resultTest = async (
eventClass: TypedEvent<Result<any, any>> | any,

View file

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

View file

@ -1,9 +1,9 @@
import { delay } from "../../src/core/helper/delay.js";
import { EXEC_TYPE } from "../../src/core/model/exec_error_model.js";
import { ExecutorResult } from "../../src/core/model/executor_result.js";
import { ExecutorProgramService } from "../../src/core/services/executor_program_service.js";
import { TestCore } from "../core/test_core.js";
import { resultTest as resultTest, dirname__ } from "../test.js";
import { delay } from "../../src/core/helper/delay";
import { EXEC_TYPE } from "../../src/core/model/exec_error_model";
import { ExecutorResult } from "../../src/core/model/executor_result";
import { ExecutorProgramService } from "../../src/core/services/executor_program_service";
import { TestCore } from "../core/test_core";
import { resultTest as resultTest, dirname__ } from "../test";
import { Worker } from "node:cluster";
export class ExecutorProgramServiceTest extends ExecutorProgramService {
@ -19,7 +19,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
dirname__ + "/"
);
executorProgramService.call(EXEC_TYPE.SPAWN, "node", [
"./mocks/log_code.js",
"./mocks/log_code",
]);
const test = TestCore.instance;
let testIsOk = false;
@ -45,7 +45,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
const executorProgramService = await new ExecutorProgramService(dirname__);
executorProgramService.call(
EXEC_TYPE.EXEC,
"node ./test/mocks/log_code.js"
"node ./test/mocks/log_code"
);
const test = TestCore.instance;
executorProgramService.on((e) => {
@ -63,7 +63,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
const executorProgramService = await new ExecutorProgramService("", 1000);
executorProgramService.call(
EXEC_TYPE.EXEC,
"node ./test/mocks/long_code.js"
"node ./test/mocks/long_code"
);
await delay(1500);
const worker = executorProgramService.worker as Worker;
@ -73,7 +73,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
private resultsTests = async () => {
await resultTest(
new ExecutorProgramService(dirname__),
[EXEC_TYPE.EXEC, "node ./mocks/error.js"],
[EXEC_TYPE.EXEC, "node ./mocks/error"],
"ExecutorProgramService EXEC_TYPE.EXEC on Result.error",
false,
4000
@ -94,7 +94,7 @@ export class ExecutorProgramServiceTest extends ExecutorProgramService {
);
await resultTest(
new ExecutorProgramService(dirname__),
[EXEC_TYPE.SPAWN, "python3 ./mocks/s.js"],
[EXEC_TYPE.SPAWN, "python3 ./mocks/s"],
"ExecutorProgramService EXEC_TYPE.SPAWN on Result.error",
false,
2000

View file

@ -1,8 +1,8 @@
import * as fs from "fs";
import { FilesChangeNotifierService } from "../../src/core/services/files_change_notifier_service.js";
import { EventsFileChanger } from "../../src/core/model/meta_data_file_manager_model.js";
import { assert, dirname__ } from "../test.js";
import { delay } from "../../src/core/helper/delay.js";
import { FilesChangeNotifierService } from "../../src/core/services/files_change_notifier_service";
import { EventsFileChanger } from "../../src/core/model/meta_data_file_manager_model";
import { assert, dirname__ } from "../test";
import { delay } from "../../src/core/helper/delay";
export class FilesChangerTest extends FilesChangeNotifierService {
directory = dirname__ + "/context/";

View file

@ -4,12 +4,12 @@ import * as fs from "fs";
import {
IssueType,
StackGenerateType,
TriggerType,
} from "../../src/core/model/process_model.js";
import { EXEC_TYPE } from "../../src/core/model/exec_error_model.js";
import { StackService } from "../../src/core/services/stack_service.js";
import { delay } from "../../src/core/helper/delay.js";
import { assert, dirname__ } from "../test.js";
} from "../../src/core/model/process_model";
import { EXEC_TYPE } from "../../src/core/model/exec_error_model";
import { StackService } from "../../src/core/services/stack_service";
import { delay } from "../../src/core/helper/delay";
import { assert, dirname__ } from "../test";
import { TriggerType } from "../../src/features/triggers/trigger_model";
abstract class IStackServiceTest {
abstract test(): Promise<boolean>;

View file

@ -1,10 +1,11 @@
import {
EventsFileChanger,
MetaDataFileManagerModel,
} from "../../src/core/model/meta_data_file_manager_model.js";
import { TriggerType } from "../../src/core/model/process_model.js";
import { TriggerService } from "../../src/core/services/trigger_service.js";
import { assert } from "../test.js";
} 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";
abstract class TriggerTest {
abstract test(): Promise<boolean>;
}

View file

@ -1,17 +1,21 @@
import locator from "../src/core/di/register_di.js";
import { UnitTestEnv } from "../src/core/di/env.js";
import { fileURLToPath } from "url";
import { TestCore } from "./core/test_core";
import { UnitTestEnv } from "../src/core/di/env";
import { dirname } from "path";
import { ExecutorProgramServiceTest } from "./features/executor_program_service_test.js";
import { FilesChangerTest } from "./features/files_change_notifier_service_test.js";
import { TestCore } from "./core/test_core.js";
import "reflect-metadata";
import { StackServiceTest } from "./features/stack_service_test.js";
import { TriggerServiceTest } from "./features/trigger_service_test.js";
import locator from "../src/core/di/register_di";
import { ExecutorProgramServiceTest } from "./services/executor_program_service_test";
import { FilesChangerTest } from "./services/files_change_notifier_service_test";
import { TriggerServiceTest } from "./services/trigger_service_test";
import { StackServiceTest } from "./services/stack_service_test";
import mongoose from "mongoose";
import { CreateDataBaseModelUseCaseTest } from "./usecases/create_database_model_usecase_test";
import { DeleteDataBaseModelUseCaseTest } from "./usecases/delete_database_model_usecase_test";
import { ReadDataBaseModelUseCaseTest } from "./usecases/read_database_model_usecase_test";
import { UpdateDataBaseModelUseCaseTest } from "./usecases/update_database_model_usecase";
import { PaginationDataBaseModelUseCaseTest } from "./usecases/pagination_database_model_usecase_test";
const testCore = TestCore.instance;
const __filename: string = fileURLToPath(import.meta.url);
export const dirname__: string = dirname(__filename);
export const assert = testCore.assert;
export const resultTest = testCore.resultTest;
@ -19,11 +23,29 @@ const env = new UnitTestEnv(dirname__);
locator(env);
const main = async () => {
const tests = [CreateDataBaseModelUseCaseTest, DeleteDataBaseModelUseCaseTest,ReadDataBaseModelUseCaseTest,UpdateDataBaseModelUseCaseTest, PaginationDataBaseModelUseCaseTest]
const init = async () =>{
await mongoose.connect('mongodb://127.0.0.1:27017/test')
}
const test = async () =>{
await new ExecutorProgramServiceTest(dirname__).test();
await new FilesChangerTest(dirname__).test();
await new StackServiceTest(dirname__ + "/context/").test();
await new TriggerServiceTest().test();
await new CreateDataBaseModelUseCaseTest().test()
await new CreateDataBaseModelUseCaseTest().test()
await new DeleteDataBaseModelUseCaseTest().test()
await new ReadDataBaseModelUseCaseTest().test()
await new UpdateDataBaseModelUseCaseTest().test()
for await (const usecase of tests) {
testCore.assert(await new usecase().test(), usecase.name)
}
}
const main = async () => {
await init()
await test()
await testCore.testResult();
};

View file

@ -0,0 +1,12 @@
import { CreateDataBaseModelUseCase } from "../../src/core/usecases/create_database_model_usecase";
import { ITestModel, TestDBModel } from "../model/test_db_mongo_model";
export class CreateDataBaseModelUseCaseTest {
async test() {
return (
await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
result: "test",
})
).isSuccess();
}
}

View file

@ -0,0 +1,29 @@
import { CreateDataBaseModelUseCase } from "../../src/core/usecases/create_database_model_usecase";
import { DeleteDataBaseModelUseCase } from "../../src/core/usecases/delete_database_model_usecase";
import { ITestModel, TestDBModel } from "../model/test_db_mongo_model";
export class DeleteDataBaseModelUseCaseTest {
async test() {
let testIsSuccess = false;
const result = await new CreateDataBaseModelUseCase<ITestModel>(TestDBModel).call({
result: "test",
});
await result.fold(
async (s) => {
(await new DeleteDataBaseModelUseCase(TestDBModel).call(s.id)).fold(
(_s1) => {
testIsSuccess = true;
},
(_e1) => {}
);
},
async (_e) => {
return;
}
);
return testIsSuccess;
}
}

View file

@ -0,0 +1,19 @@
import { PaginationDataBaseModelUseCase } from "../../src/core/usecases/pagination_database_model_usecase";
import { ITestModel, TestDBModel } from "../model/test_db_mongo_model";
export class PaginationDataBaseModelUseCaseTest {
async test() {
let testIsSuccess = false;
await (
await new PaginationDataBaseModelUseCase<ITestModel>(TestDBModel, 1).call(
1
)
).fold(
(s) => {
testIsSuccess = s.length === 1;
},
(_e) => {}
);
return testIsSuccess;
}
}

View file

@ -0,0 +1,32 @@
import { CreateDataBaseModelUseCase } from "../../src/core/usecases/create_database_model_usecase";
import { ReadByIdDataBaseModelUseCase } from "../../src/core/usecases/read_database_model_usecase";
import { ITestModel, TestDBModel } from "../model/test_db_mongo_model";
export class ReadDataBaseModelUseCaseTest {
async test() {
let testIsSuccess = false;
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);
await r.fold(
(_s1) => {
testIsSuccess = true;
},
(_e) => {}
);
},
async (_e) => {}
);
return testIsSuccess;
}
}

View file

@ -0,0 +1,35 @@
import { CreateDataBaseModelUseCase } from "../../src/core/usecases/create_database_model_usecase";
import { UpdateDataBaseModelUseCase } from "../../src/core/usecases/update_database_model_usecase";
import { ITestModel, TestDBModel } from "../model/test_db_mongo_model";
export class UpdateDataBaseModelUseCaseTest {
async test() {
let testIsSuccess = false;
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,
result: "complete",
})
).fold(
(s1) => {
testIsSuccess = s1.result === "complete";
},
(_e1) => {}
);
},
async (_e) => {}
);
return testIsSuccess;
}
}

View file

@ -1,25 +1,19 @@
{
"compileOnSave": false,
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"esnext",
"dom"
],
"moduleResolution":"node",
"sourceMap": true,
"noImplicitReturns": true,
"noUnusedParameters": true,
"pretty": true,
"strict": true,
"skipLibCheck": true,
"noImplicitAny": false
// "moduleResolution": "node"
},
// "include": ["src/**/*.ts", "src/**/*.json", ".env"],
// "exclude": ["node_modules"]
}
"target": "es2017",
"allowSyntheticDefaultImports": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"pretty": true,
"declaration": true,
"outDir": "./build",
"allowJs": true,
"noEmit": false,
"esModuleInterop": true,
"resolveJsonModule": true,
"importHelpers": true,
}
}