5htp-core 0.6.2-99 → 0.6.3-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ import type { TBasicSSrData } from '@server/services/router/response';
17
17
  import BaseRouter, {
18
18
  defaultOptions, TRoute, TErrorRoute,
19
19
  TClientOrServerContextForPage, TRouteModule,
20
- matchRoute, buildUrl, TDomainsList
20
+ matchRoute, buildUrl
21
21
  } from '@common/router'
22
22
  import { getLayout } from '@common/router/layouts';
23
23
  import { getRegisterPageArgs, buildRegex } from '@common/router/register';
@@ -134,6 +134,9 @@ const units: {[name: string]: TUnit} = {
134
134
 
135
135
  export function ago(date: Date | string, { min, max }: { min?: string, max?: string } = {}): string {
136
136
 
137
+ if (!date)
138
+ return '-';
139
+
137
140
  if (typeof date === 'string')
138
141
  date = new Date(date);
139
142
 
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.6.2-99",
4
+ "version": "0.6.3-1",
5
5
  "author": "Gaetan Le Gac (https://github.com/gaetanlegac)",
6
6
  "repository": "git://github.com/gaetanlegac/5htp-core.git",
7
7
  "license": "MIT",
@@ -12,7 +12,8 @@ import fs from 'fs-extra';
12
12
  import yaml from 'yaml';
13
13
 
14
14
  // Types
15
- import type { Config as TConsoleConfig } from './console';
15
+ import type { TDomainsList } from '@common/router';
16
+ import type { TLogProfile } from './console';
16
17
 
17
18
  /*----------------------------------
18
19
  - TYPES
@@ -29,12 +30,50 @@ declare global {
29
30
  }
30
31
  }
31
32
 
33
+ /*
34
+ name: server
35
+ profile: prod
36
+
37
+ router:
38
+ port: 80
39
+ domains:
40
+ current: 'https://recruiters.becrosspath.com'
41
+ recruiters: 'https://recruiters.becrosspath.com'
42
+ landing: 'https://becrosspath.com'
43
+ employers: 'https://employers.becrosspath.com'
44
+ candidates: 'https://candidates.becrosspath.com'
45
+ csm: 'https://csm.becrosspath.com'
46
+
47
+ database:
48
+ name: 'aws'
49
+ databases: [railway]
50
+ host: 'mysql-z7vp.railway.internal'
51
+ port: 3306
52
+ login: root
53
+ password: "GMnVsczoyYkyzwvVqDkMUOAIjVsumEev"
54
+
55
+ console:
56
+ enable: false
57
+ debug: false
58
+ bufferLimit: 10000
59
+ level: 'log'
60
+ */
61
+
32
62
  export type TEnvName = TEnvConfig["name"];
33
63
  export type TEnvConfig = {
34
64
  name: 'local' | 'server',
35
- profile: 'dev' | 'prod',
36
- version: string,
37
- console: TConsoleConfig
65
+ profile: 'dev' | 'testing' | 'prod',
66
+
67
+ router: {
68
+ port: number,
69
+ domains: TDomainsList
70
+ },
71
+ console: {
72
+ enable: boolean,
73
+ debug: boolean,
74
+ bufferLimit: number,
75
+ level: TLogProfile,
76
+ },
38
77
  }
39
78
 
40
79
  type AppIdentityConfig = {
@@ -27,7 +27,7 @@ import { SqlError } from '@server/services/database/debug';
27
27
  - SERVICE CONFIG
28
28
  ----------------------------------*/
29
29
 
30
- type TLogProfile = 'silly' | 'info' | 'warn' | 'error'
30
+ export type TLogProfile = 'silly' | 'info' | 'warn' | 'error'
31
31
 
32
32
  export type Config = {
33
33
  debug?: boolean,
@@ -10,10 +10,12 @@ import {
10
10
  RouterService
11
11
  } from '@server/services/router';
12
12
 
13
+ import type { Application } from '@server/app';
14
+
13
15
  import type { TRouterServiceArgs } from '@server/services/router/service';
14
16
 
15
17
  // Specific
16
- import type { default as UsersService, TUserRole } from '..';
18
+ import type { default as UsersService, TUserRole, TBasicUser } from '..';
17
19
  import UsersRequestService from './request';
18
20
 
19
21
  /*----------------------------------
@@ -31,7 +33,7 @@ const LogPrefix = '[router][auth]';
31
33
  - SERVICE
32
34
  ----------------------------------*/
33
35
  export default class AuthenticationRouterService<
34
- TUser extends {} = {},
36
+ TUser extends TBasicUser = TBasicUser,
35
37
  TRequest extends ServerRequest<Router> = ServerRequest<Router>,
36
38
  > extends RouterService {
37
39
 
@@ -39,7 +41,7 @@ export default class AuthenticationRouterService<
39
41
  - LIFECYCLE
40
42
  ----------------------------------*/
41
43
 
42
- public users: UsersService;
44
+ public users: UsersService<TUser, Application>;
43
45
 
44
46
  public constructor(...args: TRouterServiceArgs) {
45
47
  super(...args);
@@ -36,7 +36,6 @@ type ConnectionConfig = {
36
36
 
37
37
  export type DatabaseServiceConfig = {
38
38
  debug: boolean,
39
- connections: ConnectionConfig[],
40
39
  connectionsLimit: number
41
40
  }
42
41
 
@@ -66,6 +65,9 @@ export type TQueryResult = TSelectQueryResult;
66
65
  // TODO: specifiy return type of every mysql query type
67
66
  type TSelectQueryResult = any;
68
67
 
68
+ const DATABASE_URL = process.env.DATABASE_URL;
69
+ if (!DATABASE_URL) throw new Error("Missing env var: DATABASE_URL");
70
+
69
71
  /*----------------------------------
70
72
  - SERVICES
71
73
  ----------------------------------*/
@@ -99,14 +101,12 @@ export default class DatabaseManager {
99
101
 
100
102
  // Try to connect to one of the databases
101
103
  const connectionErrors: string[] = []
102
- for (const connectionConfig of this.config.connections){
103
- try {
104
- await this.connect(connectionConfig)
105
- break;
106
- } catch (error) {
107
- this.config.debug && console.warn(LogPrefix, `Failed to connect to ${connectionConfig.name}: ` + error);
108
- connectionErrors.push(connectionConfig.name + ': ' + error);
109
- }
104
+
105
+ try {
106
+ await this.connect()
107
+ } catch (error) {
108
+ this.config.debug && console.warn(LogPrefix, `Failed to connect to database: ` + error);
109
+ connectionErrors.push('database: ' + error);
110
110
  }
111
111
 
112
112
  // Coudnt connect to any database
@@ -127,17 +127,31 @@ export default class DatabaseManager {
127
127
  /*----------------------------------
128
128
  - INIT
129
129
  ----------------------------------*/
130
- public async connect(config: ConnectionConfig) {
130
+ public async connect() {
131
+
132
+
133
+ const u = new URL(DATABASE_URL as string);
134
+ const connectionConfig = {
135
+ name: u.hostname,
136
+ databases: [u.pathname.replace(/^\//, "")],
137
+ host: u.hostname,
138
+ port: u.port ? Number(u.port) : 3306,
139
+ login: decodeURIComponent(u.username),
140
+ password: decodeURIComponent(u.password),
141
+ }
142
+
143
+ console.log('connectionConfig', connectionConfig);
144
+
131
145
 
132
- this.config.debug && console.info(LogPrefix, `Trying to connect to ${config.name} ...`);
146
+ this.config.debug && console.info(LogPrefix, `Trying to connect to database...`, connectionConfig);
133
147
  this.connection = mysql.createPool({
134
148
 
135
149
  // Identification
136
- host: config.host,
137
- port: config.port,
138
- user: config.login,
139
- password: config.password,
140
- database: config.databases[0],
150
+ host: connectionConfig.host,
151
+ port: connectionConfig.port,
152
+ user: connectionConfig.login,
153
+ password: connectionConfig.password,
154
+ database: connectionConfig.databases[0],
141
155
 
142
156
  // Pool
143
157
  waitForConnections: true,
@@ -164,10 +178,10 @@ export default class DatabaseManager {
164
178
  }
165
179
  })
166
180
 
167
- this.tables = await this.metas.load( config.databases );
168
- this.connectionConfig = config; // Memorise configuration if connection succeed
181
+ this.tables = await this.metas.load(connectionConfig.databases);
182
+ this.connectionConfig = connectionConfig; // Memorise configuration if connection succeed
169
183
  this.status = 'connected';
170
- this.config.debug && console.info(LogPrefix, `Successfully connected to ${config.name}.`);
184
+ this.config.debug && console.info(LogPrefix, `Successfully connected to database.`);
171
185
  }
172
186
 
173
187
  private typeCast( field: mysql.Field, next: Function ) {
@@ -174,7 +174,7 @@ export default abstract class Email<TConfig extends Config>
174
174
  console.info(LogPrefix, `Sending ${emailsToSend.length} emails:`, emailsToSend[0].subject);
175
175
 
176
176
  // Pas d'envoi d'email quand local
177
- if (this.app.env.name === 'local' && this.config.simulateWhenLocal === true) {
177
+ if (this.app.env.profile !== 'prod' && this.config.simulateWhenLocal === true) {
178
178
  console.log(LogPrefix, `Simulate email sending:\n`, emailsToSend[0].html);
179
179
  return;
180
180
  } else if (emailsToSend.length === 0) {
@@ -48,11 +48,11 @@ export type TRouterContext<TRouter extends TServerRouter> = (
48
48
  response: ServerResponse<TRouter>,
49
49
  route: TRoute,
50
50
  page?: Page,
51
- user: TBasicUser,
52
51
 
53
52
  Router: TRouter,
54
53
  }
55
54
  & TRouterContextServices<TRouter>
55
+ //& TRouterRequestContext<TRouter>
56
56
  )
57
57
 
58
58
  export type TRouterContextServices<
@@ -68,6 +68,10 @@ export type TRouterContextServices<
68
68
  }
69
69
  )
70
70
 
71
+ export type TRouterRequestContext<
72
+ TRouter extends TServerRouter
73
+ > = ReturnType<TRouter["config"]["context"]>
74
+
71
75
 
72
76
  /*----------------------------------
73
77
  - CLASSE
@@ -63,11 +63,29 @@ declare type PrimitiveValue = string | number | boolean;
63
63
  - COPY FROM CLI/APP/INDEX.TS
64
64
  ----------------------------------*/
65
65
 
66
- type TEnvConfig = {
66
+ /*type TEnvConfig = {
67
67
  name: 'local' | 'server',
68
- profile: 'dev' | 'prod',
69
- version: string,
70
- }
68
+ profile: 'dev' | 'testing' | 'prod',
69
+
70
+ router: {
71
+ port: number,
72
+ domains: TDomainsList
73
+ },
74
+ database: {
75
+ name: string,
76
+ databases: string[],
77
+ host: string,
78
+ port: number,
79
+ login: string,
80
+ password: string,
81
+ },
82
+ console: {
83
+ enable: boolean,
84
+ debug: boolean,
85
+ bufferLimit: number,
86
+ level: TLogProfile,
87
+ },
88
+ }*/
71
89
 
72
90
  type TServiceSetup = {
73
91
  id: string,
package/types/icons.d.ts CHANGED
@@ -1 +1 @@
1
- export type TIcones = "solid/spinner-third"|"rocket"|"user-circle"|"brands/linkedin"|"play"|"stop"|"trash"|"times"|"at"|"star"|"plus"|"minus"|"magnet"|"paper-plane"|"search"|"check"|"plus-circle"|"regular/shield-check"|"angle-down"|"clock"|"cog"|"ellipsis-h"|"long-arrow-right"|"lightbulb"|"long-arrow-left"|"phone"|"arrow-right"|"plane-departure"|"comments-alt"|"user-shield"|"shield-alt"|"chart-line"|"money-bill-wave"|"link"|"file-alt"|"solid/crown"|"eye"|"pen"|"file"|"envelope"|"angle-up"|"user-plus"|"sack-dollar"|"info-circle"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"download"|"brands/google"|"brands/whatsapp"|"crown"|"check-circle"|"exclamation-circle"|"times-circle"|"arrow-left"|"key"|"building"|"briefcase"|"map-marker-alt"|"graduation-cap"|"solid/check-circle"|"solid/exclamation-triangle"|"solid/times-circle"|"hourglass"|"angle-left"|"angle-right"|"broom"|"question-circle"|"coin"|"coins"|"plug"|"arrow-to-bottom"|"external-link"|"magic"|"minus-circle"|"user"|"meh-rolling-eyes"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"code"|"unlink"|"font"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"
1
+ export type TIcones = "solid/spinner-third"|"rocket"|"user-circle"|"search"|"long-arrow-right"|"lightbulb"|"long-arrow-left"|"magnet"|"at"|"phone"|"brands/linkedin"|"arrow-right"|"times"|"star"|"plus"|"minus"|"trash"|"paper-plane"|"play"|"stop"|"plus-circle"|"clock"|"cog"|"ellipsis-h"|"regular/shield-check"|"angle-down"|"check"|"angle-up"|"plane-departure"|"comments-alt"|"user-shield"|"shield-alt"|"chart-line"|"money-bill-wave"|"link"|"file-alt"|"solid/crown"|"eye"|"pen"|"file"|"user-plus"|"sack-dollar"|"info-circle"|"mouse-pointer"|"thumbs-up"|"dollar-sign"|"envelope"|"download"|"brands/google"|"brands/whatsapp"|"crown"|"check-circle"|"exclamation-circle"|"times-circle"|"arrow-left"|"key"|"broom"|"angle-left"|"angle-right"|"solid/check-circle"|"solid/exclamation-triangle"|"solid/times-circle"|"hourglass"|"building"|"briefcase"|"map-marker-alt"|"graduation-cap"|"coins"|"plug"|"coin"|"question-circle"|"arrow-to-bottom"|"external-link"|"minus-circle"|"magic"|"user"|"meh-rolling-eyes"|"unlink"|"bold"|"italic"|"underline"|"strikethrough"|"subscript"|"superscript"|"code"|"font"|"empty-set"|"horizontal-rule"|"page-break"|"image"|"table"|"poll"|"columns"|"sticky-note"|"caret-right"|"list-ul"|"check-square"|"h1"|"h2"|"h3"|"h4"|"list-ol"|"paragraph"|"quote-left"|"align-left"|"align-center"|"align-right"|"align-justify"|"indent"|"outdent"