namirasoft-node 1.4.21 → 1.4.23
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.
- package/dist/BaseApplication.js +7 -17
- package/dist/BaseApplication.js.map +1 -1
- package/dist/OTPOperation.d.ts +11 -2
- package/dist/OTPOperation.js +14 -4
- package/dist/OTPOperation.js.map +1 -1
- package/package.json +1 -1
- package/src/AnomalyDetector.ts +84 -84
- package/src/BaseApplication.ts +432 -432
- package/src/BaseApplicationLink.ts +6 -6
- package/src/BaseController.ts +193 -193
- package/src/BaseCron.ts +54 -54
- package/src/BaseDatabase.ts +199 -199
- package/src/BaseEmailService.ts +38 -38
- package/src/BaseTable.ts +107 -107
- package/src/CommandOperation.ts +32 -32
- package/src/EmptyDatabase.ts +11 -11
- package/src/GmailService.ts +22 -22
- package/src/IPOperation.ts +38 -38
- package/src/Meta.ts +40 -40
- package/src/OTPOperation.ts +90 -71
- package/src/RequestHeaderService.ts +27 -27
- package/src/SMTPService.ts +26 -26
- package/src/ServerToServerOperation.ts +23 -23
- package/src/index.ts +16 -16
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
export type BaseApplicationLink =
|
|
2
|
-
{
|
|
3
|
-
name: string;
|
|
4
|
-
url: string;
|
|
5
|
-
logo: string;
|
|
6
|
-
description: string;
|
|
1
|
+
export type BaseApplicationLink =
|
|
2
|
+
{
|
|
3
|
+
name: string;
|
|
4
|
+
url: string;
|
|
5
|
+
logo: string;
|
|
6
|
+
description: string;
|
|
7
7
|
};
|
package/src/BaseController.ts
CHANGED
|
@@ -1,194 +1,194 @@
|
|
|
1
|
-
import * as express from 'express';
|
|
2
|
-
import { BaseDatabase } from './BaseDatabase';
|
|
3
|
-
import { AnomalyDetector } from './AnomalyDetector';
|
|
4
|
-
import { Meta } from './Meta';
|
|
5
|
-
import { ErrorOperation, HTTPError, HTTPMethod, ObjectService } from 'namirasoft-core';
|
|
6
|
-
import { BaseApplication } from './BaseApplication';
|
|
7
|
-
import { BaseTypeSchema, BaseVariableSchema, ControllerSchema, JoiValidator } from 'namirasoft-schema';
|
|
8
|
-
|
|
9
|
-
export abstract class BaseController<D extends BaseDatabase, State, Props, Output>
|
|
10
|
-
{
|
|
11
|
-
protected showLogAtTheBeginning: boolean = false;
|
|
12
|
-
protected showLogAtTheEnd: boolean = true;
|
|
13
|
-
public app: BaseApplication<D>;
|
|
14
|
-
public req: express.Request;
|
|
15
|
-
public res: express.Response;
|
|
16
|
-
public meta!: Meta;
|
|
17
|
-
protected output!: Output | null;
|
|
18
|
-
protected result!: any;
|
|
19
|
-
protected database!: D;
|
|
20
|
-
protected state!: State;
|
|
21
|
-
protected props!: Props;
|
|
22
|
-
protected validate_query: boolean = true;
|
|
23
|
-
protected bodyAs: {
|
|
24
|
-
json: { enabled: boolean, limit: string },
|
|
25
|
-
raw: { enabled: boolean, type: string }
|
|
26
|
-
} = {
|
|
27
|
-
json: {
|
|
28
|
-
enabled: true,
|
|
29
|
-
limit: "100kb"
|
|
30
|
-
},
|
|
31
|
-
raw: {
|
|
32
|
-
enabled: false,
|
|
33
|
-
type: "application/json"
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
protected sensitive: boolean = false;
|
|
37
|
-
public generate_sdk: boolean = true;
|
|
38
|
-
public generate_swagger: boolean = true;
|
|
39
|
-
constructor(app: BaseApplication<D>, req: express.Request, res: express.Response)
|
|
40
|
-
{
|
|
41
|
-
this.app = app;
|
|
42
|
-
this.req = req;
|
|
43
|
-
this.res = res;
|
|
44
|
-
}
|
|
45
|
-
protected getAnomaly(): AnomalyDetector | null
|
|
46
|
-
{
|
|
47
|
-
return null;
|
|
48
|
-
}
|
|
49
|
-
abstract getInfo(): { name: string, tag: string, method: HTTPMethod, path: string, summary: string, ignoreDatabase?: boolean };
|
|
50
|
-
abstract getHeadersSchema(): Promise<BaseVariableSchema[]>;
|
|
51
|
-
abstract getParametersSchema(): Promise<BaseVariableSchema[]>;
|
|
52
|
-
abstract getBodySchema(): Promise<BaseTypeSchema | null>;
|
|
53
|
-
abstract getQueriesSchema(): Promise<BaseVariableSchema[]>;
|
|
54
|
-
async getQueriesSchemaSimple(): Promise<BaseVariableSchema[] | null>
|
|
55
|
-
{
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
abstract getOutputSchema(): Promise<BaseTypeSchema | null>;
|
|
59
|
-
abstract getState(): Promise<State>;
|
|
60
|
-
abstract getProps(): Promise<Props>;
|
|
61
|
-
abstract preHandle(): Promise<void>;
|
|
62
|
-
abstract handle(): Promise<Output>;
|
|
63
|
-
abstract postHandle(): Promise<void>;
|
|
64
|
-
|
|
65
|
-
async run()
|
|
66
|
-
{
|
|
67
|
-
let info = this.getInfo();
|
|
68
|
-
this.meta = new Meta(info, this.req, this.sensitive);
|
|
69
|
-
// output
|
|
70
|
-
this.output = null;
|
|
71
|
-
this.result = null;
|
|
72
|
-
try
|
|
73
|
-
{
|
|
74
|
-
// meta
|
|
75
|
-
this.meta.onStart();
|
|
76
|
-
if (this.showLogAtTheBeginning)
|
|
77
|
-
if (!this.meta.url.endsWith("/healthz"))
|
|
78
|
-
this.app.logger.info(this.meta);
|
|
79
|
-
|
|
80
|
-
let accpet: string = new ObjectService(this.req.headers.accept).getString("");
|
|
81
|
-
let isJson = accpet.includes("application/json") || accpet.includes("*/*");
|
|
82
|
-
let isSchema = accpet.includes("application/schema");
|
|
83
|
-
if (isJson)
|
|
84
|
-
{
|
|
85
|
-
// init controller
|
|
86
|
-
if (!info.ignoreDatabase)
|
|
87
|
-
{
|
|
88
|
-
this.database = this.app.getDatabase();
|
|
89
|
-
this.database.init();
|
|
90
|
-
this.database.connect();
|
|
91
|
-
}
|
|
92
|
-
this.state = await this.getState();
|
|
93
|
-
this.props = await this.getProps();
|
|
94
|
-
|
|
95
|
-
// preHandle
|
|
96
|
-
await this.preHandle();
|
|
97
|
-
|
|
98
|
-
// check for anomaly
|
|
99
|
-
let anomaly: AnomalyDetector | null = this.getAnomaly();
|
|
100
|
-
if (anomaly != null)
|
|
101
|
-
if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
|
|
102
|
-
ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
|
|
103
|
-
|
|
104
|
-
// check
|
|
105
|
-
await JoiValidator.check(await this.getBodySchema(), this.req.body);
|
|
106
|
-
if (this.validate_query)
|
|
107
|
-
{
|
|
108
|
-
let query = this.req.query;
|
|
109
|
-
let schemas = await this.getQueriesSchemaSimple();
|
|
110
|
-
if (schemas == null)
|
|
111
|
-
schemas = await this.getQueriesSchema();
|
|
112
|
-
else
|
|
113
|
-
{
|
|
114
|
-
for (let key of Object.keys(query))
|
|
115
|
-
{
|
|
116
|
-
let element = query[key];
|
|
117
|
-
if (Array.isArray(element))
|
|
118
|
-
query[key] = element.join(",");
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
await JoiValidator.checkArray(schemas, query);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// call controller
|
|
125
|
-
this.output = await this.handle();
|
|
126
|
-
|
|
127
|
-
// postHandle
|
|
128
|
-
await this.postHandle();
|
|
129
|
-
}
|
|
130
|
-
else if (isSchema)
|
|
131
|
-
{
|
|
132
|
-
// init controller
|
|
133
|
-
this.database = this.app.getDatabase();
|
|
134
|
-
this.database.init();
|
|
135
|
-
this.result = await this.getSchema();
|
|
136
|
-
}
|
|
137
|
-
else
|
|
138
|
-
ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
|
|
139
|
-
} catch (error)
|
|
140
|
-
{
|
|
141
|
-
let message: string;
|
|
142
|
-
if (error instanceof Error)
|
|
143
|
-
{
|
|
144
|
-
this.meta.error = error;
|
|
145
|
-
message = error.message;
|
|
146
|
-
}
|
|
147
|
-
else
|
|
148
|
-
message = error + "";
|
|
149
|
-
|
|
150
|
-
if (error instanceof HTTPError)
|
|
151
|
-
{
|
|
152
|
-
this.meta.code = error.code;
|
|
153
|
-
this.app.logger.error(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
|
|
154
|
-
}
|
|
155
|
-
else
|
|
156
|
-
{
|
|
157
|
-
this.meta.code = 500;
|
|
158
|
-
if (error instanceof Error)
|
|
159
|
-
this.app.logger.critical(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
|
|
160
|
-
}
|
|
161
|
-
this.meta.message = message;
|
|
162
|
-
if (error instanceof HTTPError)
|
|
163
|
-
this.result = this.meta.message;
|
|
164
|
-
else
|
|
165
|
-
this.result = "Sorry, internl server error.";
|
|
166
|
-
}
|
|
167
|
-
// result
|
|
168
|
-
if (!this.result)
|
|
169
|
-
{
|
|
170
|
-
if (this.output == null)
|
|
171
|
-
this.result = "Success";
|
|
172
|
-
else
|
|
173
|
-
this.result = this.output;
|
|
174
|
-
}
|
|
175
|
-
// finish
|
|
176
|
-
this.meta.onFinish();
|
|
177
|
-
if (this.showLogAtTheEnd)
|
|
178
|
-
if (!this.meta.url.endsWith("/healthz"))
|
|
179
|
-
this.app.logger.info(this.meta);
|
|
180
|
-
return this.res.status(this.meta.code).send(this.result);
|
|
181
|
-
}
|
|
182
|
-
async getSchema(): Promise<ControllerSchema>
|
|
183
|
-
{
|
|
184
|
-
let info = this.getInfo();
|
|
185
|
-
let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
|
|
186
|
-
schema.headers = await this.getHeadersSchema();
|
|
187
|
-
schema.parameters = await this.getParametersSchema();
|
|
188
|
-
schema.body = await this.getBodySchema();
|
|
189
|
-
schema.queries = await this.getQueriesSchema();
|
|
190
|
-
schema.output = await this.getOutputSchema();
|
|
191
|
-
schema.check();
|
|
192
|
-
return schema;
|
|
193
|
-
}
|
|
1
|
+
import * as express from 'express';
|
|
2
|
+
import { BaseDatabase } from './BaseDatabase';
|
|
3
|
+
import { AnomalyDetector } from './AnomalyDetector';
|
|
4
|
+
import { Meta } from './Meta';
|
|
5
|
+
import { ErrorOperation, HTTPError, HTTPMethod, ObjectService } from 'namirasoft-core';
|
|
6
|
+
import { BaseApplication } from './BaseApplication';
|
|
7
|
+
import { BaseTypeSchema, BaseVariableSchema, ControllerSchema, JoiValidator } from 'namirasoft-schema';
|
|
8
|
+
|
|
9
|
+
export abstract class BaseController<D extends BaseDatabase, State, Props, Output>
|
|
10
|
+
{
|
|
11
|
+
protected showLogAtTheBeginning: boolean = false;
|
|
12
|
+
protected showLogAtTheEnd: boolean = true;
|
|
13
|
+
public app: BaseApplication<D>;
|
|
14
|
+
public req: express.Request;
|
|
15
|
+
public res: express.Response;
|
|
16
|
+
public meta!: Meta;
|
|
17
|
+
protected output!: Output | null;
|
|
18
|
+
protected result!: any;
|
|
19
|
+
protected database!: D;
|
|
20
|
+
protected state!: State;
|
|
21
|
+
protected props!: Props;
|
|
22
|
+
protected validate_query: boolean = true;
|
|
23
|
+
protected bodyAs: {
|
|
24
|
+
json: { enabled: boolean, limit: string },
|
|
25
|
+
raw: { enabled: boolean, type: string }
|
|
26
|
+
} = {
|
|
27
|
+
json: {
|
|
28
|
+
enabled: true,
|
|
29
|
+
limit: "100kb"
|
|
30
|
+
},
|
|
31
|
+
raw: {
|
|
32
|
+
enabled: false,
|
|
33
|
+
type: "application/json"
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
protected sensitive: boolean = false;
|
|
37
|
+
public generate_sdk: boolean = true;
|
|
38
|
+
public generate_swagger: boolean = true;
|
|
39
|
+
constructor(app: BaseApplication<D>, req: express.Request, res: express.Response)
|
|
40
|
+
{
|
|
41
|
+
this.app = app;
|
|
42
|
+
this.req = req;
|
|
43
|
+
this.res = res;
|
|
44
|
+
}
|
|
45
|
+
protected getAnomaly(): AnomalyDetector | null
|
|
46
|
+
{
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
abstract getInfo(): { name: string, tag: string, method: HTTPMethod, path: string, summary: string, ignoreDatabase?: boolean };
|
|
50
|
+
abstract getHeadersSchema(): Promise<BaseVariableSchema[]>;
|
|
51
|
+
abstract getParametersSchema(): Promise<BaseVariableSchema[]>;
|
|
52
|
+
abstract getBodySchema(): Promise<BaseTypeSchema | null>;
|
|
53
|
+
abstract getQueriesSchema(): Promise<BaseVariableSchema[]>;
|
|
54
|
+
async getQueriesSchemaSimple(): Promise<BaseVariableSchema[] | null>
|
|
55
|
+
{
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
abstract getOutputSchema(): Promise<BaseTypeSchema | null>;
|
|
59
|
+
abstract getState(): Promise<State>;
|
|
60
|
+
abstract getProps(): Promise<Props>;
|
|
61
|
+
abstract preHandle(): Promise<void>;
|
|
62
|
+
abstract handle(): Promise<Output>;
|
|
63
|
+
abstract postHandle(): Promise<void>;
|
|
64
|
+
|
|
65
|
+
async run()
|
|
66
|
+
{
|
|
67
|
+
let info = this.getInfo();
|
|
68
|
+
this.meta = new Meta(info, this.req, this.sensitive);
|
|
69
|
+
// output
|
|
70
|
+
this.output = null;
|
|
71
|
+
this.result = null;
|
|
72
|
+
try
|
|
73
|
+
{
|
|
74
|
+
// meta
|
|
75
|
+
this.meta.onStart();
|
|
76
|
+
if (this.showLogAtTheBeginning)
|
|
77
|
+
if (!this.meta.url.endsWith("/healthz"))
|
|
78
|
+
this.app.logger.info(this.meta);
|
|
79
|
+
|
|
80
|
+
let accpet: string = new ObjectService(this.req.headers.accept).getString("");
|
|
81
|
+
let isJson = accpet.includes("application/json") || accpet.includes("*/*");
|
|
82
|
+
let isSchema = accpet.includes("application/schema");
|
|
83
|
+
if (isJson)
|
|
84
|
+
{
|
|
85
|
+
// init controller
|
|
86
|
+
if (!info.ignoreDatabase)
|
|
87
|
+
{
|
|
88
|
+
this.database = this.app.getDatabase();
|
|
89
|
+
this.database.init();
|
|
90
|
+
this.database.connect();
|
|
91
|
+
}
|
|
92
|
+
this.state = await this.getState();
|
|
93
|
+
this.props = await this.getProps();
|
|
94
|
+
|
|
95
|
+
// preHandle
|
|
96
|
+
await this.preHandle();
|
|
97
|
+
|
|
98
|
+
// check for anomaly
|
|
99
|
+
let anomaly: AnomalyDetector | null = this.getAnomaly();
|
|
100
|
+
if (anomaly != null)
|
|
101
|
+
if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
|
|
102
|
+
ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
|
|
103
|
+
|
|
104
|
+
// check
|
|
105
|
+
await JoiValidator.check(await this.getBodySchema(), this.req.body);
|
|
106
|
+
if (this.validate_query)
|
|
107
|
+
{
|
|
108
|
+
let query = this.req.query;
|
|
109
|
+
let schemas = await this.getQueriesSchemaSimple();
|
|
110
|
+
if (schemas == null)
|
|
111
|
+
schemas = await this.getQueriesSchema();
|
|
112
|
+
else
|
|
113
|
+
{
|
|
114
|
+
for (let key of Object.keys(query))
|
|
115
|
+
{
|
|
116
|
+
let element = query[key];
|
|
117
|
+
if (Array.isArray(element))
|
|
118
|
+
query[key] = element.join(",");
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
await JoiValidator.checkArray(schemas, query);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// call controller
|
|
125
|
+
this.output = await this.handle();
|
|
126
|
+
|
|
127
|
+
// postHandle
|
|
128
|
+
await this.postHandle();
|
|
129
|
+
}
|
|
130
|
+
else if (isSchema)
|
|
131
|
+
{
|
|
132
|
+
// init controller
|
|
133
|
+
this.database = this.app.getDatabase();
|
|
134
|
+
this.database.init();
|
|
135
|
+
this.result = await this.getSchema();
|
|
136
|
+
}
|
|
137
|
+
else
|
|
138
|
+
ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
|
|
139
|
+
} catch (error)
|
|
140
|
+
{
|
|
141
|
+
let message: string;
|
|
142
|
+
if (error instanceof Error)
|
|
143
|
+
{
|
|
144
|
+
this.meta.error = error;
|
|
145
|
+
message = error.message;
|
|
146
|
+
}
|
|
147
|
+
else
|
|
148
|
+
message = error + "";
|
|
149
|
+
|
|
150
|
+
if (error instanceof HTTPError)
|
|
151
|
+
{
|
|
152
|
+
this.meta.code = error.code;
|
|
153
|
+
this.app.logger.error(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
|
|
154
|
+
}
|
|
155
|
+
else
|
|
156
|
+
{
|
|
157
|
+
this.meta.code = 500;
|
|
158
|
+
if (error instanceof Error)
|
|
159
|
+
this.app.logger.critical(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
|
|
160
|
+
}
|
|
161
|
+
this.meta.message = message;
|
|
162
|
+
if (error instanceof HTTPError)
|
|
163
|
+
this.result = this.meta.message;
|
|
164
|
+
else
|
|
165
|
+
this.result = "Sorry, internl server error.";
|
|
166
|
+
}
|
|
167
|
+
// result
|
|
168
|
+
if (!this.result)
|
|
169
|
+
{
|
|
170
|
+
if (this.output == null)
|
|
171
|
+
this.result = "Success";
|
|
172
|
+
else
|
|
173
|
+
this.result = this.output;
|
|
174
|
+
}
|
|
175
|
+
// finish
|
|
176
|
+
this.meta.onFinish();
|
|
177
|
+
if (this.showLogAtTheEnd)
|
|
178
|
+
if (!this.meta.url.endsWith("/healthz"))
|
|
179
|
+
this.app.logger.info(this.meta);
|
|
180
|
+
return this.res.status(this.meta.code).send(this.result);
|
|
181
|
+
}
|
|
182
|
+
async getSchema(): Promise<ControllerSchema>
|
|
183
|
+
{
|
|
184
|
+
let info = this.getInfo();
|
|
185
|
+
let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
|
|
186
|
+
schema.headers = await this.getHeadersSchema();
|
|
187
|
+
schema.parameters = await this.getParametersSchema();
|
|
188
|
+
schema.body = await this.getBodySchema();
|
|
189
|
+
schema.queries = await this.getQueriesSchema();
|
|
190
|
+
schema.output = await this.getOutputSchema();
|
|
191
|
+
schema.check();
|
|
192
|
+
return schema;
|
|
193
|
+
}
|
|
194
194
|
}
|
package/src/BaseCron.ts
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
|
-
import { BaseDatabase } from './BaseDatabase';
|
|
2
|
-
import cron from 'node-cron';
|
|
3
|
-
import { BaseApplication } from './BaseApplication';
|
|
4
|
-
|
|
5
|
-
export abstract class BaseCron<D extends BaseDatabase>
|
|
6
|
-
{
|
|
7
|
-
protected app: BaseApplication<D>;
|
|
8
|
-
protected database!: D;
|
|
9
|
-
constructor(app: BaseApplication<D>)
|
|
10
|
-
{
|
|
11
|
-
this.app = app;
|
|
12
|
-
}
|
|
13
|
-
abstract getInfo(): { name: string, expression: string, runOnStart: boolean, ignoreDatabase?: boolean };
|
|
14
|
-
async preHandle(): Promise<void> { }
|
|
15
|
-
abstract handleOne(): Promise<void>;
|
|
16
|
-
async postHandle(): Promise<void> { }
|
|
17
|
-
|
|
18
|
-
run()
|
|
19
|
-
{
|
|
20
|
-
let info = this.getInfo();
|
|
21
|
-
this.app.logger.info(`Cron ${info.name} was schedued for ${info.expression}.`);
|
|
22
|
-
let runner = async () =>
|
|
23
|
-
{
|
|
24
|
-
this.app.logger.info(`Cron ${info.name} was started.`);
|
|
25
|
-
try
|
|
26
|
-
{
|
|
27
|
-
if (!info.ignoreDatabase)
|
|
28
|
-
{
|
|
29
|
-
if (!this.database)
|
|
30
|
-
{
|
|
31
|
-
this.database = this.app.getDatabase();
|
|
32
|
-
this.database.init();
|
|
33
|
-
}
|
|
34
|
-
this.database.connect();
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// preHandle
|
|
38
|
-
await this.preHandle();
|
|
39
|
-
// Handler
|
|
40
|
-
await this.handleOne();
|
|
41
|
-
// postHandle
|
|
42
|
-
await this.postHandle();
|
|
43
|
-
// Log
|
|
44
|
-
this.app.logger.info(`Cron ${info.name} was finished.`);
|
|
45
|
-
}
|
|
46
|
-
catch (error: any)
|
|
47
|
-
{
|
|
48
|
-
this.app.logger.onCatchError(error);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
if (info.runOnStart)
|
|
52
|
-
runner();
|
|
53
|
-
cron.schedule(info.expression, runner);
|
|
54
|
-
}
|
|
1
|
+
import { BaseDatabase } from './BaseDatabase';
|
|
2
|
+
import cron from 'node-cron';
|
|
3
|
+
import { BaseApplication } from './BaseApplication';
|
|
4
|
+
|
|
5
|
+
export abstract class BaseCron<D extends BaseDatabase>
|
|
6
|
+
{
|
|
7
|
+
protected app: BaseApplication<D>;
|
|
8
|
+
protected database!: D;
|
|
9
|
+
constructor(app: BaseApplication<D>)
|
|
10
|
+
{
|
|
11
|
+
this.app = app;
|
|
12
|
+
}
|
|
13
|
+
abstract getInfo(): { name: string, expression: string, runOnStart: boolean, ignoreDatabase?: boolean };
|
|
14
|
+
async preHandle(): Promise<void> { }
|
|
15
|
+
abstract handleOne(): Promise<void>;
|
|
16
|
+
async postHandle(): Promise<void> { }
|
|
17
|
+
|
|
18
|
+
run()
|
|
19
|
+
{
|
|
20
|
+
let info = this.getInfo();
|
|
21
|
+
this.app.logger.info(`Cron ${info.name} was schedued for ${info.expression}.`);
|
|
22
|
+
let runner = async () =>
|
|
23
|
+
{
|
|
24
|
+
this.app.logger.info(`Cron ${info.name} was started.`);
|
|
25
|
+
try
|
|
26
|
+
{
|
|
27
|
+
if (!info.ignoreDatabase)
|
|
28
|
+
{
|
|
29
|
+
if (!this.database)
|
|
30
|
+
{
|
|
31
|
+
this.database = this.app.getDatabase();
|
|
32
|
+
this.database.init();
|
|
33
|
+
}
|
|
34
|
+
this.database.connect();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// preHandle
|
|
38
|
+
await this.preHandle();
|
|
39
|
+
// Handler
|
|
40
|
+
await this.handleOne();
|
|
41
|
+
// postHandle
|
|
42
|
+
await this.postHandle();
|
|
43
|
+
// Log
|
|
44
|
+
this.app.logger.info(`Cron ${info.name} was finished.`);
|
|
45
|
+
}
|
|
46
|
+
catch (error: any)
|
|
47
|
+
{
|
|
48
|
+
this.app.logger.onCatchError(error);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
if (info.runOnStart)
|
|
52
|
+
runner();
|
|
53
|
+
cron.schedule(info.expression, runner);
|
|
54
|
+
}
|
|
55
55
|
}
|