proteum 1.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 (156) hide show
  1. package/.dockerignore +10 -0
  2. package/Rte.zip +0 -0
  3. package/cli/app/config.ts +54 -0
  4. package/cli/app/index.ts +195 -0
  5. package/cli/bin.js +11 -0
  6. package/cli/commands/build.ts +34 -0
  7. package/cli/commands/deploy/app.ts +29 -0
  8. package/cli/commands/deploy/web.ts +60 -0
  9. package/cli/commands/dev.ts +109 -0
  10. package/cli/commands/init.ts +85 -0
  11. package/cli/compiler/client/identite.ts +72 -0
  12. package/cli/compiler/client/index.ts +334 -0
  13. package/cli/compiler/common/babel/index.ts +170 -0
  14. package/cli/compiler/common/babel/plugins/index.ts +0 -0
  15. package/cli/compiler/common/babel/plugins/services.ts +579 -0
  16. package/cli/compiler/common/babel/routes/imports.ts +127 -0
  17. package/cli/compiler/common/babel/routes/routes.ts +1130 -0
  18. package/cli/compiler/common/files/autres.ts +39 -0
  19. package/cli/compiler/common/files/images.ts +35 -0
  20. package/cli/compiler/common/files/style.ts +78 -0
  21. package/cli/compiler/common/index.ts +154 -0
  22. package/cli/compiler/index.ts +532 -0
  23. package/cli/compiler/server/index.ts +211 -0
  24. package/cli/index.ts +189 -0
  25. package/cli/paths.ts +165 -0
  26. package/cli/print.ts +12 -0
  27. package/cli/tsconfig.json +38 -0
  28. package/cli/utils/index.ts +22 -0
  29. package/cli/utils/keyboard.ts +78 -0
  30. package/client/app/component.tsx +54 -0
  31. package/client/app/index.ts +142 -0
  32. package/client/app/service.ts +34 -0
  33. package/client/app.tsconfig.json +28 -0
  34. package/client/components/Button.tsx +298 -0
  35. package/client/components/Dialog/Manager.tsx +309 -0
  36. package/client/components/Dialog/card.tsx +208 -0
  37. package/client/components/Dialog/index.less +151 -0
  38. package/client/components/Dialog/status.less +176 -0
  39. package/client/components/Dialog/status.tsx +48 -0
  40. package/client/components/index.ts +2 -0
  41. package/client/components/types.d.ts +3 -0
  42. package/client/data/input.ts +32 -0
  43. package/client/global.d.ts +5 -0
  44. package/client/hooks.ts +22 -0
  45. package/client/index.ts +6 -0
  46. package/client/pages/_layout/index.less +6 -0
  47. package/client/pages/_layout/index.tsx +43 -0
  48. package/client/pages/bug.tsx.old +60 -0
  49. package/client/pages/useHeader.tsx +50 -0
  50. package/client/services/captcha/index.ts +67 -0
  51. package/client/services/router/components/Link.tsx +46 -0
  52. package/client/services/router/components/Page.tsx +55 -0
  53. package/client/services/router/components/router.tsx +218 -0
  54. package/client/services/router/index.tsx +521 -0
  55. package/client/services/router/request/api.ts +267 -0
  56. package/client/services/router/request/history.ts +5 -0
  57. package/client/services/router/request/index.ts +53 -0
  58. package/client/services/router/request/multipart.ts +147 -0
  59. package/client/services/router/response/index.tsx +128 -0
  60. package/client/services/router/response/page.ts +86 -0
  61. package/client/services/socket/index.ts +147 -0
  62. package/client/utils/dom.ts +77 -0
  63. package/common/app/index.ts +9 -0
  64. package/common/data/chaines/index.ts +54 -0
  65. package/common/data/dates.ts +179 -0
  66. package/common/data/markdown.ts +73 -0
  67. package/common/data/rte/nodes.ts +83 -0
  68. package/common/data/stats.ts +90 -0
  69. package/common/errors/index.tsx +326 -0
  70. package/common/router/index.ts +213 -0
  71. package/common/router/layouts.ts +93 -0
  72. package/common/router/register.ts +55 -0
  73. package/common/router/request/api.ts +77 -0
  74. package/common/router/request/index.ts +35 -0
  75. package/common/router/response/index.ts +45 -0
  76. package/common/router/response/page.ts +128 -0
  77. package/common/utils/rte.ts +183 -0
  78. package/common/utils.ts +7 -0
  79. package/doc/TODO.md +71 -0
  80. package/doc/front/router.md +27 -0
  81. package/doc/workspace/workspace.png +0 -0
  82. package/doc/workspace/workspace2.png +0 -0
  83. package/doc/workspace/workspace_26.01.22.png +0 -0
  84. package/package.json +171 -0
  85. package/server/app/commands.ts +141 -0
  86. package/server/app/container/config.ts +203 -0
  87. package/server/app/container/console/index.ts +550 -0
  88. package/server/app/container/index.ts +137 -0
  89. package/server/app/index.ts +273 -0
  90. package/server/app/service/container.ts +88 -0
  91. package/server/app/service/index.ts +235 -0
  92. package/server/app.tsconfig.json +28 -0
  93. package/server/context.ts +4 -0
  94. package/server/index.ts +4 -0
  95. package/server/services/auth/index.ts +250 -0
  96. package/server/services/auth/old.ts +277 -0
  97. package/server/services/auth/router/index.ts +95 -0
  98. package/server/services/auth/router/request.ts +54 -0
  99. package/server/services/auth/router/service.json +6 -0
  100. package/server/services/auth/service.json +6 -0
  101. package/server/services/cache/commands.ts +41 -0
  102. package/server/services/cache/index.ts +297 -0
  103. package/server/services/cache/service.json +6 -0
  104. package/server/services/cron/CronTask.ts +86 -0
  105. package/server/services/cron/index.ts +112 -0
  106. package/server/services/cron/service.json +6 -0
  107. package/server/services/disks/driver.ts +103 -0
  108. package/server/services/disks/drivers/local/index.ts +188 -0
  109. package/server/services/disks/drivers/local/service.json +6 -0
  110. package/server/services/disks/drivers/s3/index.ts +301 -0
  111. package/server/services/disks/drivers/s3/service.json +6 -0
  112. package/server/services/disks/index.ts +90 -0
  113. package/server/services/disks/service.json +6 -0
  114. package/server/services/email/index.ts +188 -0
  115. package/server/services/email/utils.ts +53 -0
  116. package/server/services/fetch/index.ts +201 -0
  117. package/server/services/fetch/service.json +7 -0
  118. package/server/services/models.7z +0 -0
  119. package/server/services/prisma/Facet.ts +142 -0
  120. package/server/services/prisma/index.ts +201 -0
  121. package/server/services/prisma/service.json +6 -0
  122. package/server/services/router/http/index.ts +217 -0
  123. package/server/services/router/http/multipart.ts +102 -0
  124. package/server/services/router/http/session.ts.old +40 -0
  125. package/server/services/router/index.ts +801 -0
  126. package/server/services/router/request/api.ts +87 -0
  127. package/server/services/router/request/index.ts +184 -0
  128. package/server/services/router/request/service.ts +21 -0
  129. package/server/services/router/request/validation/zod.ts +180 -0
  130. package/server/services/router/response/index.ts +338 -0
  131. package/server/services/router/response/mask/Filter.ts +323 -0
  132. package/server/services/router/response/mask/index.ts +60 -0
  133. package/server/services/router/response/mask/selecteurs.ts +92 -0
  134. package/server/services/router/response/page/document.tsx +160 -0
  135. package/server/services/router/response/page/index.tsx +196 -0
  136. package/server/services/router/service.json +6 -0
  137. package/server/services/router/service.ts +36 -0
  138. package/server/services/schema/index.ts +44 -0
  139. package/server/services/schema/request.ts +49 -0
  140. package/server/services/schema/router/index.ts +28 -0
  141. package/server/services/schema/router/service.json +6 -0
  142. package/server/services/schema/service.json +6 -0
  143. package/server/services/security/encrypt/aes/index.ts +85 -0
  144. package/server/services/security/encrypt/aes/service.json +6 -0
  145. package/server/services/socket/index.ts +162 -0
  146. package/server/services/socket/scope.ts +226 -0
  147. package/server/services/socket/service.json +6 -0
  148. package/server/services_old/SocketClient.ts +92 -0
  149. package/server/services_old/Token.old.ts +97 -0
  150. package/server/utils/slug.ts +79 -0
  151. package/tsconfig.common.json +45 -0
  152. package/tsconfig.json +3 -0
  153. package/types/aliases.d.ts +54 -0
  154. package/types/global/modules.d.ts +49 -0
  155. package/types/global/utils.d.ts +103 -0
  156. package/types/icons.d.ts +1 -0
@@ -0,0 +1,87 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Core
6
+
7
+ import RequestService from './service';
8
+
9
+ import ApiClientService, {
10
+ TApiFetchOptions, TFetcherList, TFetcherArgs, TFetcher,
11
+ TDataReturnedByFetchers
12
+ } from '@common/router/request/api';
13
+
14
+ /*----------------------------------
15
+ - TYPES
16
+ ----------------------------------*/
17
+
18
+
19
+ /*----------------------------------
20
+ - SERVICE
21
+ ----------------------------------*/
22
+ export default class ApiClientRequest extends RequestService implements ApiClientService {
23
+
24
+ /*----------------------------------
25
+ - HIGH LEVEL
26
+ ----------------------------------*/
27
+
28
+ public fetch<TProvidedData extends TFetcherList = TFetcherList>(
29
+ fetchers: TFetcherList
30
+ ): TDataReturnedByFetchers<TProvidedData> {
31
+ throw new Error("api.fetch shouldn't be called here.");
32
+ }
33
+
34
+ /*----------------------------------
35
+ - PLACEHOLDERS
36
+ ----------------------------------*/
37
+
38
+ public set( newData: TObjetDonnees ) {
39
+ throw new Error("api.set is not available on server side.");
40
+ }
41
+
42
+ public reload( ids?: string | string[], params?: TObjetDonnees ) {
43
+ throw new Error("api.set is not available on server side.");
44
+ }
45
+
46
+ /*----------------------------------
47
+ - API CALLS FROM SERVER
48
+ ----------------------------------*/
49
+
50
+ public createFetcher<TData extends unknown = unknown>(...[method, path, data, options]: TFetcherArgs): TFetcher<TData> {
51
+ return {
52
+ method, path, data, options,
53
+ // We don't put the then and catch methods so the api consumer on server side will know it's a fetcher and not a promize to wait
54
+ } as TFetcher<TData>;
55
+ }
56
+
57
+ public async fetchSync(fetchers: TFetcherList, alreadyLoadedData: {}): Promise<TObjetDonnees> {
58
+
59
+ const fetchedData: TObjetDonnees = { ...alreadyLoadedData };
60
+
61
+ for (const id in fetchers) {
62
+
63
+ const fetcher = fetchers[id]
64
+ if (!fetcher)
65
+ continue;
66
+
67
+ // Promise Fetcher (direct call from service method)
68
+ if ('then' in fetcher) {
69
+ fetchedData[id] = await fetcher;
70
+ continue;
71
+ }
72
+
73
+ const { method, path, data, options } = fetcher;
74
+ //this.router.config.debug && console.log(`[api] Resolving from internal api`, method, path, data);
75
+
76
+ // We don't fetch the already given data
77
+ if (id in fetchedData)
78
+ continue;
79
+
80
+ // Create a children request to resolve the api data
81
+ const request = this.request.children(method, path, data);
82
+ fetchedData[id] = await request.router.resolve(request).then(res => res.data);
83
+ }
84
+
85
+ return fetchedData;
86
+ }
87
+ }
@@ -0,0 +1,184 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ // Npm
6
+ import type express from 'express';
7
+ import ISO6391 from 'iso-639-1';
8
+ import accepts from 'accepts';
9
+ import Bowser from "bowser";
10
+
11
+ // Core
12
+ import BaseRequest from '@common/router/request';
13
+
14
+ // Specific
15
+ import type {
16
+ default as Router, Config as RouterConfig,
17
+ HttpMethod, HttpHeaders
18
+ } from '..';
19
+ import ApiClient from './api';
20
+ import ServerResponse from '../response';
21
+ import type { TAnyRouter } from '..';
22
+
23
+ /*----------------------------------
24
+ - TYPES
25
+ ----------------------------------*/
26
+
27
+ const localeFilter = (input: any) => {
28
+
29
+ // Data type
30
+ if (typeof input !== 'string')
31
+ return;
32
+
33
+ // Extract ISO code
34
+ let lang = input.trim().split(/[-_]/)[0].toLowerCase();
35
+
36
+ // Check size
37
+ if (!ISO6391.validate(lang))
38
+ return;
39
+
40
+ return lang.toUpperCase();
41
+ }
42
+
43
+ export type UploadedFile = File
44
+
45
+ /*----------------------------------
46
+ - CONTEXTE
47
+ ----------------------------------*/
48
+ export default class ServerRequest<
49
+ TRouter extends TAnyRouter = TAnyRouter
50
+ > extends BaseRequest {
51
+
52
+ /*----------------------------------
53
+ - PROPRIÉTÉS
54
+ ----------------------------------*/
55
+
56
+ public id: string;
57
+ public isVirtual: boolean = false;
58
+
59
+ // Requete
60
+ public method: HttpMethod;
61
+ public ip?: string;
62
+ public locale: string;
63
+ public domain: string;
64
+ public headers: HttpHeaders = {};
65
+ public cookies: TObjetDonnees = {};
66
+ public validatedData?: TObjetDonnees; // Results from the last schema.validate
67
+
68
+ // reponse
69
+ public response?: ServerResponse<TRouter>;
70
+ public router: TRouter;
71
+
72
+ // Origin
73
+ public req: express.Request;
74
+ public res: express.Response;
75
+
76
+ // Services
77
+ public api: ApiClient;
78
+
79
+ /*----------------------------------
80
+ - INITIALISATION
81
+ ----------------------------------*/
82
+ public constructor(
83
+
84
+ id: string,
85
+ method: HttpMethod,
86
+ path: string,
87
+ data: TObjetDonnees | undefined,
88
+ headers: HttpHeaders | undefined,
89
+
90
+ res: express.Response,
91
+ router: TRouter,
92
+ isVirtual: boolean = false
93
+ ) {
94
+
95
+ super(path);
96
+
97
+ this.id = id;
98
+ this.isVirtual = isVirtual;
99
+
100
+ this.req = res.req;
101
+ this.res = res
102
+ this.router = router;
103
+ this.api = new ApiClient(this);
104
+
105
+ this.url = this.req.protocol + '://' + this.req.get('host') + this.req.originalUrl;
106
+ this.host = this.req.get('host') as string;
107
+ this.method = method;
108
+ this.headers = headers || {};
109
+ this.locale = this.getLocale();
110
+ this.domain = res.req.hostname;
111
+ this.cookies = res.req.cookies;
112
+
113
+ this.ip = res.req.ip;
114
+
115
+ this.data = data || {};
116
+ }
117
+
118
+ public children(method: HttpMethod, path: string, data: TObjetDonnees | undefined) {
119
+ const children = new ServerRequest(
120
+ this.id, method, path, data, { ...this.headers, accept: 'application/json' },
121
+ this.res, this.router, true
122
+ );
123
+ children.user = this.user;
124
+ return children;
125
+ }
126
+
127
+ private getLocale() {
128
+
129
+ const fromQuery = localeFilter(this.req.query.lang);
130
+ if (fromQuery) {
131
+ this.res.cookie('lang', fromQuery);
132
+ return fromQuery;
133
+ }
134
+
135
+ const locale = (
136
+ // Member settings
137
+ this.user?.locale
138
+ ||
139
+ // URL
140
+ localeFilter( this.req.cookies.lang )
141
+ ||
142
+ // Browser
143
+ localeFilter( this.req.acceptsLanguages()[0] )
144
+ ||
145
+ // Default
146
+ 'EN'
147
+ )
148
+
149
+ return locale ? locale.toUpperCase() : 'EN'
150
+ }
151
+
152
+ public cookie( key: string, consume: boolean = false ) {
153
+
154
+ const value = this.req.cookies[ key ];
155
+
156
+ if (consume)
157
+ this.res.clearCookie(key);
158
+
159
+ return value;
160
+
161
+ }
162
+
163
+ /*----------------------------------
164
+ - TESTS
165
+ ----------------------------------*/
166
+
167
+ public accepts(datatype: string | undefined) {
168
+ // https://github.com/jshttp/accepts
169
+ return datatype === undefined || datatype === '*' || accepts(this).type(datatype);
170
+ }
171
+
172
+ public device(): Bowser.Parser.ParsedResult | undefined {
173
+ return this.headers['user-agent'] !== undefined
174
+ ? Bowser.parse(this.headers['user-agent'])
175
+ : undefined;
176
+ }
177
+
178
+ public deviceString(): string | undefined {
179
+ const info = this.device();
180
+ if (info === undefined) return undefined;
181
+ const { os, browser } = info;
182
+ return (os.name || 'Unknown OS') + ' ' + (os.versionName || os.version || '') + ' / ' + (browser.name || 'Unknown browser') + ' ' + (browser.version || '');
183
+ }
184
+ }
@@ -0,0 +1,21 @@
1
+ /*----------------------------------
2
+ - DEPENDANCES
3
+ ----------------------------------*/
4
+
5
+ import type Router from '..';
6
+ import type ServerRequest from '.';
7
+
8
+ /*----------------------------------
9
+ - SERVICE
10
+ ----------------------------------*/
11
+ export default abstract class RequestService {
12
+
13
+ public constructor(
14
+ public request: ServerRequest<Router>,
15
+ public router = request.router,
16
+ public app = router.app
17
+ ) {
18
+
19
+ }
20
+
21
+ }
@@ -0,0 +1,180 @@
1
+ import { InputError } from '@common/errors';
2
+ import zod, { _ZodType } from 'zod';
3
+
4
+ export type TRichTextValidatorOptions = {
5
+ attachements?: boolean
6
+ }
7
+
8
+ export const preprocessSchema = (schema: zod.ZodObject): zod.ZodObject => {
9
+
10
+ // Not working, data is {}
11
+ return schema;
12
+
13
+ if (!(schema instanceof zod.ZodObject))
14
+ return schema;
15
+
16
+ if (schema.withPreprocessing)
17
+ return schema;
18
+
19
+ const shape = schema.def.shape;
20
+ const newShape: Record<string, zod.ZodTypeAny> = {};
21
+
22
+ for (const key in shape) {
23
+
24
+ if (!['newEntity', 'email'].includes(key))
25
+ continue;
26
+
27
+ let current: zod.ZodTypeAny = shape[key];
28
+ while (current) {
29
+
30
+ const origType = current.type;
31
+ const preprocessor = toPreprocess[origType];
32
+
33
+ if (origType === 'object') {
34
+ newShape[key] = preprocessSchema(current as zod.ZodObject);
35
+ break;
36
+ }
37
+
38
+ if (preprocessor) {
39
+ newShape[key] = preprocessor(current);
40
+ console.log('====newShape', key, newShape[key]);
41
+ break;
42
+ }
43
+
44
+ current = current.def;
45
+ }
46
+ }
47
+
48
+ const newSchema = zod.object(newShape);
49
+ newSchema.withPreprocessing = true;
50
+ return newSchema;
51
+ }
52
+
53
+ const toPreprocess = {
54
+
55
+ string: (zString: zod.ZodString) => zod.preprocess( val => {
56
+ return val === '' ? undefined : val;
57
+ }, zString),
58
+
59
+ int: (zInt: zod.ZodInt) => zod.preprocess( val => {
60
+ return typeof val === 'string' ? Number.parseInt(val) : val;
61
+ }, zInt),
62
+
63
+ }
64
+
65
+ export const schema = {
66
+ ...zod,
67
+
68
+ file: () => {
69
+
70
+ // Chaine = url ancien fichier = exclusion de la valeur pour conserver l'ancien fichier
71
+ // NOTE: Si la valeur est présente mais undefined, alors on supprimera le fichier
72
+ /*if (typeof val === 'string')
73
+ return true;*/
74
+
75
+ return zod.file();
76
+ },
77
+
78
+ choice: ( choices: string[] | { value: any, label: string }[] | _ZodType, options: { multiple?: boolean } = {} ) => {
79
+
80
+ const normalizeValue = (value: any) => typeof value === 'object' ? value.value : value;
81
+
82
+ const valueType: _ZodType = Array.isArray(choices)
83
+ ? zod.enum( choices.map(normalizeValue) )
84
+ : zod.string();
85
+
86
+ const itemType = zod.union([
87
+
88
+ zod.object({ value: valueType, label: zod.string() }),
89
+
90
+ valueType
91
+
92
+ ]);
93
+
94
+ const type = options.multiple ? zod.array( itemType ) : itemType;
95
+
96
+ return type.transform(v => {
97
+ if (options.multiple) {
98
+ return v.map(normalizeValue);
99
+ } else {
100
+ return normalizeValue(v);
101
+ }
102
+ });
103
+ },
104
+
105
+ richText: (opts: TRichTextValidatorOptions = {}) => schema.custom(val => {
106
+
107
+ if (typeof val !== 'string') {
108
+ console.error("Invalid rich text format.", val);
109
+ return false;
110
+ }
111
+
112
+ // We get a stringified json as input since the editor workds with JSON string
113
+ try {
114
+ val = JSON.parse(val);
115
+ } catch (error) {
116
+ console.error("Failed to parse rich text json:", error, val);
117
+ return false;//throw new InputError("Invalid rich text format.");
118
+ }
119
+
120
+ // Check that the root exists and has a valid type
121
+ if (!val || typeof val !== 'object' || typeof val.root !== 'object' || val.root.type !== 'root') {
122
+ console.error("Invalid rich text value (1).", val);
123
+ return false;//throw new InputError("Invalid rich text value (1).");
124
+ }
125
+
126
+ // Check if root has children array
127
+ if (!Array.isArray(val.root.children)) {
128
+ console.error("Invalid rich text value (2).", val);
129
+ return false;
130
+ }
131
+
132
+ // Validate each child node in root
133
+ for (const child of val.root.children) {
134
+ if (!validateLexicalNode(child, opts))
135
+ return false;
136
+ }
137
+
138
+ return true;
139
+ })
140
+ }
141
+
142
+ // Recursive function to validate each node
143
+ function validateLexicalNode(node: any, opts: TRichTextValidatorOptions ) {
144
+
145
+ // Each node should be an object with a `type` property
146
+ if (typeof node !== 'object' || !node.type || typeof node.type !== 'string')
147
+ throw new InputError("Invalid rich text value (3).");
148
+
149
+ // Validate text nodes
150
+ if (node.type === 'text') {
151
+
152
+ if (typeof node.text !== 'string')
153
+ throw new InputError("Invalid rich text value (4).");
154
+
155
+ // Validate paragraph, heading, or other structural nodes that may contain children
156
+ } else if (['paragraph', 'heading', 'list', 'listitem'].includes(node.type)) {
157
+
158
+ if (!Array.isArray(node.children) || !node.children.every(children => validateLexicalNode(children, opts))) {
159
+ throw new InputError("Invalid rich text value (5).");
160
+ }
161
+
162
+ // Files upload
163
+ } else if (node.type === 'image') {
164
+
165
+ // Check if allowed
166
+ /*if (opts.attachements === undefined)
167
+ throw new InputError("Image attachments not allowed in this rich text field.");*/
168
+
169
+ // TODO: check mime
170
+
171
+
172
+ // Upload file
173
+
174
+
175
+ }
176
+
177
+ return true;
178
+ }
179
+
180
+ export type { default as z } from 'zod';