5htp-core 0.1.2 → 0.2.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/changelog.md +5 -0
- package/doc/TODO.md +71 -0
- package/package.json +5 -4
- package/src/client/{App.tsx → app/component.tsx} +15 -11
- package/src/client/app/index.ts +128 -0
- package/src/client/app/service.ts +34 -0
- package/src/client/app.tsconfig.json +0 -4
- package/src/client/assets/css/components.less +52 -0
- package/src/client/assets/css/core.less +7 -28
- package/src/client/assets/css/theme.less +1 -1
- package/src/client/assets/css/{borders.less → utils/borders.less} +0 -0
- package/src/client/assets/css/{layouts.less → utils/layouts.less} +0 -0
- package/src/client/assets/css/{medias.less → utils/medias.less} +14 -1
- package/src/client/assets/css/{sizing.less → utils/sizing.less} +0 -0
- package/src/client/assets/css/{spacing.less → utils/spacing.less} +0 -0
- package/src/client/components/Card/index.tsx +13 -7
- package/src/client/components/Dialog/Manager.tsx +41 -14
- package/src/client/components/Dialog/index.less +2 -4
- package/src/client/components/Form/index.tsx +1 -1
- package/src/client/components/Row/index.less +0 -2
- package/src/client/components/Table/index.tsx +3 -2
- package/src/client/components/button.tsx +2 -2
- package/src/client/components/containers/Popover/index.tsx +1 -1
- package/src/client/components/containers/champs.less +0 -2
- package/src/client/components/data/spintext/index.tsx +1 -1
- package/src/client/components/dropdown/index.tsx +1 -1
- package/src/client/components/index.ts +23 -0
- package/src/client/components/input/BaseV2/index.less +0 -2
- package/src/client/components/input/BaseV2/index.tsx +1 -1
- package/src/client/components/input/Date/index.less +0 -2
- package/src/client/components/input/Periode/index.less +0 -2
- package/src/client/components/input/Radio/index.less +0 -2
- package/src/client/components/input/UploadImage/index.less +0 -2
- package/src/client/components/input/UploadImage/index.tsx +1 -1
- package/src/client/hooks/index.ts +5 -0
- package/src/client/hooks/useState/index.tsx +2 -2
- package/src/client/hooks.ts +22 -0
- package/src/client/index.ts +5 -0
- package/src/client/pages/_layout/landing/index.tsx +0 -2
- package/src/client/pages/_messages/400.tsx +2 -2
- package/src/client/pages/_messages/401.tsx +2 -2
- package/src/client/pages/_messages/403.tsx +2 -2
- package/src/client/pages/_messages/404.tsx +2 -2
- package/src/client/pages/_messages/500.tsx +2 -2
- package/src/client/pages/bug.tsx +1 -1
- package/src/client/pages/useHeader.tsx +1 -1
- package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
- package/src/client/services/metrics/index.ts +37 -0
- package/src/client/{router → services/router/components}/Link.tsx +1 -1
- package/src/client/services/router/components/Page.tsx +59 -0
- package/src/client/{router/component.tsx → services/router/components/router.tsx} +52 -74
- package/src/client/services/router/index.tsx +453 -0
- package/src/client/services/router/request/api.ts +227 -0
- package/src/client/{router → services/router}/request/history.ts +0 -0
- package/src/client/services/router/request/index.ts +52 -0
- package/src/client/services/router/response/index.tsx +107 -0
- package/src/client/services/router/response/page.ts +90 -0
- package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
- package/src/client/utils/dom.ts +1 -1
- package/src/common/app/index.ts +9 -0
- package/src/common/data/chaines/index.ts +9 -6
- package/src/common/data/input/validate.ts +3 -166
- package/src/common/data/objets.ts +25 -0
- package/src/common/data/tableaux.ts +8 -0
- package/src/common/errors/index.ts +3 -1
- package/src/common/router/index.ts +67 -88
- package/src/common/router/layouts.ts +50 -0
- package/src/common/router/register.ts +62 -0
- package/src/common/router/request/api.ts +72 -0
- package/src/common/router/request/index.ts +31 -0
- package/src/common/router/{response.ts → response/index.ts} +9 -13
- package/src/common/router/response/page.ts +46 -54
- package/src/common/validation/index.ts +3 -0
- package/src/common/validation/schema.ts +185 -0
- package/src/common/validation/validator.ts +95 -0
- package/src/common/validation/validators.ts +313 -0
- package/src/server/app/config.ts +9 -27
- package/src/server/app/index.ts +81 -124
- package/src/server/app/service.ts +98 -0
- package/src/server/app.tsconfig.json +0 -8
- package/src/server/index.ts +5 -0
- package/src/server/patch.ts +0 -6
- package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
- package/src/server/services/console/bugReporter.ts +26 -16
- package/src/server/services/console/index.ts +59 -51
- package/src/server/services/cron/index.ts +12 -26
- package/src/server/services/database/bucket.ts +40 -0
- package/src/server/services/database/connection.ts +213 -80
- package/src/server/services/database/datatypes.ts +63 -40
- package/src/server/services/database/debug.ts +20 -0
- package/src/server/services/database/index.ts +295 -272
- package/src/server/services/database/metas.ts +246 -135
- package/src/server/services/database/stats.ts +151 -126
- package/src/server/services/email/index.ts +30 -62
- package/src/server/services/email/transporter.ts +38 -0
- package/src/server/services/{router/request/services → metrics}/detect.ts +8 -10
- package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
- package/src/server/services/{http → router/http}/index.ts +28 -70
- package/src/server/services/{http → router/http}/multipart.ts +0 -0
- package/src/server/services/{http → router/http}/session.ts.old +0 -0
- package/src/server/services/router/index.ts +273 -202
- package/src/server/services/router/request/api.ts +76 -0
- package/src/server/services/router/request/index.ts +16 -97
- package/src/server/services/router/request/service.ts +21 -0
- package/src/server/services/router/response/index.ts +131 -65
- package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
- package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
- package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
- package/src/server/services/router/response/page/document.tsx +194 -0
- package/src/server/services/router/response/page/index.tsx +157 -0
- package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
- package/src/server/services/router/service.ts +48 -0
- package/src/server/services/schema/index.ts +47 -0
- package/src/server/services/schema/request.ts +55 -0
- package/src/server/services/schema/router.ts +33 -0
- package/src/server/services/socket/index.ts +38 -43
- package/src/server/services/socket/scope.ts +6 -4
- package/src/server/services/users/index.ts +203 -0
- package/src/server/services/{auth/base.ts → users/old.ts} +28 -112
- package/src/server/services/users/router/index.ts +72 -0
- package/src/server/services/users/router/request.ts +49 -0
- package/src/server/{data → services_old}/SocketClient.ts +0 -0
- package/src/server/{data/Token.olg.ts → services_old/Token.old.ts} +0 -0
- package/src/server/{data → services_old}/aes.ts +0 -0
- package/src/types/aliases.d.ts +43 -2
- package/templates/composant.tsx +1 -1
- package/templates/modal.tsx +1 -1
- package/templates/page.tsx +1 -1
- package/tsconfig.common.json +0 -4
- package/src/client/assets/css/components/components.less +0 -31
- package/src/client/context/api.ts +0 -92
- package/src/client/context/index.ts +0 -246
- package/src/client/index.tsx +0 -129
- package/src/client/router/index.ts +0 -286
- package/src/client/router/request/index.ts +0 -106
- package/src/client/router/response/index.ts +0 -38
- package/src/client/router/route.ts +0 -75
- package/src/common/data/input/validators/basic.ts +0 -299
- package/src/common/data/input/validators/build.ts +0 -63
- package/src/common/router/request.ts +0 -83
- package/src/server/data/ApiClient.ts +0 -119
- package/src/server/data/input.ts +0 -41
- package/src/server/libs/pages/document.static.tsx +0 -41
- package/src/server/libs/pages/document.tsx +0 -203
- package/src/server/libs/pages/render.tsx +0 -90
- package/src/server/routes/auth.ts +0 -151
- package/src/server/services/redis/index.ts +0 -71
- package/src/server/services/router/request/services/auth.ts +0 -177
|
@@ -6,30 +6,26 @@
|
|
|
6
6
|
import { FunctionalComponent } from "preact";
|
|
7
7
|
|
|
8
8
|
// Core
|
|
9
|
-
import { TRoute } from "
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import PageResponse from './response/page';
|
|
13
|
-
import { ClientContext } from '@client/context';
|
|
9
|
+
import { TRoute } from "..";
|
|
10
|
+
import type ClientRequest from '@client/services/router';
|
|
11
|
+
import Page from '@client/services/router/response/page'
|
|
14
12
|
|
|
15
13
|
/*----------------------------------
|
|
16
14
|
- TYPES
|
|
17
15
|
----------------------------------*/
|
|
18
16
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export type TResponseData = PageResponse | unknown
|
|
17
|
+
type TResponseData = Page
|
|
22
18
|
|
|
23
19
|
/*----------------------------------
|
|
24
20
|
- CONTEXT
|
|
25
21
|
----------------------------------*/
|
|
26
22
|
export default abstract class BaseResponse<
|
|
27
|
-
TData extends TResponseData =
|
|
28
|
-
TRequest extends
|
|
23
|
+
TData extends TResponseData = Page,
|
|
24
|
+
TRequest extends ClientRequest = ClientRequest
|
|
29
25
|
> {
|
|
30
26
|
|
|
31
|
-
public data?:
|
|
32
|
-
public request:
|
|
27
|
+
public data?: TData;
|
|
28
|
+
public request: TRequest;
|
|
33
29
|
public route?: TRoute;
|
|
34
30
|
|
|
35
31
|
public constructor(
|
|
@@ -37,7 +33,7 @@ export default abstract class BaseResponse<
|
|
|
37
33
|
) {
|
|
38
34
|
// ServerResponse et ClientResponse assignent request.response
|
|
39
35
|
request.response = this;
|
|
40
|
-
this.request = request as
|
|
36
|
+
this.request = request as TRequest;
|
|
41
37
|
}
|
|
42
38
|
|
|
43
39
|
public setRoute(route: TRoute) {
|
|
@@ -2,19 +2,38 @@
|
|
|
2
2
|
- DEPENDANCES
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
|
-
import type { ComponentChild } from 'preact';
|
|
5
|
+
import type { ComponentChild, FunctionComponent } from 'preact';
|
|
6
6
|
|
|
7
7
|
// Core libs
|
|
8
|
-
import {
|
|
9
|
-
import { TFetcherList } from '@common/router/request';
|
|
10
|
-
import { history } from '@client/router/request/history';
|
|
11
|
-
import { ClientContext } from '@client/context';
|
|
8
|
+
import { ClientOrServerRouter, TClientOrServerContext } from '@common/router';
|
|
9
|
+
import { TFetcherList, TDataReturnedByFetchers } from '@common/router/request/api';
|
|
10
|
+
import { history } from '@client/services/router/request/history';
|
|
12
11
|
|
|
13
12
|
/*----------------------------------
|
|
14
13
|
- TYPES
|
|
15
14
|
----------------------------------*/
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
// The function that fetch data from the api before to pass them as context to the renderer
|
|
17
|
+
export type TDataProvider<TProvidedData extends TFetcherList = {}> =
|
|
18
|
+
(context: TClientOrServerContext/* & TUrlData */) => TProvidedData
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
// The function that renders routes
|
|
23
|
+
export type TFrontRenderer<
|
|
24
|
+
TProvidedData extends TFetcherList = {},
|
|
25
|
+
TAdditionnalData = {},
|
|
26
|
+
TRouter = ClientOrServerRouter,
|
|
27
|
+
> = FunctionComponent<(
|
|
28
|
+
TClientOrServerContext
|
|
29
|
+
&
|
|
30
|
+
TDataReturnedByFetchers<TProvidedData>
|
|
31
|
+
&
|
|
32
|
+
TAdditionnalData
|
|
33
|
+
)>;
|
|
34
|
+
|
|
35
|
+
// Script or CSS resource
|
|
36
|
+
export type TPageResource = {
|
|
18
37
|
id: string,
|
|
19
38
|
attrs?: TObjetDonnees
|
|
20
39
|
} & ({
|
|
@@ -27,70 +46,43 @@ type TResource = {
|
|
|
27
46
|
/*----------------------------------
|
|
28
47
|
- CLASS
|
|
29
48
|
----------------------------------*/
|
|
30
|
-
export default class PageResponse {
|
|
31
|
-
|
|
32
|
-
// Render
|
|
33
|
-
public id: string;
|
|
34
|
-
public data: TObjetDonnees = {};
|
|
35
|
-
public loading: ComponentChild = false;
|
|
36
|
-
public component: TFrontRenderer;
|
|
49
|
+
export default class PageResponse<TRouter extends ClientOrServerRouter = ClientOrServerRouter> {
|
|
37
50
|
|
|
38
51
|
// Metadata
|
|
52
|
+
public chunkId: string;
|
|
39
53
|
public title?: string;
|
|
40
54
|
public description?: string;
|
|
41
55
|
public bodyClass: Set<string> = new Set<string>();
|
|
42
56
|
public bodyId?: string;
|
|
43
57
|
|
|
44
|
-
//
|
|
58
|
+
// Resources
|
|
45
59
|
public amp?: boolean;
|
|
46
|
-
public scripts:
|
|
47
|
-
public style:
|
|
48
|
-
|
|
49
|
-
// State
|
|
50
|
-
public hash?: string; // Element id to scroll to
|
|
51
|
-
|
|
52
|
-
public constructor(
|
|
53
|
-
public context: ClientContext,
|
|
54
|
-
public route: TClientRoute,
|
|
55
|
-
data: TObjetDonnees = {},
|
|
56
|
-
) {
|
|
57
|
-
this.id = route.options.id; // Binded by the pages babel plugin
|
|
58
|
-
this.bodyId = route.options.bodyId;
|
|
59
|
-
this.component = route.renderer;
|
|
60
|
-
this.data = data;
|
|
61
|
-
this.hash = context.request.hash;
|
|
62
|
-
}
|
|
60
|
+
public scripts: TPageResource[] = [];
|
|
61
|
+
public style: TPageResource[] = [];
|
|
63
62
|
|
|
64
|
-
//
|
|
63
|
+
// Data
|
|
65
64
|
public fetchers: TFetcherList = {};
|
|
65
|
+
public data: TObjetDonnees = {};
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
public constructor(
|
|
68
|
+
public dataProvider: TDataProvider | null,
|
|
69
|
+
public renderer: TFrontRenderer,
|
|
70
|
+
public context: TClientOrServerContext
|
|
71
|
+
) {
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
document.body.className = [...this.bodyClass].join(' ');
|
|
73
|
-
|
|
73
|
+
this.chunkId = context.route.options["id"];
|
|
74
|
+
|
|
74
75
|
}
|
|
75
76
|
|
|
76
|
-
|
|
77
77
|
public async fetchData() {
|
|
78
|
-
this.isDataLoaded = true;
|
|
79
|
-
this.data = await this.context.request.fetchSync(this.fetchers);
|
|
80
|
-
return this.data;
|
|
81
|
-
}
|
|
82
78
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
public setData( key: string, value: ((value: any) => void) | any ) {
|
|
87
|
-
this.setAllData(old => ({
|
|
88
|
-
...old,
|
|
89
|
-
[key]: typeof value === 'function' ? value(old[key]) : value
|
|
90
|
-
}));
|
|
91
|
-
}
|
|
79
|
+
// Load the fetchers list to load data if needed
|
|
80
|
+
if (this.dataProvider)
|
|
81
|
+
this.fetchers = this.dataProvider({ ...this.context, ...this.context.request.data });
|
|
92
82
|
|
|
93
|
-
|
|
94
|
-
|
|
83
|
+
// Execute the fetchers for missing data
|
|
84
|
+
console.log(`[router][page] Fetching api data:` + Object.keys(this.fetchers));
|
|
85
|
+
this.data = await this.context.request.api.fetchSync( this.fetchers, this.data );
|
|
86
|
+
return this.data;
|
|
95
87
|
}
|
|
96
88
|
}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Core
|
|
6
|
+
import { Erreur, TListeErreursSaisie, InputErrorSchema } from '@common/errors';
|
|
7
|
+
|
|
8
|
+
// Specific
|
|
9
|
+
import { default as Validator, EXCLUDE_VALUE } from './validator';
|
|
10
|
+
|
|
11
|
+
/*----------------------------------
|
|
12
|
+
- TYPES
|
|
13
|
+
----------------------------------*/
|
|
14
|
+
|
|
15
|
+
export type TSchemaFields = { [fieldName: string]: Schema<{}> | Validator<any> }
|
|
16
|
+
|
|
17
|
+
type TOptsValider = {
|
|
18
|
+
critique?: boolean,
|
|
19
|
+
validationComplete?: boolean,
|
|
20
|
+
avecDependances?: boolean,
|
|
21
|
+
corriger?: boolean,
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export type TValidationResult<TFields extends TSchemaFields> = {
|
|
25
|
+
values: TValidatedData<TFields>,
|
|
26
|
+
nbErreurs: number,
|
|
27
|
+
erreurs: TListeErreursSaisie
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type TValidatedData<TFields extends TSchemaFields> = {
|
|
31
|
+
// For each field, the values returned by validator.validate()
|
|
32
|
+
[name in keyof TFields]: ReturnType<TFields[name]["validate"]>
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/*----------------------------------
|
|
36
|
+
- CONST
|
|
37
|
+
----------------------------------*/
|
|
38
|
+
|
|
39
|
+
const debug = true;
|
|
40
|
+
|
|
41
|
+
const LogPrefix = '[schema][validator]';
|
|
42
|
+
|
|
43
|
+
/*----------------------------------
|
|
44
|
+
- CLASS
|
|
45
|
+
----------------------------------*/
|
|
46
|
+
export default class Schema<TFields extends TSchemaFields> {
|
|
47
|
+
|
|
48
|
+
public constructor(
|
|
49
|
+
public fields: TFields
|
|
50
|
+
) {
|
|
51
|
+
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public validate<TDonnees extends TObjetDonnees>(
|
|
55
|
+
|
|
56
|
+
dataToValidate: Partial<TDonnees>,
|
|
57
|
+
allData: TDonnees,
|
|
58
|
+
output: TObjetDonnees = {},
|
|
59
|
+
|
|
60
|
+
opts: TOptsValider = {},
|
|
61
|
+
chemin: string[] = []
|
|
62
|
+
|
|
63
|
+
): TValidationResult<TFields> {
|
|
64
|
+
|
|
65
|
+
opts = {
|
|
66
|
+
critique: false,
|
|
67
|
+
validationComplete: false,
|
|
68
|
+
avecDependances: true,
|
|
69
|
+
corriger: false,
|
|
70
|
+
...opts,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const clesAvalider = Object.keys(opts.validationComplete === true ? this.fields : dataToValidate);
|
|
74
|
+
|
|
75
|
+
let outputSchema = output;
|
|
76
|
+
for (const branche of chemin)
|
|
77
|
+
outputSchema = outputSchema[branche];
|
|
78
|
+
|
|
79
|
+
// Validation de chacune d'entre elles
|
|
80
|
+
let erreurs: TListeErreursSaisie = {};
|
|
81
|
+
let nbErreurs = 0;
|
|
82
|
+
for (const champ of clesAvalider) {
|
|
83
|
+
|
|
84
|
+
// La donnée est répertoriée dans le schema
|
|
85
|
+
const field = this.fields[champ];
|
|
86
|
+
if (field === undefined) {
|
|
87
|
+
debug && console.warn(LogPrefix, '[' + champ + ']', 'Exclusion (pas présent dans le schéma)');
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const cheminA = [...chemin, champ]
|
|
92
|
+
const cheminAstr = cheminA.join('.')
|
|
93
|
+
|
|
94
|
+
// Sous-schema
|
|
95
|
+
if (field instanceof Schema) {
|
|
96
|
+
|
|
97
|
+
// Initialise la structure pour permettre l'assignement d'outputSchema
|
|
98
|
+
if (outputSchema[champ] === undefined)
|
|
99
|
+
outputSchema[champ] = {}
|
|
100
|
+
|
|
101
|
+
// The corresponding data should be an object
|
|
102
|
+
const schemadata = dataToValidate[champ];
|
|
103
|
+
if (typeof schemadata !== 'object') {
|
|
104
|
+
erreurs[ cheminAstr ] = [`Should be an object`];
|
|
105
|
+
nbErreurs++;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Validate the data
|
|
110
|
+
const validationSchema = field.validate(
|
|
111
|
+
|
|
112
|
+
schemadata,
|
|
113
|
+
allData,
|
|
114
|
+
output,
|
|
115
|
+
|
|
116
|
+
opts,
|
|
117
|
+
cheminA
|
|
118
|
+
);
|
|
119
|
+
erreurs = { ...erreurs, ...validationSchema.erreurs };
|
|
120
|
+
nbErreurs += validationSchema.nbErreurs;
|
|
121
|
+
|
|
122
|
+
// Pas besoin d'assigner, car output est passé en référence
|
|
123
|
+
//output[champ] = validationSchema.values;
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
// I don't remind what is options.activer about
|
|
127
|
+
/*} else if (field.activer !== undefined && field.activer(allData) === false) {
|
|
128
|
+
|
|
129
|
+
delete outputSchema[champ];*/
|
|
130
|
+
|
|
131
|
+
// Validator
|
|
132
|
+
} else {
|
|
133
|
+
|
|
134
|
+
// Champ composé de plusieurs values
|
|
135
|
+
const valOrigine = field.options.as === undefined
|
|
136
|
+
? dataToValidate[champ]
|
|
137
|
+
// Le champ regroupe plusieurs values (ex: Periode)
|
|
138
|
+
: field.options.as.map((nomVal: string) => dataToValidate[nomVal])
|
|
139
|
+
|
|
140
|
+
// Validation
|
|
141
|
+
try {
|
|
142
|
+
|
|
143
|
+
const val = field.validate(valOrigine, allData, output, opts.corriger);
|
|
144
|
+
|
|
145
|
+
// Exclusion seulement si explicitement demandé
|
|
146
|
+
// IMPORTANT: Conserver les values undefined
|
|
147
|
+
// La présence d'un valeur undefined peut être utile, par exemple, pour indiquer qu'on souhaite supprimer une donnée
|
|
148
|
+
// Exemple: undefinec = suppression fichier | Absende donnée = conservation fihcier actuel
|
|
149
|
+
if (val === EXCLUDE_VALUE)
|
|
150
|
+
debug && console.log(LogPrefix, '[' + cheminA + '] Exclusion demandée');
|
|
151
|
+
else
|
|
152
|
+
outputSchema[champ] = val;
|
|
153
|
+
|
|
154
|
+
debug && console.log(LogPrefix, '[' + cheminA + ']', valOrigine, '=>', val);
|
|
155
|
+
|
|
156
|
+
} catch (error) {
|
|
157
|
+
|
|
158
|
+
debug && console.warn(LogPrefix, '[' + cheminA + ']', valOrigine, '|| Erreur:', error);
|
|
159
|
+
|
|
160
|
+
if (error instanceof Erreur) {
|
|
161
|
+
|
|
162
|
+
// Référencement erreur
|
|
163
|
+
erreurs[cheminAstr] = [error.message]
|
|
164
|
+
nbErreurs++;
|
|
165
|
+
|
|
166
|
+
} else
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
if (nbErreurs !== 0 && opts.critique === true) {
|
|
173
|
+
throw new InputErrorSchema(erreurs);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
debug && console.log(LogPrefix, '', dataToValidate, '=>', output);
|
|
177
|
+
|
|
178
|
+
return {
|
|
179
|
+
values: output as TValidatedData<TFields>,
|
|
180
|
+
erreurs,
|
|
181
|
+
nbErreurs,
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import type { ComponentChild } from 'preact'
|
|
7
|
+
|
|
8
|
+
// Core
|
|
9
|
+
import { InputError } from '@common/errors';
|
|
10
|
+
|
|
11
|
+
/*----------------------------------
|
|
12
|
+
- TYPES
|
|
13
|
+
----------------------------------*/
|
|
14
|
+
|
|
15
|
+
export type TValidator<TValue> = {
|
|
16
|
+
|
|
17
|
+
rendu?: TFieldRenderer,
|
|
18
|
+
|
|
19
|
+
// I don't remind what is options.activer about
|
|
20
|
+
activer?: (donnees: TObjetDonnees) => boolean,
|
|
21
|
+
onglet?: string, // Sert juste d'identifiant secondaire. Ex: nom onglet correspondant
|
|
22
|
+
|
|
23
|
+
// Restrict to a specific set of values
|
|
24
|
+
in?: TValue[],
|
|
25
|
+
|
|
26
|
+
// Executé après le validateur propre au type
|
|
27
|
+
dependances?: string[],
|
|
28
|
+
opt?: true,
|
|
29
|
+
defaut?: TValue,
|
|
30
|
+
as?: string[], // Mapping personnalisé
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export type TFieldRenderer = (props: any) => ComponentChild;
|
|
35
|
+
|
|
36
|
+
type TNonEmptyValue = Exclude<any, undefined | '' | null>
|
|
37
|
+
|
|
38
|
+
type TValidationArgs<TValue, TAllValues extends {}> = [
|
|
39
|
+
// For the value given as input in the validation function,
|
|
40
|
+
// Only the empty values were escluded
|
|
41
|
+
val: TNonEmptyValue,
|
|
42
|
+
input: TAllValues,
|
|
43
|
+
output: Partial<TAllValues>,
|
|
44
|
+
corriger?: boolean
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
type TValidationFunction<TValue, TAllValues extends {} = {}> = (
|
|
48
|
+
...args: TValidationArgs<TValue, TAllValues>
|
|
49
|
+
) => TValue | typeof EXCLUDE_VALUE;
|
|
50
|
+
|
|
51
|
+
type TValidateReturnType<
|
|
52
|
+
TOptions extends TValidator<TValue>,
|
|
53
|
+
TValue extends any
|
|
54
|
+
> = TOptions extends { opt: true }
|
|
55
|
+
? (undefined | TValue)
|
|
56
|
+
: TValue
|
|
57
|
+
|
|
58
|
+
/*----------------------------------
|
|
59
|
+
- CONST
|
|
60
|
+
----------------------------------*/
|
|
61
|
+
|
|
62
|
+
export const EXCLUDE_VALUE = "action:exclure" as const;
|
|
63
|
+
|
|
64
|
+
/*----------------------------------
|
|
65
|
+
- CLASS
|
|
66
|
+
----------------------------------*/
|
|
67
|
+
export default class Validator<TValue, TOptions extends TValidator<TValue> = TValidator<TValue>> {
|
|
68
|
+
|
|
69
|
+
public constructor(
|
|
70
|
+
public type: string,
|
|
71
|
+
public validateType: TValidationFunction<TValue>,
|
|
72
|
+
public options: TOptions
|
|
73
|
+
) {
|
|
74
|
+
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
public isEmpty = (val: any) => val === undefined || val === '' || val === null
|
|
78
|
+
|
|
79
|
+
public validate(...[ val, input, output, correct ]: TValidationArgs<TValue, {}>): TValidateReturnType<TOptions, TValue> {
|
|
80
|
+
|
|
81
|
+
// Required value
|
|
82
|
+
if (this.isEmpty(val)) {
|
|
83
|
+
// Optionnel, on skip
|
|
84
|
+
if (this.options.opt === true)
|
|
85
|
+
return undefined as TValidateReturnType<TOptions, TValue>;
|
|
86
|
+
// Requis
|
|
87
|
+
else
|
|
88
|
+
throw new InputError("Please enter a value");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Validate type
|
|
92
|
+
return this.validateType(val, input, output, correct) as TValidateReturnType<TOptions, TValue>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|