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,286 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import React from 'react';
7
-
8
- // Core: libs
9
- import ClientRequest from './request';
10
- import ClientResponse from './response';
11
-
12
- // Core: types
13
- import BaseRouter, { defaultOptions, } from '@common/router'
14
- import { PageResponse } from '@common/router/response';
15
- import type { TSsrData } from '@server/services/router/response';
16
- import type { ClientContext } from '@client/context';
17
-
18
- // Type xports
19
- export type { default as ClientResponse } from "./response";
20
- export { Link } from './Link';
21
- import type {
22
- TClientRoute,
23
- TUnresolvedRoute,
24
- TSsrUnresolvedRoute,
25
- TRoutesLoaders,
26
- TRouteCallback,
27
- TFetchedRoute,
28
- TRegisterPageArgs
29
- } from './route';
30
-
31
- // Temporary
32
- // TODO: Import these types directly from router/routes
33
- export type {
34
- TClientRoute,
35
- TUnresolvedRoute,
36
- TSsrUnresolvedRoute,
37
- TRoutesLoaders,
38
- TRouteCallback,
39
- TFetchedRoute,
40
- TRegisterPageArgs,
41
- TFrontController
42
- } from './route';
43
-
44
- /*----------------------------------
45
- - CONFIG
46
- ----------------------------------*/
47
-
48
- const debug = true;
49
- const LogPrefix = '[router]'
50
-
51
- /*----------------------------------
52
- - TYPES
53
- ----------------------------------*/
54
-
55
- export type THookCallback = (request: ClientRequest) => void;
56
-
57
- type THookName = 'locationChange'
58
-
59
- /*----------------------------------
60
- - ROUTER
61
- ----------------------------------*/
62
- class Router extends BaseRouter {
63
-
64
- /*----------------------------------
65
- - HOOKS
66
- ----------------------------------*/
67
- private hooks: {
68
- [hookname in THookName]?: (THookCallback | null)[]
69
- } = {}
70
-
71
- public on( hookName: THookName, callback: THookCallback ) {
72
-
73
- debug && console.info(LogPrefix, `Register hook ${hookName}`);
74
-
75
- let cbIndex: number;
76
- let callbacks = this.hooks[ hookName ];
77
- if (!callbacks) {
78
- cbIndex = 0;
79
- callbacks = this.hooks[ hookName ] = [callback]
80
- } else {
81
- cbIndex = callbacks.length;
82
- callbacks.push(callback);
83
- }
84
-
85
- // Listener remover
86
- return () => {
87
- debug && console.info(LogPrefix, `De-register hook ${hookName} (index ${cbIndex})`);
88
- delete (callbacks as THookCallback[])[ cbIndex ];
89
- }
90
-
91
- }
92
- private runHook( hookName: THookName, request: ClientRequest ) {
93
- const callbacks = this.hooks[hookName];
94
- if (callbacks)
95
- for (const callback of callbacks)
96
- // callback can be null since we use delete to unregister
97
- callback && callback(request);
98
- }
99
-
100
- /*----------------------------------
101
- - ROUTES MANAGEMENT
102
- ----------------------------------*/
103
-
104
- public disableResolver = false;
105
-
106
- public routes: (TClientRoute | TUnresolvedRoute)[] = [];
107
-
108
- public set(data: TObjetDonnees) {
109
- throw new Error(`router.set was not attached to the router component.`);
110
- }
111
-
112
- public async initialize( loaders: TRoutesLoaders, callback: TRouteCallback, context: ClientContext ) {
113
- debug && console.log(`Initializing client router ...`);
114
-
115
- const ssrRoutes = window["routes"] as TSsrUnresolvedRoute[];
116
- const ssrResponse = window["ssr"] as TSsrData | undefined;
117
- let foundPage: boolean = false;
118
-
119
- // Associe la liste des routes (obtenue via ssr) à leur loader
120
- for (let i = 0; i < ssrRoutes.length; i++) {
121
-
122
- const ssrRoute = ssrRoutes[i];
123
-
124
- if (loaders[ssrRoute.chunk] === undefined)
125
- throw new Error(`Loader not found for chunk id ${ssrRoute.chunk}`);
126
-
127
- let route: TUnresolvedRoute = {
128
- type: 'PAGE',
129
- regex: ssrRoute.regex ? new RegExp(ssrRoute.regex) : null,
130
- chunk: ssrRoute.chunk,
131
- load: loaders[ssrRoute.chunk],
132
- keys: ssrRoute.keys || [],
133
- }
134
-
135
- debug && console.log(`- ${route.regex} => ${route.chunk}`, route);
136
-
137
- if (ssrResponse !== undefined && route.chunk === ssrResponse?.page.id) {
138
-
139
- const loaded = ('load' in route) ? await this.load( route, context ) as TClientRoute : route;
140
- callback(loaded);
141
- this.routes[i] = loaded;
142
- foundPage = true;
143
- continue;
144
- }
145
-
146
- this.routes[i] = route;
147
- }
148
-
149
- if (!foundPage)
150
- callback(undefined);
151
-
152
- }
153
-
154
- public async resolve( request: ClientRequest, context: ClientContext ): Promise<PageResponse | undefined | null> {
155
- debug && console.log('Resolving request', request.path, Object.keys(request.data));
156
-
157
- this.runHook('locationChange', request);
158
-
159
- for (let iRoute = 0; iRoute < this.routes.length; iRoute++) {
160
-
161
- let route = this.routes[iRoute];
162
- if (route.regex === null)
163
- continue;
164
-
165
- const match = route.regex.exec(request.path);
166
- //console.log('Trying', route.regex.source, match);
167
- if (!match)
168
- continue;
169
-
170
- // Non résolue = on charge le chunk
171
- if ('load' in route) {
172
- const loaded = await this.load(route, context);
173
- if (loaded === null) return null;
174
- route = this.routes[iRoute] = loaded;
175
- }
176
-
177
- // URL data
178
- for (let iKey = 0; iKey < route.keys.length; iKey++) {
179
- const nomParam = route.keys[iKey];
180
- if (typeof nomParam === 'string') // number = sans nom
181
- request.data[nomParam] = match[iKey + 1]
182
- }
183
-
184
- // Create response
185
- new ClientResponse<PageResponse>(request, route);
186
- const page = await context.createPage(route).catch((e) => {
187
-
188
- return this.handleError(e, request, iRoute, context);
189
-
190
- });
191
-
192
- return page;
193
-
194
- };
195
-
196
- return undefined;
197
-
198
- }
199
-
200
- private async handleError(e: Error, request: ClientRequest, iRoute: number, context: ClientContext ) {
201
-
202
- const code = 'http' in e ? e.http : 500;
203
- console.log(`Loading error page ` + code);
204
-
205
- // ERROR PAGE
206
-
207
- let route = this.routes.find( r => r.chunk === 'pages/_messages_' + code);
208
- if (route === undefined) {
209
- console.error(`Error page for http error code ${code} not found.`, this.routes);
210
- context.handleError(e);
211
- return;
212
- }
213
-
214
- // Non résolue = on charge le chunk
215
- if ('load' in route) {
216
- const loaded = await this.load(route, context);
217
- if (loaded === null) return null;
218
- route = this.routes[iRoute] = loaded;
219
- }
220
-
221
- new ClientResponse<PageResponse>(request, route);
222
- return await context.createPage(route);
223
- }
224
-
225
- private async load<TRoute extends TUnresolvedRoute>(
226
- route: TRoute,
227
- context: ClientContext
228
- ): Promise<TClientRoute | null> {
229
- debug && console.log(`Fetching route ${route.chunk} ...`, route);
230
-
231
- let fetched: TFetchedRoute;
232
- if (typeof route.load === 'function') {
233
-
234
- try {
235
- fetched = (await route.load()).default;
236
- } catch (e) {
237
- console.error(`Failed to fetch the route ${route.chunk}`, e);
238
- context.toast.error("Failed to load content. Please make sure you're connected to Internet.");
239
- return null;
240
- }
241
-
242
- } else {
243
-
244
- debug && console.log(`Route already fetched: ${route.chunk}`, route.load);
245
- fetched = route.load;
246
-
247
- }
248
-
249
- debug && console.log(`Route fetched: ${route.chunk}`, fetched);
250
- return {
251
- ...fetched,
252
- type: route.type,
253
- regex: route.regex,
254
- keys: route.keys
255
- }
256
- }
257
-
258
- protected registerPage( ...args: TRegisterPageArgs ): TFetchedRoute | void {
259
-
260
- const { path, options, controller, renderer } = this.getRegisterPageArgs(...args);
261
-
262
- console.log('Registering PAGE', path, options);
263
-
264
- const id = options["id"];
265
-
266
- // S'il s'agit d'une page, son id doit avoir été injecté via le plugin babel
267
- if (id === undefined)
268
- return console.error(`ID not found for the following page route:`, { path });
269
-
270
- return {
271
- method: 'GET',
272
- options: {
273
- ...defaultOptions,
274
- ...options
275
- },
276
- path,
277
- controller,
278
- renderer
279
- };
280
-
281
-
282
- }
283
-
284
- }
285
-
286
- export default new Router
@@ -1,106 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import { Location } from 'history';
7
- import type Bowser from 'bowser';
8
-
9
- // Core
10
- import BaseRequest, { TFetcherArgs, TFetcherList } from '@common/router/request';
11
- import ClientResponse from '../response';
12
- import apiRequest from '@client/context/api';
13
- import { ClientContext } from '@client/context';
14
- import { NetworkError } from "@common/errors";
15
-
16
- /*----------------------------------
17
- - TYPES
18
- ----------------------------------*/
19
-
20
- // Modeles
21
- import type { User } from '@models';
22
-
23
- /*----------------------------------
24
- - ROUTER
25
- ----------------------------------*/
26
- export default class ClientRequest extends BaseRequest {
27
-
28
- public gui!: ClientContext; // a initialiser le plus tot possible
29
- public response?: ClientResponse;
30
- public context: ClientContext;
31
-
32
- public hash?: string;
33
-
34
- public constructor( location: Location, context: ClientContext ) {
35
-
36
- super(
37
- location.pathname
38
- );
39
-
40
- this.context = context;
41
- this.host = window.location.host;
42
- this.hash = location.hash;
43
-
44
- }
45
-
46
- public device(): Bowser.Parser.ParsedResult | undefined {
47
- // We load bowser only when required
48
- const Bowser = require("bowser");
49
- return Bowser.parse(window.navigator.userAgent);
50
- }
51
-
52
- public createFetcher(...args: TFetcherArgs) {
53
- const [method, path, data, options] = args;
54
- return {
55
- method, path, data, options,
56
- // For async calls: api.post(...).then((data) => ...)
57
- then: (callback: (data: any) => void) => this.fetchAsync(...args).then(callback),
58
- catch: (callback: (data: any) => void) => this.fetchAsync(...args).catch(callback),
59
- finally: (callback: () => void) => this.fetchAsync(...args).finally(callback),
60
- run: () => this.fetchAsync(...args)
61
- };
62
- }
63
-
64
- public async fetchAsync(...[method, path, data, options]: TFetcherArgs): Promise<any> {
65
-
66
- /*if (options?.captcha !== undefined)
67
- await this.gui.captcha.check(options?.captcha);*/
68
-
69
- return await apiRequest(this.context, method, path, data, options).catch((e) => {
70
- this.gui.handleError(e);
71
- throw e;
72
- })
73
- }
74
-
75
- public async fetchSync(fetchers: TFetcherList): Promise<TObjetDonnees> {
76
-
77
- const ids = Object.keys(fetchers);
78
- if (ids.length === 1) {
79
- const id = ids[0];
80
- const fetcher = fetchers[id];
81
- return {
82
- [id]: await apiRequest( this.context, fetcher.method, fetcher.path, fetcher.data, undefined )
83
- };
84
- }
85
-
86
- const fetchersArgs: {[id: string]: TFetcherArgs} = {};
87
- for (const id in fetchers)
88
- fetchersArgs[id] = [
89
- fetchers[id].method,
90
- fetchers[id].path,
91
- fetchers[id].data,
92
- ]
93
-
94
- return await apiRequest(this.context, "POST", "/api", { fetchers: fetchersArgs }, undefined).then((res) => {
95
-
96
- const data: TObjetDonnees = {};
97
- for (const id in res)
98
- data[id] = res[id];
99
-
100
- return data;
101
-
102
- });
103
-
104
- }
105
-
106
- }
@@ -1,38 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Libs
6
- import { TClientRoute } from '..';
7
- import { history } from '@client/router/request/history';
8
- import BaseResponse, { TResponseData } from '@common/router/response';
9
- import ClientRequest from '@client/router/request'
10
-
11
- /*----------------------------------
12
- - TYPES
13
- ----------------------------------*/
14
-
15
- import type ServerResponse from '@server/services/router/response';
16
- import type { PageResponse } from '@common/router/response';
17
- export type TPageResponse = With<ClientResponse<PageResponse> | ServerResponse<PageResponse>, 'data'>;
18
-
19
- /*----------------------------------
20
- - ROUTER
21
- ----------------------------------*/
22
- export default class ClientResponse<TData extends TResponseData = TResponseData> extends BaseResponse<TData> {
23
-
24
- public constructor(
25
- request: ClientRequest,
26
- route: TClientRoute
27
- ) {
28
-
29
- super(request);
30
-
31
- this.route = route;
32
-
33
- }
34
-
35
- public redirect(url: string) {
36
- history?.replace(url);
37
- }
38
- }
@@ -1,75 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import type { ComponentChild } from 'preact';
7
-
8
- // Core
9
- import type { ClientContext } from '@client/context';
10
- import type { TBaseRoute, TRouteOptions, } from '@common/router'
11
- import type { TFetcher, TFetcherList } from '@common/router/request';
12
-
13
- /*----------------------------------
14
- - TYPES: PARTIAL ROUTES
15
- ----------------------------------*/
16
-
17
- export type TSsrUnresolvedRoute = Pick<TClientRoute, 'type' | 'keys'> & {
18
- regex: string,
19
- chunk: string,
20
- }
21
-
22
- export type TUnresolvedRoute = Pick<TClientRoute, 'type' | 'keys'> & {
23
- regex: RegExp | null,
24
- chunk: string,
25
- load: TRouteLoader,
26
- }
27
-
28
- export type TFetchedRoute = Pick<TClientRoute, 'path' | 'options' | 'controller' | 'renderer' | 'method'>
29
-
30
- /*----------------------------------
31
- - TYPES: REGISTER
32
- ----------------------------------*/
33
-
34
- type TRouteLoader = () => Promise<{ default: TFetchedRoute }>;
35
-
36
- export type TRoutesLoaders = {
37
- [chunkId: string]: /* Preloaded via require() */TFetchedRoute | /* Loader via import() */TRouteLoader/* | undefined*/
38
- }
39
-
40
- export type TRouteCallback = (route?: TClientRoute) => void;
41
-
42
- export type TRegisterPageArgs<TControllerData extends TFetcherList = {}> = [
43
- path: string,
44
- options: Partial<TRouteOptions>,
45
- controller: TFrontController<TControllerData> | null,
46
- renderer: TFrontRenderer<TControllerData>
47
- ];
48
-
49
- /*----------------------------------
50
- - TYPES: COMPLETE ROUTES
51
- ----------------------------------*/
52
-
53
- export type TClientRoute = TBaseRoute & {
54
- type: 'PAGE',
55
- method: 'GET',
56
- controller: TFrontController | null,
57
- renderer: TFrontRenderer
58
- }
59
-
60
- // https://stackoverflow.com/questions/44851268/typescript-how-to-extract-the-generic-parameter-from-a-type
61
- type TypeWithGeneric<T> = TFetcher<T>
62
- type extractGeneric<Type> = Type extends TypeWithGeneric<infer X> ? X : never
63
-
64
- export type TFrontController<TControllerData extends TFetcherList = {}> =
65
- (urlParams: TObjetDonnees, context: ClientContext) => TControllerData
66
-
67
- export type TFrontRenderer<TControllerData extends TFetcherList = {}> = (
68
- data: {
69
- [Property in keyof TControllerData]: undefined | (extractGeneric<TControllerData[Property]> extends ((...args: any[]) => any)
70
- ? ThenArg<ReturnType< extractGeneric<TControllerData[Property]> >>
71
- : extractGeneric<TControllerData[Property]>
72
- )
73
- },
74
- context: ClientContext
75
- ) => ComponentChild