@xrystal/core 3.20.9 → 3.21.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.
- package/package.json +1 -1
- package/source/loader/controller/index.d.ts +21 -22
- package/source/loader/controller/index.js +9 -20
- package/source/loader/logger/index.js +2 -2
- package/source/loader/system/index.js +1 -1
- package/source/utils/models/classes/class.interfaces.d.ts +1 -0
- package/source/utils/models/classes/class.interfaces.js +2 -0
- package/source/utils/models/classes/class.x.d.ts +5 -3
- package/source/utils/models/classes/class.x.js +54 -30
package/package.json
CHANGED
|
@@ -26,26 +26,9 @@ export declare const getControllerCtx: () => {
|
|
|
26
26
|
_isRaw?: boolean;
|
|
27
27
|
};
|
|
28
28
|
};
|
|
29
|
-
export declare
|
|
30
|
-
export interface CustomRequest {
|
|
31
|
-
accounts?: any;
|
|
32
|
-
url: string;
|
|
33
|
-
method: string;
|
|
34
|
-
headers: Record<string, any>;
|
|
35
|
-
body?: any;
|
|
36
|
-
params: Record<string, any>;
|
|
37
|
-
query: Record<string, any>;
|
|
38
|
-
lang: string;
|
|
39
|
-
t: (k: string, args?: any) => string;
|
|
40
|
-
}
|
|
41
|
-
export interface CustomResponse {
|
|
42
|
-
status: (code: number) => CustomResponse;
|
|
43
|
-
send: (data: any) => any;
|
|
44
|
-
json: (data: any) => any;
|
|
45
|
-
locals: Record<string, any>;
|
|
46
|
-
}
|
|
47
|
-
declare abstract class Controller {
|
|
29
|
+
export declare abstract class Controller {
|
|
48
30
|
protected logger: LoggerService;
|
|
31
|
+
protected systemService: SystemService;
|
|
49
32
|
protected supportedProtocols: ProtocolEnum[];
|
|
50
33
|
protected get protocol(): ProtocolEnum;
|
|
51
34
|
protected get currentStore(): {
|
|
@@ -64,9 +47,9 @@ declare abstract class Controller {
|
|
|
64
47
|
protected get res(): CustomResponse;
|
|
65
48
|
}
|
|
66
49
|
export declare abstract class ControllerService extends Controller implements IService<any> {
|
|
67
|
-
|
|
68
|
-
constructor({ systemService }: {
|
|
50
|
+
constructor({ systemService, loggerService }: {
|
|
69
51
|
systemService: SystemService;
|
|
52
|
+
loggerService: LoggerService;
|
|
70
53
|
});
|
|
71
54
|
load(): Promise<void>;
|
|
72
55
|
schema({ checks, logic, response }: {
|
|
@@ -75,4 +58,20 @@ export declare abstract class ControllerService extends Controller implements IS
|
|
|
75
58
|
response?: (args: any) => Promise<any>;
|
|
76
59
|
}): Promise<any>;
|
|
77
60
|
}
|
|
78
|
-
export
|
|
61
|
+
export interface CustomRequest {
|
|
62
|
+
accounts?: any;
|
|
63
|
+
url: string;
|
|
64
|
+
method: string;
|
|
65
|
+
headers: Record<string, any>;
|
|
66
|
+
body?: any;
|
|
67
|
+
params: Record<string, any>;
|
|
68
|
+
query: Record<string, any>;
|
|
69
|
+
lang: string;
|
|
70
|
+
t: (k: string, args?: any) => string;
|
|
71
|
+
}
|
|
72
|
+
export interface CustomResponse {
|
|
73
|
+
status: (code: number) => CustomResponse;
|
|
74
|
+
send: (data: any) => any;
|
|
75
|
+
json: (data: any) => any;
|
|
76
|
+
locals: Record<string, any>;
|
|
77
|
+
}
|
|
@@ -1,17 +1,10 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
-
import { ProtocolEnum, responseMessageHelper, ResponseSchema
|
|
3
|
-
import LoggerService from '../logger';
|
|
2
|
+
import { LoggerLayerEnum, ProtocolEnum, responseMessageHelper, ResponseSchema } from '../../utils/index';
|
|
4
3
|
export const controllerContextStorage = new AsyncLocalStorage();
|
|
5
4
|
export const getControllerCtx = () => controllerContextStorage.getStore();
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
store.protocol = protocol;
|
|
10
|
-
}
|
|
11
|
-
return await callback();
|
|
12
|
-
};
|
|
13
|
-
class Controller {
|
|
14
|
-
logger = x.get(LoggerService);
|
|
5
|
+
export class Controller {
|
|
6
|
+
logger;
|
|
7
|
+
systemService;
|
|
15
8
|
supportedProtocols = [ProtocolEnum.HTTP, ProtocolEnum.WEBSOCKET];
|
|
16
9
|
get protocol() {
|
|
17
10
|
return this.currentStore?.protocol || ProtocolEnum.HTTP;
|
|
@@ -79,14 +72,14 @@ class Controller {
|
|
|
79
72
|
}
|
|
80
73
|
}
|
|
81
74
|
export class ControllerService extends Controller {
|
|
82
|
-
systemService
|
|
83
|
-
constructor({ systemService }) {
|
|
75
|
+
constructor({ systemService, loggerService }) {
|
|
84
76
|
super();
|
|
85
77
|
this.systemService = systemService;
|
|
78
|
+
this.logger = loggerService;
|
|
86
79
|
}
|
|
87
80
|
async load() {
|
|
88
|
-
const protocols = this.systemService
|
|
89
|
-
this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols];
|
|
81
|
+
const protocols = this.systemService?.tmp?.configs?.loaders?.controller?.protocols;
|
|
82
|
+
this.supportedProtocols = Array.isArray(protocols) ? protocols : [protocols || ProtocolEnum.HTTP];
|
|
90
83
|
}
|
|
91
84
|
async schema({ checks, logic, response }) {
|
|
92
85
|
try {
|
|
@@ -153,10 +146,7 @@ export class ControllerService extends Controller {
|
|
|
153
146
|
}).getResponse);
|
|
154
147
|
}
|
|
155
148
|
catch (error) {
|
|
156
|
-
this.logger
|
|
157
|
-
level: 'error',
|
|
158
|
-
message: `Controller Error: ${error.message}`
|
|
159
|
-
});
|
|
149
|
+
this.logger?.log(LoggerLayerEnum.ERROR, `Controller Error: ${error.message}`);
|
|
160
150
|
return this.res.status(500).send(new ResponseSchema({
|
|
161
151
|
status: false,
|
|
162
152
|
message: error.message,
|
|
@@ -165,4 +155,3 @@ export class ControllerService extends Controller {
|
|
|
165
155
|
}
|
|
166
156
|
}
|
|
167
157
|
}
|
|
168
|
-
export { Controller };
|
|
@@ -43,10 +43,10 @@ export default class LoggerService {
|
|
|
43
43
|
constructor({ systemService, configsService }) {
|
|
44
44
|
this.#systemService = systemService;
|
|
45
45
|
this.#configsService = configsService;
|
|
46
|
-
this.serviceName = this.#systemService?.tmp?.configs?.service;
|
|
47
|
-
this.kafkaLogsTopic = this.#configsService?.all?.kafkaLogsTopic;
|
|
48
46
|
}
|
|
49
47
|
load = async () => {
|
|
48
|
+
this.serviceName = this.#systemService?.tmp?.configs?.service;
|
|
49
|
+
this.kafkaLogsTopic = this.#configsService?.all?.kafkaLogsTopic;
|
|
50
50
|
winston.addColors(customColors);
|
|
51
51
|
this.winston = winston.createLogger({
|
|
52
52
|
level: this.#configsService?.all?.systemLoggerLayer || 'info',
|
|
@@ -7,8 +7,8 @@ export default class SystemService {
|
|
|
7
7
|
load = async ({ core }) => {
|
|
8
8
|
this._core = core;
|
|
9
9
|
this._tmp = this._core._;
|
|
10
|
-
await this.initializeKafkaInfrastructure();
|
|
11
10
|
await this._systemLoader({});
|
|
11
|
+
await this.initializeKafkaInfrastructure();
|
|
12
12
|
};
|
|
13
13
|
initializeKafkaInfrastructure = async () => {
|
|
14
14
|
const { kafkaBrokers, kafkaTopics, isKafkaPassive, serviceName } = {
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { AwilixContainer, LifetimeType } from 'awilix';
|
|
2
|
+
export declare const xSymbol: unique symbol;
|
|
2
3
|
type Constructor<T> = new (...args: any[]) => T;
|
|
3
4
|
type AbstractConstructor<T> = abstract new (...args: any[]) => T;
|
|
4
|
-
declare abstract class
|
|
5
|
+
declare abstract class X {
|
|
5
6
|
protected checkRegistration(container: AwilixContainer, name: string): boolean;
|
|
6
7
|
}
|
|
7
|
-
declare class
|
|
8
|
+
declare class DIM extends X {
|
|
8
9
|
private container;
|
|
9
10
|
private initializedNames;
|
|
10
11
|
private loadedPaths;
|
|
11
12
|
private registeredClasses;
|
|
12
13
|
private isInitializing;
|
|
13
14
|
constructor();
|
|
15
|
+
private getName;
|
|
14
16
|
load(patterns: string | string[], options?: {
|
|
15
17
|
verbose?: boolean;
|
|
16
18
|
exclude?: string | Function | (string | Function)[];
|
|
@@ -29,5 +31,5 @@ declare class X extends XHelper {
|
|
|
29
31
|
shutdown(): Promise<void>;
|
|
30
32
|
get cradle(): any;
|
|
31
33
|
}
|
|
32
|
-
declare const _default:
|
|
34
|
+
declare const _default: DIM;
|
|
33
35
|
export default _default;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createContainer, asClass, asValue, InjectionMode, listModules, Lifetime } from 'awilix';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { pathToFileURL } from 'node:url';
|
|
4
|
-
|
|
4
|
+
export const xSymbol = Symbol.for('@xrystal/core/di-container');
|
|
5
|
+
class X {
|
|
5
6
|
checkRegistration(container, name) {
|
|
6
7
|
return !!container.registrations[name];
|
|
7
8
|
}
|
|
8
9
|
}
|
|
9
|
-
class
|
|
10
|
+
class DIM extends X {
|
|
10
11
|
container;
|
|
11
12
|
initializedNames = new Set();
|
|
12
13
|
loadedPaths = new Set();
|
|
@@ -19,10 +20,16 @@ class X extends XHelper {
|
|
|
19
20
|
strict: true
|
|
20
21
|
});
|
|
21
22
|
}
|
|
23
|
+
getName(target) {
|
|
24
|
+
if (typeof target === 'string')
|
|
25
|
+
return target.charAt(0).toLowerCase() + target.slice(1);
|
|
26
|
+
if (typeof target === 'function' && target.name)
|
|
27
|
+
return target.name.charAt(0).toLowerCase() + target.name.slice(1);
|
|
28
|
+
return '';
|
|
29
|
+
}
|
|
22
30
|
async load(patterns, options = {}) {
|
|
23
31
|
const { verbose = false, exclude = [], lifetime = Lifetime.SINGLETON } = options;
|
|
24
32
|
const cwd = process.cwd();
|
|
25
|
-
const excludeList = Array.isArray(exclude) ? exclude : [exclude];
|
|
26
33
|
const resolvedPatterns = (Array.isArray(patterns) ? patterns : [patterns]).map(p => {
|
|
27
34
|
const resolved = path.isAbsolute(p) ? p : path.resolve(cwd, p);
|
|
28
35
|
return resolved.replace(/\\/g, '/').toLowerCase();
|
|
@@ -50,10 +57,10 @@ class X extends XHelper {
|
|
|
50
57
|
if (typeof dependency === 'function' && !!dependency.prototype && !!dependency.name) {
|
|
51
58
|
if (this.registeredClasses.has(dependency))
|
|
52
59
|
continue;
|
|
53
|
-
const name =
|
|
54
|
-
if (!this.checkRegistration(this.container, name)) {
|
|
60
|
+
const name = this.getName(dependency);
|
|
61
|
+
if (name && !this.checkRegistration(this.container, name)) {
|
|
55
62
|
this.container.register({
|
|
56
|
-
[name]: asClass(dependency).
|
|
63
|
+
[name]: asClass(dependency).setLifetime(lifetime)
|
|
57
64
|
});
|
|
58
65
|
this.loadedPaths.add(normalizedMPath);
|
|
59
66
|
this.registeredClasses.add(dependency);
|
|
@@ -68,19 +75,19 @@ class X extends XHelper {
|
|
|
68
75
|
return this;
|
|
69
76
|
}
|
|
70
77
|
register(Dependency, lifetime = Lifetime.SINGLETON) {
|
|
71
|
-
|
|
78
|
+
const name = this.getName(Dependency);
|
|
79
|
+
if (!name || this.registeredClasses.has(Dependency))
|
|
72
80
|
return this;
|
|
73
|
-
const name = Dependency.name.charAt(0).toLowerCase() + Dependency.name.slice(1);
|
|
74
81
|
if (this.checkRegistration(this.container, name))
|
|
75
82
|
return this;
|
|
76
|
-
this.container.register({ [name]: asClass(Dependency).
|
|
83
|
+
this.container.register({ [name]: asClass(Dependency).setLifetime(lifetime) });
|
|
77
84
|
this.registeredClasses.add(Dependency);
|
|
78
85
|
return this;
|
|
79
86
|
}
|
|
80
87
|
registerInstance(name, instance) {
|
|
81
88
|
if (!name)
|
|
82
89
|
return this;
|
|
83
|
-
const formattedName =
|
|
90
|
+
const formattedName = this.getName(name);
|
|
84
91
|
this.container.register({ [formattedName]: asValue(instance) });
|
|
85
92
|
return this;
|
|
86
93
|
}
|
|
@@ -89,34 +96,55 @@ class X extends XHelper {
|
|
|
89
96
|
return this;
|
|
90
97
|
this.isInitializing = true;
|
|
91
98
|
try {
|
|
92
|
-
const cradle = this.container.cradle;
|
|
93
99
|
const inputList = input ? (Array.isArray(input) ? input : [input]) : [];
|
|
94
|
-
const propsMap = new Map();
|
|
95
100
|
for (const item of inputList) {
|
|
96
|
-
|
|
101
|
+
const name = this.getName(item.service);
|
|
102
|
+
if (!name || this.initializedNames.has(name))
|
|
103
|
+
continue;
|
|
104
|
+
const reg = this.container.registrations[name];
|
|
105
|
+
if (!reg || reg.lifetime !== Lifetime.SINGLETON)
|
|
97
106
|
continue;
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
try {
|
|
108
|
+
const instance = this.container.cradle[name];
|
|
109
|
+
if (instance && typeof instance.load === 'function') {
|
|
110
|
+
await instance.load(item.props || {});
|
|
111
|
+
}
|
|
112
|
+
this.initializedNames.add(name);
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
if (verbose)
|
|
116
|
+
console.error(`[DI] Priority Init Failed (${name}):`, err.message);
|
|
117
|
+
}
|
|
101
118
|
}
|
|
102
|
-
const
|
|
103
|
-
for (const key of
|
|
119
|
+
const allKeys = Object.keys(this.container.registrations);
|
|
120
|
+
for (const key of allKeys) {
|
|
104
121
|
if (this.initializedNames.has(key))
|
|
105
122
|
continue;
|
|
106
123
|
const reg = this.container.registrations[key];
|
|
107
124
|
if (reg.lifetime !== Lifetime.SINGLETON)
|
|
108
125
|
continue;
|
|
109
126
|
try {
|
|
110
|
-
const instance = cradle[key];
|
|
127
|
+
const instance = this.container.cradle[key];
|
|
111
128
|
if (instance && typeof instance.load === 'function') {
|
|
112
|
-
|
|
113
|
-
await instance.load(props);
|
|
129
|
+
await instance.load({});
|
|
114
130
|
}
|
|
115
131
|
this.initializedNames.add(key);
|
|
116
132
|
}
|
|
117
133
|
catch (err) {
|
|
118
134
|
if (verbose)
|
|
119
|
-
console.error(`[DI] Init Failed (${key}):`, err.message);
|
|
135
|
+
console.error(`[DI] Auto Init Failed (${key}):`, err.message);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (const name of this.initializedNames) {
|
|
139
|
+
try {
|
|
140
|
+
const instance = this.container.cradle[name];
|
|
141
|
+
if (instance && typeof instance.ready === 'function') {
|
|
142
|
+
await instance.afterInit();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
if (verbose)
|
|
147
|
+
console.error(`[DI] afterInit Hook Failed (${name}):`, err.message);
|
|
120
148
|
}
|
|
121
149
|
}
|
|
122
150
|
}
|
|
@@ -126,9 +154,7 @@ class X extends XHelper {
|
|
|
126
154
|
return this;
|
|
127
155
|
}
|
|
128
156
|
get(target) {
|
|
129
|
-
const resolveName =
|
|
130
|
-
? target.name.charAt(0).toLowerCase() + target.name.slice(1)
|
|
131
|
-
: target;
|
|
157
|
+
const resolveName = this.getName(target);
|
|
132
158
|
return this.container.resolve(resolveName);
|
|
133
159
|
}
|
|
134
160
|
async shutdown() {
|
|
@@ -136,9 +162,7 @@ class X extends XHelper {
|
|
|
136
162
|
}
|
|
137
163
|
get cradle() { return this.container.cradle; }
|
|
138
164
|
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
if (!globalObj[X_SYMBOL]) {
|
|
142
|
-
globalObj[X_SYMBOL] = new X();
|
|
165
|
+
if (!global[xSymbol]) {
|
|
166
|
+
global[xSymbol] = new DIM();
|
|
143
167
|
}
|
|
144
|
-
export default
|
|
168
|
+
export default global[xSymbol];
|