biz-a-cli 2.3.70 → 2.3.72

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/bin/hubEvent.js CHANGED
@@ -1,294 +1,422 @@
1
- import axios from 'axios';
2
- import net from 'node:net';
3
- import tls from 'node:tls';
1
+ import axios from "axios";
2
+ import net from "node:net";
3
+ import tls from "node:tls";
4
4
  import { createRequire } from "module";
5
5
  const require = createRequire(import.meta.url);
6
- const ss = require('socket.io-stream'); //SCY: Temporary, next will be replaced with import
7
- import { Transform } from 'node:stream'
8
- import os from 'node:os';
9
- const packageJson = require('../package.json');
6
+ const ss = require("socket.io-stream"); //SCY: Temporary, next will be replaced with import
7
+ import { Transform } from "node:stream";
8
+ import os from "node:os";
9
+ const packageJson = require("../package.json");
10
10
  // import { pipeline } from 'node:stream'
11
- import { deploymentListenerForHubServer } from './deployEvent.js';
11
+ import { deploymentListenerForHubServer } from "./deployEvent.js";
12
12
 
13
13
  export const IDLE_SOCKET_TIMEOUT_MILLISECONDS = 1000 * 30;
14
14
  export const RECONNECT_SOCKET_DELAY = 60 * 1000;
15
- const DISCONNECT_REASON_BY_SOCKET_SERVER = 'io server disconnect'
16
-
17
- export const socketAgent = isUsingHttps=>(isUsingHttps==true) ? tls : net
18
-
19
- const getIdText = id=>id ? id+' ' : ''
20
-
21
- export const streamEvent = async (socket, argv) => new Promise((resolve, reject) => {
22
- let id
23
-
24
- const connectCb = () => {
25
- id = socket.id
26
- socket.emit('createTunnel', argv['subdomain'], (err) => {
27
- if (err) {
28
- console.log(`${new Date()}: ${getIdText(id)}connection error to BizA Server. Error : ${err}`);
29
- reject(err);
30
- } else {
31
- console.log(`${new Date()}: ${getIdText(id)}connected to BizA Server at ${argv.server} using sub domain "${argv['subdomain']}"`)
32
- resolve(argv['server'].toString());
33
- }
34
- });
35
- }
36
-
37
- const incomingHubCb = (clientId) => {
38
- // console.log(clientId, 'incoming clientId')
39
-
40
- const addCLIAddressAsResponseHeader = new Transform({
41
- transform(chunk, encoding, next){
42
- const apiResponse = chunk.toString().toLowerCase()
43
- const cliAddress = argv.cliAddress()
44
- if ( (apiResponse.indexOf('200 ok') > -1) && (apiResponse.indexOf('server: datasnaphttpservice') > -1)) {
45
- // don't use string to insert additional headers, chunk can have mixed content of string and binary data
46
- const response = Buffer.from(chunk)
47
- const delimiter = '\r\n\r\n'
48
- const delimiterPos = response.indexOf(delimiter)
49
- const header = Buffer.concat([
50
- Buffer.copyBytesFrom(response, 0, delimiterPos),
51
- Buffer.from(
52
- '\r\n' +
53
- 'Access-Control-Expose-Headers: biza-cli-address, biza-hub-address\r\n' +
54
- // `biza-cli-address: ${cliAddress.address}\r\n` + // if we need directHub with local LAN
55
- (cliAddress.publicUrl ? `biza-cli-address: ${cliAddress.publicUrl}\r\n` : '') +
56
- (cliAddress.hubUrl ? `biza-hub-address: ${cliAddress.hubUrl}\r\n` : '') +
57
- '\r\n'
58
- )
59
- ])
60
- const body = (response.length>delimiterPos+delimiter.length) ? Buffer.copyBytesFrom(response, delimiterPos+4) : Buffer.from('')
61
- this.push(body.length>0 ? Buffer.concat([header, body]) : header)
62
- }
63
- else {
64
- this.push(chunk)
65
- }
66
- next()
67
- }
68
- })
69
-
70
- // let client = net.connect(argv['port'], argv['hostname']);
71
- let client = socketAgent(argv['secure']).connect(argv['port'], argv['hostname']);
72
- client.on('connect', () => {
73
- // console.log(`client connected to ${argv['hostname']}:${argv['port']}`)
74
- let s = ss.createStream();
75
-
76
- // s.pipe(client).pipe(s);
77
- s.pipe(client).pipe(addCLIAddressAsResponseHeader).pipe(s)
78
-
79
- // use pipeline for better performance, back pressure, memory management, error handling and clean up
80
- // pipeline(s, client, addCLIAddressAsResponseHeader, s, (err)=>{if (err) {console.error(err)}}) // Not work well with heroku
81
-
82
- s.on('end', () => {
83
- client.destroy()
84
- })
85
-
86
- socket.once(clientId, ()=>{ // hub server shall notify us to end pipeline as soon as possible
87
- client.end()
88
- })
89
-
90
- ss(socket).emit(clientId, s);
91
- })
92
-
93
- client.setTimeout(IDLE_SOCKET_TIMEOUT_MILLISECONDS);
94
- client.on('timeout', () => { // in case client not notify to end pipeline, then inactivity timeout will end it
95
- client.end()
96
- });
97
-
98
- client.on('error', (err) => {
99
- // handle connection refusal (create a stream and immediately close it)
100
- console.error('API Error : ', err)
101
- let s = ss.createStream();
102
- ss(socket).emit(clientId, s);
103
- s.end();
104
- });
105
- }
106
-
107
- const cliReqCb = async (data, callback) => {
108
- const { path, method, ...remainData } = data;
109
-
110
- const result = await axios.request({
111
- method: data.method,
112
- url: `${process.env.HOST || 'http://localhost'}:${argv.serverport}/cb${path || ''}`,
113
- data: remainData
114
- })
115
- callback(result.data);
116
- }
117
-
118
- socket.on('connect', connectCb);
119
- socket.on('incomingClient', incomingHubCb)
120
- socket.on('cli-req', cliReqCb);
121
-
122
- socket.on('disconnect', reason=>{
123
- console.log(`${new Date()}: ${getIdText(id)}disconnected from BizA Server. Reason: ${reason}`)
124
- id = undefined
125
- if (reason.toLowerCase()===DISCONNECT_REASON_BY_SOCKET_SERVER) {
126
- socket.connect()
127
- }
128
- })
129
-
130
- socket.io.on('reconnect', ()=>{
131
- console.log(`${new Date()}: ${getIdText(id)}reconnecting to BizA Server`)
132
- })
133
- return socket
134
- })
135
-
136
- export const hubEvent = (socket, argv, notifier)=>{
137
- let id
138
- socket.on('connect', ()=>{
139
- id = socket.id
140
- notifier(argv['hubServer'])
141
- console.log(`${new Date()}: ${getIdText(id)}connected to BizA Hub at ${argv['hubServer']} using sub domain "${argv['subdomain']}"`)
142
- })
143
- socket.on('disconnect', (reason)=>{
144
- notifier('')
145
- console.log(`${new Date()}: ${getIdText(id)}disconnected from BizA Hub. Reason: ${reason}`)
146
- id = undefined
147
- if (reason.toLowerCase()===DISCONNECT_REASON_BY_SOCKET_SERVER) {
148
- socket.connect()
149
- }
150
- })
151
- const logError = msg=>{console.log(`${new Date()}: ${getIdText(id)}connection error to BizA Hub at ${argv['hubServer']} using sub domain "${argv['subdomain']}". Error : ${msg}`)}
152
- socket.on('connect_error', (error)=>{
15
+ const DISCONNECT_REASON_BY_SOCKET_SERVER = "io server disconnect";
16
+
17
+ export const socketAgent = (isUsingHttps) => (isUsingHttps == true ? tls : net);
18
+
19
+ const getIdText = (id) => (id ? id + " " : "");
20
+
21
+ export const streamEvent = async (socket, argv) =>
22
+ new Promise((resolve, reject) => {
23
+ let id;
24
+
25
+ const connectCb = () => {
26
+ id = socket.id;
27
+ socket.emit("createTunnel", argv["subdomain"], (err) => {
28
+ if (err) {
29
+ console.log(
30
+ `${new Date()}: ${getIdText(id)}connection error to BizA Server. Error : ${err}`,
31
+ );
32
+ reject(err);
33
+ } else {
34
+ console.log(
35
+ `${new Date()}: ${getIdText(id)}connected to BizA Server at ${argv.server} using sub domain "${argv["subdomain"]}"`,
36
+ );
37
+ resolve(argv["server"].toString());
38
+ }
39
+ });
40
+ };
41
+
42
+ const incomingHubCb = (clientId) => {
43
+ // console.log(clientId, 'incoming clientId')
44
+
45
+ const addCLIAddressAsResponseHeader = new Transform({
46
+ transform(chunk, encoding, next) {
47
+ const apiResponse = chunk.toString().toLowerCase();
48
+ const cliAddress = argv.cliAddress();
49
+ if (
50
+ apiResponse.indexOf("200 ok") > -1 &&
51
+ apiResponse.indexOf("server: datasnaphttpservice") > -1
52
+ ) {
53
+ // don't use string to insert additional headers, chunk can have mixed content of string and binary data
54
+ const response = Buffer.from(chunk);
55
+ const delimiter = "\r\n\r\n";
56
+ const delimiterPos = response.indexOf(delimiter);
57
+ const header = Buffer.concat([
58
+ Buffer.copyBytesFrom(response, 0, delimiterPos),
59
+ Buffer.from(
60
+ "\r\n" +
61
+ "Access-Control-Expose-Headers: biza-cli-address, biza-hub-address\r\n" +
62
+ // `biza-cli-address: ${cliAddress.address}\r\n` + // if we need directHub with local LAN
63
+ (cliAddress.publicUrl
64
+ ? `biza-cli-address: ${cliAddress.publicUrl}\r\n`
65
+ : "") +
66
+ (cliAddress.hubUrl
67
+ ? `biza-hub-address: ${cliAddress.hubUrl}\r\n`
68
+ : "") +
69
+ "\r\n",
70
+ ),
71
+ ]);
72
+ const body =
73
+ response.length > delimiterPos + delimiter.length
74
+ ? Buffer.copyBytesFrom(
75
+ response,
76
+ delimiterPos + 4,
77
+ )
78
+ : Buffer.from("");
79
+ this.push(
80
+ body.length > 0
81
+ ? Buffer.concat([header, body])
82
+ : header,
83
+ );
84
+ } else {
85
+ this.push(chunk);
86
+ }
87
+ next();
88
+ },
89
+ });
90
+
91
+ // let client = net.connect(argv['port'], argv['hostname']);
92
+ let client = socketAgent(argv["secure"]).connect(
93
+ argv["port"],
94
+ argv["hostname"],
95
+ );
96
+ client.on("connect", () => {
97
+ // console.log(`client connected to ${argv['hostname']}:${argv['port']}`)
98
+ let s = ss.createStream();
99
+
100
+ // s.pipe(client).pipe(s);
101
+ s.pipe(client).pipe(addCLIAddressAsResponseHeader).pipe(s);
102
+
103
+ // use pipeline for better performance, back pressure, memory management, error handling and clean up
104
+ // pipeline(s, client, addCLIAddressAsResponseHeader, s, (err)=>{if (err) {console.error(err)}}) // Not work well with heroku
105
+
106
+ s.on("end", () => {
107
+ client.destroy();
108
+ });
109
+
110
+ socket.once(clientId, () => {
111
+ // hub server shall notify us to end pipeline as soon as possible
112
+ client.end();
113
+ });
114
+
115
+ ss(socket).emit(clientId, s);
116
+ });
117
+
118
+ client.setTimeout(IDLE_SOCKET_TIMEOUT_MILLISECONDS);
119
+ client.on("timeout", () => {
120
+ // in case client not notify to end pipeline, then inactivity timeout will end it
121
+ client.end();
122
+ });
123
+
124
+ client.on("error", (err) => {
125
+ // handle connection refusal (create a stream and immediately close it)
126
+ console.error("API Error : ", err);
127
+ let s = ss.createStream();
128
+ ss(socket).emit(clientId, s);
129
+ s.end();
130
+ });
131
+ };
132
+
133
+ const cliReqCb = async (data, callback) => {
134
+ const { path, method, ...remainData } = data;
135
+
136
+ const result = await axios.request({
137
+ method: data.method,
138
+ url: `${process.env.HOST || "http://localhost"}:${argv.serverport}/cb${path || ""}`,
139
+ data: remainData,
140
+ });
141
+ callback(result.data);
142
+ };
143
+
144
+ const publishReqCb = async (data, callback) => {
145
+ try {
146
+ process.env.BIZA_APP_SKIP_PARSE = "1";
147
+ const { addApp } = await import("./app.js");
148
+
149
+ const requestBody =
150
+ typeof data?.body === "string"
151
+ ? JSON.parse(data.body || "{}")
152
+ : data?.body || {};
153
+ const hasTransportEnvelope =
154
+ requestBody &&
155
+ typeof requestBody === "object" &&
156
+ typeof requestBody.body === "object" &&
157
+ (Object.prototype.hasOwnProperty.call(
158
+ requestBody,
159
+ "method",
160
+ ) ||
161
+ Object.prototype.hasOwnProperty.call(
162
+ requestBody,
163
+ "query",
164
+ ) ||
165
+ Object.prototype.hasOwnProperty.call(
166
+ requestBody,
167
+ "headers",
168
+ ));
169
+ const unwrappedPayload = hasTransportEnvelope
170
+ ? requestBody.body
171
+ : requestBody;
172
+ const publishPayload =
173
+ unwrappedPayload &&
174
+ typeof unwrappedPayload === "object" &&
175
+ unwrappedPayload.addApp &&
176
+ typeof unwrappedPayload.addApp === "object"
177
+ ? unwrappedPayload.addApp
178
+ : unwrappedPayload;
179
+ const params =
180
+ publishPayload && typeof publishPayload.options === "object"
181
+ ? publishPayload.options
182
+ : publishPayload;
183
+ const toNumber = (value, fallback) => {
184
+ const parsed = Number(value);
185
+ return Number.isFinite(parsed) ? parsed : fallback;
186
+ };
187
+
188
+ const response = await addApp({
189
+ workingDir: params.workingDir || process.cwd(),
190
+ verbose: !!params.verbose,
191
+ server: params.server || argv.server || "http://localhost",
192
+ apiPort: toNumber(params.apiPort, argv.port || 212),
193
+ dbIndex: toNumber(params.dbIndex, argv.dbindex || 2),
194
+ sub: params.sub || params.subdomain || argv.subdomain,
195
+ files: params.files || params.fileList,
196
+ body: publishPayload,
197
+ });
198
+
199
+ callback(response);
200
+ } catch (error) {
201
+ callback({
202
+ success: false,
203
+ error: error?.message || error,
204
+ });
205
+ } finally {
206
+ delete process.env.BIZA_APP_SKIP_PARSE;
207
+ }
208
+ };
209
+
210
+ socket.on("connect", connectCb);
211
+ socket.on("incomingClient", incomingHubCb);
212
+ socket.on("cli-req", cliReqCb);
213
+ socket.on("publish-req", publishReqCb);
214
+
215
+ socket.on("disconnect", (reason) => {
216
+ console.log(
217
+ `${new Date()}: ${getIdText(id)}disconnected from BizA Server. Reason: ${reason}`,
218
+ );
219
+ id = undefined;
220
+ if (reason.toLowerCase() === DISCONNECT_REASON_BY_SOCKET_SERVER) {
221
+ socket.connect();
222
+ }
223
+ });
224
+
225
+ socket.io.on("reconnect", () => {
226
+ console.log(
227
+ `${new Date()}: ${getIdText(id)}reconnecting to BizA Server`,
228
+ );
229
+ });
230
+ return socket;
231
+ });
232
+
233
+ export const hubEvent = (socket, argv, notifier) => {
234
+ let id;
235
+ socket.on("connect", () => {
236
+ id = socket.id;
237
+ notifier(argv["hubServer"]);
238
+ console.log(
239
+ `${new Date()}: ${getIdText(id)}connected to BizA Hub at ${argv["hubServer"]} using sub domain "${argv["subdomain"]}"`,
240
+ );
241
+ });
242
+ socket.on("disconnect", (reason) => {
243
+ notifier("");
244
+ console.log(
245
+ `${new Date()}: ${getIdText(id)}disconnected from BizA Hub. Reason: ${reason}`,
246
+ );
247
+ id = undefined;
248
+ if (reason.toLowerCase() === DISCONNECT_REASON_BY_SOCKET_SERVER) {
249
+ socket.connect();
250
+ }
251
+ });
252
+ const logError = (msg) => {
253
+ console.log(
254
+ `${new Date()}: ${getIdText(id)}connection error to BizA Hub at ${argv["hubServer"]} using sub domain "${argv["subdomain"]}". Error : ${msg}`,
255
+ );
256
+ };
257
+ socket.on("connect_error", (error) => {
153
258
  // console.log('Connect Error :', error);
154
- notifier('')
155
- logError(error.message)
156
- })
157
- socket.on('error', (error)=>{
259
+ notifier("");
260
+ logError(error.message);
261
+ });
262
+ socket.on("error", (error) => {
158
263
  // console.log('Error :', error);
159
- notifier('')
160
- logError(error)
161
- })
162
- socket.io.on('reconnect', ()=>{
163
- notifier('')
164
- console.log(`${new Date()}: ${getIdText(id)}reconnecting to BizA Hub`)
165
- })
166
- clientListener(socket, argv);
167
- deploymentListenerForHubServer(socket, argv);
168
- return socket
169
- }
170
-
171
- export const status = (argv)=>{
172
- const cliAddress = argv.cliAddress();
173
- const cpuArchitecture = os.arch();
174
- const osArchitecture = (['x64', 'arm64', 'ppc64', 's390x'].includes(cpuArchitecture)) ? '64-bit' : (['ia32', 'arm', 'mips', 'mipsel', 's390'].includes(cpuArchitecture)) ? '32-bit' : `Unknown CPU architecture: ${cpuArchitecture}`;
175
- const totalMemory = os.totalmem();
176
- const freeMemory = os.freemem();
177
- const usedMemoy = totalMemory - freeMemory;
178
- const getUptime = ()=>{
179
- let totalSeconds = Math.floor(process.uptime());
180
- const days = Math.floor(totalSeconds / (24 * 3600));
181
- totalSeconds %= (24 * 3600); // Remaining seconds after calculating days
182
-
183
- const hours = Math.floor(totalSeconds / 3600);
184
- totalSeconds %= 3600; // Remaining seconds after calculating hours
185
-
186
- const minutes = Math.floor(totalSeconds / 60);
187
- const seconds = totalSeconds % 60; // Remaining seconds after calculating minutes
188
-
189
- return {
190
- days: days,
191
- hours: hours,
192
- minutes: minutes,
193
- seconds: seconds
194
- };
195
- };
196
-
197
- return {
198
- cli: {
199
- address: cliAddress.address,
200
- publicUrl: cliAddress.publicUrl,
201
- hubUrl: cliAddress.hubUrl,
202
- version: packageJson.version,
203
- mode: process.env.NODE_ENV,
204
- memoryUsage: `${(process.memoryUsage().rss / (1024 * 1024)).toFixed(2)} MB`,
205
- nodeVersion: process.version,
206
- uptime: getUptime()
207
- },
208
- api: {
209
- address: `${argv.hostname}:${argv.port}`,
210
- dbIndex: argv.dbindex,
211
- },
212
- os: {
213
- name: os.type(),
214
- architecture: osArchitecture,
215
- cpuCount: os.cpus().length,
216
- platform: os.platform(),
217
- memory: {
218
- total: (totalMemory / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
219
- free: (freeMemory / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
220
- used: (usedMemoy / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
221
- }
222
- }
223
- };
264
+ notifier("");
265
+ logError(error);
266
+ });
267
+ socket.io.on("reconnect", () => {
268
+ notifier("");
269
+ console.log(`${new Date()}: ${getIdText(id)}reconnecting to BizA Hub`);
270
+ });
271
+ clientListener(socket, argv);
272
+ deploymentListenerForHubServer(socket, argv);
273
+ return socket;
224
274
  };
225
275
 
226
- export const clientListener = (socket, argv)=>{
227
- socket
228
- .on('apiRequest', (reqData, resCB)=>{
229
- let apiAddress = `${argv['secure']==true ? 'https://' : 'http://'}${argv['hostname']}:${argv['port']}`
230
- let reqBody = reqData.body
231
- try{
232
- let parsedBody = (typeof reqData.body==='object') ? reqBody : JSON.parse(reqBody)
233
- if (parsedBody.apiAddress){
234
- apiAddress = parsedBody.apiAddress
235
- delete parsedBody.apiAddress
236
- reqBody = (typeof reqData.body==='string') ? JSON.stringify(parsedBody) : parsedBody
237
- }
238
- } catch (error) {}
239
-
240
- const socketResponse = (resp)=>{
241
- const cliAddress = argv.cliAddress();
242
- let cliAddressHeaders = {};
243
- if (cliAddress.publicUrl) {
244
- cliAddressHeaders['biza-cli-address'] = cliAddress.publicUrl;
245
- };
246
- if (cliAddress.hubUrl) {
247
- cliAddressHeaders['biza-hub-address'] = cliAddress.hubUrl;
248
- };
249
- return {
250
- status: resp.status,
251
- statusText: resp.statusText,
252
- headers: {...resp.headers, ...cliAddressHeaders},
253
- body: resp.data,
254
- url: apiAddress + resp.config.url
255
- };
256
- };
257
- if (argv['subdomain'].localeCompare(reqData.subDomain)==0) {
258
- axios.request({
259
- timeout : (reqData.timeout || IDLE_SOCKET_TIMEOUT_MILLISECONDS),
260
- baseURL : apiAddress,
261
- url : reqData.path,
262
- method : reqData.method,
263
- headers : reqData.headers,
264
- data : reqBody,
265
- // decompress : false, // if we need to interfered default Agent compression
266
- responseType : reqData.responseType,
267
- maxContentLength : Infinity,
268
- })
269
- .then(response=>{
270
- resCB(null, socketResponse(response))
271
- })
272
- .catch(error=>{
273
- resCB(error, null)
274
- })
275
- }
276
- else {
277
- resCB({status: 401, statusText: 'bad subdomain', url: apiAddress + reqData.path}, null)
278
- }
279
- })
280
- .on('cliCommand', async (data, cb)=>{
281
- try {
282
- const command = data.command.trim().toLowerCase();
283
- switch (command) { //ensure case insensitive
284
- case 'status':
285
- cb(null, status(argv));
286
- break;
287
- default:
288
- cb(`Unknown CLI command '${command}'`, null);
289
- };
290
- } catch (err) {
291
- cb(err.message || err, null);
292
- };
293
- });
294
- };
276
+ export const status = (argv) => {
277
+ const cliAddress = argv.cliAddress();
278
+ const cpuArchitecture = os.arch();
279
+ const osArchitecture = ["x64", "arm64", "ppc64", "s390x"].includes(
280
+ cpuArchitecture,
281
+ )
282
+ ? "64-bit"
283
+ : ["ia32", "arm", "mips", "mipsel", "s390"].includes(cpuArchitecture)
284
+ ? "32-bit"
285
+ : `Unknown CPU architecture: ${cpuArchitecture}`;
286
+ const totalMemory = os.totalmem();
287
+ const freeMemory = os.freemem();
288
+ const usedMemoy = totalMemory - freeMemory;
289
+ const getUptime = () => {
290
+ let totalSeconds = Math.floor(process.uptime());
291
+ const days = Math.floor(totalSeconds / (24 * 3600));
292
+ totalSeconds %= 24 * 3600; // Remaining seconds after calculating days
293
+
294
+ const hours = Math.floor(totalSeconds / 3600);
295
+ totalSeconds %= 3600; // Remaining seconds after calculating hours
296
+
297
+ const minutes = Math.floor(totalSeconds / 60);
298
+ const seconds = totalSeconds % 60; // Remaining seconds after calculating minutes
299
+
300
+ return {
301
+ days: days,
302
+ hours: hours,
303
+ minutes: minutes,
304
+ seconds: seconds,
305
+ };
306
+ };
307
+
308
+ return {
309
+ cli: {
310
+ address: cliAddress.address,
311
+ publicUrl: cliAddress.publicUrl,
312
+ hubUrl: cliAddress.hubUrl,
313
+ version: packageJson.version,
314
+ mode: process.env.NODE_ENV,
315
+ memoryUsage: `${(process.memoryUsage().rss / (1024 * 1024)).toFixed(2)} MB`,
316
+ nodeVersion: process.version,
317
+ uptime: getUptime(),
318
+ },
319
+ api: {
320
+ address: `${argv.hostname}:${argv.port}`,
321
+ dbIndex: argv.dbindex,
322
+ },
323
+ os: {
324
+ name: os.type(),
325
+ architecture: osArchitecture,
326
+ cpuCount: os.cpus().length,
327
+ platform: os.platform(),
328
+ memory: {
329
+ total: (totalMemory / (1024 * 1024 * 1024)).toFixed(2) + " GB",
330
+ free: (freeMemory / (1024 * 1024 * 1024)).toFixed(2) + " GB",
331
+ used: (usedMemoy / (1024 * 1024 * 1024)).toFixed(2) + " GB",
332
+ },
333
+ },
334
+ };
335
+ };
336
+
337
+ export const clientListener = (socket, argv) => {
338
+ socket
339
+ .on("apiRequest", (reqData, resCB) => {
340
+ let apiAddress = `${argv["secure"] == true ? "https://" : "http://"}${argv["hostname"]}:${argv["port"]}`;
341
+ let reqBody = reqData.body;
342
+ try {
343
+ let parsedBody =
344
+ typeof reqData.body === "object"
345
+ ? reqBody
346
+ : JSON.parse(reqBody);
347
+ if (parsedBody.apiAddress) {
348
+ apiAddress = parsedBody.apiAddress;
349
+ delete parsedBody.apiAddress;
350
+ reqBody =
351
+ typeof reqData.body === "string"
352
+ ? JSON.stringify(parsedBody)
353
+ : parsedBody;
354
+ }
355
+ } catch (error) {}
356
+
357
+ const socketResponse = (resp) => {
358
+ const cliAddress = argv.cliAddress();
359
+ let cliAddressHeaders = {};
360
+ if (cliAddress.publicUrl) {
361
+ cliAddressHeaders["biza-cli-address"] =
362
+ cliAddress.publicUrl;
363
+ }
364
+ if (cliAddress.hubUrl) {
365
+ cliAddressHeaders["biza-hub-address"] = cliAddress.hubUrl;
366
+ }
367
+ return {
368
+ status: resp.status,
369
+ statusText: resp.statusText,
370
+ headers: { ...resp.headers, ...cliAddressHeaders },
371
+ body: resp.data,
372
+ url: apiAddress + resp.config.url,
373
+ };
374
+ };
375
+ if (argv["subdomain"].localeCompare(reqData.subDomain) == 0) {
376
+ axios
377
+ .request({
378
+ timeout:
379
+ reqData.timeout || IDLE_SOCKET_TIMEOUT_MILLISECONDS,
380
+ baseURL: apiAddress,
381
+ url: reqData.path,
382
+ method: reqData.method,
383
+ headers: reqData.headers,
384
+ data: reqBody,
385
+ // decompress : false, // if we need to interfered default Agent compression
386
+ responseType: reqData.responseType,
387
+ maxContentLength: Infinity,
388
+ })
389
+ .then((response) => {
390
+ resCB(null, socketResponse(response));
391
+ })
392
+ .catch((error) => {
393
+ resCB(error, null);
394
+ });
395
+ } else {
396
+ resCB(
397
+ {
398
+ status: 401,
399
+ statusText: "bad subdomain",
400
+ url: apiAddress + reqData.path,
401
+ },
402
+ null,
403
+ );
404
+ }
405
+ })
406
+ .on("cliCommand", async (data, cb) => {
407
+ try {
408
+ const command = data.command.trim().toLowerCase();
409
+ switch (
410
+ command //ensure case insensitive
411
+ ) {
412
+ case "status":
413
+ cb(null, status(argv));
414
+ break;
415
+ default:
416
+ cb(`Unknown CLI command '${command}'`, null);
417
+ }
418
+ } catch (err) {
419
+ cb(err.message || err, null);
420
+ }
421
+ });
422
+ };