5htp-core 0.4.2-5 → 0.4.3-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 (32) hide show
  1. package/package.json +4 -12
  2. package/src/client/assets/css/utils/layouts.less +1 -1
  3. package/src/client/components/Table/index.tsx +1 -1
  4. package/src/client/components/index.ts +5 -16
  5. package/src/client/services/router/request/api.ts +31 -52
  6. package/src/common/data/dates.ts +50 -6
  7. package/src/common/validation/validators.ts +0 -4
  8. package/src/server/services/router/http/index.ts +16 -22
  9. package/src/server/services/router/response/page/index.tsx +0 -2
  10. package/src/client/components/Amount.tsx +0 -38
  11. package/src/client/components/Form_old/index.tsx +0 -450
  12. package/src/client/components/Form_old/index.tsx.old +0 -436
  13. package/src/client/components/dropdown.old/Manager.tsx +0 -164
  14. package/src/client/components/dropdown.old/getPosition.ts +0 -137
  15. package/src/client/components/dropdown.old/index.tsx +0 -99
  16. package/src/client/components/dropdown.old/popover.less +0 -56
  17. package/src/client/components/input/Base/Choix.ts +0 -48
  18. package/src/client/components/input/Base/index.tsx +0 -432
  19. package/src/client/components/input/BaseV2/index.tsx +0 -72
  20. package/src/client/components/input/Checkbox/old.tsx +0 -74
  21. package/src/client/components/input/Select/Classique.tsx +0 -80
  22. package/src/client/components/input/Select/Liste.tsx +0 -123
  23. package/src/client/components/input/Select/Periode.tsx +0 -50
  24. package/src/client/components/input/Select/Switch.tsx +0 -57
  25. package/src/client/components/input/Select/base.tsx +0 -192
  26. package/src/client/components/input/Select/index.less +0 -60
  27. /package/src/client/components/{input → inputv3}/Checkbox/index.less +0 -0
  28. /package/src/client/components/{input → inputv3}/Checkbox/index.tsx +0 -0
  29. /package/src/client/components/inputv3/{date → Date}/Calendar.css +0 -0
  30. /package/src/client/components/inputv3/{date → Date}/Clock.css +0 -0
  31. /package/src/client/components/inputv3/{date → Date}/DateTimePicker.css +0 -0
  32. /package/src/client/components/inputv3/{date → Date}/index.tsx +0 -0
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "5htp-core",
3
3
  "description": "Convenient TypeScript framework designed for Performance and Productivity.",
4
- "version": "0.4.2-5",
4
+ "version": "0.4.3-1",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -18,12 +18,10 @@
18
18
  "ansi-to-html": "^0.7.1",
19
19
  "array-move": "^3.0.1",
20
20
  "aws-sdk": "^2.1415.0",
21
- "axios": "^1.2.1",
22
21
  "bowser": "^2.11.0",
23
22
  "chart.js": "^3.6.2",
24
23
  "cli-highlight": "^2.1.11",
25
24
  "compression": "^1.7.4",
26
- "connect-redis": "^6.0.0",
27
25
  "cookie-parser": "^1.4.5",
28
26
  "core-js": "^3.18.1",
29
27
  "cors": "^2.8.5",
@@ -34,11 +32,9 @@
34
32
  "express": "^4.17.1",
35
33
  "express-csp-header": "^5.0.0",
36
34
  "express-fileupload": "^1.2.1",
37
- "express-static-gzip": "^2.1.1",
38
35
  "fast-safe-stringify": "^2.1.1",
39
36
  "formattor": "^0.0.2",
40
37
  "fs-extra": "^10.1.0",
41
- "google-auth-library": "^7.11.0",
42
38
  "got": "^11.8.3",
43
39
  "handlebars": "^4.7.7",
44
40
  "helmet": "^4.6.0",
@@ -47,7 +43,6 @@
47
43
  "human-interval": "^2.0.1",
48
44
  "intl": "^1.2.5",
49
45
  "iso-639-1": "^2.1.9",
50
- "javascript-time-ago": "^2.3.9",
51
46
  "js-cookie": "^3.0.1",
52
47
  "jsonwebtoken": "^8.5.1",
53
48
  "load-script": "^2.0.0",
@@ -58,17 +53,15 @@
58
53
  "module-alias": "^2.2.2",
59
54
  "morgan": "^1.10.0",
60
55
  "mysql2": "^2.3.0",
61
- "nodemailer": "^6.6.3",
62
56
  "object-sizeof": "^1.6.3",
63
57
  "path-to-regexp": "^6.2.0",
64
58
  "picomatch": "^2.3.1",
65
- "preact": "^10.5.15",
66
- "preact-render-to-string": "^5.1.19",
59
+ "preact": "^10.22.1",
60
+ "preact-render-to-string": "^6.5.5",
67
61
  "react-datetime-picker": "^5.6.0",
68
62
  "react-scrollbars-custom": "^4.0.27",
69
63
  "react-slider": "^2.0.1",
70
64
  "react-textarea-autosize": "^8.3.3",
71
- "redis": "^3.1.2",
72
65
  "regenerator-runtime": "^0.13.9",
73
66
  "request": "^2.88.2",
74
67
  "sharp": "^0.29.1",
@@ -94,8 +87,7 @@
94
87
  "@types/universal-analytics": "^0.4.5",
95
88
  "@types/webpack-env": "^1.16.2",
96
89
  "@types/ws": "^7.4.7",
97
- "@types/yargs-parser": "^21.0.0",
98
- "babel-plugin-glob-import": "^0.0.7"
90
+ "@types/yargs-parser": "^21.0.0"
99
91
  },
100
92
  "peerDependencies": {
101
93
  "5htp": "0.3.9"
@@ -138,7 +138,7 @@
138
138
  }
139
139
 
140
140
  &, &.al-top { justify-content: flex-start; }
141
- &.al-middle { justify-content: center; }
141
+ &.al-middle, &.al-center { justify-content: center; }
142
142
  &.al-bottom { justify-content: flex-end; }
143
143
 
144
144
  &.al-left { align-items: flex-start; }
@@ -9,7 +9,7 @@ import { ComponentChild } from 'preact';
9
9
  // Composants
10
10
  import Button, { Props as TButtonProps } from '@client/components/button';
11
11
  import Popover from '../containers/Popover';
12
- import Checkbox from '../input/Checkbox';
12
+ import Checkbox from '../inputv3/Checkbox';
13
13
 
14
14
  /*----------------------------------
15
15
  - TYPES
@@ -12,14 +12,11 @@ export { default as Row } from './Row';
12
12
  export { default as Logo } from './logo';
13
13
  export { default as Video } from './Video';
14
14
 
15
- // Input
16
- export { default as Number } from './input/Number';
17
- export { default as Slider } from './input/Slider';
18
- export { default as Radio } from './input/Radio';
19
- export { default as Checkbox } from './input/Checkbox';
15
+ // Input (OLD, TO ADAPT)
16
+ //export { default as Slider } from './input/Slider';
17
+ //export { default as Radio } from './input/Radio';
20
18
 
21
19
  // Data
22
- export { default as Amount } from './Amount';
23
20
  export { default as Time } from './data/Time';
24
21
  export { default as SpinText } from './data/spintext';
25
22
  export { default as Progressbar } from './data/progressbar';
@@ -28,14 +25,6 @@ export { default as CircularProgressbar } from './data/progressbar/circular';
28
25
  // Input V3
29
26
  export { default as Select } from './Select';
30
27
  export { default as Input } from './inputv3';
28
+ export { default as Checkbox } from './inputv3/Checkbox';
31
29
  export { default as File } from './inputv3/file';
32
- export { default as DateRangeInput } from './inputv3/date';
33
-
34
- // TOD: fix popover component
35
- //export { default as Date } from './input/Date';
36
- //export { default as Periode } from './input/Periode';
37
-
38
- // TODO: adapt
39
- //export { default as Couleur } from './input/Couleur';
40
- //export { default as Code } from './input/Code';
41
- //export { default as Rte } from './input/Rte';
30
+ export { default as DateRangeInput } from './inputv3/Date';
@@ -2,9 +2,6 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
- // Npm
6
- import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
7
-
8
5
  // Core
9
6
  import type { TApiResponseData } from '@server/services/router';
10
7
  import ApiClientService, {
@@ -190,83 +187,65 @@ export default class ApiClient implements ApiClientService {
190
187
  return { ...alreadyLoadedData, ...fetchedData }
191
188
  }
192
189
 
193
- public configure = (...[method, path, data, options]: TFetcherArgs): AxiosRequestConfig => {
194
-
190
+ public configure = (...[method, path, data, options]: TFetcherArgs) => {
195
191
  const { onProgress, captcha } = options || {};
196
-
197
- const url = this.router.url( path, {}, false );
198
192
 
199
- debug && console.log(`[api] Sending request`, method, url, data);
193
+ const url = this.router.url(path, {}, false);
200
194
 
201
- // Create AXIOS config
202
- const config: AxiosRequestConfig = {
195
+ debug && console.log(`[api] Sending request`, method, url, data);
203
196
 
204
- url,
197
+ // Create Fetch config
198
+ const config = {
205
199
  method: method,
206
200
  headers: {
207
201
  'Content-Type': "application/json",
208
202
  'Accept': "application/json",
209
- },
210
-
211
- validateStatus: function (status: number) {
212
- return status === 200;
213
- },
214
-
215
- onUploadProgress: onProgress === undefined ? undefined : (e) => {
216
- const percentCompleted = Math.round((e.loaded * 100) / e.total);
217
- onProgress(percentCompleted);
218
203
  }
219
-
220
204
  };
221
205
 
222
206
  // Format request data
223
207
  if (data) {
224
- // URL params
225
208
  if (method === "GET") {
226
- config.params = data;
227
- // Post form data
209
+ const params = new URLSearchParams(data).toString();
210
+ config.url = `${url}?${params}`;
228
211
  } else if (options?.encoding === 'multipart') {
229
212
  config.headers["Content-Type"] = 'multipart/form-data';
230
- config.data = toMultipart(data);
231
- // Post JSON
213
+ const formData = new FormData();
214
+ Object.keys(data).forEach(key => formData.append(key, data[key]));
215
+ config.body = formData;
232
216
  } else {
233
- config.data = data;
217
+ config.body = JSON.stringify(data);
234
218
  }
235
219
  }
236
220
 
237
- return config;
221
+ return { url, config };
238
222
  }
239
223
 
240
224
  public execute<TData = unknown>(...args: TFetcherArgs): Promise<TData> {
225
+ const { url, config } = this.configure(...args);
241
226
 
242
- const config = this.configure(...args);
243
-
244
- return axios.request(config)
245
- .then((res: AxiosResponse<TApiResponseData>) => {
246
-
247
- debug && console.log(`[api] Success:`, res);
248
- return res.data as TData;
249
-
250
- })
251
- .catch((e: AxiosError) => {
252
-
253
- if (e.response !== undefined) {
254
-
255
- // Transmiss error
256
- console.warn(`[api] Failure:`, e);
257
- const error = viaHttpCode(
258
- e.response.status || 500,
259
- e.response.data
260
- );
261
-
227
+ return fetch(url, config)
228
+ .then(async (response) => {
229
+ if (!response.ok) {
230
+ const errorData = await response.json();
231
+ console.warn(`[api] Failure:`, response.status, errorData);
232
+ const error = viaHttpCode(response.status || 500, errorData);
262
233
  throw error;
263
-
264
- // Erreur réseau: l'utilisateur n'ets probablement plus connecté à internet
234
+ }
235
+ debug && console.log(`[api] Success:`, response);
236
+ return response.json() as Promise<TData>;
237
+ })
238
+ .catch((error) => {
239
+ if (error instanceof TypeError) {
240
+ // Network error
241
+ console.warn(`[api] Network Failure:`, error);
242
+ const networkError = new NetworkError(error.message);
243
+ this.app.handleError(networkError);
244
+ throw networkError;
265
245
  } else {
266
- const error = new NetworkError(e.message);
267
- this.app.handleError(error);
268
246
  throw error;
269
247
  }
270
248
  });
271
249
  }
250
+
272
251
  }
@@ -1,9 +1,53 @@
1
- import TimeAgo from 'javascript-time-ago';
2
- import en from 'javascript-time-ago/locale/en'
3
- TimeAgo.addLocale(en)
4
- const timeAgo = new TimeAgo('en-US')
5
-
6
1
  import dayjs from 'dayjs';
2
+ /*
3
+ // Function to calculate the difference in the specified unit
4
+ function dateDiffInUnits(date1, date2) {
5
+ const msPerSecond = 1000;
6
+ const msPerMinute = msPerSecond * 60;
7
+ const msPerHour = msPerMinute * 60;
8
+ const msPerDay = msPerHour * 24;
9
+ const msPerMonth = msPerDay * 30; // Approximation
10
+ const msPerYear = msPerDay * 365; // Approximation
11
+
12
+ const diffInMs = date2 - date1;
13
+
14
+ return {
15
+ years: diffInMs / msPerYear,
16
+ months: diffInMs / msPerMonth,
17
+ days: diffInMs / msPerDay,
18
+ hours: diffInMs / msPerHour,
19
+ minutes: diffInMs / msPerMinute,
20
+ seconds: diffInMs / msPerSecond,
21
+ };
22
+ }
23
+
24
+ // Function to determine the best unit based on the differences
25
+ function chooseBestUnit(diffs) {
26
+ if (Math.abs(diffs.years) >= 1) return 'year';
27
+ if (Math.abs(diffs.months) >= 1) return 'month';
28
+ if (Math.abs(diffs.days) >= 1) return 'day';
29
+ if (Math.abs(diffs.hours) >= 1) return 'hour';
30
+ if (Math.abs(diffs.minutes) >= 1) return 'minute';
31
+ return 'second';
32
+ }
33
+
34
+ // Function to format the relative time between two dates
35
+ function formatRelativeTime(date1, date2, locale = 'en') {
36
+ const diffs = dateDiffInUnits(date1, date2);
37
+ const bestUnit = chooseBestUnit(diffs);
38
+ const diff = diffs[bestUnit];
39
+ const rtf = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' });
40
+ return rtf.format(Math.round(diff), bestUnit);
41
+ }
42
+
43
+ // Example dates
44
+ const date1 = new Date('2023-07-01');
45
+ const date2 = new Date('2024-07-13');
46
+
47
+ // Format the relative time automatically choosing the best unit
48
+ console.log(formatRelativeTime(date1, date2)); // Output: "in 1 year"
49
+
50
+ */
7
51
 
8
52
  export type TDateInfo = {
9
53
  isPast: boolean,
@@ -30,7 +74,7 @@ export const timeSince = (date: Date | number | string): TDateInfo | null => {
30
74
  const isPast = now > timestamp;
31
75
 
32
76
  return {
33
- text: timeAgo.format(date),
77
+ text: date,//timeAgo.format(date),
34
78
  isPast,
35
79
  delta: deltaSeconds
36
80
  };
@@ -19,9 +19,6 @@ import FileToUpload from '@client/components/inputv3/file/FileToUpload';
19
19
  import Schema, { TSchemaFields } from './schema'
20
20
  import Validator, { TValidator } from './validator'
21
21
 
22
- // Components
23
- import NumberInput from '@client/components/input/Number';
24
-
25
22
  /*----------------------------------
26
23
  - TYPES
27
24
  ----------------------------------*/
@@ -281,7 +278,6 @@ export default class SchemaValidators {
281
278
  }, {
282
279
  // Force une valeur par défaut si requis
283
280
  defaut: opts.opt ? undefined : (opts.min || 0),
284
- rendu: NumberInput,
285
281
  ...opts,
286
282
  })
287
283
 
@@ -17,7 +17,6 @@ import hpp from 'hpp'; // Protection contre la pollution des reuqtees http
17
17
  import helmet from 'helmet'; // Diverses protections
18
18
  import compression from 'compression';
19
19
  import fileUpload from 'express-fileupload';
20
- import expressStaticGzip from 'express-static-gzip';
21
20
  import cookieParser from 'cookie-parser';
22
21
  import * as csp from 'express-csp-header';
23
22
 
@@ -114,39 +113,34 @@ export default class HttpServer {
114
113
  // Normalement, seulement utile pour le mode production,
115
114
  // Quand mode debug, les ressources client semblent servies par le dev middlewae
116
115
  // Sauf que les ressources serveur ne semblent pas trouvées par le dev-middleware
116
+ routes.use(compression());
117
117
  routes.use('/public', cors());
118
118
  routes.use(
119
119
  '/public',
120
- expressStaticGzip( Container.path.root + '/bin/public', {
121
- enableBrotli: true,
122
- serveStatic: {
123
- dotfiles: 'deny',
124
- setHeaders: function setCustomCacheControl(res, path) {
120
+ express.static( Container.path.root + '/bin/public', {
121
+ dotfiles: 'deny',
122
+ setHeaders: function setCustomCacheControl(res, path) {
125
123
 
126
- const dontCache = [
127
- '/public/icons',
128
- '/public/client'
129
- ]
124
+ const dontCache = [
125
+ '/public/icons',
126
+ '/public/client'
127
+ ]
130
128
 
131
- res.setHeader('Cache-Control', 'public, max-age=0');
129
+ res.setHeader('Cache-Control', 'public, max-age=0');
132
130
 
133
- // Set long term cache, except for non-hashed filenames
134
- /*if (dontCache.some( p => path.startsWith( p ))) {
135
- res.setHeader('Cache-Control', 'public, max-age=0');
136
- } else {
137
- res.setHeader('Cache-Control', 'public, max-age=604800000'); // 7 Days
138
- }*/
139
-
140
- }
131
+ // Set long term cache, except for non-hashed filenames
132
+ /*if (dontCache.some( p => path.startsWith( p ))) {
133
+ res.setHeader('Cache-Control', 'public, max-age=0');
134
+ } else {
135
+ res.setHeader('Cache-Control', 'public, max-age=604800000'); // 7 Days
136
+ }*/
137
+
141
138
  }
142
139
  }),
143
140
  (req, res) => {
144
141
  res.status(404).send();
145
142
  }
146
143
  );
147
-
148
- // Activation Gzip
149
- routes.use(compression());
150
144
 
151
145
  routes.use('/robots.txt', express.static( path.resolve(__dirname, 'public/robots.txt')) );
152
146
 
@@ -49,8 +49,6 @@ export default class Page<TRouter extends Router = Router> extends PageResponse<
49
49
  ) {
50
50
 
51
51
  super(route, renderer, context)
52
-
53
- // TODO: create safe context?
54
52
 
55
53
  }
56
54
 
@@ -1,38 +0,0 @@
1
- /*----------------------------------
2
- - DEPENDANCES
3
- ----------------------------------*/
4
-
5
- // Npm
6
- import React, { JSX } from 'react';
7
-
8
- // Core libs
9
- import Format from '@common/data/number/format';
10
-
11
- /*----------------------------------
12
- - TYPES
13
- ----------------------------------*/
14
-
15
- export type Unit= 'satoshi' | 'bitcoin' | 'dollars' | 'credits'
16
-
17
- /*----------------------------------
18
- - COMPONENTS
19
- ----------------------------------*/
20
- export default ({ amount, unit, sign, decimals, ...props }: {
21
- amount: number,
22
- unit: Unit,
23
- decimals?: number,
24
- sign?: '+' | '-'
25
- } & JSX.HTMLAttributes<HTMLDivElement>) => {
26
-
27
- const className = 'number row sp-05 ' + (props.class ? props.class + ' ' : '');//sign === undefined ? 'txtPrimary' : (sign === '+' ? 'fg success' : 'fg error');
28
- if (unit === 'credits')
29
- return <strong {...props} class={className}>{sign} {Format.credits(amount, decimals)} Credits</strong>;
30
- else if (unit === 'dollars')
31
- return <strong {...props} class={className}>{sign} {Format.dollars(amount, decimals)} $</strong>;
32
- else if (unit === 'satoshi')
33
- return <strong {...props} class={className}>{sign} {Format.satoshi(amount)} sat.</strong>;
34
- else if (unit === 'bitcoin')
35
- return <strong {...props} class={className}>{sign} {Format.bitcoin(amount)} BTC</strong>;
36
- else
37
- return <>-</>
38
- }