@clairejs/client 3.2.33 → 3.3.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/.mocharc.json +3 -0
- package/README.md +4 -0
- package/dist/api/AbstractHttpClient.d.ts +0 -1
- package/dist/api/AbstractHttpClient.js +21 -0
- package/dist/api/AbstractTokenManager.d.ts +0 -1
- package/dist/api/AbstractTokenManager.js +2 -0
- package/dist/api/CrudApi.d.ts +1 -2
- package/dist/api/CrudApi.js +109 -0
- package/dist/api/DefaultHttpClient.d.ts +1 -2
- package/dist/api/DefaultHttpClient.js +134 -0
- package/dist/api/DefaultTokenManager.d.ts +0 -1
- package/dist/api/DefaultTokenManager.js +42 -0
- package/dist/api/RefreshHttpClient.d.ts +0 -1
- package/dist/api/RefreshHttpClient.js +99 -0
- package/dist/constants.d.ts +0 -1
- package/dist/constants.js +2 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.js +17 -2
- package/dist/routing/AbstractErrorHandler.d.ts +0 -1
- package/dist/routing/AbstractErrorHandler.js +2 -0
- package/dist/routing/AbstractViewMiddleware.d.ts +0 -1
- package/dist/routing/AbstractViewMiddleware.js +2 -0
- package/dist/routing/ComponentInfo.d.ts +0 -1
- package/dist/routing/ComponentInfo.js +1 -0
- package/dist/routing/RouterConfig.d.ts +0 -1
- package/dist/routing/RouterConfig.js +1 -0
- package/dist/routing/UrlInfo.d.ts +0 -1
- package/dist/routing/UrlInfo.js +1 -0
- package/dist/socket/AbstractClientSocketManager.d.ts +0 -1
- package/dist/socket/AbstractClientSocketManager.js +2 -0
- package/dist/socket/DefaultClientSocket.d.ts +0 -1
- package/dist/socket/DefaultClientSocket.js +27 -0
- package/dist/socket/DefaultClientSocketManager.d.ts +0 -1
- package/dist/socket/DefaultClientSocketManager.js +369 -0
- package/dist/socket/IWebSocket.d.ts +0 -1
- package/dist/socket/IWebSocket.js +1 -0
- package/dist/socket/SocketConfig.d.ts +0 -1
- package/dist/socket/SocketConfig.js +1 -0
- package/dist/system/AbstractStorage.d.ts +0 -1
- package/dist/system/AbstractStorage.js +2 -0
- package/dist/system/ClaireClient.d.ts +0 -1
- package/dist/system/ClaireClient.js +3 -0
- package/dist/translation/Translator.d.ts +3 -6
- package/dist/translation/Translator.js +103 -0
- package/package.json +9 -13
- package/tsconfig-build.json +3 -4
- package/dist/api/AbstractHttpClient.d.ts.map +0 -1
- package/dist/api/AbstractTokenManager.d.ts.map +0 -1
- package/dist/api/CrudApi.d.ts.map +0 -1
- package/dist/api/DefaultHttpClient.d.ts.map +0 -1
- package/dist/api/DefaultTokenManager.d.ts.map +0 -1
- package/dist/api/RefreshHttpClient.d.ts.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/routing/AbstractErrorHandler.d.ts.map +0 -1
- package/dist/routing/AbstractViewMiddleware.d.ts.map +0 -1
- package/dist/routing/ComponentInfo.d.ts.map +0 -1
- package/dist/routing/RouterConfig.d.ts.map +0 -1
- package/dist/routing/UrlInfo.d.ts.map +0 -1
- package/dist/socket/AbstractClientSocketManager.d.ts.map +0 -1
- package/dist/socket/DefaultClientSocket.d.ts.map +0 -1
- package/dist/socket/DefaultClientSocketManager.d.ts.map +0 -1
- package/dist/socket/IWebSocket.d.ts.map +0 -1
- package/dist/socket/SocketConfig.d.ts.map +0 -1
- package/dist/system/AbstractStorage.d.ts.map +0 -1
- package/dist/system/ClaireClient.d.ts.map +0 -1
- package/dist/translation/Translator.d.ts.map +0 -1
- package/webpack.config.js +0 -46
package/.mocharc.json
ADDED
package/README.md
CHANGED
|
@@ -12,4 +12,3 @@ export declare abstract class AbstractHttpClient {
|
|
|
12
12
|
abstract put<T = any, R = any>(url: string, body: R, headers?: object, options?: RequestOptions): Promise<T | undefined>;
|
|
13
13
|
abstract delete<T = any>(url: string, headers?: object, options?: RequestOptions): Promise<T | undefined>;
|
|
14
14
|
}
|
|
15
|
-
//# sourceMappingURL=AbstractHttpClient.d.ts.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class AbstractHttpClient {
|
|
2
|
+
issuedGetRequests = {};
|
|
3
|
+
/*
|
|
4
|
+
Keep track off all get request had been sent and allow decache (using regex pattern) those requests
|
|
5
|
+
so next request will not get from cache
|
|
6
|
+
*/
|
|
7
|
+
resetCache(pattern) {
|
|
8
|
+
const regex = new RegExp(pattern);
|
|
9
|
+
Object.keys(this.issuedGetRequests)
|
|
10
|
+
.filter((key) => key.match(regex))
|
|
11
|
+
.forEach((key) => (this.issuedGetRequests[key] = false));
|
|
12
|
+
}
|
|
13
|
+
//-- normally T will be returned or error will throw, but in case undefined is returned, that is because error handler
|
|
14
|
+
//-- has intercepted and decided to return nothing
|
|
15
|
+
async get(url, headers, options) {
|
|
16
|
+
const shouldUseCache = this.issuedGetRequests[url];
|
|
17
|
+
const result = await this.doGet(url, { ...headers, ...(shouldUseCache ? {} : { "cache-control": "no-cache" }) }, options);
|
|
18
|
+
this.issuedGetRequests[url] = true;
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
}
|
package/dist/api/CrudApi.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { AbstractModel, Constructor, CreateManyRequestBody, CreateManyResponseBo
|
|
|
2
2
|
import { AbstractHttpClient } from "./AbstractHttpClient";
|
|
3
3
|
export declare const stringifyQueries: (queries: Record<string, any>) => string;
|
|
4
4
|
export declare const removeInstances: <T extends Identifiable<string | number>>(target: T[], source: T[]) => T[];
|
|
5
|
-
export declare const mergeInstances: <T extends Identifiable<string | number>>(model: Constructor<T>, target: readonly T[], source: readonly DeepPartial<T>[] | undefined, syncTarget?: boolean
|
|
5
|
+
export declare const mergeInstances: <T extends Identifiable<string | number>>(model: Constructor<T>, target: readonly T[], source: readonly DeepPartial<T>[] | undefined, syncTarget?: boolean) => T[];
|
|
6
6
|
export declare class CrudApi<T extends AbstractModel> {
|
|
7
7
|
readonly model: Constructor<T>;
|
|
8
8
|
readonly httpClient: AbstractHttpClient;
|
|
@@ -15,4 +15,3 @@ export declare class CrudApi<T extends AbstractModel> {
|
|
|
15
15
|
createMany(body: CreateManyRequestBody<T>): Promise<CreateManyResponseBody<T> | undefined>;
|
|
16
16
|
updateRecords<K extends keyof T>(body: UpdateRecordsBody<T, K>, queries?: ReturningQueries): Promise<UpdateManyResponse<T> | undefined>;
|
|
17
17
|
}
|
|
18
|
-
//# sourceMappingURL=CrudApi.d.ts.map
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { deepMerge, getModelById, getObjectMetadata, uniqueReducer, } from "@clairejs/core";
|
|
2
|
+
export const stringifyQueries = (queries) => {
|
|
3
|
+
const keys = Object.keys(queries).filter((key) => queries[key] !== undefined);
|
|
4
|
+
return keys.reduce((collector, key) => collector + `&${encodeURIComponent(key)}=${encodeURIComponent(JSON.stringify(queries[key]))}`, "");
|
|
5
|
+
};
|
|
6
|
+
export const removeInstances = (target, source) => {
|
|
7
|
+
const result = target.slice();
|
|
8
|
+
for (const instance of source) {
|
|
9
|
+
const index = result.findIndex((i) => !!i.id && !!instance.id && i.id === instance.id);
|
|
10
|
+
if (index >= 0) {
|
|
11
|
+
result.splice(index, 1);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
};
|
|
16
|
+
export const mergeInstances = (model, target, source, syncTarget) => {
|
|
17
|
+
const result = (syncTarget ? target.filter((i) => (source || []).some((newI) => i.id && newI.id && i.id === newI.id)) : target).map((i) => ({ ...i }));
|
|
18
|
+
const metadata = getObjectMetadata(model);
|
|
19
|
+
for (const instance of source || []) {
|
|
20
|
+
const index = result.findIndex((i) => i.id && instance.id && i.id === instance.id);
|
|
21
|
+
if (index < 0) {
|
|
22
|
+
result.push(Object.assign(new model(), instance));
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const targetObj = result[index];
|
|
26
|
+
const sourceObject = instance;
|
|
27
|
+
const fields = Object.keys(targetObj)
|
|
28
|
+
.concat(Object.keys(instance))
|
|
29
|
+
.reduce(uniqueReducer, []);
|
|
30
|
+
for (const field of fields) {
|
|
31
|
+
//-- check if we are merging hasMany field
|
|
32
|
+
const fieldMeta = metadata?.fields.find((f) => f.name === field);
|
|
33
|
+
let mergeByModel = false;
|
|
34
|
+
if (fieldMeta?.hasMany) {
|
|
35
|
+
const targetModel = getModelById(fieldMeta.hasMany.relationDto.id);
|
|
36
|
+
if (targetModel) {
|
|
37
|
+
mergeByModel = true;
|
|
38
|
+
if (targetObj[field] === null || targetObj[field] === undefined) {
|
|
39
|
+
if (sourceObject[field] !== undefined) {
|
|
40
|
+
targetObj[field] = sourceObject[field];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
if (fieldMeta.hasMany.single) {
|
|
45
|
+
targetObj[field] = mergeInstances(targetModel, [targetObj[field]], [sourceObject[field]], true);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
targetObj[field] = mergeInstances(targetModel, targetObj[field], sourceObject[field], true);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!mergeByModel) {
|
|
54
|
+
if (typeof targetObj[field] === "object" &&
|
|
55
|
+
!Array.isArray(targetObj[field]) &&
|
|
56
|
+
targetObj[field] !== null) {
|
|
57
|
+
//-- call deep merge to merge object
|
|
58
|
+
deepMerge(targetObj[field], sourceObject[field]);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
//-- direct assign
|
|
62
|
+
if (sourceObject[field] !== undefined) {
|
|
63
|
+
targetObj[field] = sourceObject[field];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result;
|
|
71
|
+
};
|
|
72
|
+
export class CrudApi {
|
|
73
|
+
model;
|
|
74
|
+
httpClient;
|
|
75
|
+
dirty = true;
|
|
76
|
+
constructor(model, httpClient) {
|
|
77
|
+
this.model = model;
|
|
78
|
+
this.httpClient = httpClient;
|
|
79
|
+
}
|
|
80
|
+
getEndpointBaseUrl() {
|
|
81
|
+
return `/${this.model.name.toLowerCase()}`;
|
|
82
|
+
}
|
|
83
|
+
async getMany(queries, useCache = true) {
|
|
84
|
+
const noCache = !useCache || this.dirty;
|
|
85
|
+
const result = await this.httpClient.get(`${this.getEndpointBaseUrl()}?${stringifyQueries(queries || {})}`, noCache
|
|
86
|
+
? {
|
|
87
|
+
"cache-control": "no-cache",
|
|
88
|
+
}
|
|
89
|
+
: undefined);
|
|
90
|
+
this.dirty = false;
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
async updateMany(body, queries) {
|
|
94
|
+
this.dirty = true;
|
|
95
|
+
return await this.httpClient.put(`${this.getEndpointBaseUrl()}?${stringifyQueries(queries || {})}`, body);
|
|
96
|
+
}
|
|
97
|
+
async deleteMany(queries) {
|
|
98
|
+
this.dirty = true;
|
|
99
|
+
return await this.httpClient.delete(`${this.getEndpointBaseUrl()}?${stringifyQueries(queries || {})}`);
|
|
100
|
+
}
|
|
101
|
+
async createMany(body) {
|
|
102
|
+
this.dirty = true;
|
|
103
|
+
return await this.httpClient.post(`${this.getEndpointBaseUrl()}`, body);
|
|
104
|
+
}
|
|
105
|
+
async updateRecords(body, queries) {
|
|
106
|
+
this.dirty = true;
|
|
107
|
+
return await this.httpClient.put(`${this.getEndpointBaseUrl()}/records?${stringifyQueries(queries || {})}`, body);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
@@ -19,7 +19,7 @@ export declare class DefaultHttpClient extends AbstractHttpClient {
|
|
|
19
19
|
constructor(apiServerUrl: string, logger: AbstractLogger, maxRetryCount?: number, delayMsBetweenRetry?: number, storage?: AbstractStorage | undefined);
|
|
20
20
|
protected resolveUrl(url: string): Promise<string>;
|
|
21
21
|
protected getAuthorization(): Promise<string>;
|
|
22
|
-
protected errorHandler<T = any>(
|
|
22
|
+
protected errorHandler<T = any>(_operation: () => Promise<T>, err: any): Promise<T | undefined>;
|
|
23
23
|
protected retry<T = any>(apiCall: () => Promise<T>, retryCount?: number): Promise<T | undefined>;
|
|
24
24
|
protected performRequest<T = any>(data: RequestData): Promise<T | undefined>;
|
|
25
25
|
protected doGet<T = any>(url: string, headers?: object, options?: RequestOptions): Promise<T | undefined>;
|
|
@@ -27,4 +27,3 @@ export declare class DefaultHttpClient extends AbstractHttpClient {
|
|
|
27
27
|
put<T = any, R = any>(url: string, body: R, headers?: object, options?: RequestOptions): Promise<T | undefined>;
|
|
28
28
|
delete<T = any>(url: string, headers?: object, options?: RequestOptions): Promise<T | undefined>;
|
|
29
29
|
}
|
|
30
|
-
//# sourceMappingURL=DefaultHttpClient.d.ts.map
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { Errors } from "@clairejs/core";
|
|
3
|
+
import { AbstractHttpClient } from "./AbstractHttpClient";
|
|
4
|
+
export class DefaultHttpClient extends AbstractHttpClient {
|
|
5
|
+
apiServerUrl;
|
|
6
|
+
logger;
|
|
7
|
+
maxRetryCount;
|
|
8
|
+
delayMsBetweenRetry;
|
|
9
|
+
storage;
|
|
10
|
+
api = axios.create();
|
|
11
|
+
constructor(apiServerUrl, logger, maxRetryCount = 2, delayMsBetweenRetry = 200, storage) {
|
|
12
|
+
super();
|
|
13
|
+
this.apiServerUrl = apiServerUrl;
|
|
14
|
+
this.logger = logger;
|
|
15
|
+
this.maxRetryCount = maxRetryCount;
|
|
16
|
+
this.delayMsBetweenRetry = delayMsBetweenRetry;
|
|
17
|
+
this.storage = storage;
|
|
18
|
+
if (this.storage) {
|
|
19
|
+
//-- setup axios cache
|
|
20
|
+
this.api.interceptors.request.use(async (config) => {
|
|
21
|
+
if (config.method === "get") {
|
|
22
|
+
const cacheKey = config.url || "";
|
|
23
|
+
const cachedData = await this.storage.getItem(cacheKey);
|
|
24
|
+
if (cachedData) {
|
|
25
|
+
if (Date.now() < cachedData.expiration) {
|
|
26
|
+
return cachedData.data;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
await this.storage.deleteItem(cacheKey);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return config;
|
|
34
|
+
});
|
|
35
|
+
// add a response interceptor to cache response data
|
|
36
|
+
this.api.interceptors.response.use(async (response) => {
|
|
37
|
+
if (response.config.method === "get") {
|
|
38
|
+
const cacheKey = response.config.url || "";
|
|
39
|
+
const maxAgeMatch = response.headers["Cache-Control"]?.toString()?.match(/max-age=(\d+)/);
|
|
40
|
+
const maxAge = maxAgeMatch ? parseInt(maxAgeMatch[1]) : 0;
|
|
41
|
+
if (maxAge) {
|
|
42
|
+
const dataToCache = {
|
|
43
|
+
data: response.data,
|
|
44
|
+
expiration: Date.now() + maxAge * 1000,
|
|
45
|
+
};
|
|
46
|
+
await this.storage.setItem(cacheKey, dataToCache);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return response;
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async resolveUrl(url) {
|
|
54
|
+
return this.apiServerUrl + url;
|
|
55
|
+
}
|
|
56
|
+
async getAuthorization() {
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
async errorHandler(_operation, err) {
|
|
60
|
+
throw err;
|
|
61
|
+
}
|
|
62
|
+
async retry(apiCall, retryCount = 0) {
|
|
63
|
+
try {
|
|
64
|
+
return await apiCall();
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
//-- if error is 503 or has empty body then retry
|
|
68
|
+
if ((!err.response ||
|
|
69
|
+
err.response.status === 503 ||
|
|
70
|
+
err.response.data?.message === "Service Unavailable") &&
|
|
71
|
+
retryCount < this.maxRetryCount) {
|
|
72
|
+
this.logger.debug(`unknown error encountered, retrying request ${retryCount + 1}/${this.maxRetryCount} after ${this.delayMsBetweenRetry}ms`);
|
|
73
|
+
await new Promise((resolve) => setTimeout(resolve, this.delayMsBetweenRetry));
|
|
74
|
+
return await this.retry(apiCall, retryCount + 1);
|
|
75
|
+
}
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async performRequest(data) {
|
|
80
|
+
const finalUrl = await this.resolveUrl(data.url);
|
|
81
|
+
const operation = async () => {
|
|
82
|
+
const authHeader = !data.options?.noAuthorization ? { authorization: await this.getAuthorization() } : {};
|
|
83
|
+
const result = await this.api({
|
|
84
|
+
method: data.method,
|
|
85
|
+
url: finalUrl,
|
|
86
|
+
data: data.body,
|
|
87
|
+
headers: {
|
|
88
|
+
...data.headers,
|
|
89
|
+
...authHeader,
|
|
90
|
+
},
|
|
91
|
+
withCredentials: data.options?.withCredentials,
|
|
92
|
+
});
|
|
93
|
+
return result.data;
|
|
94
|
+
};
|
|
95
|
+
try {
|
|
96
|
+
return await this.retry(operation);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
if (data.options?.noErrorHandling) {
|
|
100
|
+
throw err;
|
|
101
|
+
}
|
|
102
|
+
return await this.errorHandler(operation, err.response?.data || Errors.HTTP_REQUEST_ERROR());
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async doGet(url, headers, options) {
|
|
106
|
+
return await this.performRequest({ method: "GET", url, headers, options });
|
|
107
|
+
}
|
|
108
|
+
async post(url, body, headers, options) {
|
|
109
|
+
return await this.performRequest({
|
|
110
|
+
method: "POST",
|
|
111
|
+
url,
|
|
112
|
+
headers,
|
|
113
|
+
options,
|
|
114
|
+
body,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
async put(url, body, headers, options) {
|
|
118
|
+
return await this.performRequest({
|
|
119
|
+
method: "PUT",
|
|
120
|
+
url,
|
|
121
|
+
headers,
|
|
122
|
+
options,
|
|
123
|
+
body,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
async delete(url, headers, options) {
|
|
127
|
+
return await this.performRequest({
|
|
128
|
+
method: "DELETE",
|
|
129
|
+
url,
|
|
130
|
+
headers,
|
|
131
|
+
options,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
9
|
+
};
|
|
10
|
+
import { Injectable } from "@clairejs/core";
|
|
11
|
+
import { AbstractStorage } from "../system/AbstractStorage";
|
|
12
|
+
import { AbstractTokenManager } from "./AbstractTokenManager";
|
|
13
|
+
let DefaultTokenManager = class DefaultTokenManager extends AbstractTokenManager {
|
|
14
|
+
storage;
|
|
15
|
+
storageKey;
|
|
16
|
+
accessToken = null;
|
|
17
|
+
constructor(storage, storageKey = "ACCESS_TOKEN") {
|
|
18
|
+
super();
|
|
19
|
+
this.storage = storage;
|
|
20
|
+
this.storageKey = storageKey;
|
|
21
|
+
}
|
|
22
|
+
async getAccessToken() {
|
|
23
|
+
if (this.accessToken === null) {
|
|
24
|
+
this.accessToken = await this.storage.getItem(this.storageKey);
|
|
25
|
+
}
|
|
26
|
+
return this.accessToken;
|
|
27
|
+
}
|
|
28
|
+
async setAccessToken(token) {
|
|
29
|
+
if (token) {
|
|
30
|
+
await this.storage.setItem(this.storageKey, token);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
await this.storage.deleteItem(this.storageKey);
|
|
34
|
+
}
|
|
35
|
+
this.accessToken = token;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
DefaultTokenManager = __decorate([
|
|
39
|
+
Injectable(),
|
|
40
|
+
__metadata("design:paramtypes", [AbstractStorage, String])
|
|
41
|
+
], DefaultTokenManager);
|
|
42
|
+
export { DefaultTokenManager };
|
|
@@ -19,4 +19,3 @@ export declare class RefreshHttpClient extends DefaultHttpClient {
|
|
|
19
19
|
protected refreshToken(token?: AccessToken): Promise<void>;
|
|
20
20
|
protected errorHandler<T = any>(operation: () => Promise<T>, err: any): Promise<T | undefined>;
|
|
21
21
|
}
|
|
22
|
-
//# sourceMappingURL=RefreshHttpClient.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { Errors } from "@clairejs/core";
|
|
2
|
+
import { DefaultHttpClient } from "./DefaultHttpClient";
|
|
3
|
+
const tokenExpiredError = Errors.TOKEN_EXPIRED().name;
|
|
4
|
+
const invalidTokenError = Errors.INVALID_TOKEN().name;
|
|
5
|
+
export class RefreshHttpClient extends DefaultHttpClient {
|
|
6
|
+
apiServerUrl;
|
|
7
|
+
logger;
|
|
8
|
+
tokenManager;
|
|
9
|
+
maxRetryCount;
|
|
10
|
+
delayMsBetweenRetry;
|
|
11
|
+
storage;
|
|
12
|
+
refreshing = false;
|
|
13
|
+
refreshQueue = [];
|
|
14
|
+
tokenQueue = [];
|
|
15
|
+
constructor(apiServerUrl, logger, tokenManager, maxRetryCount = 2, delayMsBetweenRetry = 200, storage) {
|
|
16
|
+
super(apiServerUrl, logger, maxRetryCount, delayMsBetweenRetry, storage);
|
|
17
|
+
this.apiServerUrl = apiServerUrl;
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
this.tokenManager = tokenManager;
|
|
20
|
+
this.maxRetryCount = maxRetryCount;
|
|
21
|
+
this.delayMsBetweenRetry = delayMsBetweenRetry;
|
|
22
|
+
this.storage = storage;
|
|
23
|
+
}
|
|
24
|
+
async getRefreshedAccessToken() {
|
|
25
|
+
throw Errors.INVALID_TOKEN();
|
|
26
|
+
}
|
|
27
|
+
async reauthenticate() {
|
|
28
|
+
throw Errors.INVALID_CREDENTIALS();
|
|
29
|
+
}
|
|
30
|
+
async getAuthorization() {
|
|
31
|
+
if (this.refreshing) {
|
|
32
|
+
const promise = new Promise((resolver) => {
|
|
33
|
+
this.tokenQueue.push(resolver);
|
|
34
|
+
});
|
|
35
|
+
return promise;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
const accessToken = await this.tokenManager.getAccessToken();
|
|
39
|
+
return accessToken?.token || "";
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async refreshToken(token) {
|
|
43
|
+
if (this.refreshing) {
|
|
44
|
+
this.logger.debug("Awaiting refresh token, queued");
|
|
45
|
+
return await new Promise((resolver) => {
|
|
46
|
+
this.refreshQueue.push(resolver);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
token = token || (await this.tokenManager.getAccessToken());
|
|
50
|
+
//-- call to api server to refresh token
|
|
51
|
+
if (!token || !token.refreshToken) {
|
|
52
|
+
//-- there is no refresh token to refresh
|
|
53
|
+
return await this.reauthenticate();
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
this.refreshing = true;
|
|
57
|
+
token = await this.getRefreshedAccessToken();
|
|
58
|
+
await this.tokenManager.setAccessToken(token);
|
|
59
|
+
this.logger.debug("Access token was refreshed");
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
this.refreshing = false;
|
|
63
|
+
for (const resolver of this.refreshQueue) {
|
|
64
|
+
resolver();
|
|
65
|
+
}
|
|
66
|
+
for (const resolver of this.tokenQueue) {
|
|
67
|
+
resolver(token.token);
|
|
68
|
+
}
|
|
69
|
+
//-- clear queue
|
|
70
|
+
this.refreshQueue = [];
|
|
71
|
+
this.tokenQueue = [];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async errorHandler(operation, err) {
|
|
75
|
+
const errorName = err.name;
|
|
76
|
+
if (errorName === tokenExpiredError) {
|
|
77
|
+
return await this.refreshToken()
|
|
78
|
+
.catch(() => this.reauthenticate())
|
|
79
|
+
.catch(() => {
|
|
80
|
+
throw Errors.SESSION_EXPIRED();
|
|
81
|
+
})
|
|
82
|
+
.then(() => operation())
|
|
83
|
+
.catch((err) => {
|
|
84
|
+
throw err.response?.data || Errors.HTTP_REQUEST_ERROR();
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
else if (errorName === invalidTokenError) {
|
|
88
|
+
return await this.reauthenticate()
|
|
89
|
+
.catch(() => {
|
|
90
|
+
throw Errors.SESSION_EXPIRED();
|
|
91
|
+
})
|
|
92
|
+
.then(() => operation())
|
|
93
|
+
.catch((err) => {
|
|
94
|
+
throw err.response?.data || Errors.HTTP_REQUEST_ERROR();
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
throw err;
|
|
98
|
+
}
|
|
99
|
+
}
|
package/dist/constants.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,2 +1,17 @@
|
|
|
1
|
-
(()=>{"use strict";var e={560:function(e,t){var n=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractHttpClient=void 0;t.AbstractHttpClient=class AbstractHttpClient{constructor(){this.issuedGetRequests={}}resetCache(e){const t=new RegExp(e);Object.keys(this.issuedGetRequests).filter((e=>e.match(t))).forEach((e=>this.issuedGetRequests[e]=!1))}get(e,t,s){return n(this,void 0,void 0,(function*(){const n=this.issuedGetRequests[e],i=yield this.doGet(e,Object.assign(Object.assign({},t),n?{}:{"cache-control":"no-cache"}),s);return this.issuedGetRequests[e]=!0,i}))}}},805:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractTokenManager=void 0;t.AbstractTokenManager=class AbstractTokenManager{}},814:function(e,t,n){var s=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.CrudApi=t.mergeInstances=t.removeInstances=t.stringifyQueries=void 0;const i=n(318);t.stringifyQueries=e=>Object.keys(e).filter((t=>void 0!==e[t])).reduce(((t,n)=>t+`&${encodeURIComponent(n)}=${encodeURIComponent(JSON.stringify(e[n]))}`),"");t.removeInstances=(e,t)=>{const n=e.slice();for(const e of t){const t=n.findIndex((t=>!!t.id&&!!e.id&&t.id===e.id));t>=0&&n.splice(t,1)}return n};t.mergeInstances=(e,n,s,r)=>{const o=(r?n.filter((e=>(s||[]).some((t=>e.id&&t.id&&e.id===t.id)))):n).map((e=>Object.assign({},e))),a=(0,i.getObjectMetadata)(e);for(const n of s||[]){const s=o.findIndex((e=>e.id&&n.id&&e.id===n.id));if(s<0)o.push(Object.assign(new e,n));else{const e=o[s],r=n,c=Object.keys(e).concat(Object.keys(n)).reduce(i.uniqueReducer,[]);for(const n of c){const s=null==a?void 0:a.fields.find((e=>e.name===n));let o=!1;if(null==s?void 0:s.hasMany){const a=(0,i.getModelById)(s.hasMany.relationDto.id);a&&(o=!0,null===e[n]||void 0===e[n]?void 0!==r[n]&&(e[n]=r[n]):s.hasMany.single?e[n]=(0,t.mergeInstances)(a,[e[n]],[r[n]],!0):e[n]=(0,t.mergeInstances)(a,e[n],r[n],!0))}o||("object"!=typeof e[n]||Array.isArray(e[n])||null===e[n]?void 0!==r[n]&&(e[n]=r[n]):(0,i.deepMerge)(e[n],r[n]))}}}return o};t.CrudApi=class CrudApi{constructor(e,t){this.model=e,this.httpClient=t,this.dirty=!0}getEndpointBaseUrl(){return`/${this.model.name.toLowerCase()}`}getMany(e,n=!0){return s(this,void 0,void 0,(function*(){const s=!n||this.dirty,i=yield this.httpClient.get(`${this.getEndpointBaseUrl()}?${(0,t.stringifyQueries)(e||{})}`,s?{"cache-control":"no-cache"}:void 0);return this.dirty=!1,i}))}updateMany(e,n){return s(this,void 0,void 0,(function*(){return this.dirty=!0,yield this.httpClient.put(`${this.getEndpointBaseUrl()}?${(0,t.stringifyQueries)(n||{})}`,e)}))}deleteMany(e){return s(this,void 0,void 0,(function*(){return this.dirty=!0,yield this.httpClient.delete(`${this.getEndpointBaseUrl()}?${(0,t.stringifyQueries)(e||{})}`)}))}createMany(e){return s(this,void 0,void 0,(function*(){return this.dirty=!0,yield this.httpClient.post(`${this.getEndpointBaseUrl()}`,e)}))}updateRecords(e,n){return s(this,void 0,void 0,(function*(){return this.dirty=!0,yield this.httpClient.put(`${this.getEndpointBaseUrl()}/records?${(0,t.stringifyQueries)(n||{})}`,e)}))}}},854:function(e,t,n){var s=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))},i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.DefaultHttpClient=void 0;const r=i(n(167)),o=n(318),a=n(560);class DefaultHttpClient extends a.AbstractHttpClient{constructor(e,t,n=2,i=200,o){super(),this.apiServerUrl=e,this.logger=t,this.maxRetryCount=n,this.delayMsBetweenRetry=i,this.storage=o,this.api=r.default.create(),this.storage&&(this.api.interceptors.request.use((e=>s(this,void 0,void 0,(function*(){if("get"===e.method){const t=e.url||"",n=yield this.storage.getItem(t);if(n){if(Date.now()<n.expiration)return n.data;yield this.storage.deleteItem(t)}}return e})))),this.api.interceptors.response.use((e=>s(this,void 0,void 0,(function*(){var t,n;if("get"===e.config.method){const s=e.config.url||"",i=null===(n=null===(t=e.headers["Cache-Control"])||void 0===t?void 0:t.toString())||void 0===n?void 0:n.match(/max-age=(\d+)/),r=i?parseInt(i[1]):0;if(r){const t={data:e.data,expiration:Date.now()+1e3*r};yield this.storage.setItem(s,t)}}return e})))))}resolveUrl(e){return s(this,void 0,void 0,(function*(){return this.apiServerUrl+e}))}getAuthorization(){return s(this,void 0,void 0,(function*(){return""}))}errorHandler(e,t){return s(this,void 0,void 0,(function*(){throw t}))}retry(e,t=0){var n;return s(this,void 0,void 0,(function*(){try{return yield e()}catch(s){if((!s.response||503===s.response.status||"Service Unavailable"===(null===(n=s.response.data)||void 0===n?void 0:n.message))&&t<this.maxRetryCount)return this.logger.debug(`unknown error encountered, retrying request ${t+1}/${this.maxRetryCount} after ${this.delayMsBetweenRetry}ms`),yield new Promise((e=>setTimeout(e,this.delayMsBetweenRetry))),yield this.retry(e,t+1);throw s}}))}performRequest(e){var t,n;return s(this,void 0,void 0,(function*(){const i=yield this.resolveUrl(e.url),operation=()=>s(this,void 0,void 0,(function*(){var t,n;const s=(null===(t=e.options)||void 0===t?void 0:t.noAuthorization)?{}:{authorization:yield this.getAuthorization()};return(yield this.api({method:e.method,url:i,data:e.body,headers:Object.assign(Object.assign({},e.headers),s),withCredentials:null===(n=e.options)||void 0===n?void 0:n.withCredentials})).data}));try{return yield this.retry(operation)}catch(s){if(null===(t=e.options)||void 0===t?void 0:t.noErrorHandling)throw s;return yield this.errorHandler(operation,(null===(n=s.response)||void 0===n?void 0:n.data)||o.Errors.HTTP_REQUEST_ERROR())}}))}doGet(e,t,n){return s(this,void 0,void 0,(function*(){return yield this.performRequest({method:"GET",url:e,headers:t,options:n})}))}post(e,t,n,i){return s(this,void 0,void 0,(function*(){return yield this.performRequest({method:"POST",url:e,headers:n,options:i,body:t})}))}put(e,t,n,i){return s(this,void 0,void 0,(function*(){return yield this.performRequest({method:"PUT",url:e,headers:n,options:i,body:t})}))}delete(e,t,n){return s(this,void 0,void 0,(function*(){return yield this.performRequest({method:"DELETE",url:e,headers:t,options:n})}))}}t.DefaultHttpClient=DefaultHttpClient},375:function(e,t,n){var s=this&&this.__decorate||function(e,t,n,s){var i,r=arguments.length,o=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(o=(r<3?i(o):r>3?i(t,n,o):i(t,n))||o);return r>3&&o&&Object.defineProperty(t,n,o),o},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.DefaultTokenManager=void 0;const o=n(318),a=n(259),c=n(805);let l=class DefaultTokenManager extends c.AbstractTokenManager{constructor(e,t="ACCESS_TOKEN"){super(),this.storage=e,this.storageKey=t,this.accessToken=null}getAccessToken(){return r(this,void 0,void 0,(function*(){return null===this.accessToken&&(this.accessToken=yield this.storage.getItem(this.storageKey)),this.accessToken}))}setAccessToken(e){return r(this,void 0,void 0,(function*(){e?yield this.storage.setItem(this.storageKey,e):yield this.storage.deleteItem(this.storageKey),this.accessToken=e}))}};l=s([(0,o.Injectable)(),i("design:paramtypes",[a.AbstractStorage,String])],l),t.DefaultTokenManager=l},390:function(e,t,n){var s=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.RefreshHttpClient=void 0;const i=n(318),r=n(854),o=i.Errors.TOKEN_EXPIRED().name,a=i.Errors.INVALID_TOKEN().name;class RefreshHttpClient extends r.DefaultHttpClient{constructor(e,t,n,s=2,i=200,r){super(e,t,s,i,r),this.apiServerUrl=e,this.logger=t,this.tokenManager=n,this.maxRetryCount=s,this.delayMsBetweenRetry=i,this.storage=r,this.refreshing=!1,this.refreshQueue=[],this.tokenQueue=[]}getRefreshedAccessToken(){return s(this,void 0,void 0,(function*(){throw i.Errors.INVALID_TOKEN()}))}reauthenticate(){return s(this,void 0,void 0,(function*(){throw i.Errors.INVALID_CREDENTIALS()}))}getAuthorization(){return s(this,void 0,void 0,(function*(){if(this.refreshing){return new Promise((e=>{this.tokenQueue.push(e)}))}{const e=yield this.tokenManager.getAccessToken();return(null==e?void 0:e.token)||""}}))}refreshToken(e){return s(this,void 0,void 0,(function*(){if(this.refreshing)return this.logger.debug("Awaiting refresh token, queued"),yield new Promise((e=>{this.refreshQueue.push(e)}));if(!(e=e||(yield this.tokenManager.getAccessToken()))||!e.refreshToken)return yield this.reauthenticate();try{this.refreshing=!0,e=yield this.getRefreshedAccessToken(),yield this.tokenManager.setAccessToken(e),this.logger.debug("Access token was refreshed")}finally{this.refreshing=!1;for(const e of this.refreshQueue)e();for(const t of this.tokenQueue)t(e.token);this.refreshQueue=[],this.tokenQueue=[]}}))}errorHandler(e,t){return s(this,void 0,void 0,(function*(){const n=t.name;if(n===o)return yield this.refreshToken().catch((()=>this.reauthenticate())).catch((()=>{throw i.Errors.SESSION_EXPIRED()})).then((()=>e())).catch((e=>{var t;throw(null===(t=e.response)||void 0===t?void 0:t.data)||i.Errors.HTTP_REQUEST_ERROR()}));if(n===a)return yield this.reauthenticate().catch((()=>{throw i.Errors.SESSION_EXPIRED()})).then((()=>e())).catch((e=>{var t;throw(null===(t=e.response)||void 0===t?void 0:t.data)||i.Errors.HTTP_REQUEST_ERROR()}));throw t}))}}t.RefreshHttpClient=RefreshHttpClient},341:function(e,t,n){var s=this&&this.__createBinding||(Object.create?function(e,t,n,s){void 0===s&&(s=n);var i=Object.getOwnPropertyDescriptor(t,n);i&&!("get"in i?!t.__esModule:i.writable||i.configurable)||(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,s,i)}:function(e,t,n,s){void 0===s&&(s=n),e[s]=t[n]}),i=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||s(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),i(n(533),t),i(n(390),t),i(n(854),t),i(n(560),t),i(n(422),t),i(n(548),t),i(n(259),t),i(n(182),t),i(n(332),t),i(n(628),t),i(n(999),t),i(n(23),t),i(n(359),t),i(n(805),t),i(n(819),t),i(n(375),t),i(n(814),t)},332:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractErrorHandler=void 0;t.AbstractErrorHandler=class AbstractErrorHandler{}},628:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractViewMiddleware=void 0;t.AbstractViewMiddleware=class AbstractViewMiddleware{}},359:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},23:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},999:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},422:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractClientSocketManager=void 0;t.AbstractClientSocketManager=class AbstractClientSocketManager{}},38:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DefaultClientSocket=void 0;t.DefaultClientSocket=class DefaultClientSocket{constructor(e){this.socketManager=e}joinChannels(e){this.socketManager.subChannels(this,e)}leaveChannels(e){this.socketManager.unsubChannels(this,e)}close(){this.socketManager.removeSocket(this)}onReconnect(e){this.socketManager.registerReconnectionHandler(this,e)}onDisconnect(e){this.socketManager.registerDisconnectionHandler(this,e)}onMessage(e){this.socketManager.registerMessageHandler(this,e)}send(e,t){this.socketManager.sendPlainMessageToChannel(e,t)}}},548:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.DefaultClientSocketManager=void 0;const s=n(318),i=n(422),r=n(38);class DefaultClientSocketManager extends i.AbstractClientSocketManager{constructor(e,t,n){super(),this.wsProvider=e,this.logger=t,this.config=n,this.allSockets=[],this.allChannels=[],this.accumulatedPing=0,this.retryDelay=0,this.pingpongId=0,this.pingpong=[]}getPingMs(){const e=this.pingpong.filter((e=>e.sentTimestamp&&e.receivedTimestamp));return e.length?e.map((e=>e.receivedTimestamp-e.sentTimestamp)).reduce(((e,t)=>e+t),0)/e.length:0}subChannels(e,t){const n=this.allSockets.find((t=>t.socket===e));if(!n)return void this.logger.debug("Socket not found");const s=[];for(const e of t){n.registeredChannels.includes(e)||n.registeredChannels.push(e);const t=this.allChannels.find((t=>t.channel===e));t&&t.connected||s.push(e)}this.joinChannels(s)}unsubChannels(e,t){const n=this.allSockets.find((t=>t.socket===e));if(!n)return void this.logger.debug("Socket not found");n.registeredChannels=n.registeredChannels.filter((e=>!t.includes(e)));const s=[];for(const e of t)this.allSockets.find((t=>t.registeredChannels.includes(e)))||s.push(e);this.leaveChannels(s)}removeSocket(e){const t=this.allSockets.find((t=>t.socket===e));t&&t.disconnectionHandler&&t.disconnectionHandler(),this.allSockets=this.allSockets.filter((t=>t.socket!==e)),this.allSockets.length||this.forceDisconnect()}registerReconnectionHandler(e,t){const n=this.allSockets.find((t=>t.socket===e));n&&(n.reconnectionHandler=t)}registerDisconnectionHandler(e,t){const n=this.allSockets.find((t=>t.socket===e));n&&(n.disconnectionHandler=t)}registerMessageHandler(e,t){const n=this.allSockets.find((t=>t.socket===e));n&&(n.messageHandler=t)}sendPlainMessageToChannel(e,t){if(t){let n=this.allChannels.find((e=>e.channel===t));n||(n={channel:t,connected:!1,pendingMessages:[]},this.allChannels.push(n)),n.connected?this.sendRawMessage({type:s.MessageType.PLAIN,data:{channel:t,message:e}}):n.pendingMessages.push(e)}else this.sendRawMessage({type:s.MessageType.PLAIN,data:{message:e}})}joinChannels(e){if(e.length)if(this.socket&&this.socketConnected)this.sendRawMessage({type:s.MessageType.CHANNEL_JOIN,data:e});else for(const t of e){let e=this.allChannels.find((e=>e.channel===t));e||(e={channel:t,connected:!1,pendingMessages:[]},this.allChannels.push(e)),e.connected}}leaveChannels(e){e.length&&(this.handleChannelLeave(e),this.socket&&this.socketConnected&&this.sendRawMessage({type:s.MessageType.CHANNEL_LEAVE,data:e}))}sendPingPong(){this.pingpongId+=1,this.pingpongId%=100;const e={id:this.pingpongId,sentTimestamp:Date.now()};this.pingpong.push(e),this.pingpong.length>10&&this.pingpong.shift(),this.sendRawMessage({type:s.MessageType.PING_PONG,data:e.id})}sendRawMessage(e){if(!this.socket||!this.socketConnected)throw s.Errors.SYSTEM_ERROR("Socket not available");this.socket.send(e),this.logger.debug("Raw send",e)}handleChannelJoin(e){this.logger.debug("Joinning channels",e);for(const t of e){let e=this.allChannels.find((e=>e.channel===t));if(e||(e={channel:t,connected:!1,pendingMessages:[]},this.allChannels.push(e)),e.connected=!0,e.pendingMessages.length){this.logger.debug(`Flushing ${e.pendingMessages.length} message`);for(const t of e.pendingMessages)this.sendPlainMessageToChannel(t,e.channel);e.pendingMessages=[]}}}handleChannelLeave(e){this.logger.debug("Leaving channels",e),this.allChannels=this.allChannels.filter((t=>!e.includes(t.channel)))}handlePlainMessage(e,t){for(const n of this.allSockets)n.messageHandler&&n.messageHandler(e,t)}handleConnect(){var e,t;this.logger.debug("Socket connected"),this.pingIntervalId&&clearInterval(this.pingIntervalId),this.accumulatedPing=0,this.pingIntervalId=setInterval((()=>{var e,t,n;this.accumulatedPing+=1,this.accumulatedPing>((null===(t=null===(e=this.config)||void 0===e?void 0:e.keepAlive)||void 0===t?void 0:t.deadThreshold)||3)?(this.intendedDisconnection=!1,null===(n=this.socket)||void 0===n||n.close()):this.sendPingPong()}),(null===(t=null===(e=this.config)||void 0===e?void 0:e.keepAlive)||void 0===t?void 0:t.pingIntervalMs)||1e4),this.intendedDisconnection=!1,this.retryTimeoutId&&(clearTimeout(this.retryTimeoutId),this.retryTimeoutId=void 0);for(const e of this.allSockets)e.reconnectionHandler&&e.reconnectionHandler();const n=this.allChannels.filter((e=>!e.connected)).map((e=>e.channel));this.joinChannels(n)}handleDisconnect(e){e&&(this.intendedDisconnection=!0),this.logger.debug("Socket connnection closed, error: ",e),this.pingIntervalId&&clearInterval(this.pingIntervalId),this.socket=void 0,this.socketConnected=!1;for(const t of this.allSockets)t.disconnectionHandler&&t.disconnectionHandler(e);this.intendedDisconnection?(this.allSockets=[],this.allChannels=[],this.logger.debug("Socket connection terminated")):(this.allChannels=this.allChannels.map((e=>Object.assign(Object.assign({},e),{connected:!1}))),this.retryTimeoutId||(this.retryDelay=0,this.retry()))}handleMessage(e){var t;switch(this.logger.debug("Raw receive",e),e.type){case s.MessageType.READY:this.handleConnect();break;case s.MessageType.PING_PONG:this.accumulatedPing=0;const n=e.data;if(n){const e=this.pingpong.find((e=>e.id===n));e&&(e.receivedTimestamp=Date.now())}break;case s.MessageType.CHANNEL_JOIN:(null===(t=e.data)||void 0===t?void 0:t.error)?this.logger.error("Join channel error",e.data.error):this.handleChannelJoin(e.data);break;case s.MessageType.CHANNEL_LEAVE:this.handleChannelLeave(e.data);break;case s.MessageType.PLAIN:this.handlePlainMessage(e.data.message,e.data.channel)}}create(){const e=new r.DefaultClientSocket(this);return this.allSockets.push({socket:e,registeredChannels:[]}),1===this.allSockets.length&&this.forceReconnect(),e}forceDisconnect(){this.intendedDisconnection=!0,this.socket&&(this.socket.close(),this.socket=void 0),this.retryTimeoutId&&clearTimeout(this.retryTimeoutId)}forceReconnect(){var e;this.intendedDisconnection=!1,this.socketConnected?null===(e=this.socket)||void 0===e||e.close():(this.retryDelay=0,void 0===this.socket&&(this.retryTimeoutId&&(clearTimeout(this.retryTimeoutId),this.retryTimeoutId=void 0),this.physicConnect()))}physicConnect(){this.wsProvider().then((e=>{this.socket=e,this.socket.onopen((()=>{this.socketConnected=!0,this.logger.debug("Physic link connected, sending & waiting for READY message"),this.sendRawMessage({type:s.MessageType.READY,data:""})})),this.socket.onmessage((e=>{const t=JSON.parse(e);t&&t.type?this.handleMessage(t):this.logger.debug("Invalid mesasge structure",e)})),this.socket.onclose((e=>{this.handleDisconnect(e)}))}))}retry(){var e;this.logger.debug(`Socket connection retrying in ${this.retryDelay}ms`),this.physicConnect(),this.retryDelay+=(null===(e=this.config)||void 0===e?void 0:e.reconnectTimeDeltaMs)||3e3,this.retryTimeoutId=setTimeout((()=>{this.socketConnected||this.intendedDisconnection||this.retry()}),this.retryDelay)}}t.DefaultClientSocketManager=DefaultClientSocketManager},819:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},259:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.AbstractStorage=void 0;t.AbstractStorage=class AbstractStorage{}},533:(e,t,n)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.ClaireClient=void 0;const s=n(318);class ClaireClient extends s.ClaireApp{}t.ClaireClient=ClaireClient},182:function(e,t,n){var s=this&&this.__decorate||function(e,t,n,s){var i,r=arguments.length,o=r<3?t:null===s?s=Object.getOwnPropertyDescriptor(t,n):s;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,s);else for(var a=e.length-1;a>=0;a--)(i=e[a])&&(o=(r<3?i(o):r>3?i(t,n,o):i(t,n))||o);return r>3&&o&&Object.defineProperty(t,n,o),o},i=this&&this.__metadata||function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)},r=this&&this.__awaiter||function(e,t,n,s){return new(n||(n=Promise))((function(i,r){function fulfilled(e){try{step(s.next(e))}catch(e){r(e)}}function rejected(e){try{step(s.throw(e))}catch(e){r(e)}}function step(e){e.done?i(e.value):function adopt(e){return e instanceof n?e:new n((function(t){t(e)}))}(e.value).then(fulfilled,rejected)}step((s=s.apply(e,t||[])).next())}))};Object.defineProperty(t,"__esModule",{value:!0}),t.Translator=void 0;const o=n(318),a=/{([_a-zA-Z][a-zA-Z0-9_]*)}/g;let c=class Translator{constructor(e){this.logger=e,this.translations={},this.translationLoadings={}}setTranslations(e){const t=Object.keys(e);this.translationProviders=e;for(const e of t)this.translations[e]=null}awaitingTranslations(e){return r(this,void 0,void 0,(function*(){if(null!==this.translations[e])return Promise.resolve();if(this.translationLoadings[e]){let resolver=()=>{};const t=new Promise((e=>resolver=e));return this.translationLoadings[e].push(resolver),t}if(this.translationLoadings[e]=[],this.translationProviders&&this.translationProviders[e])try{const t=yield this.translationProviders[e];this.translations[e]=t.default}catch(t){this.logger.error("Error loading translation",t),this.translations[e]=void 0}else this.translations[e]=void 0;for(const t of this.translationLoadings[e]||[])t();this.translationLoadings[e]=[]}))}translate(e,t,n){if(!this.translationProviders||!this.translationProviders[e])return this.translateText(t,n);const s=this.translations[e];return s&&s[t]?this.translateText(s[t],n):this.translateText(t,n)}translateText(e,t){let n="";if(e){const s=e.matchAll(a);let i=0;for(const r of s){const s=r[1];n+=e.slice(i,r.index),t&&"string"==typeof t[s]?n+=t[s]:n+=r[0],i=(r.index||0)+r[0].length}i<e.length&&(n+=e.slice(i))}return n}};c=s([(0,o.Injectable)(),i("design:paramtypes",[o.AbstractLogger])],c),t.Translator=c},318:e=>{e.exports=require("@clairejs/core")},167:e=>{e.exports=require("axios")}},t={};var n=function __webpack_require__(n){var s=t[n];if(void 0!==s)return s.exports;var i=t[n]={exports:{}};return e[n].call(i.exports,i,i.exports,__webpack_require__),i.exports}(341),s=exports;for(var i in n)s[i]=n[i];n.__esModule&&Object.defineProperty(s,"__esModule",{value:!0})})();
|
|
2
|
-
|
|
1
|
+
export * from "./system/ClaireClient";
|
|
2
|
+
export * from "./api/RefreshHttpClient";
|
|
3
|
+
export * from "./api/DefaultHttpClient";
|
|
4
|
+
export * from "./api/AbstractHttpClient";
|
|
5
|
+
export * from "./socket/AbstractClientSocketManager";
|
|
6
|
+
export * from "./socket/DefaultClientSocketManager";
|
|
7
|
+
export * from "./system/AbstractStorage";
|
|
8
|
+
export * from "./translation/Translator";
|
|
9
|
+
export * from "./routing/AbstractErrorHandler";
|
|
10
|
+
export * from "./routing/AbstractViewMiddleware";
|
|
11
|
+
export * from "./routing/UrlInfo";
|
|
12
|
+
export * from "./routing/RouterConfig";
|
|
13
|
+
export * from "./routing/ComponentInfo";
|
|
14
|
+
export * from "./api/AbstractTokenManager";
|
|
15
|
+
export * from "./socket/IWebSocket";
|
|
16
|
+
export * from "./api/DefaultTokenManager";
|
|
17
|
+
export * from "./api/CrudApi";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|