proteum 1.0.2 → 2.0.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 (185) hide show
  1. package/AGENTS.md +101 -0
  2. package/agents/codex/AGENTS.md +95 -0
  3. package/agents/codex/CODING_STYLE.md +71 -0
  4. package/agents/codex/agents.md.zip +0 -0
  5. package/agents/codex/client/AGENTS.md +102 -0
  6. package/agents/codex/client/pages/AGENTS.md +35 -0
  7. package/agents/codex/server/routes/AGENTS.md +12 -0
  8. package/agents/codex/server/services/AGENTS.md +137 -0
  9. package/agents/codex/tests/AGENTS.md +8 -0
  10. package/cli/app/config.ts +13 -11
  11. package/cli/app/index.ts +74 -82
  12. package/cli/bin.js +1 -1
  13. package/cli/commands/build.ts +51 -14
  14. package/cli/commands/check.ts +19 -0
  15. package/cli/commands/deploy/app.ts +4 -8
  16. package/cli/commands/deploy/web.ts +16 -20
  17. package/cli/commands/dev.ts +189 -64
  18. package/cli/commands/devEvents.ts +106 -0
  19. package/cli/commands/init.ts +63 -57
  20. package/cli/commands/lint.ts +21 -0
  21. package/cli/commands/refresh.ts +18 -0
  22. package/cli/commands/typecheck.ts +18 -0
  23. package/cli/compiler/client/identite.ts +80 -53
  24. package/cli/compiler/client/index.ts +139 -213
  25. package/cli/compiler/common/bundleAnalysis.ts +94 -0
  26. package/cli/compiler/common/clientManifest.ts +67 -0
  27. package/cli/compiler/common/controllers.ts +288 -0
  28. package/cli/compiler/common/files/autres.ts +7 -18
  29. package/cli/compiler/common/files/images.ts +40 -37
  30. package/cli/compiler/common/files/style.ts +11 -22
  31. package/cli/compiler/common/generatedRouteModules.ts +368 -0
  32. package/cli/compiler/common/index.ts +31 -65
  33. package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
  34. package/cli/compiler/common/rspackAliases.ts +13 -0
  35. package/cli/compiler/common/scripts.ts +37 -0
  36. package/cli/compiler/index.ts +781 -230
  37. package/cli/compiler/server/index.ts +59 -75
  38. package/cli/compiler/writeIfChanged.ts +21 -0
  39. package/cli/index.ts +71 -72
  40. package/cli/paths.ts +51 -57
  41. package/cli/print.ts +17 -11
  42. package/cli/tsconfig.json +5 -4
  43. package/cli/utils/agents.ts +100 -0
  44. package/cli/utils/check.ts +71 -0
  45. package/cli/utils/index.ts +1 -3
  46. package/cli/utils/keyboard.ts +8 -25
  47. package/cli/utils/runProcess.ts +30 -0
  48. package/client/app/component.tsx +29 -29
  49. package/client/app/index.ts +36 -57
  50. package/client/app/service.ts +7 -12
  51. package/client/app.tsconfig.json +2 -2
  52. package/client/components/Dialog/Manager.ssr.tsx +40 -0
  53. package/client/components/Dialog/Manager.tsx +119 -150
  54. package/client/components/Dialog/status.tsx +3 -3
  55. package/client/components/index.ts +1 -1
  56. package/client/components/types.d.ts +1 -3
  57. package/client/dev/hmr.ts +65 -0
  58. package/client/global.d.ts +2 -2
  59. package/client/hooks.ts +6 -9
  60. package/client/index.ts +2 -1
  61. package/client/islands/index.ts +7 -0
  62. package/client/islands/useDeferredModule.ts +199 -0
  63. package/client/pages/_layout/index.tsx +4 -12
  64. package/client/pages/useHeader.tsx +14 -21
  65. package/client/router.ts +27 -0
  66. package/client/services/router/components/Link.tsx +34 -27
  67. package/client/services/router/components/Page.tsx +6 -14
  68. package/client/services/router/components/router.ssr.tsx +36 -0
  69. package/client/services/router/components/router.tsx +63 -83
  70. package/client/services/router/index.tsx +185 -220
  71. package/client/services/router/request/api.ts +97 -119
  72. package/client/services/router/request/history.ts +2 -2
  73. package/client/services/router/request/index.ts +13 -12
  74. package/client/services/router/request/multipart.ts +72 -62
  75. package/client/services/router/response/index.tsx +68 -61
  76. package/client/services/router/response/page.ts +28 -32
  77. package/client/utils/dom.ts +17 -33
  78. package/common/app/index.ts +3 -3
  79. package/common/data/chaines/index.ts +22 -23
  80. package/common/data/dates.ts +35 -70
  81. package/common/data/markdown.ts +42 -39
  82. package/common/dev/serverHotReload.ts +26 -0
  83. package/common/errors/index.tsx +110 -142
  84. package/common/router/contracts.ts +29 -0
  85. package/common/router/index.ts +89 -108
  86. package/common/router/layouts.ts +34 -47
  87. package/common/router/pageSetup.ts +50 -0
  88. package/common/router/register.ts +53 -24
  89. package/common/router/request/api.ts +30 -36
  90. package/common/router/request/index.ts +2 -8
  91. package/common/router/response/index.ts +8 -15
  92. package/common/router/response/page.ts +70 -58
  93. package/common/utils.ts +1 -1
  94. package/doc/TODO.md +1 -1
  95. package/eslint.js +62 -0
  96. package/package.json +12 -47
  97. package/prettier.config.cjs +9 -0
  98. package/scripts/cleanup-generated-controllers.ts +62 -0
  99. package/scripts/fix-reference-app-typing.ts +490 -0
  100. package/scripts/refactor-client-app-imports.ts +244 -0
  101. package/scripts/refactor-client-pages.ts +587 -0
  102. package/scripts/refactor-server-controllers.ts +470 -0
  103. package/scripts/refactor-server-runtime-aliases.ts +360 -0
  104. package/scripts/restore-client-app-import-files.ts +41 -0
  105. package/scripts/restore-files-from-git-head.ts +20 -0
  106. package/scripts/update-codex-agents.ts +35 -0
  107. package/server/app/commands.ts +35 -64
  108. package/server/app/container/config.ts +48 -59
  109. package/server/app/container/console/index.ts +202 -248
  110. package/server/app/container/index.ts +33 -71
  111. package/server/app/controller/index.ts +61 -0
  112. package/server/app/index.ts +39 -105
  113. package/server/app/service/container.ts +41 -42
  114. package/server/app/service/index.ts +120 -147
  115. package/server/context.ts +1 -1
  116. package/server/index.ts +25 -1
  117. package/server/services/auth/index.ts +75 -115
  118. package/server/services/auth/router/index.ts +31 -32
  119. package/server/services/auth/router/request.ts +14 -16
  120. package/server/services/cron/CronTask.ts +13 -26
  121. package/server/services/cron/index.ts +14 -36
  122. package/server/services/disks/driver.ts +40 -58
  123. package/server/services/disks/drivers/local/index.ts +79 -90
  124. package/server/services/disks/drivers/s3/index.ts +116 -163
  125. package/server/services/disks/index.ts +23 -38
  126. package/server/services/email/index.ts +45 -104
  127. package/server/services/email/utils.ts +14 -27
  128. package/server/services/fetch/index.ts +53 -85
  129. package/server/services/prisma/Facet.ts +39 -91
  130. package/server/services/prisma/index.ts +74 -110
  131. package/server/services/router/generatedRuntime.ts +29 -0
  132. package/server/services/router/http/index.ts +78 -73
  133. package/server/services/router/http/multipart.ts +19 -42
  134. package/server/services/router/index.ts +378 -365
  135. package/server/services/router/request/api.ts +26 -25
  136. package/server/services/router/request/index.ts +44 -51
  137. package/server/services/router/request/service.ts +7 -11
  138. package/server/services/router/request/validation/zod.ts +111 -148
  139. package/server/services/router/response/index.ts +110 -125
  140. package/server/services/router/response/mask/Filter.ts +31 -72
  141. package/server/services/router/response/mask/index.ts +8 -15
  142. package/server/services/router/response/mask/selecteurs.ts +11 -25
  143. package/server/services/router/response/page/clientManifest.ts +25 -0
  144. package/server/services/router/response/page/document.tsx +199 -127
  145. package/server/services/router/response/page/index.tsx +89 -94
  146. package/server/services/router/service.ts +13 -15
  147. package/server/services/schema/index.ts +17 -26
  148. package/server/services/schema/request.ts +19 -33
  149. package/server/services/schema/router/index.ts +8 -11
  150. package/server/services/security/encrypt/aes/index.ts +15 -35
  151. package/server/utils/slug.ts +29 -35
  152. package/skills/clean-project-code/SKILL.md +63 -0
  153. package/skills/clean-project-code/agents/openai.yaml +4 -0
  154. package/tsconfig.common.json +4 -3
  155. package/tsconfig.json +4 -1
  156. package/types/aliases.d.ts +17 -21
  157. package/types/controller-input.test.ts +48 -0
  158. package/types/express-extra.d.ts +6 -0
  159. package/types/global/constants.d.ts +13 -0
  160. package/types/global/express-extra.d.ts +6 -0
  161. package/types/global/modules.d.ts +13 -16
  162. package/types/global/utils.d.ts +17 -49
  163. package/types/global/vendors.d.ts +62 -0
  164. package/types/icons.d.ts +65 -1
  165. package/types/uuid.d.ts +3 -0
  166. package/types/vendors.d.ts +62 -0
  167. package/cli/compiler/common/babel/index.ts +0 -170
  168. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  169. package/cli/compiler/common/babel/plugins/services.ts +0 -586
  170. package/cli/compiler/common/babel/routes/imports.ts +0 -127
  171. package/cli/compiler/common/babel/routes/routes.ts +0 -1130
  172. package/client/services/captcha/index.ts +0 -67
  173. package/client/services/socket/index.ts +0 -147
  174. package/common/data/rte/nodes.ts +0 -83
  175. package/common/data/stats.ts +0 -90
  176. package/common/utils/rte.ts +0 -183
  177. package/server/services/auth/old.ts +0 -277
  178. package/server/services/cache/commands.ts +0 -41
  179. package/server/services/cache/index.ts +0 -297
  180. package/server/services/cache/service.json +0 -6
  181. package/server/services/socket/index.ts +0 -162
  182. package/server/services/socket/scope.ts +0 -226
  183. package/server/services/socket/service.json +0 -6
  184. package/server/services_old/SocketClient.ts +0 -92
  185. package/server/services_old/Token.old.ts +0 -97
@@ -2,66 +2,84 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
- // Libs
6
- import type ServerRouter from '@server/services/router';
5
+ // Libs
6
+ import type { TAnyRouter } from '@server/services/router';
7
7
  import type ServerResponse from '@server/services/router/response';
8
8
 
9
9
  import type { TAnyRoute, TErrorRoute } from '@common/router';
10
10
  import BaseResponse, { TResponseData } from '@common/router/response';
11
11
 
12
12
  import type ClientApplication from '@client/app';
13
- import type { default as ClientRouter } from '@client/services/router'
14
- import type ClientResponse from '@client/services/router/response'
15
- import ClientRequest from '@client/services/router/request'
16
- import ClientPage from '@client/services/router/response/page'
13
+ import type { default as ClientRouter } from '@client/services/router';
14
+ import type ClientResponse from '@client/services/router/response';
15
+ import ClientRequest from '@client/services/router/request';
16
+ import ClientPage from '@client/services/router/response/page';
17
17
  import { history } from '@client/services/router/request/history';
18
+ import createControllers from '@/common/.generated/controllers';
19
+ import type { TControllers } from '@/common/.generated/controllers';
18
20
 
19
21
  /*----------------------------------
20
22
  - TYPES
21
23
  ----------------------------------*/
22
24
 
23
- export type TPageResponse<TRouter extends ClientRouter> = (
24
- ClientResponse<TRouter, ClientPage>
25
- |
26
- ServerResponse<ServerRouter, ClientPage>
27
- );
25
+ export type TPageResponse<TRouter extends ClientRouter<any, any>> =
26
+ | ClientResponse<TRouter, ClientPage<TRouter>>
27
+ | ServerResponse<TAnyRouter>;
28
+
29
+ type TRouterContextBase<
30
+ TRouter extends ClientRouter<any, any> = ClientRouter<any, any>,
31
+ TApplication extends ClientApplication = ClientApplication,
32
+ > = {
33
+ app: TApplication;
34
+ request: ClientRequest<TRouter>;
35
+ route: TAnyRoute<TRouterContext<TRouter, TApplication>>;
36
+ api: ClientRequest<TRouter>['api'];
37
+ Router: TRouter;
38
+ page: ClientPage<TRouter>;
39
+ data: TObjetDonnees;
40
+ };
41
+
42
+ type TContextOwnState<TValue> = {
43
+ [TKey in keyof TValue as TValue[TKey] extends (...args: any[]) => any ? never : TKey]: TValue[TKey];
44
+ };
45
+
46
+ type TRouterRuntimeContext<
47
+ TRouter extends ClientRouter<any, any> = ClientRouter<any, any>,
48
+ TApplication extends ClientApplication = ClientApplication,
49
+ > = TRouterContextBase<TRouter, TApplication> &
50
+ TContextOwnState<TApplication> &
51
+ TControllers;
52
+
53
+ const createRuntimeContextBase = <
54
+ TRouter extends ClientRouter<any, any> = ClientRouter<any, any>,
55
+ TApplication extends ClientApplication = ClientApplication,
56
+ >(
57
+ app: TApplication,
58
+ controllers: TControllers,
59
+ fields: TRouterContextBase<TRouter, TApplication>,
60
+ ): TRouterRuntimeContext<TRouter, TApplication> => Object.assign({}, app, controllers, fields);
28
61
 
29
62
  export type TRouterContext<
30
- TRouter extends ClientRouter = ClientRouter,
31
- TApplication extends ClientApplication = ClientApplication
32
- > = (
33
- // ClientPage context
34
- {
35
- app: TApplication,
36
- request: ClientRequest<TRouter>,
37
- route: TAnyRoute<TRouterContext>,
38
- api: ClientRequest<TRouter>["api"],
39
- page: ClientPage<TRouter>,
40
- data: TObjetDonnees
41
- }
42
- // Expose client application services (api, socket, ...)
43
- //TRouter["app"]
44
- & TApplication
45
- & ReturnType<TRouter["config"]["context"]>
46
- )
63
+ TRouter extends ClientRouter<any, any> = ClientRouter<any, any>,
64
+ TApplication extends ClientApplication = ClientApplication,
65
+ > = TRouterRuntimeContext<TRouter, TApplication> &
66
+ ReturnType<TRouter['config']['context']> & { context: TRouterContext<TRouter, TApplication> };
47
67
 
48
68
  /*----------------------------------
49
69
  - ROUTER
50
70
  ----------------------------------*/
51
71
  export default class ClientPageResponse<
52
72
  TRouter extends ClientRouter,
53
- TData extends TResponseData = TResponseData
73
+ TData extends TResponseData = TResponseData,
54
74
  > extends BaseResponse<TData> {
55
-
56
- public context: TRouterContext<TRouter, TRouter["app"]>;
75
+ public context: TRouterContext<TRouter, TRouter['app']>;
57
76
 
58
77
  public constructor(
59
78
  public request: ClientRequest<TRouter>,
60
- public route: TAnyRoute | TErrorRoute,
79
+ public route: TAnyRoute<TRouterContext<TRouter, TRouter['app']>>,
61
80
 
62
81
  public app = request.app,
63
82
  ) {
64
-
65
83
  super(request);
66
84
 
67
85
  request.response = this;
@@ -70,54 +88,43 @@ export default class ClientPageResponse<
70
88
  this.context = this.createContext();
71
89
  }
72
90
 
73
- private createContext(): TRouterContext<TRouter, TRouter["app"]> {
74
-
75
- const basicContext: TRouterContext<TRouter, TRouter["app"]> = {
76
-
77
- // App services (TODO: expose only services)
78
- ...this.request.app,
79
-
91
+ private createContext(): TRouterContext<TRouter, TRouter['app']> {
92
+ const basicContext = createRuntimeContextBase(this.request.app, createControllers(this.request.api), {
80
93
  // Router context
81
94
  app: this.app,
82
95
  request: this.request,
83
96
  route: this.route,
84
97
  api: this.request.api,
98
+ Router: this.request.router,
85
99
  // Will be assigned when the controller will be runned
86
- page: undefined as unknown as ClientPage<TRouter>,
100
+ page: undefined!,
87
101
  data: {},
88
- }
89
-
90
- const newContext: TRouterContext<TRouter, TRouter["app"]> = {
91
- ...basicContext,
92
- // Custom context
93
- ...this.request.router.config.context( basicContext, this.request.router )
94
- }
102
+ });
103
+ const customContext = this.request.router.config.context(basicContext, this.request.router);
95
104
 
105
+ const newContext: TRouterContext<TRouter, TRouter['app']> = Object.create(Object.prototype);
106
+ Object.assign(newContext, basicContext, customContext);
96
107
  newContext.context = newContext;
97
108
 
98
109
  // Update context object if already exists
99
110
  // NOTE: we don't create a nex instance of context because we don't want to rereder the full page (inc layout) to update the context given by thr react context provider
100
111
  const existingContext = this.request.router.context;
101
112
  if (existingContext === undefined) {
113
+ this.request.router.context = newContext;
114
+ } else {
115
+ Object.assign(existingContext, newContext);
116
+ }
102
117
 
103
- this.request.router.context = newContext
104
-
105
- } else for(const key in newContext)
106
- existingContext[ key ] = newContext[ key ];
107
-
108
- return newContext
118
+ return newContext;
109
119
  }
110
120
 
111
- public async runController( additionnalData: {} = {} ): Promise<ClientPage> {
112
-
121
+ public async runController(additionnalData: {} = {}): Promise<ClientPage<TRouter>> {
113
122
  // Run contoller
114
123
  const result = this.route.controller(this.context);
115
124
 
116
125
  // Default data type for `return <raw data>`
117
- if (result instanceof ClientPage)
118
- await result.preRender(additionnalData);
119
- else
120
- throw new Error(`Unsupported response format: ${result.constructor?.name}`);
126
+ if (result instanceof ClientPage) await result.preRender(additionnalData);
127
+ else throw new Error(`Unsupported response format: ${result.constructor?.name}`);
121
128
 
122
129
  return result;
123
130
  }
@@ -125,4 +132,4 @@ export default class ClientPageResponse<
125
132
  public redirect(url: string) {
126
133
  history?.replace(url);
127
134
  }
128
- }
135
+ }
@@ -6,81 +6,77 @@
6
6
  import type { ComponentChild } from 'preact';
7
7
 
8
8
  // Core
9
- import type { TClientOrServerContextForPage, Layout, TRoute, TErrorRoute } from '@common/router';
10
- import PageResponse, { TFrontRenderer } from "@common/router/response/page";
9
+ import type { Layout, TErrorRoute, TRoute } from '@common/router';
10
+ import PageResponse, { TFrontRenderer } from '@common/router/response/page';
11
+ import { isClientRequest } from '../request';
11
12
 
12
13
  // Specific
13
14
  import type ClientRouter from '..';
15
+ import type { TRouterContext } from '../response';
14
16
 
15
17
  /*----------------------------------
16
18
  - TYPES
17
19
  ----------------------------------*/
18
20
 
19
-
21
+ type TClientPageRouteLike<TRouter extends ClientRouter<any, any>> =
22
+ | TRoute<TRouterContext<TRouter, TRouter['app']>>
23
+ | TErrorRoute<TRouterContext<TRouter, TRouter['app']>>;
20
24
 
21
25
  /*----------------------------------
22
26
  - CLASS
23
27
  ----------------------------------*/
24
28
 
25
- export default class ClientPage<TRouter = ClientRouter> extends PageResponse<TRouter> {
26
-
27
- public scrollToId: string;
29
+ export default class ClientPage<TRouter extends ClientRouter<any, any> = ClientRouter<any, any>> extends PageResponse<
30
+ TRouter,
31
+ TClientPageRouteLike<TRouter>,
32
+ TRouterContext<TRouter, TRouter['app']>
33
+ > {
34
+ public scrollToId?: string;
28
35
 
29
36
  public constructor(
30
- public route: TRoute | TErrorRoute,
37
+ public route: TClientPageRouteLike<TRouter>,
31
38
  public component: TFrontRenderer,
32
- public context: TClientOrServerContextForPage,
33
- public layout?: Layout
39
+ public context: TRouterContext<TRouter, TRouter['app']>,
40
+ public layout?: Layout,
34
41
  ) {
35
-
36
42
  super(route, component, context);
37
43
 
38
44
  this.bodyId = context.route.options.bodyId;
39
- this.scrollToId = context.request.hash;
40
-
45
+ this.scrollToId = isClientRequest(context.request) ? context.request.hash : undefined;
41
46
  }
42
-
43
- public async preRender( data?: TObjetDonnees ) {
44
47
 
48
+ public async preRender(data?: TObjetDonnees) {
45
49
  // Add the page to the context
46
50
  this.context.page = this;
47
51
 
48
52
  // Data succesfully loaded
49
- this.context.data = this.data = data || await this.fetchData();
53
+ this.context.data = this.data = data || (await this.fetchData());
50
54
 
51
55
  return this;
52
56
  }
53
57
 
54
- /*----------------------------------
58
+ /*----------------------------------
55
59
  - ACTIONS
56
60
  ----------------------------------*/
57
61
  // Should be called AFTER rendering the page
58
62
  public updateClient() {
59
-
60
- document.body.id = this.bodyId || this.id;
63
+ document.body.id = this.bodyId || this.chunkId || '';
61
64
  document.title = this.title || APP_NAME;
62
65
  document.body.className = [...this.bodyClass].join(' ');
63
-
64
66
  }
65
67
 
66
- public setAllData( callback: (data: {[k: string]: any}) => void) {
67
- console.warn(`page.setAllData not yet attached to the page Reatc component.`);
68
+ public setAllData(callback: (data: { [k: string]: any }) => void) {
69
+ console.warn(`page.setAllData not yet attached to the page Reatc component.`);
68
70
  }
69
- public setData( key: string, value: ((value: any) => void) | any ) {
70
- this.setAllData(old => ({
71
- ...old,
72
- [key]: typeof value === 'function' ? value(old[key]) : value
73
- }));
71
+ public setData(key: string, value: ((value: any) => void) | any) {
72
+ this.setAllData((old) => ({ ...old, [key]: typeof value === 'function' ? value(old[key]) : value }));
74
73
  }
75
74
 
76
75
  public setLoading(state: boolean) {
77
-
78
76
  if (state === true) {
79
- if (!document.body.classList.contains("loading"))
80
- document.body.classList.add("loading");
77
+ if (!document.body.classList.contains('loading')) document.body.classList.add('loading');
81
78
  } else {
82
- document.body.classList.remove("loading");
79
+ document.body.classList.remove('loading');
83
80
  }
84
-
85
81
  }
86
- }
82
+ }
@@ -1,14 +1,8 @@
1
- import type { RefObject } from 'preact';
2
1
  import { history } from '@client/services/router/request/history';
3
2
 
4
3
  type ElementOrSelector = HTMLElement | string;
5
- export const deepContains = (
6
- parents: ElementOrSelector | ElementOrSelector[],
7
- children: HTMLElement
8
- ): boolean => {
9
-
10
- if (!Array.isArray(parents))
11
- parents = [parents];
4
+ export const deepContains = (parents: ElementOrSelector | ElementOrSelector[], children: HTMLElement): boolean => {
5
+ if (!Array.isArray(parents)) parents = [parents];
12
6
 
13
7
  let node: HTMLElement | null = children;
14
8
  while (node) {
@@ -16,8 +10,7 @@ export const deepContains = (
16
10
  //console.log('Checking if', parent, 'matches with', node);
17
11
  if (
18
12
  // HTML Element
19
- node === parent
20
- ||
13
+ node === parent ||
21
14
  // CSS Selector
22
15
  (typeof parent === 'string' && node.matches && node.matches(parent))
23
16
  )
@@ -28,50 +21,41 @@ export const deepContains = (
28
21
  }
29
22
 
30
23
  return false;
31
- }
24
+ };
32
25
 
33
26
  // Usage: React.useEffect( blurable([ <element>, <function> ]) );
34
27
  export const blurable = (...args: [HTMLElement, Function][]) => {
35
-
36
- if (!history)
37
- return;
28
+ if (!history) return;
38
29
 
39
30
  const blur = (e: MouseEvent) => {
40
-
41
- if (e.target === null)
42
- return;
31
+ if (!(e.target instanceof HTMLElement)) return;
43
32
 
44
33
  for (const [refElement, masquer] of args) {
45
-
46
34
  //console.log("refElement", refElement, e.target?.matches);
47
35
 
48
- if (!deepContains([refElement], e.target))
49
- masquer();
50
-
36
+ if (!deepContains([refElement], e.target)) masquer();
51
37
  }
52
- }
38
+ };
53
39
 
54
40
  window.addEventListener('mousedown', blur);
55
41
 
56
42
  const unlisten = history.listen(() => {
57
43
  for (const [, masquer] of args) {
58
-
59
44
  masquer();
60
-
61
45
  }
62
- })
46
+ });
63
47
 
64
48
  return () => {
65
49
  window.removeEventListener('mousedown', blur);
66
50
  unlisten();
67
- }
68
- }
69
-
70
- export const focusContent = ( container: HTMLElement ) => {
51
+ };
52
+ };
71
53
 
72
- const toFocus = container.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLButtonElement>(
73
- 'input, textarea, button.btn.primary, footer > button.btn'
74
- ) || container; // Is it useful ? Creating unwanted scroll issue on showing popover
54
+ export const focusContent = (container: HTMLElement) => {
55
+ const toFocus =
56
+ container.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLButtonElement>(
57
+ 'input, textarea, button.btn.primary, footer > button.btn',
58
+ ) || container; // Is it useful ? Creating unwanted scroll issue on showing popover
75
59
 
76
60
  toFocus?.focus();
77
- }
61
+ };
@@ -1,9 +1,9 @@
1
1
  import type ClientApplication from '@client/app';
2
- import type ServerApplication from '@server/app';
2
+ import type ServerApplication from '@server/app/index';
3
3
 
4
4
  export type ClientOrServerApplication = ClientApplication | ServerApplication;
5
5
 
6
6
  export type TAppArrowFunction<
7
7
  TRegisteredData = void,
8
- TApplication extends ClientOrServerApplication = ClientOrServerApplication
9
- > = (app: TApplication) => TRegisteredData
8
+ TApplication extends ClientOrServerApplication = ClientOrServerApplication,
9
+ > = (app: TApplication) => TRegisteredData;
@@ -11,44 +11,43 @@ export const nameToID = (name: string) => name.toLowerCase().replace(/[^a-z1-9]/
11
11
 
12
12
  export const ucfirst = (chaine: string): string => {
13
13
  return chaine.charAt(0).toUpperCase() + chaine.slice(1);
14
- }
14
+ };
15
15
 
16
16
  export const linkify = (texte: string): string => {
17
17
  const regex = /((http|https)\:\/\/([a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?))/gi;
18
18
  return texte.replace(regex, '<a href="$1" target="_blank">$3</a>');
19
- }
19
+ };
20
20
 
21
21
  export const trim = (s: string, c: string) => {
22
- if (c === "]") c = "\\]";
23
- if (c === "\\") c = "\\\\";
24
- return s.replace(new RegExp(
25
- "^[" + c + "]+|[" + c + "]+$", "g"
26
- ), "");
27
- }
22
+ if (c === ']') c = '\\]';
23
+ if (c === '\\') c = '\\\\';
24
+ return s.replace(new RegExp('^[' + c + ']+|[' + c + ']+$', 'g'), '');
25
+ };
28
26
 
29
- export const trimLeft = (chaine: string, toTrim: string) => chaine.startsWith(toTrim)
30
- ? chaine.substring(toTrim.length) : chaine;
27
+ export const trimLeft = (chaine: string, toTrim: string) =>
28
+ chaine.startsWith(toTrim) ? chaine.substring(toTrim.length) : chaine;
31
29
 
32
- export const trimRight = (chaine: string, toTrim: string) => chaine.endsWith(toTrim)
33
- ? chaine.substring(0, -toTrim.length) : chaine;
30
+ export const trimRight = (chaine: string, toTrim: string) =>
31
+ chaine.endsWith(toTrim) ? chaine.substring(0, -toTrim.length) : chaine;
34
32
 
35
- export const escapeRegExp = (string: string) =>
36
- string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
33
+ export const escapeRegExp = (string: string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
37
34
 
38
35
  /*----------------------------------
39
36
  - EXTRACT
40
37
  ----------------------------------*/
41
- export const getKeywords = (str: string, delimiter: string = ' ') => str
38
+ export const getKeywords = (str: string, delimiter: string = ' ') =>
39
+ str
42
40
 
43
- // Minuscule
44
- .toLowerCase()
41
+ // Minuscule
42
+ .toLowerCase()
45
43
 
46
- // condenseWhitespace ( https://github.com/sindresorhus/condense-whitespace/blob/main/index.js )
47
- .trim().replace(/\s{2,}/gu, ' ')
44
+ // condenseWhitespace ( https://github.com/sindresorhus/condense-whitespace/blob/main/index.js )
45
+ .trim()
46
+ .replace(/\s{2,}/g, ' ')
48
47
 
49
- // Ne garde que les caractères alĥanumériques, ainsi que .
50
- // https://stackoverflow.com/questions/20690499/concrete-javascript-regex-for-accented-characters-diacritics
51
- .replace(/[^\.0-9A-Za-zÀ-ÖØ-öø-ÿ]/ig, ' ')
48
+ // Ne garde que les caractères alĥanumériques, ainsi que .
49
+ // https://stackoverflow.com/questions/20690499/concrete-javascript-regex-for-accented-characters-diacritics
50
+ .replace(/[^\.0-9A-Za-zÀ-ÖØ-öø-ÿ]/gi, ' ');
52
51
 
53
52
  // TODO: remove stopwords: https://github.com/fergiemcdowall/stopword
54
- export const getSlug = (str: string) => getKeywords(str, '-')
53
+ export const getSlug = (str: string) => getKeywords(str, '-');
@@ -49,80 +49,59 @@ console.log(formatRelativeTime(date1, date2)); // Output: "in 1 year"
49
49
 
50
50
  */
51
51
 
52
- export type TDateInfo = {
53
- isPast: boolean,
54
- delta: number,
55
- text: string
56
- }
52
+ export type TDateInfo = { isPast: boolean; delta: number; text: string };
57
53
 
58
54
  export const timeSince = (date: Date | number | string): TDateInfo | null => {
59
-
60
- if (date === undefined)
61
- return null;
55
+ if (date === undefined) return null;
62
56
 
63
57
  // Timeago ne prend que des dates et des timestamp
64
58
  if (typeof date === 'string') {
65
59
  date = Date.parse(date);
66
- if (isNaN(date))
67
- return null;
60
+ if (isNaN(date)) return null;
68
61
  }
69
62
 
70
63
  // Get metas
71
- const now = Date.now()
64
+ const now = Date.now();
72
65
  const timestamp = date instanceof Date ? date.getTime() : date;
73
- const deltaSeconds = Math.abs( Math.round( (now - timestamp) / 1000 ));
66
+ const deltaSeconds = Math.abs(Math.round((now - timestamp) / 1000));
74
67
  const isPast = now > timestamp;
75
68
 
76
69
  return {
77
- text: date,//timeAgo.format(date),
70
+ text: String(date), //timeAgo.format(date),
78
71
  isPast,
79
- delta: deltaSeconds
72
+ delta: deltaSeconds,
80
73
  };
81
- }
74
+ };
82
75
 
83
76
  export const tempsRelatif = (time: number, nbChiffresInit?: number) => {
84
-
85
77
  const nbChiffres = nbChiffresInit === undefined ? 2 : nbChiffresInit;
86
78
 
87
79
  const jours = Math.floor(time / (60 * 60 * 24));
88
80
 
89
81
  if (jours >= 1) {
90
-
91
- return jours + (jours === 1 ? ' day' : ' days')
92
-
82
+ return jours + (jours === 1 ? ' day' : ' days');
93
83
  } else {
94
-
95
84
  const heures = Math.floor((time % (60 * 60 * 24)) / (60 * 60));
96
- const minutes = Math.floor((time % (60 * 60)) / (60));
97
- const secondes = Math.floor(time % (60));
98
-
99
- return [heures, minutes, secondes].filter(
100
- (nb: number | false, i: number) => nb > 0 || 4 - i <= nbChiffres
101
- ).map(
102
- (nb: number) => nb < 10 ? '0' + nb : nb
103
- ).join(':');
85
+ const minutes = Math.floor((time % (60 * 60)) / 60);
86
+ const secondes = Math.floor(time % 60);
87
+
88
+ return [heures, minutes, secondes]
89
+ .filter((nb, i) => nb > 0 || 4 - i <= nbChiffres)
90
+ .map((nb) => (nb < 10 ? '0' + nb : nb))
91
+ .join(':');
104
92
  }
105
- }
93
+ };
106
94
 
107
95
  export const chaineDate = (chaine: string): boolean => {
108
96
  // 2019-09-09T11:28:21.778Z
109
97
  const regexDate = /[0-9]{4}\-[0-9]{2}\-[0-9]{2}T[0-9]{2}\:[0-9]{2}\:[0-9]{2}\.[0-9]{3}Z/;
110
- return regexDate.test( chaine );
111
- }
112
-
113
-
114
-
115
-
98
+ return regexDate.test(chaine);
99
+ };
116
100
 
117
101
  // Based on https://github.com/sebastiansandqvist/s-ago/blob/master/index.ts
118
- type TUnit = {
119
- max: number,
120
- divisor?: number,
121
- past: string,
122
- future: string
123
- }
102
+ type TUnit = { max: number; divisor?: number; past: string; future: string };
124
103
 
125
- const units: {[name: string]: TUnit} = {
104
+ const units: { [name: string]: TUnit } = {
126
105
  seconds: { max: 60000, past: 'just now', future: 'now' },
127
106
  minute: { max: 2760000, divisor: 60000, past: 'a minute ago', future: 'in a minute' }, // max: 46 minutes
128
107
  hour: { max: 72000000, divisor: 3600000, past: 'an hour ago', future: 'in an hour' }, // max: 20 hours
@@ -132,13 +111,10 @@ const units: {[name: string]: TUnit} = {
132
111
  year: { max: Infinity, divisor: 31536000000, past: 'last year', future: 'in a year' },
133
112
  };
134
113
 
135
- export function ago(date: Date | string, { min, max }: { min?: string, max?: string } = {}): string {
136
-
137
- if (!date)
138
- return '-';
114
+ export function ago(date: Date | string, { min, max }: { min?: string; max?: string } = {}): string {
115
+ if (!date) return '-';
139
116
 
140
- if (typeof date === 'string')
141
- date = new Date(date);
117
+ if (typeof date === 'string') date = new Date(date);
142
118
 
143
119
  const minUnit = min ? units[min].max : 0;
144
120
  const diff = Date.now() - date.getTime();
@@ -148,32 +124,21 @@ export function ago(date: Date | string, { min, max }: { min?: string, max?: str
148
124
  let unit!: TUnit;
149
125
  for (unitName in units) {
150
126
  unit = units[unitName];
151
- if (unit.max >= minUnit && (delta < unit.max || unitName === max))
152
- break;
127
+ if (unit.max >= minUnit && (delta < unit.max || unitName === max)) break;
153
128
  }
154
129
 
155
- if (unit.divisor === undefined)
156
- return diff < 0 ? unit.future : unit.past;
130
+ if (unit.divisor === undefined) return diff < 0 ? unit.future : unit.past;
157
131
 
158
132
  var val = Math.round(delta / unit.divisor);
159
- if (diff < 0)
160
- return val <= 1 ? unit.future : 'in ' + val + ' ' + unitName + 's';
161
- else
162
- return val <= 1 ? unit.past : val + ' ' + unitName + 's ago';
163
-
164
- };
133
+ if (diff < 0) return val <= 1 ? unit.future : 'in ' + val + ' ' + unitName + 's';
134
+ else return val <= 1 ? unit.past : val + ' ' + unitName + 's ago';
135
+ }
165
136
 
166
137
  export const daysAgo = (date: string) => {
138
+ const days = dayjs().diff(date, 'days');
167
139
 
168
- const days = dayjs().diff(date, 'days')
169
-
170
- if (days === 0)
171
- return 'Today';
172
- else if (days === 1)
173
- return 'Yesterday';
174
- else if (days <= 7)
175
- return days + ' days ago'
176
- else
177
- return dayjs(date).format('DD/MM');
178
-
179
- }
140
+ if (days === 0) return 'Today';
141
+ else if (days === 1) return 'Yesterday';
142
+ else if (days <= 7) return days + ' days ago';
143
+ else return dayjs(date).format('DD/MM');
144
+ };