Repository navigation
Expand file tree
/
Copy pathZAPIBridgeClient.js
More file actions
106 lines (94 loc) · 3.44 KB
/
Copy pathZAPIBridgeClient.js
File metadata and controls
106 lines (94 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// ZAPIBridgeClient.js
const http = require('http');
const https = require('https');
class ZAPIBridgeClient {
constructor(baseUrl = 'http://127.0.0.1:8080/v1', timeout = 30) {
this.baseUrl = baseUrl.replace(/\/+$/, '');
this.timeout = timeout * 1000;
}
async invoke(app, api, args = [], timeoutMs = 5000) {
const payload = { app, api, args, timeout: timeoutMs };
const response = await this._httpPost('/invoke', payload);
this._assertSuccess(response);
return response.result;
}
async notify(app, api, args = []) {
const payload = { app, api, args };
const response = await this._httpPost('/notify', payload);
this._assertSuccess(response);
}
async registerHook(app, api, callbackUrl, mode = 'call') {
const payload = { app, api, callback_url: callbackUrl, mode };
const response = await this._httpPost('/hooks/register', payload);
this._assertSuccess(response);
return response;
}
async unregisterHook(app, api) {
const payload = { app, api };
const response = await this._httpPost('/hooks/unregister', payload);
this._assertSuccess(response);
return response;
}
async listHooks() {
const response = await this._httpGet('/hooks/list');
this._assertSuccess(response);
return response.hooks || [];
}
async health() {
try {
const response = await this._httpGet('/health');
return response.status === 'ok';
} catch {
return false;
}
}
_httpPost(endpoint, data) {
return this._request('POST', endpoint, JSON.stringify(data), {
'Content-Type': 'application/json'
});
}
_httpGet(endpoint) {
return this._request('GET', endpoint, null, {
'Accept': 'application/json'
});
}
_request(method, endpoint, body, headers) {
return new Promise((resolve, reject) => {
const fullUrl = this.baseUrl + endpoint;
const parsed = new URL(fullUrl);
const options = {
hostname: parsed.hostname,
port: parsed.port || (parsed.protocol === 'https:' ? 443 : 80),
path: parsed.pathname + parsed.search,
method: method,
headers: headers || {},
timeout: this.timeout
};
const client = parsed.protocol === 'https:' ? https : http;
const req = client.request(options, (res) => {
let data = '';
res.on('data', chunk => { data += chunk; });
res.on('end', () => {
try {
resolve(JSON.parse(data));
} catch (e) {
reject(new Error(`Invalid JSON response: ${data}`));
}
});
});
req.on('error', (e) => reject(new Error(`Request error: ${e.message}`)));
req.on('timeout', () => {
req.destroy();
reject(new Error(`Request timeout after ${this.timeout}ms`));
});
if (body) req.write(body);
req.end();
});
}
_assertSuccess(response) {
if (response.code !== undefined && response.code !== 0) {
throw new Error(`Bridge error: ${response.error || 'Unknown error'}`);
}
}
}
module.exports = { ZAPIBridgeClient };