@icgio/clients-config 1.0.258 → 1.0.259
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/.gitsecret/keys/crls.d/DIR.txt +1 -1
- package/.gitsecret/paths/mapping.cfg +1 -1
- package/config-archive.json +28 -1
- package/config.json +9 -34
- package/data-source.js.secret +0 -0
- package/index.js +19 -19
- package/package.json +27 -27
- package/secretread.js.secret +0 -0
- package/update-config-json.js +278 -278
|
@@ -1 +1 @@
|
|
|
1
|
-
v:1:
|
|
1
|
+
v:1:
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
secretread.js:
|
|
1
|
+
secretread.js:f71d24bf11dbf885004178a6269acca8642ea73dcdf34bf851e0b7cf10cb4656
|
|
2
2
|
data-source.js:a88043810676f6017be94bbcc357f8f0d439890c6698cc0b02941b605e7dbd9a
|
package/config-archive.json
CHANGED
|
@@ -239,6 +239,9 @@
|
|
|
239
239
|
"SWFTC": {
|
|
240
240
|
"Htx": ["SWFTCBTC"]
|
|
241
241
|
},
|
|
242
|
+
"TACC": {
|
|
243
|
+
"Weex": ["TACCUSDT"]
|
|
244
|
+
},
|
|
242
245
|
"TAZZ": {
|
|
243
246
|
"Weex": ["TAZZUSDT"]
|
|
244
247
|
},
|
|
@@ -363,6 +366,7 @@
|
|
|
363
366
|
"SHROOMY": [],
|
|
364
367
|
"SLOR": [],
|
|
365
368
|
"SPONSTAR": [],
|
|
369
|
+
"TACC": [],
|
|
366
370
|
"TAZZ": [],
|
|
367
371
|
"TES": [],
|
|
368
372
|
"TGMT": [],
|
|
@@ -579,6 +583,9 @@
|
|
|
579
583
|
"SWFTC": {
|
|
580
584
|
"SWFTCBTC": ["Htx"]
|
|
581
585
|
},
|
|
586
|
+
"TACC": {
|
|
587
|
+
"TACCUSDT": ["Weex"]
|
|
588
|
+
},
|
|
582
589
|
"TAZZ": {
|
|
583
590
|
"TAZZUSDT": ["Weex"]
|
|
584
591
|
},
|
|
@@ -942,6 +949,12 @@
|
|
|
942
949
|
"trades": 1,
|
|
943
950
|
"orderbook": 1
|
|
944
951
|
},
|
|
952
|
+
"TACC": {
|
|
953
|
+
"balance": 1,
|
|
954
|
+
"trades": 1,
|
|
955
|
+
"orderbook": 1,
|
|
956
|
+
"deposits_withdrawals":1
|
|
957
|
+
},
|
|
945
958
|
"TAZZ": {
|
|
946
959
|
"balance": 1,
|
|
947
960
|
"trades": 1,
|
|
@@ -1079,6 +1092,7 @@
|
|
|
1079
1092
|
"SHROOMY": true,
|
|
1080
1093
|
"SLOR": true,
|
|
1081
1094
|
"SPONSTAR": true,
|
|
1095
|
+
"TACC": true,
|
|
1082
1096
|
"TAZZ": true,
|
|
1083
1097
|
"TES": true,
|
|
1084
1098
|
"TIPS": true,
|
|
@@ -1098,6 +1112,9 @@
|
|
|
1098
1112
|
"IONX": true,
|
|
1099
1113
|
"XERT": true
|
|
1100
1114
|
},
|
|
1115
|
+
"deposits_withdrawals": {
|
|
1116
|
+
"TACC": true
|
|
1117
|
+
},
|
|
1101
1118
|
"total_in_usd": {
|
|
1102
1119
|
"AXL": true,
|
|
1103
1120
|
"DIS": true,
|
|
@@ -1165,6 +1182,7 @@
|
|
|
1165
1182
|
"SHROOMY": true,
|
|
1166
1183
|
"SLOR": true,
|
|
1167
1184
|
"SPONSTAR": true,
|
|
1185
|
+
"TACC": true,
|
|
1168
1186
|
"TAZZ": true,
|
|
1169
1187
|
"TES": true,
|
|
1170
1188
|
"TIN": true,
|
|
@@ -1257,6 +1275,7 @@
|
|
|
1257
1275
|
"SHROOMY": [10, 50, 100],
|
|
1258
1276
|
"SLOR": [1, 2, 5, 10, 20, 50, 100],
|
|
1259
1277
|
"SPONSTAR": [10, 50, 100],
|
|
1278
|
+
"TACC": [1, 2, 5, 10, 20, 50, 100],
|
|
1260
1279
|
"TAZZ": [10, 50, 100],
|
|
1261
1280
|
"TES": [10, 50, 100],
|
|
1262
1281
|
"TGMT": [2, 5, 10],
|
|
@@ -1340,6 +1359,7 @@
|
|
|
1340
1359
|
"SHROOMY": ["BTC", "ETH"],
|
|
1341
1360
|
"SLOR": ["BTC", "ETH"],
|
|
1342
1361
|
"SPONSTAR": ["BTC", "ETH"],
|
|
1362
|
+
"TACC": ["BTC", "ETH"],
|
|
1343
1363
|
"TAZZ": ["BTC", "ETH"],
|
|
1344
1364
|
"TES": ["BTC", "ETH"],
|
|
1345
1365
|
"TGMT": ["BTC", "ETH"],
|
|
@@ -1424,6 +1444,7 @@
|
|
|
1424
1444
|
"SHROOMY": "-4777465585",
|
|
1425
1445
|
"SLOR": "-4721907187",
|
|
1426
1446
|
"SPONSTAR": "-4727729020",
|
|
1447
|
+
"TACC": "-4874959768",
|
|
1427
1448
|
"TAZZ": "-4506672630",
|
|
1428
1449
|
"TES": "-4232847552",
|
|
1429
1450
|
"TGMT": "-1002053322082",
|
|
@@ -1501,6 +1522,7 @@
|
|
|
1501
1522
|
"SHROOMY": "icg",
|
|
1502
1523
|
"SLOR": "icg",
|
|
1503
1524
|
"SPONSTAR": "icg",
|
|
1525
|
+
"TACC": "icg",
|
|
1504
1526
|
"TAZZ": "icg",
|
|
1505
1527
|
"TITAN": "icg",
|
|
1506
1528
|
"TKT": "icg",
|
|
@@ -1627,6 +1649,10 @@
|
|
|
1627
1649
|
"username": "sponstar@icg.io",
|
|
1628
1650
|
"password": "pqVJQPuuPThfjZp"
|
|
1629
1651
|
},
|
|
1652
|
+
"TACC": {
|
|
1653
|
+
"username": "tacc@icg.io",
|
|
1654
|
+
"password": "NqDhRLCE68zsKA4"
|
|
1655
|
+
},
|
|
1630
1656
|
"TITAN": {
|
|
1631
1657
|
"username": "titan@icg.io",
|
|
1632
1658
|
"password": "PWW8Te4dPDoDS76"
|
|
@@ -1666,6 +1692,7 @@
|
|
|
1666
1692
|
"BVT": [],
|
|
1667
1693
|
"GO": [],
|
|
1668
1694
|
"LST": [],
|
|
1669
|
-
"MAK": ["172.105.237.102"]
|
|
1695
|
+
"MAK": ["172.105.237.102"],
|
|
1696
|
+
"TACC": ["172.105.237.102"]
|
|
1670
1697
|
}
|
|
1671
1698
|
}
|
package/config.json
CHANGED
|
@@ -62,9 +62,6 @@
|
|
|
62
62
|
"Htx": ["SWFTCUSDT"],
|
|
63
63
|
"Kucoin": ["SWFTCUSDT"],
|
|
64
64
|
"Okx": ["SWFTCUSDT"]
|
|
65
|
-
},
|
|
66
|
-
"TACC": {
|
|
67
|
-
"Weex": ["TACCUSDT"]
|
|
68
65
|
}
|
|
69
66
|
},
|
|
70
67
|
"client_not_include_exchanges": {
|
|
@@ -82,8 +79,7 @@
|
|
|
82
79
|
"OPUL": [],
|
|
83
80
|
"SARA": [],
|
|
84
81
|
"SQL": [],
|
|
85
|
-
"SWFTC": ["Lbank"]
|
|
86
|
-
"TACC": []
|
|
82
|
+
"SWFTC": ["Lbank"]
|
|
87
83
|
},
|
|
88
84
|
"client_pair_main_exchanges": {
|
|
89
85
|
"ARMY": {
|
|
@@ -136,9 +132,6 @@
|
|
|
136
132
|
"SWFTC": {
|
|
137
133
|
"SWFTCUSDC": ["Coinbase"],
|
|
138
134
|
"SWFTCUSDT": ["Okx"]
|
|
139
|
-
},
|
|
140
|
-
"TACC": {
|
|
141
|
-
"TACCUSDT": ["Weex"]
|
|
142
135
|
}
|
|
143
136
|
},
|
|
144
137
|
"clients_reporter_interval": {
|
|
@@ -231,12 +224,6 @@
|
|
|
231
224
|
"trades": 1,
|
|
232
225
|
"orderbook": 1,
|
|
233
226
|
"deposits_withdrawals":1
|
|
234
|
-
},
|
|
235
|
-
"TACC": {
|
|
236
|
-
"balance": 1,
|
|
237
|
-
"trades": 1,
|
|
238
|
-
"orderbook": 1,
|
|
239
|
-
"deposits_withdrawals":1
|
|
240
227
|
}
|
|
241
228
|
},
|
|
242
229
|
"client_enabled": {
|
|
@@ -255,8 +242,7 @@
|
|
|
255
242
|
"OPUL": true,
|
|
256
243
|
"SARA": true,
|
|
257
244
|
"SQL": true,
|
|
258
|
-
"SWFTC": true
|
|
259
|
-
"TACC": true
|
|
245
|
+
"SWFTC": true
|
|
260
246
|
},
|
|
261
247
|
"balance_cur": {},
|
|
262
248
|
"deposits_withdrawals": {
|
|
@@ -274,8 +260,7 @@
|
|
|
274
260
|
"OPUL": true,
|
|
275
261
|
"SARA": true,
|
|
276
262
|
"SQL": true,
|
|
277
|
-
"SWFTC": true
|
|
278
|
-
"TACC": true
|
|
263
|
+
"SWFTC": true
|
|
279
264
|
},
|
|
280
265
|
"total_in_usd": {
|
|
281
266
|
"SWFTC": true
|
|
@@ -296,8 +281,7 @@
|
|
|
296
281
|
"OPUL": true,
|
|
297
282
|
"SARA": true,
|
|
298
283
|
"SQL": true,
|
|
299
|
-
"SWFTC": true
|
|
300
|
-
"TACC": true
|
|
284
|
+
"SWFTC": true
|
|
301
285
|
},
|
|
302
286
|
"orderbook": {
|
|
303
287
|
"MIX": true
|
|
@@ -318,8 +302,7 @@
|
|
|
318
302
|
"OPUL": [1, 2, 5, 10, 20, 50, 100],
|
|
319
303
|
"SARA": [1, 2, 5, 10, 20, 50, 100],
|
|
320
304
|
"SQL": [1, 2, 5, 10, 20, 50, 100],
|
|
321
|
-
"SWFTC": [1, 2, 5, 10, 20, 50, 100]
|
|
322
|
-
"TACC": [1, 2, 5, 10, 20, 50, 100]
|
|
305
|
+
"SWFTC": [1, 2, 5, 10, 20, 50, 100]
|
|
323
306
|
},
|
|
324
307
|
"client_price_index_curs": {
|
|
325
308
|
"ARMY": ["BTC", "ETH"],
|
|
@@ -336,8 +319,7 @@
|
|
|
336
319
|
"OPUL": ["BTC", "ETH"],
|
|
337
320
|
"SARA": ["BTC", "ETH"],
|
|
338
321
|
"SQL": ["BTC", "ETH"],
|
|
339
|
-
"SWFTC": ["BTC", "ETH"]
|
|
340
|
-
"TACC": ["BTC", "ETH"]
|
|
322
|
+
"SWFTC": ["BTC", "ETH"]
|
|
341
323
|
},
|
|
342
324
|
"client_telegram_ids": {
|
|
343
325
|
"ARMY": "-4733838023",
|
|
@@ -354,8 +336,7 @@
|
|
|
354
336
|
"OPUL": "-4581926908",
|
|
355
337
|
"SARA": "-4660700305",
|
|
356
338
|
"SQL": "-4959066810",
|
|
357
|
-
"SWFTC": "-1002067948127"
|
|
358
|
-
"TACC": "-4874959768"
|
|
339
|
+
"SWFTC": "-1002067948127"
|
|
359
340
|
},
|
|
360
341
|
"balance_premium": {
|
|
361
342
|
"SWFTC": {
|
|
@@ -381,8 +362,7 @@
|
|
|
381
362
|
"OPUL": "icg",
|
|
382
363
|
"SARA": "icg",
|
|
383
364
|
"SQL": "icg",
|
|
384
|
-
"SWFTC": "icg"
|
|
385
|
-
"TACC": "icg"
|
|
365
|
+
"SWFTC": "icg"
|
|
386
366
|
},
|
|
387
367
|
"client_dashboard_credentials": {
|
|
388
368
|
"ADMIN": {
|
|
@@ -452,10 +432,6 @@
|
|
|
452
432
|
"SWFTC": {
|
|
453
433
|
"username": "swftc@icg.io",
|
|
454
434
|
"password": "XeH7kUVRjsEisQ0"
|
|
455
|
-
},
|
|
456
|
-
"TACC": {
|
|
457
|
-
"username": "tacc@icg.io",
|
|
458
|
-
"password": "NqDhRLCE68zsKA4"
|
|
459
435
|
}
|
|
460
436
|
},
|
|
461
437
|
"server_config_enabled": {
|
|
@@ -479,7 +455,6 @@
|
|
|
479
455
|
"OPUL": ["172.105.237.102"],
|
|
480
456
|
"SARA": ["172.105.237.102"],
|
|
481
457
|
"SQL": ["172.105.237.102"],
|
|
482
|
-
"SWFTC": ["172.105.237.102"]
|
|
483
|
-
"TACC": ["172.105.237.102"]
|
|
458
|
+
"SWFTC": ["172.105.237.102"]
|
|
484
459
|
}
|
|
485
460
|
}
|
package/data-source.js.secret
CHANGED
|
Binary file
|
package/index.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
function safe_require(path) {
|
|
2
|
-
try {
|
|
3
|
-
return require(path)
|
|
4
|
-
} catch (error) {
|
|
5
|
-
if (error.code === 'MODULE_NOT_FOUND') {
|
|
6
|
-
return {}
|
|
7
|
-
} else {
|
|
8
|
-
throw error
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
module.exports = {
|
|
14
|
-
config: safe_require('./config.js'),
|
|
15
|
-
secretread: safe_require('./secretread.js').secret,
|
|
16
|
-
secretread_shared: safe_require('./secretread.js').shared,
|
|
17
|
-
'data-source': safe_require('./data-source.js'),
|
|
18
|
-
benchmarks: safe_require('./config-benchmarks.js'),
|
|
19
|
-
}
|
|
1
|
+
function safe_require(path) {
|
|
2
|
+
try {
|
|
3
|
+
return require(path)
|
|
4
|
+
} catch (error) {
|
|
5
|
+
if (error.code === 'MODULE_NOT_FOUND') {
|
|
6
|
+
return {}
|
|
7
|
+
} else {
|
|
8
|
+
throw error
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = {
|
|
14
|
+
config: safe_require('./config.js'),
|
|
15
|
+
secretread: safe_require('./secretread.js').secret,
|
|
16
|
+
secretread_shared: safe_require('./secretread.js').shared,
|
|
17
|
+
'data-source': safe_require('./data-source.js'),
|
|
18
|
+
benchmarks: safe_require('./config-benchmarks.js'),
|
|
19
|
+
}
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@icgio/clients-config",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
-
},
|
|
9
|
-
"repository": {
|
|
10
|
-
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/icgio/clients-config.git"
|
|
12
|
-
},
|
|
13
|
-
"author": "",
|
|
14
|
-
"license": "ISC",
|
|
15
|
-
"bugs": {
|
|
16
|
-
"url": "https://github.com/icgio/clients-config/issues"
|
|
17
|
-
},
|
|
18
|
-
"homepage": "https://github.com/icgio/clients-config#readme",
|
|
19
|
-
"dependencies": {
|
|
20
|
-
"lodash": "^4.17.20"
|
|
21
|
-
},
|
|
22
|
-
"devDependencies": {
|
|
23
|
-
"fs-extra": "^11.2.0",
|
|
24
|
-
"node-cmd": "^5.0.0",
|
|
25
|
-
"prompt": "^1.3.0"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@icgio/clients-config",
|
|
3
|
+
"version": "1.0.259",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
8
|
+
},
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/icgio/clients-config.git"
|
|
12
|
+
},
|
|
13
|
+
"author": "",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/icgio/clients-config/issues"
|
|
17
|
+
},
|
|
18
|
+
"homepage": "https://github.com/icgio/clients-config#readme",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"lodash": "^4.17.20"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"fs-extra": "^11.2.0",
|
|
24
|
+
"node-cmd": "^5.0.0",
|
|
25
|
+
"prompt": "^1.3.0"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/secretread.js.secret
CHANGED
|
Binary file
|
package/update-config-json.js
CHANGED
|
@@ -1,278 +1,278 @@
|
|
|
1
|
-
const fs = require('fs')
|
|
2
|
-
const prompt = require('prompt')
|
|
3
|
-
|
|
4
|
-
const config_file_path = './config.json'
|
|
5
|
-
const config_archive_file_path = './config-archive.json'
|
|
6
|
-
|
|
7
|
-
prompt.start()
|
|
8
|
-
|
|
9
|
-
function read_config_file(path) {
|
|
10
|
-
return new Promise((resolve, reject) => {
|
|
11
|
-
fs.readFile(path, 'utf8', (err, data) => {
|
|
12
|
-
if (err) reject(err)
|
|
13
|
-
else resolve(data)
|
|
14
|
-
})
|
|
15
|
-
})
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function write_config_file(data, path) {
|
|
19
|
-
return new Promise((resolve, reject) => {
|
|
20
|
-
fs.writeFile(path, JSON.stringify(data, null, 2), 'utf8', (err) => {
|
|
21
|
-
if (err) return reject(err)
|
|
22
|
-
else resolve()
|
|
23
|
-
})
|
|
24
|
-
})
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function process_config() {
|
|
28
|
-
try {
|
|
29
|
-
const schema = {
|
|
30
|
-
properties: {
|
|
31
|
-
action: {
|
|
32
|
-
description: 'Enter the action ( add, delete )',
|
|
33
|
-
pattern: /^(add|delete)$/,
|
|
34
|
-
message: 'Action must be one of "add", "delete"',
|
|
35
|
-
required: true,
|
|
36
|
-
},
|
|
37
|
-
client_name: {
|
|
38
|
-
description: 'Enter the client name you want to perform the action on',
|
|
39
|
-
required: true,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
prompt.get(schema, (err, result) => {
|
|
45
|
-
if (err) {
|
|
46
|
-
console.error(err)
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
switch (result.action) {
|
|
51
|
-
case 'add':
|
|
52
|
-
add_client(result.client_name)
|
|
53
|
-
break
|
|
54
|
-
case 'delete':
|
|
55
|
-
delete_client(result.client_name)
|
|
56
|
-
break
|
|
57
|
-
default:
|
|
58
|
-
console.log('Invalid action')
|
|
59
|
-
break
|
|
60
|
-
}
|
|
61
|
-
})
|
|
62
|
-
} catch (error) {
|
|
63
|
-
console.error(`Error processing the config file: ${error}`)
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function delete_client(client_name) {
|
|
68
|
-
read_config_file(config_file_path)
|
|
69
|
-
.then((config_file_data) => {
|
|
70
|
-
config_file_data = JSON.parse(config_file_data)
|
|
71
|
-
|
|
72
|
-
update_config_archive(config_file_data, client_name)
|
|
73
|
-
.then(() => {
|
|
74
|
-
delete config_file_data.client_exchange_pairs[client_name]
|
|
75
|
-
delete config_file_data.client_pair_main_exchanges[client_name]
|
|
76
|
-
delete config_file_data.client_not_include_exchanges[client_name]
|
|
77
|
-
delete config_file_data.client_levels[client_name]
|
|
78
|
-
delete config_file_data.client_price_index_curs[client_name]
|
|
79
|
-
delete config_file_data.client_telegram_ids[client_name]
|
|
80
|
-
delete config_file_data.clients_reporter_interval[client_name]
|
|
81
|
-
|
|
82
|
-
for (let key in config_file_data.client_enabled) {
|
|
83
|
-
if (config_file_data.client_enabled.hasOwnProperty(key)) {
|
|
84
|
-
delete config_file_data.client_enabled[key][client_name]
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
write_config_file(config_file_data, config_file_path)
|
|
89
|
-
.then(() => {
|
|
90
|
-
console.log(`Client '${client_name}' has been deleted successfully.`)
|
|
91
|
-
})
|
|
92
|
-
.catch((err) => {
|
|
93
|
-
console.error(`Error writing to config file: ${err}`)
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
.catch((err) => {
|
|
97
|
-
console.error(`Error updating config archive: ${err}`)
|
|
98
|
-
})
|
|
99
|
-
})
|
|
100
|
-
.catch((err) => {
|
|
101
|
-
console.error(`Error reading config file: ${err}`)
|
|
102
|
-
})
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function add_client(client_name) {
|
|
106
|
-
const schema = {
|
|
107
|
-
properties: {
|
|
108
|
-
client_exchange_pairs: {
|
|
109
|
-
description: 'Enter client exchange pairs (JSON format i.e { "Mexc": ["RWXUSDT"], "Bitget": ["RWXUSDT"] } )',
|
|
110
|
-
required: true,
|
|
111
|
-
pattern: /^\{.*\}$/,
|
|
112
|
-
message: 'Please enter a valid JSON object.',
|
|
113
|
-
},
|
|
114
|
-
client_not_include_exchanges: {
|
|
115
|
-
description: 'Enter client not include exchanges (Comma-separated values, e.g., Jubi, Lbank)',
|
|
116
|
-
required: false,
|
|
117
|
-
},
|
|
118
|
-
client_pair_main_exchanges: {
|
|
119
|
-
description: 'Enter client pair main exchanges (JSON format i.e {"ETHUSDT": ["Bitget", "Gate"]} )',
|
|
120
|
-
required: true,
|
|
121
|
-
pattern: /^\{.*\}$/,
|
|
122
|
-
message: 'Please enter a valid JSON object.',
|
|
123
|
-
},
|
|
124
|
-
clients_reporter_interval: {
|
|
125
|
-
description: 'Enter clients reporter interval (JSON format i.e { "balance": 1, "trades": 1, "orderbook": 1} )',
|
|
126
|
-
required: true,
|
|
127
|
-
pattern: /^\{.*\}$/,
|
|
128
|
-
message: 'Please enter a valid JSON object.',
|
|
129
|
-
},
|
|
130
|
-
client_levels: {
|
|
131
|
-
description: 'Enter client levels (Comma-separated values, e.g. 2, 5, 10 ) ',
|
|
132
|
-
required: true,
|
|
133
|
-
},
|
|
134
|
-
client_price_index_curs: {
|
|
135
|
-
description: 'Enter client benchmarks (Comma-separated values, e.g., BTC,ETH)',
|
|
136
|
-
required: false,
|
|
137
|
-
},
|
|
138
|
-
client_telegram_ids: {
|
|
139
|
-
description: 'Enter client telegram ids i.e 1233457 ',
|
|
140
|
-
required: true,
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
}
|
|
144
|
-
read_config_file(config_file_path)
|
|
145
|
-
.then((config_file_data) => {
|
|
146
|
-
prompt.get(schema, (err, result) => {
|
|
147
|
-
if (err) {
|
|
148
|
-
console.error(err)
|
|
149
|
-
return
|
|
150
|
-
}
|
|
151
|
-
config_file_data = JSON.parse(config_file_data)
|
|
152
|
-
|
|
153
|
-
let exchange_pairs = result.client_exchange_pairs.trim()
|
|
154
|
-
exchange_pairs = JSON.parse(exchange_pairs)
|
|
155
|
-
|
|
156
|
-
let pair_exchanges = result.client_pair_main_exchanges.trim()
|
|
157
|
-
pair_exchanges = JSON.parse(pair_exchanges)
|
|
158
|
-
|
|
159
|
-
let reporter_interval = result.clients_reporter_interval.trim()
|
|
160
|
-
reporter_interval = JSON.parse(reporter_interval)
|
|
161
|
-
|
|
162
|
-
let not_include_exchanges = []
|
|
163
|
-
if (result.client_not_include_exchanges) {
|
|
164
|
-
not_include_exchanges = result.client_not_include_exchanges.split(',').map((value) => value.trim())
|
|
165
|
-
not_include_exchanges.sort()
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
let benchmarks = []
|
|
169
|
-
if (result.client_price_index_curs) {
|
|
170
|
-
benchmarks = result.client_price_index_curs.split(',').map((value) => value.trim())
|
|
171
|
-
benchmarks.sort()
|
|
172
|
-
}
|
|
173
|
-
let levels = result.client_levels.split(',').map((value) => Number(value.trim()))
|
|
174
|
-
|
|
175
|
-
config_file_data.client_exchange_pairs[client_name] = exchange_pairs
|
|
176
|
-
config_file_data.client_pair_main_exchanges[client_name] = pair_exchanges
|
|
177
|
-
|
|
178
|
-
config_file_data.clients_reporter_interval[client_name] = reporter_interval
|
|
179
|
-
|
|
180
|
-
config_file_data.client_not_include_exchanges[client_name] = not_include_exchanges
|
|
181
|
-
config_file_data.client_levels[client_name] = levels
|
|
182
|
-
config_file_data.client_price_index_curs[client_name] = benchmarks
|
|
183
|
-
|
|
184
|
-
config_file_data.client_telegram_ids[client_name] = result.client_telegram_ids
|
|
185
|
-
|
|
186
|
-
config_file_data.client_exchange_pairs = sort(config_file_data.client_exchange_pairs)
|
|
187
|
-
config_file_data.client_pair_main_exchanges = sort(config_file_data.client_pair_main_exchanges)
|
|
188
|
-
config_file_data.clients_reporter_interval = sort(config_file_data.clients_reporter_interval)
|
|
189
|
-
config_file_data.client_not_include_exchanges = sort(config_file_data.client_not_include_exchanges)
|
|
190
|
-
config_file_data.client_levels = sort(config_file_data.client_levels)
|
|
191
|
-
config_file_data.client_price_index_curs = sort(config_file_data.client_price_index_curs)
|
|
192
|
-
config_file_data.client_telegram_ids = sort(config_file_data.client_telegram_ids)
|
|
193
|
-
|
|
194
|
-
write_config_file(config_file_data, config_file_path)
|
|
195
|
-
.then(() => {
|
|
196
|
-
console.log(`Client '${client_name}' has been added successfully.`)
|
|
197
|
-
})
|
|
198
|
-
.catch((err) => {
|
|
199
|
-
console.error(`Error writing to config file: ${err}`)
|
|
200
|
-
})
|
|
201
|
-
})
|
|
202
|
-
})
|
|
203
|
-
.catch((err) => {
|
|
204
|
-
console.error(`Error reading config file: ${err}`)
|
|
205
|
-
})
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
function update_config_archive(config_file_data, client_name) {
|
|
209
|
-
return new Promise((resolve, reject) => {
|
|
210
|
-
read_config_file(config_archive_file_path)
|
|
211
|
-
.then((config_archive_data) => {
|
|
212
|
-
try {
|
|
213
|
-
config_archive_data = JSON.parse(config_archive_data)
|
|
214
|
-
} catch (error) {
|
|
215
|
-
console.error(`Error parsing config archive data: ${error}`)
|
|
216
|
-
reject(error)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
config_archive_data.client_exchange_pairs[client_name] = config_file_data.client_exchange_pairs[client_name]
|
|
220
|
-
config_archive_data.client_pair_main_exchanges[client_name] = config_file_data.client_pair_main_exchanges[client_name]
|
|
221
|
-
config_archive_data.clients_reporter_interval[client_name] = config_file_data.clients_reporter_interval[client_name]
|
|
222
|
-
config_archive_data.client_not_include_exchanges[client_name] = config_file_data.client_not_include_exchanges[client_name]
|
|
223
|
-
config_archive_data.client_levels[client_name] = config_file_data.client_levels[client_name]
|
|
224
|
-
config_archive_data.client_price_index_curs[client_name] = config_file_data.client_price_index_curs[client_name]
|
|
225
|
-
config_archive_data.client_telegram_ids[client_name] = config_file_data.client_telegram_ids[client_name]
|
|
226
|
-
|
|
227
|
-
if (!config_archive_data.client_enabled) {
|
|
228
|
-
config_archive_data.client_enabled = {}
|
|
229
|
-
}
|
|
230
|
-
for (let key in config_file_data.client_enabled) {
|
|
231
|
-
if (config_file_data.client_enabled.hasOwnProperty(key)) {
|
|
232
|
-
if (!config_archive_data.client_enabled[key]) {
|
|
233
|
-
config_archive_data.client_enabled[key] = {}
|
|
234
|
-
}
|
|
235
|
-
config_archive_data.client_enabled[key][client_name] = config_file_data.client_enabled[key][client_name]
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
config_archive_data.client_exchange_pairs = sort(config_archive_data.client_exchange_pairs)
|
|
240
|
-
config_archive_data.client_pair_main_exchanges = sort(config_archive_data.client_pair_main_exchanges)
|
|
241
|
-
config_archive_data.clients_reporter_interval = sort(config_archive_data.clients_reporter_interval)
|
|
242
|
-
config_archive_data.client_not_include_exchanges = sort(config_archive_data.client_not_include_exchanges)
|
|
243
|
-
config_archive_data.client_levels = sort(config_archive_data.client_levels)
|
|
244
|
-
config_archive_data.client_price_index_curs = sort(config_archive_data.client_price_index_curs)
|
|
245
|
-
config_archive_data.client_telegram_ids = sort(config_archive_data.client_telegram_ids)
|
|
246
|
-
|
|
247
|
-
for (let key in config_archive_data.client_enabled) {
|
|
248
|
-
if (config_archive_data.client_enabled.hasOwnProperty(key)) {
|
|
249
|
-
config_archive_data.client_enabled[key] = sort(config_archive_data.client_enabled[key])
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
write_config_file(config_archive_data, config_archive_file_path)
|
|
254
|
-
.then(() => {
|
|
255
|
-
resolve()
|
|
256
|
-
})
|
|
257
|
-
.catch((err) => {
|
|
258
|
-
console.error(`Error writing to config file: ${err}`)
|
|
259
|
-
reject(err)
|
|
260
|
-
})
|
|
261
|
-
})
|
|
262
|
-
.catch((err) => {
|
|
263
|
-
console.error(`Error reading config archive file: ${err}`)
|
|
264
|
-
reject(err)
|
|
265
|
-
})
|
|
266
|
-
})
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
function sort(obj) {
|
|
270
|
-
return Object.keys(obj)
|
|
271
|
-
.sort()
|
|
272
|
-
.reduce((result, key) => {
|
|
273
|
-
result[key] = obj[key]
|
|
274
|
-
return result
|
|
275
|
-
}, {})
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
process_config()
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const prompt = require('prompt')
|
|
3
|
+
|
|
4
|
+
const config_file_path = './config.json'
|
|
5
|
+
const config_archive_file_path = './config-archive.json'
|
|
6
|
+
|
|
7
|
+
prompt.start()
|
|
8
|
+
|
|
9
|
+
function read_config_file(path) {
|
|
10
|
+
return new Promise((resolve, reject) => {
|
|
11
|
+
fs.readFile(path, 'utf8', (err, data) => {
|
|
12
|
+
if (err) reject(err)
|
|
13
|
+
else resolve(data)
|
|
14
|
+
})
|
|
15
|
+
})
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function write_config_file(data, path) {
|
|
19
|
+
return new Promise((resolve, reject) => {
|
|
20
|
+
fs.writeFile(path, JSON.stringify(data, null, 2), 'utf8', (err) => {
|
|
21
|
+
if (err) return reject(err)
|
|
22
|
+
else resolve()
|
|
23
|
+
})
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function process_config() {
|
|
28
|
+
try {
|
|
29
|
+
const schema = {
|
|
30
|
+
properties: {
|
|
31
|
+
action: {
|
|
32
|
+
description: 'Enter the action ( add, delete )',
|
|
33
|
+
pattern: /^(add|delete)$/,
|
|
34
|
+
message: 'Action must be one of "add", "delete"',
|
|
35
|
+
required: true,
|
|
36
|
+
},
|
|
37
|
+
client_name: {
|
|
38
|
+
description: 'Enter the client name you want to perform the action on',
|
|
39
|
+
required: true,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
prompt.get(schema, (err, result) => {
|
|
45
|
+
if (err) {
|
|
46
|
+
console.error(err)
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
switch (result.action) {
|
|
51
|
+
case 'add':
|
|
52
|
+
add_client(result.client_name)
|
|
53
|
+
break
|
|
54
|
+
case 'delete':
|
|
55
|
+
delete_client(result.client_name)
|
|
56
|
+
break
|
|
57
|
+
default:
|
|
58
|
+
console.log('Invalid action')
|
|
59
|
+
break
|
|
60
|
+
}
|
|
61
|
+
})
|
|
62
|
+
} catch (error) {
|
|
63
|
+
console.error(`Error processing the config file: ${error}`)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function delete_client(client_name) {
|
|
68
|
+
read_config_file(config_file_path)
|
|
69
|
+
.then((config_file_data) => {
|
|
70
|
+
config_file_data = JSON.parse(config_file_data)
|
|
71
|
+
|
|
72
|
+
update_config_archive(config_file_data, client_name)
|
|
73
|
+
.then(() => {
|
|
74
|
+
delete config_file_data.client_exchange_pairs[client_name]
|
|
75
|
+
delete config_file_data.client_pair_main_exchanges[client_name]
|
|
76
|
+
delete config_file_data.client_not_include_exchanges[client_name]
|
|
77
|
+
delete config_file_data.client_levels[client_name]
|
|
78
|
+
delete config_file_data.client_price_index_curs[client_name]
|
|
79
|
+
delete config_file_data.client_telegram_ids[client_name]
|
|
80
|
+
delete config_file_data.clients_reporter_interval[client_name]
|
|
81
|
+
|
|
82
|
+
for (let key in config_file_data.client_enabled) {
|
|
83
|
+
if (config_file_data.client_enabled.hasOwnProperty(key)) {
|
|
84
|
+
delete config_file_data.client_enabled[key][client_name]
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
write_config_file(config_file_data, config_file_path)
|
|
89
|
+
.then(() => {
|
|
90
|
+
console.log(`Client '${client_name}' has been deleted successfully.`)
|
|
91
|
+
})
|
|
92
|
+
.catch((err) => {
|
|
93
|
+
console.error(`Error writing to config file: ${err}`)
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
.catch((err) => {
|
|
97
|
+
console.error(`Error updating config archive: ${err}`)
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
.catch((err) => {
|
|
101
|
+
console.error(`Error reading config file: ${err}`)
|
|
102
|
+
})
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function add_client(client_name) {
|
|
106
|
+
const schema = {
|
|
107
|
+
properties: {
|
|
108
|
+
client_exchange_pairs: {
|
|
109
|
+
description: 'Enter client exchange pairs (JSON format i.e { "Mexc": ["RWXUSDT"], "Bitget": ["RWXUSDT"] } )',
|
|
110
|
+
required: true,
|
|
111
|
+
pattern: /^\{.*\}$/,
|
|
112
|
+
message: 'Please enter a valid JSON object.',
|
|
113
|
+
},
|
|
114
|
+
client_not_include_exchanges: {
|
|
115
|
+
description: 'Enter client not include exchanges (Comma-separated values, e.g., Jubi, Lbank)',
|
|
116
|
+
required: false,
|
|
117
|
+
},
|
|
118
|
+
client_pair_main_exchanges: {
|
|
119
|
+
description: 'Enter client pair main exchanges (JSON format i.e {"ETHUSDT": ["Bitget", "Gate"]} )',
|
|
120
|
+
required: true,
|
|
121
|
+
pattern: /^\{.*\}$/,
|
|
122
|
+
message: 'Please enter a valid JSON object.',
|
|
123
|
+
},
|
|
124
|
+
clients_reporter_interval: {
|
|
125
|
+
description: 'Enter clients reporter interval (JSON format i.e { "balance": 1, "trades": 1, "orderbook": 1} )',
|
|
126
|
+
required: true,
|
|
127
|
+
pattern: /^\{.*\}$/,
|
|
128
|
+
message: 'Please enter a valid JSON object.',
|
|
129
|
+
},
|
|
130
|
+
client_levels: {
|
|
131
|
+
description: 'Enter client levels (Comma-separated values, e.g. 2, 5, 10 ) ',
|
|
132
|
+
required: true,
|
|
133
|
+
},
|
|
134
|
+
client_price_index_curs: {
|
|
135
|
+
description: 'Enter client benchmarks (Comma-separated values, e.g., BTC,ETH)',
|
|
136
|
+
required: false,
|
|
137
|
+
},
|
|
138
|
+
client_telegram_ids: {
|
|
139
|
+
description: 'Enter client telegram ids i.e 1233457 ',
|
|
140
|
+
required: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
}
|
|
144
|
+
read_config_file(config_file_path)
|
|
145
|
+
.then((config_file_data) => {
|
|
146
|
+
prompt.get(schema, (err, result) => {
|
|
147
|
+
if (err) {
|
|
148
|
+
console.error(err)
|
|
149
|
+
return
|
|
150
|
+
}
|
|
151
|
+
config_file_data = JSON.parse(config_file_data)
|
|
152
|
+
|
|
153
|
+
let exchange_pairs = result.client_exchange_pairs.trim()
|
|
154
|
+
exchange_pairs = JSON.parse(exchange_pairs)
|
|
155
|
+
|
|
156
|
+
let pair_exchanges = result.client_pair_main_exchanges.trim()
|
|
157
|
+
pair_exchanges = JSON.parse(pair_exchanges)
|
|
158
|
+
|
|
159
|
+
let reporter_interval = result.clients_reporter_interval.trim()
|
|
160
|
+
reporter_interval = JSON.parse(reporter_interval)
|
|
161
|
+
|
|
162
|
+
let not_include_exchanges = []
|
|
163
|
+
if (result.client_not_include_exchanges) {
|
|
164
|
+
not_include_exchanges = result.client_not_include_exchanges.split(',').map((value) => value.trim())
|
|
165
|
+
not_include_exchanges.sort()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
let benchmarks = []
|
|
169
|
+
if (result.client_price_index_curs) {
|
|
170
|
+
benchmarks = result.client_price_index_curs.split(',').map((value) => value.trim())
|
|
171
|
+
benchmarks.sort()
|
|
172
|
+
}
|
|
173
|
+
let levels = result.client_levels.split(',').map((value) => Number(value.trim()))
|
|
174
|
+
|
|
175
|
+
config_file_data.client_exchange_pairs[client_name] = exchange_pairs
|
|
176
|
+
config_file_data.client_pair_main_exchanges[client_name] = pair_exchanges
|
|
177
|
+
|
|
178
|
+
config_file_data.clients_reporter_interval[client_name] = reporter_interval
|
|
179
|
+
|
|
180
|
+
config_file_data.client_not_include_exchanges[client_name] = not_include_exchanges
|
|
181
|
+
config_file_data.client_levels[client_name] = levels
|
|
182
|
+
config_file_data.client_price_index_curs[client_name] = benchmarks
|
|
183
|
+
|
|
184
|
+
config_file_data.client_telegram_ids[client_name] = result.client_telegram_ids
|
|
185
|
+
|
|
186
|
+
config_file_data.client_exchange_pairs = sort(config_file_data.client_exchange_pairs)
|
|
187
|
+
config_file_data.client_pair_main_exchanges = sort(config_file_data.client_pair_main_exchanges)
|
|
188
|
+
config_file_data.clients_reporter_interval = sort(config_file_data.clients_reporter_interval)
|
|
189
|
+
config_file_data.client_not_include_exchanges = sort(config_file_data.client_not_include_exchanges)
|
|
190
|
+
config_file_data.client_levels = sort(config_file_data.client_levels)
|
|
191
|
+
config_file_data.client_price_index_curs = sort(config_file_data.client_price_index_curs)
|
|
192
|
+
config_file_data.client_telegram_ids = sort(config_file_data.client_telegram_ids)
|
|
193
|
+
|
|
194
|
+
write_config_file(config_file_data, config_file_path)
|
|
195
|
+
.then(() => {
|
|
196
|
+
console.log(`Client '${client_name}' has been added successfully.`)
|
|
197
|
+
})
|
|
198
|
+
.catch((err) => {
|
|
199
|
+
console.error(`Error writing to config file: ${err}`)
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
})
|
|
203
|
+
.catch((err) => {
|
|
204
|
+
console.error(`Error reading config file: ${err}`)
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function update_config_archive(config_file_data, client_name) {
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
read_config_file(config_archive_file_path)
|
|
211
|
+
.then((config_archive_data) => {
|
|
212
|
+
try {
|
|
213
|
+
config_archive_data = JSON.parse(config_archive_data)
|
|
214
|
+
} catch (error) {
|
|
215
|
+
console.error(`Error parsing config archive data: ${error}`)
|
|
216
|
+
reject(error)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
config_archive_data.client_exchange_pairs[client_name] = config_file_data.client_exchange_pairs[client_name]
|
|
220
|
+
config_archive_data.client_pair_main_exchanges[client_name] = config_file_data.client_pair_main_exchanges[client_name]
|
|
221
|
+
config_archive_data.clients_reporter_interval[client_name] = config_file_data.clients_reporter_interval[client_name]
|
|
222
|
+
config_archive_data.client_not_include_exchanges[client_name] = config_file_data.client_not_include_exchanges[client_name]
|
|
223
|
+
config_archive_data.client_levels[client_name] = config_file_data.client_levels[client_name]
|
|
224
|
+
config_archive_data.client_price_index_curs[client_name] = config_file_data.client_price_index_curs[client_name]
|
|
225
|
+
config_archive_data.client_telegram_ids[client_name] = config_file_data.client_telegram_ids[client_name]
|
|
226
|
+
|
|
227
|
+
if (!config_archive_data.client_enabled) {
|
|
228
|
+
config_archive_data.client_enabled = {}
|
|
229
|
+
}
|
|
230
|
+
for (let key in config_file_data.client_enabled) {
|
|
231
|
+
if (config_file_data.client_enabled.hasOwnProperty(key)) {
|
|
232
|
+
if (!config_archive_data.client_enabled[key]) {
|
|
233
|
+
config_archive_data.client_enabled[key] = {}
|
|
234
|
+
}
|
|
235
|
+
config_archive_data.client_enabled[key][client_name] = config_file_data.client_enabled[key][client_name]
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
config_archive_data.client_exchange_pairs = sort(config_archive_data.client_exchange_pairs)
|
|
240
|
+
config_archive_data.client_pair_main_exchanges = sort(config_archive_data.client_pair_main_exchanges)
|
|
241
|
+
config_archive_data.clients_reporter_interval = sort(config_archive_data.clients_reporter_interval)
|
|
242
|
+
config_archive_data.client_not_include_exchanges = sort(config_archive_data.client_not_include_exchanges)
|
|
243
|
+
config_archive_data.client_levels = sort(config_archive_data.client_levels)
|
|
244
|
+
config_archive_data.client_price_index_curs = sort(config_archive_data.client_price_index_curs)
|
|
245
|
+
config_archive_data.client_telegram_ids = sort(config_archive_data.client_telegram_ids)
|
|
246
|
+
|
|
247
|
+
for (let key in config_archive_data.client_enabled) {
|
|
248
|
+
if (config_archive_data.client_enabled.hasOwnProperty(key)) {
|
|
249
|
+
config_archive_data.client_enabled[key] = sort(config_archive_data.client_enabled[key])
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
write_config_file(config_archive_data, config_archive_file_path)
|
|
254
|
+
.then(() => {
|
|
255
|
+
resolve()
|
|
256
|
+
})
|
|
257
|
+
.catch((err) => {
|
|
258
|
+
console.error(`Error writing to config file: ${err}`)
|
|
259
|
+
reject(err)
|
|
260
|
+
})
|
|
261
|
+
})
|
|
262
|
+
.catch((err) => {
|
|
263
|
+
console.error(`Error reading config archive file: ${err}`)
|
|
264
|
+
reject(err)
|
|
265
|
+
})
|
|
266
|
+
})
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function sort(obj) {
|
|
270
|
+
return Object.keys(obj)
|
|
271
|
+
.sort()
|
|
272
|
+
.reduce((result, key) => {
|
|
273
|
+
result[key] = obj[key]
|
|
274
|
+
return result
|
|
275
|
+
}, {})
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
process_config()
|