5htp-core 0.1.2 → 0.2.1

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 (148) hide show
  1. package/changelog.md +5 -0
  2. package/doc/TODO.md +71 -0
  3. package/package.json +5 -4
  4. package/src/client/{App.tsx → app/component.tsx} +15 -11
  5. package/src/client/app/index.ts +128 -0
  6. package/src/client/app/service.ts +34 -0
  7. package/src/client/app.tsconfig.json +0 -4
  8. package/src/client/assets/css/components.less +52 -0
  9. package/src/client/assets/css/core.less +7 -28
  10. package/src/client/assets/css/theme.less +1 -1
  11. package/src/client/assets/css/{borders.less → utils/borders.less} +0 -0
  12. package/src/client/assets/css/{layouts.less → utils/layouts.less} +0 -0
  13. package/src/client/assets/css/{medias.less → utils/medias.less} +14 -1
  14. package/src/client/assets/css/{sizing.less → utils/sizing.less} +0 -0
  15. package/src/client/assets/css/{spacing.less → utils/spacing.less} +0 -0
  16. package/src/client/components/Card/index.tsx +13 -7
  17. package/src/client/components/Dialog/Manager.tsx +41 -14
  18. package/src/client/components/Dialog/index.less +2 -4
  19. package/src/client/components/Form/index.tsx +1 -1
  20. package/src/client/components/Row/index.less +0 -2
  21. package/src/client/components/Table/index.tsx +3 -2
  22. package/src/client/components/button.tsx +2 -2
  23. package/src/client/components/containers/Popover/index.tsx +1 -1
  24. package/src/client/components/containers/champs.less +0 -2
  25. package/src/client/components/data/spintext/index.tsx +1 -1
  26. package/src/client/components/dropdown/index.tsx +1 -1
  27. package/src/client/components/index.ts +23 -0
  28. package/src/client/components/input/BaseV2/index.less +0 -2
  29. package/src/client/components/input/BaseV2/index.tsx +1 -1
  30. package/src/client/components/input/Date/index.less +0 -2
  31. package/src/client/components/input/Periode/index.less +0 -2
  32. package/src/client/components/input/Radio/index.less +0 -2
  33. package/src/client/components/input/UploadImage/index.less +0 -2
  34. package/src/client/components/input/UploadImage/index.tsx +1 -1
  35. package/src/client/hooks/index.ts +5 -0
  36. package/src/client/hooks/useState/index.tsx +2 -2
  37. package/src/client/hooks.ts +22 -0
  38. package/src/client/index.ts +5 -0
  39. package/src/client/pages/_layout/landing/index.tsx +0 -2
  40. package/src/client/pages/_messages/400.tsx +2 -2
  41. package/src/client/pages/_messages/401.tsx +2 -2
  42. package/src/client/pages/_messages/403.tsx +2 -2
  43. package/src/client/pages/_messages/404.tsx +2 -2
  44. package/src/client/pages/_messages/500.tsx +2 -2
  45. package/src/client/pages/bug.tsx +1 -1
  46. package/src/client/pages/useHeader.tsx +1 -1
  47. package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
  48. package/src/client/services/metrics/index.ts +37 -0
  49. package/src/client/{router → services/router/components}/Link.tsx +1 -1
  50. package/src/client/services/router/components/Page.tsx +59 -0
  51. package/src/client/{router/component.tsx → services/router/components/router.tsx} +52 -74
  52. package/src/client/services/router/index.tsx +453 -0
  53. package/src/client/services/router/request/api.ts +227 -0
  54. package/src/client/{router → services/router}/request/history.ts +0 -0
  55. package/src/client/services/router/request/index.ts +52 -0
  56. package/src/client/services/router/response/index.tsx +107 -0
  57. package/src/client/services/router/response/page.ts +90 -0
  58. package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
  59. package/src/client/utils/dom.ts +1 -1
  60. package/src/common/app/index.ts +9 -0
  61. package/src/common/data/chaines/index.ts +9 -6
  62. package/src/common/data/input/validate.ts +3 -166
  63. package/src/common/data/objets.ts +25 -0
  64. package/src/common/data/tableaux.ts +8 -0
  65. package/src/common/errors/index.ts +3 -1
  66. package/src/common/router/index.ts +67 -88
  67. package/src/common/router/layouts.ts +50 -0
  68. package/src/common/router/register.ts +62 -0
  69. package/src/common/router/request/api.ts +72 -0
  70. package/src/common/router/request/index.ts +31 -0
  71. package/src/common/router/{response.ts → response/index.ts} +9 -13
  72. package/src/common/router/response/page.ts +46 -54
  73. package/src/common/validation/index.ts +3 -0
  74. package/src/common/validation/schema.ts +185 -0
  75. package/src/common/validation/validator.ts +95 -0
  76. package/src/common/validation/validators.ts +313 -0
  77. package/src/server/app/config.ts +9 -27
  78. package/src/server/app/index.ts +81 -124
  79. package/src/server/app/service.ts +98 -0
  80. package/src/server/app.tsconfig.json +0 -8
  81. package/src/server/index.ts +5 -0
  82. package/src/server/patch.ts +0 -6
  83. package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
  84. package/src/server/services/console/bugReporter.ts +26 -16
  85. package/src/server/services/console/index.ts +59 -51
  86. package/src/server/services/cron/index.ts +12 -26
  87. package/src/server/services/database/bucket.ts +40 -0
  88. package/src/server/services/database/connection.ts +213 -80
  89. package/src/server/services/database/datatypes.ts +63 -40
  90. package/src/server/services/database/debug.ts +20 -0
  91. package/src/server/services/database/index.ts +295 -272
  92. package/src/server/services/database/metas.ts +246 -135
  93. package/src/server/services/database/stats.ts +151 -126
  94. package/src/server/services/email/index.ts +30 -62
  95. package/src/server/services/email/transporter.ts +38 -0
  96. package/src/server/services/{router/request/services → metrics}/detect.ts +8 -10
  97. package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
  98. package/src/server/services/{http → router/http}/index.ts +28 -70
  99. package/src/server/services/{http → router/http}/multipart.ts +0 -0
  100. package/src/server/services/{http → router/http}/session.ts.old +0 -0
  101. package/src/server/services/router/index.ts +273 -202
  102. package/src/server/services/router/request/api.ts +76 -0
  103. package/src/server/services/router/request/index.ts +16 -97
  104. package/src/server/services/router/request/service.ts +21 -0
  105. package/src/server/services/router/response/index.ts +131 -65
  106. package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
  107. package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
  108. package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
  109. package/src/server/services/router/response/page/document.tsx +194 -0
  110. package/src/server/services/router/response/page/index.tsx +157 -0
  111. package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
  112. package/src/server/services/router/service.ts +48 -0
  113. package/src/server/services/schema/index.ts +47 -0
  114. package/src/server/services/schema/request.ts +55 -0
  115. package/src/server/services/schema/router.ts +33 -0
  116. package/src/server/services/socket/index.ts +38 -43
  117. package/src/server/services/socket/scope.ts +6 -4
  118. package/src/server/services/users/index.ts +203 -0
  119. package/src/server/services/{auth/base.ts → users/old.ts} +28 -112
  120. package/src/server/services/users/router/index.ts +72 -0
  121. package/src/server/services/users/router/request.ts +49 -0
  122. package/src/server/{data → services_old}/SocketClient.ts +0 -0
  123. package/src/server/{data/Token.olg.ts → services_old/Token.old.ts} +0 -0
  124. package/src/server/{data → services_old}/aes.ts +0 -0
  125. package/src/types/aliases.d.ts +43 -2
  126. package/templates/composant.tsx +1 -1
  127. package/templates/modal.tsx +1 -1
  128. package/templates/page.tsx +1 -1
  129. package/tsconfig.common.json +0 -4
  130. package/src/client/assets/css/components/components.less +0 -31
  131. package/src/client/context/api.ts +0 -92
  132. package/src/client/context/index.ts +0 -246
  133. package/src/client/index.tsx +0 -129
  134. package/src/client/router/index.ts +0 -286
  135. package/src/client/router/request/index.ts +0 -106
  136. package/src/client/router/response/index.ts +0 -38
  137. package/src/client/router/route.ts +0 -75
  138. package/src/common/data/input/validators/basic.ts +0 -299
  139. package/src/common/data/input/validators/build.ts +0 -63
  140. package/src/common/router/request.ts +0 -83
  141. package/src/server/data/ApiClient.ts +0 -119
  142. package/src/server/data/input.ts +0 -41
  143. package/src/server/libs/pages/document.static.tsx +0 -41
  144. package/src/server/libs/pages/document.tsx +0 -203
  145. package/src/server/libs/pages/render.tsx +0 -90
  146. package/src/server/routes/auth.ts +0 -151
  147. package/src/server/services/redis/index.ts +0 -71
  148. package/src/server/services/router/request/services/auth.ts +0 -177
@@ -2,12 +2,13 @@
2
2
  - OUTILS DE TRAITEMENT
3
3
  ----------------------------------*/
4
4
 
5
- // nPM
5
+ // Npm
6
6
  import hInterval from 'human-interval';
7
7
 
8
- // Cor elibs
9
- import { $ } from '@server/app';
10
- import Cache from '@server/data/Cache';
8
+ // Core
9
+ import Service from '@server/app/service';
10
+ import type CacheService from '../cache';
11
+ import type SQL from '../database';
11
12
 
12
13
  /*----------------------------------
13
14
  - CONST
@@ -41,6 +42,11 @@ const debug = false;
41
42
  /*----------------------------------
42
43
  - TYPES
43
44
  ----------------------------------*/
45
+
46
+ type TStatsServiceConfig = {
47
+
48
+ }
49
+
44
50
  type TObjDonneesStats = { [cheminStats: string]: number }
45
51
  export type TStat<TDonnees extends TObjDonneesStats> = { date: string } & TDonnees
46
52
  export type TTimeStat<TDonnees extends TObjDonneesStats> = { time: number } & TDonnees
@@ -55,141 +61,160 @@ type TRetourStats<TDonnees extends TObjDonneesStats> = {
55
61
  interval: number,
56
62
  }
57
63
 
58
- export default async function fetchStats<TDonnees extends TObjDonneesStats>(
59
-
60
- table: string, columns: (string | [string, string])[], {
61
-
62
- // Query
63
- where,
64
- // time
65
- period, interval,
66
- // Options
67
- relative, cache
68
-
69
- }: {
70
- // Database
71
- where?: string,
72
- // Time
73
- period: string,
74
- interval: string,
75
- // Options
76
- relative?: boolean,
77
- cache?: { id: string, duration?: string },
78
- }): Promise< TRetourStats<TDonnees> > {
79
-
80
- if (!debug && cache !== undefined) {
81
- const fromCache = await Cache.getVal<TRetourStats<TDonnees>>(cache.id);
82
- if (fromCache !== null) {
83
- console.log("Using value from cache " + cache.id);
84
- return fromCache;
85
- }
86
- }
64
+ /*----------------------------------
65
+ - SERVICE
66
+ ----------------------------------*/
67
+ export default class StatsService extends Service<TStatsServiceConfig> {
87
68
 
88
- // NOTE: On ne génère pas le timestamp via la bdd pour éviter les incohérences de timezone
89
- const periodTime = hInterval(period);
90
- if (periodTime === undefined) throw new Error(`Invalid period string: ` + period);
91
- const intervalTime = hInterval(interval);
92
- if (intervalTime === undefined) throw new Error(`Invalid interval string: ` + interval);
93
- const periodSec = Math.floor(periodTime / 1000);
94
-
95
- const startTime = scaleTime(Date.now() - periodTime, intervalTime); // Round start date to the specified interval
96
- const endTime = scaleTime(Date.now(), intervalTime);
97
- const stats: TRetourStats<TDonnees> = {
98
- graph: [],
99
- stats: {} as TDonnees,
100
- start: new Date(startTime),
101
- end: new Date(endTime),
102
- interval: intervalTime
103
- }
69
+ public constructor(
70
+ config: TStatsServiceConfig,
71
+ private cache: CacheService,
72
+ private sql: SQL
73
+ ) {
104
74
 
105
- let rows: TDonnees[];
106
- let previousRow: TObjetDonnees = {};
107
-
108
- const selector = statsCols(columns, relative ? 'SUM' : '');
109
-
110
- // Fetch data (initial point + variations)
111
- // Since values are relative, we will use stats.total as initialValues,
112
- // and then increment it to get the latest tota value
113
- ([[previousRow], rows] = await $.sql.query(`
114
-
115
- # Latest values before start time
116
- SELECT ${selector}
117
- FROM ${table}
118
- WHERE date < (NOW() - INTERVAL ${periodSec} SECOND) ${where ? 'AND ' + where : ''}
119
- ORDER BY date DESC
120
- LIMIT 1;
121
-
122
- # First value for each peiod of time
123
- SELECT ${selector},
124
- FLOOR( UNIX_TIMESTAMP(date) * 1000 / ${intervalTime}) * ${intervalTime} as periodTime
125
- FROM ${table}
126
- WHERE (date BETWEEN (NOW() - INTERVAL ${periodSec} SECOND) AND NOW())
127
- ${where ? 'AND ' + where : ''}
128
-
129
- # In addition of the variations between start and end date, we take the latest values
130
- GROUP BY (date = (SELECT MAX(date) FROM core.NetworkStats)), periodTime
131
- ORDER BY date DESC;
132
-
133
- `) as [[TDonnees | undefined], TDonnees[]]);
134
-
135
- // Process
136
- if (rows.length === 0)
137
- return stats;
138
- if (previousRow === undefined)
139
- previousRow = {};
75
+ super(config);
140
76
 
141
- rows.reverse();
77
+ }
142
78
 
143
- // Index entries by time
144
- const periods: { [periodTime: number]: TTimeStat<TDonnees> } = {};
145
- for (const { periodTime, ...row } of rows)
146
- periods[periodTime] = row;
79
+ public async register() {}
80
+ public async start() {}
147
81
 
148
- // Completion
149
- for (let time = startTime; time <= endTime; time += intervalTime) {
82
+ public async fetchStats<TDonnees extends TObjDonneesStats>(
83
+
84
+ table: string, columns: (string | [string, string])[], {
85
+
86
+ // Query
87
+ where,
88
+ // time
89
+ period, interval,
90
+ // Options
91
+ relative, cache
92
+
93
+ }: {
94
+ // Database
95
+ where?: string,
96
+ // Time
97
+ period: string,
98
+ interval: string,
99
+ // Options
100
+ relative?: boolean,
101
+ cache?: { id: string, duration?: string },
102
+ }): Promise< TRetourStats<TDonnees> > {
103
+
104
+ if (!debug && cache !== undefined) {
105
+ const fromCache = await this.cache.get<TRetourStats<TDonnees>>(cache.id);
106
+ if (fromCache !== null) {
107
+ console.log("Using value from cache " + cache.id);
108
+ return fromCache.value;
109
+ }
110
+ }
150
111
 
151
- const row = relative ? { ...previousRow, time } : { time };
152
- stats.graph.push(row);
112
+ // NOTE: On ne génère pas le timestamp via la bdd pour éviter les incohérences de timezone
113
+ const periodTime = hInterval(period);
114
+ if (periodTime === undefined) throw new Error(`Invalid period string: ` + period);
115
+ const intervalTime = hInterval(interval);
116
+ if (intervalTime === undefined) throw new Error(`Invalid interval string: ` + interval);
117
+ const periodSec = Math.floor(periodTime / 1000);
118
+
119
+ const startTime = scaleTime(Date.now() - periodTime, intervalTime); // Round start date to the specified interval
120
+ const endTime = scaleTime(Date.now(), intervalTime);
121
+ const stats: TRetourStats<TDonnees> = {
122
+ graph: [],
123
+ stats: {} as TDonnees,
124
+ start: new Date(startTime),
125
+ end: new Date(endTime),
126
+ interval: intervalTime
127
+ }
153
128
 
154
- // No data for this period
155
- if (periods[time] === undefined)
156
- continue;
129
+ let rows: TDonnees[];
130
+ let previousRow: TObjetDonnees = {};
157
131
 
158
- for (const nom in periods[time]) {
132
+ const selector = statsCols(columns, relative ? 'SUM' : '');
133
+
134
+ // Fetch data (initial point + variations)
135
+ // Since values are relative, we will use stats.total as initialValues,
136
+ // and then increment it to get the latest tota value
137
+ ([[previousRow], rows] = await this.sql.query(`
138
+
139
+ # Latest values before start time
140
+ SELECT ${selector}
141
+ FROM ${table}
142
+ WHERE date < (NOW() - INTERVAL ${periodSec} SECOND) ${where ? 'AND ' + where : ''}
143
+ ORDER BY date DESC
144
+ LIMIT 1;
145
+
146
+ # First value for each peiod of time
147
+ SELECT ${selector},
148
+ FLOOR( UNIX_TIMESTAMP(date) * 1000 / ${intervalTime}) * ${intervalTime} as periodTime
149
+ FROM ${table}
150
+ WHERE (date BETWEEN (NOW() - INTERVAL ${periodSec} SECOND) AND NOW())
151
+ ${where ? 'AND ' + where : ''}
152
+
153
+ # In addition of the variations between start and end date, we take the latest values
154
+ GROUP BY (date = (SELECT MAX(date) FROM core.NetworkStats)), periodTime
155
+ ORDER BY date DESC;
156
+
157
+ `) as [[TDonnees | undefined], TDonnees[]]);
158
+
159
+ // Process
160
+ if (rows.length === 0)
161
+ return stats;
162
+ if (previousRow === undefined)
163
+ previousRow = {};
164
+
165
+ rows.reverse();
166
+
167
+ // Index entries by time
168
+ const periods: { [periodTime: number]: TTimeStat<TDonnees> } = {};
169
+ for (const { periodTime, ...row } of rows)
170
+ periods[periodTime] = row;
171
+
172
+ // Completion
173
+ for (let time = startTime; time <= endTime; time += intervalTime) {
174
+
175
+ const row = relative ? { ...previousRow, time } : { time };
176
+ stats.graph.push(row);
177
+
178
+ // No data for this period
179
+ if (periods[time] === undefined)
180
+ continue;
181
+
182
+ for (const nom in periods[time]) {
159
183
 
160
- const value = periods[time][nom];
184
+ const value = periods[time][nom];
161
185
 
162
- row[nom] = (relative && typeof row[nom] === 'number')
163
- ? row[nom] + value
164
- : value;
186
+ row[nom] = (relative && typeof row[nom] === 'number')
187
+ ? row[nom] + value
188
+ : value;
165
189
 
166
- }
190
+ }
167
191
 
168
- previousRow = { ...row };
169
- }
192
+ previousRow = { ...row };
193
+ }
170
194
 
171
- // Total = latest known values
172
- stats.stats = previousRow;
173
-
174
- // Check if the times selected from the database matches with the times iéterated from the completion
175
- if (debug) {
176
- for (const period in periods)
177
- if (!stats.graph.find( g => g.time.toString() === period )) {
178
- console.warn(
179
- `The timetamps selected from the database do not match with the one generated by the completion function`,
180
- '\nStart date:', startTime, stats.start.toISOString(), ' End date:', endTime, stats.end.toISOString(),
181
- '\nFrom database', Object.keys(periods).map(time => time + ' (' + new Date( parseInt(time) ).toISOString() + ')'),
182
- '\nFrom completion (now - period ; now):', stats.graph.map(g => g.time + ' (' + new Date(g.time).toISOString() + ')')
183
- );
184
- throw new Error("Integrity check failed.");
195
+ // Total = latest known values
196
+ stats.stats = previousRow;
197
+
198
+ // Check if the times selected from the database matches with the times iéterated from the completion
199
+ if (debug) {
200
+ for (const period in periods)
201
+ if (!stats.graph.find( g => g.time.toString() === period )) {
202
+ console.warn(
203
+ `The timetamps selected from the database do not match with the one generated by the completion function`,
204
+ '\nStart date:', startTime, stats.start.toISOString(), ' End date:', endTime, stats.end.toISOString(),
205
+ '\nFrom database', Object.keys(periods).map(time => time + ' (' + new Date( parseInt(time) ).toISOString() + ')'),
206
+ '\nFrom completion (now - period ; now):', stats.graph.map(g => g.time + ' (' + new Date(g.time).toISOString() + ')')
207
+ );
208
+ throw new Error("Integrity check failed.");
209
+
210
+ }
185
211
 
186
- }
187
-
188
- console.log(cache?.id, "Cumulative stats: total =", stats.stats, "rows =", rows, "periods =", periods, "stats =", stats);
189
- }
212
+ console.log(cache?.id, "Cumulative stats: total =", stats.stats, "rows =", rows, "periods =", periods, "stats =", stats);
213
+ }
190
214
 
191
- if (cache !== undefined)
192
- await Cache.set( cache.id, stats, cache.duration || interval );
193
-
194
- return stats;
215
+ if (cache !== undefined)
216
+ await this.cache.set( cache.id, stats, cache.duration || interval );
217
+
218
+ return stats;
219
+ }
195
220
  }
@@ -7,39 +7,41 @@
7
7
  */
8
8
 
9
9
  // Core
10
- import app, { $ } from '@server/app';
11
- //import templates from './templates';
12
- const templates = {} as {[template: string]: (data: any) => string}
10
+ import Application, { Service } from '@server/app';
11
+
12
+ // Speciic
13
13
  import { jsonToHtml } from './utils';
14
+ import type { Transporter } from './transporter';
14
15
 
15
16
  /*----------------------------------
16
17
  - SERVICE CONFIG
17
18
  ----------------------------------*/
18
19
 
19
- export type EmailServiceConfig = {
20
+ export type Config = {
20
21
  debug: boolean,
21
22
  default: {
22
23
  transporter: string,
23
24
  from: string
24
25
  },
25
- transporters: Core.EmailTransporters
26
+ transporters: {
27
+ [transporterName: string]: Transporter
28
+ },
29
+ bugReport: {
30
+ from: string,
31
+ to: string
32
+ }
26
33
  }
27
34
 
28
- declare global {
29
- namespace Core {
30
- interface EmailTransporters { }
31
- namespace Config {
32
- interface Services {
33
- email: EmailServiceConfig
34
- }
35
- }
36
- }
35
+ export type Hooks = {
36
+
37
37
  }
38
-
38
+
39
39
  /*----------------------------------
40
40
  - TYPES: EMAILS
41
41
  ----------------------------------*/
42
42
 
43
+ export { Transporter } from './transporter';
44
+
43
45
  export type TEmail = THtmlEmail | TTemplateEmail;
44
46
 
45
47
  type TBaseEmail = {
@@ -65,50 +67,27 @@ export type TCompleteEmail = With<THtmlEmail, {
65
67
  /*----------------------------------
66
68
  - TYPES: OPTIONS
67
69
  ----------------------------------*/
68
-
69
- export abstract class Transporter {
70
- public abstract send( emails: TCompleteEmail[] ): Promise<void>;
71
- }
72
-
73
70
  type TOptions = {
74
71
  transporter?: string,
75
72
  testing?: boolean
76
73
  }
77
74
 
78
- const config = app.config.email;
79
-
80
75
  /*----------------------------------
81
76
  - FONCTIONS
82
77
  ----------------------------------*/
83
- export default class Email {
78
+ export default class Email extends Service<Config, Hooks, Application> {
79
+
80
+ private transporters = this.config.transporters;
81
+
82
+ public async register() {
84
83
 
85
- private transporters = {} as {[name: string]: Transporter};
86
- public register( name: string, transporter: (new () => Transporter) ) {
87
- console.log(`[email] registering email transporter: ${name}`);
88
- this.transporters[ name ] = new transporter();
89
84
  }
90
85
 
91
- public load() {
92
- $.console.bugReport.addTransporter('email', (report) => this.send(report.type === 'server' ? {
93
- to: app.identity.author.email,
94
- subject: "Bug on server: " + (report.error.message),
95
- html: `
96
- <a href="${app.env.url}/admin/activity/requests/${report.channelId}">
97
- View Request details & console
98
- </a>
99
- <br/>
100
- ${report.logs}
101
- `
102
- } : {
103
- to: app.identity.author.email,
104
- subject: "Bug on application " + (report.action),
105
- html: {
106
- ...report
107
- }
108
- }));
86
+ public async start() {
109
87
 
110
88
  }
111
89
 
90
+
112
91
  public async send(
113
92
  emails: TEmail | TEmail[],
114
93
  options: TOptions = {}
@@ -118,12 +97,12 @@ export default class Email {
118
97
  if (!Array.isArray( emails ))
119
98
  emails = [emails];
120
99
 
121
- config.debug && console.log(`Preparing to send ${emails.length} emails ...`);
100
+ this.config.debug && console.log(`Preparing to send ${emails.length} emails ...`);
122
101
 
123
102
  const emailsToSend: TCompleteEmail[] = emails.map(email => {
124
103
 
125
104
  const from = email.from === undefined
126
- ? config.default.from
105
+ ? this.config.default.from
127
106
  : email.from;
128
107
 
129
108
  const to = typeof email.to === 'string'
@@ -131,6 +110,7 @@ export default class Email {
131
110
  : email.to;
132
111
 
133
112
  // Via template
113
+ // TODO: Restore templates feature
134
114
  if ('template' in email) {
135
115
 
136
116
  const template = templates[email.template];
@@ -164,7 +144,7 @@ export default class Email {
164
144
 
165
145
  });
166
146
 
167
- const transporterName = options.transporter || app.config.email.default.transporter;
147
+ const transporterName = options.transporter || this.config.default.transporter;
168
148
  if (transporterName === undefined)
169
149
  throw new Error(`Please define at least one mail transporter.`);
170
150
 
@@ -182,20 +162,8 @@ export default class Email {
182
162
  return;
183
163
  }
184
164
 
185
- const Transporter = this.transporters[ transporterName ];
186
- await Transporter.send(emailsToSend);
165
+ const transporter = this.transporters[ transporterName ];
166
+ await transporter.send(emailsToSend);
187
167
 
188
168
  }
189
- }
190
-
191
- /*----------------------------------
192
- - REGISTER SERVICE
193
- ----------------------------------*/
194
- app.register('email', Email);
195
- declare global {
196
- namespace Core {
197
- interface Services {
198
- email: Email;
199
- }
200
- }
201
169
  }
@@ -0,0 +1,38 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+
7
+ // Core
8
+ import type Application from "@server/app";
9
+ import type EmailService from '@server/services/email';
10
+
11
+ // Specific
12
+ import type { TCompleteEmail } from ".";
13
+
14
+ /*----------------------------------
15
+ - TYPES
16
+ ----------------------------------*/
17
+
18
+ export type TBasicConfig = {
19
+ api: string,
20
+ debug: boolean
21
+ }
22
+
23
+ /*----------------------------------
24
+ - CLASS
25
+ ----------------------------------*/
26
+ export abstract class Transporter<TConfig extends {} = {}> {
27
+
28
+ public constructor(
29
+ protected app: Application & { email: EmailService },
30
+ protected config: TBasicConfig & TConfig,
31
+
32
+ protected email = app.email
33
+ ) {
34
+
35
+ }
36
+
37
+ public abstract send( emails: TCompleteEmail[] ): Promise<void>;
38
+ }
@@ -3,17 +3,14 @@
3
3
  ----------------------------------*/
4
4
 
5
5
  // Npm
6
- import express from 'express';
6
+ import got from 'got';
7
7
 
8
8
  // Core
9
9
  import { Forbidden } from '@common/errors';
10
- import request from '@server/data/ApiClient';
11
- import ServerRequest from '..';
12
- import TrackerService from './tracking';
10
+ import ServerRequest from '../router/request';
13
11
 
14
12
  // App
15
13
  import app from '@server/app';
16
- import { IP } from '@models';
17
14
 
18
15
  /*----------------------------------
19
16
  - TYPES
@@ -80,6 +77,8 @@ export default class ProtectService {
80
77
 
81
78
  return conflict;*/
82
79
 
80
+ return false;
81
+
83
82
  }
84
83
 
85
84
  public async captcha(token?: string) {
@@ -92,14 +91,13 @@ export default class ProtectService {
92
91
  if (!token)
93
92
  throw new Forbidden("Le captcha n'a pas été complété.");
94
93
 
95
- const res = await request.post('https://www.google.com/recaptcha/api/siteverify', {}, {
96
- params: {
94
+ const res = await got.post('https://www.google.com/recaptcha/api/siteverify', {
95
+ body: JSON.stringify({
97
96
  secret: app.config.http.security.recaptcha.prv,
98
97
  response: token,
99
98
  remoteip: null
100
- },
101
- debug: false
102
- }).then(res => res.data)
99
+ })
100
+ }).json()
103
101
 
104
102
  console.info(`Réponse captcha`, res);
105
103