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
@@ -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
- }
@@ -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
- }