biz-a-cli 2.3.71 → 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,347 +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
- const publishReqCb = async (data, callback) => {
119
- try {
120
- process.env.BIZA_APP_SKIP_PARSE = '1';
121
- const { addApp } = await import('./app.js');
122
-
123
- const requestBody = (typeof data?.body === 'string')
124
- ? JSON.parse(data.body || '{}')
125
- : (data?.body || {});
126
- const hasTransportEnvelope = (
127
- requestBody &&
128
- typeof requestBody === 'object' &&
129
- typeof requestBody.body === 'object' &&
130
- (
131
- Object.prototype.hasOwnProperty.call(requestBody, 'method') ||
132
- Object.prototype.hasOwnProperty.call(requestBody, 'query') ||
133
- Object.prototype.hasOwnProperty.call(requestBody, 'headers')
134
- )
135
- );
136
- const unwrappedPayload = hasTransportEnvelope ? requestBody.body : requestBody;
137
- const publishPayload = (unwrappedPayload && typeof unwrappedPayload === 'object' && unwrappedPayload.addApp && typeof unwrappedPayload.addApp === 'object')
138
- ? unwrappedPayload.addApp
139
- : unwrappedPayload;
140
- const params = (publishPayload && typeof publishPayload.options === 'object')
141
- ? publishPayload.options
142
- : publishPayload;
143
- const toNumber = (value, fallback) => {
144
- const parsed = Number(value);
145
- return Number.isFinite(parsed) ? parsed : fallback;
146
- };
147
-
148
- const response = await addApp({
149
- workingDir: params.workingDir || process.cwd(),
150
- verbose: !!params.verbose,
151
- server: params.server || argv.server || 'http://localhost',
152
- apiPort: toNumber(params.apiPort, argv.port || 212),
153
- dbIndex: toNumber(params.dbIndex, argv.dbindex || 2),
154
- sub: params.sub || params.subdomain || argv.subdomain,
155
- files: params.files || params.fileList,
156
- body: publishPayload
157
- });
158
-
159
- callback(response);
160
- } catch (error) {
161
- callback({
162
- success: false,
163
- error: error?.message || error
164
- });
165
- } finally {
166
- delete process.env.BIZA_APP_SKIP_PARSE;
167
- }
168
- }
169
-
170
- socket.on('connect', connectCb);
171
- socket.on('incomingClient', incomingHubCb)
172
- socket.on('cli-req', cliReqCb);
173
- socket.on('publish-req', publishReqCb);
174
-
175
- socket.on('disconnect', reason => {
176
- console.log(`${new Date()}: ${getIdText(id)}disconnected from BizA Server. Reason: ${reason}`)
177
- id = undefined
178
- if (reason.toLowerCase() === DISCONNECT_REASON_BY_SOCKET_SERVER) {
179
- socket.connect()
180
- }
181
- })
182
-
183
- socket.io.on('reconnect', () => {
184
- console.log(`${new Date()}: ${getIdText(id)}reconnecting to BizA Server`)
185
- })
186
- return socket
187
- })
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
+ });
188
232
 
189
233
  export const hubEvent = (socket, argv, notifier) => {
190
- let id
191
- socket.on('connect', () => {
192
- id = socket.id
193
- notifier(argv['hubServer'])
194
- console.log(`${new Date()}: ${getIdText(id)}connected to BizA Hub at ${argv['hubServer']} using sub domain "${argv['subdomain']}"`)
195
- })
196
- socket.on('disconnect', (reason) => {
197
- notifier('')
198
- console.log(`${new Date()}: ${getIdText(id)}disconnected from BizA Hub. Reason: ${reason}`)
199
- id = undefined
200
- if (reason.toLowerCase() === DISCONNECT_REASON_BY_SOCKET_SERVER) {
201
- socket.connect()
202
- }
203
- })
204
- const logError = msg=>{console.log(`${new Date()}: ${getIdText(id)}connection error to BizA Hub at ${argv['hubServer']} using sub domain "${argv['subdomain']}". Error : ${msg}`)}
205
- socket.on('connect_error', (error)=>{
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) => {
206
258
  // console.log('Connect Error :', error);
207
- notifier('')
208
- logError(error.message)
209
- })
210
- socket.on('error', (error) => {
259
+ notifier("");
260
+ logError(error.message);
261
+ });
262
+ socket.on("error", (error) => {
211
263
  // console.log('Error :', error);
212
- notifier('')
213
- logError(error)
214
- })
215
- socket.io.on('reconnect', () => {
216
- notifier('')
217
- console.log(`${new Date()}: ${getIdText(id)}reconnecting to BizA Hub`)
218
- })
219
- clientListener(socket, argv);
220
- deploymentListenerForHubServer(socket, argv);
221
- return socket
222
- }
223
-
224
- export const status = (argv)=>{
225
- const cliAddress = argv.cliAddress();
226
- const cpuArchitecture = os.arch();
227
- const osArchitecture = (['x64', 'arm64', 'ppc64', 's390x'].includes(cpuArchitecture)) ? '64-bit' : (['ia32', 'arm', 'mips', 'mipsel', 's390'].includes(cpuArchitecture)) ? '32-bit' : `Unknown CPU architecture: ${cpuArchitecture}`;
228
- const totalMemory = os.totalmem();
229
- const freeMemory = os.freemem();
230
- const usedMemoy = totalMemory - freeMemory;
231
- const getUptime = ()=>{
232
- let totalSeconds = Math.floor(process.uptime());
233
- const days = Math.floor(totalSeconds / (24 * 3600));
234
- totalSeconds %= (24 * 3600); // Remaining seconds after calculating days
235
-
236
- const hours = Math.floor(totalSeconds / 3600);
237
- totalSeconds %= 3600; // Remaining seconds after calculating hours
238
-
239
- const minutes = Math.floor(totalSeconds / 60);
240
- const seconds = totalSeconds % 60; // Remaining seconds after calculating minutes
241
-
242
- return {
243
- days: days,
244
- hours: hours,
245
- minutes: minutes,
246
- seconds: seconds
247
- };
248
- };
249
-
250
- return {
251
- cli: {
252
- address: cliAddress.address,
253
- publicUrl: cliAddress.publicUrl,
254
- hubUrl: cliAddress.hubUrl,
255
- version: packageJson.version,
256
- mode: process.env.NODE_ENV,
257
- memoryUsage: `${(process.memoryUsage().rss / (1024 * 1024)).toFixed(2)} MB`,
258
- nodeVersion: process.version,
259
- uptime: getUptime()
260
- },
261
- api: {
262
- address: `${argv.hostname}:${argv.port}`,
263
- dbIndex: argv.dbindex,
264
- },
265
- os: {
266
- name: os.type(),
267
- architecture: osArchitecture,
268
- cpuCount: os.cpus().length,
269
- platform: os.platform(),
270
- memory: {
271
- total: (totalMemory / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
272
- free: (freeMemory / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
273
- used: (usedMemoy / (1024 * 1024 * 1024)).toFixed(2) + ' GB',
274
- }
275
- }
276
- };
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;
277
274
  };
278
275
 
279
- export const clientListener = (socket, argv)=>{
280
- socket
281
- .on('apiRequest', (reqData, resCB)=>{
282
- let apiAddress = `${argv['secure']==true ? 'https://' : 'http://'}${argv['hostname']}:${argv['port']}`
283
- let reqBody = reqData.body
284
- try {
285
- let parsedBody = (typeof reqData.body === 'object') ? reqBody : JSON.parse(reqBody)
286
- if (parsedBody.apiAddress) {
287
- apiAddress = parsedBody.apiAddress
288
- delete parsedBody.apiAddress
289
- reqBody = (typeof reqData.body === 'string') ? JSON.stringify(parsedBody) : parsedBody
290
- }
291
- } catch (error) { }
292
-
293
- const socketResponse = (resp) => {
294
- const cliAddress = argv.cliAddress();
295
- let cliAddressHeaders = {};
296
- if (cliAddress.publicUrl) {
297
- cliAddressHeaders['biza-cli-address'] = cliAddress.publicUrl;
298
- };
299
- if (cliAddress.hubUrl) {
300
- cliAddressHeaders['biza-hub-address'] = cliAddress.hubUrl;
301
- };
302
- return {
303
- status: resp.status,
304
- statusText: resp.statusText,
305
- headers: { ...resp.headers, ...cliAddressHeaders },
306
- body: resp.data,
307
- url: apiAddress + resp.config.url
308
- };
309
- };
310
- if (argv['subdomain'].localeCompare(reqData.subDomain) == 0) {
311
- axios.request({
312
- timeout: (reqData.timeout || IDLE_SOCKET_TIMEOUT_MILLISECONDS),
313
- baseURL: apiAddress,
314
- url: reqData.path,
315
- method: reqData.method,
316
- headers: reqData.headers,
317
- data: reqBody,
318
- // decompress : false, // if we need to interfered default Agent compression
319
- responseType: reqData.responseType,
320
- maxContentLength: Infinity,
321
- })
322
- .then(response => {
323
- resCB(null, socketResponse(response))
324
- })
325
- .catch(error => {
326
- resCB(error, null)
327
- })
328
- }
329
- else {
330
- resCB({ status: 401, statusText: 'bad subdomain', url: apiAddress + reqData.path }, null)
331
- }
332
- })
333
- .on('cliCommand', async (data, cb)=>{
334
- try {
335
- const command = data.command.trim().toLowerCase();
336
- switch (command) { //ensure case insensitive
337
- case 'status':
338
- cb(null, status(argv));
339
- break;
340
- default:
341
- cb(`Unknown CLI command '${command}'`, null);
342
- };
343
- } catch (err) {
344
- cb(err.message || err, null);
345
- };
346
- });
347
- };
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
+ };