proteum 1.0.0-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 (156) hide show
  1. package/.dockerignore +10 -0
  2. package/Rte.zip +0 -0
  3. package/cli/app/config.ts +54 -0
  4. package/cli/app/index.ts +195 -0
  5. package/cli/bin.js +11 -0
  6. package/cli/commands/build.ts +34 -0
  7. package/cli/commands/deploy/app.ts +29 -0
  8. package/cli/commands/deploy/web.ts +60 -0
  9. package/cli/commands/dev.ts +109 -0
  10. package/cli/commands/init.ts +85 -0
  11. package/cli/compiler/client/identite.ts +72 -0
  12. package/cli/compiler/client/index.ts +334 -0
  13. package/cli/compiler/common/babel/index.ts +170 -0
  14. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  15. package/cli/compiler/common/babel/plugins/services.ts +579 -0
  16. package/cli/compiler/common/babel/routes/imports.ts +127 -0
  17. package/cli/compiler/common/babel/routes/routes.ts +1130 -0
  18. package/cli/compiler/common/files/autres.ts +39 -0
  19. package/cli/compiler/common/files/images.ts +35 -0
  20. package/cli/compiler/common/files/style.ts +78 -0
  21. package/cli/compiler/common/index.ts +154 -0
  22. package/cli/compiler/index.ts +532 -0
  23. package/cli/compiler/server/index.ts +211 -0
  24. package/cli/index.ts +189 -0
  25. package/cli/paths.ts +165 -0
  26. package/cli/print.ts +12 -0
  27. package/cli/tsconfig.json +38 -0
  28. package/cli/utils/index.ts +22 -0
  29. package/cli/utils/keyboard.ts +78 -0
  30. package/client/app/component.tsx +54 -0
  31. package/client/app/index.ts +142 -0
  32. package/client/app/service.ts +34 -0
  33. package/client/app.tsconfig.json +28 -0
  34. package/client/components/Button.tsx +298 -0
  35. package/client/components/Dialog/Manager.tsx +309 -0
  36. package/client/components/Dialog/card.tsx +208 -0
  37. package/client/components/Dialog/index.less +151 -0
  38. package/client/components/Dialog/status.less +176 -0
  39. package/client/components/Dialog/status.tsx +48 -0
  40. package/client/components/index.ts +2 -0
  41. package/client/components/types.d.ts +3 -0
  42. package/client/data/input.ts +32 -0
  43. package/client/global.d.ts +5 -0
  44. package/client/hooks.ts +22 -0
  45. package/client/index.ts +6 -0
  46. package/client/pages/_layout/index.less +6 -0
  47. package/client/pages/_layout/index.tsx +43 -0
  48. package/client/pages/bug.tsx.old +60 -0
  49. package/client/pages/useHeader.tsx +50 -0
  50. package/client/services/captcha/index.ts +67 -0
  51. package/client/services/router/components/Link.tsx +46 -0
  52. package/client/services/router/components/Page.tsx +55 -0
  53. package/client/services/router/components/router.tsx +218 -0
  54. package/client/services/router/index.tsx +521 -0
  55. package/client/services/router/request/api.ts +267 -0
  56. package/client/services/router/request/history.ts +5 -0
  57. package/client/services/router/request/index.ts +53 -0
  58. package/client/services/router/request/multipart.ts +147 -0
  59. package/client/services/router/response/index.tsx +128 -0
  60. package/client/services/router/response/page.ts +86 -0
  61. package/client/services/socket/index.ts +147 -0
  62. package/client/utils/dom.ts +77 -0
  63. package/common/app/index.ts +9 -0
  64. package/common/data/chaines/index.ts +54 -0
  65. package/common/data/dates.ts +179 -0
  66. package/common/data/markdown.ts +73 -0
  67. package/common/data/rte/nodes.ts +83 -0
  68. package/common/data/stats.ts +90 -0
  69. package/common/errors/index.tsx +326 -0
  70. package/common/router/index.ts +213 -0
  71. package/common/router/layouts.ts +93 -0
  72. package/common/router/register.ts +55 -0
  73. package/common/router/request/api.ts +77 -0
  74. package/common/router/request/index.ts +35 -0
  75. package/common/router/response/index.ts +45 -0
  76. package/common/router/response/page.ts +128 -0
  77. package/common/utils/rte.ts +183 -0
  78. package/common/utils.ts +7 -0
  79. package/doc/TODO.md +71 -0
  80. package/doc/front/router.md +27 -0
  81. package/doc/workspace/workspace.png +0 -0
  82. package/doc/workspace/workspace2.png +0 -0
  83. package/doc/workspace/workspace_26.01.22.png +0 -0
  84. package/package.json +171 -0
  85. package/server/app/commands.ts +141 -0
  86. package/server/app/container/config.ts +203 -0
  87. package/server/app/container/console/index.ts +550 -0
  88. package/server/app/container/index.ts +137 -0
  89. package/server/app/index.ts +273 -0
  90. package/server/app/service/container.ts +88 -0
  91. package/server/app/service/index.ts +235 -0
  92. package/server/app.tsconfig.json +28 -0
  93. package/server/context.ts +4 -0
  94. package/server/index.ts +4 -0
  95. package/server/services/auth/index.ts +250 -0
  96. package/server/services/auth/old.ts +277 -0
  97. package/server/services/auth/router/index.ts +95 -0
  98. package/server/services/auth/router/request.ts +54 -0
  99. package/server/services/auth/router/service.json +6 -0
  100. package/server/services/auth/service.json +6 -0
  101. package/server/services/cache/commands.ts +41 -0
  102. package/server/services/cache/index.ts +297 -0
  103. package/server/services/cache/service.json +6 -0
  104. package/server/services/cron/CronTask.ts +86 -0
  105. package/server/services/cron/index.ts +112 -0
  106. package/server/services/cron/service.json +6 -0
  107. package/server/services/disks/driver.ts +103 -0
  108. package/server/services/disks/drivers/local/index.ts +188 -0
  109. package/server/services/disks/drivers/local/service.json +6 -0
  110. package/server/services/disks/drivers/s3/index.ts +301 -0
  111. package/server/services/disks/drivers/s3/service.json +6 -0
  112. package/server/services/disks/index.ts +90 -0
  113. package/server/services/disks/service.json +6 -0
  114. package/server/services/email/index.ts +188 -0
  115. package/server/services/email/utils.ts +53 -0
  116. package/server/services/fetch/index.ts +201 -0
  117. package/server/services/fetch/service.json +7 -0
  118. package/server/services/models.7z +0 -0
  119. package/server/services/prisma/Facet.ts +142 -0
  120. package/server/services/prisma/index.ts +201 -0
  121. package/server/services/prisma/service.json +6 -0
  122. package/server/services/router/http/index.ts +217 -0
  123. package/server/services/router/http/multipart.ts +102 -0
  124. package/server/services/router/http/session.ts.old +40 -0
  125. package/server/services/router/index.ts +801 -0
  126. package/server/services/router/request/api.ts +87 -0
  127. package/server/services/router/request/index.ts +184 -0
  128. package/server/services/router/request/service.ts +21 -0
  129. package/server/services/router/request/validation/zod.ts +180 -0
  130. package/server/services/router/response/index.ts +338 -0
  131. package/server/services/router/response/mask/Filter.ts +323 -0
  132. package/server/services/router/response/mask/index.ts +60 -0
  133. package/server/services/router/response/mask/selecteurs.ts +92 -0
  134. package/server/services/router/response/page/document.tsx +160 -0
  135. package/server/services/router/response/page/index.tsx +196 -0
  136. package/server/services/router/service.json +6 -0
  137. package/server/services/router/service.ts +36 -0
  138. package/server/services/schema/index.ts +44 -0
  139. package/server/services/schema/request.ts +49 -0
  140. package/server/services/schema/router/index.ts +28 -0
  141. package/server/services/schema/router/service.json +6 -0
  142. package/server/services/schema/service.json +6 -0
  143. package/server/services/security/encrypt/aes/index.ts +85 -0
  144. package/server/services/security/encrypt/aes/service.json +6 -0
  145. package/server/services/socket/index.ts +162 -0
  146. package/server/services/socket/scope.ts +226 -0
  147. package/server/services/socket/service.json +6 -0
  148. package/server/services_old/SocketClient.ts +92 -0
  149. package/server/services_old/Token.old.ts +97 -0
  150. package/server/utils/slug.ts +79 -0
  151. package/tsconfig.common.json +45 -0
  152. package/tsconfig.json +3 -0
  153. package/types/aliases.d.ts +54 -0
  154. package/types/global/modules.d.ts +49 -0
  155. package/types/global/utils.d.ts +103 -0
  156. package/types/icons.d.ts +1 -0
@@ -0,0 +1,550 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Node
6
+ import { serialize } from 'v8';
7
+ import { formatWithOptions } from 'util';
8
+ import md5 from 'md5';
9
+ import dayjs from 'dayjs';
10
+ import Youch from 'youch';
11
+ import forTerminal from 'youch-terminal';
12
+
13
+ // Npm
14
+ import { v4 as uuid } from 'uuid';
15
+ import { Logger, IMeta, ILogObj, ISettings } from 'tslog';
16
+ import highlight from 'cli-highlight';
17
+ import Ansi2Html from 'ansi-to-html';
18
+
19
+ // Core libs
20
+ import type ApplicationContainer from '..';
21
+ import context from '@server/context';
22
+ import type { ServerBug, TCatchedError, CoreError } from '@common/errors';
23
+ import type ServerRequest from '@server/services/router/request';
24
+
25
+ /*----------------------------------
26
+ - SERVICE CONFIG
27
+ ----------------------------------*/
28
+
29
+ export type TLogProfile = 'silly' | 'info' | 'warn' | 'error'
30
+
31
+ export type Config = {
32
+ debug?: boolean,
33
+ enable: boolean,
34
+ bufferLimit: number,
35
+ level: TLogProfile,
36
+ }
37
+
38
+ export type Hooks = {
39
+
40
+ }
41
+
42
+ export type Services = {
43
+
44
+ }
45
+
46
+ /*----------------------------------
47
+ - TYPES
48
+ ----------------------------------*/
49
+
50
+ export type ChannelInfos = {
51
+ channelType: 'cron' | 'master' | 'request' | 'socket',
52
+ channelId?: string,
53
+
54
+ method?: string,
55
+ path?: string,
56
+
57
+ user?: string
58
+ }
59
+
60
+ export type TGuestLogs = {
61
+ id: string,
62
+ meet: Date,
63
+ activity: Date,
64
+
65
+ device: string,
66
+ ip: string,
67
+ user?: string
68
+ }
69
+
70
+ export type TRequestLogs = {
71
+
72
+ id: string,
73
+ date: Date,
74
+
75
+ method: string,
76
+ url: string,
77
+ data: TObjetDonnees,
78
+
79
+ ip: string,
80
+ user?: string,
81
+ clientId: string,
82
+
83
+ statusCode: number,
84
+ time: number
85
+ }
86
+
87
+ export type TDbQueryLog = ChannelInfos & {
88
+ date: Date,
89
+ query: string,
90
+ time: number,
91
+ }
92
+
93
+ export type TLogLevel = keyof typeof logLevels
94
+
95
+ export type TJsonLog = {
96
+ time: Date,
97
+ level: TLogLevel,
98
+ args: unknown[],
99
+ channel: ChannelInfos
100
+ }
101
+
102
+ /*----------------------------------
103
+ - CONST
104
+ ----------------------------------*/
105
+
106
+ const LogPrefix = '[console]'
107
+
108
+ const logLevels = {
109
+ 'log': 0,
110
+ 'info': 3,
111
+ 'warn': 4,
112
+ 'error': 5
113
+ } as const;
114
+
115
+
116
+ var ansi2Html = new Ansi2Html({
117
+ newline: true,
118
+ // Material theme for Tilix
119
+ // https://github.com/gnunn1/tilix/blob/master/data/schemes/material.json
120
+ fg: '#fff',
121
+ bg: '#000',
122
+ colors: [
123
+ "#252525",
124
+ "#FF5252",
125
+ "#C3D82C",
126
+ "#FFC135",
127
+ "#42A5F5",
128
+ "#D81B60",
129
+ "#00ACC1",
130
+ "#F5F5F5",
131
+ "#708284",
132
+ "#FF5252",
133
+ "#C3D82C",
134
+ "#FFC135",
135
+ "#42A5F5",
136
+ "#D81B60",
137
+ "#00ACC1",
138
+ "#F5F5F5"
139
+ ]
140
+ });
141
+
142
+ /*----------------------------------
143
+ - LOGGER
144
+ ----------------------------------*/
145
+ export default class Console {
146
+
147
+ // Services
148
+ public logger!: Logger<ILogObj>;
149
+ // Buffers
150
+ public logs: TJsonLog[] = [];
151
+ private reported: {
152
+ [hash: string]: {
153
+ times: number,
154
+ last: Date,
155
+ }
156
+ } = {};
157
+
158
+ /*----------------------------------
159
+ - LIFECYCLE
160
+ ----------------------------------*/
161
+ /*
162
+ WARN: This service should depend on the less services as possible, and be usable ASAP.
163
+ So bug reports can be sent at any state of the app, includoing thre most early
164
+ */
165
+ public constructor(
166
+ private container: typeof ApplicationContainer,
167
+ private config: Config,
168
+ ) {
169
+
170
+ console.log("Setting up Console shell module.");
171
+
172
+ const origLog = console.log
173
+
174
+ const Env = container.Environment;
175
+
176
+ this.logger = new Logger({
177
+ // Use to improve performance in production
178
+ hideLogPositionForProduction: Env.profile === 'prod',
179
+ type: 'pretty',
180
+ prettyInspectOptions: {
181
+ depth: 2
182
+ },
183
+ overwrite: {
184
+ formatMeta: (meta?: IMeta) => {
185
+
186
+ // Shorten file paths
187
+ if (meta?.path !== undefined) {
188
+ meta.path.filePathWithLine = this.shortenFilePath( meta.path.filePathWithLine );
189
+ }
190
+
191
+ return this.logger["_prettyFormatLogObjMeta"]( meta );
192
+ },
193
+ transportFormatted: (
194
+ logMetaMarkup: string,
195
+ logArgs: unknown[],
196
+ logErrors: string[],
197
+ settings: ISettings<ILogObj>
198
+ ) => {
199
+ try {
200
+ const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
201
+ settings.prettyInspectOptions = settings.prettyInspectOptions || {};
202
+ settings.prettyInspectOptions.colors = settings.stylePrettyLogs;
203
+ origLog(logMetaMarkup + formatWithOptions(settings.prettyInspectOptions, ...logArgs) + logErrorsStr);
204
+ } catch (error) {
205
+ origLog("Error formatting log", error);
206
+ }
207
+ },
208
+ }
209
+ });
210
+
211
+ if (!this.config.enable || console["_wrapped"] !== undefined)
212
+ return;
213
+
214
+ this.enableLogging(origLog);
215
+ }
216
+
217
+ private enableLogging( origLog: typeof console.log ) {
218
+
219
+ const minLogLevel = logLevels[this.config.level];
220
+
221
+ let logLevel: TLogLevel;
222
+ for (logLevel in logLevels) {
223
+ const levelNumber = logLevels[logLevel];
224
+ console[logLevel] = (...args: any[]) => {
225
+
226
+ // Dev mode = no care about performance = rich logging
227
+ if (levelNumber >= minLogLevel)
228
+ //this.logger[ logLevel ](...args);
229
+ origLog(...args);
230
+ // Prod mode = minimal logging
231
+
232
+ const channel = this.getChannel();
233
+
234
+ this.logs.push({
235
+ time: new Date,
236
+ level: logLevel,
237
+ args,
238
+ channel
239
+ });
240
+ }
241
+ }
242
+
243
+ console["_wrapped"] = true;
244
+
245
+ setInterval(() => this.clean(), 10000);
246
+ }
247
+
248
+ /*----------------------------------
249
+ - LOGS FORMATTING
250
+ ----------------------------------*/
251
+
252
+ public shortenFilePath( filepath?: string ) {
253
+
254
+ if (filepath === undefined)
255
+ return undefined;
256
+
257
+ const projectRoot = this.container.path.root;
258
+ if (filepath.startsWith( projectRoot ))
259
+ filepath = filepath.substring( projectRoot.length )
260
+
261
+ const frameworkRoot = '/node_modules/proteum/';
262
+ if (filepath.startsWith( frameworkRoot ))
263
+ filepath = '@' + filepath.substring( frameworkRoot.length )
264
+
265
+ return filepath;
266
+
267
+ }
268
+
269
+
270
+ /*----------------------------------
271
+ - ACTIONS
272
+ ----------------------------------*/
273
+
274
+ public getLogLevelId( logLevelName: TLogLevel ) {
275
+ return logLevels[ logLevelName ]
276
+ }
277
+
278
+ private clean() {
279
+
280
+ if (this.config.debug) {
281
+ console.log(
282
+ LogPrefix,
283
+ `Clean logs buffer. Current size:`,
284
+ this.logs.length, '/', this.config.bufferLimit,
285
+ 'Memory Size:', serialize(this.logs).byteLength
286
+ );
287
+ }
288
+
289
+ const bufferOverflow = this.logs.length - this.config.bufferLimit;
290
+ if (bufferOverflow > 0)
291
+ this.logs = this.logs.slice(bufferOverflow);
292
+ }
293
+
294
+ // We don't prevent duplicates because we want to receive all variants of the same error
295
+ public async createBugReport( error: TCatchedError, request?: ServerRequest ) {
296
+
297
+ const application = this.container.application;
298
+ if (application === undefined)
299
+ return console.error(LogPrefix, "Can't send bug report because the application is not instanciated");
300
+
301
+ // Get context
302
+ const now = new Date();
303
+ const { channelType, channelId } = this.getChannel();
304
+
305
+ // On envoi l'email avant l'insertion dans bla bdd
306
+ // Car cette denrière a plus de chances de provoquer une erreur
307
+ //const logs = this.logs.filter(e => e.channel.channelId === channelId).slice(-100);
308
+ const inspection = this.getDetailledError(error);
309
+
310
+ // Genertae unique error hash
311
+ const hash = md5( inspection.stacktraces[0] );
312
+
313
+ // Don't send the same error twice in a row (avoid email spamming)
314
+ const lastReport = this.reported[hash];
315
+ let isDuplicate = false;
316
+ if (lastReport === undefined) {
317
+
318
+ this.reported[hash] = {
319
+ times: 0,
320
+ last: new Date()
321
+ }
322
+
323
+ // If error older than 1 day
324
+ } else if (dayjs(now).diff( dayjs(lastReport.last), 'day' ) > 1) {
325
+
326
+ lastReport.times++;
327
+ lastReport.last = now;
328
+
329
+ } else {
330
+
331
+ isDuplicate = true;
332
+ }
333
+
334
+ const bugReport: ServerBug = {
335
+
336
+ // Context
337
+ hash: hash,
338
+ isDuplicate,
339
+ date: now,
340
+ channelType,
341
+ channelId,
342
+
343
+ ...(request ? {
344
+
345
+ // User
346
+ user: request.user,
347
+ ip: request.ip,
348
+
349
+ // Request
350
+ request: {
351
+ method: request.method,
352
+ url: request.url,
353
+ data: request.data,
354
+ validatedData: request.validatedData,
355
+ headers: request.headers,
356
+ cookies: request.cookies,
357
+ }
358
+
359
+ } : {}),
360
+
361
+ // Error
362
+ title: inspection.title,
363
+ stacktraces: inspection.stacktraces,
364
+ context: inspection.context
365
+ }
366
+
367
+ await application.runHook('bug', bugReport);
368
+
369
+ return bugReport;
370
+ }
371
+
372
+ public getDetailledError( error: TCatchedError ) {
373
+
374
+ const stacktraces: string[] = [];
375
+ const context: object[] = [];
376
+
377
+ let currentError: TCatchedError | undefined = error;
378
+ let title: string | undefined;
379
+ while (currentError !== undefined) {
380
+
381
+ if (title === undefined)
382
+ title = currentError.message;
383
+
384
+ // Stacktrace
385
+ this.logger.error(LogPrefix, `Sending bug report for the following error:`, currentError);
386
+ stacktraces.push(currentError.stack || currentError.message);
387
+
388
+ // Context
389
+ if (('dataForDebugging' in currentError) && currentError.dataForDebugging !== undefined) {
390
+ console.error(LogPrefix, `More data about the error:`, currentError.dataForDebugging);
391
+ context.push(currentError.dataForDebugging || {});
392
+ }
393
+
394
+ // Go deeper
395
+ currentError = 'originalError' in currentError
396
+ ? currentError.originalError
397
+ : undefined
398
+ }
399
+
400
+ return { title, stacktraces, context };
401
+ }
402
+
403
+ public getChannel() {
404
+ return context.getStore() || {
405
+ channelType: 'master',
406
+ channelId: undefined
407
+ }
408
+ }
409
+
410
+ /*----------------------------------
411
+ - PRINT
412
+ ----------------------------------*/
413
+
414
+ public bugToHtml( report: ServerBug ) {
415
+
416
+ return `
417
+ <b>Channel</b>: ${report.channelType} (${report.channelId})<br />
418
+ <b>User</b>: ${report.user ? (report.user.name + ' (' + report.user.email + ')') : 'Unknown'}<br />
419
+ <b>IP</b>: ${report.ip}<br />
420
+
421
+ ${this.stacktracesToHTML(report.stacktraces)}
422
+
423
+ ${report.context.map((context, index) => `
424
+ <hr />
425
+ <b>Context ${index + 1}</b>: ${this.jsonToHTML(context)}<br />
426
+ `).join('')}
427
+
428
+ ${report.request ? `
429
+ <hr />
430
+ <b>Request</b>: ${report.request.method} ${report.request.url}<br />
431
+ <b>Headers</b>: ${this.jsonToHTML(report.request.headers)}<br />
432
+ <b>Cookies</b>: ${this.jsonToHTML(report.request.cookies)}<br />
433
+ <b>Raw Data</b>: ${this.jsonToHTML(report.request.data)}<br />
434
+ <b>Validated Data</b>: ${this.jsonToHTML(report.request.validatedData)}
435
+ ` : ''}
436
+ <hr/>
437
+ Logs: ${this.config.enable ? `<br/>` + this.logsToHTML(report.logs) : 'Logs collection is disabled'}<br />
438
+ `
439
+ }
440
+
441
+ public stacktracesToHTML( stacktraces: string[] ): string {
442
+ return stacktraces.map((stacktrace, index) => `
443
+ <hr />
444
+ <b>Stacktrace ${index + 1}</b>: ${this.printHtml(stacktrace)}<br />
445
+ `).join('');
446
+ }
447
+
448
+ public logsToHTML( logs: TJsonLog[] ): string {
449
+
450
+ let ansi = logs.map( logEntry => this.logToAnsi( logEntry )).join('<br />');
451
+
452
+ // Convert ANSI to HTML
453
+ const html = ansi2Html.toHtml(ansi)
454
+
455
+ return this.printHtml( html );
456
+ }
457
+
458
+ private logToAnsi( log: TJsonLog ) {
459
+
460
+ // Print metas as ANSI
461
+ const logMetaMarkup = this.logger["_prettyFormatLogObjMeta"]({
462
+ date: log.time,
463
+ logLevelId: this.getLogLevelId(log.level),
464
+ logLevelName: log.level,
465
+ // We consider that having the path is useless in this case
466
+ path: undefined,
467
+ });
468
+
469
+ // Print args as ANSI
470
+ const logArgsAndErrorsMarkup = this.logger["runtime"].prettyFormatLogObj(log.args, this.logger.settings);
471
+ const logErrors = logArgsAndErrorsMarkup.errors;
472
+ const logArgs = logArgsAndErrorsMarkup.args;
473
+ const logErrorsStr = (logErrors.length > 0 && logArgs.length > 0 ? "\n" : "") + logErrors.join("\n");
474
+ this.logger.settings.prettyInspectOptions.colors = this.logger.settings.stylePrettyLogs;
475
+ let ansi = logMetaMarkup + formatWithOptions(this.logger.settings.prettyInspectOptions, ...logArgs) + logErrorsStr;
476
+
477
+ return ansi;
478
+ }
479
+
480
+ public jsonToHTML( json: unknown ): string {
481
+
482
+ if (!json)
483
+ return 'No data';
484
+
485
+ const coloredJson = highlight(
486
+ JSON.stringify(json, null, 4),
487
+ { language: 'json', ignoreIllegals: true }
488
+ );
489
+
490
+ const html = ansi2Html.toHtml(coloredJson)
491
+
492
+ return this.printHtml( html );
493
+ }
494
+
495
+ public printHtml( html: string ): string {
496
+
497
+ if (!html)
498
+ return 'No data';
499
+
500
+ // Preserve spaces
501
+ html = html
502
+ .replace(/\t/g, '&nbsp;&nbsp;&nbsp;&nbsp;')
503
+ .replace(/ /g, '&nbsp;')
504
+ .replace(/\n/g, '<br />');
505
+
506
+ // Create console wrapper
507
+ const consoleCss = `background: #000; padding: 20px; font-family: 'Fira Mono', 'monospace', 'Monaco'; font-size: 12px; line-height: 20px;color: #aaa;`
508
+ html = '<div style="' + consoleCss + '">' + html + '</div>';
509
+
510
+ return html;
511
+ }
512
+
513
+ public printSql = (requete: string) => highlight(
514
+ requete,//formatSql(requete, { indent: ' '.repeat(4) }),
515
+ { language: 'sql', ignoreIllegals: true }
516
+ )
517
+
518
+ /*public async getLogs( channelType: ChannelInfos["channelType"], channelId?: string ) {
519
+
520
+ const filters: Partial<TDbQueryLog> = { channelType };
521
+ if (channelId !== undefined)
522
+ filters.channelId = channelId;
523
+
524
+ const entries: TLog[] = []
525
+ for (const log of this.logs) {
526
+
527
+ // Filters
528
+ if (!(log.channelId === channelId && log.channelType === channelType))
529
+ continue;
530
+
531
+ // Remove path prefixs
532
+ if (log.filePath !== undefined) {
533
+
534
+ const appPrefix = '/webpack:/' + this.app.pkg.name + '/';
535
+ const appPrefixIndex = log.filePath.indexOf(appPrefix);
536
+
537
+ const corePrefix = '/webpack:/' + this.app.pkg.name + '/node_modules/proteum/';
538
+ const corePrefixIndex = log.filePath.indexOf(corePrefix);
539
+
540
+ if (appPrefixIndex !== -1)
541
+ log.filePath = '@/' + log.filePath.substring(appPrefixIndex + appPrefix.length);
542
+ else if (corePrefixIndex !== -1)
543
+ log.filePath = '@' + log.filePath.substring(corePrefixIndex + corePrefix.length);
544
+ }
545
+ }
546
+
547
+ return this.printHtml( entries );
548
+ }*/
549
+
550
+ }
@@ -0,0 +1,137 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Set timezone
6
+ process.env.TZ = 'UTC';
7
+ import 'source-map-support/register';
8
+
9
+ // Npm
10
+ import path from 'path';
11
+
12
+ // Core
13
+ import type Application from '..';
14
+ import type { StartedServicesIndex } from '../service';
15
+ import Services, { ServicesContainer } from '../service/container';
16
+ import ConfigParser, { TEnvConfig } from './config';
17
+ import Console from './console';
18
+ import type ServerRequest from '@server/services/router/request';
19
+
20
+ /*----------------------------------
21
+ - CLASS
22
+ ----------------------------------*/
23
+ export class ApplicationContainer<
24
+ TServicesIndex extends StartedServicesIndex = StartedServicesIndex
25
+ > {
26
+
27
+ /*----------------------------------
28
+ - INIT
29
+ ----------------------------------*/
30
+
31
+ public Services = Services as ServicesContainer<TServicesIndex>;
32
+ public Environment: TEnvConfig;
33
+ public Identity: Config.Identity;
34
+ public Console: Console;
35
+
36
+ public application?: Application;
37
+
38
+ public constructor() {
39
+
40
+ // Load config files
41
+ const configParser = new ConfigParser( this.path.root );
42
+ this.Environment = configParser.env();
43
+ this.Identity = configParser.identity();
44
+ this.Console = new Console(this, this.Environment.console);
45
+ }
46
+
47
+ // Context
48
+ public hmr: __WebpackModuleApi.Hot | undefined = module.hot;
49
+
50
+ public path = {
51
+ root: process.cwd(),
52
+ public: path.join( process.cwd(), '/public'),
53
+ var: path.join( process.cwd(), '/var'),
54
+
55
+ client: {
56
+ generated: path.join( process.cwd(), 'src', 'client', '.generated')
57
+ },
58
+ server: {
59
+ generated: path.join( process.cwd(), 'src', 'server', '.generated')
60
+ },
61
+ }
62
+
63
+ public start( ApplicationClass: typeof Application ): Application {
64
+
65
+ // Instanciate Application
66
+ try {
67
+ this.application = new ApplicationClass;
68
+ } catch (error) {
69
+ this.handleBug(error, "Failed to instanciate the Application Class");
70
+ process.exit(1);
71
+ }
72
+
73
+ // Start application
74
+ try {
75
+ this.application.start();
76
+ } catch (error) {
77
+ this.handleBug(error, "Failed to start the Application");
78
+ process.exit(1);
79
+ }
80
+
81
+ return this.application;
82
+ }
83
+
84
+ public async handleBug( rejection: Error, message: string, request?: ServerRequest ) {
85
+ if (this.Console) {
86
+ try {
87
+
88
+ this.Console.createBugReport(rejection, request);
89
+
90
+ } catch (consoleError) {
91
+ console.error(
92
+ message, rejection,
93
+ "Failed to transmiss the previous error to console:", consoleError
94
+ );
95
+ process.exit(1);
96
+ }
97
+ } else {
98
+ console.error(message, rejection);
99
+ process.exit(1);
100
+ }
101
+ }
102
+
103
+
104
+ /*----------------------------------
105
+ - HMR
106
+ - TODO: move in dev server
107
+ ----------------------------------*/
108
+ private activateHMR() {
109
+
110
+ if (!module.hot) return;
111
+
112
+ console.info(`Activating HMR ...`);
113
+
114
+ module.hot.accept();
115
+ module.hot.accept( this.path.root + '/.cache/commun/routes.ts' );
116
+
117
+ module.hot.addDisposeHandler((data) => {
118
+
119
+ console.info(`Cleaning application ...`);
120
+
121
+ // Services hooks
122
+ //this.app.shutdown();
123
+
124
+ /*
125
+ console.log("[nettoyage] Arrêt serveur socket ...");
126
+ if (socket !== undefined)
127
+ socket.serveur.close()
128
+
129
+ console.log("[nettoyage] Reset du cache requêtes JSQL ...");
130
+ QueryParser.clearCache();*/
131
+
132
+ });
133
+ }
134
+
135
+ }
136
+
137
+ export default new ApplicationContainer;