5htp-core 0.1.2 → 0.2.0

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 (127) hide show
  1. package/changelog.md +5 -0
  2. package/doc/TODO.md +71 -0
  3. package/package.json +5 -4
  4. package/src/client/{App.tsx → app/component.tsx} +15 -8
  5. package/src/client/app/index.ts +128 -0
  6. package/src/client/app/service.ts +34 -0
  7. package/src/client/app.tsconfig.json +0 -4
  8. package/src/client/assets/css/medias.less +14 -0
  9. package/src/client/components/Card/index.tsx +2 -2
  10. package/src/client/components/Dialog/Manager.tsx +39 -12
  11. package/src/client/components/Form/index.tsx +1 -1
  12. package/src/client/components/button.tsx +2 -2
  13. package/src/client/components/containers/Popover/index.tsx +1 -1
  14. package/src/client/components/data/spintext/index.tsx +1 -1
  15. package/src/client/components/dropdown/index.tsx +1 -1
  16. package/src/client/components/index.ts +8 -0
  17. package/src/client/components/input/BaseV2/index.tsx +1 -1
  18. package/src/client/components/input/UploadImage/index.tsx +1 -1
  19. package/src/client/hooks/index.ts +5 -0
  20. package/src/client/hooks/useState/index.tsx +2 -2
  21. package/src/client/hooks.ts +22 -0
  22. package/src/client/index.ts +5 -0
  23. package/src/client/pages/_layout/landing/index.tsx +0 -2
  24. package/src/client/pages/_messages/400.tsx +2 -2
  25. package/src/client/pages/_messages/401.tsx +2 -2
  26. package/src/client/pages/_messages/403.tsx +2 -2
  27. package/src/client/pages/_messages/404.tsx +2 -2
  28. package/src/client/pages/_messages/500.tsx +2 -2
  29. package/src/client/pages/bug.tsx +1 -1
  30. package/src/client/pages/useHeader.tsx +1 -1
  31. package/src/client/{context/captcha.ts → services/captcha/index.ts} +0 -0
  32. package/src/client/services/metrics/index.ts +37 -0
  33. package/src/client/{router → services/router/components}/Link.tsx +1 -1
  34. package/src/client/services/router/components/Page.tsx +59 -0
  35. package/src/client/{router/component.tsx → services/router/components/router.tsx} +43 -74
  36. package/src/client/services/router/index.tsx +448 -0
  37. package/src/client/services/router/request/api.ts +229 -0
  38. package/src/client/{router → services/router}/request/history.ts +0 -0
  39. package/src/client/services/router/request/index.ts +52 -0
  40. package/src/client/services/router/response/index.tsx +107 -0
  41. package/src/client/services/router/response/page.ts +95 -0
  42. package/src/client/{context/socket.ts → services/socket/index.ts} +2 -2
  43. package/src/client/utils/dom.ts +1 -1
  44. package/src/common/app/index.ts +9 -0
  45. package/src/common/data/chaines/index.ts +9 -6
  46. package/src/common/data/input/validate.ts +3 -166
  47. package/src/common/data/objets.ts +25 -0
  48. package/src/common/data/tableaux.ts +8 -0
  49. package/src/common/errors/index.ts +3 -1
  50. package/src/common/router/index.ts +67 -88
  51. package/src/common/router/layouts.ts +50 -0
  52. package/src/common/router/register.ts +62 -0
  53. package/src/common/router/request/api.ts +72 -0
  54. package/src/common/router/request/index.ts +31 -0
  55. package/src/common/router/{response.ts → response/index.ts} +9 -13
  56. package/src/common/router/response/page.ts +40 -56
  57. package/src/common/validation/index.ts +3 -0
  58. package/src/common/validation/schema.ts +184 -0
  59. package/src/common/validation/validator.ts +88 -0
  60. package/src/common/validation/validators.ts +313 -0
  61. package/src/server/app/config.ts +9 -27
  62. package/src/server/app/index.ts +81 -124
  63. package/src/server/app/service.ts +98 -0
  64. package/src/server/app.tsconfig.json +0 -8
  65. package/src/server/error/index.ts +13 -0
  66. package/src/server/index.ts +5 -0
  67. package/src/server/patch.ts +0 -6
  68. package/src/server/{data/Cache.ts → services/cache/index.ts} +79 -47
  69. package/src/server/services/console/bugReporter.ts +26 -16
  70. package/src/server/services/console/index.ts +59 -51
  71. package/src/server/services/cron/index.ts +12 -26
  72. package/src/server/services/database/bucket.ts +40 -0
  73. package/src/server/services/database/connection.ts +206 -75
  74. package/src/server/services/database/datatypes.ts +63 -40
  75. package/src/server/services/database/index.ts +295 -272
  76. package/src/server/services/database/metas.ts +246 -135
  77. package/src/server/services/database/stats.ts +151 -126
  78. package/src/server/services/email/index.ts +28 -52
  79. package/src/server/services/{router/request/services → metrics}/detect.ts +8 -10
  80. package/src/server/services/{router/request/services/tracking.ts → metrics/index.ts} +68 -45
  81. package/src/server/services/{http → router/http}/index.ts +28 -70
  82. package/src/server/services/{http → router/http}/multipart.ts +0 -0
  83. package/src/server/services/{http → router/http}/session.ts.old +0 -0
  84. package/src/server/services/router/index.ts +273 -203
  85. package/src/server/services/router/request/api.ts +73 -0
  86. package/src/server/services/router/request/index.ts +16 -97
  87. package/src/server/services/router/request/service.ts +21 -0
  88. package/src/server/services/router/response/index.ts +125 -64
  89. package/src/server/services/router/response/{filter → mask}/Filter.ts +0 -0
  90. package/src/server/services/router/response/{filter → mask}/index.ts +0 -2
  91. package/src/server/services/router/response/{filter → mask}/selecteurs.ts +0 -0
  92. package/src/server/services/router/response/page/document.tsx +194 -0
  93. package/src/server/services/router/response/page/index.tsx +157 -0
  94. package/src/server/{libs/pages → services/router/response/page}/schemaGenerator.ts +0 -0
  95. package/src/server/services/router/service.ts +48 -0
  96. package/src/server/services/schema/index.ts +47 -0
  97. package/src/server/services/schema/request.ts +55 -0
  98. package/src/server/services/schema/router.ts +33 -0
  99. package/src/server/services/socket/index.ts +38 -43
  100. package/src/server/services/socket/scope.ts +6 -4
  101. package/src/server/services/users/index.ts +203 -0
  102. package/src/server/services/{auth/base.ts → users/old.ts} +28 -112
  103. package/src/server/services/users/router/index.ts +72 -0
  104. package/src/server/services/users/router/request.ts +49 -0
  105. package/src/types/aliases.d.ts +43 -2
  106. package/templates/composant.tsx +1 -1
  107. package/templates/modal.tsx +1 -1
  108. package/templates/page.tsx +1 -1
  109. package/tsconfig.common.json +0 -4
  110. package/src/client/context/api.ts +0 -92
  111. package/src/client/context/index.ts +0 -246
  112. package/src/client/index.tsx +0 -129
  113. package/src/client/router/index.ts +0 -286
  114. package/src/client/router/request/index.ts +0 -106
  115. package/src/client/router/response/index.ts +0 -38
  116. package/src/client/router/route.ts +0 -75
  117. package/src/common/data/input/validators/basic.ts +0 -299
  118. package/src/common/data/input/validators/build.ts +0 -63
  119. package/src/common/router/request.ts +0 -83
  120. package/src/server/data/ApiClient.ts +0 -119
  121. package/src/server/data/input.ts +0 -41
  122. package/src/server/libs/pages/document.static.tsx +0 -41
  123. package/src/server/libs/pages/document.tsx +0 -203
  124. package/src/server/libs/pages/render.tsx +0 -90
  125. package/src/server/routes/auth.ts +0 -151
  126. package/src/server/services/redis/index.ts +0 -71
  127. package/src/server/services/router/request/services/auth.ts +0 -177
@@ -7,8 +7,11 @@ import fs from 'fs-extra';
7
7
  import type mysql from 'mysql2/promise';
8
8
 
9
9
  // Core
10
- import { mysqlToJs } from './datatypes';
11
- import app from '@server/app';
10
+ import Application from '@server/app';
11
+
12
+ // Database
13
+ import type DatabaseConnection from './connection';
14
+ import { mysqlToJs, TMySQLTypeName, TJsTypeName, js as jsTypes } from './datatypes';
12
15
 
13
16
  /*----------------------------------
14
17
  - TYPES: DATABASE
@@ -25,6 +28,7 @@ type TDatabaseColumn = {
25
28
  type: string,
26
29
  cle: string,
27
30
  extra: string,
31
+ comment: string | null,
28
32
 
29
33
  assoTable: string,
30
34
  assoCol: string,
@@ -42,195 +46,302 @@ export type TDatabasesList = {
42
46
 
43
47
  export type TMetasTable = {
44
48
 
45
- nom: string,
46
- loaded: true,
47
-
49
+ // Table
48
50
  database: string,
49
- chemin: string, // database + nom
50
-
51
+ chemin: string, // database + name
52
+ nom: string,
51
53
  alias: string,
54
+ loaded: true,
52
55
 
53
- pk: { 0: string } & string[], // Au moins une pk doit être renseignée
56
+ // Columns
54
57
  colonnes: TListeMetasColonnesTable,
58
+ pk: string[], // Au moins une pk doit être renseignée
59
+ columnNamesButPk: string[]
55
60
  }
56
61
 
57
62
  export type TListeMetasColonnesTable = { [nom: string]: TMetasColonne }
58
63
 
59
64
  export type TMetasColonne = {
60
- attached: boolean, // Si les métadonnées ont bien été enrichies avec celles provenant de MySQL
61
65
 
66
+ // Column
62
67
  table: TMetasTable,
63
68
  nom: string,
64
- type: TTypeColonne,
65
- typeParams: string[],
69
+ attached: boolean, // Si les métadonnées ont bien été enrichies avec celles provenant de MySQL
66
70
  primary: boolean,
67
- api?: TMetasApi,
71
+
72
+ // Type
73
+ type: TColumnTypes,
68
74
  nullable: boolean,
75
+
76
+ // Value
69
77
  defaut?: any, // ATTENTION: Valeur déjà sérialisée
70
78
  autoIncrement: boolean,
79
+
80
+ // Extra
81
+ comment?: string
82
+ }
83
+
84
+ export type TColumnTypes = {
85
+ sql: TMySQLType,
86
+ js: TJsType
87
+ }
88
+
89
+ export type TMySQLType = {
90
+ name: TMySQLTypeName,
91
+ params: string[]
92
+ }
93
+
94
+ export type TJsType = {
95
+ name: TJsTypeName,
96
+ params: string[],
71
97
  }
72
98
 
73
99
  /*----------------------------------
74
- - LIB
100
+ - CONFIG
75
101
  ----------------------------------*/
76
102
 
77
- const regParamsTypeSql = /\'([^\']+)\'\,?/gi;
103
+ const LogPrefix = '[database][meta]';
78
104
 
79
- export default async function loadMetadata( toLoad: string[], connection: mysql.Pool ) {
80
-
81
- console.info(`${toLoad.length} databases to load`);
82
- if (toLoad.length === 0)
83
- return {};
105
+ const sqlTypeParamsReg = /\'([^\']+)\'\,?/gi;
106
+ const typeViaCommentReg = /^\[type=([a-z]+)\]/g;
84
107
 
85
- const dbNames = Array.from(toLoad);
86
- const dbColumns = await queryMetadatas(dbNames, connection);
108
+ const modelsTypesPath = process.cwd() + '/src/server/models.ts';
87
109
 
88
- const metas = importTables(dbColumns);
110
+ /*----------------------------------
111
+ - FUNCTIONS
112
+ ----------------------------------*/
113
+ export default class MySQLMetasParser {
89
114
 
90
- // Update the models typings
91
- if (app.env.profile === 'dev')
92
- genTypes(metas);
115
+ public constructor(
116
+ private database: DatabaseConnection,
117
+ public app = database.app,
118
+ ) {
93
119
 
94
- console.log(`Databases are loaded.`);
95
- return metas;
96
- }
120
+ }
97
121
 
98
- async function queryMetadatas( databases: string[], connection: mysql.Pool ) {
99
- console.log(`Loading tables metadatas for the following databases: ${databases.join(', ')} ...`);
100
- return (await connection.query(`
101
- SELECT
122
+ public async load( toLoad: string[] ) {
123
+
124
+ console.info(`${toLoad.length} databases to load`);
125
+ if (toLoad.length === 0)
126
+ return {};
102
127
 
103
- /* Provenance */
104
- col.TABLE_SCHEMA as 'database',
105
- col.TABLE_NAME as 'table',
106
- col.COLUMN_NAME as 'colonne',
128
+ const dbNames = Array.from(toLoad);
129
+ const dbColumns = await this.query(dbNames);
107
130
 
108
- /* Options */
109
- col.COLUMN_DEFAULT as 'defaut',
110
- col.IS_NULLABLE as 'nullable',
111
- col.COLUMN_TYPE as 'type',
112
- col.COLUMN_KEY as 'cle',
113
- col.EXTRA as 'extra'
131
+ const metas = this.importTables(dbColumns);
114
132
 
115
- /* Colonnes */
116
- FROM information_schema.COLUMNS col
133
+ // Update the models typings
134
+ if (this.app.env.profile === 'dev')
135
+ this.genTypesDef(metas);
117
136
 
118
- WHERE col.TABLE_SCHEMA IN(${databases.map(d => '"' + d + '"').join(', ')})
119
- `))[0] as TDatabaseColumn[];
120
- }
137
+ console.log(`Databases are loaded.`);
138
+ return metas;
139
+ }
121
140
 
122
- function importTables(dbColumns: TDatabaseColumn[]): TDatabasesList {
141
+ private async query( databases: string[] ) {
142
+ console.log(`Loading tables metadatas for the following databases: ${databases.join(', ')} ...`);
143
+ return (await this.database.connection.query(`
144
+ SELECT
145
+
146
+ /* Provenance */
147
+ col.TABLE_SCHEMA as 'database',
148
+ col.TABLE_NAME as 'table',
149
+ col.COLUMN_NAME as 'colonne',
150
+
151
+ /* Options */
152
+ col.COLUMN_COMMENT as 'comment',
153
+ col.COLUMN_DEFAULT as 'defaut',
154
+ col.IS_NULLABLE as 'nullable',
155
+ col.COLUMN_TYPE as 'type',
156
+ col.COLUMN_KEY as 'cle',
157
+ col.EXTRA as 'extra'
158
+
159
+ /* Colonnes */
160
+ FROM information_schema.COLUMNS col
161
+
162
+ WHERE col.TABLE_SCHEMA IN(${databases.map(d => '"' + d + '"').join(', ')})
163
+ `))[0] as TDatabaseColumn[];
164
+ }
165
+
166
+ private importTables( dbColumns: TDatabaseColumn[] ): TDatabasesList {
167
+
168
+ console.log(`Processing ${dbColumns.length} rows of metadatas`);
169
+
170
+ const tablesIndex: TDatabasesList = {};
123
171
 
124
- console.log(`Processing ${dbColumns.length} rows of metadatas`);
172
+ for (const {
173
+ database, table: nomTable, colonne: nomColonne,
174
+ defaut, nullable, type, cle, extra, comment
175
+ } of dbColumns) {
125
176
 
126
- const metas: TDatabasesList = {};
177
+ if (tablesIndex[database] === undefined)
178
+ tablesIndex[database] = {}
179
+
180
+ // Indexage de la table si pas déjà fait
181
+ if (tablesIndex[database][nomTable] === undefined)
182
+ tablesIndex[database][nomTable] = {
183
+
184
+ // Table
185
+ chemin: '`' + database + '`.`' + nomTable + '`',
186
+ database: database,
187
+ nom: nomTable,
188
+ alias: nomTable.toLowerCase(),
189
+ loaded: true,
190
+
191
+ // Columns
192
+ colonnes: {},
193
+ pk: [],
194
+ columnNamesButPk: []
195
+ }
127
196
 
128
- for (const {
129
- database, table: nomTable, colonne: nomColonne,
130
- defaut, nullable, type, cle, extra
131
- } of dbColumns) {
197
+ // Extrct tablesIndex
198
+ const table = tablesIndex[database][nomTable];
199
+ const parsedTypes = this.parseColType(type, comment);
132
200
 
133
- if (metas[database] === undefined)
134
- metas[database] = {}
201
+ // Reference primary keys
202
+ const isPrimary = cle === 'PRI';
203
+ if (isPrimary && !table.pk.includes(nomColonne))
204
+ table.pk.push(nomColonne);
135
205
 
136
- // Indexage de la table si pas déjà fait
137
- if (metas[database][nomTable] === undefined)
138
- metas[database][nomTable] = {
139
- loaded: true,
140
- database: database,
141
- alias: nomTable.toLowerCase(),
142
- nom: nomTable,
143
- chemin: '`' + database + '`.`' + nomTable + '`',
144
- colonnes: {},
145
- pk: [],
146
- default: false,
147
- modele: undefined
206
+ // Index column
207
+ table.colonnes[nomColonne] = {
208
+
209
+ // Column
210
+ table: tablesIndex[database][nomTable],
211
+ nom: nomColonne,
212
+ attached: true,
213
+ primary: isPrimary,
214
+
215
+ // Type
216
+ type: parsedTypes,
217
+ nullable: nullable === 'YES',
218
+
219
+ // Value
220
+ defaut: defaut === null ? undefined : defaut,
221
+ autoIncrement: extra.includes('auto_increment'),
222
+
223
+ // Extra
224
+ comment: comment || undefined
148
225
  }
226
+ }
227
+
228
+ // Re-process every table
229
+ for (const databaseName in tablesIndex) {
230
+ for (const tableName in tablesIndex[ databaseName ]) {
149
231
 
150
- // Extraction des informations
151
- const table = metas[database][nomTable];
152
- const { nomType, paramsType } = parseColType(type);
153
-
154
- // Indexage clés primaires
155
- const primaire = cle === 'PRI';
156
- if (primaire && !table.pk.includes(nomColonne))
157
- table.pk.push(nomColonne);
158
-
159
- // Indexage de la colonne
160
- table.colonnes[nomColonne] = {
161
- attached: true,
162
- table: metas[database][nomTable],
163
- nom: nomColonne,
164
- primary: primaire,
165
- autoIncrement: extra.includes('auto_increment'),
166
- nullable: nullable === 'YES',
167
- defaut: defaut === null ? undefined : defaut,
168
-
169
- type: nomType,
170
- typeParams: paramsType
232
+ const table = tablesIndex[ databaseName ][ tableName ];
233
+
234
+ table.columnNamesButPk = Object.keys(table.colonnes).filter(
235
+ colName => !table.pk.includes( colName )
236
+ )
237
+ }
171
238
  }
172
239
 
240
+ return tablesIndex;
241
+
173
242
  }
174
243
 
175
- return metas;
176
-
177
- }
244
+ private parseColType( rawType: string, comment: string | null ): TColumnTypes {
245
+
246
+ const mysqlType = this.parseMySQLType(rawType);
247
+
248
+ const jsType = this.parseJsType(mysqlType, comment);
249
+
250
+ return {
251
+ sql: mysqlType,
252
+ js: jsType
253
+ }
178
254
 
179
- function parseColType(brut: string) {
180
-
181
- let nomType: TMetasColonne["type"];
182
- let paramsType: TMetasColonne["typeParams"] = [];
183
-
184
- const posParenthese = brut.indexOf('(');
185
- if (posParenthese === -1)
186
- nomType = brut.toUpperCase() as TMetasColonne["type"];
187
- else {
188
- nomType = brut.substring(0, posParenthese).toUpperCase() as TMetasColonne["type"];
189
-
190
- // Extraction paramètres du type entre les parentheses
191
- const paramsStr = brut.substring(posParenthese + 1, brut.length - 1)
192
- let m;
193
- do {
194
- m = regParamsTypeSql.exec(paramsStr);
195
- if (m)
196
- paramsType.push(m[1]);
197
- } while (m);
198
255
  }
199
256
 
200
- return { nomType, paramsType }
257
+ private parseMySQLType( rawType: string ): TMySQLType {
258
+
259
+ let name: TMySQLType["name"];
260
+ let params: TMySQLType["params"] = [];
261
+
262
+ // Via native MySQL type: parse type expression + params
263
+ const posParenthese = rawType.indexOf('(');
264
+ if (posParenthese === -1)
265
+ name = rawType.toUpperCase() as TMySQLType["name"];
266
+ else {
267
+ name = rawType.substring(0, posParenthese).toUpperCase() as TMySQLType["name"];
268
+
269
+ // Extraction paramètres du type entre les parentheses
270
+ const paramsStr = rawType.substring(posParenthese + 1, rawType.length - 1)
271
+ let m;
272
+ do {
273
+ m = sqlTypeParamsReg.exec(paramsStr);
274
+ if (m)
275
+ params.push(m[1]);
276
+ } while (m);
277
+ }
201
278
 
202
- }
279
+ return { name, params }
203
280
 
204
- function genTypes( databases: TDatabasesList ) {
281
+ }
205
282
 
206
- const types: string[] = [];
283
+ private parseJsType( mysqlType: TMySQLType, comment: string | null ): TJsType {
284
+
285
+ // Via comment
286
+ if (comment) {
287
+ // Exract via comments: [type=array]
288
+ const foundTypeExpression = typeViaCommentReg.exec( comment );
289
+ if (foundTypeExpression !== null) {
290
+
291
+ const typeNameViaComment = foundTypeExpression[1];
292
+ if (!(typeNameViaComment in jsTypes))
293
+ console.warn(`Invalid type "${typeNameViaComment}" found in column comments.`);
294
+ else
295
+ return {
296
+ name: typeNameViaComment as TJsTypeName,
297
+ params: []
298
+ }
299
+ }
300
+ }
301
+
302
+ // Via mysql Type
303
+ let jsTypeName = mysqlToJs[ mysqlType.name ];
304
+ if (jsTypeName === undefined) {
305
+ console.warn(`The mySQL data type « ${mysqlType.name} » has not been associated with a JS equivalent in mysqlToJs. Using any instead.`);
306
+ jsTypeName = mysqlToJs['UNKNOWN'];
307
+ }
207
308
 
208
- for (const db in databases) {
209
- for (const tableName in databases[db]) {
309
+ return {
310
+ name: jsTypeName,
311
+ params: [],
312
+ }
210
313
 
211
- const table = databases[db][tableName];
314
+ }
212
315
 
213
- const colsDecl: string[] = [];
214
- for (const colName in table.colonnes) {
316
+ private genTypesDef( databases: TDatabasesList ) {
215
317
 
216
- const col = table.colonnes[colName];
217
- let jsType = mysqlToJs[col.type];
218
- if (jsType === undefined) {
219
- console.warn(`The mySQL data type « ${col.type} » has not been associated with a JS equivalent in mysqlToJs. Using any instead.`);
220
- jsType = mysqlToJs['UNKNOWN'];
221
- }
318
+ const types: string[] = [];
222
319
 
223
- colsDecl.push('\t' + col.nom + (col.nullable ? '?' : '') + ': ' + jsType.typescript);
320
+ for (const db in databases) {
321
+ for (const tableName in databases[db]) {
224
322
 
225
- }
226
-
227
- types.push('export type ' + table.nom + ' = {\n' + colsDecl.join(',\n') + '\n}');
323
+ const table = databases[db][tableName];
228
324
 
325
+ const colsDecl: string[] = [];
326
+ for (const colName in table.colonnes) {
327
+
328
+ const col = table.colonnes[colName];
329
+ const jsTypeUtils = jsTypes[ col.type.js.name ];
330
+ if (!jsTypeUtils) {
331
+ console.warn(`Unable to find the typescript print funvction for js type "${col.type.js.name}"`);
332
+ continue;
333
+ }
334
+
335
+ colsDecl.push('\t' + col.nom + (col.nullable ? '?' : '') + ': ' + jsTypeUtils.print( col ));
336
+ }
337
+
338
+ types.push('export type ' + table.nom + ' = {\n' + colsDecl.join(',\n') + '\n}');
339
+
340
+ }
229
341
  }
230
- }
231
342
 
232
- const modelsTypesPath = process.cwd() + '/src/server/models.ts';
233
- fs.outputFileSync( modelsTypesPath, types.join('\n') );
234
- console.log(`Wrote database types to ${modelsTypesPath}`);
235
-
343
+ fs.outputFileSync( modelsTypesPath, types.join('\n') );
344
+ console.log(LogPrefix, `Wrote database types to ${modelsTypesPath}`);
345
+
346
+ }
236
347
  }