proteum 1.0.2 → 2.0.0-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +14 -49
  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
@@ -11,13 +11,16 @@
11
11
  import express from 'express';
12
12
 
13
13
  // Core
14
- import { Application } from '@server/app';
14
+ import context from '@server/context';
15
15
  import type { AnyRouterService, default as ServerRouter, TServerRouter, TAnyRouter } from '@server/services/router';
16
16
  import ServerRequest from '@server/services/router/request';
17
- import { TRoute, TAnyRoute, TDomainsList } from '@common/router';
17
+ import { TMatchedRoute, TRoute, TAnyRoute, TDomainsList } from '@common/router';
18
18
  import { NotFound, Forbidden, Anomaly } from '@common/errors';
19
19
  import BaseResponse, { TResponseData } from '@common/router/response';
20
+ import { splitRouteSetupResult } from '@common/router/pageSetup';
20
21
  import Page from './page';
22
+ import createControllers from '@/common/.generated/controllers';
23
+ import type { TControllers } from '@/common/.generated/controllers';
21
24
 
22
25
  // To move into a new npm module: json-mask
23
26
  import jsonMask from './mask';
@@ -32,72 +35,62 @@ import type { TBasicUser } from '@server/services/auth';
32
35
  const debug = true;
33
36
 
34
37
  export type TBasicSSrData = {
35
- request: { data: TObjetDonnees, id: string },
36
- page: { chunkId: string, data?: TObjetDonnees },
37
- user: TBasicUser | null,
38
- domains: TDomainsList
39
- }
38
+ request: { data: TObjetDonnees; id: string };
39
+ page: { chunkId: string; data?: TObjetDonnees };
40
+ user: TBasicUser | null;
41
+ domains: TDomainsList;
42
+ };
40
43
 
41
- export type TRouterContext<TRouter extends TServerRouter> = (
44
+ export type TRouterContext<TRouter extends TServerRouter> =
42
45
  // Request context
43
46
  {
44
- app: TRouter["app"],
45
- context: TRouterContext<TRouter>, // = this
46
- request: ServerRequest<TRouter>,
47
- api: ServerRequest<TRouter>["api"],
48
- response: ServerResponse<TRouter>,
49
- route: TRoute,
50
- page?: Page,
51
-
52
- Router: TRouter,
53
- }
54
- & TRouterContextServices<TRouter>
55
- & TRouterRequestContext<TRouter>
56
- )
57
-
58
- export type TRouterContextServices<
59
- TRouter extends TServerRouter,
60
- TPlugins = TRouter["config"]["plugins"]
61
- > = (
47
+ app: TRouter['app'];
48
+ context: TRouterContext<TRouter>; // = this
49
+ request: ServerRequest<TRouter>;
50
+ api: ServerRequest<TRouter>['api'];
51
+ response: ServerResponse<TRouter>;
52
+ route: TAnyRoute<TRouterContext<TRouter>>;
53
+ page?: Page;
54
+
55
+ Router: TRouter;
56
+ } & TRouterContextServices<TRouter> &
57
+ TControllers &
58
+ TRouterRequestContext<TRouter>;
59
+
60
+ export type TRouterContextServices<TRouter extends TServerRouter, TPlugins = TRouter['config']['plugins']> =
62
61
  // Custom context via servuces
63
62
  // For each roiuter service, return the request service (returned by roiuterService.requestService() )
64
63
  {
65
- [serviceName in keyof TPlugins]: TPlugins[serviceName] extends AnyRouterService
66
- ? ReturnType<TPlugins[serviceName]["requestService"]>
67
- : TPlugins[serviceName]
68
- }
69
- )
70
-
71
- export type TRouterRequestContext<
72
- TRouter extends TServerRouter
73
- > = ReturnType<TRouter["config"]["context"]>
64
+ [serviceName in keyof TPlugins]: TPlugins[serviceName] extends AnyRouterService
65
+ ? Exclude<ReturnType<TPlugins[serviceName]['requestService']>, null | undefined>
66
+ : TPlugins[serviceName];
67
+ };
74
68
 
69
+ export type TRouterRequestContext<TRouter extends TServerRouter> = ReturnType<TRouter['config']['context']>;
75
70
 
76
71
  /*----------------------------------
77
72
  - CLASSE
78
73
  ----------------------------------*/
79
74
  export default class ServerResponse<
80
75
  TRouter extends TAnyRouter,
81
- TRequestContext = TRouterContext<TAnyRouter>,
82
- TData extends TResponseData = TResponseData
76
+ TRequestContext extends TRouterContext<TRouter> = TRouterContext<TRouter>,
77
+ TData extends TResponseData = TResponseData,
83
78
  > extends BaseResponse<TData, ServerRequest<TRouter>> {
84
-
85
79
  // Services
86
- public app: Application;
80
+ public app: TRouter['app'];
87
81
  public router: TRouter;
88
82
 
89
83
  // Response metadata
90
84
  public statusCode: number = 200;
91
- public headers: {[cle: string]: string} = {}
92
- public cookie: express.Response["cookie"];
93
- public clearCookie: express.Response["clearCookie"];
85
+ public headers: { [cle: string]: string } = {};
86
+ public cookie: express.Response['cookie'];
87
+ public clearCookie: express.Response['clearCookie'];
94
88
  public canonicalUrl: URL;
95
89
 
96
90
  // If data was provided by at lead one controller
97
91
  public wasProvided = false;
98
92
 
99
- public constructor( request: ServerRequest<TRouter> ) {
100
-
93
+ public constructor(request: ServerRequest<TRouter>) {
101
94
  super(request);
102
95
 
103
96
  this.cookie = this.request.res.cookie.bind(this.request.res);
@@ -110,44 +103,42 @@ export default class ServerResponse<
110
103
  this.canonicalUrl.search = '';
111
104
  }
112
105
 
113
- public async runController( route: TAnyRoute, additionnalData: {} = {} ) {
114
-
106
+ public async runController(route: TAnyRoute<TRouterContext<TRouter>>, additionnalData: {} = {}) {
115
107
  this.route = route;
116
108
 
117
109
  // Update canonical url
118
110
  this.updateCanonicalUrl(route);
119
111
 
120
112
  // Create response context for controllers
121
- const context = await this.createContext(route);
113
+ const requestContext = await this.createContext(route);
114
+ const contextStore = context.getStore() as
115
+ | { requestContext?: TRouterContext<TAnyRouter>; inputSchemaUsed?: boolean }
116
+ | undefined;
117
+ if (contextStore) {
118
+ contextStore.requestContext = requestContext;
119
+ contextStore.inputSchemaUsed = false;
120
+ }
122
121
 
123
122
  // Run controller
124
- const content = await this.route.controller( context );
125
- if (content === undefined)
126
- return;
123
+ const content = await this.route.controller(requestContext);
124
+ if (content === undefined) return;
127
125
 
128
126
  // No need to process the content
129
- if (content instanceof ServerResponse)
130
- return;
127
+ if (content instanceof ServerResponse) return;
131
128
  // Render react page to html
132
- else if (content instanceof Page)
133
- await this.render(content, context, additionnalData);
129
+ else if (content instanceof Page) await this.render(content, requestContext, additionnalData);
134
130
  // Return HTML
135
- else if (typeof content === 'string' && this.route.options.accept === 'html')
136
- await this.html(content);
131
+ else if (typeof content === 'string' && this.route.options.accept === 'html') await this.html(content);
137
132
  // Return JSON
138
- else
139
- await this.json(content);
133
+ else await this.json(content);
140
134
  }
141
135
 
142
- private updateCanonicalUrl( route: TAnyRoute ) {
143
-
144
- if (!route.options.canonicalParams)
145
- return;
136
+ private updateCanonicalUrl(route: TAnyRoute<TRouterContext<TRouter>>) {
137
+ if (!route.options.canonicalParams) return;
146
138
 
147
139
  for (const key of route.options.canonicalParams) {
148
- const paramValue = this.request.data[ key ];
149
- if (paramValue !== undefined)
150
- this.canonicalUrl.searchParams.set(key, paramValue);
140
+ const paramValue = this.request.data[key];
141
+ if (paramValue !== undefined) this.canonicalUrl.searchParams.set(key, paramValue);
151
142
  }
152
143
  }
153
144
 
@@ -155,51 +146,58 @@ export default class ServerResponse<
155
146
  - INTERNAL
156
147
  ----------------------------------*/
157
148
 
158
- // Start controller services
159
- private async createContext( route: TRoute ): Promise<TRequestContext> {
149
+ public async resolveRouteOptions(
150
+ route: TMatchedRoute<TRouterContext<TRouter>>,
151
+ ): Promise<TMatchedRoute<TRouterContext<TRouter>>> {
152
+ const setup = route.options.setup;
153
+ if (!setup) return route;
154
+
155
+ const requestContext = await this.createContext(route);
156
+ const { options } = splitRouteSetupResult(((setup as any)({ ...requestContext, data: this.request.data }) as {}) || {});
157
+
158
+ return { ...route, options: { ...route.options, ...options } };
159
+ }
160
160
 
161
+ // Start controller services
162
+ private async createContext(route: TAnyRoute<TRouterContext<TRouter>>): Promise<TRequestContext> {
161
163
  const contextServices = this.router.createContextServices(this.request);
162
164
 
163
- const customSsrData = this.router.config.context(this.request, this.app);
165
+ const customSsrData = this.router.config.context(this.request, this.app) as TRouterRequestContext<TRouter>;
164
166
 
165
167
  // TODO: transmiss safe data (especially for Router), as Router info could be printed on client side
166
- const context: TRequestContext = {
168
+ const requestContext = {
167
169
  // Router context
168
170
  app: this.app,
169
- context: undefined as TRequestContext,
171
+ context: undefined!,
170
172
  request: this.request,
171
173
  response: this,
172
174
  route: route,
173
175
  api: this.request.api,
174
176
 
175
177
  Router: this.router,
178
+ ...(this.app as {}),
179
+ ...createControllers(this.request.api),
176
180
 
177
181
  // Router services
178
182
  ...(contextServices as TRouterContextServices<TRouter>),
179
- ...customSsrData
180
- }
183
+ ...customSsrData,
184
+ } as TRequestContext;
181
185
 
182
- context.context = context;
186
+ requestContext.context = requestContext;
183
187
 
184
- return context;
188
+ return requestContext;
185
189
  }
186
190
 
187
- public forSsr( page: Page<TRouter> ): TBasicSSrData {
188
-
191
+ public forSsr(page: Page<TRouter>): TBasicSSrData {
189
192
  const customSsrData = this.router.config.context(this.request, this.app);
190
193
 
191
194
  return {
192
- request: {
193
- id: this.request.id,
194
- data: this.request.data,
195
- },
196
- page: {
197
- chunkId: page.chunkId,
198
- data: page.data
199
- },
195
+ request: { id: this.request.id, data: this.request.data },
196
+ page: { chunkId: page.chunkId || '', data: page.data },
197
+ user: this.request.user,
200
198
  domains: this.router.config.domains,
201
- ...customSsrData
202
- }
199
+ ...customSsrData,
200
+ };
203
201
  }
204
202
 
205
203
  public status(code: number) {
@@ -207,29 +205,29 @@ export default class ServerResponse<
207
205
  return this;
208
206
  }
209
207
 
210
- public setHeaders( headers: {[cle: string]: string} ) {
208
+ public setHeaders(headers: { [cle: string]: string }) {
211
209
  this.headers = { ...this.headers, ...headers };
212
210
  return this;
213
211
  }
214
-
212
+
215
213
  /*----------------------------------
216
214
  - DATA RESPONSE
217
215
  ----------------------------------*/
218
216
 
219
- public type( mimetype: string ) {
217
+ public type(mimetype: string) {
220
218
  this.headers['Content-Type'] = mimetype;
221
219
  return this;
222
220
  }
223
221
 
224
- public async render( page: Page, context: TRouterContext<TRouter>, additionnalData: {} ) {
225
-
222
+ public async render(page: Page, context: TRouterContext<TRouter>, additionnalData: {}) {
226
223
  // Set page in context for the client side
227
224
  context.page = page;
228
-
225
+
229
226
  // Prepare page & fetch data
230
227
  page.data = await page.fetchData();
231
- if (additionnalData !== undefined) // Example: error message for error pages
232
- page.data = { ...page.data, ...additionnalData }
228
+ if (additionnalData !== undefined)
229
+ // Example: error message for error pages
230
+ page.data = { ...page.data, ...additionnalData };
233
231
 
234
232
  // Render page
235
233
  await this.router.runHook('render', page);
@@ -238,51 +236,42 @@ export default class ServerResponse<
238
236
 
239
237
  // Never put html in the cache
240
238
  // Because assets urls need to be updated when their hash has been changed by a release
241
- this.request.res.setHeader("Expires", "0");
242
-
239
+ this.request.res.setHeader('Expires', '0');
243
240
  }
244
241
 
245
242
  public async json(data?: any, mask?: string) {
246
-
247
243
  // RAPPEL: On jsonMask aussi les requetes internes, car leurs données seront imprimées au SSR pour le contexte client
248
244
  // filtreApi vérifie systèmatiquement si la donnée a été filtrée
249
245
  // NOTE: On évite le filtrage sans masque spécifié (performances + risques erreurs)
250
- if (mask !== undefined)
251
- data = await jsonMask(data, mask, this.request.user);
246
+ if (mask !== undefined) data = await jsonMask(data, mask);
252
247
 
253
248
  this.headers['Content-Type'] = 'application/json';
254
- this.data = this.request.isVirtual ? data : JSON.stringify(data);
249
+ this.data = (this.request.isVirtual ? data : JSON.stringify(data)) as TData;
255
250
  return this.end();
256
251
  }
257
252
 
258
253
  public html(html: string) {
259
-
260
254
  this.headers['Content-Type'] = 'text/html';
261
- this.data = html;
255
+ this.data = html as TData;
262
256
  return this.end();
263
-
264
257
  }
265
258
 
266
259
  public xml(xml: string) {
267
-
268
260
  this.headers['Content-Type'] = 'text/xml';
269
- this.data = xml;
261
+ this.data = xml as TData;
270
262
  return this.end();
271
263
  }
272
264
 
273
265
  public text(text: string, mimetype: string = 'text/plain') {
274
-
275
266
  this.headers['Content-Type'] = mimetype;
276
- this.data = text;
267
+ this.data = text as TData;
277
268
  return this.end();
278
269
  }
279
270
 
280
271
  // TODO: https://github.com/adonisjs/http-server/blob/develop/src/Response/index.ts#L430
281
- public async file( filename: string, mimetype?: string ) {
282
-
272
+ public async file(filename: string, mimetype?: string) {
283
273
  // Securité
284
- if (filename.includes('..'))
285
- throw new Forbidden("Disallowed");
274
+ if (filename.includes('..')) throw new Forbidden('Disallowed');
286
275
 
287
276
  // // Force absolute path
288
277
  // if (!filename.startsWith( this.app.path.root ))
@@ -291,7 +280,9 @@ export default class ServerResponse<
291
280
  // : this.app.path.data + '/' + filename;
292
281
  // Disk not provided = file response disabled
293
282
  if (this.router.disks === undefined)
294
- throw new Anomaly("Router: Unable to return file response in router, because no disk has been given in the router config.");
283
+ throw new Anomaly(
284
+ 'Router: Unable to return file response in router, because no disk has been given in the router config.',
285
+ );
295
286
 
296
287
  // Retirve disk driver
297
288
  const disk = this.router.disks.get('default');
@@ -299,29 +290,24 @@ export default class ServerResponse<
299
290
  // Verif existance
300
291
  const fileExists = await disk.exists('data', filename);
301
292
  if (!fileExists) {
302
- console.log("File " + filename + " was not found.");
293
+ console.log('File ' + filename + ' was not found.');
303
294
  throw new NotFound();
304
295
  }
305
296
 
306
297
  // envoi filename
307
- const file = await disk.readFile('data', filename, {
308
- encoding: 'buffer'
309
- });
310
- this.data = file;
311
-
298
+ const file = await disk.readFile('data', filename, { encoding: 'buffer' });
299
+ this.data = file as TData;
312
300
 
313
301
  // Mimetype
314
- if (mimetype !== undefined)
315
- this.headers['Content-Type'] = mimetype;
302
+ if (mimetype !== undefined) this.headers['Content-Type'] = mimetype;
316
303
 
317
304
  return this.end();
318
305
  }
319
306
 
320
307
  public redirect(url: string, code: number = 302, absolute: boolean = false) {
321
-
322
- debug && console.log("[routeur][response] Redirect", url);
308
+ debug && console.log('[routeur][response] Redirect', url);
323
309
  this.statusCode = code;
324
- this.headers['Location'] = this.router.url( url, {}, absolute );
310
+ this.headers['Location'] = this.router.url(url, {}, absolute);
325
311
  return this.end();
326
312
  }
327
313
 
@@ -334,5 +320,4 @@ export default class ServerResponse<
334
320
  this.wasProvided = false;
335
321
  return this;
336
322
  }
337
-
338
- }
323
+ }
@@ -23,28 +23,23 @@ const maxLevel = 10; // Prévention contre les références circulaires
23
23
  - CLASS
24
24
  ----------------------------------*/
25
25
  export default class Filtre {
26
-
27
- public constructor() {
28
-
29
-
30
- }
26
+ public constructor() {}
31
27
 
32
28
  public filtrer(
33
29
  donnee: TObjet | Array<unknown> | Date,
34
30
  schema?: TSelecteur,
35
31
  chemin: string[] = [],
36
- schemaParent?: TObjet
32
+ schemaParent?: TObjet,
37
33
  ): any {
38
-
39
34
  // Prévention contre les références circulaires
40
35
  if (chemin.length > maxLevel)
41
- throw new Error(`Erreur: Niveau max (${maxLevel}) atteint via la branche ${chemin.join('.')}. Vérifier s'il n'existe pas une référence circulaire dans l'objet à filtrer.`)
36
+ throw new Error(
37
+ `Erreur: Niveau max (${maxLevel}) atteint via la branche ${chemin.join('.')}. Vérifier s'il n'existe pas une référence circulaire dans l'objet à filtrer.`,
38
+ );
42
39
 
43
40
  try {
44
-
45
41
  // Tableau: on itère chaque élement de celui-ci
46
42
  if (Array.isArray(donnee)) {
47
-
48
43
  debug && console.log(`[requete][reponse][filtre]`, chemin.join('.'), ': Tableau');
49
44
 
50
45
  return this.tableau(donnee, schema, chemin, schemaParent);
@@ -53,38 +48,25 @@ export default class Filtre {
53
48
  // Si la donnée est une chaine, un nombre, etc ... On la traite comme s'il y avait un true
54
49
  } else if (
55
50
  // Extrémité de la branche
56
- schema === true
57
- ||
51
+ schema === true ||
58
52
  // Valeur non-itérable
59
- !donnee
60
- ||
61
- typeof donnee !== 'object'
62
- ||
53
+ !donnee ||
54
+ typeof donnee !== 'object' ||
63
55
  donnee instanceof Date
64
56
  ) {
65
-
66
57
  debug && console.log(`[requete][reponse][filtre]`, chemin.join('.'), ': Valeur');
67
58
 
68
- return this.valeur(
69
- donnee,
70
- schema,
71
- chemin
72
- );
59
+ return this.valeur(donnee, schema, chemin);
73
60
 
74
61
  // Objet
75
62
  } else {
76
-
77
63
  debug && console.log(`[requete][reponse][filtre]`, chemin.join('.'), ': Objet');
78
64
 
79
65
  return this.objet(donnee, schema, chemin, schemaParent);
80
-
81
66
  }
82
-
83
67
  } catch (error) {
84
-
85
68
  console.error('Erreur =', error, '|| données =', donnee, '|| chemin =', chemin, '|| schema =', schema);
86
69
  throw new Error(`Erreur lors du filtrage. Infos ci-dessus.`);
87
-
88
70
  }
89
71
  }
90
72
 
@@ -93,9 +75,8 @@ export default class Filtre {
93
75
  schema: TSelecteur | undefined,
94
76
 
95
77
  chemin: string[],
96
- schemaParent?: TObjet
78
+ schemaParent?: TObjet,
97
79
  ) {
98
-
99
80
  let retour: any[] = [];
100
81
 
101
82
  for (const iElem in donnee) {
@@ -105,9 +86,9 @@ export default class Filtre {
105
86
  schema,
106
87
 
107
88
  [...chemin, iElem],
108
- schemaParent
109
- )
110
- )
89
+ schemaParent,
90
+ ),
91
+ );
111
92
  }
112
93
 
113
94
  return retour;
@@ -118,39 +99,34 @@ export default class Filtre {
118
99
  schema: TSelecteur | undefined,
119
100
 
120
101
  chemin: string[],
121
- schemaParent?: TObjet
102
+ schemaParent?: TObjet,
122
103
  ) {
123
-
124
104
  if (typeof schema === 'object') {
125
-
126
105
  // Exemple: article ( titre enfant( @ ) )
127
106
  // Copie du schéma parent
128
107
  if (schema['@'] === true) {
129
-
130
108
  if (schemaParent === undefined)
131
- throw new Error(`Référence au schéma parent trouvée, mais impossible d'accéder au schéma parent (schemaParent = undefined)`);
109
+ throw new Error(
110
+ `Référence au schéma parent trouvée, mais impossible d'accéder au schéma parent (schemaParent = undefined)`,
111
+ );
132
112
 
133
113
  schema = schemaParent;
134
114
 
135
115
  // Exemple: *
136
116
  // Parcours et filtre toutes les entrées
137
117
  } else if (schema['*'] === true) {
138
-
139
118
  // L'itération se fera directement sur les données fournies
140
119
  schema = undefined;
141
120
 
142
121
  // Exemple: * ( nom symbole )
143
122
  // Applique un selecteurs à toutes les entrées
144
123
  } else if (schema['*'] !== undefined) {
145
-
146
124
  const schemaBranches = schema['*'];
147
125
  schema = {};
148
126
 
149
127
  // Applique le schema du wildcard à toutes les entrées de l'objet
150
128
  // TODO: alternative plus performante
151
- for (const cle in donnee)
152
- schema[cle] = schemaBranches;
153
-
129
+ for (const cle in donnee) schema[cle] = schemaBranches;
154
130
  }
155
131
  }
156
132
 
@@ -159,62 +135,46 @@ export default class Filtre {
159
135
  // Liste des clés à itérer
160
136
  let clesAiterer: string[];
161
137
  if (schema !== undefined)
162
- clesAiterer = Object.keys(schema as object);
163
- else // En dernier recours, on itère tout simplement les données de l'objet
164
- clesAiterer = Object.keys(donnee);
138
+ clesAiterer = Object.keys(schema as object); // En dernier recours, on itère tout simplement les données de l'objet
139
+ else clesAiterer = Object.keys(donnee);
165
140
 
166
141
  // Objet
167
142
  for (const nomBranche of clesAiterer) {
168
-
169
143
  const cheminA = [...chemin, nomBranche];
170
144
  let donneeBranche = undefined;
171
145
 
172
146
  // Extraction de la valeur de la propriété
173
- if (donneeBranche === undefined)
174
- donneeBranche = donnee[nomBranche];
147
+ if (donneeBranche === undefined) donneeBranche = donnee[nomBranche];
175
148
 
176
149
  // Filtrage de la valeur de la propriété
177
- retour[nomBranche] = this.filtrer(
178
- donneeBranche,
179
- schema !== undefined ? schema[nomBranche] : undefined,
150
+ const objectSchema = typeof schema === 'object' && schema !== null ? schema : undefined;
180
151
 
181
- cheminA,
182
-
183
- schema as TObjet
184
- );
152
+ retour[nomBranche] = this.filtrer(donneeBranche, objectSchema?.[nomBranche], cheminA, schema as TObjet);
185
153
  }
186
154
 
187
155
  return retour;
188
156
  }
189
157
 
190
158
  // Traitement des données aux extrémités (auxquelles font référence les true)
191
- private valeur(
192
- donnee: any,
193
- schema: TSelecteur,
194
- chemin: string[]
195
- ) {
196
-
159
+ private valeur(donnee: any, schema: TSelecteur | undefined, chemin: string[]) {
197
160
  // Si sélecteur wildcard
198
- const wildcard = typeof schema === 'object' && schema['*'] === true
161
+ const wildcard = typeof schema === 'object' && schema['*'] === true;
199
162
 
200
163
  // Traitement des objets
201
164
  if (donnee && typeof donnee === 'object') {
202
-
203
165
  // Promise
204
166
  if (typeof donnee.then === 'function')
205
- throw new Error(chemin.join('.') + ": Les promises ne sont pas autorisées en retour api, sauf via un getter de modèle.");
206
-
167
+ throw new Error(
168
+ chemin.join('.') +
169
+ ': Les promises ne sont pas autorisées en retour api, sauf via un getter de modèle.',
170
+ );
207
171
  // Sinon, wildcard obliatoire si on souhaite conserver l'objet entier
208
172
  else if (wildcard === false) {
209
-
210
- if (donnee instanceof Date)
211
- return donnee.toISOString();
173
+ if (donnee instanceof Date) return donnee.toISOString();
212
174
  // Mauvaise idée: Les instances de modèle Sequelize possèdent une méthode toString()
213
175
  /*else if (typeof donnee.toString === 'function')
214
176
  return donnee.toString();*/
215
-
216
177
  }
217
-
218
178
  }
219
179
 
220
180
  return donnee;
@@ -319,5 +279,4 @@ export default class Filtre {
319
279
  return false;
320
280
  }
321
281
  }*/
322
-
323
- }
282
+ }