namirasoft-node 1.4.67 → 1.4.68

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.
@@ -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
  };
@@ -1,206 +1,206 @@
1
- import * as express from 'express';
2
- import { BaseDatabase } from './BaseDatabase';
3
- import { AnomalyDetector } from './AnomalyDetector';
4
- import { Meta } from './Meta';
5
- import { EnvService, 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.req = this.req;
90
- this.database.res = this.res;
91
- this.database.init();
92
- this.database.connect();
93
- }
94
- this.state = await this.getState();
95
- this.props = await this.getProps();
96
-
97
- // preHandle
98
- await this.preHandle();
99
-
100
- // check for anomaly
101
- let anomaly: AnomalyDetector | null = this.getAnomaly();
102
- if (anomaly != null)
103
- if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
104
- ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
105
-
106
- // check
107
- JoiValidator.check(await this.getBodySchema(), this.req.body, "Body");
108
- if (this.validate_query)
109
- {
110
- let query = this.req.query;
111
- let schemas = await this.getQueriesSchemaSimple();
112
- if (schemas == null)
113
- schemas = await this.getQueriesSchema();
114
- else
115
- {
116
- for (let key of Object.keys(query))
117
- {
118
- let element = query[key];
119
- if (Array.isArray(element))
120
- query[key] = element.join(",");
121
- }
122
- }
123
- JoiValidator.checkArray(schemas, query, "Query String");
124
- }
125
-
126
- // call controller
127
- this.output = await this.handle();
128
-
129
- // postHandle
130
- await this.postHandle();
131
- }
132
- else if (isSchema)
133
- {
134
- // init controller
135
- this.database = this.app.getDatabase();
136
- this.database.req = this.req;
137
- this.database.res = this.res;
138
- this.database.init();
139
- this.result = await this.getSchema();
140
- }
141
- else
142
- ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
143
- } catch (error)
144
- {
145
- let message: string;
146
- if (error instanceof Error)
147
- {
148
- this.meta.error = error;
149
- message = error.message;
150
- }
151
- else
152
- message = error + "";
153
-
154
- if (error instanceof HTTPError)
155
- {
156
- this.meta.code = error.code;
157
- this.app.logger.error(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
158
- }
159
- else
160
- {
161
- this.meta.code = 500;
162
- if (error instanceof Error)
163
- this.app.logger.critical(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
164
- }
165
- this.meta.message = message;
166
- if (error instanceof HTTPError)
167
- this.result = this.meta.message;
168
- else
169
- this.result = "Sorry, internl server error.";
170
- }
171
- // result
172
- if (!this.result)
173
- {
174
- if (this.output == null)
175
- this.result = "Success";
176
- else
177
- this.result = this.output;
178
- }
179
- // finish
180
- this.meta.onFinish();
181
- if (this.showLogAtTheEnd)
182
- if (!this.meta.url.endsWith("/healthz"))
183
- this.app.logger.info(this.meta);
184
- if (this.meta.redirect_location)
185
- return this.res.redirect(this.meta.code, this.meta.redirect_location);
186
- return this.res.status(this.meta.code).send(this.result);
187
- }
188
- async getSchema(): Promise<ControllerSchema>
189
- {
190
- let info = this.getInfo();
191
- let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
192
- schema.headers = await this.getHeadersSchema();
193
- schema.parameters = await this.getParametersSchema();
194
- schema.body = await this.getBodySchema();
195
- schema.queries = await this.getQueriesSchema();
196
- schema.output = await this.getOutputSchema();
197
- schema.check();
198
- return schema;
199
- }
200
- protected _setCookie(name: string, value: any)
201
- {
202
- let DOMAIN = new EnvService("DOMAIN").getString();
203
- let domain = "." + DOMAIN;
204
- this.res.cookie(name, value, { domain, path: "/", sameSite: "none", secure: true });
205
- }
1
+ import * as express from 'express';
2
+ import { BaseDatabase } from './BaseDatabase';
3
+ import { AnomalyDetector } from './AnomalyDetector';
4
+ import { Meta } from './Meta';
5
+ import { EnvService, 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.req = this.req;
90
+ this.database.res = this.res;
91
+ this.database.init();
92
+ this.database.connect();
93
+ }
94
+ this.state = await this.getState();
95
+ this.props = await this.getProps();
96
+
97
+ // preHandle
98
+ await this.preHandle();
99
+
100
+ // check for anomaly
101
+ let anomaly: AnomalyDetector | null = this.getAnomaly();
102
+ if (anomaly != null)
103
+ if (anomaly.isAnomaly(this.meta.ip, this.meta.url))
104
+ ErrorOperation.throwHTTP(403, 'Suspicious activity detected.');
105
+
106
+ // check
107
+ JoiValidator.check(await this.getBodySchema(), this.req.body, "Body");
108
+ if (this.validate_query)
109
+ {
110
+ let query = this.req.query;
111
+ let schemas = await this.getQueriesSchemaSimple();
112
+ if (schemas == null)
113
+ schemas = await this.getQueriesSchema();
114
+ else
115
+ {
116
+ for (let key of Object.keys(query))
117
+ {
118
+ let element = query[key];
119
+ if (Array.isArray(element))
120
+ query[key] = element.join(",");
121
+ }
122
+ }
123
+ JoiValidator.checkArray(schemas, query, "Query String");
124
+ }
125
+
126
+ // call controller
127
+ this.output = await this.handle();
128
+
129
+ // postHandle
130
+ await this.postHandle();
131
+ }
132
+ else if (isSchema)
133
+ {
134
+ // init controller
135
+ this.database = this.app.getDatabase();
136
+ this.database.req = this.req;
137
+ this.database.res = this.res;
138
+ this.database.init();
139
+ this.result = await this.getSchema();
140
+ }
141
+ else
142
+ ErrorOperation.throwHTTP(400, "Invalid accept: " + accpet);
143
+ } catch (error)
144
+ {
145
+ let message: string;
146
+ if (error instanceof Error)
147
+ {
148
+ this.meta.error = error;
149
+ message = error.message;
150
+ }
151
+ else
152
+ message = error + "";
153
+
154
+ if (error instanceof HTTPError)
155
+ {
156
+ this.meta.code = error.code;
157
+ this.app.logger.error(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
158
+ }
159
+ else
160
+ {
161
+ this.meta.code = 500;
162
+ if (error instanceof Error)
163
+ this.app.logger.critical(error.message + "\n" + JSON.stringify(this.meta, undefined, 4), error.stack);
164
+ }
165
+ this.meta.message = message;
166
+ if (error instanceof HTTPError)
167
+ this.result = this.meta.message;
168
+ else
169
+ this.result = "Sorry, internl server error.";
170
+ }
171
+ // result
172
+ if (!this.result)
173
+ {
174
+ if (this.output == null)
175
+ this.result = "Success";
176
+ else
177
+ this.result = this.output;
178
+ }
179
+ // finish
180
+ this.meta.onFinish();
181
+ if (this.showLogAtTheEnd)
182
+ if (!this.meta.url.endsWith("/healthz"))
183
+ this.app.logger.info(this.meta);
184
+ if (this.meta.redirect_location)
185
+ return this.res.redirect(this.meta.code, this.meta.redirect_location);
186
+ return this.res.status(this.meta.code).send(this.result);
187
+ }
188
+ async getSchema(): Promise<ControllerSchema>
189
+ {
190
+ let info = this.getInfo();
191
+ let schema = new ControllerSchema(info.name, info.tag, info.method, info.path, info.summary);
192
+ schema.headers = await this.getHeadersSchema();
193
+ schema.parameters = await this.getParametersSchema();
194
+ schema.body = await this.getBodySchema();
195
+ schema.queries = await this.getQueriesSchema();
196
+ schema.output = await this.getOutputSchema();
197
+ schema.check();
198
+ return schema;
199
+ }
200
+ protected _setCookie(name: string, value: any)
201
+ {
202
+ let DOMAIN = new EnvService("DOMAIN").getString();
203
+ let domain = "." + DOMAIN;
204
+ this.res.cookie(name, value, { domain, path: "/", sameSite: "none", secure: true });
205
+ }
206
206
  }
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
  }
@@ -1,46 +1,46 @@
1
- import * as express from "express";
2
- import { ErrorOperation, SortItem } from "namirasoft-core";
3
-
4
- export abstract class BaseDatabase
5
- {
6
- private tables: { [name: string]: any } = {};
7
- public req?: express.Request;
8
- public res?: express.Response;
9
- abstract init(): Promise<void>;
10
- abstract connect(): void;
11
- abstract sync(force: boolean): Promise<void>;
12
- async seedBefore(): Promise<void>
13
- {
14
- }
15
- async seedAfter(): Promise<void>
16
- {
17
- }
18
- addTable(name: string, table: any)
19
- {
20
- this.tables[name] = table;
21
- }
22
- getTable<T>(name: string): T
23
- {
24
- let ans = this.tables[name] as T;
25
- if (!ans)
26
- ErrorOperation.throwHTTP(404, `Table '${name}' not found`);
27
- return ans;
28
- }
29
- paginate(page_number: number, page_size: number, page_size_default?: number): { offset: number, limit: number }
30
- {
31
- // page_number
32
- if (isNaN(page_number))
33
- page_number = 1;
34
- // page_size
35
- if (isNaN(page_size))
36
- if (page_size_default)
37
- page_size = page_size_default;
38
- if (isNaN(page_size))
39
- page_size = 25;
40
- //
41
- let offset = (page_number - 1) * page_size;
42
- let limit = page_size;
43
- return { offset, limit };
44
- }
45
- public abstract getSortOptions(sorts?: SortItem[] | undefined): any;
1
+ import * as express from "express";
2
+ import { ErrorOperation, SortItem } from "namirasoft-core";
3
+
4
+ export abstract class BaseDatabase
5
+ {
6
+ private tables: { [name: string]: any } = {};
7
+ public req?: express.Request;
8
+ public res?: express.Response;
9
+ abstract init(): Promise<void>;
10
+ abstract connect(): void;
11
+ abstract sync(force: boolean): Promise<void>;
12
+ async seedBefore(): Promise<void>
13
+ {
14
+ }
15
+ async seedAfter(): Promise<void>
16
+ {
17
+ }
18
+ addTable(name: string, table: any)
19
+ {
20
+ this.tables[name] = table;
21
+ }
22
+ getTable<T>(name: string): T
23
+ {
24
+ let ans = this.tables[name] as T;
25
+ if (!ans)
26
+ ErrorOperation.throwHTTP(404, `Table '${name}' not found`);
27
+ return ans;
28
+ }
29
+ paginate(page_number: number, page_size: number, page_size_default?: number): { offset: number, limit: number }
30
+ {
31
+ // page_number
32
+ if (isNaN(page_number))
33
+ page_number = 1;
34
+ // page_size
35
+ if (isNaN(page_size))
36
+ if (page_size_default)
37
+ page_size = page_size_default;
38
+ if (isNaN(page_size))
39
+ page_size = 25;
40
+ //
41
+ let offset = (page_number - 1) * page_size;
42
+ let limit = page_size;
43
+ return { offset, limit };
44
+ }
45
+ public abstract getSortOptions(sorts?: SortItem[] | undefined): any;
46
46
  }