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
@@ -1,45 +1,50 @@
1
1
  export type TSide = "left" | "top" | "right" | "bottom";
2
2
 
3
- const debug = false;
3
+ // Margin from container
4
+ const containerMargin = 8;
5
+
6
+ // Margin from the screen/edges
7
+ const screenMargin = 10;
4
8
 
5
9
  export type TPosition = ReturnType<typeof corrigerPosition>;
6
10
 
7
11
  export default function corrigerPosition(
8
12
  container: HTMLElement, // button
9
- popover: HTMLElement, // popover
13
+ popover: HTMLElement, // popover
10
14
  preferredSide: TSide = "bottom",
11
- frame?: HTMLElement // body
15
+ frame?: HTMLElement | null // body or closest positioned ancestor
12
16
  ) {
13
- // Dimensions and bounding rectangles
14
- const popoverDims = { width: popover.offsetWidth, height: popover.offsetHeight };
17
+ // Dimensions
18
+ const popoverDims = {
19
+ width: popover.offsetWidth,
20
+ height: popover.offsetHeight,
21
+ };
15
22
  const containerRect = container.getBoundingClientRect();
16
23
 
17
- // Find the frame if not provided
24
+ // Find frame if not provided
18
25
  if (!frame) {
19
- // Find the closest relative-positioned parent
26
+ // Find the closest relative-positioned or sticky-positioned parent
20
27
  frame = container.parentElement;
21
28
  while (frame && !["relative", "sticky"].includes(getComputedStyle(frame).position)) {
22
29
  frame = frame.parentElement;
23
30
  }
24
-
25
31
  if (!frame) frame = document.body;
26
32
  }
27
33
 
28
- if (debug) console.log("frame", frame);
29
-
30
34
  const frameRect = frame.getBoundingClientRect();
35
+ const frameContRect = document.body.getBoundingClientRect();
31
36
  const frameOffsetTop = frame.scrollTop;
32
37
  const frameOffsetLeft = frame.scrollLeft;
33
38
 
34
- // Calculate available space in each direction relative to the frame
39
+ // Calculate available space (relative to the document body) around the container
35
40
  const space = {
36
- top: containerRect.top - frameRect.top,
37
- bottom: frameRect.bottom - containerRect.bottom,
38
- left: containerRect.left - frameRect.left,
39
- right: frameRect.right - containerRect.right,
41
+ top: containerRect.top - frameContRect.top,
42
+ bottom: frameContRect.bottom - containerRect.bottom,
43
+ left: containerRect.left - frameContRect.left,
44
+ right: frameContRect.right - containerRect.right,
40
45
  };
41
46
 
42
- // Helper function to check if there's enough space
47
+ // Helper to check if the popover can fit on a given side without clipping
43
48
  const canFit = (side: TSide) => {
44
49
  switch (side) {
45
50
  case "top":
@@ -53,7 +58,7 @@ export default function corrigerPosition(
53
58
  }
54
59
  };
55
60
 
56
- // Try preferred side first, then fallback
61
+ // Start with the preferred side; if it doesn't fit, pick the first side that fits
57
62
  let side: TSide = preferredSide;
58
63
  if (!canFit(preferredSide)) {
59
64
  if (canFit("top")) side = "top";
@@ -62,14 +67,17 @@ export default function corrigerPosition(
62
67
  else if (canFit("right")) side = "right";
63
68
  }
64
69
 
65
- // Calculate position based on side
70
+ // Calculate initial position (without screen-margin clamping)
66
71
  const position = { top: 0, left: 0 };
72
+
67
73
  if (side === "top") {
68
74
  position.top =
69
75
  containerRect.top -
70
76
  frameRect.top -
71
77
  popoverDims.height +
72
- frameOffsetTop;
78
+ frameOffsetTop -
79
+ containerMargin; // gap above container
80
+
73
81
  position.left =
74
82
  containerRect.left -
75
83
  frameRect.left +
@@ -79,7 +87,9 @@ export default function corrigerPosition(
79
87
  position.top =
80
88
  containerRect.bottom -
81
89
  frameRect.top +
82
- frameOffsetTop;
90
+ frameOffsetTop +
91
+ containerMargin; // gap below container
92
+
83
93
  position.left =
84
94
  containerRect.left -
85
95
  frameRect.left +
@@ -91,34 +101,44 @@ export default function corrigerPosition(
91
101
  frameRect.top +
92
102
  (containerRect.height - popoverDims.height) / 2 +
93
103
  frameOffsetTop;
104
+
94
105
  position.left =
95
106
  containerRect.left -
96
107
  frameRect.left -
97
108
  popoverDims.width +
98
- frameOffsetLeft;
109
+ frameOffsetLeft -
110
+ containerMargin; // gap to the left of container
99
111
  } else if (side === "right") {
100
112
  position.top =
101
113
  containerRect.top -
102
114
  frameRect.top +
103
115
  (containerRect.height - popoverDims.height) / 2 +
104
116
  frameOffsetTop;
117
+
105
118
  position.left =
106
119
  containerRect.right -
107
120
  frameRect.left +
108
- frameOffsetLeft;
121
+ frameOffsetLeft +
122
+ containerMargin; // gap to the right of container
109
123
  }
110
124
 
111
- // Adjust for overflow
125
+ // Clamp the final position to ensure a screenMargin from edges
112
126
  position.top = Math.max(
113
- frameOffsetTop,
114
- Math.min(frameRect.height - popoverDims.height + frameOffsetTop, position.top)
127
+ frameOffsetTop + screenMargin,
128
+ Math.min(
129
+ frameContRect.height - popoverDims.height + frameOffsetTop - screenMargin,
130
+ position.top
131
+ )
115
132
  );
116
133
  position.left = Math.max(
117
- frameOffsetLeft,
118
- Math.min(frameRect.width - popoverDims.width + frameOffsetLeft, position.left)
134
+ frameOffsetLeft + screenMargin,
135
+ Math.min(
136
+ frameContRect.width - popoverDims.width + frameOffsetLeft - screenMargin,
137
+ position.left
138
+ )
119
139
  );
120
140
 
121
- // Return result
141
+ // Return the final side and position
122
142
  return {
123
143
  side,
124
144
  css: {
@@ -77,15 +77,21 @@ export default (props: Props) => {
77
77
  )
78
78
  );
79
79
 
80
- // Autofocus elements
81
- focusContent( refContent.current );
82
-
83
80
  // Close when the user clicks elsewere tha the popover
84
81
  return blurable([ refCont.current, () => show(false) ])
85
82
  }
86
83
 
87
84
  }, [shown]);
88
85
 
86
+ React.useEffect(() => {
87
+ if (position !== undefined) {
88
+
89
+ // Autofocus elements once the final position has been set
90
+ focusContent( refContent.current );
91
+
92
+ }
93
+ }, [position]);
94
+
89
95
  /*----------------------------------
90
96
  - ATTRIBUTES
91
97
  ----------------------------------*/
@@ -84,10 +84,6 @@ export const EMPTY_STATE = '{"root":{"children":[{"children":[],"direction":null
84
84
  - TYPES
85
85
  ----------------------------------*/
86
86
 
87
- export type Props = {
88
- preview?: boolean,
89
- }
90
-
91
87
  const ValueControlPlugin = ({ props, value }) => {
92
88
 
93
89
  const [editor] = useLexicalComposerContext();
@@ -111,6 +107,69 @@ export default ({ value, setValue, props }: {
111
107
  setValue: (value: string) => void,
112
108
  props: TRteProps
113
109
  }) => {
110
+
111
+ let {
112
+ // Decoration
113
+ title,
114
+ // Actions
115
+ preview = true
116
+ } = props;
117
+
118
+ /*----------------------------------
119
+ - PREVIEW
120
+ ----------------------------------*/
121
+
122
+ const [isPreview, setIsPreview] = React.useState(preview);
123
+ const [html, setHTML] = React.useState(null);
124
+
125
+ React.useEffect(() => {
126
+ if (isPreview) {
127
+ renderPreview(value).then(setHTML);
128
+ }
129
+ }, [value, isPreview]);
130
+
131
+ // When isPreview changes, close the active editor
132
+ React.useEffect(() => {
133
+ if (!isPreview) {
134
+
135
+ // Close active editor
136
+ if (RichEditorUtils.active && RichEditorUtils.active?.title !== title)
137
+ RichEditorUtils.active.close();
138
+
139
+ // Set active Editor
140
+ RichEditorUtils.active = {
141
+ title,
142
+ close: () => preview ? setIsPreview(true) : null
143
+ }
144
+
145
+ }
146
+ }, [isPreview]);
147
+
148
+ const renderPreview = async (value: {} | undefined) => {
149
+
150
+ if (!value)
151
+ return '';
152
+
153
+ if (typeof document === 'undefined')
154
+ throw new Error("HTML preview disabled in server side.");
155
+
156
+ const html = await RichEditorUtils.jsonToHtml(value);
157
+
158
+ return html;
159
+ }
160
+
161
+ if (isPreview)
162
+ return (
163
+ html === null ? (
164
+ <div class="col al-center h-2">
165
+ <i src="spin" />
166
+ </div>
167
+ ) : (
168
+ <div class="preview reading h-1-4 scrollable col clickable"
169
+ onClick={() => setIsPreview(false)}
170
+ dangerouslySetInnerHTML={{ __html: html }} />
171
+ )
172
+ )
114
173
 
115
174
  /*----------------------------------
116
175
  - INIT
@@ -185,7 +244,7 @@ export default ({ value, setValue, props }: {
185
244
  <div className="editor-inner">
186
245
  <RichTextPlugin
187
246
  contentEditable={
188
- <div className="editor pdh-2" ref={onRef}>
247
+ <div className="editor" ref={onRef}>
189
248
  <ContentEditable
190
249
  className="editor-input reading col"
191
250
  aria-placeholder={"Type text here ..."}
@@ -206,7 +206,7 @@ export default function BlockFormatDropDown({
206
206
 
207
207
  return (
208
208
  <DropDown disabled={disabled} icon={currentBlockType ? currentBlockType.icon : 'question'} size="s"
209
- label={currentBlockType ? currentBlockType.label : 'Unknown Block Type'}
209
+ //label={currentBlockType ? currentBlockType.label : 'Unknown Block Type'}
210
210
  popover={{ tag: 'li' }}
211
211
  >
212
212
  {blockTypes.map((block) => (
@@ -21,6 +21,7 @@ import './style.less';
21
21
 
22
22
  export type Props = {
23
23
  preview?: boolean,
24
+ title: string,
24
25
  }
25
26
 
26
27
  /*----------------------------------
@@ -28,22 +29,14 @@ export type Props = {
28
29
  ----------------------------------*/
29
30
  export default (props: Props & InputBaseProps<string>) => {
30
31
 
31
- let {
32
- // Decoration
33
- required, size, title, className = '',
34
- // State
35
- errors,
36
- // Actions
37
- preview = true
38
- } = props;
32
+ let { className = '' } = props;
39
33
 
40
34
  /*----------------------------------
41
35
  - INIT
42
36
  ----------------------------------*/
43
37
 
44
38
  const [Editor, setEditor] = React.useState<{ default: typeof TEditor }>(null);
45
- const [isPreview, setIsPreview] = React.useState(preview);
46
- const [html, setHTML] = React.useState(null);
39
+
47
40
  const [{ value }, setValue] = useInput(props, undefined, true);
48
41
 
49
42
  className += ' input rte';
@@ -53,46 +46,13 @@ export default (props: Props & InputBaseProps<string>) => {
53
46
  ----------------------------------*/
54
47
 
55
48
  React.useEffect(() => {
56
- if (isPreview) {
57
- renderPreview(value).then(setHTML);
58
- }
59
- }, [value, isPreview]);
60
-
61
- // When isPreview changes, close the active editor
62
- React.useEffect(() => {
63
- if (!isPreview) {
64
-
65
- // Close active editor
66
- if (RichEditorUtils.active && RichEditorUtils.active?.title !== title)
67
- RichEditorUtils.active.close();
68
-
69
- // Set active Editor
70
- RichEditorUtils.active = {
71
- title,
72
- close: () => preview ? setIsPreview(true) : null
73
- }
49
+ if (!Editor) {
74
50
 
75
51
  // Load editor component if not alreayd done
76
52
  // We lazy load since it's heavy and needs to be loade donly on client side
77
- if (!Editor) {
78
- import('./Editor').then(setEditor);
79
- }
80
-
53
+ import('./Editor').then(setEditor);
81
54
  }
82
- }, [isPreview]);
83
-
84
- const renderPreview = async (value: {} | undefined) => {
85
-
86
- if (!value)
87
- return '';
88
-
89
- if (typeof document === 'undefined')
90
- throw new Error("HTML preview disabled in server side.");
91
-
92
- const html = await RichEditorUtils.jsonToHtml(value);
93
-
94
- return html;
95
- }
55
+ }, []);
96
56
 
97
57
  /*----------------------------------
98
58
  - RENDER
@@ -101,40 +61,15 @@ export default (props: Props & InputBaseProps<string>) => {
101
61
  <InputWrapper {...props}>
102
62
  <div class={className}>
103
63
 
104
- {isPreview ? (
64
+ {Editor === null ? (
105
65
 
106
- html === null ? (
107
- <div class="col al-center h-2">
108
- <i src="spin" />
109
- </div>
110
- ) : (
111
- <div class="preview reading h-1-4 scrollable col clickable"
112
- onClick={() => setIsPreview(false)}
113
- dangerouslySetInnerHTML={{ __html: html }} />
114
- )
66
+ <div class="col al-center h-2">
67
+ <i src="spin" />
68
+ </div>
115
69
 
116
- ) : Editor !== null && (
70
+ ) : (
117
71
  <Editor.default value={value} setValue={setValue} props={props} />
118
72
  )}
119
-
120
- {/* <Tag {...fieldProps}
121
-
122
- placeholder={props.title}
123
-
124
- // @ts-ignore: Property 'ref' does not exist on type 'IntrinsicAttributes'
125
- ref={refInput}
126
- value={value}
127
- onFocus={() => setState({ focus: true })}
128
- onBlur={() => setState({ focus: false })}
129
- onChange={(e) => updateValue(e.target.value)}
130
- onKeyDown={(e: KeyboardEvent) => {
131
-
132
- if (onPressEnter && e.key === 'Enter' && value !== undefined) {
133
- commitValue();
134
- onPressEnter(value)
135
- }
136
- }}
137
- /> */}
138
73
  </div>
139
74
  </InputWrapper>
140
75
  )
@@ -4,7 +4,7 @@
4
4
  cursor: grab;
5
5
  opacity: 0;
6
6
  position: absolute;
7
- left: 0;
7
+ left: -20px;
8
8
  top: 0;
9
9
  will-change: transform;
10
10
  }
@@ -2,31 +2,7 @@
2
2
 
3
3
  .preview {
4
4
  position: relative;
5
-
6
- &:before {
7
-
8
- content: 'Click here to edit';
9
-
10
- display: flex;
11
- justify-content: center;
12
- align-items: center;
13
-
14
- position: absolute;
15
- top: 0;
16
- left: 0;
17
- right: 0;
18
- bottom: 0;
19
-
20
- background: fade(#FFF, 50%);
21
- pointer-events: none;
22
- z-index: 1;
23
- opacity: 0;
24
- transition: all 0.3s linear;
25
- }
26
-
27
- &:hover:before {
28
- opacity: 1;
29
- }
5
+ cursor: text;
30
6
  }
31
7
 
32
8
  .other h2 {
@@ -41,7 +41,7 @@ export type TInputState<TValue> = {
41
41
  - HOOKS
42
42
  ----------------------------------*/
43
43
  export function useInput<TValue>(
44
- { value: externalValue, onChange, ...otherProps }: InputBaseProps<TValue>,
44
+ { value: externalValue, onChange, className, hint, ...otherProps }: InputBaseProps<TValue>,
45
45
  defaultValue: TValue,
46
46
  autoCommit: boolean = false
47
47
  ): [
@@ -173,7 +173,13 @@ export default (props: Props & InputBaseProps<string> & TInputElementProps) => {
173
173
  ----------------------------------*/
174
174
  return (
175
175
  <InputWrapper {...props}>
176
- <div class={className} onClick={() => refInput.current?.focus()}>
176
+ <div class={className} onClick={(e) => {
177
+
178
+ const shouldFocus = props.onClick ? props.onClick() !== false : true;
179
+ if (shouldFocus)
180
+ refInput.current?.focus()
181
+
182
+ }}>
177
183
 
178
184
  {prefix}
179
185
 
@@ -147,12 +147,12 @@ export default ({ service: clientRouter, loaderComponent }: TProps) => {
147
147
  if (newLayout && curLayout && newLayout.path !== curLayout.path) {
148
148
 
149
149
  // TEMPORARY FIX: reload everything when we change layout
150
- // Because layout can have a different theme
150
+ // Because layout can have a different CSS theme
151
151
  // But when we call setLayout, the style of the previous layout are still oaded and applied
152
152
  // Find a way to unload the previous layout / page resources before to load the new one
153
153
  console.log(LogPrefix, `Changing layout. Before:`, curLayout, 'New layout:', newLayout);
154
- window.location.replace( request ? request.url : location.href );
155
- return { ...page }
154
+ window.location.replace( request ? request.url : window.location.href );
155
+ return page; // Don't spread since it's an instance
156
156
 
157
157
  context.app.setLayout(newLayout);
158
158
  }
@@ -191,6 +191,7 @@ export default ({ service: clientRouter, loaderComponent }: TProps) => {
191
191
  // Reset scroll
192
192
  window.scrollTo(0, 0);
193
193
  // Should be called AFTER rendering the page (so after the state change)
194
+ console.log("CHANGE PAGE", currentPage);
194
195
  currentPage?.updateClient();
195
196
  // Scroll to the selected content via url hash
196
197
  restoreScroll(currentPage);
@@ -124,7 +124,7 @@ export type TRoutesLoaders = {
124
124
 
125
125
  export type THookCallback<TRouter extends ClientRouter> = (request: ClientRequest<TRouter>) => void;
126
126
 
127
- type THookName = 'page.change' | 'page.changed'
127
+ type THookName = 'page.change' | 'page.changed' | 'page.rendered'
128
128
 
129
129
  type Config<TAdditionnalContext extends {} = {}> = {
130
130
  preload: string[], // List of globs
@@ -428,6 +428,7 @@ export default class ClientRouter<
428
428
 
429
429
  console.log(`Render complete`);
430
430
 
431
+ this.runHook('page.rendered', request);
431
432
  });
432
433
  }
433
434
 
@@ -71,7 +71,7 @@ export const focusContent = ( container: HTMLElement ) => {
71
71
 
72
72
  const toFocus = container.querySelector<HTMLInputElement | HTMLTextAreaElement | HTMLButtonElement>(
73
73
  'input, textarea, button.btn.primary, footer > button.btn'
74
- ) || container;
74
+ ) || container; // Is it useful ? Creating unwanted scroll issue on showing popover
75
75
 
76
76
  toFocus?.focus();
77
77
  }
@@ -17,9 +17,13 @@ type TJsonError = {
17
17
  message: string,
18
18
  // Form fields
19
19
  errors?: TListeErreursSaisie
20
- } & TDetailsErreur
20
+ } & TErrorDetails
21
21
 
22
- type TDetailsErreur = {
22
+ type TErrorDetails = {
23
+ // Allow to identify the error catched (ex: displaying custop content, running custom actions, ...)
24
+ id?: string,
25
+ data?: {},
26
+ // For debugging
23
27
  stack?: string,
24
28
  origin?: string,
25
29
  }
@@ -66,13 +70,13 @@ export abstract class CoreError extends Error {
66
70
  public abstract http: number;
67
71
  public title: string = "Uh Oh ...";
68
72
  public message: string;
69
- public details: TDetailsErreur = {};
73
+ public details: TErrorDetails = {};
70
74
 
71
75
  // Note: On ne le redéfini pas ici, car déjà présent dans Error
72
76
  // La redéfinition reset la valeur du stacktrace
73
77
  //public stack?: string;
74
78
 
75
- public constructor(message?: string, details?: TDetailsErreur) {
79
+ public constructor(message?: string, details?: TErrorDetails) {
76
80
 
77
81
  super(message);
78
82
 
@@ -120,7 +124,7 @@ export class InputErrorSchema extends CoreError {
120
124
  return chaines.join('; ');
121
125
  }
122
126
 
123
- public constructor( public errors: TListeErreursSaisie, details?: TDetailsErreur) {
127
+ public constructor( public errors: TListeErreursSaisie, details?: TErrorDetails) {
124
128
 
125
129
  super( InputErrorSchema.listeToString(errors), details );
126
130
 
@@ -162,6 +166,12 @@ export class NotFound extends CoreError {
162
166
  public static msgDefaut = "The resource you asked for was not found.";
163
167
  }
164
168
 
169
+ export class RateLimit extends CoreError {
170
+ public http = 429;
171
+ public title = "You're going too fast";
172
+ public static msgDefaut = "Please slow down a bit and retry again later.";
173
+ }
174
+
165
175
  export class Anomaly extends CoreError {
166
176
 
167
177
  public http = 500;
@@ -193,7 +203,7 @@ export class NetworkError extends Error {
193
203
  export const viaHttpCode = (
194
204
  code: number,
195
205
  message: string,
196
- details?: TDetailsErreur
206
+ details?: TErrorDetails
197
207
  ): CoreError => {
198
208
  return fromJson({
199
209
  code,
@@ -229,6 +239,8 @@ export const fromJson = ({ code, message, ...details }: TJsonError) => {
229
239
 
230
240
  case 404: return new NotFound( message, details );
231
241
 
242
+ case 429: return new RateLimit( message, details );
243
+
232
244
  default: return new Anomaly( message, details );
233
245
  }
234
246
 
@@ -78,7 +78,9 @@ export type TRouteOptions = {
78
78
  // Resolving
79
79
  domain?: string,
80
80
  accept?: string,
81
+ raw?: boolean, // true to return raw data
81
82
  auth?: TUserRole | boolean,
83
+ canonicalParams?: string[],
82
84
 
83
85
  // Rendering
84
86
  static?: boolean,
@@ -43,15 +43,6 @@ export type TConfig = {
43
43
  key: string,
44
44
  expiration: string,
45
45
  },
46
- google?: {
47
- web: {
48
- clientId: string,
49
- secret: string,
50
- },
51
- android: {
52
- clientId: string
53
- }
54
- }
55
46
  }
56
47
 
57
48
  export type THooks = {
@@ -143,7 +143,7 @@ export default class SQL extends Service<Config, Hooks, Application, Services> {
143
143
  query.then = (cb: (data: any) => void) => query().then(cb);
144
144
 
145
145
  query.first = <TRowData extends TObjetDonnees = {}>(opts: TSelectQueryOptions = {}) => this.first<TRowData>(string, opts);
146
- query.firstOrFail = (message?: string, opts: TQueryOptions = {}) => this.firstOrFail<TRowData>(string, message, opts);
146
+ query.firstOrFail = (message: string, opts: TQueryOptions = {}) => this.firstOrFail<TRowData>(string, message, opts);
147
147
 
148
148
  query.value = <TValue extends any = number>(opts: TQueryOptions = {}) => this.selectVal<TValue>(string, opts);
149
149
 
@@ -283,7 +283,7 @@ export default class SQL extends Service<Config, Hooks, Application, Services> {
283
283
  return resultatRequetes[0] || null;
284
284
  });
285
285
 
286
- public firstOrFail = <TRowData extends TObjetDonnees = {}>(query: string, message?: string, opts: TSelectQueryOptions = {}): Promise<TRowData> =>
286
+ public firstOrFail = <TRowData extends TObjetDonnees = {}>(query: string, message: string, opts: TSelectQueryOptions = {}): Promise<TRowData> =>
287
287
  this.select(query, opts).then((resultatRequetes: any) => {
288
288
 
289
289
  if (resultatRequetes.length === 0)
@@ -162,16 +162,12 @@ export default class HttpServer {
162
162
 
163
163
  // Décodage des données post
164
164
  express.json({
165
-
166
- // NOTE: Encore nécessaire ? Les webhooks stripe & bitgo n'étant plus utilisés
167
- // Because Stripe needs the raw body, we compute it but only when hitting the Stripe callback URL.
168
- /*verify: function (req: Request, res: Response, buf: Buffer) {
169
- if (req.originalUrl.startsWith('/api/paiement/impact/stripe'))
170
- //req.rawBody = buf.toString();
171
- },*/
172
-
173
165
  // TODO: prendre en considération les upload de fichiers
174
- limit: '2mb'
166
+ limit: '2mb',
167
+ verify: (req, res, buf, encoding) => {
168
+ // Store the raw request body so we can access it later
169
+ req.rawBody = buf;
170
+ }
175
171
  }),
176
172
 
177
173
  // Permet de receptionner les données multipart (req.body + req.files)