proteum 2.2.7 → 2.2.9
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/AGENTS.md +2 -1
- package/README.md +1 -1
- package/agents/project/AGENTS.md +4 -5
- package/agents/project/CODING_STYLE.md +5 -1
- package/agents/project/client/AGENTS.md +2 -0
- package/agents/project/diagnostics.md +2 -3
- package/agents/project/root/AGENTS.md +4 -5
- package/agents/project/tests/AGENTS.md +0 -1
- package/cli/commands/check.ts +21 -3
- package/cli/commands/configure.ts +1 -0
- package/cli/compiler/artifacts/controllers.ts +30 -4
- package/cli/compiler/artifacts/services.ts +67 -29
- package/cli/presentation/commands.ts +2 -2
- package/cli/scaffold/templates.ts +2 -3
- package/cli/utils/agents.ts +114 -4
- package/client/dev/profiler/ApexChart.tsx +4 -3
- package/common/dev/inspection.ts +16 -3
- package/common/dev/serverHotReload.ts +26 -25
- package/eslint.js +220 -0
- package/package.json +1 -1
- package/server/app/commands.ts +11 -16
- package/server/app/commandsManager.ts +5 -1
- package/server/app/controller/index.ts +68 -16
- package/server/app/devCommands.ts +3 -3
- package/server/app/devDiagnostics.ts +2 -2
- package/server/app/index.ts +19 -8
- package/server/app/service/container.ts +22 -19
- package/server/app/service/index.ts +33 -13
- package/server/app.tsconfig.json +0 -1
- package/server/services/auth/index.ts +12 -6
- package/server/services/auth/router/index.ts +12 -14
- package/server/services/auth/router/request.ts +34 -13
- package/server/services/disks/driver.ts +1 -1
- package/server/services/disks/index.ts +11 -8
- package/server/services/email/index.ts +1 -1
- package/server/services/prisma/Facet.ts +6 -5
- package/server/services/router/index.ts +8 -7
- package/server/services/router/request/validation/zod.ts +2 -0
- package/server/services/router/response/index.ts +9 -9
- package/server/services/router/service.ts +12 -8
- package/tests/agents-utils.test.cjs +55 -0
- package/tests/eslint-rules.test.cjs +110 -0
- package/types/global/vendors.d.ts +70 -0
|
@@ -3,29 +3,32 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Specific
|
|
6
|
-
import type {
|
|
6
|
+
import type { AnyServiceClass, StartedServicesIndex } from '.';
|
|
7
7
|
|
|
8
8
|
/*----------------------------------
|
|
9
9
|
- TYPES
|
|
10
10
|
----------------------------------*/
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
type ConstructorConfig<TServiceClass extends AnyServiceClass> = ConstructorParameters<TServiceClass> extends [
|
|
13
|
+
_parent: object | 'self',
|
|
14
|
+
config: infer TConfig,
|
|
15
|
+
_app: object | 'self',
|
|
16
|
+
..._rest: []
|
|
17
|
+
]
|
|
18
|
+
? NonNullable<TConfig>
|
|
19
|
+
: ConstructorParameters<TServiceClass> extends [config: infer TConfig, _app: object | 'self', ..._rest: []]
|
|
20
|
+
? NonNullable<TConfig>
|
|
21
|
+
: {};
|
|
13
22
|
|
|
14
|
-
type
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
? Exclude<keyof TValue, keyof TShape> extends never
|
|
24
|
-
? { [K in keyof TValue]: K extends keyof TShape ? ExactConfig<TValue[K], TShape[K]> : never }
|
|
25
|
-
: never
|
|
26
|
-
: TValue
|
|
27
|
-
: TValue
|
|
28
|
-
: never;
|
|
23
|
+
export type ServiceConfig<TServiceClass extends AnyServiceClass> = ConstructorConfig<TServiceClass>;
|
|
24
|
+
|
|
25
|
+
type ExactConfig<TConfig, TExpected> = TExpected extends object
|
|
26
|
+
? TConfig extends object
|
|
27
|
+
? { [TKey in Exclude<keyof TConfig, keyof TExpected>]: never } & {
|
|
28
|
+
[TKey in keyof TConfig & keyof TExpected]?: ExactConfig<TConfig[TKey], NonNullable<TExpected[TKey]>>;
|
|
29
|
+
}
|
|
30
|
+
: {}
|
|
31
|
+
: {};
|
|
29
32
|
|
|
30
33
|
/*----------------------------------
|
|
31
34
|
- CLASS
|
|
@@ -41,7 +44,7 @@ export class ServicesContainer<TServicesIndex extends StartedServicesIndex = Sta
|
|
|
41
44
|
public callableInstance = <TInstance extends object, TCallableName extends keyof TInstance>(
|
|
42
45
|
instance: TInstance,
|
|
43
46
|
funcName: TCallableName,
|
|
44
|
-
): TInstance[TCallableName] & TInstance => {
|
|
47
|
+
): TInstance[TCallableName] & { serviceInstance: TInstance } => {
|
|
45
48
|
const instanceRecord = instance as Record<string, unknown>;
|
|
46
49
|
const callableFunc = instance[funcName];
|
|
47
50
|
if (typeof callableFunc !== 'function') throw new Error(`instance[funcName] isn't callable.`);
|
|
@@ -66,7 +69,7 @@ export class ServicesContainer<TServicesIndex extends StartedServicesIndex = Sta
|
|
|
66
69
|
// Allow us to recognize a callable as a service
|
|
67
70
|
callable.serviceInstance = instance;
|
|
68
71
|
|
|
69
|
-
return callable as TInstance[TCallableName] & TInstance;
|
|
72
|
+
return callable as TInstance[TCallableName] & { serviceInstance: TInstance };
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
|
|
@@ -5,16 +5,27 @@
|
|
|
5
5
|
// Specific
|
|
6
6
|
import type { Application } from '../index';
|
|
7
7
|
import type { Command } from '../commands';
|
|
8
|
-
import type {
|
|
8
|
+
import type {
|
|
9
|
+
Request as ServerRequest,
|
|
10
|
+
Response as ServerResponse,
|
|
11
|
+
TRouterContextServices,
|
|
12
|
+
TAnyRouter,
|
|
13
|
+
} from '../../services/router';
|
|
9
14
|
|
|
10
15
|
export { schema } from '../../services/router/request/validation/zod';
|
|
11
|
-
export type {
|
|
16
|
+
export type {
|
|
17
|
+
z,
|
|
18
|
+
TInferValidationSchema,
|
|
19
|
+
TTypedValidationSchema,
|
|
20
|
+
TValidationSchema,
|
|
21
|
+
TValidationShape,
|
|
22
|
+
} from '../../services/router/request/validation/zod';
|
|
12
23
|
|
|
13
24
|
/*----------------------------------
|
|
14
25
|
- TYPES: OPTIONS
|
|
15
26
|
----------------------------------*/
|
|
16
27
|
|
|
17
|
-
export type AnyService = Service<{},
|
|
28
|
+
export type AnyService = Service<{}, any, any, any>;
|
|
18
29
|
export type AnyServiceClass = ClassType<AnyService>;
|
|
19
30
|
|
|
20
31
|
/*----------------------------------
|
|
@@ -31,7 +42,7 @@ export type THooksIndex<THooks extends THooksList> = { [name in keyof THooks]?:
|
|
|
31
42
|
|
|
32
43
|
export type StartedServicesIndex = { [serviceId: string]: AnyService };
|
|
33
44
|
|
|
34
|
-
type TServiceRouter<TApplication extends
|
|
45
|
+
type TServiceRouter<TApplication extends object> = TApplication extends { Router: infer TRouter }
|
|
35
46
|
? TRouter extends TAnyRouter
|
|
36
47
|
? TRouter
|
|
37
48
|
: TAnyRouter
|
|
@@ -41,11 +52,18 @@ type TServiceRouter<TApplication extends Application> = TApplication extends { R
|
|
|
41
52
|
* @deprecated Services should not depend on request context.
|
|
42
53
|
* Resolve auth/input/request data in controllers and pass explicit typed values into services instead.
|
|
43
54
|
*/
|
|
44
|
-
export type TServiceRequestContext<TApplication extends
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
55
|
+
export type TServiceRequestContext<TApplication extends object = object> = {
|
|
56
|
+
app: TApplication;
|
|
57
|
+
context: object;
|
|
58
|
+
request: ServerRequest<TServiceRouter<TApplication>>;
|
|
59
|
+
api: ServerRequest<TServiceRouter<TApplication>>['api'];
|
|
60
|
+
response: ServerResponse<TServiceRouter<TApplication>>;
|
|
61
|
+
route: object;
|
|
62
|
+
page?: object;
|
|
63
|
+
Router: TServiceRouter<TApplication>;
|
|
64
|
+
} & TRouterContextServices<TServiceRouter<TApplication>>;
|
|
65
|
+
|
|
66
|
+
export type TServiceModelsClient<TApplication extends object = object> = TApplication extends {
|
|
49
67
|
Models: { client: infer TModels };
|
|
50
68
|
}
|
|
51
69
|
? TModels
|
|
@@ -53,10 +71,12 @@ export type TServiceModelsClient<TApplication extends Application = Application>
|
|
|
53
71
|
models: { client: infer TModels };
|
|
54
72
|
}
|
|
55
73
|
? TModels
|
|
56
|
-
:
|
|
74
|
+
: object;
|
|
57
75
|
|
|
58
|
-
export type TSetupConfig<TConfig> = TConfig extends (...args:
|
|
76
|
+
export type TSetupConfig<TConfig> = TConfig extends (...args: infer TFunctionArgs) => infer TFunctionResult
|
|
59
77
|
? TConfig
|
|
78
|
+
: TConfig extends { getServiceInstance: (...args: infer TServiceArgs) => infer TServiceInstance }
|
|
79
|
+
? TConfig
|
|
60
80
|
: TConfig extends Array<infer TItem>
|
|
61
81
|
? Array<TSetupConfig<TItem>>
|
|
62
82
|
: TConfig extends object
|
|
@@ -86,8 +106,8 @@ const resolveSelfReference = <TSelf extends object, TValue extends object>(
|
|
|
86
106
|
export default abstract class Service<
|
|
87
107
|
TConfig extends {},
|
|
88
108
|
THooks extends THooksList,
|
|
89
|
-
TApplication extends
|
|
90
|
-
TParent extends object =
|
|
109
|
+
TApplication extends object = object,
|
|
110
|
+
TParent extends object = object,
|
|
91
111
|
> {
|
|
92
112
|
public started?: Promise<void>;
|
|
93
113
|
public starting?: Promise<void>;
|
package/server/app.tsconfig.json
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
"paths": {
|
|
7
7
|
|
|
8
8
|
"@/server/models": ["./.proteum/server/models.ts"],
|
|
9
|
-
"@/client/context": ["./.proteum/client/context.ts"],
|
|
10
9
|
"@generated/client/*": ["./.proteum/client/*"],
|
|
11
10
|
"@generated/common/*": ["./.proteum/common/*"],
|
|
12
11
|
"@generated/server/*": ["./.proteum/server/*"],
|
|
@@ -10,7 +10,6 @@ import type http from 'http';
|
|
|
10
10
|
// Core
|
|
11
11
|
import type { Application } from '@server/app/index';
|
|
12
12
|
import Service from '@server/app/service';
|
|
13
|
-
import { type TAnyRouter, Request as ServerRequest } from '@server/services/router';
|
|
14
13
|
import * as AuthErrors from '@common/errors';
|
|
15
14
|
import type { TTraceCaptureMode, TTraceEventType } from '@common/dev/requestTrace';
|
|
16
15
|
|
|
@@ -103,7 +102,13 @@ export type TAuthConfiguredRules = {
|
|
|
103
102
|
|
|
104
103
|
export type TAuthTrackingContext = ProteumAuthTrackingContext | null;
|
|
105
104
|
|
|
106
|
-
export type
|
|
105
|
+
export type TAuthRequest = {
|
|
106
|
+
id: string;
|
|
107
|
+
res: Pick<express.Response, 'clearCookie' | 'cookie'>;
|
|
108
|
+
user: TBasicUser | null;
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
export type TAuthRulesFactory<TUser extends TBasicUser, TRequest extends TAuthRequest> = (
|
|
107
112
|
user: TUser,
|
|
108
113
|
tracking: TAuthTrackingContext,
|
|
109
114
|
request: TRequest,
|
|
@@ -121,7 +126,7 @@ export const UserRoles = ['USER', 'ADMIN', 'TEST', 'DEV'] as const;
|
|
|
121
126
|
|
|
122
127
|
export type TConfig<
|
|
123
128
|
TUser extends TBasicUser = TBasicUser,
|
|
124
|
-
TRequest extends
|
|
129
|
+
TRequest extends TAuthRequest = TAuthRequest,
|
|
125
130
|
> = {
|
|
126
131
|
debug: boolean;
|
|
127
132
|
logoutUrl: string;
|
|
@@ -155,7 +160,7 @@ export default abstract class AuthService<
|
|
|
155
160
|
TUser extends TBasicUser,
|
|
156
161
|
TApplication extends Application,
|
|
157
162
|
TJwtSession extends TBasicJwtSession = TBasicJwtSession,
|
|
158
|
-
TRequest extends
|
|
163
|
+
TRequest extends TAuthRequest = TAuthRequest,
|
|
159
164
|
> extends Service<TConfig<TUser, TRequest>, THooks, TApplication, TApplication> {
|
|
160
165
|
public login?(request: TRequest, email: string): Promise<unknown>;
|
|
161
166
|
public abstract decodeSession(jwt: TJwtSession, req: THttpRequest): Promise<TUser | null>;
|
|
@@ -200,7 +205,8 @@ export default abstract class AuthService<
|
|
|
200
205
|
if ('apiKey' in session) {
|
|
201
206
|
return {
|
|
202
207
|
payloadKind: 'api-key',
|
|
203
|
-
payloadAccountType:
|
|
208
|
+
payloadAccountType:
|
|
209
|
+
'accountType' in session && typeof session.accountType === 'string' ? session.accountType : null,
|
|
204
210
|
};
|
|
205
211
|
}
|
|
206
212
|
|
|
@@ -602,7 +608,7 @@ export default abstract class AuthService<
|
|
|
602
608
|
): TUser | null {
|
|
603
609
|
const user = this.getDecodedUser(request);
|
|
604
610
|
const conditionRuleNames =
|
|
605
|
-
conditions
|
|
611
|
+
conditions
|
|
606
612
|
? (Object.keys(conditions) as Array<Extract<keyof TAuthConfiguredRules, string>>)
|
|
607
613
|
: [];
|
|
608
614
|
|
|
@@ -11,32 +11,30 @@ import {
|
|
|
11
11
|
TAnyRoute,
|
|
12
12
|
RouterService,
|
|
13
13
|
TAnyRouter,
|
|
14
|
+
TServerRouter,
|
|
14
15
|
} from '@server/services/router';
|
|
15
16
|
|
|
16
17
|
import type { Application } from '@server/app/index';
|
|
18
|
+
import AppContainer from '@server/app/container';
|
|
17
19
|
|
|
18
20
|
import type { TRouterServiceArgs } from '@server/services/router/service';
|
|
19
21
|
|
|
20
22
|
// Specific
|
|
21
23
|
import type { default as UsersService, TAuthCheckConditions, TBasicUser } from '..';
|
|
22
|
-
import
|
|
23
|
-
|
|
24
|
-
/*----------------------------------
|
|
25
|
-
- TYPES
|
|
26
|
-
----------------------------------*/
|
|
24
|
+
import { createUsersRequestService, type TUsersRequestContext } from './request';
|
|
27
25
|
|
|
28
26
|
/*----------------------------------
|
|
29
27
|
- SERVICE
|
|
30
28
|
----------------------------------*/
|
|
31
29
|
export default class AuthenticationRouterService<
|
|
32
|
-
TApplication extends Application
|
|
33
|
-
TUser extends TBasicUser
|
|
34
|
-
TRouter extends TAnyRouter =
|
|
30
|
+
TApplication extends Application,
|
|
31
|
+
TUser extends TBasicUser,
|
|
32
|
+
TRouter extends TAnyRouter = TServerRouter,
|
|
35
33
|
TRequest extends ServerRequest<TRouter> = ServerRequest<TRouter>,
|
|
36
34
|
> extends RouterService<
|
|
37
35
|
{ users: UsersService<TUser, TApplication> },
|
|
38
36
|
TRouter,
|
|
39
|
-
|
|
37
|
+
TUsersRequestContext<TUser>
|
|
40
38
|
> {
|
|
41
39
|
/*----------------------------------
|
|
42
40
|
- LIFECYCLE
|
|
@@ -45,7 +43,7 @@ export default class AuthenticationRouterService<
|
|
|
45
43
|
public users: UsersService<TUser, TApplication>;
|
|
46
44
|
|
|
47
45
|
public constructor(
|
|
48
|
-
getConfig: TRouterServiceArgs<{ users: UsersService<TUser, TApplication> }
|
|
46
|
+
getConfig: TRouterServiceArgs<{ users: UsersService<TUser, TApplication> }>[0],
|
|
49
47
|
app: TApplication,
|
|
50
48
|
) {
|
|
51
49
|
super(getConfig, app);
|
|
@@ -59,11 +57,11 @@ export default class AuthenticationRouterService<
|
|
|
59
57
|
details: Record<string, any>,
|
|
60
58
|
minimumCapture: 'summary' | 'resolve' | 'deep' = 'resolve',
|
|
61
59
|
) {
|
|
62
|
-
|
|
60
|
+
AppContainer.Trace.record(
|
|
63
61
|
request.id,
|
|
64
62
|
'auth.route',
|
|
65
63
|
{
|
|
66
|
-
routePath: route.path || '',
|
|
64
|
+
routePath: 'path' in route ? route.path || '' : '',
|
|
67
65
|
routeId: route.options.id || '',
|
|
68
66
|
authInput: route.options.auth ?? null,
|
|
69
67
|
tracking: route.options.authTracking ?? null,
|
|
@@ -219,7 +217,7 @@ export default class AuthenticationRouterService<
|
|
|
219
217
|
- ROUTER SERVICE LIFECYCLE
|
|
220
218
|
----------------------------------*/
|
|
221
219
|
|
|
222
|
-
public requestService(request: TRequest):
|
|
223
|
-
return
|
|
220
|
+
public requestService(request: TRequest): TUsersRequestContext<TUser> {
|
|
221
|
+
return createUsersRequestService(request, this.users);
|
|
224
222
|
}
|
|
225
223
|
}
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
- DEPENDANCES
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import type { Request as ServerRequest, TAnyRouter } from '@server/services/router';
|
|
7
|
-
import RequestService from '@server/services/router/request/service';
|
|
5
|
+
import type { Application } from '@server/app/index';
|
|
8
6
|
|
|
9
7
|
// Specific
|
|
10
|
-
import type
|
|
11
|
-
import type { TAuthCheckConditions, TAuthTrackingContext, TUserRole } from '..';
|
|
8
|
+
import type UsersService from '..';
|
|
9
|
+
import type { TAuthCheckConditions, TAuthRequest, TAuthTrackingContext, TUserRole } from '..';
|
|
12
10
|
|
|
13
11
|
// Types
|
|
14
12
|
import type { TBasicUser } from '@server/services/auth';
|
|
@@ -17,21 +15,36 @@ import type { TBasicUser } from '@server/services/auth';
|
|
|
17
15
|
- TYPES
|
|
18
16
|
----------------------------------*/
|
|
19
17
|
|
|
18
|
+
type TUsersRouterService<TUser extends TBasicUser> = {
|
|
19
|
+
users: UsersService<TUser, Application>;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export interface TUsersRequestContext<TUser extends TBasicUser> {
|
|
23
|
+
login(email: string): Promise<unknown>;
|
|
24
|
+
logout(): void;
|
|
25
|
+
|
|
26
|
+
check(): TUser;
|
|
27
|
+
check(conditions: null, tracking?: TAuthTrackingContext): TUser;
|
|
28
|
+
check(conditions: TAuthCheckConditions, tracking?: TAuthTrackingContext): TUser;
|
|
29
|
+
check(conditions: false, tracking?: TAuthTrackingContext): null;
|
|
30
|
+
check(role: TUserRole, feature: null): TUser;
|
|
31
|
+
check(role: false): null;
|
|
32
|
+
check(role: TUserRole | true, feature: FeatureKeys, action?: string): TUser;
|
|
33
|
+
check(role: false, feature: FeatureKeys, action?: string): null;
|
|
34
|
+
}
|
|
35
|
+
|
|
20
36
|
/*----------------------------------
|
|
21
37
|
- MODULE
|
|
22
38
|
----------------------------------*/
|
|
23
39
|
export default class UsersRequestService<
|
|
24
|
-
TRouter extends TAnyRouter,
|
|
25
40
|
TUser extends TBasicUser,
|
|
26
|
-
TRequest extends
|
|
27
|
-
>
|
|
41
|
+
TRequest extends TAuthRequest,
|
|
42
|
+
> implements TUsersRequestContext<TUser> {
|
|
28
43
|
public constructor(
|
|
29
|
-
request: TRequest,
|
|
30
|
-
public auth:
|
|
44
|
+
public request: TRequest,
|
|
45
|
+
public auth: TUsersRouterService<TUser>,
|
|
31
46
|
public users = auth.users,
|
|
32
|
-
) {
|
|
33
|
-
super(request);
|
|
34
|
-
}
|
|
47
|
+
) {}
|
|
35
48
|
|
|
36
49
|
public login(email: string) {
|
|
37
50
|
if (!this.users.login) throw new Error('The current auth service does not implement login().');
|
|
@@ -93,3 +106,11 @@ export default class UsersRequestService<
|
|
|
93
106
|
return this.users.check(this.request, roleOrConditions, featureOrTracking, action);
|
|
94
107
|
}
|
|
95
108
|
}
|
|
109
|
+
|
|
110
|
+
export const createUsersRequestService = <
|
|
111
|
+
TUser extends TBasicUser,
|
|
112
|
+
TRequest extends TAuthRequest,
|
|
113
|
+
>(
|
|
114
|
+
request: TRequest,
|
|
115
|
+
users: UsersService<TUser, Application>,
|
|
116
|
+
): TUsersRequestContext<TUser> => new UsersRequestService<TUser, TRequest>(request, { users });
|
|
@@ -27,7 +27,7 @@ export type TDrivercnfig = {
|
|
|
27
27
|
|
|
28
28
|
export type SourceFile = { name: string; path: string; modified: number; parentFolder: string; source: string };
|
|
29
29
|
|
|
30
|
-
export type TOutputFileOptions = { encoding:
|
|
30
|
+
export type TOutputFileOptions = { encoding: BufferEncoding };
|
|
31
31
|
|
|
32
32
|
export type TReadFileOptions = { encoding?: 'string' | 'buffer'; withMetas?: boolean };
|
|
33
33
|
|
|
@@ -32,8 +32,6 @@ export default class DisksManager<
|
|
|
32
32
|
TConfig extends Config & { default: keyof MountpointList & string; drivers: MountpointList },
|
|
33
33
|
TApplication extends Application,
|
|
34
34
|
> extends Service<TConfig, Hooks, TApplication, TApplication> {
|
|
35
|
-
public default!: MountpointList[keyof MountpointList & string];
|
|
36
|
-
|
|
37
35
|
/*----------------------------------
|
|
38
36
|
- LIFECYCLE
|
|
39
37
|
----------------------------------*/
|
|
@@ -50,10 +48,14 @@ export default class DisksManager<
|
|
|
50
48
|
drivers[driverId].parent = this;
|
|
51
49
|
}*/
|
|
52
50
|
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
this.default;
|
|
52
|
+
}
|
|
55
53
|
|
|
56
|
-
|
|
54
|
+
public get default(): Driver {
|
|
55
|
+
const drivers: Services = this.config.drivers;
|
|
56
|
+
const defaultDisk = drivers[this.config.default];
|
|
57
|
+
if (defaultDisk === undefined) throw new Error(`Default disk "${String(this.config.default)}" not mounted.`);
|
|
58
|
+
return defaultDisk;
|
|
57
59
|
}
|
|
58
60
|
|
|
59
61
|
public async shutdown() {}
|
|
@@ -62,13 +64,14 @@ export default class DisksManager<
|
|
|
62
64
|
- LIFECYCLE
|
|
63
65
|
----------------------------------*/
|
|
64
66
|
|
|
65
|
-
public get(diskName?: 'default' | keyof MountpointList) {
|
|
67
|
+
public get(diskName?: 'default' | keyof MountpointList): Driver {
|
|
68
|
+
const drivers: Services = this.config.drivers;
|
|
66
69
|
const disk =
|
|
67
70
|
diskName === 'default' || diskName === undefined
|
|
68
71
|
? this.default
|
|
69
|
-
:
|
|
72
|
+
: drivers[String(diskName)];
|
|
70
73
|
|
|
71
|
-
if (disk === undefined) throw new Error(`Disk "${diskName
|
|
74
|
+
if (disk === undefined) throw new Error(`Disk "${String(diskName)}" not found.`);
|
|
72
75
|
|
|
73
76
|
return disk;
|
|
74
77
|
}
|
|
@@ -57,7 +57,7 @@ type TOptions = { transporter?: string };
|
|
|
57
57
|
/*----------------------------------
|
|
58
58
|
- FONCTIONS
|
|
59
59
|
----------------------------------*/
|
|
60
|
-
export default abstract class Email<TConfig extends Config, TApplication extends Application
|
|
60
|
+
export default abstract class Email<TConfig extends Config, TApplication extends Application> extends Service<
|
|
61
61
|
TConfig,
|
|
62
62
|
Hooks,
|
|
63
63
|
TApplication,
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import type { PrismaClient } from '@models/types';
|
|
2
|
-
|
|
3
1
|
export type TDelegate<R = unknown> = {
|
|
4
2
|
findMany(args?: Record<string, unknown>): Promise<R[]>;
|
|
5
3
|
findFirst(args?: Record<string, unknown>): Promise<R | null>;
|
|
6
4
|
};
|
|
5
|
+
type TPrismaRawClient = {
|
|
6
|
+
$queryRawUnsafe(query: string): Promise<Record<string, unknown>[]>;
|
|
7
|
+
};
|
|
7
8
|
|
|
8
9
|
export type TWithStats = { $table: string; $key: string } & Record<string, string>;
|
|
9
10
|
|
|
@@ -18,7 +19,7 @@ export default class Facet<
|
|
|
18
19
|
RT = R,
|
|
19
20
|
> {
|
|
20
21
|
constructor(
|
|
21
|
-
private readonly prisma:
|
|
22
|
+
private readonly prisma: TPrismaRawClient,
|
|
22
23
|
private readonly delegate: D,
|
|
23
24
|
private readonly subset: S,
|
|
24
25
|
private readonly transform?: Transform<R, RT>,
|
|
@@ -57,13 +58,13 @@ export default class Facet<
|
|
|
57
58
|
), 0)) as ${key}`,
|
|
58
59
|
);
|
|
59
60
|
|
|
60
|
-
const statRows =
|
|
61
|
+
const statRows = await this.prisma.$queryRawUnsafe(`
|
|
61
62
|
SELECT ${$key}, ${select.join(', ')}
|
|
62
63
|
FROM ${$table}
|
|
63
64
|
WHERE ${$key} IN (
|
|
64
65
|
${(results as Array<Record<string, unknown>>).map((row) => "'" + row[$key] + "'").join(',')}
|
|
65
66
|
)
|
|
66
|
-
`)
|
|
67
|
+
`);
|
|
67
68
|
|
|
68
69
|
for (const stat of statRows) {
|
|
69
70
|
for (const key in stat) {
|
|
@@ -19,7 +19,8 @@ import zod, { ZodError } from 'zod';
|
|
|
19
19
|
export { default as schema } from 'zod';
|
|
20
20
|
|
|
21
21
|
// Core
|
|
22
|
-
import
|
|
22
|
+
import type { Application } from '@server/app/index';
|
|
23
|
+
import Service, { TServiceArgs } from '@server/app/service';
|
|
23
24
|
import context from '@server/context';
|
|
24
25
|
import type DisksManager from '@server/services/disks';
|
|
25
26
|
import { CoreError, InputError, NotFound, toJson as errorToJson } from '@common/errors';
|
|
@@ -104,16 +105,16 @@ const staticHtmlCacheControl = 'public, max-age=0, must-revalidate';
|
|
|
104
105
|
----------------------------------*/
|
|
105
106
|
|
|
106
107
|
export type TAnyRouter = ServerRouter<
|
|
107
|
-
|
|
108
|
+
Application,
|
|
108
109
|
TRouterServicesList,
|
|
109
|
-
Config<TRouterServicesList,
|
|
110
|
+
Config<TRouterServicesList, Application>
|
|
110
111
|
>;
|
|
111
112
|
|
|
112
113
|
const LogPrefix = '[router]';
|
|
113
114
|
|
|
114
115
|
export type Config<
|
|
115
116
|
TServices extends TRouterServicesList,
|
|
116
|
-
TApplication extends
|
|
117
|
+
TApplication extends Application = Application,
|
|
117
118
|
> = {
|
|
118
119
|
debug: boolean;
|
|
119
120
|
|
|
@@ -147,16 +148,16 @@ export type TControllerDefinition = {
|
|
|
147
148
|
};
|
|
148
149
|
|
|
149
150
|
export type TServerRouter = ServerRouter<
|
|
150
|
-
|
|
151
|
+
Application,
|
|
151
152
|
TRouterServicesList,
|
|
152
|
-
Config<TRouterServicesList,
|
|
153
|
+
Config<TRouterServicesList, Application>
|
|
153
154
|
>;
|
|
154
155
|
|
|
155
156
|
/*----------------------------------
|
|
156
157
|
- CLASSE
|
|
157
158
|
----------------------------------*/
|
|
158
159
|
export default class ServerRouter<
|
|
159
|
-
TApplication extends
|
|
160
|
+
TApplication extends Application = Application,
|
|
160
161
|
TServices extends TRouterServicesList = TRouterServicesList,
|
|
161
162
|
TConfig extends Config<TServices, TApplication> = Config<TServices, TApplication>,
|
|
162
163
|
>
|
|
@@ -4,6 +4,8 @@ import zod from 'zod';
|
|
|
4
4
|
export type TRichTextValidatorOptions = { attachements?: boolean };
|
|
5
5
|
export type TValidationSchema = zod.ZodTypeAny;
|
|
6
6
|
export type TValidationShape = zod.ZodRawShape;
|
|
7
|
+
export type TInferValidationSchema<TSchema extends TValidationSchema> = zod.infer<TSchema>;
|
|
8
|
+
export type TTypedValidationSchema<TOutput> = zod.ZodType<TOutput>;
|
|
7
9
|
|
|
8
10
|
type TChoiceOption = { value: PrimitiveValue; label: string };
|
|
9
11
|
|
|
@@ -12,7 +12,7 @@ import express from 'express';
|
|
|
12
12
|
|
|
13
13
|
// Core
|
|
14
14
|
import context from '@server/context';
|
|
15
|
-
import type {
|
|
15
|
+
import type { default as ServerRouter, TServerRouter, TAnyRouter } from '@server/services/router';
|
|
16
16
|
import ServerRequest from '@server/services/router/request';
|
|
17
17
|
import { TMatchedRoute, TRoute, TAnyRoute } from '@common/router';
|
|
18
18
|
import { NotFound, Forbidden, Anomaly } from '@common/errors';
|
|
@@ -40,8 +40,7 @@ export type TBasicSSrData = {
|
|
|
40
40
|
currentDomain: string;
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
type TServerRouterApplication<TRouter extends TServerRouter> =
|
|
44
|
-
TRouter extends ServerRouter<infer TApplication, any, any> ? TApplication : never;
|
|
43
|
+
type TServerRouterApplication<TRouter extends TServerRouter> = TRouter['app'];
|
|
45
44
|
|
|
46
45
|
type TServerRouterPlugins<TRouter extends TServerRouter> =
|
|
47
46
|
TRouter extends ServerRouter<any, any, infer TConfig>
|
|
@@ -80,8 +79,10 @@ export type TRouterContextServices<
|
|
|
80
79
|
// Custom context via servuces
|
|
81
80
|
// For each roiuter service, return the request service (returned by roiuterService.requestService() )
|
|
82
81
|
{
|
|
83
|
-
[serviceName in keyof TPlugins]: TPlugins[serviceName] extends
|
|
84
|
-
?
|
|
82
|
+
[serviceName in keyof TPlugins]: TPlugins[serviceName] extends { requestService: infer TRequestServiceMethod }
|
|
83
|
+
? TRequestServiceMethod extends (...args: infer TRequestServiceArgs) => infer TRequestService
|
|
84
|
+
? Exclude<TRequestService, null | undefined>
|
|
85
|
+
: TPlugins[serviceName]
|
|
85
86
|
: TPlugins[serviceName];
|
|
86
87
|
};
|
|
87
88
|
|
|
@@ -97,7 +98,6 @@ const getRouteTraceTarget = (route: TAnyRoute<TRouterContext<TServerRouter>>) =>
|
|
|
97
98
|
----------------------------------*/
|
|
98
99
|
export default class ServerResponse<
|
|
99
100
|
TRouter extends TAnyRouter,
|
|
100
|
-
TRequestContext extends TRouterContext<TRouter> = TRouterContext<TRouter>,
|
|
101
101
|
TData extends TResponseData = TResponseData,
|
|
102
102
|
> extends BaseResponse<TData, ServerRequest<TRouter>> {
|
|
103
103
|
// Services
|
|
@@ -220,13 +220,13 @@ export default class ServerResponse<
|
|
|
220
220
|
----------------------------------*/
|
|
221
221
|
|
|
222
222
|
// Start controller services
|
|
223
|
-
private async createContext(route: TAnyRoute<TRouterContext<TRouter>>): Promise<
|
|
223
|
+
private async createContext(route: TAnyRoute<TRouterContext<TRouter>>): Promise<TRouterContext<TRouter>> {
|
|
224
224
|
const contextServices = this.router.createContextServices(this.request);
|
|
225
225
|
const controllers = createControllers(this.request.api);
|
|
226
226
|
const customSsrData = this.router.config.context(this.request, this.app) as TRouterRequestContext<TRouter>;
|
|
227
227
|
|
|
228
228
|
// TODO: transmiss safe data (especially for Router), as Router info could be printed on client side
|
|
229
|
-
const requestContext = {
|
|
229
|
+
const requestContext: TRouterContext<TRouter> = {
|
|
230
230
|
// Router context
|
|
231
231
|
app: this.app,
|
|
232
232
|
context: undefined!,
|
|
@@ -242,7 +242,7 @@ export default class ServerResponse<
|
|
|
242
242
|
// Router services
|
|
243
243
|
...(contextServices as TRouterContextServices<TRouter>),
|
|
244
244
|
...customSsrData,
|
|
245
|
-
}
|
|
245
|
+
};
|
|
246
246
|
|
|
247
247
|
requestContext.context = requestContext;
|
|
248
248
|
|
|
@@ -7,15 +7,16 @@ import type { Application } from '@server/app/index';
|
|
|
7
7
|
import Service, { TSetupConfig } from '@server/app/service';
|
|
8
8
|
|
|
9
9
|
// Specific
|
|
10
|
-
import type { default as Router } from '.';
|
|
11
10
|
import type ServerRequest from './request';
|
|
12
11
|
import type { TAnyRouter } from '.';
|
|
13
12
|
|
|
14
|
-
export type AnyRouterService =
|
|
13
|
+
export type AnyRouterService = Service<{}, {}, Application, object> & {
|
|
14
|
+
requestService(request: object): object | null;
|
|
15
|
+
};
|
|
15
16
|
|
|
16
|
-
export type TRouterServiceArgs<TConfig extends {} = {}
|
|
17
|
+
export type TRouterServiceArgs<TConfig extends {} = {}> = [
|
|
17
18
|
getConfig: TSetupConfig<TConfig> | null | undefined,
|
|
18
|
-
app:
|
|
19
|
+
app: Application,
|
|
19
20
|
];
|
|
20
21
|
|
|
21
22
|
/*----------------------------------
|
|
@@ -23,11 +24,14 @@ export type TRouterServiceArgs<TConfig extends {} = {}, TRouter extends TAnyRout
|
|
|
23
24
|
----------------------------------*/
|
|
24
25
|
export default abstract class RouterService<
|
|
25
26
|
TConfig extends {},
|
|
26
|
-
TRouter extends TAnyRouter
|
|
27
|
+
TRouter extends TAnyRouter,
|
|
27
28
|
TRequestService extends object | null = object | null,
|
|
28
|
-
> extends Service<TConfig, {},
|
|
29
|
-
public
|
|
30
|
-
|
|
29
|
+
> extends Service<TConfig, {}, Application, object> {
|
|
30
|
+
public declare parent: TRouter;
|
|
31
|
+
public declare app: TRouter extends { app: infer TApplication extends Application } ? TApplication : Application;
|
|
32
|
+
|
|
33
|
+
public constructor(...[config, app]: TRouterServiceArgs<TConfig>) {
|
|
34
|
+
super(app, config, app);
|
|
31
35
|
}
|
|
32
36
|
|
|
33
37
|
public abstract requestService(request: ServerRequest<TRouter>): TRequestService;
|