@zintrust/queue-monitor 0.4.48 → 0.4.50
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/dist/QueueMonitoringService.d.ts +5 -4
- package/dist/QueueMonitoringService.js +84 -72
- package/dist/api/workerClient.d.ts +20 -0
- package/dist/api/workerClient.js +45 -0
- package/dist/build-manifest.json +52 -8
- package/dist/config/queueMonitor.d.ts +18 -0
- package/dist/config/queueMonitor.js +21 -0
- package/dist/config/workerConfig.d.ts +3 -0
- package/dist/config/workerConfig.js +19 -0
- package/dist/dashboard-ui.js +143 -16
- package/dist/index.d.ts +1 -0
- package/dist/index.js +27 -6
- package/dist/metrics.d.ts +1 -0
- package/dist/routes/workers.d.ts +10 -0
- package/dist/routes/workers.js +20 -0
- package/dist/workers-ui.d.ts +7 -0
- package/dist/workers-ui.js +655 -0
- package/package.json +3 -3
|
@@ -2,6 +2,7 @@ import type { IRequest, IResponse } from '@zintrust/core';
|
|
|
2
2
|
import type { QueueDriver } from './driver';
|
|
3
3
|
import type { LockAnalytics, QueueMonitorSnapshot } from './index';
|
|
4
4
|
import type { JobSummary, Metrics } from './metrics';
|
|
5
|
+
export declare const ALL_QUEUES = "__all__";
|
|
5
6
|
type QueueSnapshotData = {
|
|
6
7
|
type: string;
|
|
7
8
|
ts: string;
|
|
@@ -20,11 +21,11 @@ type QueueMonitoringConfig = {
|
|
|
20
21
|
pattern: string;
|
|
21
22
|
intervalMs: number;
|
|
22
23
|
};
|
|
24
|
+
type QueueMonitoringCallback = (data: QueueSnapshotData) => void;
|
|
25
|
+
export declare function getRecentJobsForSelection(queueName: string, metrics: Metrics, driver: QueueDriver, queueNames?: ReadonlyArray<string>): Promise<JobSummary[]>;
|
|
23
26
|
export declare const QueueMonitoringService: Readonly<{
|
|
24
|
-
subscribe(callback:
|
|
25
|
-
unsubscribe(callback:
|
|
26
|
-
startPollingForClient(config: QueueMonitoringConfig): void;
|
|
27
|
-
stopPollingForClient(): void;
|
|
27
|
+
subscribe(callback: QueueMonitoringCallback, config: QueueMonitoringConfig): void;
|
|
28
|
+
unsubscribe(callback: QueueMonitoringCallback): void;
|
|
28
29
|
}>;
|
|
29
30
|
export declare const QueueMonitoringStream: (res: IResponse, req: IRequest, getSnapshot: () => Promise<QueueMonitorSnapshot>, getLocks: (pattern?: string) => Promise<LockAnalytics>, metrics: Metrics, driver: QueueDriver, settings: {
|
|
30
31
|
basePath: string;
|
|
@@ -1,80 +1,92 @@
|
|
|
1
|
-
import { Logger
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { Logger } from '@zintrust/core';
|
|
2
|
+
export const ALL_QUEUES = '__all__';
|
|
3
|
+
const subscriptions = new Map();
|
|
4
|
+
const isAllQueuesSelection = (queue) => queue === ALL_QUEUES;
|
|
5
|
+
const sortJobsByTimestamp = (jobs) => jobs.sort((left, right) => right.timestamp - left.timestamp);
|
|
6
|
+
export async function getRecentJobsForSelection(queueName, metrics, driver, queueNames) {
|
|
7
|
+
if (!isAllQueuesSelection(queueName)) {
|
|
8
|
+
return getRecentJobsForQueue(queueName, metrics, driver);
|
|
9
|
+
}
|
|
10
|
+
const names = Array.from(new Set((queueNames ?? (await driver.getQueues())).filter(Boolean)));
|
|
11
|
+
const jobsByQueue = await Promise.all(names.map(async (name) => getRecentJobsForQueue(name, metrics, driver)));
|
|
12
|
+
return sortJobsByTimestamp(jobsByQueue.flat()).slice(0, 100);
|
|
13
|
+
}
|
|
14
|
+
const buildSnapshotPayload = async (config) => {
|
|
15
|
+
const { getSnapshot, getLocks, metrics, driver, queue: configuredQueue, pattern } = config;
|
|
16
|
+
const snapshot = await getSnapshot();
|
|
17
|
+
let queue;
|
|
18
|
+
if (isAllQueuesSelection(configuredQueue)) {
|
|
19
|
+
queue = ALL_QUEUES;
|
|
20
|
+
}
|
|
21
|
+
else if (configuredQueue &&
|
|
22
|
+
snapshot.queues.some((candidate) => candidate.name === configuredQueue)) {
|
|
23
|
+
queue = configuredQueue;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
queue = snapshot.queues[0]?.name ?? null;
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
type: 'snapshot',
|
|
30
|
+
ts: new Date().toISOString(),
|
|
31
|
+
queue,
|
|
32
|
+
snapshot,
|
|
33
|
+
jobs: queue
|
|
34
|
+
? await getRecentJobsForSelection(queue, metrics, driver, snapshot.queues.map((candidate) => candidate.name))
|
|
35
|
+
: [],
|
|
36
|
+
locks: await getLocks(pattern),
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
const pushSnapshot = async (subscription) => {
|
|
9
40
|
try {
|
|
10
|
-
|
|
11
|
-
return;
|
|
12
|
-
const { getSnapshot, getLocks, metrics, driver, queue: initialQueue, pattern } = currentConfig;
|
|
13
|
-
const snapshot = await getSnapshot();
|
|
14
|
-
let queue = initialQueue;
|
|
15
|
-
if (!queue && snapshot.queues.length > 0) {
|
|
16
|
-
queue = snapshot.queues[0].name;
|
|
17
|
-
}
|
|
18
|
-
const jobs = queue ? await getRecentJobsForQueue(queue, metrics, driver) : [];
|
|
19
|
-
const locks = await getLocks(pattern);
|
|
20
|
-
const payload = {
|
|
21
|
-
type: 'snapshot',
|
|
22
|
-
ts: new Date().toISOString(),
|
|
23
|
-
queue: queue || null,
|
|
24
|
-
snapshot,
|
|
25
|
-
jobs,
|
|
26
|
-
locks,
|
|
27
|
-
};
|
|
28
|
-
emitter.emit('snapshot', payload);
|
|
41
|
+
subscription.callback(await buildSnapshotPayload(subscription.config));
|
|
29
42
|
}
|
|
30
43
|
catch (err) {
|
|
31
|
-
Logger.error('QueueMonitoringService.
|
|
32
|
-
if (emitter.listenerCount('error') > 0) {
|
|
33
|
-
emitter.emit('error', err);
|
|
34
|
-
}
|
|
44
|
+
Logger.error('QueueMonitoringService.pushSnapshot failed', err);
|
|
35
45
|
}
|
|
36
46
|
};
|
|
37
|
-
const startPolling = () => {
|
|
38
|
-
if (interval
|
|
47
|
+
const startPolling = (subscription) => {
|
|
48
|
+
if (subscription.interval)
|
|
39
49
|
return;
|
|
40
|
-
Logger.debug('Starting QueueMonitoringService polling'
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
Logger.debug('Starting QueueMonitoringService polling', {
|
|
51
|
+
queue: subscription.config.queue || null,
|
|
52
|
+
pattern: subscription.config.pattern,
|
|
53
|
+
});
|
|
54
|
+
void pushSnapshot(subscription);
|
|
55
|
+
subscription.interval = setInterval(() => {
|
|
56
|
+
void pushSnapshot(subscription);
|
|
57
|
+
}, subscription.config.intervalMs);
|
|
46
58
|
};
|
|
47
|
-
const stopPolling = () => {
|
|
48
|
-
if (interval)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
const stopPolling = (subscription) => {
|
|
60
|
+
if (!subscription.interval)
|
|
61
|
+
return;
|
|
62
|
+
Logger.debug('Stopping QueueMonitoringService polling', {
|
|
63
|
+
queue: subscription.config.queue || null,
|
|
64
|
+
pattern: subscription.config.pattern,
|
|
65
|
+
});
|
|
66
|
+
clearInterval(subscription.interval);
|
|
67
|
+
subscription.interval = null;
|
|
53
68
|
};
|
|
54
69
|
export const QueueMonitoringService = Object.freeze({
|
|
55
|
-
subscribe(callback) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
emitter.off('snapshot', callback);
|
|
61
|
-
subscribers--;
|
|
62
|
-
if (subscribers <= 0) {
|
|
63
|
-
stopPolling();
|
|
64
|
-
currentConfig = null;
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
startPollingForClient(config) {
|
|
68
|
-
if (subscribers === 1) {
|
|
69
|
-
currentConfig = config;
|
|
70
|
-
startPolling();
|
|
70
|
+
subscribe(callback, config) {
|
|
71
|
+
const existing = subscriptions.get(callback);
|
|
72
|
+
if (existing) {
|
|
73
|
+
stopPolling(existing);
|
|
74
|
+
subscriptions.delete(callback);
|
|
71
75
|
}
|
|
76
|
+
const subscription = {
|
|
77
|
+
callback,
|
|
78
|
+
config,
|
|
79
|
+
interval: null,
|
|
80
|
+
};
|
|
81
|
+
subscriptions.set(callback, subscription);
|
|
82
|
+
startPolling(subscription);
|
|
72
83
|
},
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
84
|
+
unsubscribe(callback) {
|
|
85
|
+
const subscription = subscriptions.get(callback);
|
|
86
|
+
if (!subscription)
|
|
87
|
+
return;
|
|
88
|
+
stopPolling(subscription);
|
|
89
|
+
subscriptions.delete(callback);
|
|
78
90
|
},
|
|
79
91
|
});
|
|
80
92
|
// settings: {
|
|
@@ -116,10 +128,7 @@ export const QueueMonitoringStream = (res, req, getSnapshot, getLocks, metrics,
|
|
|
116
128
|
const onSnapshot = (data) => {
|
|
117
129
|
send(data);
|
|
118
130
|
};
|
|
119
|
-
|
|
120
|
-
QueueMonitoringService.subscribe(onSnapshot);
|
|
121
|
-
// Start polling for this client
|
|
122
|
-
QueueMonitoringService.startPollingForClient({
|
|
131
|
+
QueueMonitoringService.subscribe(onSnapshot, {
|
|
123
132
|
getSnapshot,
|
|
124
133
|
getLocks,
|
|
125
134
|
getRecentJobsForQueue,
|
|
@@ -138,13 +147,15 @@ export const QueueMonitoringStream = (res, req, getSnapshot, getLocks, metrics,
|
|
|
138
147
|
closed = true;
|
|
139
148
|
clearInterval(hb);
|
|
140
149
|
QueueMonitoringService.unsubscribe(onSnapshot);
|
|
141
|
-
QueueMonitoringService.stopPollingForClient();
|
|
142
150
|
});
|
|
143
151
|
};
|
|
144
152
|
export async function getRecentJobsForQueue(queueName, metrics, driver) {
|
|
145
153
|
const recent = await metrics.getRecentJobs(queueName);
|
|
146
154
|
const failed = await metrics.getFailedJobs(queueName);
|
|
147
|
-
const all = [...recent, ...failed].
|
|
155
|
+
const all = sortJobsByTimestamp([...recent, ...failed].map((job) => ({
|
|
156
|
+
...job,
|
|
157
|
+
queue: job.queue ?? queueName,
|
|
158
|
+
}))).slice(0, 100);
|
|
148
159
|
if (all.length > 0) {
|
|
149
160
|
return all;
|
|
150
161
|
}
|
|
@@ -182,6 +193,7 @@ export async function getRecentJobsForQueue(queueName, metrics, driver) {
|
|
|
182
193
|
return {
|
|
183
194
|
id: job.id,
|
|
184
195
|
name: job.name,
|
|
196
|
+
queue: queueName,
|
|
185
197
|
data: job.data,
|
|
186
198
|
attempts: job.attemptsMade,
|
|
187
199
|
status,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
type WorkerApiResponse<T> = {
|
|
2
|
+
ok: boolean;
|
|
3
|
+
error?: string;
|
|
4
|
+
} & T;
|
|
5
|
+
export declare const WorkerClient: Readonly<{
|
|
6
|
+
listWorkers(): Promise<string[]>;
|
|
7
|
+
getWorker(name: string): Promise<unknown>;
|
|
8
|
+
getStatus(name: string): Promise<unknown>;
|
|
9
|
+
getHealth(name: string): Promise<unknown>;
|
|
10
|
+
startWorker(name: string): Promise<WorkerApiResponse<{
|
|
11
|
+
message?: string;
|
|
12
|
+
}>>;
|
|
13
|
+
stopWorker(name: string): Promise<WorkerApiResponse<{
|
|
14
|
+
message?: string;
|
|
15
|
+
}>>;
|
|
16
|
+
restartWorker(name: string): Promise<WorkerApiResponse<{
|
|
17
|
+
message?: string;
|
|
18
|
+
}>>;
|
|
19
|
+
}>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ErrorFactory, Logger } from '@zintrust/core';
|
|
2
|
+
import { WorkerConfig } from '../config/workerConfig.js';
|
|
3
|
+
const requestJson = async (path, options = {}) => {
|
|
4
|
+
const baseUrl = WorkerConfig.getWorkerBaseUrl();
|
|
5
|
+
const url = `${baseUrl}${path}`;
|
|
6
|
+
const response = await fetch(url, {
|
|
7
|
+
...options,
|
|
8
|
+
headers: {
|
|
9
|
+
'Content-Type': 'application/json',
|
|
10
|
+
...options.headers,
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
Logger.error('Worker API request failed', { url, status: response.status });
|
|
15
|
+
throw ErrorFactory.createWorkerError(`Worker API request failed (${response.status})`);
|
|
16
|
+
}
|
|
17
|
+
return (await response.json());
|
|
18
|
+
};
|
|
19
|
+
export const WorkerClient = Object.freeze({
|
|
20
|
+
async listWorkers() {
|
|
21
|
+
const response = await requestJson('/api/workers');
|
|
22
|
+
return response.workers ?? [];
|
|
23
|
+
},
|
|
24
|
+
async getWorker(name) {
|
|
25
|
+
const response = await requestJson(`/api/workers/${name}`);
|
|
26
|
+
return response.worker;
|
|
27
|
+
},
|
|
28
|
+
async getStatus(name) {
|
|
29
|
+
const response = await requestJson(`/api/workers/${name}/status`);
|
|
30
|
+
return response.status;
|
|
31
|
+
},
|
|
32
|
+
async getHealth(name) {
|
|
33
|
+
const response = await requestJson(`/api/workers/${name}/health`);
|
|
34
|
+
return response.health;
|
|
35
|
+
},
|
|
36
|
+
async startWorker(name) {
|
|
37
|
+
return requestJson(`/api/workers/${name}/start`, { method: 'POST' });
|
|
38
|
+
},
|
|
39
|
+
async stopWorker(name) {
|
|
40
|
+
return requestJson(`/api/workers/${name}/stop`, { method: 'POST' });
|
|
41
|
+
},
|
|
42
|
+
async restartWorker(name) {
|
|
43
|
+
return requestJson(`/api/workers/${name}/restart`, { method: 'POST' });
|
|
44
|
+
},
|
|
45
|
+
});
|
package/dist/build-manifest.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/queue-monitor",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"buildDate": "2026-04-
|
|
3
|
+
"version": "0.4.43",
|
|
4
|
+
"buildDate": "2026-04-01T18:15:53.560Z",
|
|
5
5
|
"buildEnvironment": {
|
|
6
|
-
"node": "
|
|
7
|
-
"platform": "
|
|
8
|
-
"arch": "
|
|
6
|
+
"node": "v22.22.1",
|
|
7
|
+
"platform": "darwin",
|
|
8
|
+
"arch": "arm64"
|
|
9
9
|
},
|
|
10
10
|
"git": {
|
|
11
|
-
"commit": "
|
|
12
|
-
"branch": "
|
|
11
|
+
"commit": "57e4d1b5",
|
|
12
|
+
"branch": "release"
|
|
13
13
|
},
|
|
14
14
|
"package": {
|
|
15
15
|
"engines": {
|
|
@@ -32,6 +32,34 @@
|
|
|
32
32
|
"size": 6190,
|
|
33
33
|
"sha256": "068477c0b545686c9c35d6b42960b5ecf8d19ee4f3f5adec8ddeeb21113258b3"
|
|
34
34
|
},
|
|
35
|
+
"api/workerClient.d.ts": {
|
|
36
|
+
"size": 597,
|
|
37
|
+
"sha256": "1d712bfa9127aa2df4f1fbd0efbb6d84069e1888ed73aca5542a41eee865d4bb"
|
|
38
|
+
},
|
|
39
|
+
"api/workerClient.js": {
|
|
40
|
+
"size": 1629,
|
|
41
|
+
"sha256": "60f993a42f4a9dd5000b01dae3b0f105a8f4348da8433a735b5cc1929a8f64ce"
|
|
42
|
+
},
|
|
43
|
+
"build-manifest.json": {
|
|
44
|
+
"size": 3865,
|
|
45
|
+
"sha256": "6b9eece186e37f5ed657a014c799e3783f30d0e16e0c2fb4e9fa8f2ffcbdd673"
|
|
46
|
+
},
|
|
47
|
+
"config/queueMonitor.d.ts": {
|
|
48
|
+
"size": 407,
|
|
49
|
+
"sha256": "4541f47e64c8ede1bfd8fc0cb7edb76c4e885311b28b1f51c9be7639e5d87eca"
|
|
50
|
+
},
|
|
51
|
+
"config/queueMonitor.js": {
|
|
52
|
+
"size": 689,
|
|
53
|
+
"sha256": "0b95e6b65d4b6ffdd69788cdfd19e0e76400a39ad69dce018d8827a3b298e419"
|
|
54
|
+
},
|
|
55
|
+
"config/workerConfig.d.ts": {
|
|
56
|
+
"size": 86,
|
|
57
|
+
"sha256": "b669205d50c8844455a2d9b34a54f48a71118eb6ac99bad5372683ab666f5a22"
|
|
58
|
+
},
|
|
59
|
+
"config/workerConfig.js": {
|
|
60
|
+
"size": 628,
|
|
61
|
+
"sha256": "ca1c6dbaa751893f0e6b7c8a7fd41a80f7d5e8fc9aaaa4877ca12821bb25f56f"
|
|
62
|
+
},
|
|
35
63
|
"connection.d.ts": {
|
|
36
64
|
"size": 107,
|
|
37
65
|
"sha256": "653b300a25df08a2380bdc74ea38342190771386cb1847dc92802e6eef88a88f"
|
|
@@ -62,7 +90,7 @@
|
|
|
62
90
|
},
|
|
63
91
|
"index.js": {
|
|
64
92
|
"size": 11889,
|
|
65
|
-
"sha256": "
|
|
93
|
+
"sha256": "19a7bdc71cec34fe732dd0d7177ad366d271e31462f402911d4a2700d0ea8b2c"
|
|
66
94
|
},
|
|
67
95
|
"metrics.d.ts": {
|
|
68
96
|
"size": 848,
|
|
@@ -72,6 +100,14 @@
|
|
|
72
100
|
"size": 3448,
|
|
73
101
|
"sha256": "022c97865d37933fd7ed92f47b86b0450056caffd629fce6add51c902529bfe5"
|
|
74
102
|
},
|
|
103
|
+
"routes/workers.d.ts": {
|
|
104
|
+
"size": 477,
|
|
105
|
+
"sha256": "cfcc3527c47d1a796a3ced2d4777b339dd767f7feb3ecc66c5ce0a91d8ff1bc8"
|
|
106
|
+
},
|
|
107
|
+
"routes/workers.js": {
|
|
108
|
+
"size": 901,
|
|
109
|
+
"sha256": "1ec48c0becc8c0628b1780fb400e957c5fe50da79f73112436c33ecde7d7d574"
|
|
110
|
+
},
|
|
75
111
|
"worker.d.ts": {
|
|
76
112
|
"size": 332,
|
|
77
113
|
"sha256": "97cddbc991c6e6724950090cd92f06671932ab848c16dd94a030d9fba3fbae26"
|
|
@@ -79,6 +115,14 @@
|
|
|
79
115
|
"worker.js": {
|
|
80
116
|
"size": 1233,
|
|
81
117
|
"sha256": "da26c1b80da7473e1644a4e0f8d814097ce0adff14e36037164f9ae5855e656a"
|
|
118
|
+
},
|
|
119
|
+
"workers-ui.d.ts": {
|
|
120
|
+
"size": 214,
|
|
121
|
+
"sha256": "4f5fd3bbd077d0dee2cc6c73d2c736fc52119b0d3a5f4a1878a4f3d3d3edf299"
|
|
122
|
+
},
|
|
123
|
+
"workers-ui.js": {
|
|
124
|
+
"size": 24928,
|
|
125
|
+
"sha256": "ba2c5cbf890fe875cc5336c76bd29b146089bc8ba3a70de4a2c383f395f9be73"
|
|
82
126
|
}
|
|
83
127
|
}
|
|
84
128
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Queue Monitor Configuration (default override)
|
|
3
|
+
*
|
|
4
|
+
* Keep this file declarative:
|
|
5
|
+
* - Core owns env parsing/default logic.
|
|
6
|
+
* - Projects can override config by editing values below.
|
|
7
|
+
*/
|
|
8
|
+
declare const _default: {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
basePath: string;
|
|
11
|
+
middleware: string[];
|
|
12
|
+
redis: {
|
|
13
|
+
host: string;
|
|
14
|
+
port: number;
|
|
15
|
+
password: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Env } from '@zintrust/core';
|
|
2
|
+
/**
|
|
3
|
+
* Queue Monitor Configuration (default override)
|
|
4
|
+
*
|
|
5
|
+
* Keep this file declarative:
|
|
6
|
+
* - Core owns env parsing/default logic.
|
|
7
|
+
* - Projects can override config by editing values below.
|
|
8
|
+
*/
|
|
9
|
+
export default {
|
|
10
|
+
enabled: Env.getBool('QUEUE_MONITOR_ENABLED', true),
|
|
11
|
+
basePath: Env.get('QUEUE_MONITOR_BASE_PATH', '/queue-monitor'),
|
|
12
|
+
middleware: Env.get('QUEUE_MONITOR_MIDDLEWARE', 'auth')
|
|
13
|
+
.split(',')
|
|
14
|
+
.map((m) => m.trim())
|
|
15
|
+
.filter((m) => m.length > 0),
|
|
16
|
+
redis: {
|
|
17
|
+
host: Env.get('REDIS_HOST', 'localhost'),
|
|
18
|
+
port: Env.getInt('REDIS_PORT', 6379),
|
|
19
|
+
password: Env.get('REDIS_PASSWORD', ''),
|
|
20
|
+
},
|
|
21
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Env } from '@zintrust/core';
|
|
2
|
+
const normalizeBaseUrl = (value) => {
|
|
3
|
+
let end = value.length;
|
|
4
|
+
while (end > 0 && value.charAt(end - 1) === '/') {
|
|
5
|
+
end--;
|
|
6
|
+
}
|
|
7
|
+
return value.slice(0, end);
|
|
8
|
+
};
|
|
9
|
+
const withHttpScheme = (value) => value.startsWith('http://') || value.startsWith('https://') ? value : `http://${value}`;
|
|
10
|
+
const resolveWorkerApiUrl = () => {
|
|
11
|
+
const workerApiUrl = Env.get('WORKER_API_URL');
|
|
12
|
+
if (workerApiUrl) {
|
|
13
|
+
return normalizeBaseUrl(withHttpScheme(workerApiUrl));
|
|
14
|
+
}
|
|
15
|
+
return '';
|
|
16
|
+
};
|
|
17
|
+
export const WorkerConfig = Object.freeze({
|
|
18
|
+
getWorkerBaseUrl: resolveWorkerApiUrl,
|
|
19
|
+
});
|