5htp-core 0.5.0 → 0.5.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 (36) hide show
  1. package/package.json +1 -1
  2. package/src/client/assets/css/core.less +5 -3
  3. package/src/client/assets/css/text/icons.less +4 -1
  4. package/src/client/assets/css/text/text.less +1 -1
  5. package/src/client/assets/css/text/titres.less +4 -3
  6. package/src/client/assets/css/theme.less +2 -1
  7. package/src/client/assets/css/utils/layouts.less +1 -0
  8. package/src/client/assets/css/utils/sizing.less +15 -15
  9. package/src/client/components/Dialog/Manager.tsx +1 -3
  10. package/src/client/components/Dialog/index.less +6 -9
  11. package/src/client/components/Form.ts +62 -31
  12. package/src/client/components/Select/index.tsx +1 -1
  13. package/src/client/components/Table/index.tsx +40 -6
  14. package/src/client/components/button.tsx +36 -23
  15. package/src/client/components/containers/Popover/getPosition.ts +48 -28
  16. package/src/client/components/containers/Popover/index.tsx +9 -3
  17. package/src/client/components/inputv3/Rte/Editor.tsx +64 -5
  18. package/src/client/components/inputv3/Rte/ToolbarPlugin/BlockFormat.tsx +1 -1
  19. package/src/client/components/inputv3/Rte/index.tsx +11 -76
  20. package/src/client/components/inputv3/Rte/plugins/DraggableBlockPlugin/index.css +1 -1
  21. package/src/client/components/inputv3/Rte/style.less +1 -25
  22. package/src/client/components/inputv3/base.tsx +1 -1
  23. package/src/client/components/inputv3/index.tsx +7 -1
  24. package/src/client/services/router/components/router.tsx +4 -3
  25. package/src/client/services/router/index.tsx +2 -1
  26. package/src/client/utils/dom.ts +1 -1
  27. package/src/common/errors/index.tsx +18 -6
  28. package/src/common/router/index.ts +2 -0
  29. package/src/server/services/auth/index.ts +0 -9
  30. package/src/server/services/database/index.ts +2 -2
  31. package/src/server/services/router/http/index.ts +5 -9
  32. package/src/server/services/router/index.ts +26 -49
  33. package/src/server/services/router/request/index.ts +11 -0
  34. package/src/server/services/router/response/index.ts +21 -0
  35. package/src/server/services/router/response/page/document.tsx +1 -4
  36. package/src/server/services/router/response/page/index.tsx +4 -0
@@ -414,22 +414,6 @@ declare type Routes = {
414
414
  // Hook
415
415
  await this.runHook('request', request);
416
416
 
417
- // TODO: move to tracking
418
- /*const now = new Date;
419
-
420
- // Identify Guest & create log entry
421
- const username = request.user?.name;
422
- let clientId: string = request.cookies.clientId;
423
- const newClient = !(typeof clientId === 'string' && clientId.length <= 39)
424
- if (newClient) {
425
- clientId = uuid();
426
- res.cookie('clientId', clientId, { expires: new Date(253402300000000) }); // Never expires
427
- }
428
-
429
- const keepLogs = request.ip !== '86.76.176.80';
430
- if (!keepLogs)
431
- requestId = 'admin';*/
432
-
433
417
  // Create request context so we can access request context across all the request-triggered libs
434
418
  context.run({ channelType: 'request', channelId: requestId }, async () => {
435
419
 
@@ -455,33 +439,6 @@ declare type Routes = {
455
439
  // Data
456
440
  res.send(response.data);
457
441
 
458
- // TODO: move to tracking
459
- /*if (newClient)
460
- console.client({
461
- id: clientId,
462
- ip: request.ip,
463
- user: username,
464
- device: request.deviceString(),
465
- meet: now,
466
- activity: now,
467
- });
468
-
469
- console.request({
470
-
471
- id: requestId,
472
- date: now,
473
-
474
- method: request.method,
475
- url: request.path,
476
- data: request.data,
477
-
478
- ip: request.ip,
479
- user: request.user?.name,
480
- clientId,
481
-
482
- statusCode: response.statusCode,
483
- time: Date.now() - now.valueOf()
484
- });*/
485
442
  });
486
443
  }
487
444
 
@@ -502,12 +459,15 @@ declare type Routes = {
502
459
 
503
460
  public async resolve(request: ServerRequest<this>): Promise<ServerResponse<this>> {
504
461
 
505
- console.info(LogPrefix, request.ip, request.method, request.domain, request.path);
462
+ const logId = LogPrefix + ' ' + (request.isVirtual ? ' ---- ' : '') + request.ip + ' ' + request.method + ' ' + request.domain + ' ' + request.path;
463
+ console.info(logId);
464
+ const timeStart = Date.now();
506
465
 
507
466
  if (this.status === 'starting') {
508
467
  console.log(LogPrefix, `Waiting for servert to be resdy before resolving request`);
509
468
  await this.started;
510
469
  }
470
+
511
471
  try {
512
472
 
513
473
  const response = new ServerResponse<this>(request);
@@ -530,12 +490,14 @@ declare type Routes = {
530
490
 
531
491
  // Run on resolution hooks. Ex: authentication check
532
492
  await this.runHook('resolved', route);
493
+ const timeEndResolving = Date.now();
533
494
 
534
495
  // Create response
535
496
  await response.runController(route);
536
- if (response.wasProvided)
537
- // On continue l'itération des routes, sauf si des données ont été fournie dans la réponse (.json(), .html(), ...)
497
+ if (response.wasProvided) {
498
+ this.printTakenTime(logId, timeStart, timeEndResolving);
538
499
  return response;
500
+ }
539
501
  }
540
502
 
541
503
  throw new NotFound();
@@ -551,10 +513,20 @@ declare type Routes = {
551
513
  error.details.origin = errOrigin;
552
514
  }
553
515
 
516
+ this.printTakenTime(logId, timeStart);
554
517
  throw error;
555
518
  }
556
519
  }
557
520
 
521
+ private printTakenTime = (logId: string, timeStart: number, timeEndResolving?: number) => {
522
+
523
+ if (this.app.env.name === 'server') return;
524
+
525
+ console.log(logId + ' ' + Math.round(Date.now() - timeStart) + 'ms' +
526
+ (timeEndResolving === undefined ? '' : ' | Routing: ' + Math.round(timeEndResolving - timeStart))
527
+ );
528
+ }
529
+
558
530
  private async resolveApiBatch( fetchers: TFetcherList, request: ServerRequest<this> ) {
559
531
 
560
532
  // TODO: use api.fetchSync instead
@@ -601,9 +573,14 @@ declare type Routes = {
601
573
  if (this.app.env.profile === 'prod')
602
574
  e.message = "We encountered an internal error, and our team has just been notified. Sorry for the inconvenience.";
603
575
 
604
- // Pour déboguer les erreurs HTTP
605
- } else if (code !== 404 && this.app.env.profile === "dev")
606
- console.warn(e);
576
+ } else {
577
+
578
+ // For debugging HTTP errors
579
+ if (this.app.env.profile === "dev")
580
+ console.warn(e);
581
+
582
+ await this.app.runHook('error.' + code, e, request);
583
+ }
607
584
 
608
585
  // Return error based on the request format
609
586
  if (request.accepts("html")) {
@@ -135,6 +135,17 @@ export default class ServerRequest<
135
135
  return locale ? locale.toUpperCase() : 'EN'
136
136
  }
137
137
 
138
+ public cookie( key: string, consume: boolean = false ) {
139
+
140
+ const value = this.req.cookies[ key ];
141
+
142
+ if (consume)
143
+ this.res.clearCookie(key);
144
+
145
+ return value;
146
+
147
+ }
148
+
138
149
  /*----------------------------------
139
150
  - TESTS
140
151
  ----------------------------------*/
@@ -81,6 +81,8 @@ export default class ServerResponse<
81
81
  public statusCode: number = 200;
82
82
  public headers: {[cle: string]: string} = {}
83
83
  public cookie: express.Response["cookie"];
84
+ public clearCookie: express.Response["clearCookie"];
85
+ public canonicalUrl: URL;
84
86
 
85
87
  // If data was provided by at lead one controller
86
88
  public wasProvided = false;
@@ -90,15 +92,22 @@ export default class ServerResponse<
90
92
  super(request);
91
93
 
92
94
  this.cookie = this.request.res.cookie.bind(this.request.res);
95
+ this.clearCookie = this.request.res.clearCookie.bind(this.request.res);
93
96
 
94
97
  this.router = request.router;
95
98
  this.app = this.router.app;
99
+
100
+ this.canonicalUrl = new URL(request.url);
101
+ this.canonicalUrl.search = '';
96
102
  }
97
103
 
98
104
  public async runController( route: TAnyRoute, additionnalData: {} = {} ) {
99
105
 
100
106
  this.route = route;
101
107
 
108
+ // Update canonical url
109
+ this.updateCanonicalUrl(route);
110
+
102
111
  // Create response context for controllers
103
112
  const context = await this.createContext(route);
104
113
 
@@ -138,6 +147,18 @@ export default class ServerResponse<
138
147
  this.router.cache[ chunkId ] = this.data;
139
148
  }
140
149
 
150
+ private updateCanonicalUrl( route: TAnyRoute ) {
151
+
152
+ if (!route.options.canonicalParams)
153
+ return;
154
+
155
+ for (const key of route.options.canonicalParams) {
156
+ const paramValue = this.request.data[ key ];
157
+ if (paramValue !== undefined)
158
+ this.canonicalUrl.searchParams.set(key, paramValue);
159
+ }
160
+ }
161
+
141
162
  /*----------------------------------
142
163
  - INTERNAL
143
164
  ----------------------------------*/
@@ -57,9 +57,6 @@ export default class DocumentRenderer<TRouter extends Router> {
57
57
 
58
58
  public async page( html: string, page: Page, response: ServerResponse<TRouter> ) {
59
59
 
60
- // TODO: can be customized via page / route config
61
- const canonicalUrl = response.request.req.url;
62
-
63
60
  let attrsBody = {
64
61
  className: [...page.bodyClass].join(' '),
65
62
  };
@@ -94,7 +91,7 @@ export default class DocumentRenderer<TRouter extends Router> {
94
91
  {/* Page */}
95
92
  <title>{page.title}</title>
96
93
  <meta content={page.description} name="description" />
97
- <link rel="canonical" href={canonicalUrl} />
94
+ <link rel="canonical" href={response.canonicalUrl} />
98
95
 
99
96
  {/* SEO, social medias, OG tags, ... */}
100
97
  {page.head.map(({ $, ...attrs }) => (
@@ -120,8 +120,12 @@ export default class ServerPage<TRouter extends Router = Router> extends PageRes
120
120
 
121
121
  private buildMetas() {
122
122
 
123
+ const shouldIndex = this.context.response.statusCode < 300;
124
+
123
125
  const metas = {
124
126
 
127
+ robots: shouldIndex ? 'index' : 'noindex',
128
+
125
129
  'og:type': 'website',
126
130
  'og:locale': this.app.identity.locale,
127
131
  'og:site_name': this.app.identity.web.title,