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.
- 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 -8
- 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/medias.less +14 -0
- package/src/client/components/Card/index.tsx +2 -2
- package/src/client/components/Dialog/Manager.tsx +39 -12
- package/src/client/components/Form/index.tsx +1 -1
- package/src/client/components/button.tsx +2 -2
- package/src/client/components/containers/Popover/index.tsx +1 -1
- 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 +8 -0
- package/src/client/components/input/BaseV2/index.tsx +1 -1
- 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} +43 -74
- package/src/client/services/router/index.tsx +448 -0
- package/src/client/services/router/request/api.ts +229 -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 +95 -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 +40 -56
- package/src/common/validation/index.ts +3 -0
- package/src/common/validation/schema.ts +184 -0
- package/src/common/validation/validator.ts +88 -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/error/index.ts +13 -0
- 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 +206 -75
- package/src/server/services/database/datatypes.ts +63 -40
- 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 +28 -52
- 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 -203
- package/src/server/services/router/request/api.ts +73 -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 +125 -64
- 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/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/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
package/tsconfig.common.json
CHANGED
|
@@ -26,14 +26,10 @@
|
|
|
26
26
|
"baseUrl": "./src",
|
|
27
27
|
"paths": {
|
|
28
28
|
|
|
29
|
-
"@root/*": ["./*"],
|
|
30
29
|
"@client/*": ["./client/*"],
|
|
31
30
|
"@common/*": ["./common/*"],
|
|
32
31
|
"@server/*": ["./server/*"],
|
|
33
32
|
|
|
34
|
-
"@errors": ["./common/errors"],
|
|
35
|
-
"@models": ["./common/models"],
|
|
36
|
-
|
|
37
33
|
"react": ["preact/compat"],
|
|
38
34
|
"react-dom": ["preact/compat"],
|
|
39
35
|
"react/jsx-runtime": ["preact/jsx-runtime"]
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// Npm
|
|
6
|
-
import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
|
|
7
|
-
|
|
8
|
-
// Core
|
|
9
|
-
import type { HttpMethod, TApiResponseData } from '@server/services/router';
|
|
10
|
-
import type { ClientContext } from '@client/context';
|
|
11
|
-
import { TFetcherArgs } from '@common/router/request';
|
|
12
|
-
import { instancierViaCode, NetworkError } from '@common/errors';
|
|
13
|
-
|
|
14
|
-
/*----------------------------------
|
|
15
|
-
- TYPES
|
|
16
|
-
----------------------------------*/
|
|
17
|
-
|
|
18
|
-
const debug = true;
|
|
19
|
-
|
|
20
|
-
/*----------------------------------
|
|
21
|
-
- FUNCTION
|
|
22
|
-
----------------------------------*/
|
|
23
|
-
const configure = (...[method, path, data, options]: TFetcherArgs): AxiosRequestConfig => {
|
|
24
|
-
|
|
25
|
-
const { onProgress, captcha } = options || {};
|
|
26
|
-
|
|
27
|
-
debug && console.log(`[api] Sending request`, method, path, data);
|
|
28
|
-
|
|
29
|
-
const config: AxiosRequestConfig = {
|
|
30
|
-
|
|
31
|
-
url: path,
|
|
32
|
-
method: method,
|
|
33
|
-
headers: {
|
|
34
|
-
'Content-Type': "application/json",
|
|
35
|
-
'Accept': "application/json",
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
validateStatus: function (status: number) {
|
|
39
|
-
return status === 200;
|
|
40
|
-
},
|
|
41
|
-
|
|
42
|
-
onUploadProgress: onProgress === undefined ? undefined : (e) => {
|
|
43
|
-
const percentCompleted = Math.round((e.loaded * 100) / e.total);
|
|
44
|
-
onProgress(percentCompleted);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
if (data) {
|
|
50
|
-
if (method === "GET")
|
|
51
|
-
config.params = data;
|
|
52
|
-
else {
|
|
53
|
-
config.data = data;
|
|
54
|
-
if (data instanceof FormData)
|
|
55
|
-
config.headers["Content-Type"] = 'multipart/form-data';
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return config;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
export default (context: ClientContext, ...args: TFetcherArgs) => {
|
|
63
|
-
|
|
64
|
-
const config = configure(...args);
|
|
65
|
-
|
|
66
|
-
return axios.request(config)
|
|
67
|
-
.then((res: AxiosResponse<TApiResponseData>) => {
|
|
68
|
-
|
|
69
|
-
debug && console.log(`[api] Success:`, res);
|
|
70
|
-
return res.data;
|
|
71
|
-
|
|
72
|
-
})
|
|
73
|
-
.catch((e: AxiosError) => {
|
|
74
|
-
|
|
75
|
-
if (e.response !== undefined) {
|
|
76
|
-
|
|
77
|
-
console.warn(`[api] Failure:`, e);
|
|
78
|
-
throw instancierViaCode(
|
|
79
|
-
e.response.status || 500,
|
|
80
|
-
e.response.data
|
|
81
|
-
);
|
|
82
|
-
|
|
83
|
-
// Erreur réseau: l'utilisateur n'ets probablement plus connecté à internet
|
|
84
|
-
} else {
|
|
85
|
-
|
|
86
|
-
console.error(`[api] Network error:`, e, context);
|
|
87
|
-
context.toast.error("Please check your internet connection and try again.", undefined, null, { autohide: false });
|
|
88
|
-
throw new NetworkError(e.message);
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
}
|
|
@@ -1,246 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
|
|
5
|
-
// npm
|
|
6
|
-
import React from 'react';
|
|
7
|
-
import type { ComponentChild } from 'preact';
|
|
8
|
-
|
|
9
|
-
// Core
|
|
10
|
-
import { createDialog } from '@client/components/Dialog/Manager';
|
|
11
|
-
import BaseRequest from '@common/router/request';
|
|
12
|
-
import router, { TClientRoute } from '@client/router';
|
|
13
|
-
import PageResponse from '@common/router/response/page';
|
|
14
|
-
|
|
15
|
-
// Services
|
|
16
|
-
import Recaptcha from './captcha';
|
|
17
|
-
import SocketClient from './socket';
|
|
18
|
-
|
|
19
|
-
/*----------------------------------
|
|
20
|
-
- TYPES
|
|
21
|
-
----------------------------------*/
|
|
22
|
-
|
|
23
|
-
import type { Layout } from '@common/router';
|
|
24
|
-
|
|
25
|
-
export type TBugReportInfos = {
|
|
26
|
-
stacktrace?: string,
|
|
27
|
-
observation?: string,
|
|
28
|
-
before?: string,
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/*----------------------------------
|
|
32
|
-
- HOOKS
|
|
33
|
-
----------------------------------*/
|
|
34
|
-
|
|
35
|
-
// Sera initialisé via le routeur
|
|
36
|
-
export const ReactClientContext = React.createContext<ClientContext>({} as ClientContext);
|
|
37
|
-
export default (): ClientContext => React.useContext<ClientContext>(ReactClientContext);
|
|
38
|
-
|
|
39
|
-
// Hooks
|
|
40
|
-
/*export { default as useState } from '@client/hooks/useState';
|
|
41
|
-
export type { TActions as TActionsState } from '@client/hooks/useState';
|
|
42
|
-
export { default as useComponent } from '@client/hooks/useComponent';
|
|
43
|
-
export { default as useScript } from '@client/hooks/useScript';*/
|
|
44
|
-
|
|
45
|
-
// Utils
|
|
46
|
-
export const Switch = (val: string | number, options: { [cle: string]: ComponentChild }) => {
|
|
47
|
-
return (val in options) ? options[val] : null;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export const useState = <TData extends TObjetDonnees>(initial: TData): [
|
|
51
|
-
TData,
|
|
52
|
-
(data: Partial<TData>) => void
|
|
53
|
-
] => {
|
|
54
|
-
const [state, setState] = React.useState<TData>(initial);
|
|
55
|
-
const setPartialState = (data: Partial<TData>) => setState(current => ({ ...current, ...data }));
|
|
56
|
-
return [state, setPartialState]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/*----------------------------------
|
|
60
|
-
- CONTEXT
|
|
61
|
-
----------------------------------*/
|
|
62
|
-
export class ClientContext {
|
|
63
|
-
|
|
64
|
-
public context = this; // To access to the full nstance within a destructuration
|
|
65
|
-
public user: User | null;
|
|
66
|
-
|
|
67
|
-
public id = Date.now();
|
|
68
|
-
public bridges: { [name: string]: Function } = {};
|
|
69
|
-
public setLayout?: (layout: Layout) => void;
|
|
70
|
-
|
|
71
|
-
public loadIndicator;
|
|
72
|
-
public loading(state: boolean) {
|
|
73
|
-
|
|
74
|
-
if (state === true) {
|
|
75
|
-
if (!document.body.classList.contains("loading"))
|
|
76
|
-
document.body.classList.add("loading");
|
|
77
|
-
} else {
|
|
78
|
-
document.body.classList.remove("loading");
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Doit etre initialisé le plus tot possible
|
|
84
|
-
public page!: PageResponse;
|
|
85
|
-
public async createPage(
|
|
86
|
-
route: TClientRoute,
|
|
87
|
-
data?: TObjetDonnees
|
|
88
|
-
) {
|
|
89
|
-
|
|
90
|
-
this.page = new PageResponse(this, route);
|
|
91
|
-
|
|
92
|
-
// Load the fetchers list to load data if needed
|
|
93
|
-
if (route.controller)
|
|
94
|
-
this.page.fetchers = route.controller(this.request.data, this);
|
|
95
|
-
|
|
96
|
-
if (data !== undefined) {
|
|
97
|
-
this.page.loading = false;
|
|
98
|
-
this.page.data = data;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return this.page;
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
public constructor(
|
|
106
|
-
public request: BaseRequest,
|
|
107
|
-
public clientBug?: (infos: TBugReportInfos) => any
|
|
108
|
-
) {
|
|
109
|
-
|
|
110
|
-
this.request = request;
|
|
111
|
-
this.user = this.request.user || null;
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Is overwrote by the native app
|
|
116
|
-
public Application = {
|
|
117
|
-
platform: () => 'web',
|
|
118
|
-
|
|
119
|
-
// Actions on the native app
|
|
120
|
-
reloadDaemon: () => { },
|
|
121
|
-
reloadGui: () => {
|
|
122
|
-
this.page?.go('/');
|
|
123
|
-
},
|
|
124
|
-
optimize: () => {},
|
|
125
|
-
|
|
126
|
-
// After auth
|
|
127
|
-
auth: (token: string, email: string) => {
|
|
128
|
-
localStorage?.setItem("latestemail", email);
|
|
129
|
-
this.page?.go('/');
|
|
130
|
-
},
|
|
131
|
-
// Google one tap click
|
|
132
|
-
googleAuth: () => {
|
|
133
|
-
window.location.replace("/auth/google");
|
|
134
|
-
},
|
|
135
|
-
logout: undefined as undefined | (() => void),
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
public async connectApp() {
|
|
139
|
-
|
|
140
|
-
// TODO: Chrome extension
|
|
141
|
-
|
|
142
|
-
// Android
|
|
143
|
-
if (window["Application"]) {
|
|
144
|
-
|
|
145
|
-
console.log("Connecting android app ...", window["Application"]);
|
|
146
|
-
|
|
147
|
-
this.Application = window["Application"];
|
|
148
|
-
|
|
149
|
-
// Web
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
if (window["ssr"] === undefined) {
|
|
153
|
-
this.user = this.request.user = await this.api.get('/user').run();
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// fetch doit appartenir à response, et non clientcontxt
|
|
158
|
-
// car la méthode varie selon client (http) ou serveur (router.resolve)
|
|
159
|
-
public api = {
|
|
160
|
-
...this.request.api,
|
|
161
|
-
set: (newData: TObjetDonnees) => {
|
|
162
|
-
|
|
163
|
-
console.log("[api] Update page data", newData);
|
|
164
|
-
if (this.page)
|
|
165
|
-
this.page.setAllData(curData => ({ ...curData, ...newData }));
|
|
166
|
-
|
|
167
|
-
},
|
|
168
|
-
reload: (ids?: string | string[], params?: TObjetDonnees) => {
|
|
169
|
-
|
|
170
|
-
if (this.page === undefined)
|
|
171
|
-
throw new Error("context.page is missing");
|
|
172
|
-
|
|
173
|
-
if (ids === undefined)
|
|
174
|
-
ids = Object.keys(this.page.fetchers);
|
|
175
|
-
else if (typeof ids === 'string')
|
|
176
|
-
ids = [ids];
|
|
177
|
-
|
|
178
|
-
console.log("[api] Reload data", ids, params, this.page.fetchers);
|
|
179
|
-
|
|
180
|
-
for (const id of ids) {
|
|
181
|
-
|
|
182
|
-
const fetcher = this.page.fetchers[id];
|
|
183
|
-
if (fetcher === undefined)
|
|
184
|
-
return console.error(`Unable to reload ${id}: Request not found in fetchers list.`);
|
|
185
|
-
|
|
186
|
-
if (params !== undefined)
|
|
187
|
-
fetcher.data = { ...(fetcher.data || {}), ...params };
|
|
188
|
-
|
|
189
|
-
console.log("[api][reload]", id, fetcher.method, fetcher.path, fetcher.data);
|
|
190
|
-
const indicator = this.toast.loading("Loading ...");
|
|
191
|
-
|
|
192
|
-
this.request.fetchAsync(fetcher.method, fetcher.path, fetcher.data).then((data) => {
|
|
193
|
-
|
|
194
|
-
this.api.set({ [id]: data });
|
|
195
|
-
|
|
196
|
-
}).finally(() => {
|
|
197
|
-
|
|
198
|
-
indicator.close(true);
|
|
199
|
-
|
|
200
|
-
})
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
public handleError(e: Error) {
|
|
206
|
-
switch (e.http) {
|
|
207
|
-
case 401:
|
|
208
|
-
this.page?.go('/');
|
|
209
|
-
break;
|
|
210
|
-
default:
|
|
211
|
-
this.toast.error(e.title || "Uh Oh ...", e.message, null, { autohide: false });
|
|
212
|
-
break;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
public register(
|
|
217
|
-
services: { [id: string]: (response: ClientContext) => any },
|
|
218
|
-
bridges: { [name: string]: Function } = {}
|
|
219
|
-
) {
|
|
220
|
-
for (const id in services) {
|
|
221
|
-
console.log('Registering service', id);
|
|
222
|
-
this[id] = services[id](this);
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
for (const id in bridges) {
|
|
226
|
-
console.log('Registering bridge', id);
|
|
227
|
-
this.bridges[id] = bridges[id];
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// Services
|
|
232
|
-
public modal = createDialog(this, false);
|
|
233
|
-
public toast = createDialog(this, true);
|
|
234
|
-
public socket = new SocketClient(this)
|
|
235
|
-
public captcha = new Recaptcha(this);
|
|
236
|
-
|
|
237
|
-
// Tracking
|
|
238
|
-
public event( name: string, params?: object ) {
|
|
239
|
-
if (!window.gtag) return;
|
|
240
|
-
if (name === 'pageview')
|
|
241
|
-
window.gtag('send', name);
|
|
242
|
-
else
|
|
243
|
-
window.gtag('event', name, params);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
}
|
package/src/client/index.tsx
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/*----------------------------------
|
|
2
|
-
- DEPENDANCES
|
|
3
|
-
----------------------------------*/
|
|
4
|
-
window.dev && require('preact/debug');
|
|
5
|
-
|
|
6
|
-
import * as testLayouts from '@/client/pages/**/_layout/index.tsx';
|
|
7
|
-
|
|
8
|
-
// Npm
|
|
9
|
-
import React from 'react';
|
|
10
|
-
import ReactDOM from 'react-dom';
|
|
11
|
-
|
|
12
|
-
// Core libs
|
|
13
|
-
import router from '@client/router';
|
|
14
|
-
import { location } from '@client/router/request/history';
|
|
15
|
-
import coreRoutes from '@client/pages/**/*.tsx';
|
|
16
|
-
import appRoutes from '@/client/pages/**/*.tsx';
|
|
17
|
-
|
|
18
|
-
import ClientResponse from './router/response';
|
|
19
|
-
import ClientRequest from './router/request';
|
|
20
|
-
import { ClientContext, TBugReportInfos } from '@client/context';
|
|
21
|
-
import PageResponse from '@common/router/response/page';
|
|
22
|
-
import type { TSsrData } from '@server/services/router/response';
|
|
23
|
-
|
|
24
|
-
// Core components
|
|
25
|
-
import App from '@client/App';
|
|
26
|
-
|
|
27
|
-
/*----------------------------------
|
|
28
|
-
- types
|
|
29
|
-
----------------------------------*/
|
|
30
|
-
|
|
31
|
-
declare global {
|
|
32
|
-
interface Window {
|
|
33
|
-
dev: boolean,
|
|
34
|
-
context: ClientContext,
|
|
35
|
-
user: User,
|
|
36
|
-
gtag: (action: string, name: string, params?: any) => void
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/*----------------------------------
|
|
41
|
-
- BUG REPORT
|
|
42
|
-
----------------------------------*/
|
|
43
|
-
const clientBug = (infos: TBugReportInfos) => fetch('/help/bug/gui', {
|
|
44
|
-
method: 'POST',
|
|
45
|
-
headers: {
|
|
46
|
-
'Accept': "application/json",
|
|
47
|
-
'Content-Type': 'application/json'
|
|
48
|
-
},
|
|
49
|
-
body: JSON.stringify({
|
|
50
|
-
url: window.location.pathname,
|
|
51
|
-
ssrData: JSON.stringify(window["ssr"]),
|
|
52
|
-
guiVersion: BUILD_DATE,
|
|
53
|
-
...infos
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
// Impossible de recup le stacktrace ...
|
|
58
|
-
/*window.addEventListener("unhandledrejection", (e) => {
|
|
59
|
-
clientBug(JSON.stringify(e))
|
|
60
|
-
console.log("unhandledrejection", e.stack);
|
|
61
|
-
|
|
62
|
-
});*/
|
|
63
|
-
|
|
64
|
-
window.onerror = (message, file, line, col, stacktrace) =>
|
|
65
|
-
clientBug({
|
|
66
|
-
stacktrace: stacktrace?.stack || JSON.stringify({ message, file, line, col })
|
|
67
|
-
}).then(() => {
|
|
68
|
-
|
|
69
|
-
if (context)
|
|
70
|
-
context.toast.warning("Bug detected",
|
|
71
|
-
"A bug report has been sent, because I've detected a bug on the interface. I'm really sorry for the interruption.",
|
|
72
|
-
null,
|
|
73
|
-
{ autohide: false });
|
|
74
|
-
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
/*----------------------------------
|
|
78
|
-
- LAUNCH APP
|
|
79
|
-
----------------------------------*/
|
|
80
|
-
const ssrResponse = window["ssr"] as (TSsrData | undefined);
|
|
81
|
-
|
|
82
|
-
if (!location)
|
|
83
|
-
throw new Error(`Unable to retrieve current location.`);
|
|
84
|
-
|
|
85
|
-
let context: ClientContext;
|
|
86
|
-
try {
|
|
87
|
-
const request = new ClientRequest(location, window.context);
|
|
88
|
-
request.context = window.context = context = request.gui = new ClientContext(request, clientBug);
|
|
89
|
-
|
|
90
|
-
router.initialize({ ...coreRoutes, ...appRoutes }, async (route) => {
|
|
91
|
-
|
|
92
|
-
// Restituate SSR response
|
|
93
|
-
let renderer = ReactDOM.render;
|
|
94
|
-
if (ssrResponse) {
|
|
95
|
-
|
|
96
|
-
console.log("SSR Response restitution ...");
|
|
97
|
-
|
|
98
|
-
if (!route)
|
|
99
|
-
throw new Error(`Route ${ssrResponse.page.id} was not found in ssr routes list.`);
|
|
100
|
-
|
|
101
|
-
context.user = request.user = ssrResponse.user || null;
|
|
102
|
-
|
|
103
|
-
request.data = ssrResponse.request.data;
|
|
104
|
-
|
|
105
|
-
request.response = new ClientResponse<PageResponse>(
|
|
106
|
-
request,
|
|
107
|
-
route
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
await context.createPage(route, ssrResponse.page.data);
|
|
111
|
-
|
|
112
|
-
renderer = ReactDOM.hydrate;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
await context.connectApp();
|
|
116
|
-
|
|
117
|
-
renderer( <App context={context} />, document.body, () => {
|
|
118
|
-
|
|
119
|
-
console.log(`Render complete`);
|
|
120
|
-
|
|
121
|
-
});
|
|
122
|
-
}, context);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
} catch (error) {
|
|
126
|
-
|
|
127
|
-
clientBug({ stacktrace: error.stack || error.message });
|
|
128
|
-
|
|
129
|
-
}
|