5htp-core 0.3.4 → 0.3.5

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 (41) hide show
  1. package/package.json +1 -1
  2. package/src/client/app/component.tsx +3 -0
  3. package/src/client/assets/css/components/button.less +6 -5
  4. package/src/client/assets/css/components/card.less +0 -22
  5. package/src/client/assets/css/components.less +0 -25
  6. package/src/client/assets/css/core.less +62 -3
  7. package/src/client/assets/css/text/icons.less +3 -2
  8. package/src/client/assets/css/text/text.less +0 -4
  9. package/src/client/assets/css/theme.less +69 -39
  10. package/src/client/assets/css/utils/layouts.less +1 -12
  11. package/src/client/assets/css/utils/medias.less +2 -15
  12. package/src/client/components/Dialog/index.less +2 -0
  13. package/src/client/components/Form.ts +4 -3
  14. package/src/client/components/Row/index.less +2 -0
  15. package/src/client/components/Video/index.less +6 -1
  16. package/src/client/components/containers/Popover/index.tsx +1 -2
  17. package/src/client/components/containers/Popover/popover.less +2 -0
  18. package/src/client/components/data/progressbar/index.less +2 -0
  19. package/src/client/components/inputv3/base.less +6 -0
  20. package/src/client/components/inputv3/file/index.less +2 -0
  21. package/src/client/pages/_messages/401.tsx +1 -2
  22. package/src/client/services/router/components/Page.tsx +1 -0
  23. package/src/client/services/router/components/router.tsx +37 -13
  24. package/src/client/services/router/index.tsx +22 -13
  25. package/src/client/services/router/request/api.ts +21 -13
  26. package/src/client/services/router/response/index.tsx +26 -12
  27. package/src/client/services/router/response/page.ts +1 -1
  28. package/src/common/router/index.ts +41 -0
  29. package/src/common/router/request/api.ts +2 -0
  30. package/src/common/router/response/index.ts +2 -2
  31. package/src/common/router/response/page.ts +1 -0
  32. package/src/common/validation/validator.ts +12 -2
  33. package/src/common/validation/validators.ts +5 -5
  34. package/src/server/app/index.ts +0 -1
  35. package/src/server/app/service/index.ts +12 -3
  36. package/src/server/services/console/index.ts +2 -4
  37. package/src/server/services/router/http/index.ts +5 -7
  38. package/src/server/services/router/index.ts +9 -10
  39. package/src/server/services/router/request/api.ts +7 -2
  40. package/src/server/services/router/response/index.ts +13 -12
  41. package/src/types/aliases.d.ts +4 -4
@@ -15,7 +15,9 @@ import type {
15
15
  import type { TBasicSSrData } from '@server/services/router/response';
16
16
 
17
17
  import BaseRouter, {
18
- defaultOptions, TRoute, TErrorRoute, TClientOrServerContext, TRouteModule
18
+ defaultOptions, TRoute, TErrorRoute,
19
+ TClientOrServerContext, TRouteModule,
20
+ buildUrl, TDomainsList
19
21
  } from '@common/router'
20
22
  import { getLayout } from '@common/router/layouts';
21
23
  import { getRegisterPageArgs, buildRegex } from '@common/router/register';
@@ -27,6 +29,7 @@ import type ClientApplication from '@client/app';
27
29
  import Service from '@client/app/service';
28
30
 
29
31
  // Specific
32
+ import type { ClientContext } from '@/client/context';
30
33
  import ClientRequest from './request';
31
34
  import { location, history } from './request/history';
32
35
  import ClientResponse from './response';
@@ -122,7 +125,8 @@ type THookName = 'location.change' | 'page.changed'
122
125
 
123
126
  type Config<TAdditionnalContext extends {} = {}> = {
124
127
  preload: string[], // List of globs
125
- context: (router: ClientRouter) => TAdditionnalContext
128
+ context: (context: ClientContext, router: ClientRouter) => TAdditionnalContext,
129
+ domains: TDomainsList
126
130
  }
127
131
 
128
132
  /*----------------------------------
@@ -134,8 +138,11 @@ export default class ClientRouter<
134
138
  > extends Service<Config<TAdditionnalContext>, ClientApplication> implements BaseRouter {
135
139
 
136
140
  // Context data
137
- public context = window["ssr"] as (TBasicSSrData | undefined);
138
141
  public ssrRoutes = window["routes"] as TSsrUnresolvedRoute[];
142
+ public ssrContext = window["ssr"] as (TBasicSSrData | undefined);
143
+ public context!: ClientContext;
144
+
145
+ public setLoading!: React.Dispatch< React.SetStateAction<boolean> >;
139
146
 
140
147
  public constructor(app: TApplication, config: Config<TAdditionnalContext>) {
141
148
 
@@ -149,9 +156,13 @@ export default class ClientRouter<
149
156
  this.initialRender(currentRoute);
150
157
  }
151
158
 
159
+ public url = (path: string, params: {} = {}, absolute: boolean = true) =>
160
+ buildUrl(path, params, this.config.domains, absolute);
161
+
152
162
  public go( url: string ) {
163
+ url = this.url(url, {}, false);
153
164
  console.log( LogPrefix, "Go to", url);
154
- history?.replace(url);
165
+ history?.replace( url );
155
166
  }
156
167
 
157
168
  /*----------------------------------
@@ -203,9 +214,9 @@ export default class ClientRouter<
203
214
  if (currentRoute === undefined) {
204
215
 
205
216
  const isCurrentRoute = (
206
- this.context !== undefined
217
+ this.ssrContext !== undefined
207
218
  &&
208
- route.chunk === this.context.page.chunkId
219
+ route.chunk === this.ssrContext.page.chunkId
209
220
  );
210
221
 
211
222
  if (isCurrentRoute) {
@@ -365,20 +376,18 @@ export default class ClientRouter<
365
376
 
366
377
  // Restituate SSR response
367
378
  let apiData: {} = {}
368
- if (this.context) {
369
-
370
- console.log("SSR Response restitution ...");
379
+ if (this.ssrContext) {
371
380
 
372
- request.user = this.context.user || null;
381
+ request.user = this.ssrContext.user || null;
373
382
 
374
- request.data = this.context.request.data;
383
+ request.data = this.ssrContext.request.data;
375
384
 
376
- apiData = this.context.page.data || {};
385
+ apiData = this.ssrContext.page.data || {};
377
386
  }
378
387
 
379
388
  // Replacer api data par ssr data
380
389
 
381
- const response = await this.createResponse(route, request, apiData)
390
+ const response = await this.createResponse(route, request, apiData);
382
391
 
383
392
  ReactDOM.hydrate((
384
393
  <App context={response.context} />
@@ -39,7 +39,7 @@ export default class ApiClient implements ApiClientService {
39
39
  public constructor(
40
40
  public app: ClientApplication,
41
41
  public request: Request,
42
- public router = request.router
42
+ public router = request.router,
43
43
  ) {
44
44
 
45
45
  }
@@ -66,30 +66,34 @@ export default class ApiClient implements ApiClientService {
66
66
  public delete = <TData extends unknown = unknown>(path: string, data?: TPostData, opts?: TApiFetchOptions) =>
67
67
  this.createFetcher<TData>('DELETE', path, data, opts);
68
68
 
69
-
70
69
  public set( newData: TObjetDonnees ) {
71
70
 
72
- console.log("[api] Update page data", newData);
73
- if (this.app.page)
74
- this.app.page.setAllData(curData => ({ ...curData, ...newData }));
75
-
71
+ if (!('context' in this.router))
72
+ throw new Error("api.set is not available on server side.");
73
+
74
+ if (this.router.context.page)
75
+ this.router.context.page.setAllData(curData => ({ ...curData, ...newData }));
76
+ else
77
+ throw new Error(`[api] this.router.context.page undefined`)
76
78
  }
77
79
 
78
80
  public reload( ids?: string | string[], params?: TObjetDonnees ) {
81
+
82
+ if (!('context' in this.router))
83
+ throw new Error("api.set is not available on server side.");
79
84
 
80
- if (this.app.page === undefined)
81
- throw new Error("context.page is missing");
85
+ const page = this.router.context.page;
82
86
 
83
87
  if (ids === undefined)
84
- ids = Object.keys(this.app.page.fetchers);
88
+ ids = Object.keys(page.fetchers);
85
89
  else if (typeof ids === 'string')
86
90
  ids = [ids];
87
91
 
88
- console.log("[api] Reload data", ids, params, this.app.page.fetchers);
92
+ console.log("[api] Reload data", ids, params, page.fetchers);
89
93
 
90
94
  for (const id of ids) {
91
95
 
92
- const fetcher = this.app.page.fetchers[id];
96
+ const fetcher = page.fetchers[id];
93
97
  if (fetcher === undefined)
94
98
  return console.error(`Unable to reload ${id}: Request not found in fetchers list.`);
95
99
 
@@ -169,12 +173,15 @@ export default class ApiClient implements ApiClientService {
169
173
  public configure = (...[method, path, data, options]: TFetcherArgs): AxiosRequestConfig => {
170
174
 
171
175
  const { onProgress, captcha } = options || {};
176
+
177
+ const url = this.router.url( path, {}, false );
172
178
 
173
- debug && console.log(`[api] Sending request`, method, path, data);
179
+ debug && console.log(`[api] Sending request`, method, url, data);
174
180
 
181
+ // Create AXIOS config
175
182
  const config: AxiosRequestConfig = {
176
183
 
177
- url: path,
184
+ url,
178
185
  method: method,
179
186
  headers: {
180
187
  'Content-Type': "application/json",
@@ -192,6 +199,7 @@ export default class ApiClient implements ApiClientService {
192
199
 
193
200
  };
194
201
 
202
+ // Format request data
195
203
  if (data) {
196
204
  // URL params
197
205
  if (method === "GET") {
@@ -6,8 +6,8 @@
6
6
  import type ServerRouter from '@server/services/router';
7
7
  import type ServerResponse from '@server/services/router/response';
8
8
 
9
- import type { TRoute, TErrorRoute } from '@common/router';
10
- import BaseResponse from '@common/router/response';
9
+ import type { TAnyRoute, TErrorRoute } from '@common/router';
10
+ import BaseResponse, { TResponseData } from '@common/router/response';
11
11
 
12
12
  import type ClientApplication from '@client/app';
13
13
  import type { default as ClientRouter } from '@client/services/router'
@@ -15,7 +15,6 @@ import type ClientResponse from '@client/services/router/response'
15
15
  import ClientRequest from '@client/services/router/request'
16
16
  import ClientPage from '@client/services/router/response/page'
17
17
  import { history } from '@client/services/router/request/history';
18
- import CommonPage from '@common/router/response/page';
19
18
 
20
19
  /*----------------------------------
21
20
  - TYPES
@@ -34,12 +33,11 @@ export type TRouterContext<
34
33
  // ClientPage context
35
34
  {
36
35
  app: TApplication,
37
- context: TRouterContext<TRouter, TApplication>,
38
36
  request: ClientRequest<TRouter>,
39
- route: TRoute<TRouterContext>,
37
+ route: TAnyRoute<TRouterContext>,
40
38
  api: ClientRequest<TRouter>["api"],
41
39
  page: ClientPage<TRouter>,
42
- user: User
40
+ data: TObjetDonnees
43
41
  }
44
42
  &
45
43
  // Expose client application services (api, socket, ...)
@@ -61,7 +59,7 @@ export default class ClientPageResponse<
61
59
 
62
60
  public constructor(
63
61
  public request: ClientRequest<TRouter>,
64
- public route: TRoute | TErrorRoute,
62
+ public route: TAnyRoute | TErrorRoute,
65
63
 
66
64
  public app = request.app,
67
65
  ) {
@@ -76,22 +74,38 @@ export default class ClientPageResponse<
76
74
 
77
75
  private createContext(): TRouterContext<TRouter, TRouter["app"]> {
78
76
 
79
- const context: TRouterContext<TRouter, TRouter["app"]> = {
77
+ const basicContext: TRouterContext<TRouter, TRouter["app"]> = {
78
+
80
79
  // App services (TODO: expose only services)
81
80
  ...this.request.app,
81
+
82
82
  // Router context
83
83
  app: this.app,
84
- context: undefined as unknown as TRouterContext<TRouter, TRouter["app"]>,
85
84
  request: this.request,
86
85
  route: this.route,
87
86
  api: this.request.api,
87
+ // Will be assigned when the controller will be runned
88
+ page: undefined as unknown as ClientPage<TRouter>,
89
+ data: {},
90
+ }
88
91
 
89
- ...this.request.router.config.context( this.request.router )
92
+ const newContext: TRouterContext<TRouter, TRouter["app"]> = {
93
+ ...basicContext,
94
+ // Custom context
95
+ ...this.request.router.config.context( basicContext, this.request.router )
90
96
  }
91
97
 
92
- context.context = context;
98
+ // Update context object if already exists
99
+ // NOTE: we don't create a nex instance of context because we don't want to rereder the full page (inc layout) to update the context given by thr react context provider
100
+ const existingContext = this.request.router.context;
101
+ if (existingContext === undefined) {
102
+
103
+ this.request.router.context = newContext
104
+
105
+ } else for(const key in newContext)
106
+ existingContext[ key ] = newContext[ key ];
93
107
 
94
- return context;
108
+ return newContext
95
109
  }
96
110
 
97
111
  public async runController( additionnalData: {} = {} ): Promise<ClientPage> {
@@ -45,7 +45,7 @@ export default class ClientPage<TRouter = ClientRouter> extends PageResponse<TRo
45
45
  this.context.page = this;
46
46
 
47
47
  // Data succesfully loaded
48
- this.data = data || await this.fetchData();
48
+ this.context.data = this.data = data || await this.fetchData();
49
49
 
50
50
  return this;
51
51
  }
@@ -107,10 +107,51 @@ export type TRouteModule<TRegisteredRoute = any> = {
107
107
  __register?: TAppArrowFunction<TRegisteredRoute>
108
108
  }
109
109
 
110
+ export type TDomainsList = {
111
+ [endpointId: string]: string
112
+ } & {
113
+ current: string
114
+ }
115
+
110
116
  export const defaultOptions = {
111
117
  priority: 0,
112
118
  }
113
119
 
120
+ /*----------------------------------
121
+ - FUNCTIONS
122
+ ----------------------------------*/
123
+ export const buildUrl = (
124
+ path: string,
125
+ params: {} = {},
126
+ domains: TDomainsList,
127
+ absolute: boolean
128
+ ) => {
129
+
130
+ // Relative to domain
131
+ if (path[0] === '/' && absolute)
132
+ return domains.current + path;
133
+ // Other domains of the project
134
+ else if (path[0] === '@') {
135
+
136
+ // Extract domain ID from path
137
+ let domainId: string;
138
+ const slackPos = path.indexOf('/');
139
+ domainId = path.substring(1, slackPos);
140
+ path = path.substring(slackPos);
141
+
142
+ // Get domain
143
+ const domain = domains[ domainId ];
144
+ if (domain === undefined)
145
+ throw new Error("Unknown API endpoint ID: " + domainId);
146
+
147
+ // Return full url
148
+ return domain + path;
149
+
150
+ // Absolute URL
151
+ } else
152
+ return path;
153
+ }
154
+
114
155
  /*----------------------------------
115
156
  - BASE ROUTER
116
157
  ----------------------------------*/
@@ -72,6 +72,8 @@ export default abstract class ApiClient {
72
72
 
73
73
  public abstract delete<TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions): TFetcher<TData>;
74
74
 
75
+ public abstract set( newData: TObjetDonnees );
76
+
75
77
  /*----------------------------------
76
78
  - LOW LEVEL
77
79
  ----------------------------------*/
@@ -7,14 +7,14 @@ import { FunctionalComponent } from "preact";
7
7
 
8
8
  // Core
9
9
  import { TAnyRoute } from "..";
10
- import type ClientRequest from '@client/services/router';
10
+ import type ClientRequest from '@client/services/router/request';
11
11
  import Page from '@client/services/router/response/page'
12
12
 
13
13
  /*----------------------------------
14
14
  - TYPES
15
15
  ----------------------------------*/
16
16
 
17
- type TResponseData = Page
17
+ export type TResponseData = Page
18
18
 
19
19
  /*----------------------------------
20
20
  - CONTEXT
@@ -35,6 +35,7 @@ export type TFrontRenderer<
35
35
  TAdditionnalData
36
36
  &
37
37
  {
38
+ context: TClientOrServerContext,
38
39
  data: {[key: string]: PrimitiveValue}
39
40
  }
40
41
  )
@@ -10,6 +10,7 @@ import { InputError } from '@common/errors';
10
10
 
11
11
  // Specific
12
12
  import type { TValidateOptions } from './schema';
13
+ import type { InputBaseProps } from '@client/components/inputv3/base';
13
14
 
14
15
  /*----------------------------------
15
16
  - TYPES
@@ -64,14 +65,23 @@ export const EXCLUDE_VALUE = "action:exclure" as const;
64
65
  /*----------------------------------
65
66
  - CLASS
66
67
  ----------------------------------*/
67
- export default class Validator<TValue, TOptions extends TValidator<TValue> = TValidator<TValue>> {
68
+ export default class Validator<
69
+ TValue,
70
+ TOptions extends TValidator<TValue> = TValidator<TValue>,
71
+ TComponent = React.FunctionComponent< InputBaseProps< TValue > >
72
+ > {
68
73
 
69
74
  public constructor(
70
75
  public type: string,
71
76
  public validateType: TValidationFunction<TValue>,
72
- public options: TOptions
77
+ public options: TOptions,
78
+ public componentAttributes: Partial<InputBaseProps<TValue>> = {}
73
79
  ) {
74
80
 
81
+ // Basic component attriutes
82
+ this.componentAttributes.required = options?.opt !== true;
83
+ //this.componentAttributes.validator = this;
84
+
75
85
  }
76
86
 
77
87
  public isEmpty = (val: any) => val === undefined || val === '' || val === null
@@ -111,22 +111,22 @@ export default class SchemaValidators {
111
111
  })
112
112
  }
113
113
 
114
- public choice = (values?: any[], opts: TValidator<any> & {} = {}) =>
114
+ public choice = (choices?: any[], opts: TValidator<any> & {} = {}) =>
115
115
  new Validator<any>('choice', (val, input, output) => {
116
116
 
117
117
  // Choice object
118
118
  if (typeof val === 'object' && ('value' in val) && typeof val.value !== 'object')
119
119
  val = val.value;
120
120
 
121
- if (values !== undefined) {
122
- const isValid = values.some(v => v.value === val);
121
+ if (choices !== undefined) {
122
+ const isValid = choices.some(v => v.value === val);
123
123
  if (!isValid)
124
- throw new InputError("Invalid value. Must be: " + values.map(v => v.value).join(', '));
124
+ throw new InputError("Invalid value. Must be: " + choices.map(v => v.value).join(', '));
125
125
  }
126
126
 
127
127
  return val;
128
128
 
129
- }, opts)
129
+ }, opts, { choices })
130
130
 
131
131
  /*----------------------------------
132
132
  - CHAINES
@@ -165,7 +165,6 @@ export class Application<
165
165
  public async startServices() {
166
166
 
167
167
  const propsNames = Object.getOwnPropertyNames(this);
168
-
169
168
  for (const propName of propsNames) {
170
169
 
171
170
  // Don't check services prop as it will trigger an error (it's a proxy)
@@ -41,6 +41,10 @@ export type StartedServicesIndex = {
41
41
  [serviceId: string]: AnyService
42
42
  }
43
43
 
44
+ type TServiceUseOptions = {
45
+ optional?: boolean
46
+ }
47
+
44
48
  /*----------------------------------
45
49
  - CONFIG
46
50
  ----------------------------------*/
@@ -147,7 +151,8 @@ export default abstract class Service<
147
151
  TSubServices extends TServiceClass["services"],
148
152
  >(
149
153
  serviceId: TServiceId,
150
- subServices?: TSubServices
154
+ subServices?: TSubServices,
155
+ serviceUseOptions: TServiceUseOptions = {}
151
156
  ): (
152
157
  // We can't pass the services types as a generic to TServiceClass
153
158
  // So we overwrite the services property
@@ -164,8 +169,12 @@ export default abstract class Service<
164
169
 
165
170
  // Check of the service has been configurated
166
171
  const registered = ServicesContainer.registered[ serviceId ];
167
- if (registered === undefined)
168
- throw new Error(`Unable to use service "${serviceId}": This one hasn't been setup.`);
172
+ if (registered === undefined) {
173
+ if (serviceUseOptions.optional)
174
+ return undefined;
175
+ else
176
+ throw new Error(`Unable to use service "${serviceId}": This one hasn't been setup.`);
177
+ }
169
178
 
170
179
  // Bind subservices
171
180
  if (subServices !== undefined)
@@ -137,8 +137,6 @@ export default class Console extends Service<Config, Hooks, Application, Service
137
137
 
138
138
  protected async start() {
139
139
 
140
- return;
141
-
142
140
  const origLog = console.log
143
141
 
144
142
  this.logger = new Logger({
@@ -352,10 +350,10 @@ export default class Console extends Service<Config, Hooks, Application, Service
352
350
 
353
351
  public printHtml( logs: TJsonLog[], full: boolean = false ): string {
354
352
 
355
- let html = logs.map( logEntry => logToHTML( logEntry, this )).join('\n');
353
+ let html = logs.map( logEntry => logToHTML( logEntry, this )).join('<br />');
356
354
 
357
355
  if (full) {
358
- const consoleCss = `background: #000; padding: 20px; font-family: 'Fira Mono', 'monospace', 'Monaco'; font-size: 12px; line-height: 20px;`
356
+ const consoleCss = `background: #000; padding: 20px; font-family: 'Fira Mono', 'monospace', 'Monaco'; font-size: 12px; line-height: 20px;color: #aaa;`
359
357
  html = '<div style="' + consoleCss + '">' + html + '</div>';
360
358
  }
361
359
 
@@ -8,7 +8,7 @@ import express from 'express';
8
8
  import http from 'http';
9
9
  import https from 'https';
10
10
  import path from 'path';
11
- import cors from 'cors';
11
+ import cors, { CorsOptions } from 'cors';
12
12
  //var serveStatic = require('serve-static')
13
13
 
14
14
  // Middlewares (npm)
@@ -52,7 +52,8 @@ export type Config = {
52
52
  styles?: string[],
53
53
  images?: string[],
54
54
  scripts: string[],
55
- }
55
+ },
56
+ cors?: CorsOptions
56
57
  }
57
58
 
58
59
  export type Hooks = {
@@ -200,11 +201,8 @@ export default class HttpServer {
200
201
  - PAGES / API
201
202
  ----------------------------------*/
202
203
 
203
- // TODO: Migrer dans app
204
- //routes.use('/chrome', cors());
205
- // TODO: Trouver une solution pour n'autoriser les requetes que depuis l'application & dopamyn.io
206
- // https://www.google.com/search?q=http+cors+from+android%7Cwindows%7Cdesktop%7Cmodile+app
207
- //routes.use('/auth', cors());
204
+ if (this.config.cors !== undefined)
205
+ routes.use( cors( this.config.cors ));
208
206
 
209
207
  routes.use( csp.expressCspHeader({
210
208
  directives: {
@@ -24,7 +24,8 @@ import type DisksManager from '@server/services/disks';
24
24
  import { CoreError, NotFound } from '@common/errors';
25
25
  import BaseRouter, {
26
26
  TRoute, TErrorRoute, TRouteModule,
27
- TRouteOptions, defaultOptions
27
+ TRouteOptions, defaultOptions,
28
+ buildUrl, TDomainsList
28
29
  } from '@common/router';
29
30
  import { buildRegex, getRegisterPageArgs } from '@common/router/register';
30
31
  import { layoutsList, getLayout } from '@common/router/layouts';
@@ -86,6 +87,8 @@ export type Config<
86
87
 
87
88
  disk?: string, // Disk driver ID
88
89
 
90
+ domains: TDomainsList,
91
+
89
92
  http: HttpServiceConfig
90
93
 
91
94
  context: (
@@ -114,7 +117,9 @@ export default class ServerRouter<
114
117
  TSubservices extends Services = Services
115
118
  > extends Service<Config, Hooks, Application, TSubservices> implements BaseRouter {
116
119
 
117
- public disks = this.use('Core/Disks') as unknown as DisksManager;
120
+ public disks = this.use('Core/Disks', undefined, {
121
+ optional: true
122
+ }) as unknown as DisksManager | undefined;
118
123
 
119
124
  // Services
120
125
  public http: HTTP;
@@ -144,7 +149,6 @@ export default class ServerRouter<
144
149
 
145
150
  this.http = new HTTP(config.http, this);
146
151
  this.render = new DocumentRenderer(this);
147
-
148
152
  }
149
153
 
150
154
  /*----------------------------------
@@ -205,13 +209,8 @@ export default class ServerRouter<
205
209
  this.afterRegister();
206
210
  }
207
211
 
208
- // TODO: Generate TS type of the routes list
209
- public url<TRoutePath extends keyof Routes = keyof Routes>(
210
- path: TRoutePath,
211
- params: Routes[TRoutePath]["params"]
212
- ) {
213
- return this.http.publicUrl + path;
214
- }
212
+ public url = (path: string, params: {} = {}, absolute: boolean = true) =>
213
+ buildUrl(path, params, this.config.domains, absolute);
215
214
 
216
215
  /*----------------------------------
217
216
  - REGISTER
@@ -47,6 +47,10 @@ export default class ApiClientRequest extends RequestService implements ApiClien
47
47
  public delete = <TData extends unknown = unknown>(path: string, data?: TObjetDonnees, opts?: TApiFetchOptions) =>
48
48
  this.createFetcher<TData>('DELETE', path, data, opts);
49
49
 
50
+ public set( newData: TObjetDonnees ) {
51
+ throw new Error("api.set is not available on server side.");
52
+ }
53
+
50
54
  /*----------------------------------
51
55
  - API CALLS FROM SERVER
52
56
  ----------------------------------*/
@@ -65,10 +69,11 @@ export default class ApiClientRequest extends RequestService implements ApiClien
65
69
 
66
70
  for (const id in fetchers) {
67
71
 
68
- if (!fetchers[id])
72
+ const fetcher = fetchers[id]
73
+ if (!fetcher)
69
74
  continue;
70
75
 
71
- const { method, path, data, options } = fetchers[id];
76
+ const { method, path, data, options } = fetcher;
72
77
  //this.router.config.debug && console.log(`[api] Resolving from internal api`, method, path, data);
73
78
 
74
79
  // We don't fetch the already given data
@@ -31,7 +31,7 @@ const debug = true;
31
31
  export type TBasicSSrData = {
32
32
  request: { data: TObjetDonnees, id: string },
33
33
  page: { chunkId: string, data?: TObjetDonnees },
34
- //user: User | null
34
+ user: User | null
35
35
  }
36
36
 
37
37
  export type TRouterContext<TRouter extends ServerRouter = ServerRouter> = (
@@ -245,17 +245,17 @@ export default class ServerResponse<
245
245
  }
246
246
 
247
247
  // TODO: https://github.com/adonisjs/http-server/blob/develop/src/Response/index.ts#L430
248
- public async file( fichier: string ) {
248
+ public async file( filename: string ) {
249
249
 
250
250
  // Securité
251
- if (fichier.includes('..'))
251
+ if (filename.includes('..'))
252
252
  throw new Forbidden("Disallowed");
253
253
 
254
254
  // // Force absolute path
255
- // if (!fichier.startsWith( this.app.path.root ))
256
- // fichier = fichier[0] === '/'
257
- // ? this.app.path.root + '/bin' + fichier
258
- // : this.app.path.data + '/' + fichier;
255
+ // if (!filename.startsWith( this.app.path.root ))
256
+ // filename = filename[0] === '/'
257
+ // ? this.app.path.root + '/bin' + filename
258
+ // : this.app.path.data + '/' + filename;
259
259
  // Disk not provided = file response disabled
260
260
  if (this.router.disks === undefined)
261
261
  throw new Anomaly("Router: Unable to return file response in router, because no disk has been given in the router config.");
@@ -264,14 +264,15 @@ export default class ServerResponse<
264
264
  const disk = this.router.disks.get('default');
265
265
 
266
266
  // Verif existance
267
- const fileExists = await disk.exists('data', fichier);
267
+ const fileExists = await disk.exists('data', filename);
268
268
  if (!fileExists) {
269
- console.log("File " + fichier + " was not found.");
269
+ console.log("File " + filename + " was not found.");
270
270
  throw new NotFound();
271
271
  }
272
272
 
273
- // envoi fichier
274
- this.data = await disk.readFile('data', fichier, {});
273
+ // envoi filename
274
+ const file = await disk.readFile('data', filename, {});
275
+ this.data = file;
275
276
  return this.end();
276
277
  }
277
278
 
@@ -279,7 +280,7 @@ export default class ServerResponse<
279
280
 
280
281
  debug && console.log("[routeur][response] Redirect", url);
281
282
  this.statusCode = code;
282
- this.headers['Location'] = url;
283
+ this.headers['Location'] = this.router.url( url );
283
284
  return this.end();
284
285
  }
285
286