5htp-core 0.3.7-3 → 0.3.8
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/package.json +4 -2
- package/src/common/router/index.ts +1 -1
- package/src/common/validation/validators.ts +2 -3
- package/src/server/{services → app/container}/console/index.ts +44 -10
- package/src/server/app/container/index.ts +54 -0
- package/src/server/app/index.ts +3 -25
- package/src/server/app/service/index.ts +7 -8
- package/src/server/context.ts +1 -1
- package/src/server/index.ts +2 -10
- package/src/server/services/{users → auth}/index.ts +1 -1
- package/src/server/services/database/index.ts +12 -2
- package/src/server/services/fetch/index.ts +4 -3
- package/src/server/services/socket/index.ts +1 -1
- package/src/server/services/console/service.json +0 -6
- /package/src/server/{services → app/container}/console/html.ts +0 -0
- /package/src/server/services/{users → auth}/old.ts +0 -0
- /package/src/server/services/{users → auth}/router/index.ts +0 -0
- /package/src/server/services/{users → auth}/router/request.ts +0 -0
- /package/src/server/services/{users → auth}/router/service.json +0 -0
- /package/src/server/services/{users → auth}/service.json +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "5htp-core",
|
|
3
3
|
"description": "Convenient TypeScript framework designed for Performance and Productivity.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.8",
|
|
5
5
|
"author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
|
|
6
6
|
"repository": "git://github.com/gaetanlegac/5htp-core.git",
|
|
7
7
|
"license": "MIT",
|
|
@@ -80,7 +80,9 @@
|
|
|
80
80
|
"validator": "^13.7.0",
|
|
81
81
|
"ws": "^8.2.2",
|
|
82
82
|
"yaml": "^1.10.2",
|
|
83
|
-
"yargs-parser": "^21.1.1"
|
|
83
|
+
"yargs-parser": "^21.1.1",
|
|
84
|
+
"youch": "^3.3.3",
|
|
85
|
+
"youch-terminal": "^2.2.3"
|
|
84
86
|
},
|
|
85
87
|
"devDependencies": {
|
|
86
88
|
"@types/cookie": "^0.4.1",
|
|
@@ -145,10 +145,9 @@ export default class SchemaValidators {
|
|
|
145
145
|
/*----------------------------------
|
|
146
146
|
- CHAINES
|
|
147
147
|
----------------------------------*/
|
|
148
|
-
public string = ({ min, max,
|
|
148
|
+
public string = ({ min, max, ...opts }: TValidator<string> & {
|
|
149
149
|
min?: number,
|
|
150
|
-
max?: number
|
|
151
|
-
include?: string
|
|
150
|
+
max?: number
|
|
152
151
|
} = {}) => new Validator<string>('string', (val, input, output, corriger?: boolean) => {
|
|
153
152
|
|
|
154
153
|
// Check type
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
// Node
|
|
6
6
|
import { serialize } from 'v8';
|
|
7
7
|
import { formatWithOptions } from 'util';
|
|
8
|
+
import Youch from 'youch';
|
|
9
|
+
import forTerminal from 'youch-terminal';
|
|
8
10
|
|
|
9
11
|
// Npm
|
|
10
12
|
import { v4 as uuid } from 'uuid';
|
|
@@ -13,8 +15,7 @@ import { format as formatSql } from 'sql-formatter';
|
|
|
13
15
|
import highlight from 'cli-highlight';
|
|
14
16
|
|
|
15
17
|
// Core libs
|
|
16
|
-
import type
|
|
17
|
-
import Service from '@server/app/service';
|
|
18
|
+
import type ApplicationContainer from '..';
|
|
18
19
|
import context from '@server/context';
|
|
19
20
|
import type { ServerBug } from '@common/errors';
|
|
20
21
|
import type ServerRequest from '@server/services/router/request';
|
|
@@ -117,7 +118,7 @@ const logLevels = {
|
|
|
117
118
|
/*----------------------------------
|
|
118
119
|
- LOGGER
|
|
119
120
|
----------------------------------*/
|
|
120
|
-
export default class Console
|
|
121
|
+
export default class Console {
|
|
121
122
|
|
|
122
123
|
// Services
|
|
123
124
|
public logger!: Logger<ILogObj>;
|
|
@@ -138,18 +139,23 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
138
139
|
WARN: This service should depend on the less services as possible, and be usable ASAP.
|
|
139
140
|
So bug reports can be sent at any state of the app, includoing thre most early
|
|
140
141
|
*/
|
|
141
|
-
public constructor(
|
|
142
|
+
public constructor(
|
|
143
|
+
private container: typeof ApplicationContainer,
|
|
144
|
+
private config: Config,
|
|
145
|
+
) {
|
|
142
146
|
|
|
143
|
-
|
|
147
|
+
console.log("Setting up Console shell module.");
|
|
144
148
|
|
|
145
149
|
const origLog = console.log
|
|
146
150
|
|
|
147
|
-
const
|
|
151
|
+
const Env = container.Environment;
|
|
152
|
+
|
|
153
|
+
const envConfig = this.config[ Env.profile === 'prod' ? 'prod' : 'dev' ];
|
|
148
154
|
const minLogLevel = logLevels[ envConfig.level ];
|
|
149
155
|
|
|
150
156
|
this.logger = new Logger({
|
|
151
157
|
// Use to improve performance in production
|
|
152
|
-
hideLogPositionForProduction:
|
|
158
|
+
hideLogPositionForProduction: Env.profile === 'prod',
|
|
153
159
|
type: 'pretty',
|
|
154
160
|
prettyInspectOptions: {
|
|
155
161
|
depth: 2
|
|
@@ -220,7 +226,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
220
226
|
if (filepath === undefined)
|
|
221
227
|
return undefined;
|
|
222
228
|
|
|
223
|
-
const projectRoot = this.
|
|
229
|
+
const projectRoot = this.container.path.root;
|
|
224
230
|
if (filepath.startsWith( projectRoot ))
|
|
225
231
|
filepath = filepath.substring( projectRoot.length )
|
|
226
232
|
|
|
@@ -259,6 +265,34 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
259
265
|
|
|
260
266
|
public async createBugReport( error: Error, request?: ServerRequest ) {
|
|
261
267
|
|
|
268
|
+
// Print error
|
|
269
|
+
this.logger.error(LogPrefix, `Sending bug report for the following error:`, error);
|
|
270
|
+
/*const youchRes = new Youch(error, {});
|
|
271
|
+
const jsonResponse = await youchRes.toJSON()
|
|
272
|
+
console.log( forTerminal(jsonResponse, {
|
|
273
|
+
// Defaults to false
|
|
274
|
+
displayShortPath: false,
|
|
275
|
+
|
|
276
|
+
// Defaults to single whitspace
|
|
277
|
+
prefix: ' ',
|
|
278
|
+
|
|
279
|
+
// Defaults to false
|
|
280
|
+
hideErrorTitle: false,
|
|
281
|
+
|
|
282
|
+
// Defaults to false
|
|
283
|
+
hideMessage: false,
|
|
284
|
+
|
|
285
|
+
// Defaults to false
|
|
286
|
+
displayMainFrameOnly: false,
|
|
287
|
+
|
|
288
|
+
// Defaults to 3
|
|
289
|
+
framesMaxLimit: 3,
|
|
290
|
+
}) );*/
|
|
291
|
+
|
|
292
|
+
const application = this.container.application;
|
|
293
|
+
if (application === undefined)
|
|
294
|
+
return console.error(LogPrefix, "Can't send bug report because the application is not instanciated");
|
|
295
|
+
|
|
262
296
|
// Print the error so it's accessible via logs
|
|
263
297
|
if (error instanceof SqlError) {
|
|
264
298
|
let printedQuery: string;
|
|
@@ -269,7 +303,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
269
303
|
}
|
|
270
304
|
console.error(`Error caused by this query:`, printedQuery);
|
|
271
305
|
}
|
|
272
|
-
|
|
306
|
+
|
|
273
307
|
if (error.dataForDebugging !== undefined)
|
|
274
308
|
console.error(LogPrefix, `More data about the error:`, error.dataForDebugging);
|
|
275
309
|
|
|
@@ -308,7 +342,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
308
342
|
logs: logsHtml
|
|
309
343
|
}
|
|
310
344
|
|
|
311
|
-
await
|
|
345
|
+
await application.reportBug( bugReport );
|
|
312
346
|
}
|
|
313
347
|
|
|
314
348
|
public getChannel() {
|
|
@@ -8,9 +8,11 @@ import './patch';
|
|
|
8
8
|
import path from 'path';
|
|
9
9
|
|
|
10
10
|
// Core
|
|
11
|
+
import type Application from '..';
|
|
11
12
|
import type { StartedServicesIndex } from '../service';
|
|
12
13
|
import Services, { ServicesContainer } from '../service/container';
|
|
13
14
|
import ConfigParser, { TEnvConfig } from './config';
|
|
15
|
+
import Console from './console';
|
|
14
16
|
|
|
15
17
|
/*----------------------------------
|
|
16
18
|
- CLASS
|
|
@@ -26,6 +28,9 @@ export class ApplicationContainer<
|
|
|
26
28
|
public Services = Services as ServicesContainer<TServicesIndex>;
|
|
27
29
|
public Environment: TEnvConfig;
|
|
28
30
|
public Identity: Config.Identity;
|
|
31
|
+
public Console: Console;
|
|
32
|
+
|
|
33
|
+
public application?: Application;
|
|
29
34
|
|
|
30
35
|
public constructor() {
|
|
31
36
|
|
|
@@ -33,6 +38,16 @@ export class ApplicationContainer<
|
|
|
33
38
|
const configParser = new ConfigParser( this.path.root );
|
|
34
39
|
this.Environment = configParser.env();
|
|
35
40
|
this.Identity = configParser.identity();
|
|
41
|
+
this.Console = new Console(this, {
|
|
42
|
+
debug: false,
|
|
43
|
+
bufferLimit: 10000,
|
|
44
|
+
dev: {
|
|
45
|
+
level: 'log'
|
|
46
|
+
},
|
|
47
|
+
prod: {
|
|
48
|
+
level: 'log'
|
|
49
|
+
}
|
|
50
|
+
});
|
|
36
51
|
}
|
|
37
52
|
|
|
38
53
|
// Context
|
|
@@ -51,6 +66,45 @@ export class ApplicationContainer<
|
|
|
51
66
|
},
|
|
52
67
|
}
|
|
53
68
|
|
|
69
|
+
public start( ApplicationClass: typeof Application ) {
|
|
70
|
+
|
|
71
|
+
// Instanciate Application
|
|
72
|
+
try {
|
|
73
|
+
this.application = new ApplicationClass;
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.handleBug(error, "Failed to instanciate the Application Class");
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Start application
|
|
80
|
+
try {
|
|
81
|
+
this.application.start();
|
|
82
|
+
} catch (error) {
|
|
83
|
+
this.handleBug(error, "Failed to start the Application");
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
public async handleBug( rejection: Error, message: string ) {
|
|
89
|
+
if (this.Console) {
|
|
90
|
+
try {
|
|
91
|
+
|
|
92
|
+
this.Console.createBugReport(rejection);
|
|
93
|
+
|
|
94
|
+
} catch (consoleError) {
|
|
95
|
+
console.error(
|
|
96
|
+
message, rejection,
|
|
97
|
+
"Failed to transmiss the previous error to console:", consoleError
|
|
98
|
+
);
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
} else {
|
|
102
|
+
console.error(message, rejection);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
54
108
|
/*----------------------------------
|
|
55
109
|
- HMR
|
|
56
110
|
- TODO: move in dev server
|
package/src/server/app/index.ts
CHANGED
|
@@ -11,7 +11,7 @@ import ServicesContainer, {
|
|
|
11
11
|
TRegisteredService,
|
|
12
12
|
TServiceMetas
|
|
13
13
|
} from './service/container';
|
|
14
|
-
import type { ServerBug } from '
|
|
14
|
+
import type { ServerBug } from './container/console';
|
|
15
15
|
|
|
16
16
|
// Built-in
|
|
17
17
|
import type { default as Router, Request as ServerRequest } from '@server/services/router';
|
|
@@ -82,9 +82,6 @@ export class Application<
|
|
|
82
82
|
public debug: boolean = false;
|
|
83
83
|
public launched: boolean = false;
|
|
84
84
|
|
|
85
|
-
// Mandatory services
|
|
86
|
-
public Console = this.use('Core/Console');
|
|
87
|
-
|
|
88
85
|
/*----------------------------------
|
|
89
86
|
- INIT
|
|
90
87
|
----------------------------------*/
|
|
@@ -98,7 +95,7 @@ export class Application<
|
|
|
98
95
|
super(self, {}, {}, self);
|
|
99
96
|
|
|
100
97
|
// Handle unhandled crash
|
|
101
|
-
this.on('error', e => this.
|
|
98
|
+
this.on('error', e => this.container.handleBug(e, "An error occured in the application"));
|
|
102
99
|
|
|
103
100
|
process.on('unhandledRejection', (error: any, promise: any) => {
|
|
104
101
|
console.log("unhandledRejection");
|
|
@@ -126,7 +123,7 @@ export class Application<
|
|
|
126
123
|
- LAUNCH
|
|
127
124
|
----------------------------------*/
|
|
128
125
|
|
|
129
|
-
|
|
126
|
+
public async start() {
|
|
130
127
|
|
|
131
128
|
console.log("Build date", BUILD_DATE);
|
|
132
129
|
console.log("Core version", CORE_VERSION);
|
|
@@ -204,25 +201,6 @@ export class Application<
|
|
|
204
201
|
/*----------------------------------
|
|
205
202
|
- ERROR HANDLING
|
|
206
203
|
----------------------------------*/
|
|
207
|
-
private async unhandledRejection(rejection: Error) {
|
|
208
|
-
if (this.Console) {
|
|
209
|
-
try {
|
|
210
|
-
|
|
211
|
-
this.Console.createBugReport(rejection);
|
|
212
|
-
|
|
213
|
-
} catch (consoleError) {
|
|
214
|
-
console.error(
|
|
215
|
-
"Unhandled rejection", rejection,
|
|
216
|
-
"Failed to transmiss the previous error to console:", consoleError
|
|
217
|
-
);
|
|
218
|
-
process.exit(1);
|
|
219
|
-
}
|
|
220
|
-
} else {
|
|
221
|
-
console.error("Unhandled rejection", rejection);
|
|
222
|
-
process.exit(1);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
|
|
226
204
|
// Default error handler
|
|
227
205
|
public async reportBug( bug: ServerBug ) {
|
|
228
206
|
|
|
@@ -174,8 +174,7 @@ export default abstract class Service<
|
|
|
174
174
|
if (serviceUseOptions.optional)
|
|
175
175
|
return undefined;
|
|
176
176
|
else {
|
|
177
|
-
|
|
178
|
-
process.exit(1);
|
|
177
|
+
throw new Error(`Unable to use service "${serviceId}": This one hasn't been setup.`);
|
|
179
178
|
}
|
|
180
179
|
}
|
|
181
180
|
|
|
@@ -200,8 +199,8 @@ export default abstract class Service<
|
|
|
200
199
|
try {
|
|
201
200
|
ServiceClass = registered.metas.class().default;
|
|
202
201
|
} catch (error) {
|
|
203
|
-
console.error("Failed to
|
|
204
|
-
|
|
202
|
+
console.error("Failed to load the class of the", registered.metas.id, "service:", error);
|
|
203
|
+
throw error;
|
|
205
204
|
}
|
|
206
205
|
|
|
207
206
|
// Create class instance
|
|
@@ -215,8 +214,8 @@ export default abstract class Service<
|
|
|
215
214
|
this.app || this
|
|
216
215
|
)
|
|
217
216
|
} catch (error) {
|
|
218
|
-
console.error("Failed to instanciate class of the", registered.metas.id, "service
|
|
219
|
-
|
|
217
|
+
console.error("Failed to instanciate class of the", registered.metas.id, "service");
|
|
218
|
+
throw error;
|
|
220
219
|
}
|
|
221
220
|
|
|
222
221
|
// Hande custom instance getter (ex: SQL callable class)
|
|
@@ -225,8 +224,8 @@ export default abstract class Service<
|
|
|
225
224
|
try {
|
|
226
225
|
serviceInstance = service.getServiceInstance();
|
|
227
226
|
} catch (error) {
|
|
228
|
-
console.error("Failed to get service instance for the ", registered.metas.id, "service
|
|
229
|
-
|
|
227
|
+
console.error("Failed to get service instance for the ", registered.metas.id, "service");
|
|
228
|
+
throw error;
|
|
230
229
|
}
|
|
231
230
|
|
|
232
231
|
// Bind his own metas
|
package/src/server/context.ts
CHANGED
package/src/server/index.ts
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import './app/container';
|
|
3
|
-
|
|
4
|
-
// Load services setup
|
|
1
|
+
import AppContainer from './app/container';
|
|
5
2
|
import '@/server/config/*.ts';
|
|
6
|
-
|
|
7
|
-
// Load Application
|
|
8
3
|
import Application from '@/server';
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
// Start application
|
|
12
|
-
application.start();
|
|
4
|
+
AppContainer.start( Application );
|
|
@@ -65,7 +65,7 @@ export type TServices = {
|
|
|
65
65
|
/*----------------------------------
|
|
66
66
|
- SERVICE
|
|
67
67
|
----------------------------------*/
|
|
68
|
-
export default abstract class
|
|
68
|
+
export default abstract class AuthService<
|
|
69
69
|
TUser extends {},
|
|
70
70
|
TApplication extends Application,
|
|
71
71
|
TJwtSession extends {} = {},
|
|
@@ -233,9 +233,19 @@ export default class SQL extends Service<Config, Hooks, Application, Services> {
|
|
|
233
233
|
// SQL query
|
|
234
234
|
} else if (typeof value === 'function' && value.string !== undefined)
|
|
235
235
|
value = ' ' + value.string;
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
// Escape value
|
|
237
|
+
else {
|
|
238
238
|
|
|
239
|
+
const lastKeyword = stringBefore.trim().split(' ').pop();
|
|
240
|
+
|
|
241
|
+
// Escape table name
|
|
242
|
+
if (lastKeyword === 'FROM')
|
|
243
|
+
value = '`' + value + '`';
|
|
244
|
+
else
|
|
245
|
+
value = mysql.escape(value);
|
|
246
|
+
|
|
247
|
+
value = ' ' + value;
|
|
248
|
+
}
|
|
239
249
|
stringBefore += value;
|
|
240
250
|
|
|
241
251
|
}
|
|
@@ -83,7 +83,6 @@ export default class FetchService extends Service<Config, Hooks, Application, Se
|
|
|
83
83
|
if (this.services.disks)
|
|
84
84
|
this.disk = this.services.disks.get( this.config.disk );
|
|
85
85
|
|
|
86
|
-
|
|
87
86
|
}
|
|
88
87
|
|
|
89
88
|
public async ready() {
|
|
@@ -116,8 +115,10 @@ export default class FetchService extends Service<Config, Hooks, Application, Se
|
|
|
116
115
|
) {
|
|
117
116
|
|
|
118
117
|
// Parse url if router service is provided
|
|
119
|
-
if (this.services.router
|
|
120
|
-
|
|
118
|
+
if (this.services.router === undefined)
|
|
119
|
+
throw new Error(`Please bind the Router service to the Fetch service in order to contact APIs.`);
|
|
120
|
+
|
|
121
|
+
url = this.services.router.url(url);
|
|
121
122
|
|
|
122
123
|
// Send request
|
|
123
124
|
const res = await got(url, {
|
|
@@ -14,7 +14,7 @@ import Service, { AnyService, TRegisteredService } from '@server/app/service';
|
|
|
14
14
|
import SocketScope, { WebSocket } from './scope';
|
|
15
15
|
import type Router from '@server/services/router';
|
|
16
16
|
export type { WebSocket, default as SocketScope } from './scope';
|
|
17
|
-
import type UsersManagementService from '../
|
|
17
|
+
import type UsersManagementService from '../auth';
|
|
18
18
|
|
|
19
19
|
/*----------------------------------
|
|
20
20
|
- TYPES
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|