ismx-nexo-node-app 0.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/js/api/Service.js +45 -0
  2. package/dist/js/api/ServiceRest.js +33 -0
  3. package/dist/js/api/ServiceRestFormal.js +97 -0
  4. package/dist/js/api/ServiceRestFormalTemplate.js +127 -0
  5. package/dist/js/business/Business.js +5 -0
  6. package/dist/js/business/BusinessErrors.js +101 -0
  7. package/dist/js/business/BusinessLogger.js +9 -0
  8. package/dist/js/business/BusinessProxy.js +90 -0
  9. package/dist/js/business/BusinessServer.js +97 -0
  10. package/dist/js/business/BusinessState.js +5 -0
  11. package/dist/js/business/BusinessThread.js +23 -0
  12. package/dist/js/business/utils/CryptoUtils.js +30 -0
  13. package/dist/js/business/utils/NumberUtils.js +8 -0
  14. package/dist/js/business/utils/StringUtils.js +20 -0
  15. package/dist/js/index.js +56 -0
  16. package/dist/js/repository/Repository.js +5 -0
  17. package/dist/js/repository/RepositoryPostgres.js +215 -0
  18. package/dist/js/repository/RepositoryRest.js +55 -0
  19. package/dist/js/repository/RepositoryRestFormal.js +46 -0
  20. package/dist/js/repository/utils/PostgresUtils.js +51 -0
  21. package/dist/js/repository/utils/QueryUtils.js +13 -0
  22. package/dist/types/api/Service.d.ts +45 -0
  23. package/dist/types/api/ServiceRest.d.ts +6 -0
  24. package/dist/types/api/ServiceRestFormal.d.ts +23 -0
  25. package/dist/types/api/ServiceRestFormalTemplate.d.ts +40 -0
  26. package/dist/types/business/Business.d.ts +2 -0
  27. package/dist/types/business/BusinessErrors.d.ts +39 -0
  28. package/dist/types/business/BusinessLogger.d.ts +3 -0
  29. package/dist/types/business/BusinessProxy.d.ts +15 -0
  30. package/dist/types/business/BusinessServer.d.ts +15 -0
  31. package/dist/types/business/BusinessState.d.ts +2 -0
  32. package/dist/types/business/BusinessThread.d.ts +8 -0
  33. package/dist/types/business/utils/CryptoUtils.d.ts +5 -0
  34. package/dist/types/business/utils/NumberUtils.d.ts +3 -0
  35. package/dist/types/business/utils/StringUtils.d.ts +5 -0
  36. package/dist/types/index.d.ts +35 -0
  37. package/dist/types/repository/Repository.d.ts +2 -0
  38. package/dist/types/repository/RepositoryPostgres.d.ts +75 -0
  39. package/dist/types/repository/RepositoryRest.d.ts +17 -0
  40. package/dist/types/repository/RepositoryRestFormal.d.ts +7 -0
  41. package/dist/types/repository/utils/PostgresUtils.d.ts +17 -0
  42. package/dist/types/repository/utils/QueryUtils.d.ts +5 -0
  43. package/package.json +35 -0
  44. package/src/main/node/api/Service.ts +55 -0
  45. package/src/main/node/api/ServiceRest.ts +19 -0
  46. package/src/main/node/api/ServiceRestFormal.ts +58 -0
  47. package/src/main/node/api/ServiceRestFormalTemplate.ts +133 -0
  48. package/src/main/node/business/Business.ts +3 -0
  49. package/src/main/node/business/BusinessErrors.ts +94 -0
  50. package/src/main/node/business/BusinessLogger.ts +6 -0
  51. package/src/main/node/business/BusinessProxy.ts +57 -0
  52. package/src/main/node/business/BusinessServer.ts +76 -0
  53. package/src/main/node/business/BusinessState.ts +4 -0
  54. package/src/main/node/business/BusinessThread.ts +19 -0
  55. package/src/main/node/business/utils/CryptoUtils.ts +32 -0
  56. package/src/main/node/business/utils/NumberUtils.ts +6 -0
  57. package/src/main/node/business/utils/StringUtils.ts +20 -0
  58. package/src/main/node/index.ts +45 -0
  59. package/src/main/node/repository/Repository.ts +3 -0
  60. package/src/main/node/repository/RepositoryPostgres.ts +246 -0
  61. package/src/main/node/repository/RepositoryRest.ts +70 -0
  62. package/src/main/node/repository/RepositoryRestFormal.ts +37 -0
  63. package/src/main/node/repository/utils/PostgresUtils.ts +59 -0
  64. package/src/main/node/repository/utils/QueryUtils.ts +10 -0
  65. package/tsconfig.json +18 -0
@@ -0,0 +1,15 @@
1
+ import Service, { HttpRequest, HttpResponse } from "../api/Service";
2
+ import Business from "./Business";
3
+ export default class BusinessServer extends Business {
4
+ private app;
5
+ protected onStarted?: () => any;
6
+ protected onRequest?: (request: HttpRequest) => any;
7
+ protected onResponse?: (request: HttpRequest, response: HttpResponse) => HttpResponse<any> | undefined;
8
+ protected onError?: (request: HttpRequest, error: Error) => HttpResponse<any> | undefined | void;
9
+ protected onEnd?: (request: HttpRequest, response: HttpResponse) => any;
10
+ constructor();
11
+ start(port: number): void;
12
+ setServices(services: Service<any, any>[]): void;
13
+ private publish;
14
+ private run;
15
+ }
@@ -0,0 +1,2 @@
1
+ export default class BusinessState<Model> {
2
+ }
@@ -0,0 +1,8 @@
1
+ import Business from "./Business";
2
+ export default abstract class BusinessThread extends Business {
3
+ constructor();
4
+ abstract run(): void;
5
+ abstract interval(): number;
6
+ abstract delay(): number;
7
+ onError(): void;
8
+ }
@@ -0,0 +1,5 @@
1
+ export default abstract class CryptoUtils {
2
+ static zeroPad(buf: Buffer, blocksize: number): Buffer;
3
+ static encrypt3DES(key: string, message: string): Buffer;
4
+ static sha256Sign(merchantKey: string, orderId: string, encodedOrder: string): string;
5
+ }
@@ -0,0 +1,3 @@
1
+ export default abstract class NumberUtils {
2
+ static random(lower: number, upper: number): number;
3
+ }
@@ -0,0 +1,5 @@
1
+ export default abstract class StringUtils {
2
+ static base64Decode(base64: string): Buffer;
3
+ static base64Encode(buffer: Buffer): string;
4
+ static base64UrlDecode(base64: string): Buffer;
5
+ }
@@ -0,0 +1,35 @@
1
+ import BaseService, { HttpRequest as BaseHttpRequest, HttpResponse as BaseHttpResponse } from "./api/Service";
2
+ export declare const Service: typeof BaseService;
3
+ export interface HttpRequest extends BaseHttpRequest {
4
+ }
5
+ export declare const HttpResponse: typeof BaseHttpResponse;
6
+ import BaseServiceRest from "./api/ServiceRest";
7
+ export declare const ServiceRest: typeof BaseServiceRest;
8
+ import BaseServiceRestFormal, { Wrapper as BaseWrapper } from "./api/ServiceRestFormal";
9
+ export declare const ServiceRestFormal: typeof BaseServiceRestFormal;
10
+ export interface Wrapper<T> extends BaseWrapper<T> {
11
+ }
12
+ import BaseServiceRestFormalTemplate from "./api/ServiceRestFormalTemplate";
13
+ export declare const ServiceRestFormalTemplate: typeof BaseServiceRestFormalTemplate;
14
+ import BaseBusiness from "./business/Business";
15
+ export declare const Business: typeof BaseBusiness;
16
+ import BaseBusinessState from "./business/BusinessState";
17
+ export declare const BusinessState: typeof BaseBusinessState;
18
+ import BaseBusinessProxy, { Module as BaseModule } from "./business/BusinessProxy";
19
+ export declare const BusinessProxy: typeof BaseBusinessProxy;
20
+ export interface Module extends BaseModule {
21
+ }
22
+ import BaseBusinessServer from "./business/BusinessServer";
23
+ export declare const BusinessServer: typeof BaseBusinessServer;
24
+ import BaseBusinessThread from "./business/BusinessThread";
25
+ export declare const BusinessThread: typeof BaseBusinessThread;
26
+ import BaseBusinessErrors, { FormalError as BaseFormalError } from "./business/BusinessErrors";
27
+ export declare const BusinessErrors: typeof BaseBusinessErrors;
28
+ export interface FormalError extends BaseFormalError {
29
+ }
30
+ import BaseBusinessLogger from "./business/BusinessLogger";
31
+ export declare const BusinessLogger: typeof BaseBusinessLogger;
32
+ import BaseRepository from "./repository/Repository";
33
+ export declare const Repository: typeof BaseRepository;
34
+ import BaseRepositoryPostgres from "./repository/RepositoryPostgres";
35
+ export declare const RepositoryPostgres: typeof BaseRepositoryPostgres;
@@ -0,0 +1,2 @@
1
+ export default class Repository {
2
+ }
@@ -0,0 +1,75 @@
1
+ import pg, { ClientConfig, QueryResult } from "pg";
2
+ export interface QueryOptions {
3
+ schema?: string;
4
+ filters?: string;
5
+ }
6
+ export interface Chain extends ClientConfig {
7
+ host: string;
8
+ port: number;
9
+ user: string;
10
+ password: string;
11
+ database: string;
12
+ schema: string;
13
+ }
14
+ export interface Column {
15
+ name: string;
16
+ default?: string;
17
+ }
18
+ export interface Pagination<T> {
19
+ total: number;
20
+ elements: T[];
21
+ }
22
+ export type Primitive = string | number | Date | null | undefined;
23
+ export default abstract class RepositoryPostgres {
24
+ protected chain: Chain;
25
+ protected client: pg.Client;
26
+ private connected;
27
+ private tables;
28
+ private onConnectListeners;
29
+ private onQueryWillExecuteListeners;
30
+ private onQueryDidExecuteListeners;
31
+ private onIntrospectedListener;
32
+ private introspectIntervalTime;
33
+ private schema;
34
+ constructor();
35
+ init(chain: Chain): void;
36
+ isConnected(): boolean;
37
+ addOnConnect(listener: () => void): void;
38
+ addOnQueryWillExecuteListener(listener: (query: string) => void): void;
39
+ setIntrospectInterval(time: number): void;
40
+ addOnIntrospected(listener: (tables: {
41
+ [p: string]: Column[];
42
+ }) => void): void;
43
+ connect(connection: Chain): void;
44
+ native(query: string, values?: any[], options?: QueryOptions): Promise<QueryResult>;
45
+ query<E>(query: string, values?: any[], options?: QueryOptions): Promise<E[]>;
46
+ one<E>(tableName: string, id: string): Promise<E>;
47
+ any<E>(tableName: string, filters: {
48
+ [key: string]: Primitive | Array<any>;
49
+ }): Promise<E>;
50
+ find<T>(tableName: string, filters: {
51
+ [key: string]: Primitive | Array<any>;
52
+ }): Promise<T[]>;
53
+ all_depr<E>(tableName: string, options?: QueryOptions): Promise<E[]>;
54
+ add<E>(tableName: string, object: {
55
+ [key: string]: Primitive;
56
+ } | any, id?: string): Promise<E>;
57
+ addAll<T>(tableName: string, objects: {
58
+ [key: string]: Primitive;
59
+ }[]): Promise<T[]>;
60
+ update(tableName: string, id: string, object: {
61
+ [key: string]: Primitive;
62
+ }): Promise<unknown[]>;
63
+ page<T>(tableName: string, sortKey: string, maxResults?: number, pageNumber?: number, filters?: {
64
+ [key: string]: Primitive | Array<Primitive>;
65
+ }): Promise<Pagination<T>>;
66
+ count(tableName: string, filters?: {
67
+ [key: string]: Primitive | Array<Primitive>;
68
+ }): Promise<number>;
69
+ select(tableName: string, select: string, filters?: {
70
+ [key: string]: Primitive | Array<Primitive>;
71
+ }): Promise<string[]>;
72
+ del(tableName: string, id: string): Promise<void>;
73
+ private toQuery;
74
+ private introspect;
75
+ }
@@ -0,0 +1,17 @@
1
+ import Repository from './Repository';
2
+ import { HttpRequest } from "../api/Service";
3
+ export interface RestResponse<E = any> extends Response {
4
+ timestamp?: Date;
5
+ duration?: number;
6
+ }
7
+ export interface RestOptions {
8
+ interceptor: (response: RestResponse) => void;
9
+ }
10
+ export default class RepositoryRest<S = any> extends Repository {
11
+ private readonly baseUrl;
12
+ private readonly interceptor?;
13
+ private onRequestListener?;
14
+ constructor(baseUrl: string, options?: RestOptions);
15
+ setOnRequestListener(listener: (method: string, endpoint: string, request: HttpRequest) => void): void;
16
+ call<E = S>(method?: string, endpoint?: string, request?: HttpRequest): Promise<RestResponse<E>>;
17
+ }
@@ -0,0 +1,7 @@
1
+ import RepositoryRest from "./RepositoryRest";
2
+ import { Wrapper } from "../api/ServiceRestFormal";
3
+ import { HttpRequest } from "../api/Service";
4
+ export default class RepositoryRestFormal<S = any> extends RepositoryRest<Wrapper<S>> {
5
+ constructor(baseUrl: string, ...methods: RepositoryRest[]);
6
+ call<E = S>(method?: string, endpoint?: string, request?: HttpRequest): Promise<E>;
7
+ }
@@ -0,0 +1,17 @@
1
+ import { Column, Primitive } from "../RepositoryPostgres";
2
+ export default abstract class PostgresUtils {
3
+ static stringToCamel(column: string): string;
4
+ static camelToSnake(column: string): string;
5
+ static snakeToCamel(obj: any): any;
6
+ static columns(table: Column[]): string[];
7
+ static bindOrDefault(table: Column[], object: {
8
+ [p: string]: Primitive;
9
+ }, startIndex: any): {
10
+ bindings: string[];
11
+ values: any[];
12
+ };
13
+ static valueOrDefault(columns: [string], object: any): string[];
14
+ static fromEntries(iterable: [string, any][]): {
15
+ [key: string]: any;
16
+ };
17
+ }
@@ -0,0 +1,5 @@
1
+ export default class QueryUtils {
2
+ static map(query?: {
3
+ [key: string]: string;
4
+ }): string;
5
+ }
package/package.json ADDED
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "ismx-nexo-node-app",
3
+ "version": "0.3.24",
4
+ "description": "",
5
+ "scripts": {
6
+ "build": "rm -rf ./dist && npx tsc",
7
+ "publish-patch": "rm -rf ./dist && npx tsc && git add -A && git commit -m \"patch\" && npm version patch && npm publish && git push",
8
+ "publish-minor": "rm -rf ./dist && npx tsc && git add -A && git commit -m \"minor\" && npm version minor && npm publish && git push",
9
+ "publish-major": "rm -rf ./dist && npx tsc && git add -A && git commit -m \"major\" && npm version major && npm publish && git push"
10
+ },
11
+ "main": "dist/js/index.js",
12
+ "types": "dist/types/index.d.ts",
13
+ "keywords": [],
14
+ "author": "",
15
+ "license": "ISC",
16
+ "dependencies": {
17
+ "cors": "^2.8.5",
18
+ "esbuild": "^0.23.1",
19
+ "express": "^4.21.0",
20
+ "node-fetch": "^2.6.11",
21
+ "pg": "^8.11.0",
22
+ "ts-node": "8.10.1"
23
+ },
24
+ "devDependencies": {
25
+ "@types/cors": "^2.8.17",
26
+ "@types/express": "^5.0.0",
27
+ "@types/node": "^14.0.5",
28
+ "@types/node-fetch": "^2.6.11",
29
+ "@types/pg": "^8.11.10",
30
+ "rollup": "^4.24.4",
31
+ "rollup-plugin-dts": "^6.1.1",
32
+ "tsx": "^4.19.1",
33
+ "typescript": "^5.6.3"
34
+ }
35
+ }
@@ -0,0 +1,55 @@
1
+ import BusinessServer from "../business/BusinessServer";
2
+
3
+ export interface HttpRequest<T = any> {
4
+ id?: string,
5
+ url?: string,
6
+ method?: string,
7
+ endpoint?: string;
8
+ timestamp?: Date,
9
+ params?: { [key: string]: string },
10
+ query?: { [key: string]: string },
11
+ body?: T,
12
+ headers?: { [key: string]: string },
13
+ }
14
+
15
+ export class HttpResponse<T = any> {
16
+ content?: T;
17
+ httpCode?: number;
18
+ headers?: { [key: string]: string };
19
+
20
+ static ok<T=any>(content: T) {
21
+ let response = new HttpResponse();
22
+ response.content = content;
23
+ response.httpCode = 200;
24
+ return response
25
+ }
26
+ static ko<T=any>(httpCode: number, content: T | undefined) {
27
+ let response = new HttpResponse();
28
+ response.content = content;
29
+ response.httpCode = httpCode;
30
+ return response
31
+ }
32
+ }
33
+
34
+ export default abstract class Service<Req, Res>
35
+ {
36
+ public static readonly services: Service<any, any>[] = []
37
+
38
+ readonly method: string;
39
+
40
+ readonly endpoint: string;
41
+
42
+ protected constructor(method: string, endpoint: string = "/") {
43
+ this.method = method;
44
+ this.endpoint = endpoint;
45
+ Service.services.push(this);
46
+ }
47
+
48
+ async serve(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
49
+ return HttpResponse.ok({});
50
+ }
51
+
52
+ static clone<R, S>(request: HttpRequest<R>, clone: { params?: { [key: string]: string }, query?: { [key: string]: string }, body?: S, headers?: { [key: string]: string } }): HttpRequest<S> {
53
+ return { id: request.id, url: request.url, method: request.method, timestamp: request.timestamp, params: clone.params ?? {}, query: clone.query ?? {}, body: clone.body, headers: clone.headers ?? {} };
54
+ }
55
+ }
@@ -0,0 +1,19 @@
1
+ import Service, {HttpRequest, HttpResponse} from "./Service";
2
+
3
+ export default class ServiceRest<Req, Res> extends Service<Req, Res>
4
+ {
5
+ constructor(method: string, endpoint: string = "/") {
6
+ super(method, endpoint);
7
+ }
8
+
9
+ async serve(request: HttpRequest<Req>): Promise<HttpResponse<Res>>
10
+ {
11
+ let response = await this.serveRest(request)
12
+ response.headers = { "Content-Type": "application/json" };
13
+ return response;
14
+ }
15
+
16
+ async serveRest(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
17
+ return {};
18
+ }
19
+ }
@@ -0,0 +1,58 @@
1
+ import Service, {HttpRequest, HttpResponse} from "./Service";
2
+ import ServiceRest from "./ServiceRest";
3
+
4
+ export interface Wrapper<T> {
5
+ code: string,
6
+ description: string,
7
+ data?: T
8
+ debug?: Error
9
+ }
10
+
11
+ export default class ServiceRestFormal<Req=any, Res=any> extends ServiceRest<Req, Wrapper<Res>>
12
+ {
13
+ constructor(method: string, endpoint: string = "/") {
14
+ super(method, endpoint);
15
+ }
16
+
17
+ async serveRest(request: HttpRequest<Req>): Promise<HttpResponse<Wrapper<Res>>>
18
+ {
19
+ try {
20
+ let response = await this.serveRestFormal(request);
21
+ let content: Wrapper<Res> = ({ code: "0", description: "Service execution OK", data: response.content })
22
+ return Object.assign({} as HttpResponse<Wrapper<Res>>, response, {content});
23
+ } catch (error: any) {
24
+ let content: Wrapper<any> = ({ code: "-1", description: "Internal server error", debug: error.message })
25
+ throw error;
26
+ }
27
+ }
28
+
29
+ async serveRestFormal(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
30
+ return HttpResponse.ok(null);
31
+ }
32
+
33
+ async unwrap<Res>(request: Promise<HttpResponse<Wrapper<Res>>>): Promise<Res | undefined> {
34
+ return ServiceRestFormal.unwrap(request);
35
+ }
36
+
37
+ async fullSelect<Req, Res>(request: HttpRequest<Req>, api: { select: ServiceRestFormal<Req, string[]>, full: ServiceRestFormal<Req, Res> }) {
38
+ return ServiceRestFormal.fullSelect(request, api);
39
+ }
40
+
41
+ static async unwrap<Res>(request: Promise<HttpResponse<Wrapper<Res>>>): Promise<Res | undefined> {
42
+ let response = await request;
43
+ if (response.httpCode !== 200) throw response.content;
44
+ else return response.content?.data;
45
+ }
46
+
47
+ static async fullSelect<Req, Res>(request: HttpRequest<Req>, api: { select: ServiceRestFormal<Req, string[]>, full: ServiceRestFormal<Req, Res> })
48
+ {
49
+ return api.select.serve(request).then((result) => {
50
+ let select = result.content?.data;
51
+ let requests = select?.map(async (selectId) => {
52
+ let result = await api.full.serve(Service.clone(request, {query: {id: selectId}}));
53
+ return result.content?.data;
54
+ });
55
+ return Promise.all(requests ?? []);
56
+ });
57
+ }
58
+ }
@@ -0,0 +1,133 @@
1
+ import Service, {HttpRequest, HttpResponse} from "./Service";
2
+ import ServiceRestFormal, {Wrapper} from "./ServiceRestFormal";
3
+ import RepositoryPostgres, {Pagination} from "../repository/RepositoryPostgres";
4
+ import BusinessErrors from "../business/BusinessErrors";
5
+
6
+ export default class ServiceRestFormalTemplate<Req=any, Res=any>
7
+ {
8
+ readonly resource: string;
9
+ readonly tableName: string;
10
+ readonly database!: RepositoryPostgres;
11
+ readonly errors!: BusinessErrors;
12
+
13
+ readonly get!: ServiceRestFormal<Req, Res>;
14
+ readonly post!: ServiceRestFormal<Req, Res>;
15
+ readonly put!: ServiceRestFormal<Req, Res>;
16
+ readonly del!: ServiceRestFormal<Req, Res>;
17
+ readonly select!: ServiceRestFormal<Req, string[]>;
18
+ readonly exist!: ServiceRestFormal<Req, Boolean>;
19
+
20
+ readonly count!: ServiceRestFormal<Req, Number>;
21
+ readonly getList!: ServiceRestFormal<Req, Res[]>;
22
+
23
+ readonly postList!: ServiceRestFormal<Req, Res[]>;
24
+ readonly page!: ServiceRestFormal<Req, Pagination<Res>>;
25
+ readonly map!: ServiceRestFormal<Req, { [key:string]: Res }>;
26
+
27
+ constructor(resource: string, tableName: string) {
28
+ this.resource = resource;
29
+ this.tableName = tableName;
30
+
31
+ this.get = new ServiceRestFormal("GET", `${resource}`);
32
+ this.get.serveRestFormal = this.serveGet.bind(this);
33
+
34
+ this.getList = new ServiceRestFormal("GET", `${resource}/list`);
35
+ this.getList.serveRestFormal = this.serveGetList.bind(this);
36
+
37
+ this.postList = new ServiceRestFormal("POST", `${resource}/list`);
38
+ this.postList.serveRestFormal = this.servePostList.bind(this);
39
+
40
+ this.page = new ServiceRestFormal("GET", `${resource}/page`);
41
+ this.page.serveRestFormal = this.servePage.bind(this);
42
+
43
+ this.map = new ServiceRestFormal("GET", `${resource}/map`);
44
+ this.map.serveRestFormal = this.serveMap.bind(this);
45
+
46
+ this.select = new ServiceRestFormal("GET", `${resource}/select`);
47
+ this.select.serveRestFormal = this.serveSelect.bind(this);
48
+
49
+ this.exist = new ServiceRestFormal("GET", `${resource}/exist`);
50
+ this.exist.serveRestFormal = this.serveExist.bind(this);
51
+
52
+ this.count = new ServiceRestFormal("GET", `${resource}/count`);
53
+ this.count.serveRestFormal = this.serveCount.bind(this);
54
+
55
+ this.post = new ServiceRestFormal("POST", `${resource}`);
56
+ this.post.serveRestFormal = this.servePost.bind(this);
57
+
58
+ this.put = new ServiceRestFormal("PUT", `${resource}`);
59
+ this.put.serveRestFormal = this.servePut.bind(this);
60
+
61
+ this.del = new ServiceRestFormal("DELETE", `${resource}`);
62
+ this.del.serveRestFormal = this.serveDel.bind(this);
63
+ }
64
+
65
+ protected async serveGet(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
66
+ let id = this.errors.getQuery("id", request.query)
67
+ let result = await this.database.one<Res>(this.tableName, id);
68
+ return HttpResponse.ok(result);
69
+ }
70
+
71
+ protected async serveGetList(request: HttpRequest<Req>): Promise<HttpResponse<Res[]>> {
72
+ return HttpResponse.ok(await this.database.find<Res>(this.tableName, { ...request.query }));
73
+ }
74
+
75
+ protected async servePostList(request: HttpRequest<Req>): Promise<HttpResponse<Res[]>> {
76
+ let list = request.body
77
+ if (!(list instanceof Array)) throw new Error("body must be a list");
78
+ return HttpResponse.ok(this.database.addAll(this.tableName, list));
79
+ }
80
+
81
+ protected async servePage(request: HttpRequest<Req>): Promise<HttpResponse<Pagination<Res>>> {
82
+ let maxResults = this.errors.getQuery("maxResults", request.query);
83
+ let maxResultsNum = this.errors.isType("maxResults", maxResults, "number", Number.parseInt);
84
+
85
+ let pageNumber = this.errors.getQuery("pageNumber", request.query)
86
+ let pageNumberNum = this.errors.isType("pageNumber", pageNumber, "number", Number.parseInt)
87
+
88
+ let results = await this.database.page(this.tableName, "timestamp", maxResultsNum, pageNumberNum);
89
+ return HttpResponse.ok(results);
90
+ }
91
+
92
+ protected async serveMap(request: HttpRequest<Req>): Promise<HttpResponse<{[key: string]: Res}>> {
93
+ let results = await this.database.find<Res>(this.tableName, { ...request.query });
94
+ let response: {[key: string]: Res} = {}; for (let result of results) {
95
+ let key = (result as any)[this.indexer];
96
+ if (!key) return HttpResponse.ok({});
97
+ else response[key] = result;
98
+ }
99
+ return HttpResponse.ok(response);
100
+ }
101
+
102
+ protected indexer = "id"
103
+ protected async serveSelect(request: HttpRequest<Req>): Promise<HttpResponse<string[]>> {
104
+ let selection = request.query?.["selection"] ?? this.indexer;
105
+ delete request.query?.["selection"];
106
+ let select = await this.database.select(this.tableName, selection, { ...request.query });
107
+ return HttpResponse.ok(select);
108
+ }
109
+
110
+ protected async serveExist(request: HttpRequest<Req>): Promise<HttpResponse<Boolean>> {
111
+ return HttpResponse.ok((await this.database.count(this.tableName, { ...request.query })) > 0);
112
+ }
113
+
114
+ protected async serveCount(request: HttpRequest<Req>): Promise<HttpResponse<Number>> {
115
+ return HttpResponse.ok((await this.database.count(this.tableName, { ...request.query })));
116
+ }
117
+
118
+ protected async servePost(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
119
+ let entity = this.database.add(this.tableName, request.body);
120
+ return HttpResponse.ok(entity);
121
+ }
122
+
123
+ protected async servePut(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
124
+ return HttpResponse.ok("not implemented yet");
125
+ }
126
+
127
+ protected async serveDel(request: HttpRequest<Req>): Promise<HttpResponse<Res>> {
128
+ return HttpResponse.ok("not implemented yet");
129
+ }
130
+
131
+ protected readonly unwrap = ServiceRestFormal.unwrap
132
+ protected readonly fullSelect = ServiceRestFormal.fullSelect
133
+ }
@@ -0,0 +1,3 @@
1
+ export default class Business {
2
+
3
+ }
@@ -0,0 +1,94 @@
1
+ export interface FormalError {
2
+ id: string;
3
+ code: string;
4
+ description: string;
5
+ httpCode?: number;
6
+ group?: string;
7
+ }
8
+
9
+ export default class BusinessErrors {
10
+
11
+ private errors: { [key: string]: FormalError } = {};
12
+
13
+ async init() { }
14
+
15
+ setErrors(errors: { [key: string]: FormalError }) {
16
+ this.errors = errors;
17
+ }
18
+
19
+ get(code: string, ...params: string[]) {
20
+ let error = this.errors[code] ?? this.getFallback();
21
+ let result = Object.assign({} as FormalError, error);
22
+ for (const p in params) result.description = result.description?.replace(`\${${p}}`, params[p])
23
+ return result;
24
+ }
25
+
26
+ except(code: string, ...params: string[]) {
27
+ let error = this.get(code, ...params)
28
+ //this.onExcept?.(error)
29
+ throw error;
30
+ }
31
+
32
+ notFound(endpoint: string) {
33
+ this.except("0004", endpoint)
34
+ }
35
+
36
+ getQuery(key: string, query: {[key: string]: string}|undefined): string {
37
+ if (!query || !query[key]) this.except("0011", key)
38
+ return query![key];
39
+ }
40
+
41
+ eitherQuery(keys: string[], query: { [p: string]: string }): { key: string, value: string, index: number } {
42
+ let result = undefined;
43
+ for (let i = 0; i < keys.length; i++) {
44
+ let key = keys[i];
45
+ if (query[key] !== undefined) {
46
+ if (!result) result = {key: key, value: query[key], index: i}
47
+ else this.except("0017", keys.join(" or "));
48
+ }
49
+ }
50
+ if (!result) this.except("0016", keys.join(" or "));
51
+ return result!;
52
+ }
53
+
54
+ getPath(key: string, path: {[key: string]: string}): string {
55
+ if (!path[key]) this.except("0012", key)
56
+ return path[key];
57
+ }
58
+
59
+ getBody<T>(body?: T): T {
60
+ if (!body) this.except("0013")
61
+ return body!;
62
+ }
63
+
64
+ getHeaders(key: string, headers: {[key: string]: string}): string {
65
+ if (!headers[key]) this.except("0015", key)
66
+ return headers[key];
67
+ }
68
+
69
+ isType<T>(key: string, value: string, type:string, assertion: (value:string)=>T): T {
70
+ try { if (!assertion(value)) throw new Error(); }
71
+ catch { this.except("0021", key, type) }
72
+ return assertion(value);
73
+ }
74
+
75
+ exists<T>(type: string, key: string, value: string, object?:T): T {
76
+ if (!object) this.except("0030", type, key, value);
77
+ return object!;
78
+ }
79
+
80
+ isRegex(key: string, value: string, regex: string):string {
81
+ if (!new RegExp(regex).test(value))
82
+ this.except("0022", key)
83
+ return value;
84
+ }
85
+
86
+ isDate(key:string, value:string, format: string): Date {
87
+ this.except("0023", key, format);
88
+ return new Date(value);
89
+ }
90
+
91
+ getFallback(): FormalError {
92
+ return { id: "-1", description: "Internal Server error", code: "-1", httpCode: 500 };
93
+ }
94
+ }
@@ -0,0 +1,6 @@
1
+ export default class BusinessLogger
2
+ {
3
+ i(message: string) {
4
+ console.log(`${"I"}: ${new Date().toISOString()}\t${message}`)
5
+ };
6
+ }