namirasoft-node 1.3.68 → 1.3.69
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 +6 -1
- package/dist/BaseApplication.js.map +1 -1
- package/dist/CMDOperation.d.ts +4 -0
- package/dist/CMDOperation.js +43 -0
- package/dist/CMDOperation.js.map +1 -0
- package/dist/EmailService.d.ts +16 -0
- package/dist/EmailService.js +81 -0
- package/dist/EmailService.js.map +1 -0
- package/package.json +2 -2
- package/src/AnomalyDetector.ts +84 -84
- package/src/BaseApplication.ts +440 -435
- package/src/BaseApplicationLink.ts +6 -6
- package/src/BaseController.ts +193 -193
- package/src/BaseCron.ts +54 -54
- package/src/BaseDatabase.ts +192 -192
- package/src/BaseEmailService.ts +38 -38
- package/src/BaseTable.ts +94 -94
- package/src/CommandOperation.ts +32 -32
- package/src/EmptyDatabase.ts +7 -7
- package/src/EnvService.ts +22 -22
- package/src/GmailService.ts +22 -22
- package/src/IPOperation.ts +38 -38
- package/src/Meta.ts +40 -40
- package/src/OTPOperation.ts +64 -64
- package/src/RequestHeaderService.ts +27 -27
- package/src/SMTPService.ts +26 -26
- package/src/ServerToServerOperation.ts +23 -23
- package/src/index.ts +17 -17
package/src/BaseDatabase.ts
CHANGED
|
@@ -1,193 +1,193 @@
|
|
|
1
|
-
import { ErrorOperation, FilterItem, FilterItemOperator } from "namirasoft-core";
|
|
2
|
-
|
|
3
|
-
export interface IFilterableDatabase<WhereOptions>
|
|
4
|
-
{
|
|
5
|
-
getIn: (filter: FilterItem, values: string[]) => { condition: WhereOptions, partial: boolean };
|
|
6
|
-
getNotIn: (filter: FilterItem, values: string[]) => { condition: WhereOptions, partial: boolean };
|
|
7
|
-
getLike: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
8
|
-
getNotLike: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
9
|
-
getRegex: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
10
|
-
getNotRegex: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
11
|
-
getEmpty: (filter: FilterItem) => { condition: WhereOptions, partial: boolean };
|
|
12
|
-
getNotEmpty: (filter: FilterItem) => { condition: WhereOptions, partial: boolean };
|
|
13
|
-
getExists: (filter: FilterItem, not: boolean) => { condition: WhereOptions, partial: boolean };
|
|
14
|
-
getStartsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
15
|
-
getNotStartsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
16
|
-
getEndsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
17
|
-
getNotEndsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
18
|
-
getLT: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
19
|
-
getLTE: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
20
|
-
getGT: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
21
|
-
getGTE: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export abstract class BaseDatabase
|
|
25
|
-
{
|
|
26
|
-
private tables: { [name: string]: any } = {};
|
|
27
|
-
abstract init(): void;
|
|
28
|
-
abstract connect(): void;
|
|
29
|
-
abstract sync(force: boolean): Promise<void>;
|
|
30
|
-
addTable(name: string, table: any)
|
|
31
|
-
{
|
|
32
|
-
this.tables[name] = table;
|
|
33
|
-
}
|
|
34
|
-
getTable<T>(name: string): T
|
|
35
|
-
{
|
|
36
|
-
let ans = this.tables[name] as T;
|
|
37
|
-
if (!ans)
|
|
38
|
-
ErrorOperation.throwHTTP(404, `Table '${name}' not found`);
|
|
39
|
-
return ans;
|
|
40
|
-
}
|
|
41
|
-
paginate(page_number: number, page_size: number, page_size_default?: number): { offset: number, limit: number }
|
|
42
|
-
{
|
|
43
|
-
// page_number
|
|
44
|
-
if (isNaN(page_number))
|
|
45
|
-
page_number = 1;
|
|
46
|
-
// page_size
|
|
47
|
-
if (isNaN(page_size))
|
|
48
|
-
if (page_size_default)
|
|
49
|
-
page_size = page_size_default;
|
|
50
|
-
if (isNaN(page_size))
|
|
51
|
-
page_size = 25;
|
|
52
|
-
//
|
|
53
|
-
let offset = (page_number - 1) * page_size;
|
|
54
|
-
let limit = page_size;
|
|
55
|
-
return { offset, limit };
|
|
56
|
-
}
|
|
57
|
-
protected _getFiltersConditions<WhereOptions>(tables: { [table: string]: string[] }, idatabase: IFilterableDatabase<WhereOptions>, filters?: FilterItem[] | undefined): { [table: string]: WhereOptions[] }
|
|
58
|
-
{
|
|
59
|
-
let ans: { [table: string]: WhereOptions[] } = {};
|
|
60
|
-
Object.keys(tables).forEach(table => ans[table] = []);
|
|
61
|
-
if (filters)
|
|
62
|
-
{
|
|
63
|
-
let processed: { [index: number]: boolean } = {};
|
|
64
|
-
for (let i = 0; i < filters.length; i++)
|
|
65
|
-
if (!processed[i])
|
|
66
|
-
{
|
|
67
|
-
const filter = filters[i];
|
|
68
|
-
if (!tables[filter.table.name])
|
|
69
|
-
ErrorOperation.throwHTTP(404, `Invalid table name '${filter.table.name}'. Valid tables are '${Object.keys(tables).join(", ")}'.`);
|
|
70
|
-
let values = filter.values;
|
|
71
|
-
if (filter.operator.count > 0)
|
|
72
|
-
for (let j = i + 1; j < filters.length; j++)
|
|
73
|
-
{
|
|
74
|
-
const f = filters[j];
|
|
75
|
-
if (filter.table.name == f.table.name)
|
|
76
|
-
if (filter.column.name == f.column.name)
|
|
77
|
-
if (filter.not == f.not)
|
|
78
|
-
if (filter.operator.sign == f.operator.sign)
|
|
79
|
-
{
|
|
80
|
-
processed[j] = true;
|
|
81
|
-
values.push(...f.values);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
let getNumbers = () =>
|
|
86
|
-
{
|
|
87
|
-
let nums: number[] = values.map(x => parseFloat(x));
|
|
88
|
-
if (nums.filter(x => isNaN(x)).length > 0)
|
|
89
|
-
ErrorOperation.throwHTTP(400, `Invalid number values for: '${values.join(",")}'`);
|
|
90
|
-
return nums;
|
|
91
|
-
};
|
|
92
|
-
let addCondition = (res: { condition: WhereOptions, partial: boolean }) =>
|
|
93
|
-
{
|
|
94
|
-
if (res.partial)
|
|
95
|
-
{
|
|
96
|
-
let wh: any = {};
|
|
97
|
-
wh[filter.column.name] = res.condition;
|
|
98
|
-
ans[filter.table.name].push(wh);
|
|
99
|
-
}
|
|
100
|
-
else
|
|
101
|
-
ans[filter.table.name].push(res.condition);
|
|
102
|
-
};
|
|
103
|
-
if (filter.operator == FilterItemOperator.all.equals)
|
|
104
|
-
{
|
|
105
|
-
if (filter.not)
|
|
106
|
-
addCondition(idatabase.getNotIn(filter, values));
|
|
107
|
-
else
|
|
108
|
-
addCondition(idatabase.getIn(filter, values));
|
|
109
|
-
}
|
|
110
|
-
else if (filter.operator == FilterItemOperator.all.contains)
|
|
111
|
-
{
|
|
112
|
-
values.forEach(value =>
|
|
113
|
-
{
|
|
114
|
-
if (filter.not)
|
|
115
|
-
addCondition(idatabase.getNotLike(filter, value));
|
|
116
|
-
else
|
|
117
|
-
addCondition(idatabase.getLike(filter, value));
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
else if (filter.operator == FilterItemOperator.all.regex)
|
|
121
|
-
{
|
|
122
|
-
values.forEach(value =>
|
|
123
|
-
{
|
|
124
|
-
if (filter.not)
|
|
125
|
-
addCondition(idatabase.getNotRegex(filter, value));
|
|
126
|
-
else
|
|
127
|
-
addCondition(idatabase.getRegex(filter, value));
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
else if (filter.operator == FilterItemOperator.all.empty)
|
|
131
|
-
{
|
|
132
|
-
if (filter.not)
|
|
133
|
-
addCondition(idatabase.getNotEmpty(filter));
|
|
134
|
-
else
|
|
135
|
-
addCondition(idatabase.getEmpty(filter));
|
|
136
|
-
}
|
|
137
|
-
else if (filter.operator == FilterItemOperator.all.exists)
|
|
138
|
-
{
|
|
139
|
-
addCondition(idatabase.getExists(filter, filter.not));
|
|
140
|
-
}
|
|
141
|
-
else if (filter.operator == FilterItemOperator.all.startswith)
|
|
142
|
-
{
|
|
143
|
-
values.forEach(value =>
|
|
144
|
-
{
|
|
145
|
-
if (filter.not)
|
|
146
|
-
addCondition(idatabase.getNotStartsWith(filter, value));
|
|
147
|
-
else
|
|
148
|
-
addCondition(idatabase.getStartsWith(filter, value));
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
else if (filter.operator == FilterItemOperator.all.endswith)
|
|
152
|
-
{
|
|
153
|
-
values.forEach(value =>
|
|
154
|
-
{
|
|
155
|
-
if (filter.not)
|
|
156
|
-
addCondition(idatabase.getNotEndsWith(filter, value));
|
|
157
|
-
else
|
|
158
|
-
addCondition(idatabase.getEndsWith(filter, value));
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
else if (filter.operator == FilterItemOperator.all.lessthan)
|
|
162
|
-
{
|
|
163
|
-
if (filter.not)
|
|
164
|
-
addCondition(idatabase.getGTE(filter, Math.max(...getNumbers())));
|
|
165
|
-
else
|
|
166
|
-
addCondition(idatabase.getLT(filter, Math.max(...getNumbers())));
|
|
167
|
-
}
|
|
168
|
-
else if (filter.operator == FilterItemOperator.all.lessthanequal)
|
|
169
|
-
{
|
|
170
|
-
if (filter.not)
|
|
171
|
-
addCondition(idatabase.getGT(filter, Math.max(...getNumbers())));
|
|
172
|
-
else
|
|
173
|
-
addCondition(idatabase.getLTE(filter, Math.max(...getNumbers())));
|
|
174
|
-
}
|
|
175
|
-
else if (filter.operator == FilterItemOperator.all.morethan)
|
|
176
|
-
{
|
|
177
|
-
if (filter.not)
|
|
178
|
-
addCondition(idatabase.getLTE(filter, Math.max(...getNumbers())));
|
|
179
|
-
else
|
|
180
|
-
addCondition(idatabase.getGT(filter, Math.max(...getNumbers())));
|
|
181
|
-
}
|
|
182
|
-
else if (filter.operator == FilterItemOperator.all.morethanequal)
|
|
183
|
-
{
|
|
184
|
-
if (filter.not)
|
|
185
|
-
addCondition(idatabase.getLT(filter, Math.max(...getNumbers())));
|
|
186
|
-
else
|
|
187
|
-
addCondition(idatabase.getGTE(filter, Math.max(...getNumbers())));
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return ans;
|
|
192
|
-
}
|
|
1
|
+
import { ErrorOperation, FilterItem, FilterItemOperator } from "namirasoft-core";
|
|
2
|
+
|
|
3
|
+
export interface IFilterableDatabase<WhereOptions>
|
|
4
|
+
{
|
|
5
|
+
getIn: (filter: FilterItem, values: string[]) => { condition: WhereOptions, partial: boolean };
|
|
6
|
+
getNotIn: (filter: FilterItem, values: string[]) => { condition: WhereOptions, partial: boolean };
|
|
7
|
+
getLike: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
8
|
+
getNotLike: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
9
|
+
getRegex: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
10
|
+
getNotRegex: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
11
|
+
getEmpty: (filter: FilterItem) => { condition: WhereOptions, partial: boolean };
|
|
12
|
+
getNotEmpty: (filter: FilterItem) => { condition: WhereOptions, partial: boolean };
|
|
13
|
+
getExists: (filter: FilterItem, not: boolean) => { condition: WhereOptions, partial: boolean };
|
|
14
|
+
getStartsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
15
|
+
getNotStartsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
16
|
+
getEndsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
17
|
+
getNotEndsWith: (filter: FilterItem, value: string) => { condition: WhereOptions, partial: boolean };
|
|
18
|
+
getLT: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
19
|
+
getLTE: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
20
|
+
getGT: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
21
|
+
getGTE: (filter: FilterItem, value: any) => { condition: WhereOptions, partial: boolean };
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export abstract class BaseDatabase
|
|
25
|
+
{
|
|
26
|
+
private tables: { [name: string]: any } = {};
|
|
27
|
+
abstract init(): void;
|
|
28
|
+
abstract connect(): void;
|
|
29
|
+
abstract sync(force: boolean): Promise<void>;
|
|
30
|
+
addTable(name: string, table: any)
|
|
31
|
+
{
|
|
32
|
+
this.tables[name] = table;
|
|
33
|
+
}
|
|
34
|
+
getTable<T>(name: string): T
|
|
35
|
+
{
|
|
36
|
+
let ans = this.tables[name] as T;
|
|
37
|
+
if (!ans)
|
|
38
|
+
ErrorOperation.throwHTTP(404, `Table '${name}' not found`);
|
|
39
|
+
return ans;
|
|
40
|
+
}
|
|
41
|
+
paginate(page_number: number, page_size: number, page_size_default?: number): { offset: number, limit: number }
|
|
42
|
+
{
|
|
43
|
+
// page_number
|
|
44
|
+
if (isNaN(page_number))
|
|
45
|
+
page_number = 1;
|
|
46
|
+
// page_size
|
|
47
|
+
if (isNaN(page_size))
|
|
48
|
+
if (page_size_default)
|
|
49
|
+
page_size = page_size_default;
|
|
50
|
+
if (isNaN(page_size))
|
|
51
|
+
page_size = 25;
|
|
52
|
+
//
|
|
53
|
+
let offset = (page_number - 1) * page_size;
|
|
54
|
+
let limit = page_size;
|
|
55
|
+
return { offset, limit };
|
|
56
|
+
}
|
|
57
|
+
protected _getFiltersConditions<WhereOptions>(tables: { [table: string]: string[] }, idatabase: IFilterableDatabase<WhereOptions>, filters?: FilterItem[] | undefined): { [table: string]: WhereOptions[] }
|
|
58
|
+
{
|
|
59
|
+
let ans: { [table: string]: WhereOptions[] } = {};
|
|
60
|
+
Object.keys(tables).forEach(table => ans[table] = []);
|
|
61
|
+
if (filters)
|
|
62
|
+
{
|
|
63
|
+
let processed: { [index: number]: boolean } = {};
|
|
64
|
+
for (let i = 0; i < filters.length; i++)
|
|
65
|
+
if (!processed[i])
|
|
66
|
+
{
|
|
67
|
+
const filter = filters[i];
|
|
68
|
+
if (!tables[filter.table.name])
|
|
69
|
+
ErrorOperation.throwHTTP(404, `Invalid table name '${filter.table.name}'. Valid tables are '${Object.keys(tables).join(", ")}'.`);
|
|
70
|
+
let values = filter.values;
|
|
71
|
+
if (filter.operator.count > 0)
|
|
72
|
+
for (let j = i + 1; j < filters.length; j++)
|
|
73
|
+
{
|
|
74
|
+
const f = filters[j];
|
|
75
|
+
if (filter.table.name == f.table.name)
|
|
76
|
+
if (filter.column.name == f.column.name)
|
|
77
|
+
if (filter.not == f.not)
|
|
78
|
+
if (filter.operator.sign == f.operator.sign)
|
|
79
|
+
{
|
|
80
|
+
processed[j] = true;
|
|
81
|
+
values.push(...f.values);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
let getNumbers = () =>
|
|
86
|
+
{
|
|
87
|
+
let nums: number[] = values.map(x => parseFloat(x));
|
|
88
|
+
if (nums.filter(x => isNaN(x)).length > 0)
|
|
89
|
+
ErrorOperation.throwHTTP(400, `Invalid number values for: '${values.join(",")}'`);
|
|
90
|
+
return nums;
|
|
91
|
+
};
|
|
92
|
+
let addCondition = (res: { condition: WhereOptions, partial: boolean }) =>
|
|
93
|
+
{
|
|
94
|
+
if (res.partial)
|
|
95
|
+
{
|
|
96
|
+
let wh: any = {};
|
|
97
|
+
wh[filter.column.name] = res.condition;
|
|
98
|
+
ans[filter.table.name].push(wh);
|
|
99
|
+
}
|
|
100
|
+
else
|
|
101
|
+
ans[filter.table.name].push(res.condition);
|
|
102
|
+
};
|
|
103
|
+
if (filter.operator == FilterItemOperator.all.equals)
|
|
104
|
+
{
|
|
105
|
+
if (filter.not)
|
|
106
|
+
addCondition(idatabase.getNotIn(filter, values));
|
|
107
|
+
else
|
|
108
|
+
addCondition(idatabase.getIn(filter, values));
|
|
109
|
+
}
|
|
110
|
+
else if (filter.operator == FilterItemOperator.all.contains)
|
|
111
|
+
{
|
|
112
|
+
values.forEach(value =>
|
|
113
|
+
{
|
|
114
|
+
if (filter.not)
|
|
115
|
+
addCondition(idatabase.getNotLike(filter, value));
|
|
116
|
+
else
|
|
117
|
+
addCondition(idatabase.getLike(filter, value));
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else if (filter.operator == FilterItemOperator.all.regex)
|
|
121
|
+
{
|
|
122
|
+
values.forEach(value =>
|
|
123
|
+
{
|
|
124
|
+
if (filter.not)
|
|
125
|
+
addCondition(idatabase.getNotRegex(filter, value));
|
|
126
|
+
else
|
|
127
|
+
addCondition(idatabase.getRegex(filter, value));
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
else if (filter.operator == FilterItemOperator.all.empty)
|
|
131
|
+
{
|
|
132
|
+
if (filter.not)
|
|
133
|
+
addCondition(idatabase.getNotEmpty(filter));
|
|
134
|
+
else
|
|
135
|
+
addCondition(idatabase.getEmpty(filter));
|
|
136
|
+
}
|
|
137
|
+
else if (filter.operator == FilterItemOperator.all.exists)
|
|
138
|
+
{
|
|
139
|
+
addCondition(idatabase.getExists(filter, filter.not));
|
|
140
|
+
}
|
|
141
|
+
else if (filter.operator == FilterItemOperator.all.startswith)
|
|
142
|
+
{
|
|
143
|
+
values.forEach(value =>
|
|
144
|
+
{
|
|
145
|
+
if (filter.not)
|
|
146
|
+
addCondition(idatabase.getNotStartsWith(filter, value));
|
|
147
|
+
else
|
|
148
|
+
addCondition(idatabase.getStartsWith(filter, value));
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
else if (filter.operator == FilterItemOperator.all.endswith)
|
|
152
|
+
{
|
|
153
|
+
values.forEach(value =>
|
|
154
|
+
{
|
|
155
|
+
if (filter.not)
|
|
156
|
+
addCondition(idatabase.getNotEndsWith(filter, value));
|
|
157
|
+
else
|
|
158
|
+
addCondition(idatabase.getEndsWith(filter, value));
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
else if (filter.operator == FilterItemOperator.all.lessthan)
|
|
162
|
+
{
|
|
163
|
+
if (filter.not)
|
|
164
|
+
addCondition(idatabase.getGTE(filter, Math.max(...getNumbers())));
|
|
165
|
+
else
|
|
166
|
+
addCondition(idatabase.getLT(filter, Math.max(...getNumbers())));
|
|
167
|
+
}
|
|
168
|
+
else if (filter.operator == FilterItemOperator.all.lessthanequal)
|
|
169
|
+
{
|
|
170
|
+
if (filter.not)
|
|
171
|
+
addCondition(idatabase.getGT(filter, Math.max(...getNumbers())));
|
|
172
|
+
else
|
|
173
|
+
addCondition(idatabase.getLTE(filter, Math.max(...getNumbers())));
|
|
174
|
+
}
|
|
175
|
+
else if (filter.operator == FilterItemOperator.all.morethan)
|
|
176
|
+
{
|
|
177
|
+
if (filter.not)
|
|
178
|
+
addCondition(idatabase.getLTE(filter, Math.max(...getNumbers())));
|
|
179
|
+
else
|
|
180
|
+
addCondition(idatabase.getGT(filter, Math.max(...getNumbers())));
|
|
181
|
+
}
|
|
182
|
+
else if (filter.operator == FilterItemOperator.all.morethanequal)
|
|
183
|
+
{
|
|
184
|
+
if (filter.not)
|
|
185
|
+
addCondition(idatabase.getLT(filter, Math.max(...getNumbers())));
|
|
186
|
+
else
|
|
187
|
+
addCondition(idatabase.getGTE(filter, Math.max(...getNumbers())));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return ans;
|
|
192
|
+
}
|
|
193
193
|
}
|
package/src/BaseEmailService.ts
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import nodemailer from 'nodemailer';
|
|
2
|
-
import Mail, { AttachmentLike } from "nodemailer/lib/mailer";
|
|
3
|
-
import { Readable } from "stream";
|
|
4
|
-
|
|
5
|
-
export abstract class BaseEmailService
|
|
6
|
-
{
|
|
7
|
-
username: string;
|
|
8
|
-
constructor(username: string)
|
|
9
|
-
{
|
|
10
|
-
this.username = username;
|
|
11
|
-
}
|
|
12
|
-
protected abstract getTransform(): any;
|
|
13
|
-
send(from: string | null, to: string, subject: string, text: string, html?: string | Buffer | Readable | AttachmentLike | undefined, callback?: (err: Error | null, info: any) => void)
|
|
14
|
-
{
|
|
15
|
-
let transform = this.getTransform();
|
|
16
|
-
let transporter = nodemailer.createTransport(transform);
|
|
17
|
-
|
|
18
|
-
let mailOptions: Mail.Options = {
|
|
19
|
-
from: from ?? this.username,
|
|
20
|
-
to,
|
|
21
|
-
subject,
|
|
22
|
-
text,
|
|
23
|
-
html
|
|
24
|
-
};
|
|
25
|
-
if (html)
|
|
26
|
-
mailOptions.html = html;
|
|
27
|
-
|
|
28
|
-
transporter.sendMail(mailOptions, function (error, info)
|
|
29
|
-
{
|
|
30
|
-
if (callback)
|
|
31
|
-
callback(error, info);
|
|
32
|
-
else
|
|
33
|
-
{
|
|
34
|
-
if (error)
|
|
35
|
-
console.log(error);
|
|
36
|
-
}
|
|
37
|
-
});
|
|
38
|
-
}
|
|
1
|
+
import nodemailer from 'nodemailer';
|
|
2
|
+
import Mail, { AttachmentLike } from "nodemailer/lib/mailer";
|
|
3
|
+
import { Readable } from "stream";
|
|
4
|
+
|
|
5
|
+
export abstract class BaseEmailService
|
|
6
|
+
{
|
|
7
|
+
username: string;
|
|
8
|
+
constructor(username: string)
|
|
9
|
+
{
|
|
10
|
+
this.username = username;
|
|
11
|
+
}
|
|
12
|
+
protected abstract getTransform(): any;
|
|
13
|
+
send(from: string | null, to: string, subject: string, text: string, html?: string | Buffer | Readable | AttachmentLike | undefined, callback?: (err: Error | null, info: any) => void)
|
|
14
|
+
{
|
|
15
|
+
let transform = this.getTransform();
|
|
16
|
+
let transporter = nodemailer.createTransport(transform);
|
|
17
|
+
|
|
18
|
+
let mailOptions: Mail.Options = {
|
|
19
|
+
from: from ?? this.username,
|
|
20
|
+
to,
|
|
21
|
+
subject,
|
|
22
|
+
text,
|
|
23
|
+
html
|
|
24
|
+
};
|
|
25
|
+
if (html)
|
|
26
|
+
mailOptions.html = html;
|
|
27
|
+
|
|
28
|
+
transporter.sendMail(mailOptions, function (error, info)
|
|
29
|
+
{
|
|
30
|
+
if (callback)
|
|
31
|
+
callback(error, info);
|
|
32
|
+
else
|
|
33
|
+
{
|
|
34
|
+
if (error)
|
|
35
|
+
console.log(error);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
39
|
}
|
package/src/BaseTable.ts
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { ArraySchema, BaseTypeSchema, BaseVariableSchema, ObjectSchema } from "namirasoft-schema";
|
|
2
|
-
import { BaseDatabase } from "./BaseDatabase";
|
|
3
|
-
import { ErrorOperation } from "namirasoft-core";
|
|
4
|
-
|
|
5
|
-
export abstract class BaseTable<D extends BaseDatabase, ModelColumnOption>
|
|
6
|
-
{
|
|
7
|
-
database: D;
|
|
8
|
-
constructor(database: D)
|
|
9
|
-
{
|
|
10
|
-
this.database = database;
|
|
11
|
-
}
|
|
12
|
-
public abstract getName(): string;
|
|
13
|
-
public getSecureColumns(): string[]
|
|
14
|
-
{
|
|
15
|
-
return [];
|
|
16
|
-
}
|
|
17
|
-
public getReadOnlyColumns(): string[]
|
|
18
|
-
{
|
|
19
|
-
return [];
|
|
20
|
-
}
|
|
21
|
-
public secure(obj: any)
|
|
22
|
-
{
|
|
23
|
-
if (obj.dataValues)
|
|
24
|
-
obj = obj.dataValues;
|
|
25
|
-
let cols = this.getSecureColumns();
|
|
26
|
-
cols.forEach(col => delete obj[col]);
|
|
27
|
-
return obj;
|
|
28
|
-
}
|
|
29
|
-
public getArraySchema(require: boolean, name?: string): ArraySchema
|
|
30
|
-
{
|
|
31
|
-
let ans = this.getSchema(require, name);
|
|
32
|
-
return new ArraySchema(require, [ans]);
|
|
33
|
-
}
|
|
34
|
-
public getSchema(require: boolean, name?: string): ObjectSchema
|
|
35
|
-
{
|
|
36
|
-
let secureColumns = this.getSecureColumns();
|
|
37
|
-
let readOnlyColumns = this.getReadOnlyColumns();
|
|
38
|
-
let ans = new ObjectSchema(name ?? this.getName(), require, null);
|
|
39
|
-
this.forEachColumn((name, element) =>
|
|
40
|
-
{
|
|
41
|
-
if (!secureColumns.includes(name))
|
|
42
|
-
ans.addField(this.getVariableSchema(name, element, readOnlyColumns.includes(name)));
|
|
43
|
-
});
|
|
44
|
-
return ans;
|
|
45
|
-
}
|
|
46
|
-
public checkColumn(column: string)
|
|
47
|
-
{
|
|
48
|
-
let columns: string[] = [];
|
|
49
|
-
this.forEachColumn(name => columns.push(name));
|
|
50
|
-
if (!columns.includes(column))
|
|
51
|
-
ErrorOperation.throwHTTP(404, `Column '${column}' not found`);
|
|
52
|
-
}
|
|
53
|
-
public abstract forEachColumn(handler: (name: string, column: ModelColumnOption) => void): void;
|
|
54
|
-
private getVariableSchema(name: string, element: ModelColumnOption, read_only: boolean): BaseVariableSchema
|
|
55
|
-
{
|
|
56
|
-
let schema = this.getTypeSchema(element);
|
|
57
|
-
schema.read_only = read_only;
|
|
58
|
-
let es = this.getExamples();
|
|
59
|
-
schema.example = es[name] ?? "";
|
|
60
|
-
return new BaseVariableSchema(name, schema);
|
|
61
|
-
}
|
|
62
|
-
protected abstract getTypeSchema(element: ModelColumnOption): BaseTypeSchema;
|
|
63
|
-
protected getExamples(): { [name: string]: string }
|
|
64
|
-
{
|
|
65
|
-
return {};
|
|
66
|
-
}
|
|
67
|
-
public getSchemaNames(): string[]
|
|
68
|
-
{
|
|
69
|
-
return [];
|
|
70
|
-
}
|
|
71
|
-
public getSchemaByName(require: boolean, name?: string): ObjectSchema
|
|
72
|
-
{
|
|
73
|
-
let ans = this.getSchema(require, name);
|
|
74
|
-
if (name)
|
|
75
|
-
{
|
|
76
|
-
let names = this.getSchemaNames();
|
|
77
|
-
if (!names.includes(name))
|
|
78
|
-
throw new Error("Wrong schema name was provided: " + name);
|
|
79
|
-
this.setSchemaByName(ans);
|
|
80
|
-
}
|
|
81
|
-
return ans;
|
|
82
|
-
}
|
|
83
|
-
public getArraySchemaByName(require: boolean, name?: string): ArraySchema
|
|
84
|
-
{
|
|
85
|
-
let ans = this.getSchemaByName(require, name);
|
|
86
|
-
return new ArraySchema(require, [ans]);
|
|
87
|
-
}
|
|
88
|
-
protected setSchemaByName(_: ObjectSchema): void
|
|
89
|
-
{
|
|
90
|
-
}
|
|
91
|
-
public getNotFoundError(conditions: any | null)
|
|
92
|
-
{
|
|
93
|
-
return ErrorOperation.getHTTP(404, "Could not found " + this.getName() + " for " + JSON.stringify(conditions));
|
|
94
|
-
}
|
|
1
|
+
import { ArraySchema, BaseTypeSchema, BaseVariableSchema, ObjectSchema } from "namirasoft-schema";
|
|
2
|
+
import { BaseDatabase } from "./BaseDatabase";
|
|
3
|
+
import { ErrorOperation } from "namirasoft-core";
|
|
4
|
+
|
|
5
|
+
export abstract class BaseTable<D extends BaseDatabase, ModelColumnOption>
|
|
6
|
+
{
|
|
7
|
+
database: D;
|
|
8
|
+
constructor(database: D)
|
|
9
|
+
{
|
|
10
|
+
this.database = database;
|
|
11
|
+
}
|
|
12
|
+
public abstract getName(): string;
|
|
13
|
+
public getSecureColumns(): string[]
|
|
14
|
+
{
|
|
15
|
+
return [];
|
|
16
|
+
}
|
|
17
|
+
public getReadOnlyColumns(): string[]
|
|
18
|
+
{
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
public secure(obj: any)
|
|
22
|
+
{
|
|
23
|
+
if (obj.dataValues)
|
|
24
|
+
obj = obj.dataValues;
|
|
25
|
+
let cols = this.getSecureColumns();
|
|
26
|
+
cols.forEach(col => delete obj[col]);
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
public getArraySchema(require: boolean, name?: string): ArraySchema
|
|
30
|
+
{
|
|
31
|
+
let ans = this.getSchema(require, name);
|
|
32
|
+
return new ArraySchema(require, [ans]);
|
|
33
|
+
}
|
|
34
|
+
public getSchema(require: boolean, name?: string): ObjectSchema
|
|
35
|
+
{
|
|
36
|
+
let secureColumns = this.getSecureColumns();
|
|
37
|
+
let readOnlyColumns = this.getReadOnlyColumns();
|
|
38
|
+
let ans = new ObjectSchema(name ?? this.getName(), require, null);
|
|
39
|
+
this.forEachColumn((name, element) =>
|
|
40
|
+
{
|
|
41
|
+
if (!secureColumns.includes(name))
|
|
42
|
+
ans.addField(this.getVariableSchema(name, element, readOnlyColumns.includes(name)));
|
|
43
|
+
});
|
|
44
|
+
return ans;
|
|
45
|
+
}
|
|
46
|
+
public checkColumn(column: string)
|
|
47
|
+
{
|
|
48
|
+
let columns: string[] = [];
|
|
49
|
+
this.forEachColumn(name => columns.push(name));
|
|
50
|
+
if (!columns.includes(column))
|
|
51
|
+
ErrorOperation.throwHTTP(404, `Column '${column}' not found`);
|
|
52
|
+
}
|
|
53
|
+
public abstract forEachColumn(handler: (name: string, column: ModelColumnOption) => void): void;
|
|
54
|
+
private getVariableSchema(name: string, element: ModelColumnOption, read_only: boolean): BaseVariableSchema
|
|
55
|
+
{
|
|
56
|
+
let schema = this.getTypeSchema(element);
|
|
57
|
+
schema.read_only = read_only;
|
|
58
|
+
let es = this.getExamples();
|
|
59
|
+
schema.example = es[name] ?? "";
|
|
60
|
+
return new BaseVariableSchema(name, schema);
|
|
61
|
+
}
|
|
62
|
+
protected abstract getTypeSchema(element: ModelColumnOption): BaseTypeSchema;
|
|
63
|
+
protected getExamples(): { [name: string]: string }
|
|
64
|
+
{
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
public getSchemaNames(): string[]
|
|
68
|
+
{
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
public getSchemaByName(require: boolean, name?: string): ObjectSchema
|
|
72
|
+
{
|
|
73
|
+
let ans = this.getSchema(require, name);
|
|
74
|
+
if (name)
|
|
75
|
+
{
|
|
76
|
+
let names = this.getSchemaNames();
|
|
77
|
+
if (!names.includes(name))
|
|
78
|
+
throw new Error("Wrong schema name was provided: " + name);
|
|
79
|
+
this.setSchemaByName(ans);
|
|
80
|
+
}
|
|
81
|
+
return ans;
|
|
82
|
+
}
|
|
83
|
+
public getArraySchemaByName(require: boolean, name?: string): ArraySchema
|
|
84
|
+
{
|
|
85
|
+
let ans = this.getSchemaByName(require, name);
|
|
86
|
+
return new ArraySchema(require, [ans]);
|
|
87
|
+
}
|
|
88
|
+
protected setSchemaByName(_: ObjectSchema): void
|
|
89
|
+
{
|
|
90
|
+
}
|
|
91
|
+
public getNotFoundError(conditions: any | null)
|
|
92
|
+
{
|
|
93
|
+
return ErrorOperation.getHTTP(404, "Could not found " + this.getName() + " for " + JSON.stringify(conditions));
|
|
94
|
+
}
|
|
95
95
|
}
|