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.
- package/.dockerignore +10 -0
- package/Rte.zip +0 -0
- package/cli/app/config.ts +54 -0
- package/cli/app/index.ts +195 -0
- package/cli/bin.js +11 -0
- package/cli/commands/build.ts +34 -0
- package/cli/commands/deploy/app.ts +29 -0
- package/cli/commands/deploy/web.ts +60 -0
- package/cli/commands/dev.ts +109 -0
- package/cli/commands/init.ts +85 -0
- package/cli/compiler/client/identite.ts +72 -0
- package/cli/compiler/client/index.ts +334 -0
- package/cli/compiler/common/babel/index.ts +170 -0
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +579 -0
- package/cli/compiler/common/babel/routes/imports.ts +127 -0
- package/cli/compiler/common/babel/routes/routes.ts +1130 -0
- package/cli/compiler/common/files/autres.ts +39 -0
- package/cli/compiler/common/files/images.ts +35 -0
- package/cli/compiler/common/files/style.ts +78 -0
- package/cli/compiler/common/index.ts +154 -0
- package/cli/compiler/index.ts +532 -0
- package/cli/compiler/server/index.ts +211 -0
- package/cli/index.ts +189 -0
- package/cli/paths.ts +165 -0
- package/cli/print.ts +12 -0
- package/cli/tsconfig.json +38 -0
- package/cli/utils/index.ts +22 -0
- package/cli/utils/keyboard.ts +78 -0
- package/client/app/component.tsx +54 -0
- package/client/app/index.ts +142 -0
- package/client/app/service.ts +34 -0
- package/client/app.tsconfig.json +28 -0
- package/client/components/Button.tsx +298 -0
- package/client/components/Dialog/Manager.tsx +309 -0
- package/client/components/Dialog/card.tsx +208 -0
- package/client/components/Dialog/index.less +151 -0
- package/client/components/Dialog/status.less +176 -0
- package/client/components/Dialog/status.tsx +48 -0
- package/client/components/index.ts +2 -0
- package/client/components/types.d.ts +3 -0
- package/client/data/input.ts +32 -0
- package/client/global.d.ts +5 -0
- package/client/hooks.ts +22 -0
- package/client/index.ts +6 -0
- package/client/pages/_layout/index.less +6 -0
- package/client/pages/_layout/index.tsx +43 -0
- package/client/pages/bug.tsx.old +60 -0
- package/client/pages/useHeader.tsx +50 -0
- package/client/services/captcha/index.ts +67 -0
- package/client/services/router/components/Link.tsx +46 -0
- package/client/services/router/components/Page.tsx +55 -0
- package/client/services/router/components/router.tsx +218 -0
- package/client/services/router/index.tsx +521 -0
- package/client/services/router/request/api.ts +267 -0
- package/client/services/router/request/history.ts +5 -0
- package/client/services/router/request/index.ts +53 -0
- package/client/services/router/request/multipart.ts +147 -0
- package/client/services/router/response/index.tsx +128 -0
- package/client/services/router/response/page.ts +86 -0
- package/client/services/socket/index.ts +147 -0
- package/client/utils/dom.ts +77 -0
- package/common/app/index.ts +9 -0
- package/common/data/chaines/index.ts +54 -0
- package/common/data/dates.ts +179 -0
- package/common/data/markdown.ts +73 -0
- package/common/data/rte/nodes.ts +83 -0
- package/common/data/stats.ts +90 -0
- package/common/errors/index.tsx +326 -0
- package/common/router/index.ts +213 -0
- package/common/router/layouts.ts +93 -0
- package/common/router/register.ts +55 -0
- package/common/router/request/api.ts +77 -0
- package/common/router/request/index.ts +35 -0
- package/common/router/response/index.ts +45 -0
- package/common/router/response/page.ts +128 -0
- package/common/utils/rte.ts +183 -0
- package/common/utils.ts +7 -0
- package/doc/TODO.md +71 -0
- package/doc/front/router.md +27 -0
- package/doc/workspace/workspace.png +0 -0
- package/doc/workspace/workspace2.png +0 -0
- package/doc/workspace/workspace_26.01.22.png +0 -0
- package/package.json +171 -0
- package/server/app/commands.ts +141 -0
- package/server/app/container/config.ts +203 -0
- package/server/app/container/console/index.ts +550 -0
- package/server/app/container/index.ts +137 -0
- package/server/app/index.ts +273 -0
- package/server/app/service/container.ts +88 -0
- package/server/app/service/index.ts +235 -0
- package/server/app.tsconfig.json +28 -0
- package/server/context.ts +4 -0
- package/server/index.ts +4 -0
- package/server/services/auth/index.ts +250 -0
- package/server/services/auth/old.ts +277 -0
- package/server/services/auth/router/index.ts +95 -0
- package/server/services/auth/router/request.ts +54 -0
- package/server/services/auth/router/service.json +6 -0
- package/server/services/auth/service.json +6 -0
- package/server/services/cache/commands.ts +41 -0
- package/server/services/cache/index.ts +297 -0
- package/server/services/cache/service.json +6 -0
- package/server/services/cron/CronTask.ts +86 -0
- package/server/services/cron/index.ts +112 -0
- package/server/services/cron/service.json +6 -0
- package/server/services/disks/driver.ts +103 -0
- package/server/services/disks/drivers/local/index.ts +188 -0
- package/server/services/disks/drivers/local/service.json +6 -0
- package/server/services/disks/drivers/s3/index.ts +301 -0
- package/server/services/disks/drivers/s3/service.json +6 -0
- package/server/services/disks/index.ts +90 -0
- package/server/services/disks/service.json +6 -0
- package/server/services/email/index.ts +188 -0
- package/server/services/email/utils.ts +53 -0
- package/server/services/fetch/index.ts +201 -0
- package/server/services/fetch/service.json +7 -0
- package/server/services/models.7z +0 -0
- package/server/services/prisma/Facet.ts +142 -0
- package/server/services/prisma/index.ts +201 -0
- package/server/services/prisma/service.json +6 -0
- package/server/services/router/http/index.ts +217 -0
- package/server/services/router/http/multipart.ts +102 -0
- package/server/services/router/http/session.ts.old +40 -0
- package/server/services/router/index.ts +801 -0
- package/server/services/router/request/api.ts +87 -0
- package/server/services/router/request/index.ts +184 -0
- package/server/services/router/request/service.ts +21 -0
- package/server/services/router/request/validation/zod.ts +180 -0
- package/server/services/router/response/index.ts +338 -0
- package/server/services/router/response/mask/Filter.ts +323 -0
- package/server/services/router/response/mask/index.ts +60 -0
- package/server/services/router/response/mask/selecteurs.ts +92 -0
- package/server/services/router/response/page/document.tsx +160 -0
- package/server/services/router/response/page/index.tsx +196 -0
- package/server/services/router/service.json +6 -0
- package/server/services/router/service.ts +36 -0
- package/server/services/schema/index.ts +44 -0
- package/server/services/schema/request.ts +49 -0
- package/server/services/schema/router/index.ts +28 -0
- package/server/services/schema/router/service.json +6 -0
- package/server/services/schema/service.json +6 -0
- package/server/services/security/encrypt/aes/index.ts +85 -0
- package/server/services/security/encrypt/aes/service.json +6 -0
- package/server/services/socket/index.ts +162 -0
- package/server/services/socket/scope.ts +226 -0
- package/server/services/socket/service.json +6 -0
- package/server/services_old/SocketClient.ts +92 -0
- package/server/services_old/Token.old.ts +97 -0
- package/server/utils/slug.ts +79 -0
- package/tsconfig.common.json +45 -0
- package/tsconfig.json +3 -0
- package/types/aliases.d.ts +54 -0
- package/types/global/modules.d.ts +49 -0
- package/types/global/utils.d.ts +103 -0
- 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, ' ')
|
|
503
|
+
.replace(/ /g, ' ')
|
|
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;
|