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
@@ -21,62 +21,53 @@ import * as csp from 'express-csp-header';
21
21
 
22
22
  // Core
23
23
  import Container from '@server/app/container';
24
- import type Router from '..';
24
+ import type { TServerRouter } from '..';
25
25
 
26
26
  // Middlewaees (core)
27
- import { MiddlewareFormData } from './multipart';
27
+ import { isMutipart, MiddlewareFormData } from './multipart';
28
28
 
29
29
  /*----------------------------------
30
30
  - CONFIG
31
31
  ----------------------------------*/
32
32
 
33
33
  export type Config = {
34
-
35
- debug?: boolean,
34
+ debug?: boolean;
36
35
 
37
36
  // Access
38
- domain: string,
39
- port: number,
40
- ssl: boolean,
37
+ domain: string;
38
+ port: number;
39
+ ssl: boolean;
41
40
 
42
41
  // Limitations / Load restriction
43
42
  upload: {
44
- maxSize: string // Expression package bytes
45
- },
46
- csp: {
47
- default?: string[],
48
- styles?: string[],
49
- images?: string[],
50
- scripts: string[],
51
- },
52
- cors?: CorsOptions,
53
- helmet?: Parameters<typeof helmet>[0]
54
- }
43
+ maxSize: string; // Expression package bytes
44
+ };
45
+ csp: { default?: string[]; styles?: string[]; images?: string[]; scripts: string[] };
46
+ cors?: CorsOptions;
47
+ helmet?: Parameters<typeof helmet>[0];
48
+ };
55
49
 
56
- export type Hooks = {
57
-
58
- }
50
+ export type Hooks = {};
59
51
 
60
52
  /*----------------------------------
61
53
  - FUNCTION
62
54
  ----------------------------------*/
63
- export default class HttpServer {
64
-
55
+ export default class HttpServer<TRouter extends TServerRouter = TServerRouter> {
65
56
  public http: http.Server | https.Server;
66
57
  public express: express.Express;
67
58
 
68
59
  public publicUrl: string;
69
60
 
70
- public constructor(
71
- public config: Config,
72
- public router: Router,
73
- public app = router.app
61
+ public constructor(
62
+ public config: Config,
63
+ public router: TRouter,
64
+ public app = router.app,
74
65
  ) {
75
-
76
66
  // Init
77
- this.publicUrl = this.app.env.name === 'local'
78
- ? 'http://localhost:' + this.config.port
79
- : ((this.config.ssl ? 'https' : 'http') + '://' + this.config.domain);
67
+ this.publicUrl =
68
+ this.app.env.name === 'local'
69
+ ? 'http://localhost:' + this.config.port
70
+ : (this.config.ssl ? 'https' : 'http') + '://' + this.config.domain;
80
71
 
81
72
  // Configure HTTP server
82
73
  this.express = express();
@@ -91,8 +82,18 @@ export default class HttpServer {
91
82
  ----------------------------------*/
92
83
 
93
84
  public async start() {
94
-
95
- const routes = this.express
85
+ const routes = this.express;
86
+ const routeRequest = this.router.middleware.bind(this.router);
87
+ const apiOnly =
88
+ (middleware: express.RequestHandler): express.RequestHandler =>
89
+ (req, res, next) =>
90
+ req.path === '/api' || req.path.startsWith('/api/') ? middleware(req, res, next) : next();
91
+ const apiMultipartOnly =
92
+ (middleware: express.RequestHandler): express.RequestHandler =>
93
+ (req, res, next) =>
94
+ (req.path === '/api' || req.path.startsWith('/api/')) && isMutipart(req)
95
+ ? middleware(req, res, next)
96
+ : next();
96
97
 
97
98
  /*----------------------------------
98
99
  - SECURITÉ DE BASE
@@ -100,29 +101,45 @@ export default class HttpServer {
100
101
 
101
102
  // Config
102
103
  routes.set('trust proxy', 1); // Indique qu'on est sous le proxy apache
104
+ /*----------------------------------
105
+ - FAST PATH: API
106
+ ----------------------------------*/
107
+
108
+ // Keep /api requests off the heavier page middleware stack below.
109
+ routes.use(apiOnly(hpp()));
110
+ routes.use(apiOnly(cookieParser()));
111
+ routes.use(apiOnly(express.json({ limit: bytes(this.config.upload.maxSize) })));
112
+ routes.use(
113
+ apiMultipartOnly(
114
+ fileUpload({
115
+ debug: false,
116
+ limits: { fileSize: bytes(this.config.upload.maxSize), abortOnLimit: true },
117
+ }),
118
+ ),
119
+ );
120
+ routes.use(apiMultipartOnly(MiddlewareFormData));
121
+ if (this.config.cors !== undefined) routes.use(apiOnly(cors(this.config.cors)));
122
+ routes.use(apiOnly(routeRequest));
123
+
103
124
  // Diverses protections (dont le disable x-powered-by)
104
- routes.use( helmet(this.config.helmet) );
125
+ routes.use(helmet(this.config.helmet));
105
126
 
106
127
  /*----------------------------------
107
128
  - FICHIERS STATIQUES
108
129
  ----------------------------------*/
109
130
 
110
131
  // Fichiers statiques: Eviter un maximum de middlewares inutiles
111
- // Normalement, seulement utile pour le mode production,
132
+ // Normalement, seulement utile pour le mode production,
112
133
  // Quand mode debug, les ressources client semblent servies par le dev middlewae
113
134
  // Sauf que les ressources serveur ne semblent pas trouvées par le dev-middleware
114
135
  routes.use(compression());
115
136
  routes.use('/public', cors());
116
137
  routes.use(
117
138
  '/public',
118
- express.static( Container.path.root + '/bin/public', {
139
+ express.static(path.join(Container.path.root, APP_OUTPUT_DIR, 'public'), {
119
140
  dotfiles: 'deny',
120
141
  setHeaders: function setCustomCacheControl(res, path) {
121
-
122
- const dontCache = [
123
- '/public/icons',
124
- '/public/client'
125
- ]
142
+ const dontCache = ['/public/icons', '/public/client'];
126
143
 
127
144
  res.setHeader('Cache-Control', 'public, max-age=0');
128
145
 
@@ -132,17 +149,16 @@ export default class HttpServer {
132
149
  } else {
133
150
  res.setHeader('Cache-Control', 'public, max-age=604800000'); // 7 Days
134
151
  }*/
135
-
136
- }
152
+ },
137
153
  }),
138
154
  (req, res) => {
139
155
  res.status(404).send();
140
- }
156
+ },
141
157
  );
142
-
143
- routes.use('/robots.txt', express.static( path.resolve(__dirname, 'public/robots.txt')) );
144
158
 
145
- routes.get("/ping", (req, res) => res.send("pong"));
159
+ routes.use('/robots.txt', express.static(path.resolve(__dirname, 'public/robots.txt')));
160
+
161
+ routes.get('/ping', (req, res) => res.send('pong'));
146
162
 
147
163
  /*----------------------------------
148
164
  - SESSION & SECURITE
@@ -152,66 +168,55 @@ export default class HttpServer {
152
168
  routes.use(hpp());
153
169
 
154
170
  // Init de req.cookies
155
- routes.use(cookieParser())
171
+ routes.use(cookieParser());
156
172
 
157
173
  /*----------------------------------
158
174
  - DÉCODEURS
159
175
  ----------------------------------*/
160
176
  routes.use(
161
-
162
177
  // Décodage des données post
163
178
  express.json({
164
179
  // TODO: prendre en considération les upload de fichiers
165
180
  limit: bytes(this.config.upload.maxSize),
166
181
  verify: (req, res, buf, encoding) => {
167
182
  // Store the raw request body so we can access it later
168
- req.rawBody = buf;
169
- }
183
+ (req as express.Request & { rawBody?: Buffer }).rawBody = buf;
184
+ },
170
185
  }),
171
186
 
172
187
  // Permet de receptionner les données multipart (req.body + req.files)
173
188
  // A mettre avant les services, car l'assignement de req.socket fait planter les uploads
174
- fileUpload({
175
- debug: false,
176
- limits: {
177
- fileSize: bytes(this.config.upload.maxSize),
178
- abortOnLimit: true
179
- },
180
- }),
189
+ fileUpload({ debug: false, limits: { fileSize: bytes(this.config.upload.maxSize), abortOnLimit: true } }),
181
190
 
182
191
  // Décodage des requetes multipart
183
192
  // Peut-être requis par le résolver api
184
- MiddlewareFormData
193
+ MiddlewareFormData,
185
194
  );
186
195
 
187
196
  /*----------------------------------
188
197
  - PAGES / API
189
198
  ----------------------------------*/
190
199
 
191
- if (this.config.cors !== undefined)
192
- routes.use( cors( this.config.cors ));
200
+ if (this.config.cors !== undefined) routes.use(cors(this.config.cors));
193
201
 
194
- routes.use( csp.expressCspHeader({
195
- directives: {
196
- 'script-src': [csp.INLINE, csp.SELF, csp.UNSAFE_EVAL,
197
- ...this.config.csp.scripts
198
- ]
199
- }
200
- }));
201
-
202
- routes.use( this.router.middleware.bind( this.router ) );
202
+ routes.use(
203
+ csp.expressCspHeader({
204
+ directives: { 'script-src': [csp.INLINE, csp.SELF, csp.UNSAFE_EVAL, ...this.config.csp.scripts] },
205
+ }),
206
+ );
207
+
208
+ routes.use(routeRequest);
203
209
 
204
210
  /*----------------------------------
205
211
  - BOOT SERVICES
206
212
  ----------------------------------*/
207
- console.info("Lancement du serveur web");
213
+ console.info('Lancement du serveur web');
208
214
  this.http.listen(this.config.port, () => {
209
215
  console.info(`Web server ready on ${this.publicUrl}`);
210
216
  });
211
-
212
217
  }
213
218
 
214
219
  public async cleanup() {
215
220
  this.http.close();
216
221
  }
217
- }
222
+ }
@@ -2,18 +2,7 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
- // Npm
6
- import mime from 'mime-types';
7
-
8
- // Core
9
- import { InputError } from '@common/errors';
10
-
11
- /*----------------------------------
12
- - TYPES
13
- ----------------------------------*/
14
-
15
5
  import type { Request, Response, NextFunction } from 'express';
16
- import type { FileArray, UploadedFile } from 'express-fileupload';
17
6
 
18
7
  /*----------------------------------
19
8
  - CONFIG
@@ -23,34 +12,30 @@ const reMultipart = /^multipart\/(?:form-data|related)(?:;|$)/i;
23
12
  /*----------------------------------
24
13
  - MIDDLEWARE
25
14
  ----------------------------------*/
26
- export const MiddlewareFormData = (req: Request, res: Response, next: NextFunction) => {
27
-
15
+ export const MiddlewareFormData = (req: Request, _res: Response, next: NextFunction) => {
28
16
  // Verif si multipart
29
- if (!isMutipart( req ))
30
- return next();
31
-
17
+ if (!isMutipart(req)) return next();
18
+
32
19
  // Données body + fichiers
33
- // NOTE: Les données devant obligatoirement passer par le validateur de schema,
20
+ // NOTE: Les données devant obligatoirement passer par le validateur de schema,
34
21
  // On peut mélanger le body et les files sans risque de sécurité
35
22
  req.body = traiterMultipart(req.body, req['files']);
36
23
  //req.files = traiterMultipart(req.files);
37
24
 
38
25
  next();
39
- }
26
+ };
40
27
 
41
28
  /*----------------------------------
42
29
  - FUNCTIONS
43
30
  ----------------------------------*/
44
- export const isMutipart = (req: Request) => req.headers['content-type'] && reMultipart.exec( req.headers['content-type'] );
31
+ export const isMutipart = (req: Request) =>
32
+ req.headers['content-type'] && reMultipart.exec(req.headers['content-type']);
45
33
 
46
34
  export const traiterMultipart = (...canaux: any[]) => {
47
-
48
- let sortie: {[nom: string]: any} = {};
35
+ let sortie: { [nom: string]: any } = {};
49
36
 
50
37
  for (const donnees of canaux) {
51
-
52
- if (!donnees)
53
- continue;
38
+ if (!donnees) continue;
54
39
 
55
40
  for (const fieldPath in donnees) {
56
41
  let donnee = donnees[fieldPath];
@@ -58,32 +43,24 @@ export const traiterMultipart = (...canaux: any[]) => {
58
43
  let brancheA = sortie;
59
44
  const results = [...fieldPath.matchAll(/[^\[\]]+/g)];
60
45
  for (let iCle = 0; iCle < results.length; iCle++) {
61
-
62
- const [cle] = results[ iCle ];
46
+ const [cle] = results[iCle];
63
47
 
64
48
  // Need to go deeper to find data
65
49
  if (iCle !== results.length - 1) {
66
-
67
- if (brancheA[ cle ] === undefined) {
68
- const tableau = !isNaN( results[ iCle + 1 ][0] as any )
69
- brancheA[ cle ] = tableau ? [] : {};
50
+ if (brancheA[cle] === undefined) {
51
+ const tableau = !isNaN(results[iCle + 1][0] as any);
52
+ brancheA[cle] = tableau ? [] : {};
70
53
  }
71
54
 
72
- brancheA = brancheA[ cle ];
55
+ brancheA = brancheA[cle];
73
56
  continue;
74
57
  }
75
58
 
76
59
  // Data reached
77
- if (
78
- typeof donnee === 'object'
79
- &&
80
- donnee.data !== undefined
81
- &&
82
- donnee.data instanceof Buffer
83
- ){
60
+ if (typeof donnee === 'object' && donnee.data !== undefined && donnee.data instanceof Buffer) {
84
61
  const md5 = donnee.md5;
85
62
  const data = donnee.data;
86
- donnee = new File(donnee.data, donnee.name, {
63
+ donnee = new File(donnee.data, donnee.name, {
87
64
  type: donnee.mimetype,
88
65
  lastModified: Date.now(),
89
66
  //size: donnee.size,
@@ -92,11 +69,11 @@ export const traiterMultipart = (...canaux: any[]) => {
92
69
  donnee.md5 = md5;
93
70
  donnee.data = data;
94
71
  }
95
-
96
- brancheA[ cle ] = donnee;
72
+
73
+ brancheA[cle] = donnee;
97
74
  }
98
75
  }
99
76
  }
100
77
 
101
78
  return sortie;
102
- }
79
+ };