5htp-core 0.1.2 → 0.2.0

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 (127) hide show
  1. package/changelog.md +5 -0
  2. package/doc/TODO.md +71 -0
  3. package/package.json +5 -4
  4. package/src/client/{App.tsx → app/component.tsx} +15 -8
  5. package/src/client/app/index.ts +128 -0
  6. package/src/client/app/service.ts +34 -0
  7. package/src/client/app.tsconfig.json +0 -4
  8. package/src/client/assets/css/medias.less +14 -0
  9. package/src/client/components/Card/index.tsx +2 -2
  10. package/src/client/components/Dialog/Manager.tsx +39 -12
  11. package/src/client/components/Form/index.tsx +1 -1
  12. package/src/client/components/button.tsx +2 -2
  13. package/src/client/components/containers/Popover/index.tsx +1 -1
  14. package/src/client/components/data/spintext/index.tsx +1 -1
  15. package/src/client/components/dropdown/index.tsx +1 -1
  16. package/src/client/components/index.ts +8 -0
  17. package/src/client/components/input/BaseV2/index.tsx +1 -1
  18. package/src/client/components/input/UploadImage/index.tsx +1 -1
  19. package/src/client/hooks/index.ts +5 -0
  20. package/src/client/hooks/useState/index.tsx +2 -2
  21. package/src/client/hooks.ts +22 -0
  22. package/src/client/index.ts +5 -0
  23. package/src/client/pages/_layout/landing/index.tsx +0 -2
  24. package/src/client/pages/_messages/400.tsx +2 -2
  25. package/src/client/pages/_messages/401.tsx +2 -2
  26. package/src/client/pages/_messages/403.tsx +2 -2
  27. package/src/client/pages/_messages/404.tsx +2 -2
  28. package/src/client/pages/_messages/500.tsx +2 -2
  29. package/src/client/pages/bug.tsx +1 -1
  30. package/src/client/pages/useHeader.tsx +1 -1
  31. package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
  32. package/src/client/services/metrics/index.ts +37 -0
  33. package/src/client/{router → services/router/components}/Link.tsx +1 -1
  34. package/src/client/services/router/components/Page.tsx +59 -0
  35. package/src/client/{router/component.tsx → services/router/components/router.tsx} +43 -74
  36. package/src/client/services/router/index.tsx +448 -0
  37. package/src/client/services/router/request/api.ts +229 -0
  38. package/src/client/{router → services/router}/request/history.ts +0 -0
  39. package/src/client/services/router/request/index.ts +52 -0
  40. package/src/client/services/router/response/index.tsx +107 -0
  41. package/src/client/services/router/response/page.ts +95 -0
  42. package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
  43. package/src/client/utils/dom.ts +1 -1
  44. package/src/common/app/index.ts +9 -0
  45. package/src/common/data/chaines/index.ts +9 -6
  46. package/src/common/data/input/validate.ts +3 -166
  47. package/src/common/data/objets.ts +25 -0
  48. package/src/common/data/tableaux.ts +8 -0
  49. package/src/common/errors/index.ts +3 -1
  50. package/src/common/router/index.ts +67 -88
  51. package/src/common/router/layouts.ts +50 -0
  52. package/src/common/router/register.ts +62 -0
  53. package/src/common/router/request/api.ts +72 -0
  54. package/src/common/router/request/index.ts +31 -0
  55. package/src/common/router/{response.ts → response/index.ts} +9 -13
  56. package/src/common/router/response/page.ts +40 -56
  57. package/src/common/validation/index.ts +3 -0
  58. package/src/common/validation/schema.ts +184 -0
  59. package/src/common/validation/validator.ts +88 -0
  60. package/src/common/validation/validators.ts +313 -0
  61. package/src/server/app/config.ts +9 -27
  62. package/src/server/app/index.ts +81 -124
  63. package/src/server/app/service.ts +98 -0
  64. package/src/server/app.tsconfig.json +0 -8
  65. package/src/server/error/index.ts +13 -0
  66. package/src/server/index.ts +5 -0
  67. package/src/server/patch.ts +0 -6
  68. package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
  69. package/src/server/services/console/bugReporter.ts +26 -16
  70. package/src/server/services/console/index.ts +59 -51
  71. package/src/server/services/cron/index.ts +12 -26
  72. package/src/server/services/database/bucket.ts +40 -0
  73. package/src/server/services/database/connection.ts +206 -75
  74. package/src/server/services/database/datatypes.ts +63 -40
  75. package/src/server/services/database/index.ts +295 -272
  76. package/src/server/services/database/metas.ts +246 -135
  77. package/src/server/services/database/stats.ts +151 -126
  78. package/src/server/services/email/index.ts +28 -52
  79. package/src/server/services/{router/request/services → metrics}/detect.ts +8 -10
  80. package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
  81. package/src/server/services/{http → router/http}/index.ts +28 -70
  82. package/src/server/services/{http → router/http}/multipart.ts +0 -0
  83. package/src/server/services/{http → router/http}/session.ts.old +0 -0
  84. package/src/server/services/router/index.ts +273 -203
  85. package/src/server/services/router/request/api.ts +73 -0
  86. package/src/server/services/router/request/index.ts +16 -97
  87. package/src/server/services/router/request/service.ts +21 -0
  88. package/src/server/services/router/response/index.ts +125 -64
  89. package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
  90. package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
  91. package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
  92. package/src/server/services/router/response/page/document.tsx +194 -0
  93. package/src/server/services/router/response/page/index.tsx +157 -0
  94. package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
  95. package/src/server/services/router/service.ts +48 -0
  96. package/src/server/services/schema/index.ts +47 -0
  97. package/src/server/services/schema/request.ts +55 -0
  98. package/src/server/services/schema/router.ts +33 -0
  99. package/src/server/services/socket/index.ts +38 -43
  100. package/src/server/services/socket/scope.ts +6 -4
  101. package/src/server/services/users/index.ts +203 -0
  102. package/src/server/services/{auth/base.ts → users/old.ts} +28 -112
  103. package/src/server/services/users/router/index.ts +72 -0
  104. package/src/server/services/users/router/request.ts +49 -0
  105. package/src/types/aliases.d.ts +43 -2
  106. package/templates/composant.tsx +1 -1
  107. package/templates/modal.tsx +1 -1
  108. package/templates/page.tsx +1 -1
  109. package/tsconfig.common.json +0 -4
  110. package/src/client/context/api.ts +0 -92
  111. package/src/client/context/index.ts +0 -246
  112. package/src/client/index.tsx +0 -129
  113. package/src/client/router/index.ts +0 -286
  114. package/src/client/router/request/index.ts +0 -106
  115. package/src/client/router/response/index.ts +0 -38
  116. package/src/client/router/route.ts +0 -75
  117. package/src/common/data/input/validators/basic.ts +0 -299
  118. package/src/common/data/input/validators/build.ts +0 -63
  119. package/src/common/router/request.ts +0 -83
  120. package/src/server/data/ApiClient.ts +0 -119
  121. package/src/server/data/input.ts +0 -41
  122. package/src/server/libs/pages/document.static.tsx +0 -41
  123. package/src/server/libs/pages/document.tsx +0 -203
  124. package/src/server/libs/pages/render.tsx +0 -90
  125. package/src/server/routes/auth.ts +0 -151
  126. package/src/server/services/redis/index.ts +0 -71
  127. package/src/server/services/router/request/services/auth.ts +0 -177
@@ -1,299 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import {
7
- trim,
8
- isISO8601, toDate,
9
- isEmail, normalizeEmail,
10
- isURL
11
- } from 'validator';
12
-
13
- // Libs
14
- import { InputError } from '@common/errors';
15
- import File from '@common/data/file';
16
-
17
- // Libs métier
18
- import { champ } from './build';
19
- import { TSchemaChamp } from '../validate';
20
- import NormalizedFile from '@common/data/file';
21
-
22
- // Components
23
- import NumberInput from '@client/components/input/Number';
24
- import Dropdown from '@client/components/dropdown.old';
25
-
26
- /*----------------------------------
27
- - CONTENEURS
28
- ----------------------------------*/
29
- export const object = (opts: TSchemaChamp<object> & {} = {}) => champ<object>('object', {
30
- ...opts,
31
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
32
-
33
- // TODO: executer seulement coté serveur
34
- /*if (typeof val === 'string' && val.startsWith('{'))
35
- try {
36
- val = JSON.parse(val);
37
- } catch (error) {
38
- console.error('Unable to convert the given string into an object.');
39
- }*/
40
-
41
- if (typeof val !== 'object' || val.constructor !== Object)
42
- throw new InputError("This value must be an object.");
43
-
44
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
45
- },
46
- })
47
-
48
- export const array = (subtype?: Schema<any> | TSchemaChamp<any[]>, { choix, ...opts }: TSchemaChamp<any[]> & {} = {}) => {
49
-
50
- if (subtype !== undefined)
51
- subtype.choix = choix;
52
-
53
- return champ<any[]>('array', {
54
- ...opts,
55
- choix,
56
- multiple: true, // Sélection multiple
57
- subtype,
58
- valider: async (items: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
59
-
60
- //console.log('VALIDER ARRAY', items, donneesSaisie);
61
-
62
- if (!Array.isArray(items))
63
- throw new InputError("This value must be an array.");
64
-
65
- // Verif items
66
- if (subtype !== undefined) {
67
- if (subtype instanceof Schema) {
68
-
69
- console.log('TODO: VALIDER VIA SOUS SCHEMA');
70
-
71
- } else {
72
-
73
- for (let i = 0; i < items.length; i++)
74
- items[i] = await subtype.valider(items[i], items);
75
-
76
- }
77
- }
78
-
79
- return opts.valider ? await opts.valider(items, donneesSaisie, donneesRetour) : items;
80
- },
81
- })
82
- }
83
-
84
- export const choice = (values: any[], opts: TSchemaChamp<any> & {} = {}) => champ<any>('object', {
85
- ...opts,
86
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
87
-
88
- if (!values.includes(val))
89
- throw new InputError("Invalid value. Must be: " + values.join(', '));
90
-
91
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
92
- },
93
- })
94
-
95
- /*----------------------------------
96
- - CHAINES
97
- ----------------------------------*/
98
- export const string = ({ min, max, ...opts }: TSchemaChamp<string> = {}) => champ<string>('string', {
99
- ...opts,
100
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees, corriger?: boolean) => {
101
-
102
- if (val === '')
103
- val = undefined;
104
- else if (typeof val === 'number')
105
- return val.toString();
106
- else if (typeof val !== 'string')
107
- throw new InputError("This value must be a string.");
108
-
109
- // Espaces blancs
110
- val = trim(val);
111
-
112
- // Taille min
113
- if (val.length < min)
114
- throw new InputError(`Must be at least ` + min + ' characters');
115
-
116
- // Taille max
117
- if (val.length > max)
118
- if (corriger)
119
- val = val.substring(0, max);
120
- else
121
- throw new InputError(`Must be up to ` + max + ' characters');
122
-
123
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
124
- },
125
- })
126
-
127
- export const url = (opts: TSchemaChamp<string> & {} = {}) => string({
128
- ...opts,
129
- valider: async (val: string, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees, corriger?: boolean) => {
130
-
131
- if (!isURL(val, {
132
- // https://www.npmjs.com/package/validator
133
- }))
134
- throw new InputError(`Please provide a valid URL.`);
135
-
136
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour, corriger) : val;
137
- },
138
- })
139
-
140
- export const email = (opts: TSchemaChamp<string> & {} = {}) => string({
141
- ...opts,
142
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees, corriger?: boolean) => {
143
-
144
- if (!isEmail(val))
145
- throw new InputError("Please enter a valid email address.");
146
-
147
- const retour = normalizeEmail(val);
148
-
149
- return opts.valider ? await opts.valider(retour, donneesSaisie, donneesRetour, corriger) : retour;
150
-
151
- },
152
- })
153
-
154
- /*----------------------------------
155
- - NOMBRES
156
- ----------------------------------*/
157
- // On ne spread pas min et max afin quils soient passés dans les props du composant
158
- const nombre = (float: boolean) => ({ ...opts }: TSchemaChamp<number> & {} = {}) => champ<number>('nombre', {
159
- // Force une valeur par défaut si requis
160
- defaut: opts.opt ? undefined : (opts.min || 0),
161
- rendu: NumberInput,
162
- ...opts,
163
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees, corriger?: boolean) => {
164
-
165
- // Vérifications suivantes inutiles si des valeurs spécifiques ont été fournies
166
- if (opts.in === undefined) {
167
-
168
- // Tente conversion chaine en nombre
169
- if (typeof val === 'string')
170
- val = float ? parseFloat(val) : parseInt(val);
171
-
172
- if (opts.min === undefined)
173
- opts.min = 0;
174
-
175
- // Type de donnée
176
- if (Number.isNaN(val) || typeof val !== 'number') {
177
- if (corriger)
178
- val = opts.min;
179
- else
180
- throw new InputError("This value must be a number.");
181
- }
182
-
183
- // Minimum
184
- if (val < opts.min)
185
- if (corriger)
186
- val = opts.min;
187
- else
188
- throw new InputError(`Must be at least ` + opts.min);
189
-
190
- // Maximum
191
- if (opts.max !== undefined && val > opts.max)
192
- if (corriger)
193
- val = opts.max;
194
- else
195
- throw new InputError(`Must be up to ` + opts.max);
196
-
197
- }
198
-
199
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour, corriger) : val;
200
- },
201
- })
202
-
203
- export const int = nombre(false);
204
-
205
- export const float = nombre(true);
206
-
207
- export const bool = (opts: TSchemaChamp<boolean> & {} = {}) => champ<boolean>('bool', {
208
- defaut: false,
209
- ...opts,
210
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
211
-
212
- if (typeof val !== 'boolean' && !['true', 'false'].includes(val))
213
- throw new InputError("This value must be a boolean.");
214
-
215
- val = !!val;
216
-
217
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
218
-
219
- },
220
- })
221
-
222
- /*----------------------------------
223
- - AUTRES
224
- ----------------------------------*/
225
- export const date = (opts: TSchemaChamp<Date> & {} = {}) => champ<Date>('date', {
226
- //defaut: new Date,
227
- ...opts,
228
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees): Promise<Date> => {
229
-
230
- const chaine = typeof val == 'string';
231
-
232
- // Chaine = format iso
233
- if (chaine) {
234
-
235
- if (!isISO8601(val))
236
- throw new InputError("This value must be a date.");
237
-
238
- val = toDate(val);
239
-
240
- } else if (!(val instanceof Date))
241
- throw new InputError("This value must be a date.");
242
-
243
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
244
-
245
- },
246
- })
247
-
248
- /*----------------------------------
249
- - FICHIER
250
- ----------------------------------*/
251
- export type TOptsValidateurFichier = TSchemaChamp<object> & {
252
- type?: (keyof typeof raccourcisMime) | string[], // Raccourci, ou liste de mimetype
253
- taille?: number
254
- }
255
- const raccourcisMime = {
256
- image: ['image/jpeg', 'image/png']
257
- }
258
- export const validateurFichier = async (
259
- { type, taille, ...opts }: TOptsValidateurFichier = {},
260
- val: any,
261
- donneesSaisie: TObjetDonnees,
262
- donneesRetour: TObjetDonnees
263
- ): Promise<File | undefined> => {
264
-
265
- console.log('VALIDER FICHIER', type, val);
266
-
267
- if (!(val instanceof NormalizedFile))
268
- throw new InputError(`Must be a File (${typeof val} received)`);
269
-
270
- // MIME
271
- if (type !== undefined) {
272
-
273
- let mimetypes: string[];
274
-
275
- // Raccourcis
276
- if (typeof type === 'string') {
277
- if (type in raccourcisMime)
278
- mimetypes = raccourcisMime[type as keyof typeof raccourcisMime]
279
- else
280
- throw new Error(`Aucune liste de mimetype référencée pour le type de fichier « ${type} »`);
281
- } else
282
- mimetypes = type;
283
-
284
- // Vérification
285
- const mimeFichier = val.type;
286
- if (!mimetypes.includes(mimeFichier))
287
- throw new InputError('Only the following formats are allowed: ' + mimetypes.join(', ') + '. The file you gave is ' + mimeFichier + '.');
288
-
289
- }
290
-
291
- // Taille
292
- if (taille) {
293
- const tailleFichier = val.size / 1024 / 1024; // Mo
294
- if (tailleFichier > taille)
295
- throw new InputError(`Le fichier ne doit pas faire plus de ${taille} Mo (taille reçue: ${tailleFichier} Mo)`);
296
- }
297
-
298
- return opts.valider ? await opts.valider(val, donneesSaisie, donneesRetour) : val;
299
- }
@@ -1,63 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Libs
6
- import { InputError } from '@common/errors';
7
- import * as basicValidators from './basic';
8
-
9
- // Components
10
- import Input from '@client/components/input';
11
-
12
- /*----------------------------------
13
- - TYPES
14
- ----------------------------------*/
15
-
16
- import { TSchemaChampComplet, TSchema } from '../validate';
17
-
18
- export const EXCLURE_VALEUR = "action:exclure";
19
-
20
- /*----------------------------------
21
- - VALIDATION DE BASE
22
- ----------------------------------*/
23
- // Remplace un simple !val, qui compterait un zéro comme une valeur vide
24
- export const valeurVide = (val: any) => val === undefined || val === '' || val === null;
25
-
26
- export const champ = <TValeur>(
27
- type: string,
28
- opts: Omit<TSchemaChampComplet<TValeur>, 'type'>
29
- ): TSchemaChampComplet<TValeur> => {
30
- return {
31
- ...opts,
32
- type: type,
33
- rendu: Input,
34
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees, valider?: boolean) => {
35
-
36
- if (valeurVide(val)) {
37
- // Optionnel, on skip
38
- if (opts.opt === true)
39
- return undefined;
40
- // Requis
41
- else
42
- throw new InputError("Please enter a value");
43
- }
44
-
45
- if (opts.valider !== undefined)
46
- val = await opts.valider(val, donneesSaisie, donneesRetour, valider);
47
-
48
- // La valeur ayant passé les étapes de validation
49
- // On considère que son type correspond aintenant à celui attendu
50
- return val as TValeur | undefined;
51
- },
52
- };
53
- }
54
-
55
- export default (validators) => ({
56
-
57
- ...basicValidators,
58
-
59
- ...validators,
60
-
61
- new: <TSchemaA extends TSchema>(schema: TSchemaA): TSchemaA => schema,
62
-
63
- })
@@ -1,83 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Core
6
- import Response, { TResponseData } from './response';
7
- import PageResponse from './response/page';
8
- import { TRoute } from '.';
9
- import type { HttpMethod } from "@server/services/router";
10
-
11
- /*----------------------------------
12
- - TYPES
13
- ----------------------------------*/
14
-
15
- // Modeles
16
- import type { User } from '@models';
17
-
18
- export type TFetcherList = { [id: string]: TFetcher }
19
-
20
- export type TFetcher<TData extends unknown = unknown> = {
21
-
22
- // For async calls: api.post(...).then((data) => ...)
23
- then: (callback: (data: TData) => void) => Promise<TData>,
24
- run: () => Promise<TData>,
25
-
26
- method: HttpMethod,
27
- path: string,
28
- data?: object,
29
- options?: TApiFetchOptions
30
- }
31
-
32
- export type TFetcherArgs = [
33
- method: HttpMethod,
34
- path: string,
35
- data?: object,
36
- options?: TApiFetchOptions
37
- ]
38
-
39
- export type TApiFetchOptions = {
40
- captcha?: string, // Action id (required by recaptcha)
41
- onProgress?: (percent: number) => void
42
- }
43
-
44
- /*----------------------------------
45
- - CONTEXT
46
- ----------------------------------*/
47
- export default abstract class BaseRequest {
48
-
49
- // Permet d'accèder à l'instance complète via spread
50
- public request: this = this;
51
- public host!: string;
52
-
53
- public data: TObjetDonnees = {};
54
- public abstract response?: Response;
55
- public user: User | null = null;
56
-
57
- public constructor(
58
- public path: string,
59
- ) {
60
-
61
- }
62
-
63
- public api = {
64
- get: <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
65
- this.createFetcher<TData>('GET', path, data, opts),
66
-
67
- post: <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
68
- this.createFetcher<TData>('POST', path, data, opts),
69
-
70
- put: <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
71
- this.createFetcher<TData>('PUT', path, data, opts),
72
-
73
- delete: <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
74
- this.createFetcher<TData>('DELETE', path, data, opts),
75
- }
76
-
77
- public abstract createFetcher<TData extends unknown = unknown>(...args: TFetcherArgs): TFetcher<TData>;
78
-
79
- public abstract fetchSync(fetchers: TFetcherList): Promise<TObjetDonnees>;
80
-
81
- public abstract fetchAsync(...args: TFetcherArgs): Promise<any>;
82
-
83
- }
@@ -1,119 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import { Logger } from "tslog";
7
- import axios, { AxiosResponse, AxiosRequestConfig, AxiosError } from 'axios';
8
- import httpAdapter from 'axios/lib/adapters/http';
9
-
10
- // Libs
11
- import Cache from '@server/data/Cache';
12
-
13
- /*----------------------------------
14
- - TYPES
15
- ----------------------------------*/
16
- declare module 'axios' {
17
- export interface AxiosRequestConfig {
18
- fallback?: string; // ID donnée cache
19
- cache?: string; // ID donnée cache
20
- cacheExpiration?: number | Date | null,
21
- retry?: number;
22
- debug?: boolean
23
- }
24
- }
25
-
26
- const debug = false;
27
-
28
- /*----------------------------------
29
- - MODULE
30
- ----------------------------------*/
31
- // FIX: On créé une nouvelle instance d'axios ici, car si on utilise l'instance globale,
32
- // Les intercepteurs seront empilés à la suite à chaque reload HMR
33
- export default axios.create({
34
- timeout: process.env.environnement === 'local'
35
- ? 10000 // Connexion pourrie à la maison
36
- : 5000,
37
- validateStatus: function (status: number) {
38
- return status >= 200 && status < 300;
39
- },
40
- adapter: async (config: AxiosRequestConfig) => {
41
-
42
- //const logger = new Logger({ prefix: [config.url] });
43
-
44
- console.log(`Création de la requête`, { params: config.params, data: config.data });
45
-
46
- const envoyer = (tentative: number = 1) => httpAdapter(config).then(async (res: AxiosResponse) => {
47
-
48
- console.log(`Status:`, res.status ,`Reponse:`, typeof res.data);
49
-
50
- // Mise en cache
51
- const cacheId: string | undefined = config.fallback || config.cache;
52
- if (cacheId !== undefined) {
53
- console.log(`Enregistrement de la réponse dans le cache (ID: ${cacheId})`);
54
- await Cache.set(cacheId, res.data, config.cacheExpiration);
55
- }
56
-
57
- return res;
58
-
59
- }).catch(async (err: AxiosError) => {
60
-
61
- // err peut être une simple instance d'Error
62
-
63
- console.error("Error during API request:", {
64
- method: config.method,
65
- url: config.url,
66
- body: config.data,
67
- headers: config.headers,
68
- });
69
-
70
- if (err.isAxiosError && err.response) {
71
- console.error("Response:", {
72
- status: err.response.status + ' ' + err.response.statusText,
73
- headers: err.response.headers,
74
- body: err.response.data
75
- });
76
- }
77
-
78
- throw err;
79
-
80
- // Nouvelle tentative
81
- if (
82
- config.retry !== undefined && tentative < config.retry
83
- &&
84
- err.response !== undefined && err.response.status >= 400
85
- ) {
86
- console.log(`Tentative n°` + (tentative + 1));
87
- return await envoyer(tentative + 1);
88
- }
89
-
90
- // Fallback via cache
91
- const fallback = config.fallback === undefined
92
- ? undefined
93
- : await Cache.get(config.fallback)
94
-
95
- // Aucun fallback = impossible de continuer
96
- if (!err) {
97
- console.log(`Aucun fallback disponible, on fait remonter l'erreur.`);
98
- throw err;
99
- } else
100
- console.log(`Utilisation des données en fallback via le cache (ID: ${config.fallback})`/*, fallback*/);
101
-
102
- return {
103
- data: fallback,
104
- status: 200,
105
- statusText: 'OK',
106
- headers: {},
107
- config: config,
108
- request: err.request
109
- }
110
-
111
-
112
- })
113
-
114
- return config.cache === undefined
115
- ? await envoyer()
116
- : await Cache.get(config.cache, () => envoyer(), config.cacheExpiration);
117
-
118
- }
119
- })
@@ -1,41 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Libs métier
6
- import buildValidators, { EXCLURE_VALEUR, champ } from '@common/data/input/validators/build';
7
- import { validateurFichier, TOptsValidateurFichier } from '@common/data/input/validators/basic';
8
-
9
- /*----------------------------------
10
- - VALIDATEURS
11
- ----------------------------------*/
12
- export default buildValidators({
13
-
14
- file: ({ ...opts }: TOptsValidateurFichier & {}) => champ<object>('fichier', {
15
- ...opts,
16
- valider: async (val: any, donneesSaisie: TObjetDonnees, donneesRetour: TObjetDonnees) => {
17
-
18
- // Chaine = url ancien fichier = exclusion de la valeur pour conserver l'ancien fichier
19
- // NOTE: Si la valeur est présente mais undefined, alors on supprimera le fichier
20
- if (typeof val === 'string')
21
- return EXCLURE_VALEUR;
22
-
23
- // Validation universelle
24
- const fichier = await validateurFichier(opts, val, donneesSaisie, donneesRetour);
25
-
26
- if (fichier === undefined)
27
- return fichier;
28
-
29
-
30
- // Résolution image
31
- if (opts.sharp !== undefined) {
32
-
33
-
34
-
35
- }
36
-
37
- return opts.valider ? await opts.valider(fichier, donneesSaisie, donneesRetour) : fichier;
38
- }
39
- })
40
-
41
- });
@@ -1,41 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import React from 'react';
7
-
8
- // Core
9
- import app, { services } from '@server/app';
10
-
11
- /*----------------------------------
12
- - COMPOSANT
13
- ----------------------------------*/
14
- export default () => {
15
-
16
- const routesForClient = JSON.stringify(services.router.ssrRoutes);
17
- return (
18
- <html lang="en">
19
- <head>
20
- {/* Format */}
21
- <meta charSet="utf-8" />
22
- <meta name="viewport" content="width=device-width,minimum-scale=1,initial-scale=1" />
23
-
24
- {/* CSS */}
25
- <link rel="stylesheet" type="text/css" href="/public/icons.css" />
26
- <link rel="preload" href="/public/client.css" as="style" />
27
- <link rel="stylesheet" type="text/css" href="/public/client.css" />
28
-
29
- {/* JS */}
30
- <script type="text/javascript" dangerouslySetInnerHTML={{
31
- __html: `window.routes=${routesForClient};` + (app.env.profile === 'dev' ? 'window.dev = true;' : '')
32
- }} />
33
- <link rel="preload" href="/public/client.js" as="script" />
34
- <script defer type="text/javascript" src="/public/client.js" />
35
-
36
- </head>
37
- <body></body>
38
- </html>
39
- );
40
-
41
- }