5htp-core 0.3.1 → 0.3.2

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.
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.3.1",
4
+ "version": "0.3.2",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -19,7 +19,7 @@ export const Link = ({ to, ...props }: {
19
19
  } & React.HTMLProps<HTMLAnchorElement>) => {
20
20
 
21
21
  // External = open in new tab by default
22
- if (to[0] !== '/' || to.startsWith('//'))
22
+ if (to && (to[0] !== '/' || to.startsWith('//')))
23
23
  props.target = '_blank';
24
24
  // Otherwise, propagate to the router
25
25
  else
@@ -22,6 +22,7 @@ export default ({ page, isCurrent }: { page: Page, isCurrent?: boolean }) => {
22
22
  page.loading ? null : page.data
23
23
  );
24
24
  page.setAllData = setApiData;
25
+ context.data = apiData;
25
26
 
26
27
  React.useEffect(() => {
27
28
 
@@ -50,7 +51,7 @@ export default ({ page, isCurrent }: { page: Page, isCurrent?: boolean }) => {
50
51
  // URL params
51
52
  {...context.request.data}
52
53
  // API data
53
- {...apiData}
54
+ data={apiData}
54
55
  />
55
56
 
56
57
  ) : null
@@ -20,7 +20,7 @@ import BaseRouter, {
20
20
  import { getLayout } from '@common/router/layouts';
21
21
  import { getRegisterPageArgs, buildRegex } from '@common/router/register';
22
22
  import { TFetcherList } from '@common/router/request/api';
23
- import type { TFrontRenderer, TDataProvider } from '@common/router/response/page';
23
+ import type { TFrontRenderer } from '@common/router/response/page';
24
24
 
25
25
  import App from '@client/app/component';
26
26
  import type ClientApplication from '@client/app';
@@ -61,21 +61,18 @@ export type Response = ClientResponse<ClientRouter> | ServerResponse<ServerRoute
61
61
  - TYPES: ROUTES LOADING
62
62
  ----------------------------------*/
63
63
 
64
- // WARN: To be updated with the mplemenations list of Router.page
64
+ // WARN: To be updated with the mplemenations list of Router.page AND the routes babel plugin
65
65
  // (both server and client side)
66
- export type TRegisterPageArgs<TProvidedData extends TFetcherList = {}, TRouter extends Router = Router> = ([
66
+ export type TRegisterPageArgs<
67
+ TProvidedData extends TFetcherList = TFetcherList,
68
+ TRouter extends Router = Router
69
+ > = ([
67
70
  path: string,
68
- controller: TDataProvider<TProvidedData> | null,
69
71
  renderer: TFrontRenderer<TProvidedData>
70
72
  ] | [
71
73
  path: string,
72
74
  options: Partial<TRoute["options"]>,
73
75
  renderer: TFrontRenderer<TProvidedData>
74
- ] | [
75
- path: string,
76
- options: Partial<TRoute["options"]>,
77
- controller: TDataProvider<TProvidedData> | null,
78
- renderer: TFrontRenderer<TProvidedData>
79
76
  ])
80
77
 
81
78
  // Route definition passed by the server
@@ -221,28 +218,20 @@ export default class ClientRouter<
221
218
  return currentRoute;
222
219
  }
223
220
 
224
- public page(
221
+ public page<TProvidedData extends TFetcherList = TFetcherList>(
225
222
  path: string,
226
- controller: TDataProvider<{}> | null,
227
- renderer: TFrontRenderer<{}>
223
+ renderer: TFrontRenderer<TProvidedData>
228
224
  ): TRoute;
229
225
 
230
- public page(
226
+ public page<TProvidedData extends TFetcherList = TFetcherList>(
231
227
  path: string,
232
228
  options: Partial<TRoute["options"]>,
233
- renderer: TFrontRenderer<{}>
234
- ): TRoute;
235
-
236
- public page(
237
- path: string,
238
- options: Partial<TRoute["options"]>,
239
- controller: TDataProvider<{}> | null,
240
- renderer: TFrontRenderer<{}>
229
+ renderer: TFrontRenderer<TProvidedData>
241
230
  ): TRoute;
242
231
 
243
232
  public page(...args: TRegisterPageArgs): TRoute {
244
233
 
245
- const { path, options, controller, renderer, layout } = getRegisterPageArgs(...args);
234
+ const { path, options, renderer, layout } = getRegisterPageArgs(...args);
246
235
 
247
236
  // S'il s'agit d'une page, son id doit avoir été injecté via le plugin babel
248
237
  const id = options["id"];
@@ -260,7 +249,7 @@ export default class ClientRouter<
260
249
  ...defaultOptions,
261
250
  ...options
262
251
  },
263
- controller: (context: TClientOrServerContext) => new ClientPage(controller, renderer, context, layout)
252
+ controller: (context: TClientOrServerContext) => new ClientPage(route, renderer, context, layout)
264
253
  };
265
254
 
266
255
  this.routes.push(route);
@@ -275,7 +264,7 @@ export default class ClientRouter<
275
264
 
276
265
  const route: TErrorRoute = {
277
266
  code,
278
- controller: (context: TClientOrServerContext) => new ClientPage(null, renderer, context, layout),
267
+ controller: (context: TClientOrServerContext) => new ClientPage(route, renderer, context, layout),
279
268
  options
280
269
  };
281
270
 
@@ -391,7 +380,9 @@ export default class ClientRouter<
391
380
 
392
381
  const response = await this.createResponse(route, request, apiData)
393
382
 
394
- ReactDOM.hydrate( <App context={response.context} />, document.body, () => {
383
+ ReactDOM.hydrate((
384
+ <App context={response.context} />
385
+ ), document.body, () => {
395
386
 
396
387
  console.log(`Render complete`);
397
388
 
@@ -404,7 +395,7 @@ export default class ClientRouter<
404
395
  pageData: {} = {}
405
396
  ): Promise<ClientPage> {
406
397
 
407
- // Load if not done before
398
+ // Load the route if not done before
408
399
  if ('load' in route)
409
400
  route = this.routes[route.index] = await this.load(route);
410
401
 
@@ -9,7 +9,8 @@ import axios, { AxiosResponse, AxiosError, AxiosRequestConfig } from 'axios';
9
9
  import type { TApiResponseData } from '@server/services/router';
10
10
  import ApiClientService, {
11
11
  TPostData,
12
- TApiFetchOptions, TFetcherList, TFetcherArgs, TFetcher
12
+ TApiFetchOptions, TFetcherList, TFetcherArgs, TFetcher,
13
+ TDataReturnedByFetchers
13
14
  } from '@common/router/request/api';
14
15
  import { instancierViaCode, NetworkError } from '@common/errors';
15
16
  import type ClientApplication from '@client/app';
@@ -46,6 +47,13 @@ export default class ApiClient implements ApiClientService {
46
47
  /*----------------------------------
47
48
  - HIGH LEVEL
48
49
  ----------------------------------*/
50
+
51
+ public fetch<TProvidedData extends TFetcherList = TFetcherList>(
52
+ fetchers: TFetcherList
53
+ ): TDataReturnedByFetchers<TProvidedData> {
54
+ throw new Error("api.fetch shouldn't be called here.");
55
+ }
56
+
49
57
  public get = <TData extends unknown = unknown>(path: string, data?: TPostData, opts?: TApiFetchOptions) =>
50
58
  this.createFetcher<TData>('GET', path, data, opts);
51
59
 
@@ -120,7 +128,7 @@ export default class ApiClient implements ApiClientService {
120
128
  /*if (options?.captcha !== undefined)
121
129
  await this.gui.captcha.check(options?.captcha);*/
122
130
 
123
- return await this.fetch<TData>(method, path, data, options).catch((e) => {
131
+ return await this.execute<TData>(method, path, data, options).catch((e) => {
124
132
  this.app.handleError(e);
125
133
  throw e; // Throw to break the loop
126
134
  })
@@ -141,7 +149,7 @@ export default class ApiClient implements ApiClientService {
141
149
  // Fetch all the api data thanks to one http request
142
150
  const fetchedData = fetchersCount === 0
143
151
  ? 0
144
- : await this.fetch("POST", "/api", {
152
+ : await this.execute("POST", "/api", {
145
153
  fetchers: fetchersToRun
146
154
  }).then((res) => {
147
155
 
@@ -201,7 +209,7 @@ export default class ApiClient implements ApiClientService {
201
209
  return config;
202
210
  }
203
211
 
204
- public fetch<TData = unknown>(...args: TFetcherArgs): Promise<TData> {
212
+ public execute<TData = unknown>(...args: TFetcherArgs): Promise<TData> {
205
213
 
206
214
  const config = this.configure(...args);
207
215
 
@@ -6,8 +6,8 @@
6
6
  import type { ComponentChild } from 'preact';
7
7
 
8
8
  // Core
9
- import type { TClientOrServerContext, Layout } from '@common/router';
10
- import PageResponse, { TDataProvider, TFrontRenderer } from "@common/router/response/page";
9
+ import type { TClientOrServerContext, Layout, TRoute, TErrorRoute } from '@common/router';
10
+ import PageResponse, { TFrontRenderer } from "@common/router/response/page";
11
11
 
12
12
  // Specific
13
13
  import type ClientRouter from '..';
@@ -29,15 +29,13 @@ export default class ClientPage<TRouter = ClientRouter> extends PageResponse<TRo
29
29
  public scrollToId: string;
30
30
 
31
31
  public constructor(
32
- public dataProvider: TDataProvider | null,
32
+ public route: TRoute | TErrorRoute,
33
33
  public component: TFrontRenderer,
34
34
  public context: TClientOrServerContext,
35
- public layout?: Layout,
36
-
37
- public route = context.route
35
+ public layout?: Layout
38
36
  ) {
39
37
 
40
- super(dataProvider, component, context);
38
+ super(route, component, context);
41
39
 
42
40
  this.bodyId = context.route.options.bodyId;
43
41
  this.scrollToId = context.request.hash;
@@ -20,7 +20,7 @@ import type { TUserRole } from '@server/services/users';
20
20
  import type { TAppArrowFunction } from '@common/app';
21
21
 
22
22
  // Specfic
23
- import type { default as Page, TFrontRenderer } from './response/page';
23
+ import type { default as Page, TFrontRenderer, TDataProvider } from './response/page';
24
24
 
25
25
  /*----------------------------------
26
26
  - TYPES: ROUTES
@@ -81,6 +81,7 @@ export type TRouteOptions = {
81
81
 
82
82
  // Injected by the page plugin
83
83
  filepath?: string,
84
+ data?: TDataProvider
84
85
 
85
86
  // Indexing
86
87
  bodyId?: string,
@@ -10,7 +10,7 @@ import { getLayout } from './layouts';
10
10
 
11
11
  // types
12
12
  import type { TRouteOptions } from '.';
13
- import type { TDataProvider, TFrontRenderer } from './response/page';
13
+ import type { TFrontRenderer } from './response/page';
14
14
  import type { TRegisterPageArgs } from '@client/services/router';
15
15
 
16
16
  /*----------------------------------
@@ -21,20 +21,17 @@ export const getRegisterPageArgs = (...args: TRegisterPageArgs) => {
21
21
 
22
22
  let path: string;
23
23
  let options: Partial<TRouteOptions> = {};
24
- let controller: TDataProvider|null;
25
24
  let renderer: TFrontRenderer;
26
25
 
27
- if (args.length === 4)
28
- ([path, options, controller, renderer] = args)
29
- else if (typeof args[1] === 'object')
30
- ([path, options, renderer] = args)
26
+ if (args.length === 2)
27
+ ([path, renderer] = args)
31
28
  else
32
- ([path, controller, renderer] = args)
29
+ ([path, options, renderer] = args)
33
30
 
34
31
  // Automatic layout form the nearest _layout folder
35
32
  const layout = getLayout(path, options);
36
33
 
37
- return { path, options, controller, renderer, layout }
34
+ return { path, options, renderer, layout }
38
35
 
39
36
  }
40
37
 
@@ -2,10 +2,11 @@
2
2
  - DEPENDANCES
3
3
  ----------------------------------*/
4
4
 
5
- import type { ComponentChild, FunctionComponent } from 'preact';
5
+ // Npm
6
+ import type { VNode } from 'preact';
6
7
 
7
8
  // Core libs
8
- import { ClientOrServerRouter, TClientOrServerContext } from '@common/router';
9
+ import { ClientOrServerRouter, TClientOrServerContext, TRoute, TErrorRoute } from '@common/router';
9
10
  import { TFetcherList, TDataReturnedByFetchers } from '@common/router/request/api';
10
11
  import { history } from '@client/services/router/request/history';
11
12
 
@@ -14,21 +15,30 @@ import { history } from '@client/services/router/request/history';
14
15
  ----------------------------------*/
15
16
 
16
17
  // The function that fetch data from the api before to pass them as context to the renderer
17
- export type TDataProvider<TProvidedData extends TFetcherList = {}> =
18
- (context: TClientOrServerContext/* & TUrlData */) => TProvidedData
18
+ export type TDataProvider<TProvidedData extends TFetcherList = TFetcherList> = (
19
+ context: TClientOrServerContext & {
20
+ // URL query parameters
21
+ // TODO: typings
22
+ data: {[key: string]: string | number}
23
+ }
24
+ ) => TProvidedData
19
25
 
20
26
  // The function that renders routes
21
27
  export type TFrontRenderer<
22
- TProvidedData extends TFetcherList = {},
23
- TAdditionnalData = {},
28
+ TProvidedData extends TFetcherList = TFetcherList,
29
+ TAdditionnalData extends {} = {},
24
30
  TRouter = ClientOrServerRouter,
25
- > = FunctionComponent<(
26
- TClientOrServerContext
27
- &
28
- TDataReturnedByFetchers<TProvidedData>
29
- &
30
- TAdditionnalData
31
- )>;
31
+ > = (
32
+ context: (
33
+ TClientOrServerContext
34
+ &
35
+ TAdditionnalData
36
+ &
37
+ {
38
+ data: TDataReturnedByFetchers<TProvidedData>
39
+ }
40
+ )
41
+ ) => VNode<any> | null
32
42
 
33
43
  // Script or CSS resource
34
44
  export type TPageResource = {
@@ -46,7 +56,7 @@ const debug = false;
46
56
  /*----------------------------------
47
57
  - CLASS
48
58
  ----------------------------------*/
49
- export default class PageResponse<TRouter extends ClientOrServerRouter = ClientOrServerRouter> {
59
+ export default abstract class PageResponse<TRouter extends ClientOrServerRouter = ClientOrServerRouter> {
50
60
 
51
61
  // Metadata
52
62
  public chunkId: string;
@@ -65,7 +75,7 @@ export default class PageResponse<TRouter extends ClientOrServerRouter = ClientO
65
75
  public data: TObjetDonnees = {};
66
76
 
67
77
  public constructor(
68
- public dataProvider: TDataProvider | null,
78
+ public route: TRoute | TErrorRoute,
69
79
  public renderer: TFrontRenderer,
70
80
  public context: TClientOrServerContext
71
81
  ) {
@@ -77,8 +87,12 @@ export default class PageResponse<TRouter extends ClientOrServerRouter = ClientO
77
87
  public async fetchData() {
78
88
 
79
89
  // Load the fetchers list to load data if needed
80
- if (this.dataProvider)
81
- this.fetchers = this.dataProvider({ ...this.context, ...this.context.request.data });
90
+ const dataFetcher = this.route.options.data;
91
+ if (dataFetcher)
92
+ this.fetchers = dataFetcher({
93
+ ...this.context,
94
+ data: this.context.request.data
95
+ });
82
96
 
83
97
  // Execute the fetchers for missing data
84
98
  debug && console.log(`[router][page] Fetching api data:` + Object.keys(this.fetchers));
@@ -4,9 +4,13 @@
4
4
 
5
5
  // Core
6
6
  import AppContainer from './container';
7
- import ApplicationService, { AnyService } from './service';
7
+ import ApplicationService, { StartedServicesIndex } from './service';
8
8
  import CommandsManager from './commands';
9
- import ServicesContainer, { TRegisteredService, TServiceMetas } from './service/container';
9
+ import ServicesContainer, {
10
+ ServicesContainer as ServicesContainerClass,
11
+ TRegisteredService,
12
+ TServiceMetas
13
+ } from './service/container';
10
14
  import type { ServerBug } from '../services/console';
11
15
 
12
16
  // Built-in
@@ -49,7 +53,12 @@ export const Service = ServicesContainer;
49
53
  /*----------------------------------
50
54
  - FUNCTIONS
51
55
  ----------------------------------*/
52
- export class Application extends ApplicationService<Config, Hooks, /* TODO: this ? */Application, {}> {
56
+ export class Application<
57
+ TServicesContainer extends ServicesContainerClass = ServicesContainerClass
58
+ > extends ApplicationService<Config, Hooks, /* TODO: this ? */Application, {}> {
59
+
60
+ public app!: this;
61
+ public servicesContainer!: TServicesContainer;
53
62
 
54
63
  /*----------------------------------
55
64
  - PROPERTIES
@@ -53,7 +53,7 @@ export class ServicesContainer<
53
53
  public registered: TRegisteredServicesIndex = {}
54
54
 
55
55
  // All service instances by service id
56
- public allServices: {[serviceId: string]: AnyService} = {}
56
+ public allServices: TServicesIndex = {} as TServicesIndex
57
57
 
58
58
  public setup<TServiceId extends keyof TServicesIndex>(
59
59
  serviceId: keyof TServicesIndex,
@@ -12,7 +12,8 @@ import ServicesContainer from './container';
12
12
  - TYPES: OPTIONS
13
13
  ----------------------------------*/
14
14
 
15
- export type AnyService = Service<{}, {}, Application, {}>
15
+ export type AnyService<TSubServices extends StartedServicesIndex = StartedServicesIndex> =
16
+ Service<{}, {}, Application, TSubServices>
16
17
 
17
18
  type TServiceConfig = {
18
19
  debug?: boolean
@@ -140,10 +141,26 @@ export default abstract class Service<
140
141
  // this.use immediatly instanciate the subservice for few reasons:
141
142
  // - The subservice instance can be accesses from another service in the constructor, no matter the order of loading of the services
142
143
  // - Consistency: the subserviuce proprties shouldn't be assogned to two different values according depending on the app lifecycle
143
- public use<TServiceId extends keyof TServicesIndex>(
144
+ public use<
145
+ TInstalledServices extends this["app"]["servicesContainer"]["allServices"],
146
+ TServiceId extends keyof TInstalledServices,
147
+ TServiceClass extends TInstalledServices[TServiceId],
148
+ TSubServices extends TServiceClass["services"],
149
+ >(
144
150
  serviceId: TServiceId,
145
- // TODO: Only subservices types supported by the parent service
146
- subServices: TServicesIndex[TServiceId]["services"] = {}
151
+ subServices?: TSubServices
152
+ ): (
153
+ // We can't pass the services types as a generic to TServiceClass
154
+ // So we overwrite the services property
155
+ ReturnType< TServiceClass["getServiceInstance"] >
156
+ &
157
+ {
158
+ new (...args: any[]): TServiceClass & { services: TSubServices },
159
+ services: TSubServices
160
+ }
161
+ /*Omit<TServiceClass, 'services'> & {
162
+ services: TSubServices
163
+ }*/
147
164
  ) {
148
165
 
149
166
  // Check of the service has been configurated
@@ -152,7 +169,7 @@ export default abstract class Service<
152
169
  throw new Error(`Unable to use service "${serviceId}": This one hasn't been setup.`);
153
170
 
154
171
  // Bind subservices
155
- registered.subServices = subServices;
172
+ registered.subServices = subServices || {};
156
173
 
157
174
  // Check if not already instanciated
158
175
  const existing = ServicesContainer.allServices[ serviceId ];
@@ -176,7 +193,7 @@ export default abstract class Service<
176
193
  return service;
177
194
  }
178
195
 
179
- protected bindService( localName: string, service: AnyService ) {
196
+ public bindService( localName: string, service: AnyService ) {
180
197
 
181
198
  const serviceScope = this.constructor.name + '.' + localName;
182
199
 
@@ -196,7 +213,7 @@ export default abstract class Service<
196
213
 
197
214
  }
198
215
 
199
- protected async startService( localName: string, service: AnyService ) {
216
+ public async startService( localName: string, service: AnyService ) {
200
217
  // Service already started
201
218
  if (!service.started) {
202
219
 
@@ -107,13 +107,16 @@ export const mysqlToJs = {
107
107
  'POINT': 'float',
108
108
 
109
109
  // Integres
110
- 'INT': 'int',
111
- 'BIGINT': 'int',
110
+ 'BIT': 'int',
112
111
  'LONG': 'int',
113
112
  'LONGLONG': 'int',
113
+
114
114
  'TINYINT': 'int',
115
115
  'SMALLINT': 'int',
116
116
  'MEDIUMINT': 'int',
117
+ 'INT': 'int',
118
+ 'INTEGER': 'int',
119
+ 'BIGINT': 'int',
117
120
 
118
121
  // Dates
119
122
  'DATE': 'date',
@@ -121,9 +124,18 @@ export const mysqlToJs = {
121
124
 
122
125
  // Strings
123
126
  'VARCHAR': 'string',
127
+ 'BINARY': 'string',
128
+ 'VARBINARY': 'string',
129
+ 'TINYBLOB': 'string',
130
+ 'TINY_BLOB': 'string',
131
+ 'MEDIUM_BLOB': 'string',
132
+ 'BLOB': 'string',
133
+ 'LONG_BLOB': 'string',
124
134
  'CHAR': 'string',
125
135
  'VAR_STRING': 'string',
126
136
  'LONGTEXT': 'string',
137
+ 'TINYTEXT': 'string',
138
+ 'MEDIUMTEXT': 'string',
127
139
  'TEXT': 'string',
128
140
  'ENUM': 'enum',
129
141
 
@@ -5,7 +5,6 @@
5
5
  // Core
6
6
  import type { Application } from '@server/app';
7
7
  import Service, { AnyService } from '@server/app/service';
8
- import type { TRegisteredServicesIndex } from '@server/app/service/container';
9
8
 
10
9
  // Specific
11
10
  import type Driver from './driver';
@@ -25,7 +24,7 @@ export type Hooks = {
25
24
  }
26
25
 
27
26
  export type Services = {
28
-
27
+ [diskId: string]: Driver
29
28
  }
30
29
 
31
30
  /*----------------------------------
@@ -28,9 +28,6 @@ export type Config = {
28
28
  transporter: string,
29
29
  from: TPerson
30
30
  },
31
- transporters: {
32
- [transporterName: string]: Transporter
33
- },
34
31
  bugReport: {
35
32
  from: TPerson,
36
33
  to: TPerson
@@ -111,14 +108,14 @@ type TOptions = {
111
108
  ----------------------------------*/
112
109
  export default class Email extends Service<Config, Hooks, Application, Services> {
113
110
 
114
- private transporters = this.config.transporters;
111
+ private transporters = this.services;
115
112
 
116
113
  /*----------------------------------
117
114
  - LIFECYCLE
118
115
  ----------------------------------*/
119
116
 
120
117
  public async start() {
121
-
118
+
122
119
  }
123
120
 
124
121
  public async ready() {
@@ -6,6 +6,7 @@
6
6
 
7
7
  // Core
8
8
  import type Application from "@server/app";
9
+ import Service from '@server/app/service';
9
10
  import type EmailService from '@server/services/email';
10
11
 
11
12
  // Specific
@@ -23,16 +24,28 @@ export type TBasicConfig = {
23
24
  /*----------------------------------
24
25
  - CLASS
25
26
  ----------------------------------*/
26
- export abstract class Transporter<TConfig extends {} = {}> {
27
+ export abstract class Transporter<TConfig extends TBasicConfig = TBasicConfig>
28
+ extends Service<TConfig, {}, Application, {}> {
27
29
 
28
- public constructor(
29
- protected app: Application & { email: EmailService },
30
- protected config: TBasicConfig & TConfig,
30
+ /*----------------------------------
31
+ - LIFECYCLE
32
+ ----------------------------------*/
31
33
 
32
- protected email = app.email
33
- ) {
34
+ protected async start() {
35
+
36
+ }
37
+
38
+ protected async ready() {
39
+
40
+ }
41
+
42
+ protected async shutdown() {
34
43
 
35
44
  }
36
45
 
46
+ /*----------------------------------
47
+ - ACTIONS
48
+ ----------------------------------*/
49
+
37
50
  public abstract send( emails: TCompleteEmail[] ): Promise<void>;
38
51
  }
@@ -194,7 +194,7 @@ export default class HttpServer {
194
194
  ----------------------------------*/
195
195
 
196
196
  // TODO: Migrer dans app
197
- routes.use('/chrome', cors());
197
+ //routes.use('/chrome', cors());
198
198
  // TODO: Trouver une solution pour n'autoriser les requetes que depuis l'application & dopamyn.io
199
199
  // https://www.google.com/search?q=http+cors+from+android%7Cwindows%7Cdesktop%7Cmodile+app
200
200
  //routes.use('/auth', cors());
@@ -225,7 +225,7 @@ export default class HttpServer {
225
225
  // Impossible donc de créer un serveur http ici, on le fera dans start.js
226
226
  console.info("Lancement du serveur web");
227
227
  this.http.listen(this.config.port, () => {
228
- console.info(`Serveur web démarré sur ${this.publicUrl}`);
228
+ console.info(`Web server ready on ${this.publicUrl}`);
229
229
  });
230
230
 
231
231
  }
@@ -95,8 +95,6 @@ export type Config<
95
95
  }
96
96
 
97
97
  export type Services = {
98
- disks?: DisksManager
99
- } & {
100
98
  [routerServiceId: string]: RouterService
101
99
  }
102
100
 
@@ -113,14 +111,15 @@ export type Hooks = {
113
111
  - CLASSE
114
112
  ----------------------------------*/
115
113
  export default class ServerRouter<
116
- TConfig extends Config = Config,
117
- TApplication extends Application = Application
118
- > extends Service<TConfig, Hooks, TApplication, Services> implements BaseRouter {
114
+ TSubservices extends Services = Services
115
+ > extends Service<Config, Hooks, Application, TSubservices> implements BaseRouter {
119
116
 
117
+ public disks = this.use('Core/Disks') as unknown as DisksManager;
118
+
120
119
  // Services
121
120
  public http: HTTP;
122
121
  public render: DocumentRenderer<this>;
123
- protected routerServices: {[serviceId: string]: RouterService} = {}
122
+ protected routerServices: TSubservices = {} as TSubservices
124
123
 
125
124
  // Indexed
126
125
  public routes: TRoute[] = []; // API + pages front front
@@ -133,9 +132,9 @@ export default class ServerRouter<
133
132
 
134
133
  public constructor(
135
134
  parent: AnyService,
136
- config: TConfig,
137
- services: Services,
138
- app: TApplication,
135
+ config: Config,
136
+ services: TSubservices,
137
+ app: Application,
139
138
  ) {
140
139
 
141
140
  super(parent, config, services, app);
@@ -217,7 +216,7 @@ export default class ServerRouter<
217
216
 
218
217
  public page(...args: TRegisterPageArgs) {
219
218
 
220
- const { path, options, controller, renderer, layout } = getRegisterPageArgs(...args);
219
+ const { path, options, renderer, layout } = getRegisterPageArgs(...args);
221
220
 
222
221
  const { regex, keys } = buildRegex(path);
223
222
 
@@ -226,7 +225,7 @@ export default class ServerRouter<
226
225
  path,
227
226
  regex,
228
227
  keys,
229
- controller: (context: TRouterContext<this>) => new Page(controller, renderer, context, layout),
228
+ controller: (context: TRouterContext<this>) => new Page(route, renderer, context, layout),
230
229
  options: {
231
230
  ...defaultOptions,
232
231
  accept: 'html', // Les pages retournent forcémment du html
@@ -249,11 +248,13 @@ export default class ServerRouter<
249
248
  // Automatic layout form the nearest _layout folder
250
249
  const layout = getLayout('Error ' + code, options);
251
250
 
252
- this.errors[code] = {
251
+ const route = {
253
252
  code,
254
- controller: (context: TRouterContext<this>) => new Page(null, renderer, context, layout),
253
+ controller: (context: TRouterContext<this>) => new Page(route, renderer, context, layout),
255
254
  options
256
255
  };
256
+
257
+ this.errors[code] = route;
257
258
  }
258
259
 
259
260
  public all = (...args: TApiRegisterArgs<this>) => this.registerApi('*', ...args);
@@ -7,7 +7,8 @@
7
7
  import RequestService from './service';
8
8
 
9
9
  import ApiClientService, {
10
- TApiFetchOptions, TFetcherList, TFetcherArgs, TFetcher
10
+ TApiFetchOptions, TFetcherList, TFetcherArgs, TFetcher,
11
+ TDataReturnedByFetchers
11
12
  } from '@common/router/request/api';
12
13
 
13
14
  /*----------------------------------
@@ -28,6 +29,12 @@ export default class ApiClientRequest extends RequestService implements ApiClien
28
29
  - HIGH LEVEL
29
30
  ----------------------------------*/
30
31
 
32
+ public fetch<TProvidedData extends TFetcherList = TFetcherList>(
33
+ fetchers: TFetcherList
34
+ ): TDataReturnedByFetchers<TProvidedData> {
35
+ throw new Error("api.fetch shouldn't be called here.");
36
+ }
37
+
31
38
  public get = <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
32
39
  this.createFetcher<TData>('GET', path, data, opts);
33
40
 
@@ -242,11 +242,11 @@ export default class ServerResponse<
242
242
  // ? this.app.path.root + '/bin' + fichier
243
243
  // : this.app.path.data + '/' + fichier;
244
244
  // Disk not provided = file response disabled
245
- if (this.router.services.disks === undefined)
245
+ if (this.router.disks === undefined)
246
246
  throw new Anomaly("Router: Unable to return file response in router, because no disk has been given in the router config.");
247
247
 
248
248
  // Retirve disk driver
249
- const disk = this.router.services.disks.get('default');
249
+ const disk = this.router.disks.get('default');
250
250
 
251
251
  // Verif existance
252
252
  const fileExists = await disk.exists('data', fichier);
@@ -9,8 +9,8 @@ const safeStringify = require('fast-safe-stringify'); // remplace les référenc
9
9
 
10
10
  // Core
11
11
  import { default as Router, TRouterContext } from "@server/services/router";
12
- import type { Layout } from '@common/router';
13
- import PageResponse, { TDataProvider, TFrontRenderer } from "@common/router/response/page";
12
+ import type { Layout, TRoute, TErrorRoute } from '@common/router';
13
+ import PageResponse, { TFrontRenderer } from "@common/router/response/page";
14
14
 
15
15
  // Composants UI
16
16
  import App from '@client/app/component';
@@ -34,18 +34,17 @@ const seoLimits = {
34
34
  export default class Page<TRouter extends Router = Router> extends PageResponse<TRouter> {
35
35
 
36
36
  public constructor(
37
- public dataProvider: TDataProvider | null,
37
+ public route: TRoute | TErrorRoute,
38
38
  public renderer: TFrontRenderer,
39
39
  public context: TRouterContext,
40
40
  public layout?: Layout,
41
41
 
42
- public route = context.route,
43
42
  public app = context.app,
44
43
  public router = context.request.router,
45
44
 
46
45
  ) {
47
46
 
48
- super(dataProvider, renderer, context)
47
+ super(route, renderer, context)
49
48
 
50
49
  }
51
50
 
@@ -14,7 +14,6 @@ import RequestValidator, { TConfig } from '../request';
14
14
  - TYPES
15
15
  ----------------------------------*/
16
16
 
17
- type TRouterWithSchema<TAuthService extends SchemaRouterService> = Router<RouterConfig<{ auth: TAuthService }>>
18
17
 
19
18
  /*----------------------------------
20
19
  - SERVICE
@@ -43,7 +42,7 @@ export default class SchemaRouterService<
43
42
  - ROUTER SERVICE LIFECYCLE
44
43
  ----------------------------------*/
45
44
 
46
- public requestService( request: ServerRequest< TRouterWithSchema<this>> ): RequestValidator {
45
+ public requestService( request: ServerRequest ): RequestValidator {
47
46
  return new RequestValidator( request, this.config );
48
47
  }
49
48
  }