@xrystal/core 3.8.3 → 3.8.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.
- package/package.json +1 -1
- package/source/loader/clients/index.d.ts +10 -0
- package/source/loader/clients/index.js +40 -0
- package/source/loader/configs/index.js +1 -0
- package/source/loader/events/index.d.ts +4 -1
- package/source/loader/events/index.js +3 -4
- package/source/project/index.d.ts +2 -2
- package/source/project/index.js +14 -4
- package/source/utils/models/classes/class.services.d.ts +25 -91
- package/source/utils/models/classes/class.services.js +86 -304
package/package.json
CHANGED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ApiClient } from '../../utils/index';
|
|
2
|
+
import ConfigsService from '../configs';
|
|
3
|
+
export default class ClientsService {
|
|
4
|
+
apiClient: ApiClient;
|
|
5
|
+
apiClientname: string;
|
|
6
|
+
load({ configs, tmp }: {
|
|
7
|
+
configs: ConfigsService;
|
|
8
|
+
tmp: any;
|
|
9
|
+
}): Promise<void>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { ApiClient, clientRegistry } from '../../utils/index';
|
|
3
|
+
export default class ClientsService {
|
|
4
|
+
apiClient;
|
|
5
|
+
apiClientname = 'base-api-client';
|
|
6
|
+
async load({ configs, tmp }) {
|
|
7
|
+
this.apiClient = new ApiClient({
|
|
8
|
+
clientName: this.apiClientname,
|
|
9
|
+
baseURL: configs.all.baseApiUri || ''
|
|
10
|
+
});
|
|
11
|
+
clientRegistry[this.apiClientname] = this.apiClient;
|
|
12
|
+
const loaderConfig = tmp?.configs?.loaders?.clients;
|
|
13
|
+
if (!loaderConfig)
|
|
14
|
+
return;
|
|
15
|
+
const { loadPath, list } = loaderConfig;
|
|
16
|
+
let serviceMap = {};
|
|
17
|
+
if (loadPath) {
|
|
18
|
+
try {
|
|
19
|
+
const resolvedPath = path.resolve(process.cwd(), loadPath);
|
|
20
|
+
serviceMap = await import(resolvedPath);
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
//
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
if (list) {
|
|
27
|
+
for (const [instanceName, className] of Object.entries(list)) {
|
|
28
|
+
const ServiceClass = serviceMap[className];
|
|
29
|
+
if (ServiceClass) {
|
|
30
|
+
clientRegistry[instanceName] = new ServiceClass({
|
|
31
|
+
clientName: instanceName,
|
|
32
|
+
baseURL: configs.all[`${instanceName}Uri`] || configs.all.baseApiUri || '',
|
|
33
|
+
version: configs.all[`${instanceName}Version`] || 'v1',
|
|
34
|
+
timeout: configs.all[`${instanceName}Timeout`] || 15000
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -12,6 +12,7 @@ export default class ConfigsService {
|
|
|
12
12
|
serviceName: rawConfigs.service,
|
|
13
13
|
port: process.env.PORT || rawConfigs.port || 3000,
|
|
14
14
|
systemStaticFolderPath: path.resolve(rawConfigs.rootFolderPath, this.publicFolderName),
|
|
15
|
+
baseApiUri: process.env.HTTPS === 'true' ? process.env.SYSTEM_HTTPS_BASE_API_URI : process.env.SYSTEM_BASE_API_URI,
|
|
15
16
|
env: process.env.NODE_ENV,
|
|
16
17
|
...rawConfigs
|
|
17
18
|
};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { x, LoggerLayerEnum } from '../../utils/index';
|
|
1
|
+
import { LoggerLayerEnum } from '../../utils/index';
|
|
3
2
|
export default class EventsService {
|
|
4
|
-
logger
|
|
5
|
-
load = ({}) => {
|
|
3
|
+
logger;
|
|
4
|
+
load = ({ logger, }) => {
|
|
6
5
|
this._globalLoader();
|
|
7
6
|
};
|
|
8
7
|
_globalLoader = () => {
|
package/source/project/index.js
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import { SystemService, ConfigsService, LoggerService, EventsService, LocalizationsService } from '../loader/index';
|
|
4
4
|
import { packageName, tmpFileDefaultName, tmpFileDefaultExt, findFileRecursively, TmpFileLoader, x, kafkaBrokers, systemLoggerLayer, } from '../utils/index';
|
|
5
|
+
import ClientsService from 'source/loader/clients';
|
|
5
6
|
//
|
|
6
7
|
let coreHasRun = false;
|
|
7
|
-
export const
|
|
8
|
-
|
|
8
|
+
export const coreInit = async (params) => {
|
|
9
|
+
const { locales } = params;
|
|
10
|
+
if (locales)
|
|
11
|
+
globalThis.__LOCAL_MESSAGES__ = locales;
|
|
9
12
|
};
|
|
10
13
|
const coreLoader = async ({}) => {
|
|
11
14
|
if (coreHasRun)
|
|
@@ -32,8 +35,9 @@ const coreLoader = async ({}) => {
|
|
|
32
35
|
const logger = x.get(LoggerService);
|
|
33
36
|
const events = x.get(EventsService);
|
|
34
37
|
const i18n = x.get(LocalizationsService);
|
|
38
|
+
const clientsService = x.get(ClientsService);
|
|
35
39
|
await system.load({
|
|
36
|
-
tmp:
|
|
40
|
+
tmp: r
|
|
37
41
|
});
|
|
38
42
|
configService.load({
|
|
39
43
|
tmp: r,
|
|
@@ -48,12 +52,18 @@ const coreLoader = async ({}) => {
|
|
|
48
52
|
kafkaBrokers: kafkaBrokers ?? "",
|
|
49
53
|
kafkaTopic: configs.loaders.loggers.topic
|
|
50
54
|
});
|
|
51
|
-
await events.load({
|
|
55
|
+
await events.load({
|
|
56
|
+
logger
|
|
57
|
+
});
|
|
52
58
|
await i18n.load({
|
|
53
59
|
loadPath: path.resolve(rootFolderPath, configs.loaders.localization.loadPath),
|
|
54
60
|
fallbackLang: configs.loaders.localization.fallbackLang,
|
|
55
61
|
preloadLang: configs.loaders.localization.preloadLangs
|
|
56
62
|
});
|
|
63
|
+
await clientsService.load({
|
|
64
|
+
configs: configService,
|
|
65
|
+
tmp: r,
|
|
66
|
+
});
|
|
57
67
|
coreHasRun = true;
|
|
58
68
|
return { _: r };
|
|
59
69
|
}
|
|
@@ -1,129 +1,63 @@
|
|
|
1
|
-
import { AxiosInstance } from 'axios';
|
|
2
1
|
import nodemailer from 'nodemailer';
|
|
3
|
-
import { LoggerService } from '
|
|
4
|
-
export
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
declare abstract class Service {
|
|
2
|
+
import { ConfigsService, LoggerService } from 'source/loader';
|
|
3
|
+
export declare const clientRegistry: Record<string, any>;
|
|
4
|
+
export declare abstract class Service {
|
|
5
|
+
protected configService: ConfigsService;
|
|
8
6
|
protected logger: LoggerService;
|
|
9
7
|
clientName: string;
|
|
10
8
|
protected baseURL: string;
|
|
11
9
|
protected version: string | null;
|
|
12
|
-
protected headers: any;
|
|
13
10
|
protected timeout: number;
|
|
14
|
-
|
|
15
|
-
* CONSTRUCTOR *
|
|
16
|
-
***************/
|
|
17
|
-
protected constructor({ clientName, baseURL, version, timeout, headers, }: {
|
|
11
|
+
constructor({ clientName, baseURL, version, timeout }: {
|
|
18
12
|
clientName: string;
|
|
19
13
|
baseURL: string;
|
|
20
14
|
version?: string;
|
|
21
15
|
timeout?: number;
|
|
22
|
-
headers?: {
|
|
23
|
-
'Content-Type'?: string;
|
|
24
|
-
'Lang'?: string;
|
|
25
|
-
'Authorization'?: string;
|
|
26
|
-
};
|
|
27
16
|
});
|
|
28
|
-
/***********
|
|
29
|
-
* HELPERS *
|
|
30
|
-
***********/
|
|
31
|
-
protected interceptorErrorComplement(error: any): void;
|
|
32
|
-
routeSlashChecker(route: string): string;
|
|
33
17
|
static cryptoHashGenerate: ({ algorithm, input, digest }: {
|
|
34
18
|
algorithm: string;
|
|
35
19
|
input: string;
|
|
36
20
|
digest?: string;
|
|
37
21
|
}) => string;
|
|
38
|
-
static
|
|
39
|
-
algorithm: string;
|
|
40
|
-
input: string;
|
|
41
|
-
keyEncoding?: string;
|
|
42
|
-
key: string;
|
|
43
|
-
initializationVector: string;
|
|
44
|
-
inputEncoding?: BufferEncoding;
|
|
45
|
-
outputEncoding?: BufferEncoding;
|
|
46
|
-
}) => string;
|
|
47
|
-
static objectToFormData: (object: any) => FormData;
|
|
48
|
-
static generateRandomNumber: ({ prefix, suffix, hyphen, length, totalLength }: {
|
|
49
|
-
prefix?: string;
|
|
50
|
-
suffix?: string;
|
|
51
|
-
hyphen?: boolean;
|
|
22
|
+
static generateRandomNumber: ({ length }: {
|
|
52
23
|
length?: number;
|
|
53
|
-
totalLength?: number | null;
|
|
54
24
|
}) => string;
|
|
55
25
|
}
|
|
56
|
-
export declare class
|
|
57
|
-
|
|
58
|
-
private _store;
|
|
59
|
-
private constructor();
|
|
60
|
-
static create(): ServiceStore;
|
|
61
|
-
set setStore(callback: (store: Record<any, any>) => any);
|
|
62
|
-
get instance(): Record<any, any> | null;
|
|
63
|
-
get store(): Record<any, any>;
|
|
64
|
-
}
|
|
65
|
-
export declare class EmailClient extends Service {
|
|
66
|
-
private _port;
|
|
67
|
-
private _username;
|
|
68
|
-
private _password;
|
|
69
|
-
constructor({ clientName, baseURL, version, port, username, password, }: {
|
|
26
|
+
export declare class ApiClient extends Service {
|
|
27
|
+
constructor(config: {
|
|
70
28
|
clientName: string;
|
|
71
29
|
baseURL: string;
|
|
72
30
|
version?: string;
|
|
73
|
-
|
|
74
|
-
username: string;
|
|
75
|
-
password: string;
|
|
31
|
+
timeout?: number;
|
|
76
32
|
});
|
|
77
|
-
|
|
78
|
-
* LOADERS *
|
|
79
|
-
***********/
|
|
80
|
-
nodemailerLoader({ host, port, username, password, secure, }: {
|
|
81
|
-
host?: string;
|
|
82
|
-
port?: number;
|
|
83
|
-
username?: string;
|
|
84
|
-
password?: string;
|
|
85
|
-
secure?: boolean;
|
|
86
|
-
}): nodemailer.Transporter<import("nodemailer/lib/smtp-transport").SentMessageInfo, import("nodemailer/lib/smtp-transport").Options>;
|
|
33
|
+
request(path: string, options?: RequestInit): Promise<Response>;
|
|
87
34
|
}
|
|
88
|
-
export declare class
|
|
89
|
-
|
|
35
|
+
export declare abstract class AuthenticatedApiClient extends ApiClient {
|
|
36
|
+
accessToken?: string;
|
|
37
|
+
constructor(config: {
|
|
90
38
|
clientName: string;
|
|
91
39
|
baseURL: string;
|
|
92
40
|
version?: string;
|
|
41
|
+
timeout?: number;
|
|
93
42
|
});
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
***********/
|
|
97
|
-
protected axiosLoader(): AxiosInstance;
|
|
43
|
+
request(path: string, options?: RequestInit): Promise<Response>;
|
|
44
|
+
abstract authentication(): Promise<any>;
|
|
98
45
|
}
|
|
99
|
-
export declare class
|
|
100
|
-
|
|
101
|
-
constructor({ clientName, baseURL, version }: {
|
|
46
|
+
export declare class EmailClient extends Service {
|
|
47
|
+
constructor(config: {
|
|
102
48
|
clientName: string;
|
|
103
49
|
baseURL: string;
|
|
104
50
|
version?: string;
|
|
51
|
+
timeout?: number;
|
|
105
52
|
});
|
|
106
|
-
|
|
107
|
-
[key: string]: any;
|
|
108
|
-
}>;
|
|
109
|
-
createAsyncClient({ fullURL }: {
|
|
110
|
-
fullURL: string;
|
|
111
|
-
}): Promise<{
|
|
112
|
-
[key: string]: any;
|
|
113
|
-
}>;
|
|
114
|
-
getAsyncMethod(methodName: string, pathname: string, args?: {
|
|
115
|
-
[key: string | number]: any;
|
|
116
|
-
}): Promise<{
|
|
117
|
-
[key: string]: any;
|
|
118
|
-
}>;
|
|
53
|
+
nodemailerLoader(config: any): nodemailer.Transporter<import("nodemailer/lib/smtp-transport").SentMessageInfo, import("nodemailer/lib/smtp-transport").Options>;
|
|
119
54
|
}
|
|
120
|
-
export declare class
|
|
121
|
-
constructor(
|
|
55
|
+
export declare class SoapClient extends Service {
|
|
56
|
+
constructor(config: {
|
|
122
57
|
clientName: string;
|
|
123
58
|
baseURL: string;
|
|
124
|
-
version
|
|
59
|
+
version?: string;
|
|
60
|
+
timeout?: number;
|
|
125
61
|
});
|
|
126
|
-
|
|
127
|
-
authentication: () => Promise<import("axios").AxiosResponse<any, any, {}>>;
|
|
62
|
+
call(methodName: string, args: any): Promise<any>;
|
|
128
63
|
}
|
|
129
|
-
export default Service;
|
|
@@ -1,344 +1,126 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import soap from 'soap';
|
|
4
|
-
// => special
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import path from 'node:path';
|
|
5
3
|
import nodemailer from 'nodemailer';
|
|
6
4
|
import hbs from 'nodemailer-express-handlebars';
|
|
7
|
-
|
|
8
|
-
import { LoggerService } from '
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
5
|
+
import soap from 'soap';
|
|
6
|
+
import { ConfigsService, LoggerService } from 'source/loader';
|
|
7
|
+
import { TokensEnum, x } from '..';
|
|
8
|
+
export const clientRegistry = {};
|
|
9
|
+
export class Service {
|
|
10
|
+
configService = x.get(ConfigsService);
|
|
13
11
|
logger = x.get(LoggerService);
|
|
14
|
-
//private _instance: Record<string, any> = {}
|
|
15
12
|
clientName;
|
|
16
13
|
baseURL;
|
|
17
14
|
version = null;
|
|
18
|
-
|
|
19
|
-
timeout
|
|
20
|
-
/***************
|
|
21
|
-
* CONSTRUCTOR *
|
|
22
|
-
***************/
|
|
23
|
-
constructor({ clientName, baseURL, version, timeout, headers, }) {
|
|
15
|
+
timeout = 15000;
|
|
16
|
+
constructor({ clientName, baseURL, version, timeout }) {
|
|
24
17
|
this.clientName = clientName;
|
|
25
18
|
this.baseURL = baseURL;
|
|
26
|
-
version
|
|
27
|
-
if (timeout)
|
|
19
|
+
this.version = version || null;
|
|
20
|
+
if (timeout)
|
|
28
21
|
this.timeout = timeout;
|
|
29
|
-
}
|
|
30
|
-
if (headers) {
|
|
31
|
-
this.headers = {
|
|
32
|
-
...headers
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/***********
|
|
37
|
-
* HELPERS *
|
|
38
|
-
***********/
|
|
39
|
-
interceptorErrorComplement(error /* unknow */) {
|
|
40
|
-
if (error.response) {
|
|
41
|
-
this.logger.winston.info({
|
|
42
|
-
level: LoggerLayerEnum[LoggerLayerEnum.ERROR].toLowerCase(),
|
|
43
|
-
message: `${this.clientName} api service error: ${JSON.stringify(error.response)}`,
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
this.logger.winston.info({
|
|
48
|
-
level: LoggerLayerEnum[LoggerLayerEnum.CRITICAL].toLowerCase(),
|
|
49
|
-
message: `${this.clientName} api service error: ${JSON.stringify(error.message)}`,
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
routeSlashChecker(route) {
|
|
54
|
-
const splash = route.split('/');
|
|
55
|
-
let withSplash;
|
|
56
|
-
if (splash[0] === '') {
|
|
57
|
-
withSplash = route.substring(1);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
withSplash = route;
|
|
61
|
-
}
|
|
62
|
-
return withSplash;
|
|
63
22
|
}
|
|
64
|
-
static cryptoHashGenerate = ({ algorithm, input, digest = '
|
|
65
|
-
return
|
|
66
|
-
};
|
|
67
|
-
static cryptoHashDecrypt = ({ algorithm, input, keyEncoding = 'hex', key, initializationVector, inputEncoding = 'base64', outputEncoding = 'utf8', }) => {
|
|
68
|
-
const decipher = crypto.createDecipheriv(algorithm, Buffer.from(key, keyEncoding), Buffer.from(initializationVector, inputEncoding));
|
|
69
|
-
let decrypted = decipher.update(input, inputEncoding, outputEncoding);
|
|
70
|
-
decrypted += decipher.final(outputEncoding);
|
|
71
|
-
return decrypted;
|
|
72
|
-
};
|
|
73
|
-
static objectToFormData = (object) => {
|
|
74
|
-
const formData = new FormData();
|
|
75
|
-
for (const [key, value] of Object.entries(object)) {
|
|
76
|
-
let changedValue = null;
|
|
77
|
-
changedValue = value;
|
|
78
|
-
if (Array.isArray(value)) {
|
|
79
|
-
changedValue = JSON.stringify(value);
|
|
80
|
-
}
|
|
81
|
-
formData.append(key, changedValue);
|
|
82
|
-
}
|
|
83
|
-
return formData;
|
|
23
|
+
static cryptoHashGenerate = ({ algorithm, input, digest = 'hex' }) => {
|
|
24
|
+
return createHash(algorithm).update(input).digest(digest);
|
|
84
25
|
};
|
|
85
|
-
static generateRandomNumber = ({
|
|
86
|
-
|
|
87
|
-
throw new Error(`Invalid length.`);
|
|
88
|
-
}
|
|
89
|
-
if (totalLength) {
|
|
90
|
-
const prefixLength = prefix ? Number(prefix?.length) : null;
|
|
91
|
-
const suffixLength = suffix ? Number(suffix?.length) : null;
|
|
92
|
-
if (prefixLength && !Number.isInteger(prefixLength) || length <= 0 ||
|
|
93
|
-
suffixLength && !Number.isInteger(suffixLength) || length <= 0) {
|
|
94
|
-
throw new Error(`Invalid type.`);
|
|
95
|
-
}
|
|
96
|
-
if (prefixLength) {
|
|
97
|
-
totalLength -= prefixLength + 1;
|
|
98
|
-
}
|
|
99
|
-
if (suffixLength) {
|
|
100
|
-
totalLength -= suffixLength + 1;
|
|
101
|
-
}
|
|
102
|
-
length = totalLength;
|
|
103
|
-
}
|
|
104
|
-
let randomNumber = '';
|
|
26
|
+
static generateRandomNumber = ({ length = 10 }) => {
|
|
27
|
+
let result = '';
|
|
105
28
|
for (let i = 0; i < length; i++) {
|
|
106
|
-
|
|
107
|
-
randomNumber += randomDigit.toString();
|
|
29
|
+
result += Math.floor(Math.random() * 10).toString();
|
|
108
30
|
}
|
|
109
|
-
return
|
|
31
|
+
return result;
|
|
110
32
|
};
|
|
111
33
|
}
|
|
112
|
-
export class
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
34
|
+
export class ApiClient extends Service {
|
|
35
|
+
constructor(config) {
|
|
36
|
+
super(config);
|
|
37
|
+
}
|
|
38
|
+
async request(path, options = {}) {
|
|
39
|
+
const base = this.baseURL.replace(/\/$/, '');
|
|
40
|
+
const ver = this.version ? `/${this.version.replace(/^\//, '')}` : '';
|
|
41
|
+
const url = `${base}${ver}${path}`;
|
|
42
|
+
const store = LoggerService.storage.getStore();
|
|
43
|
+
const correlationId = store?.get('correlationId');
|
|
44
|
+
const headers = new Headers(options.headers || {});
|
|
45
|
+
if (!headers.has('Content-Type'))
|
|
46
|
+
headers.set('Content-Type', 'application/json');
|
|
47
|
+
if (correlationId)
|
|
48
|
+
headers.set('x-correlation-id', correlationId);
|
|
49
|
+
if (process.env.INTERNAL_SECRET)
|
|
50
|
+
headers.set('X-Internal-Secret', process.env.INTERNAL_SECRET);
|
|
51
|
+
const controller = new AbortController();
|
|
52
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
53
|
+
try {
|
|
54
|
+
const response = await fetch(url, { ...options, headers, signal: controller.signal });
|
|
55
|
+
clearTimeout(timeoutId);
|
|
56
|
+
return response;
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
this.logger.winston.error(`${this.clientName} HTTP Request Failure: ${error.message}`, { url });
|
|
60
|
+
throw error;
|
|
119
61
|
}
|
|
120
|
-
return ServiceStore._instance;
|
|
121
|
-
}
|
|
122
|
-
set setStore(callback) {
|
|
123
|
-
const returnCallback = callback(this._store);
|
|
124
|
-
this._store = {
|
|
125
|
-
...this._store,
|
|
126
|
-
...returnCallback
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
get instance() {
|
|
130
|
-
return ServiceStore._instance;
|
|
131
62
|
}
|
|
132
|
-
|
|
133
|
-
|
|
63
|
+
}
|
|
64
|
+
export class AuthenticatedApiClient extends ApiClient {
|
|
65
|
+
accessToken;
|
|
66
|
+
constructor(config) {
|
|
67
|
+
super(config);
|
|
68
|
+
}
|
|
69
|
+
async request(path, options = {}) {
|
|
70
|
+
const injectToken = (h, t) => h.set('Cookie', `${TokensEnum.ACCESS_TOKEN}:${t}`);
|
|
71
|
+
const headers = new Headers(options.headers || {});
|
|
72
|
+
if (this.accessToken)
|
|
73
|
+
injectToken(headers, this.accessToken);
|
|
74
|
+
options.headers = headers;
|
|
75
|
+
let response = await super.request(path, options);
|
|
76
|
+
if (response.status === 401) {
|
|
77
|
+
await this.authentication();
|
|
78
|
+
if (this.accessToken) {
|
|
79
|
+
const retryHeaders = new Headers(options.headers);
|
|
80
|
+
injectToken(retryHeaders, this.accessToken);
|
|
81
|
+
return super.request(path, { ...options, headers: retryHeaders });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return response;
|
|
134
85
|
}
|
|
135
86
|
}
|
|
136
87
|
export class EmailClient extends Service {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
_password = null;
|
|
140
|
-
constructor({ clientName, baseURL, version, port, username, password, }) {
|
|
141
|
-
super({ clientName, baseURL, version });
|
|
142
|
-
this._username = username;
|
|
143
|
-
this._password = password;
|
|
88
|
+
constructor(config) {
|
|
89
|
+
super(config);
|
|
144
90
|
}
|
|
145
|
-
|
|
146
|
-
* LOADERS *
|
|
147
|
-
***********/
|
|
148
|
-
nodemailerLoader({ host, port, username, password, secure = true, }) {
|
|
91
|
+
nodemailerLoader(config) {
|
|
149
92
|
const transporter = nodemailer.createTransport({
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
auth: {
|
|
155
|
-
user: username ? username : this._username,
|
|
156
|
-
pass: password ? password : this._password,
|
|
157
|
-
},
|
|
93
|
+
host: config.host || this.baseURL,
|
|
94
|
+
port: config.port,
|
|
95
|
+
secure: config.secure ?? true,
|
|
96
|
+
auth: { user: config.username, pass: config.password }
|
|
158
97
|
});
|
|
98
|
+
const staticPath = this.configService.all.systemStaticFolderPath || 'source/statics';
|
|
159
99
|
transporter.use('compile', hbs({
|
|
160
100
|
viewEngine: {
|
|
161
101
|
extname: '.hbs',
|
|
162
|
-
layoutsDir: path.resolve(
|
|
163
|
-
defaultLayout: 'index'
|
|
164
|
-
partialsDir: path.resolve('source', 'static', 'email'),
|
|
102
|
+
layoutsDir: path.resolve(staticPath, 'email'),
|
|
103
|
+
defaultLayout: 'index'
|
|
165
104
|
},
|
|
166
|
-
viewPath: path.resolve(
|
|
105
|
+
viewPath: path.resolve(staticPath, 'email', 'templates'),
|
|
167
106
|
extName: '.hbs'
|
|
168
107
|
}));
|
|
169
108
|
return transporter;
|
|
170
109
|
}
|
|
171
110
|
}
|
|
172
|
-
export class AxiosClient extends Service {
|
|
173
|
-
constructor({ clientName, baseURL, version }) {
|
|
174
|
-
super({ clientName, baseURL, version });
|
|
175
|
-
}
|
|
176
|
-
/***********
|
|
177
|
-
* LOADERS *
|
|
178
|
-
***********/
|
|
179
|
-
axiosLoader() {
|
|
180
|
-
const axiosInstance = axios.create({
|
|
181
|
-
baseURL: this.baseURL,
|
|
182
|
-
timeout: this.timeout,
|
|
183
|
-
headers: {
|
|
184
|
-
...this.headers
|
|
185
|
-
},
|
|
186
|
-
});
|
|
187
|
-
axiosInstance.interceptors.request.use((config /* unknow */) => {
|
|
188
|
-
return config;
|
|
189
|
-
}, (error) => {
|
|
190
|
-
this.logger.winston.info({
|
|
191
|
-
level: LoggerLayerEnum[LoggerLayerEnum.CRITICAL].toLowerCase(),
|
|
192
|
-
message: `${this.clientName} api service error: ${JSON.stringify(error)}`,
|
|
193
|
-
});
|
|
194
|
-
return Promise.reject(error);
|
|
195
|
-
});
|
|
196
|
-
return axiosInstance;
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
111
|
export class SoapClient extends Service {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
super({ clientName, baseURL, version });
|
|
203
|
-
}
|
|
204
|
-
async getAsyncBaseClient() {
|
|
205
|
-
try {
|
|
206
|
-
this.client = await soap.createClientAsync(this.baseURL);
|
|
207
|
-
return this.client;
|
|
208
|
-
}
|
|
209
|
-
catch (exception) {
|
|
210
|
-
this.logger.winston.error({
|
|
211
|
-
level: LoggerLayerEnum[LoggerLayerEnum.ERROR].toLowerCase(),
|
|
212
|
-
message: `${this.clientName} - soap client error: ${exception}`,
|
|
213
|
-
});
|
|
214
|
-
return null;
|
|
215
|
-
}
|
|
112
|
+
constructor(config) {
|
|
113
|
+
super(config);
|
|
216
114
|
}
|
|
217
|
-
async
|
|
115
|
+
async call(methodName, args) {
|
|
218
116
|
try {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
return
|
|
222
|
-
}
|
|
223
|
-
catch (exception) {
|
|
224
|
-
this.logger.winston.error({
|
|
225
|
-
level: LoggerLayerEnum[LoggerLayerEnum.ERROR].toLowerCase(),
|
|
226
|
-
message: `${this.clientName} - soap client error: ${exception}`,
|
|
227
|
-
});
|
|
228
|
-
return null;
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
async getAsyncMethod(methodName, pathname, args) {
|
|
232
|
-
let client = null;
|
|
233
|
-
let result = null;
|
|
234
|
-
if (pathname) {
|
|
235
|
-
client = await this.createAsyncClient({ fullURL: `${this.baseURL}${pathname}` });
|
|
236
|
-
}
|
|
237
|
-
else {
|
|
238
|
-
client = await this.getAsyncBaseClient();
|
|
239
|
-
}
|
|
240
|
-
//console.log('client: ', client)
|
|
241
|
-
if (client) {
|
|
242
|
-
try {
|
|
243
|
-
let data = await client[`${methodName}Async`](args);
|
|
244
|
-
result = data[0];
|
|
245
|
-
}
|
|
246
|
-
catch (exception) {
|
|
247
|
-
this.logger.winston.error({
|
|
248
|
-
level: LoggerLayerEnum[LoggerLayerEnum.ERROR].toLowerCase(),
|
|
249
|
-
message: `${this.clientName} - soap client method error: ${exception}`,
|
|
250
|
-
});
|
|
251
|
-
return null;
|
|
252
|
-
}
|
|
117
|
+
const client = await soap.createClientAsync(this.baseURL);
|
|
118
|
+
const result = await client[`${methodName}Async`](args);
|
|
119
|
+
return result[0];
|
|
253
120
|
}
|
|
254
|
-
|
|
121
|
+
catch (error) {
|
|
122
|
+
this.logger.winston.error(`${this.clientName} SOAP Error: ${error.message}`);
|
|
255
123
|
return null;
|
|
256
124
|
}
|
|
257
|
-
return result;
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
export class BaseApiClient extends AxiosClient {
|
|
261
|
-
constructor({ clientName, baseURL, version }) {
|
|
262
|
-
super({
|
|
263
|
-
clientName,
|
|
264
|
-
baseURL,
|
|
265
|
-
version
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
axiosLoaderAuthMiddleware() {
|
|
269
|
-
const axiosInstance = this.axiosLoader();
|
|
270
|
-
let _retry = false;
|
|
271
|
-
axiosInstance.interceptors.request.use((config) => {
|
|
272
|
-
const accessToken = (ServiceStore.create()).store?.[this.clientName]?.accessToken;
|
|
273
|
-
if (accessToken) {
|
|
274
|
-
config.headers['Cookie'] = `${TokensEnum.ACCESS_TOKEN}:${accessToken}`;
|
|
275
|
-
}
|
|
276
|
-
return config;
|
|
277
|
-
}, (error) => {
|
|
278
|
-
return Promise.reject(error);
|
|
279
|
-
});
|
|
280
|
-
axiosInstance.interceptors.response.use(async (response) => {
|
|
281
|
-
const originalRequest = response.config;
|
|
282
|
-
if (!_retry && response.data?.success === false && response.data?.status_code === 101) {
|
|
283
|
-
this.logger.winston.info({
|
|
284
|
-
level: LoggerLayerEnum[LoggerLayerEnum.INFO].toLowerCase(),
|
|
285
|
-
message: `${this.clientName} client - token refreshed!`,
|
|
286
|
-
});
|
|
287
|
-
try {
|
|
288
|
-
await this.authentication();
|
|
289
|
-
_retry = true;
|
|
290
|
-
originalRequest.headers['Cookie'] = `${TokensEnum.ACCESS_TOKEN}:${(ServiceStore.create()).store?.[this.clientName]?.accessToken}`;
|
|
291
|
-
//console.log(originalConfig)
|
|
292
|
-
return axiosInstance(originalRequest);
|
|
293
|
-
}
|
|
294
|
-
catch (error) {
|
|
295
|
-
this.logger.winston.info({
|
|
296
|
-
level: LoggerLayerEnum[LoggerLayerEnum.INFO].toLowerCase(),
|
|
297
|
-
message: `${this.clientName} client - token refresh request not initial!`,
|
|
298
|
-
});
|
|
299
|
-
return Promise.reject(error);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
return response;
|
|
303
|
-
}, async (error) => {
|
|
304
|
-
const originalConfig = error.config;
|
|
305
|
-
if (error.response.status === 401 && !originalConfig._retry) {
|
|
306
|
-
this.logger.winston.info({
|
|
307
|
-
level: LoggerLayerEnum[LoggerLayerEnum.INFO].toLowerCase(),
|
|
308
|
-
message: `${this.clientName} client - token refreshed!`,
|
|
309
|
-
});
|
|
310
|
-
originalConfig._retry = true;
|
|
311
|
-
try {
|
|
312
|
-
await this.authentication();
|
|
313
|
-
const accessToken = (ServiceStore.create()).store?.[this.clientName]?.accessToken;
|
|
314
|
-
originalConfig.headers['Cookie'] = `${TokensEnum.ACCESS_TOKEN}:${accessToken}`;
|
|
315
|
-
//console.log(originalConfig)
|
|
316
|
-
return axiosInstance(originalConfig);
|
|
317
|
-
}
|
|
318
|
-
catch (error) {
|
|
319
|
-
this.logger.winston.info({
|
|
320
|
-
level: LoggerLayerEnum[LoggerLayerEnum.INFO].toLowerCase(),
|
|
321
|
-
message: `${this.clientName} client - token refresh request not initial!`,
|
|
322
|
-
});
|
|
323
|
-
return Promise.reject(error);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
return Promise.reject(error);
|
|
327
|
-
});
|
|
328
|
-
return axiosInstance;
|
|
329
125
|
}
|
|
330
|
-
authentication = async () => {
|
|
331
|
-
const response = await this.axiosLoader().post(`/${this.version}/auth/sign-in`, {});
|
|
332
|
-
if (response.data.success !== true) {
|
|
333
|
-
throw new Error('Authorization not implemented');
|
|
334
|
-
}
|
|
335
|
-
const servicesStore = ServiceStore.create();
|
|
336
|
-
servicesStore.setStore = ((prevState => ({
|
|
337
|
-
[this.clientName]: {
|
|
338
|
-
accessToken: response.data?.payload?.data?.token
|
|
339
|
-
}
|
|
340
|
-
})));
|
|
341
|
-
return response;
|
|
342
|
-
};
|
|
343
126
|
}
|
|
344
|
-
export default Service;
|