proteum 1.0.3 → 2.0.0
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 +92 -0
- package/agents/codex/AGENTS.md +95 -0
- package/agents/codex/CODING_STYLE.md +71 -0
- package/agents/codex/agents.md.zip +0 -0
- package/agents/codex/client/AGENTS.md +102 -0
- package/agents/codex/client/pages/AGENTS.md +35 -0
- package/agents/codex/server/routes/AGENTS.md +12 -0
- package/agents/codex/server/services/AGENTS.md +137 -0
- package/agents/codex/tests/AGENTS.md +8 -0
- package/cli/app/config.ts +12 -17
- package/cli/app/index.ts +59 -99
- package/cli/bin.js +1 -1
- package/cli/commands/build.ts +23 -12
- package/cli/commands/check.ts +19 -0
- package/cli/commands/deploy/app.ts +4 -8
- package/cli/commands/deploy/web.ts +16 -20
- package/cli/commands/dev.ts +185 -75
- package/cli/commands/devEvents.ts +106 -0
- package/cli/commands/init.ts +63 -57
- package/cli/commands/lint.ts +21 -0
- package/cli/commands/refresh.ts +6 -6
- package/cli/commands/typecheck.ts +18 -0
- package/cli/compiler/client/identite.ts +79 -49
- package/cli/compiler/client/index.ts +132 -214
- package/cli/compiler/common/bundleAnalysis.ts +94 -0
- package/cli/compiler/common/clientManifest.ts +67 -0
- package/cli/compiler/common/controllers.ts +288 -0
- package/cli/compiler/common/files/autres.ts +7 -18
- package/cli/compiler/common/files/images.ts +40 -37
- package/cli/compiler/common/files/style.ts +12 -25
- package/cli/compiler/common/generatedRouteModules.ts +368 -0
- package/cli/compiler/common/index.ts +29 -68
- package/cli/compiler/common/loaders/forbid-ssr-import.js +13 -0
- package/cli/compiler/common/rspackAliases.ts +13 -0
- package/cli/compiler/common/scripts.ts +37 -0
- package/cli/compiler/index.ts +764 -234
- package/cli/compiler/server/index.ts +52 -77
- package/cli/compiler/writeIfChanged.ts +21 -0
- package/cli/index.ts +65 -90
- package/cli/paths.ts +51 -57
- package/cli/print.ts +17 -11
- package/cli/tsconfig.json +5 -4
- package/cli/utils/agents.ts +100 -0
- package/cli/utils/check.ts +71 -0
- package/cli/utils/index.ts +1 -3
- package/cli/utils/keyboard.ts +8 -25
- package/cli/utils/runProcess.ts +30 -0
- package/client/app/component.tsx +29 -29
- package/client/app/index.ts +36 -57
- package/client/app/service.ts +7 -12
- package/client/app.tsconfig.json +2 -2
- package/client/components/Dialog/Manager.ssr.tsx +40 -0
- package/client/components/Dialog/Manager.tsx +119 -150
- package/client/components/Dialog/status.tsx +3 -3
- package/client/components/index.ts +1 -1
- package/client/components/types.d.ts +1 -3
- package/client/dev/hmr.ts +65 -0
- package/client/global.d.ts +2 -2
- package/client/hooks.ts +6 -9
- package/client/index.ts +2 -1
- package/client/islands/index.ts +7 -0
- package/client/islands/useDeferredModule.ts +199 -0
- package/client/pages/_layout/index.tsx +4 -12
- package/client/pages/useHeader.tsx +14 -21
- package/client/router.ts +27 -0
- package/client/services/router/components/Link.tsx +34 -27
- package/client/services/router/components/Page.tsx +6 -14
- package/client/services/router/components/router.ssr.tsx +36 -0
- package/client/services/router/components/router.tsx +63 -83
- package/client/services/router/index.tsx +185 -220
- package/client/services/router/request/api.ts +97 -119
- package/client/services/router/request/history.ts +2 -2
- package/client/services/router/request/index.ts +13 -12
- package/client/services/router/request/multipart.ts +72 -62
- package/client/services/router/response/index.tsx +68 -61
- package/client/services/router/response/page.ts +28 -32
- package/client/utils/dom.ts +17 -33
- package/common/app/index.ts +3 -3
- package/common/data/chaines/index.ts +22 -23
- package/common/data/dates.ts +35 -70
- package/common/data/markdown.ts +42 -39
- package/common/dev/serverHotReload.ts +26 -0
- package/common/errors/index.tsx +110 -142
- package/common/router/contracts.ts +29 -0
- package/common/router/index.ts +89 -108
- package/common/router/layouts.ts +34 -47
- package/common/router/pageSetup.ts +50 -0
- package/common/router/register.ts +53 -24
- package/common/router/request/api.ts +30 -36
- package/common/router/request/index.ts +2 -8
- package/common/router/response/index.ts +8 -15
- package/common/router/response/page.ts +70 -58
- package/common/utils.ts +1 -1
- package/eslint.js +62 -0
- package/package.json +12 -45
- package/prettier.config.cjs +9 -0
- package/scripts/cleanup-generated-controllers.ts +62 -0
- package/scripts/fix-reference-app-typing.ts +490 -0
- package/scripts/refactor-client-app-imports.ts +244 -0
- package/scripts/refactor-client-pages.ts +587 -0
- package/scripts/refactor-server-controllers.ts +470 -0
- package/scripts/refactor-server-runtime-aliases.ts +360 -0
- package/scripts/restore-client-app-import-files.ts +41 -0
- package/scripts/restore-files-from-git-head.ts +20 -0
- package/scripts/update-codex-agents.ts +35 -0
- package/server/app/commands.ts +35 -64
- package/server/app/container/config.ts +39 -69
- package/server/app/container/console/index.ts +202 -248
- package/server/app/container/index.ts +33 -71
- package/server/app/controller/index.ts +61 -0
- package/server/app/index.ts +39 -105
- package/server/app/service/container.ts +41 -42
- package/server/app/service/index.ts +120 -147
- package/server/context.ts +1 -1
- package/server/index.ts +25 -1
- package/server/services/auth/index.ts +75 -115
- package/server/services/auth/router/index.ts +31 -32
- package/server/services/auth/router/request.ts +14 -16
- package/server/services/cron/CronTask.ts +13 -26
- package/server/services/cron/index.ts +14 -36
- package/server/services/disks/driver.ts +40 -58
- package/server/services/disks/drivers/local/index.ts +79 -90
- package/server/services/disks/drivers/s3/index.ts +116 -163
- package/server/services/disks/index.ts +23 -38
- package/server/services/email/index.ts +45 -104
- package/server/services/email/utils.ts +14 -27
- package/server/services/fetch/index.ts +53 -85
- package/server/services/prisma/Facet.ts +39 -91
- package/server/services/prisma/index.ts +74 -110
- package/server/services/router/generatedRuntime.ts +29 -0
- package/server/services/router/http/index.ts +77 -72
- package/server/services/router/http/multipart.ts +19 -42
- package/server/services/router/index.ts +378 -365
- package/server/services/router/request/api.ts +26 -25
- package/server/services/router/request/index.ts +44 -51
- package/server/services/router/request/service.ts +7 -11
- package/server/services/router/request/validation/zod.ts +111 -148
- package/server/services/router/response/index.ts +110 -125
- package/server/services/router/response/mask/Filter.ts +31 -72
- package/server/services/router/response/mask/index.ts +8 -15
- package/server/services/router/response/mask/selecteurs.ts +11 -25
- package/server/services/router/response/page/clientManifest.ts +25 -0
- package/server/services/router/response/page/document.tsx +199 -127
- package/server/services/router/response/page/index.tsx +89 -94
- package/server/services/router/service.ts +13 -15
- package/server/services/schema/index.ts +17 -26
- package/server/services/schema/request.ts +19 -33
- package/server/services/schema/router/index.ts +8 -11
- package/server/services/security/encrypt/aes/index.ts +15 -35
- package/server/utils/slug.ts +29 -32
- package/skills/clean-project-code/SKILL.md +63 -0
- package/skills/clean-project-code/agents/openai.yaml +4 -0
- package/tsconfig.common.json +4 -3
- package/tsconfig.json +4 -1
- package/types/aliases.d.ts +17 -21
- package/types/controller-input.test.ts +48 -0
- package/types/express-extra.d.ts +6 -0
- package/types/global/constants.d.ts +1 -0
- package/types/global/express-extra.d.ts +6 -0
- package/types/global/modules.d.ts +13 -16
- package/types/global/utils.d.ts +17 -49
- package/types/global/vendors.d.ts +62 -0
- package/types/icons.d.ts +65 -1
- package/types/uuid.d.ts +3 -0
- package/types/vendors.d.ts +62 -0
- package/cli/compiler/common/babel/index.ts +0 -173
- package/cli/compiler/common/babel/plugins/index.ts +0 -0
- package/cli/compiler/common/babel/plugins/services.ts +0 -586
- package/cli/compiler/common/babel/routes/imports.ts +0 -127
- package/cli/compiler/common/babel/routes/routes.ts +0 -1170
- package/client/services/captcha/index.ts +0 -67
- package/client/services/socket/index.ts +0 -147
- package/common/data/rte/nodes.ts +0 -83
- package/common/data/stats.ts +0 -90
- package/common/utils/rte.ts +0 -183
- package/server/services/auth/old.ts +0 -277
- package/server/services/cache/commands.ts +0 -41
- package/server/services/cache/index.ts +0 -297
- package/server/services/cache/service.json +0 -6
- package/server/services/socket/index.ts +0 -162
- package/server/services/socket/scope.ts +0 -226
- package/server/services/socket/service.json +0 -6
- package/server/services_old/SocketClient.ts +0 -92
- package/server/services_old/Token.old.ts +0 -97
|
@@ -20,12 +20,9 @@ import type ServerRequest from '@server/services/router/request';
|
|
|
20
20
|
/*----------------------------------
|
|
21
21
|
- CLASS
|
|
22
22
|
----------------------------------*/
|
|
23
|
-
export class ApplicationContainer<
|
|
24
|
-
TServicesIndex extends StartedServicesIndex = StartedServicesIndex
|
|
25
|
-
> {
|
|
26
|
-
|
|
23
|
+
export class ApplicationContainer<TServicesIndex extends StartedServicesIndex = StartedServicesIndex> {
|
|
27
24
|
/*----------------------------------
|
|
28
|
-
-
|
|
25
|
+
- STATE
|
|
29
26
|
----------------------------------*/
|
|
30
27
|
|
|
31
28
|
public Services = Services as ServicesContainer<TServicesIndex>;
|
|
@@ -35,38 +32,38 @@ export class ApplicationContainer<
|
|
|
35
32
|
|
|
36
33
|
public application?: Application;
|
|
37
34
|
|
|
38
|
-
|
|
35
|
+
// Runtime path registry used by the application container and generators.
|
|
36
|
+
public path = {
|
|
37
|
+
root: process.cwd(),
|
|
38
|
+
public: path.join(process.cwd(), '/public'),
|
|
39
|
+
var: path.join(process.cwd(), '/var'),
|
|
40
|
+
|
|
41
|
+
client: { generated: path.join(process.cwd(), 'src', 'client', '.generated') },
|
|
42
|
+
server: { generated: path.join(process.cwd(), 'src', 'server', '.generated') },
|
|
43
|
+
};
|
|
39
44
|
|
|
45
|
+
/*----------------------------------
|
|
46
|
+
- CONFIG
|
|
47
|
+
----------------------------------*/
|
|
48
|
+
|
|
49
|
+
public constructor() {
|
|
40
50
|
// Load config files
|
|
41
|
-
const configParser = new ConfigParser(
|
|
51
|
+
const configParser = new ConfigParser(this.path.root);
|
|
42
52
|
this.Environment = configParser.env();
|
|
43
53
|
this.Identity = configParser.identity();
|
|
44
54
|
this.Console = new Console(this, this.Environment.console);
|
|
45
55
|
}
|
|
46
56
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
public path = {
|
|
51
|
-
root: process.cwd(),
|
|
52
|
-
public: path.join( process.cwd(), '/public'),
|
|
53
|
-
var: path.join( process.cwd(), '/var'),
|
|
54
|
-
|
|
55
|
-
client: {
|
|
56
|
-
generated: path.join( process.cwd(), 'src', 'client', '.generated')
|
|
57
|
-
},
|
|
58
|
-
server: {
|
|
59
|
-
generated: path.join( process.cwd(), 'src', 'server', '.generated')
|
|
60
|
-
},
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
public start( ApplicationClass: typeof Application ): Application {
|
|
57
|
+
/*----------------------------------
|
|
58
|
+
- PUBLIC API
|
|
59
|
+
----------------------------------*/
|
|
64
60
|
|
|
61
|
+
public start<TApplication extends Application>(ApplicationClass: new () => TApplication): TApplication {
|
|
65
62
|
// Instanciate Application
|
|
66
63
|
try {
|
|
67
|
-
this.application = new ApplicationClass;
|
|
64
|
+
this.application = new ApplicationClass();
|
|
68
65
|
} catch (error) {
|
|
69
|
-
this.handleBug(error,
|
|
66
|
+
this.handleBug(error, 'Failed to instanciate the Application Class');
|
|
70
67
|
process.exit(1);
|
|
71
68
|
}
|
|
72
69
|
|
|
@@ -74,64 +71,29 @@ export class ApplicationContainer<
|
|
|
74
71
|
try {
|
|
75
72
|
this.application.start();
|
|
76
73
|
} catch (error) {
|
|
77
|
-
this.handleBug(error,
|
|
74
|
+
this.handleBug(error, 'Failed to start the Application');
|
|
78
75
|
process.exit(1);
|
|
79
76
|
}
|
|
80
77
|
|
|
81
|
-
return this.application;
|
|
78
|
+
return this.application as TApplication;
|
|
82
79
|
}
|
|
83
80
|
|
|
84
|
-
public async handleBug(
|
|
81
|
+
public async handleBug(rejection: unknown, message: string, request?: ServerRequest) {
|
|
82
|
+
const error =
|
|
83
|
+
rejection instanceof Error ? rejection : new Error(typeof rejection === 'string' ? rejection : message);
|
|
84
|
+
|
|
85
85
|
if (this.Console) {
|
|
86
86
|
try {
|
|
87
|
-
|
|
88
|
-
this.Console.createBugReport(rejection, request);
|
|
89
|
-
|
|
87
|
+
this.Console.createBugReport(error, request);
|
|
90
88
|
} catch (consoleError) {
|
|
91
|
-
console.error(
|
|
92
|
-
message, rejection,
|
|
93
|
-
"Failed to transmiss the previous error to console:", consoleError
|
|
94
|
-
);
|
|
89
|
+
console.error(message, error, 'Failed to transmiss the previous error to console:', consoleError);
|
|
95
90
|
process.exit(1);
|
|
96
91
|
}
|
|
97
92
|
} else {
|
|
98
|
-
console.error(message,
|
|
93
|
+
console.error(message, error);
|
|
99
94
|
process.exit(1);
|
|
100
95
|
}
|
|
101
96
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
/*----------------------------------
|
|
105
|
-
- HMR
|
|
106
|
-
- TODO: move in dev server
|
|
107
|
-
----------------------------------*/
|
|
108
|
-
private activateHMR() {
|
|
109
|
-
|
|
110
|
-
if (!module.hot) return;
|
|
111
|
-
|
|
112
|
-
console.info(`Activating HMR ...`);
|
|
113
|
-
|
|
114
|
-
module.hot.accept();
|
|
115
|
-
module.hot.accept( this.path.root + '/.cache/commun/routes.ts' );
|
|
116
|
-
|
|
117
|
-
module.hot.addDisposeHandler((data) => {
|
|
118
|
-
|
|
119
|
-
console.info(`Cleaning application ...`);
|
|
120
|
-
|
|
121
|
-
// Services hooks
|
|
122
|
-
//this.app.shutdown();
|
|
123
|
-
|
|
124
|
-
/*
|
|
125
|
-
console.log("[nettoyage] Arrêt serveur socket ...");
|
|
126
|
-
if (socket !== undefined)
|
|
127
|
-
socket.serveur.close()
|
|
128
|
-
|
|
129
|
-
console.log("[nettoyage] Reset du cache requêtes JSQL ...");
|
|
130
|
-
QueryParser.clearCache();*/
|
|
131
|
-
|
|
132
|
-
});
|
|
133
|
-
}
|
|
134
|
-
|
|
135
97
|
}
|
|
136
98
|
|
|
137
|
-
export default new ApplicationContainer;
|
|
99
|
+
export default new ApplicationContainer();
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/*----------------------------------
|
|
2
|
+
- DEPENDANCES
|
|
3
|
+
----------------------------------*/
|
|
4
|
+
|
|
5
|
+
// Npm
|
|
6
|
+
import zod from 'zod';
|
|
7
|
+
|
|
8
|
+
// Core
|
|
9
|
+
import context from '@server/context';
|
|
10
|
+
import type { Application } from '../index';
|
|
11
|
+
import type { TRouterContext, TAnyRouter } from '@server/services/router';
|
|
12
|
+
import {
|
|
13
|
+
toValidationSchema,
|
|
14
|
+
type TValidationSchema,
|
|
15
|
+
type TValidationShape,
|
|
16
|
+
} from '@server/services/router/request/validation/zod';
|
|
17
|
+
|
|
18
|
+
export { schema } from '@server/services/router/request/validation/zod';
|
|
19
|
+
export type { z } from '@server/services/router/request/validation/zod';
|
|
20
|
+
|
|
21
|
+
/*----------------------------------
|
|
22
|
+
- TYPES
|
|
23
|
+
----------------------------------*/
|
|
24
|
+
|
|
25
|
+
type TControllerContext = TRouterContext<TAnyRouter>;
|
|
26
|
+
|
|
27
|
+
/*----------------------------------
|
|
28
|
+
- CLASS
|
|
29
|
+
----------------------------------*/
|
|
30
|
+
|
|
31
|
+
export default abstract class Controller<
|
|
32
|
+
TApplication extends Application = Application,
|
|
33
|
+
TContext extends TControllerContext = TControllerContext,
|
|
34
|
+
> {
|
|
35
|
+
public constructor(public request: TContext) {}
|
|
36
|
+
|
|
37
|
+
public get app(): TApplication {
|
|
38
|
+
return this.request.app as TApplication;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
public get services(): TApplication {
|
|
42
|
+
return this.app;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public get models() {
|
|
46
|
+
const app = this.app as { models?: { client?: unknown }; Models?: { client?: unknown } };
|
|
47
|
+
return app.models?.client ?? app.Models?.client;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public input<TSchema extends TValidationSchema>(schema: TSchema): zod.output<TSchema>;
|
|
51
|
+
public input<TShape extends TValidationShape>(schema: TShape): zod.output<zod.ZodObject<TShape>>;
|
|
52
|
+
public input(schema: TValidationSchema | TValidationShape) {
|
|
53
|
+
const store = context.getStore() as { inputSchemaUsed?: boolean } | undefined;
|
|
54
|
+
|
|
55
|
+
if (store?.inputSchemaUsed) throw new Error('Controller.input() can only be called once per request handler.');
|
|
56
|
+
|
|
57
|
+
if (store) store.inputSchemaUsed = true;
|
|
58
|
+
|
|
59
|
+
return toValidationSchema(schema).parse(this.request.request.data);
|
|
60
|
+
}
|
|
61
|
+
}
|
package/server/app/index.ts
CHANGED
|
@@ -2,22 +2,15 @@
|
|
|
2
2
|
- DEPENDANCES
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
|
-
// Npm
|
|
6
|
-
import type express from 'express';
|
|
7
|
-
|
|
8
5
|
// Core
|
|
9
6
|
import AppContainer from './container';
|
|
10
|
-
import ApplicationService, { AnyService
|
|
7
|
+
import ApplicationService, { AnyService } from './service';
|
|
11
8
|
import CommandsManager from './commands';
|
|
12
|
-
import ServicesContainer, {
|
|
13
|
-
ServicesContainer as ServicesContainerClass,
|
|
14
|
-
TServiceMetas
|
|
15
|
-
} from './service/container';
|
|
9
|
+
import ServicesContainer, { ServicesContainer as ServicesContainerClass, TServiceMetas } from './service/container';
|
|
16
10
|
|
|
17
11
|
// Built-in
|
|
18
|
-
import type {
|
|
12
|
+
import type { TServerRouter, Request as ServerRequest } from '@server/services/router';
|
|
19
13
|
import { Anomaly } from '@common/errors';
|
|
20
|
-
import { preprocessSchema } from '@server/services/router/request/validation/zod';
|
|
21
14
|
import { TBasicUser } from '@server/services/auth';
|
|
22
15
|
|
|
23
16
|
export { default as Services } from './service/container';
|
|
@@ -27,28 +20,18 @@ export type { TEnvConfig as Environment } from './container/config';
|
|
|
27
20
|
- TYPES
|
|
28
21
|
----------------------------------*/
|
|
29
22
|
|
|
30
|
-
type Config = {
|
|
31
|
-
|
|
32
|
-
}
|
|
23
|
+
type Config = {};
|
|
33
24
|
|
|
34
25
|
type Hooks = {
|
|
35
|
-
ready: {
|
|
36
|
-
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
args: [],
|
|
40
|
-
},
|
|
41
|
-
error: {
|
|
42
|
-
args: [error: Error, request?: ServerRequest<Router>],
|
|
43
|
-
}
|
|
44
|
-
}
|
|
26
|
+
ready: { args: [] };
|
|
27
|
+
cleanup: { args: [] };
|
|
28
|
+
error: { args: [error: Error, request?: ServerRequest<TServerRouter>] };
|
|
29
|
+
};
|
|
45
30
|
|
|
46
31
|
export const Service = ServicesContainer;
|
|
47
32
|
|
|
48
33
|
// Without prettify, we don't get a clear list of the class properties
|
|
49
|
-
type Prettify<T> = {
|
|
50
|
-
[K in keyof T]: T[K];
|
|
51
|
-
} & {};
|
|
34
|
+
type Prettify<T> = { [K in keyof T]: T[K] } & {};
|
|
52
35
|
|
|
53
36
|
export type ApplicationProperties = Prettify<keyof Application>;
|
|
54
37
|
|
|
@@ -59,7 +42,6 @@ export abstract class Application<
|
|
|
59
42
|
TServicesContainer extends ServicesContainerClass = ServicesContainerClass,
|
|
60
43
|
TUser extends TBasicUser = TBasicUser,
|
|
61
44
|
> extends ApplicationService<Config, Hooks, Application, Application> {
|
|
62
|
-
|
|
63
45
|
public app!: this;
|
|
64
46
|
public servicesContainer!: TServicesContainer;
|
|
65
47
|
public userType!: TUser;
|
|
@@ -74,8 +56,8 @@ export abstract class Application<
|
|
|
74
56
|
name: 'Application',
|
|
75
57
|
parent: 'root',
|
|
76
58
|
dependences: [],
|
|
77
|
-
class: () => ({
|
|
78
|
-
}
|
|
59
|
+
class: () => ({ default: Application }),
|
|
60
|
+
};
|
|
79
61
|
|
|
80
62
|
// Shortcuts to ApplicationContainer
|
|
81
63
|
public container = AppContainer;
|
|
@@ -85,33 +67,26 @@ export abstract class Application<
|
|
|
85
67
|
// Status
|
|
86
68
|
public debug: boolean = false;
|
|
87
69
|
public launched: boolean = false;
|
|
88
|
-
|
|
89
|
-
protected abstract registered: {
|
|
90
|
-
[serviceId: string]: {
|
|
91
|
-
name: string,
|
|
92
|
-
start: () => AnyService
|
|
93
|
-
}
|
|
94
|
-
};
|
|
70
|
+
|
|
71
|
+
protected abstract registered: { [serviceId: string]: { name: string; start: () => AnyService } };
|
|
95
72
|
|
|
96
73
|
/*----------------------------------
|
|
97
74
|
- INIT
|
|
98
75
|
----------------------------------*/
|
|
99
76
|
|
|
100
77
|
public constructor() {
|
|
101
|
-
|
|
102
|
-
const self = 'self' as unknown as Application;
|
|
78
|
+
const self = 'self' as const;
|
|
103
79
|
|
|
104
80
|
// Application itself doesnt have configuration
|
|
105
81
|
// Configuration must be handled by application services
|
|
106
82
|
super(self, {}, self);
|
|
107
|
-
|
|
83
|
+
|
|
108
84
|
// Handle unhandled crash
|
|
109
|
-
this.on('error', (e, request) => this.container.handleBug(e,
|
|
110
|
-
|
|
111
|
-
process.on('unhandledRejection', (error: any, promise: any) => {
|
|
85
|
+
this.on('error', (e, request) => this.container.handleBug(e, 'An error occured in the application', request));
|
|
112
86
|
|
|
87
|
+
process.on('unhandledRejection', (error: any, _promise: any) => {
|
|
113
88
|
// Log so we know it's coming from unhandledRejection
|
|
114
|
-
console.error(
|
|
89
|
+
console.error('unhandledRejection', error);
|
|
115
90
|
|
|
116
91
|
// We don't log the error here because it's the role of the app to decidehiw to log errors
|
|
117
92
|
this.runHook('error', error);
|
|
@@ -120,33 +95,29 @@ export abstract class Application<
|
|
|
120
95
|
// We can't pass this in super so we assign here
|
|
121
96
|
this.parent = this;
|
|
122
97
|
this.app = this;
|
|
123
|
-
|
|
124
98
|
}
|
|
125
99
|
|
|
126
100
|
public report(...anomalyArgs: ConstructorParameters<typeof Anomaly>) {
|
|
127
|
-
return this.container.Console.createBugReport(
|
|
128
|
-
new Anomaly(...anomalyArgs)
|
|
129
|
-
);
|
|
101
|
+
return this.container.Console.createBugReport(new Anomaly(...anomalyArgs));
|
|
130
102
|
}
|
|
131
103
|
|
|
132
104
|
/*----------------------------------
|
|
133
105
|
- COMMANDS
|
|
134
106
|
----------------------------------*/
|
|
135
107
|
|
|
136
|
-
private commandsManager = new CommandsManager(this, { debug: true },
|
|
108
|
+
private commandsManager = new CommandsManager(this, { debug: true }, this);
|
|
137
109
|
|
|
138
|
-
public command(
|
|
110
|
+
public command(...args: Parameters<CommandsManager['command']>) {
|
|
139
111
|
return this.commandsManager.command(...args);
|
|
140
112
|
}
|
|
141
113
|
|
|
142
114
|
/*----------------------------------
|
|
143
115
|
- LAUNCH
|
|
144
116
|
----------------------------------*/
|
|
145
|
-
|
|
146
|
-
public async start() {
|
|
147
117
|
|
|
148
|
-
|
|
149
|
-
console.log(
|
|
118
|
+
public async start() {
|
|
119
|
+
console.log('Build date', BUILD_DATE);
|
|
120
|
+
console.log('Core version', CORE_VERSION);
|
|
150
121
|
const startTime = Date.now();
|
|
151
122
|
|
|
152
123
|
this.startServices();
|
|
@@ -169,35 +140,29 @@ export abstract class Application<
|
|
|
169
140
|
----------------------------------*/
|
|
170
141
|
|
|
171
142
|
private startServices() {
|
|
172
|
-
|
|
173
143
|
// Satrt services
|
|
174
144
|
for (const serviceId in this.registered) {
|
|
175
145
|
try {
|
|
176
146
|
const service = this.registered[serviceId];
|
|
177
147
|
const instance = service.start();
|
|
178
|
-
this[service.name] = instance.getServiceInstance();
|
|
148
|
+
(this as Record<string, unknown>)[service.name] = instance.getServiceInstance();
|
|
179
149
|
} catch (error) {
|
|
180
|
-
console.error(
|
|
150
|
+
console.error('Error while starting service', serviceId, error);
|
|
181
151
|
throw error;
|
|
182
152
|
}
|
|
183
153
|
}
|
|
184
154
|
}
|
|
185
155
|
|
|
186
|
-
public register(
|
|
187
|
-
|
|
156
|
+
public register(service: AnyService) {
|
|
188
157
|
return service.ready();
|
|
189
|
-
|
|
190
158
|
}
|
|
191
159
|
|
|
192
|
-
|
|
193
|
-
|
|
160
|
+
public async ready() {
|
|
194
161
|
const startingServices: Promise<any>[] = [];
|
|
195
162
|
|
|
196
163
|
// Print services
|
|
197
164
|
const processService = async (propKey: string, service: AnyService, level: number = 0) => {
|
|
198
|
-
|
|
199
|
-
if (service.status !== 'starting')
|
|
200
|
-
return;
|
|
165
|
+
if (service.status !== 'starting') return;
|
|
201
166
|
|
|
202
167
|
// Services start shouldn't block app boot
|
|
203
168
|
// use await ServiceName.started to make services depends on each other
|
|
@@ -206,68 +171,37 @@ export abstract class Application<
|
|
|
206
171
|
service.status = 'running';
|
|
207
172
|
console.log('-' + '-'.repeat(level * 1), propKey + ': ' + service.constructor.name);
|
|
208
173
|
|
|
209
|
-
// Routes
|
|
210
|
-
const routes = service.__routes as TRoute[];
|
|
211
|
-
if (routes) for (const route of routes) {
|
|
212
|
-
|
|
213
|
-
console.log('Attached service', service.constructor.name, 'to route', route.path);
|
|
214
|
-
|
|
215
|
-
const preprocessedSchema = route.schema ? preprocessSchema(route.schema) : undefined;
|
|
216
|
-
|
|
217
|
-
const origController = route.controller;
|
|
218
|
-
route.controller = (context: RouterContext) => {
|
|
219
|
-
|
|
220
|
-
// Filter data
|
|
221
|
-
const data = preprocessedSchema
|
|
222
|
-
? preprocessedSchema.parse( context.request.data )
|
|
223
|
-
: {};
|
|
224
|
-
|
|
225
|
-
// Run controller
|
|
226
|
-
return origController.bind( service )(
|
|
227
|
-
data,
|
|
228
|
-
context
|
|
229
|
-
);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
this.Router.controllers[ route.path ] = route;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
174
|
// Subservices
|
|
236
175
|
for (const propKey in service) {
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
continue;
|
|
240
|
-
const propValue = service[propKey];
|
|
176
|
+
if (propKey === 'app') continue;
|
|
177
|
+
const propValue = (service as Record<string, any>)[propKey];
|
|
241
178
|
|
|
242
179
|
// Check if service
|
|
243
|
-
const isService =
|
|
244
|
-
typeof propValue === 'object' &&
|
|
180
|
+
const isService =
|
|
181
|
+
typeof propValue === 'object' &&
|
|
245
182
|
!(propValue instanceof Application) &&
|
|
246
|
-
propValue !== null &&
|
|
183
|
+
propValue !== null &&
|
|
247
184
|
propValue.status !== undefined;
|
|
248
|
-
if (!isService)
|
|
249
|
-
continue;
|
|
185
|
+
if (!isService) continue;
|
|
250
186
|
|
|
251
187
|
// Services start shouldn't block app boot
|
|
252
188
|
processService(propKey, propValue, level + 1);
|
|
253
189
|
}
|
|
254
|
-
}
|
|
190
|
+
};
|
|
255
191
|
|
|
256
192
|
for (const serviceId in this.registered) {
|
|
257
|
-
|
|
258
193
|
const registeredService = this.registered[serviceId];
|
|
259
|
-
const service = this[registeredService.name];
|
|
194
|
+
const service = (this as Record<string, any>)[registeredService.name];
|
|
260
195
|
|
|
261
196
|
// TODO: move to router
|
|
262
197
|
// Application.on('service.ready')
|
|
263
|
-
|
|
198
|
+
|
|
264
199
|
// Services start shouldn't block app boot
|
|
265
200
|
processService(serviceId, service);
|
|
266
201
|
}
|
|
267
202
|
|
|
268
203
|
return startingServices;
|
|
269
204
|
}
|
|
270
|
-
|
|
271
205
|
}
|
|
272
206
|
|
|
273
|
-
export default Application
|
|
207
|
+
export default Application;
|
|
@@ -3,37 +3,39 @@
|
|
|
3
3
|
----------------------------------*/
|
|
4
4
|
|
|
5
5
|
// Specific
|
|
6
|
-
import type {
|
|
7
|
-
AnyService,
|
|
6
|
+
import type {
|
|
7
|
+
AnyService,
|
|
8
|
+
StartedServicesIndex,
|
|
8
9
|
// Hooks
|
|
9
|
-
THookCallback,
|
|
10
|
-
|
|
10
|
+
THookCallback,
|
|
11
|
+
THooksIndex,
|
|
12
|
+
} from '.';
|
|
11
13
|
|
|
12
14
|
/*----------------------------------
|
|
13
15
|
- TYPES: REGISTRATION
|
|
14
16
|
----------------------------------*/
|
|
15
17
|
|
|
16
18
|
// From service/service.json
|
|
17
|
-
export type TServiceMetas<TServiceClass extends AnyService = AnyService>
|
|
18
|
-
id: string
|
|
19
|
-
name: string
|
|
20
|
-
parent: string
|
|
21
|
-
dependences: string[]
|
|
22
|
-
class: () => { default: ClassType<TServiceClass> }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type TRegisteredService<TServiceClass extends AnyService = AnyService>
|
|
26
|
-
type: 'service'
|
|
27
|
-
config?: {}
|
|
28
|
-
metas: TServiceMetas<TServiceClass
|
|
29
|
-
hooks: THooksIndex<{}
|
|
30
|
-
on: (hookName: string, hookFunc: THookCallback<any>) => void
|
|
31
|
-
subServices: TRegisteredServicesIndex
|
|
32
|
-
}
|
|
19
|
+
export type TServiceMetas<TServiceClass extends AnyService = AnyService> = {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
parent: string;
|
|
23
|
+
dependences: string[];
|
|
24
|
+
class: () => { default: ClassType<TServiceClass> };
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type TRegisteredService<TServiceClass extends AnyService = AnyService> = {
|
|
28
|
+
type: 'service'; // Used to recognize if an object is a registered service
|
|
29
|
+
config?: {};
|
|
30
|
+
metas: TServiceMetas<TServiceClass>;
|
|
31
|
+
hooks: THooksIndex<{}>;
|
|
32
|
+
on: (hookName: string, hookFunc: THookCallback<any>) => void;
|
|
33
|
+
subServices: TRegisteredServicesIndex;
|
|
34
|
+
};
|
|
33
35
|
|
|
34
36
|
export type TRegisteredServicesIndex<TServiceClass extends AnyService = AnyService> = {
|
|
35
|
-
[serviceId: string]: TRegisteredService<TServiceClass
|
|
36
|
-
}
|
|
37
|
+
[serviceId: string]: TRegisteredService<TServiceClass>;
|
|
38
|
+
};
|
|
37
39
|
|
|
38
40
|
/*----------------------------------
|
|
39
41
|
- CONFIG
|
|
@@ -44,45 +46,42 @@ const LogPrefix = '[service]';
|
|
|
44
46
|
/*----------------------------------
|
|
45
47
|
- CLASS
|
|
46
48
|
----------------------------------*/
|
|
47
|
-
export class ServicesContainer<
|
|
48
|
-
|
|
49
|
-
> {
|
|
50
|
-
|
|
51
|
-
public registered: TRegisteredServicesIndex = {}
|
|
49
|
+
export class ServicesContainer<TServicesIndex extends StartedServicesIndex = StartedServicesIndex> {
|
|
50
|
+
public registered: TRegisteredServicesIndex = {};
|
|
52
51
|
|
|
53
52
|
// All service instances by service id
|
|
54
|
-
public allServices: TServicesIndex = {} as TServicesIndex
|
|
53
|
+
public allServices: TServicesIndex = {} as TServicesIndex;
|
|
55
54
|
|
|
56
55
|
public callableInstance = <TInstance extends object, TCallableName extends keyof TInstance>(
|
|
57
|
-
instance: TInstance,
|
|
58
|
-
funcName: TCallableName
|
|
56
|
+
instance: TInstance,
|
|
57
|
+
funcName: TCallableName,
|
|
59
58
|
): TInstance[TCallableName] & TInstance => {
|
|
60
|
-
|
|
59
|
+
const instanceRecord = instance as Record<string, unknown>;
|
|
61
60
|
const callableFunc = instance[funcName];
|
|
62
|
-
if (typeof callableFunc !== 'function')
|
|
63
|
-
throw new Error(`instance[funcName] isn't callable.`);
|
|
61
|
+
if (typeof callableFunc !== 'function') throw new Error(`instance[funcName] isn't callable.`);
|
|
64
62
|
|
|
65
63
|
const callable = callableFunc.bind(instance);
|
|
66
64
|
|
|
67
65
|
const methods = [
|
|
68
|
-
...Object.getOwnPropertyNames(
|
|
69
|
-
...Object.getOwnPropertyNames(
|
|
66
|
+
...Object.getOwnPropertyNames(Object.getPrototypeOf(instance)),
|
|
67
|
+
...Object.getOwnPropertyNames(instance),
|
|
70
68
|
// service.launch() isn't included, maybe because parent abstract class
|
|
71
69
|
'launch',
|
|
72
|
-
'bindServices'
|
|
70
|
+
'bindServices',
|
|
73
71
|
];
|
|
74
72
|
|
|
75
73
|
for (const method of methods)
|
|
76
74
|
if (method !== 'constructor')
|
|
77
|
-
callable
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
(callable as Record<string, unknown>)[method] =
|
|
76
|
+
typeof instanceRecord[method] === 'function'
|
|
77
|
+
? (instanceRecord[method] as Function).bind(instance)
|
|
78
|
+
: instanceRecord[method];
|
|
80
79
|
|
|
81
|
-
// Allow us to recognize a callable as a service
|
|
80
|
+
// Allow us to recognize a callable as a service
|
|
82
81
|
callable.serviceInstance = instance;
|
|
83
82
|
|
|
84
83
|
return callable as TInstance[TCallableName] & TInstance;
|
|
85
|
-
}
|
|
84
|
+
};
|
|
86
85
|
}
|
|
87
86
|
|
|
88
|
-
export default new ServicesContainer
|
|
87
|
+
export default new ServicesContainer();
|