5htp-core 0.3.7 → 0.3.9
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 +5 -3
- package/src/client/assets/css/components/button.less +6 -10
- package/src/client/assets/css/components/card.less +1 -7
- package/src/client/assets/css/text/icons.less +8 -5
- package/src/client/assets/css/text/text.less +2 -3
- package/src/client/assets/css/theme.less +1 -1
- package/src/client/assets/css/utils/layouts.less +4 -0
- package/src/client/components/Form.ts +2 -1
- package/src/client/components/Select/ChoiceElement.tsx +20 -6
- package/src/client/components/Select/ChoiceSelector.tsx +3 -2
- package/src/client/components/Select/index.tsx +53 -21
- package/src/client/components/containers/Popover/index.tsx +4 -1
- package/src/client/components/data/Time.tsx +16 -12
- package/src/client/components/inputv3/base.tsx +1 -0
- package/src/client/components/inputv3/index.tsx +3 -1
- package/src/client/services/router/components/router.tsx +10 -8
- package/src/client/services/router/index.tsx +0 -0
- package/src/client/services/router/request/api.ts +9 -3
- package/src/common/data/dates.ts +20 -4
- package/src/common/data/objets.ts +17 -0
- package/src/common/router/index.ts +1 -1
- package/src/common/validation/schema.ts +85 -91
- package/src/common/validation/validator.ts +4 -6
- package/src/common/validation/validators.ts +74 -72
- package/src/server/{services → app/container}/console/index.ts +52 -16
- package/src/server/app/container/index.ts +54 -0
- package/src/server/app/index.ts +22 -22
- package/src/server/app/service/index.ts +36 -11
- package/src/server/app.tsconfig.json +1 -1
- 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/connection.ts +3 -1
- package/src/server/services/database/index.ts +34 -24
- package/src/server/services/database/model.ts +28 -0
- package/src/server/services/fetch/index.ts +4 -3
- package/src/server/services/router/index.ts +4 -1
- package/src/server/services/schema/request.ts +4 -11
- 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
|
@@ -12,7 +12,7 @@ import { default as Validator, EXCLUDE_VALUE } from './validator';
|
|
|
12
12
|
- TYPES
|
|
13
13
|
----------------------------------*/
|
|
14
14
|
|
|
15
|
-
export type TSchemaFields = { [fieldName: string]: Schema<{}> | Validator<any> }
|
|
15
|
+
export type TSchemaFields = { [fieldName: string]: TSchemaFields | Schema<{}> | Validator<any> }
|
|
16
16
|
|
|
17
17
|
type TSchemaOptions = {
|
|
18
18
|
opt?: boolean
|
|
@@ -60,134 +60,128 @@ export default class Schema<TFields extends TSchemaFields> {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
public validate<TDonnees extends TObjetDonnees>(
|
|
63
|
-
|
|
64
63
|
dataToValidate: Partial<TDonnees>,
|
|
65
|
-
allData: TDonnees,
|
|
66
|
-
output: TObjetDonnees = {},
|
|
67
|
-
|
|
68
64
|
opts: TValidateOptions<TFields> = {},
|
|
69
65
|
chemin: string[] = []
|
|
66
|
+
): TValidatedData<TFields> {
|
|
67
|
+
|
|
68
|
+
// Check data type
|
|
69
|
+
if (typeof dataToValidate !== 'object')
|
|
70
|
+
throw new InputErrorSchema({ [chemin.join('.')]: ['Must be an object'] });
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
// Default options
|
|
73
73
|
opts = {
|
|
74
74
|
debug: false,
|
|
75
|
-
throwError:
|
|
75
|
+
throwError: true,
|
|
76
76
|
validateDeps: true,
|
|
77
77
|
autoCorrect: false,
|
|
78
78
|
...opts,
|
|
79
79
|
}
|
|
80
|
-
|
|
81
|
-
let outputSchema = output;
|
|
82
|
-
for (const branche of chemin)
|
|
83
|
-
outputSchema = outputSchema[branche];
|
|
84
80
|
|
|
85
|
-
const keysToValidate = opts.only || Object.keys(this.fields);
|
|
81
|
+
const keysToValidate = (opts.only || Object.keys(this.fields)) as string[];
|
|
86
82
|
|
|
87
83
|
// Validation de chacune d'entre elles
|
|
84
|
+
const output: Partial<TDonnees> = {};
|
|
88
85
|
let erreurs: TListeErreursSaisie = {};
|
|
89
86
|
let errorsCount = 0;
|
|
90
87
|
for (const fieldName of keysToValidate) {
|
|
91
88
|
|
|
92
89
|
// La donnée est répertoriée dans le schema
|
|
93
|
-
|
|
90
|
+
let field = this.fields[fieldName];
|
|
91
|
+
let validator: Validator<any> | Schema<{}>;
|
|
94
92
|
if (field === undefined) {
|
|
95
93
|
opts.debug && console.warn(LogPrefix, '[' + fieldName + ']', 'Exclusion (pas présent dans le schéma)');
|
|
96
94
|
continue;
|
|
97
|
-
}
|
|
95
|
+
} else if (field.constructor === Object)
|
|
96
|
+
validator = new Schema(field as TSchemaFields);
|
|
97
|
+
else
|
|
98
|
+
validator = field as Validator<any>;
|
|
98
99
|
|
|
100
|
+
// Create field path
|
|
99
101
|
const cheminA = [...chemin, fieldName]
|
|
100
102
|
const cheminAstr = cheminA.join('.')
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
const valOrigine = dataToValidate[fieldName];
|
|
104
|
+
|
|
105
|
+
// Validation
|
|
106
|
+
try {
|
|
107
|
+
|
|
108
|
+
const val = validator.validate(valOrigine, opts, cheminA);
|
|
109
|
+
|
|
110
|
+
// Exclusion seulement si explicitement demandé
|
|
111
|
+
// IMPORTANT: Conserver les values undefined
|
|
112
|
+
// La présence d'un valeur undefined peut être utile, par exemple, pour indiquer qu'on souhaite supprimer une donnée
|
|
113
|
+
// Exemple: undefinec = suppression fichier | Absende donnée = conservation fihcier actuel
|
|
114
|
+
if (val === EXCLUDE_VALUE)
|
|
115
|
+
opts.debug && console.log(LogPrefix, '[' + cheminA + '] Exclusion demandée');
|
|
116
|
+
else
|
|
117
|
+
output[fieldName] = val;
|
|
118
|
+
|
|
119
|
+
opts.debug && console.log(LogPrefix, '[' + cheminA + ']', valOrigine, '=>', val);
|
|
120
|
+
|
|
121
|
+
} catch (error) {
|
|
122
|
+
|
|
123
|
+
opts.debug && console.warn(LogPrefix, '[' + cheminA + ']', valOrigine, '|| CoreError:', error);
|
|
124
|
+
|
|
125
|
+
if (error instanceof InputErrorSchema) {
|
|
126
|
+
|
|
127
|
+
erreurs = { ...erreurs, ...error.erreursSaisie };
|
|
128
|
+
errorsCount += Object.keys(error.erreursSaisie).length;
|
|
129
|
+
|
|
130
|
+
} else if (error instanceof CoreError) {
|
|
131
|
+
|
|
132
|
+
erreurs[cheminAstr] = [error.message]
|
|
133
|
+
errorsCount++;
|
|
134
|
+
|
|
135
|
+
} else if (SERVER) {
|
|
136
|
+
|
|
137
|
+
// Server: transmiss error & report bug
|
|
138
|
+
throw error;
|
|
139
|
+
|
|
140
|
+
} else {
|
|
141
|
+
|
|
142
|
+
erreurs[cheminAstr] = ["Technical error while validating data"];
|
|
113
143
|
errorsCount++;
|
|
114
|
-
continue;
|
|
115
144
|
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
116
147
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
allData,
|
|
122
|
-
output,
|
|
123
|
-
|
|
124
|
-
opts,
|
|
125
|
-
cheminA
|
|
126
|
-
);
|
|
127
|
-
erreurs = { ...erreurs, ...validationSchema.erreurs };
|
|
128
|
-
errorsCount += validationSchema.errorsCount;
|
|
129
|
-
|
|
130
|
-
// Pas besoin d'assigner, car output est passé en référence
|
|
131
|
-
//output[fieldName] = validationSchema.values;
|
|
148
|
+
if (errorsCount !== 0)
|
|
149
|
+
throw new InputErrorSchema(erreurs);
|
|
150
|
+
|
|
151
|
+
opts.debug && console.log(LogPrefix, '', dataToValidate, '=>', output);
|
|
132
152
|
|
|
153
|
+
return output as TValidatedData<TFields>;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
public validateWithDetails<TDonnees extends TObjetDonnees>(
|
|
133
157
|
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
dataToValidate: Partial<TDonnees>,
|
|
159
|
+
allData: TDonnees,
|
|
160
|
+
output: TObjetDonnees = {},
|
|
136
161
|
|
|
137
|
-
|
|
162
|
+
opts: TValidateOptions<TFields> = {},
|
|
163
|
+
chemin: string[] = []
|
|
138
164
|
|
|
139
|
-
|
|
165
|
+
): TValidationResult<TFields> {
|
|
166
|
+
|
|
167
|
+
let erreurs: TListeErreursSaisie = {};
|
|
168
|
+
let errorsCount = 0;
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
this.validate(dataToValidate, opts, chemin);
|
|
172
|
+
} catch (error) {
|
|
173
|
+
if (error instanceof InputErrorSchema) {
|
|
174
|
+
erreurs = error.erreursSaisie;
|
|
175
|
+
errorsCount = Object.keys(erreurs).length;
|
|
140
176
|
} else {
|
|
141
|
-
|
|
142
|
-
// Champ composé de plusieurs values
|
|
143
|
-
const valOrigine = field.options.as === undefined
|
|
144
|
-
? dataToValidate[fieldName]
|
|
145
|
-
// Le fieldName regroupe plusieurs values (ex: Periode)
|
|
146
|
-
: field.options.as.map((nomVal: string) => dataToValidate[nomVal])
|
|
147
|
-
|
|
148
|
-
// Validation
|
|
149
|
-
try {
|
|
150
|
-
|
|
151
|
-
const val = field.validate(valOrigine, allData, output, opts);
|
|
152
|
-
|
|
153
|
-
// Exclusion seulement si explicitement demandé
|
|
154
|
-
// IMPORTANT: Conserver les values undefined
|
|
155
|
-
// La présence d'un valeur undefined peut être utile, par exemple, pour indiquer qu'on souhaite supprimer une donnée
|
|
156
|
-
// Exemple: undefinec = suppression fichier | Absende donnée = conservation fihcier actuel
|
|
157
|
-
if (val === EXCLUDE_VALUE)
|
|
158
|
-
opts.debug && console.log(LogPrefix, '[' + cheminA + '] Exclusion demandée');
|
|
159
|
-
else
|
|
160
|
-
outputSchema[fieldName] = val;
|
|
161
|
-
|
|
162
|
-
opts.debug && console.log(LogPrefix, '[' + cheminA + ']', valOrigine, '=>', val);
|
|
163
|
-
|
|
164
|
-
} catch (error) {
|
|
165
|
-
|
|
166
|
-
opts.debug && console.warn(LogPrefix, '[' + cheminA + ']', valOrigine, '|| CoreError:', error);
|
|
167
|
-
|
|
168
|
-
if (error instanceof CoreError) {
|
|
169
|
-
|
|
170
|
-
// Référencement erreur
|
|
171
|
-
erreurs[cheminAstr] = [error.message]
|
|
172
|
-
errorsCount++;
|
|
173
|
-
|
|
174
|
-
} else
|
|
175
|
-
throw error;
|
|
176
|
-
}
|
|
177
|
+
throw error;
|
|
177
178
|
}
|
|
178
179
|
}
|
|
179
|
-
|
|
180
|
-
if (errorsCount !== 0 && opts.throwError === true) {
|
|
181
|
-
throw new InputErrorSchema(erreurs);
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
opts.debug && console.log(LogPrefix, '', dataToValidate, '=>', output);
|
|
185
|
-
|
|
180
|
+
|
|
186
181
|
return {
|
|
187
182
|
values: output as TValidatedData<TFields>,
|
|
188
183
|
erreurs,
|
|
189
184
|
errorsCount,
|
|
190
185
|
};
|
|
191
|
-
|
|
192
186
|
}
|
|
193
187
|
}
|
|
@@ -28,7 +28,6 @@ export type TValidator<TValue> = {
|
|
|
28
28
|
dependances?: string[],
|
|
29
29
|
opt?: true,
|
|
30
30
|
defaut?: TValue,
|
|
31
|
-
as?: string[], // Mapping personnalisé
|
|
32
31
|
|
|
33
32
|
}
|
|
34
33
|
|
|
@@ -40,9 +39,8 @@ type TValidationArgs<TValue, TAllValues extends {}> = [
|
|
|
40
39
|
// For the value given as input in the validation function,
|
|
41
40
|
// Only the empty values were escluded
|
|
42
41
|
val: TNonEmptyValue,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
validateOptions?: TValidateOptions
|
|
42
|
+
validateOptions: TValidateOptions,
|
|
43
|
+
path: string[]
|
|
46
44
|
]
|
|
47
45
|
|
|
48
46
|
type TValidationFunction<TValue, TAllValues extends {} = {}> = (
|
|
@@ -87,7 +85,7 @@ export default class Validator<
|
|
|
87
85
|
public isEmpty = (val: any) => val === undefined || val === '' || val === null
|
|
88
86
|
|
|
89
87
|
public validate(...[
|
|
90
|
-
val,
|
|
88
|
+
val, validateOptions, path
|
|
91
89
|
]: TValidationArgs<TValue, {}>): TValidateReturnType<TOptions, TValue> {
|
|
92
90
|
|
|
93
91
|
// Required value
|
|
@@ -105,7 +103,7 @@ export default class Validator<
|
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
// Validate type
|
|
108
|
-
return this.validateType(val,
|
|
106
|
+
return this.validateType(val, validateOptions, path) as TValidateReturnType<TOptions, TValue>;
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
}
|
|
@@ -17,7 +17,7 @@ import { InputError } from '@common/errors';
|
|
|
17
17
|
import FileToUpload from '@client/components/inputv3/file/FileToUpload';
|
|
18
18
|
|
|
19
19
|
// Speciific
|
|
20
|
-
import Schema from './schema'
|
|
20
|
+
import Schema, { TSchemaFields } from './schema'
|
|
21
21
|
import Validator, { TValidator } from './validator'
|
|
22
22
|
|
|
23
23
|
// Components
|
|
@@ -32,6 +32,10 @@ export type TFileValidator = TValidator<FileToUpload> & {
|
|
|
32
32
|
taille?: number
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
type TSchemaSubtype = Schema<{}> | TSchemaFields;
|
|
36
|
+
|
|
37
|
+
type TSubtype = TSchemaSubtype | Validator<any>;
|
|
38
|
+
|
|
35
39
|
/*----------------------------------
|
|
36
40
|
- CONST
|
|
37
41
|
----------------------------------*/
|
|
@@ -48,30 +52,35 @@ export default class SchemaValidators {
|
|
|
48
52
|
/*----------------------------------
|
|
49
53
|
- CONTENEURS
|
|
50
54
|
----------------------------------*/
|
|
51
|
-
public object = ({ ...opts }: TValidator<object> & {
|
|
52
|
-
new Validator<object>('object', (val, input, output) => {
|
|
55
|
+
public object = ( subtype?: TSchemaSubtype, { ...opts }: TValidator<object> & {
|
|
53
56
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
try {
|
|
57
|
-
val = JSON.parse(val);
|
|
58
|
-
} catch (error) {
|
|
59
|
-
console.error('Unable to convert the given string into an object.');
|
|
60
|
-
}*/
|
|
57
|
+
} = {}) =>
|
|
58
|
+
new Validator<object>('object', (val, options, path) => {
|
|
61
59
|
|
|
60
|
+
// The value should be an object
|
|
62
61
|
if (typeof val !== 'object' || val.constructor !== Object)
|
|
63
62
|
throw new InputError("This value must be an object.");
|
|
64
63
|
|
|
65
|
-
return
|
|
64
|
+
// If no subtype, return the object as is
|
|
65
|
+
if (subtype === undefined)
|
|
66
|
+
return val;
|
|
67
|
+
|
|
68
|
+
// If subtype is a schema
|
|
69
|
+
const schema = subtype.constructor === Object
|
|
70
|
+
? new Schema(subtype as TSchemaFields)
|
|
71
|
+
: subtype as Schema<{}>;
|
|
72
|
+
|
|
73
|
+
// Validate schema
|
|
74
|
+
const value = schema.validate(val, options, path);
|
|
75
|
+
|
|
76
|
+
return value;
|
|
66
77
|
}, opts)
|
|
67
78
|
|
|
68
|
-
public array = ( subtype
|
|
69
|
-
choice, min, max, ...opts
|
|
70
|
-
}: TValidator<any[]> & {
|
|
79
|
+
public array = ( subtype: TSubtype, { choice, min, max, ...opts }: TValidator<any[]> & {
|
|
71
80
|
choice?: any[],
|
|
72
81
|
min?: number,
|
|
73
82
|
max?: number
|
|
74
|
-
} = {}) => new Validator<any[]>('array', (items,
|
|
83
|
+
} = {}) => new Validator<any[]>('array', (items, options, path) => {
|
|
75
84
|
|
|
76
85
|
// Type
|
|
77
86
|
if (!Array.isArray(items))
|
|
@@ -84,32 +93,26 @@ export default class SchemaValidators {
|
|
|
84
93
|
throw new InputError(`Please select maximum ${max} items.`);
|
|
85
94
|
|
|
86
95
|
// Verif each item
|
|
87
|
-
if (subtype
|
|
88
|
-
|
|
96
|
+
if (subtype === undefined)
|
|
97
|
+
return items;
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
99
|
+
const validator = subtype.constructor === Object
|
|
100
|
+
? new Schema(subtype as TSchemaFields)
|
|
101
|
+
: subtype as Schema<{}> | Validator<any>;
|
|
93
102
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
subtype.validate( item, items, items, corriger )
|
|
98
|
-
)
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
}
|
|
103
|
+
items = items.map( item =>
|
|
104
|
+
validator.validate( item, options, path )
|
|
105
|
+
)
|
|
102
106
|
|
|
103
107
|
return items;
|
|
104
108
|
}, {
|
|
105
109
|
...opts,
|
|
106
110
|
//multiple: true, // Sélection multiple
|
|
107
|
-
//subtype
|
|
108
111
|
})
|
|
109
112
|
|
|
110
113
|
public choice = (choices?: any[], { multiple, ...opts }: TValidator<any> & {
|
|
111
114
|
multiple?: boolean
|
|
112
|
-
} = {}) => new Validator<any>('choice', (val,
|
|
115
|
+
} = {}) => new Validator<any>('choice', (val, options, path) => {
|
|
113
116
|
|
|
114
117
|
// Empty array = undefined if not required
|
|
115
118
|
if (val.length === 0 && opts.opt)
|
|
@@ -145,11 +148,11 @@ export default class SchemaValidators {
|
|
|
145
148
|
/*----------------------------------
|
|
146
149
|
- CHAINES
|
|
147
150
|
----------------------------------*/
|
|
148
|
-
public string = ({ min, max,
|
|
151
|
+
public string = ({ min, max, in: choices, ...opts }: TValidator<string> & {
|
|
149
152
|
min?: number,
|
|
150
153
|
max?: number,
|
|
151
|
-
|
|
152
|
-
} = {}) => new Validator<string>('string', (val,
|
|
154
|
+
in?: string[]
|
|
155
|
+
} = {}) => new Validator<string>('string', (val, options, path) => {
|
|
153
156
|
|
|
154
157
|
// Check type
|
|
155
158
|
if (val === '')
|
|
@@ -162,13 +165,17 @@ export default class SchemaValidators {
|
|
|
162
165
|
// Whitespace
|
|
163
166
|
val = trim(val);
|
|
164
167
|
|
|
168
|
+
// In
|
|
169
|
+
if (choices !== undefined && !choices.includes(val))
|
|
170
|
+
throw new InputError(`Invalid value: ${val}. Must be one of: ${choices.join(', ')}`);
|
|
171
|
+
|
|
165
172
|
// Min size
|
|
166
173
|
if (min !== undefined && val.length < min)
|
|
167
174
|
throw new InputError(`Must be at least ` + min + ' characters');
|
|
168
175
|
|
|
169
176
|
// Max size
|
|
170
177
|
if (max !== undefined && val.length > max)
|
|
171
|
-
if (
|
|
178
|
+
if (options?.autoCorrect)
|
|
172
179
|
val = val.substring(0, max);
|
|
173
180
|
else
|
|
174
181
|
throw new InputError(`Must be up to ` + max + ' characters');
|
|
@@ -180,9 +187,9 @@ export default class SchemaValidators {
|
|
|
180
187
|
public url = (opts: TValidator<string> & {
|
|
181
188
|
normalize?: NormalizeUrlOptions
|
|
182
189
|
} = {}) =>
|
|
183
|
-
new Validator<string>('url', (inputVal,
|
|
190
|
+
new Validator<string>('url', (inputVal, options, path) => {
|
|
184
191
|
|
|
185
|
-
let val = this.string(opts).validate(inputVal,
|
|
192
|
+
let val = this.string(opts).validate(inputVal, options, path);
|
|
186
193
|
|
|
187
194
|
// Check if URL
|
|
188
195
|
if (!isURL(val, {
|
|
@@ -198,9 +205,9 @@ export default class SchemaValidators {
|
|
|
198
205
|
}, opts)
|
|
199
206
|
|
|
200
207
|
public email = (opts: TValidator<string> & {} = {}) =>
|
|
201
|
-
new Validator<string>('email', (inputVal,
|
|
208
|
+
new Validator<string>('email', (inputVal, options, path) => {
|
|
202
209
|
|
|
203
|
-
let val = this.string(opts).validate(inputVal,
|
|
210
|
+
let val = this.string(opts).validate(inputVal, options, path);
|
|
204
211
|
|
|
205
212
|
if (!isEmail(val))
|
|
206
213
|
throw new InputError("Please enter a valid email address.");
|
|
@@ -239,41 +246,36 @@ export default class SchemaValidators {
|
|
|
239
246
|
min?: number,
|
|
240
247
|
max?: number,
|
|
241
248
|
step?: number,
|
|
242
|
-
} = {}) => new Validator<number>('number', (val,
|
|
243
|
-
|
|
244
|
-
// Vérifications suivantes inutiles si des values spécifiques ont été fournies
|
|
245
|
-
if (opts.in === undefined) {
|
|
249
|
+
} = {}) => new Validator<number>('number', (val, options, path) => {
|
|
246
250
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
// Minimum
|
|
263
|
-
if (val < opts.min)
|
|
264
|
-
if (corriger)
|
|
265
|
-
val = opts.min;
|
|
266
|
-
else
|
|
267
|
-
throw new InputError(`Must be at least ` + opts.min);
|
|
251
|
+
// Tente conversion chaine en nombre
|
|
252
|
+
if (typeof val === 'string')
|
|
253
|
+
val = withDecimals ? parseFloat(val) : parseInt(val);
|
|
254
|
+
|
|
255
|
+
if (opts.min === undefined)
|
|
256
|
+
opts.min = 0;
|
|
257
|
+
|
|
258
|
+
// Type de donnée
|
|
259
|
+
if (Number.isNaN(val) || typeof val !== 'number') {
|
|
260
|
+
if (options?.autoCorrect)
|
|
261
|
+
val = opts.min;
|
|
262
|
+
else
|
|
263
|
+
throw new InputError("This value must be a number.");
|
|
264
|
+
}
|
|
268
265
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
266
|
+
// Minimum
|
|
267
|
+
if (val < opts.min)
|
|
268
|
+
if (options?.autoCorrect)
|
|
269
|
+
val = opts.min;
|
|
270
|
+
else
|
|
271
|
+
throw new InputError(`Must be at least ` + opts.min);
|
|
275
272
|
|
|
276
|
-
|
|
273
|
+
// Maximum
|
|
274
|
+
if (opts.max !== undefined && val > opts.max)
|
|
275
|
+
if (options?.autoCorrect)
|
|
276
|
+
val = opts.max;
|
|
277
|
+
else
|
|
278
|
+
throw new InputError(`Must be up to ` + opts.max);
|
|
277
279
|
|
|
278
280
|
return val;
|
|
279
281
|
}, {
|
|
@@ -288,7 +290,7 @@ export default class SchemaValidators {
|
|
|
288
290
|
public float = this.number(true)
|
|
289
291
|
|
|
290
292
|
public bool = (opts: TValidator<boolean> & {} = {}) =>
|
|
291
|
-
new Validator<boolean>('bool', (val,
|
|
293
|
+
new Validator<boolean>('bool', (val, options, path) => {
|
|
292
294
|
|
|
293
295
|
if (typeof val !== 'boolean' && !['true', 'false'].includes(val))
|
|
294
296
|
throw new InputError("This value must be a boolean.");
|
|
@@ -306,7 +308,7 @@ export default class SchemaValidators {
|
|
|
306
308
|
----------------------------------*/
|
|
307
309
|
public date = (opts: TValidator<Date> & {
|
|
308
310
|
|
|
309
|
-
} = {}) => new Validator<Date>('date', (val,
|
|
311
|
+
} = {}) => new Validator<Date>('date', (val, options, path) => {
|
|
310
312
|
|
|
311
313
|
const chaine = typeof val == 'string';
|
|
312
314
|
|
|
@@ -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>;
|
|
@@ -134,17 +135,27 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
134
135
|
/*----------------------------------
|
|
135
136
|
- LIFECYCLE
|
|
136
137
|
----------------------------------*/
|
|
138
|
+
/*
|
|
139
|
+
WARN: This service should depend on the less services as possible, and be usable ASAP.
|
|
140
|
+
So bug reports can be sent at any state of the app, includoing thre most early
|
|
141
|
+
*/
|
|
142
|
+
public constructor(
|
|
143
|
+
private container: typeof ApplicationContainer,
|
|
144
|
+
private config: Config,
|
|
145
|
+
) {
|
|
137
146
|
|
|
138
|
-
|
|
147
|
+
console.log("Setting up Console shell module.");
|
|
139
148
|
|
|
140
149
|
const origLog = console.log
|
|
141
150
|
|
|
142
|
-
const
|
|
151
|
+
const Env = container.Environment;
|
|
152
|
+
|
|
153
|
+
const envConfig = this.config[ Env.profile === 'prod' ? 'prod' : 'dev' ];
|
|
143
154
|
const minLogLevel = logLevels[ envConfig.level ];
|
|
144
155
|
|
|
145
156
|
this.logger = new Logger({
|
|
146
157
|
// Use to improve performance in production
|
|
147
|
-
hideLogPositionForProduction:
|
|
158
|
+
hideLogPositionForProduction: Env.profile === 'prod',
|
|
148
159
|
type: 'pretty',
|
|
149
160
|
prettyInspectOptions: {
|
|
150
161
|
depth: 2
|
|
@@ -201,13 +212,10 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
201
212
|
setInterval(() => this.clean(), 10000);
|
|
202
213
|
}
|
|
203
214
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
public async shutdown() {
|
|
209
|
-
|
|
210
|
-
}
|
|
215
|
+
// Avoid to use lifecycle functions
|
|
216
|
+
protected async start() {}
|
|
217
|
+
public async ready() {}
|
|
218
|
+
public async shutdown() {}
|
|
211
219
|
|
|
212
220
|
/*----------------------------------
|
|
213
221
|
- LOGS FORMATTING
|
|
@@ -218,7 +226,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
218
226
|
if (filepath === undefined)
|
|
219
227
|
return undefined;
|
|
220
228
|
|
|
221
|
-
const projectRoot = this.
|
|
229
|
+
const projectRoot = this.container.path.root;
|
|
222
230
|
if (filepath.startsWith( projectRoot ))
|
|
223
231
|
filepath = filepath.substring( projectRoot.length )
|
|
224
232
|
|
|
@@ -257,6 +265,34 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
257
265
|
|
|
258
266
|
public async createBugReport( error: Error, request?: ServerRequest ) {
|
|
259
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
|
+
|
|
260
296
|
// Print the error so it's accessible via logs
|
|
261
297
|
if (error instanceof SqlError) {
|
|
262
298
|
let printedQuery: string;
|
|
@@ -267,7 +303,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
267
303
|
}
|
|
268
304
|
console.error(`Error caused by this query:`, printedQuery);
|
|
269
305
|
}
|
|
270
|
-
|
|
306
|
+
|
|
271
307
|
if (error.dataForDebugging !== undefined)
|
|
272
308
|
console.error(LogPrefix, `More data about the error:`, error.dataForDebugging);
|
|
273
309
|
|
|
@@ -306,7 +342,7 @@ export default class Console extends Service<Config, Hooks, Application, Service
|
|
|
306
342
|
logs: logsHtml
|
|
307
343
|
}
|
|
308
344
|
|
|
309
|
-
await
|
|
345
|
+
await application.reportBug( bugReport );
|
|
310
346
|
}
|
|
311
347
|
|
|
312
348
|
public getChannel() {
|