@airmoney-degn/airmoney-cli 0.17.0 → 0.18.0
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/cli/create.js +48 -58
- package/dist/cli/dapp.js +97 -0
- package/dist/cli/demo.js +34 -28
- package/dist/cli/setup.js +17 -104
- package/dist/cli/upload.js +69 -64
- package/dist/cli/wallet.js +46 -30
- package/dist/config.json +1 -1
- package/dist/index.js +20 -41
- package/dist/service/airmoney/AirmoneyService.js +3 -2
- package/dist/service/dapp/DappService.js +162 -0
- package/dist/service/log/LogService.js +85 -0
- package/dist/service/port/PortManager.js +5 -4
- package/dist/service/serve/ServeOrchestrator.js +2 -1
- package/dist/service/simulator/BaseSimulatorService.js +5 -4
- package/dist/util/cryptoProcess.js +22 -21
- package/dist/util/env.js +44 -0
- package/dist/util/format.js +74 -0
- package/dist/util/metadata.js +3 -2
- package/dist/util/network.js +12 -7
- package/dist/util/tarball.js +6 -5
- package/package.json +3 -2
package/dist/cli/wallet.js
CHANGED
|
@@ -51,16 +51,22 @@ const ethers_1 = require("ethers");
|
|
|
51
51
|
const bs58 = __importStar(require("bs58"));
|
|
52
52
|
const web3_js_1 = require("@solana/web3.js");
|
|
53
53
|
const cryptoProcess_1 = require("../util/cryptoProcess");
|
|
54
|
+
const LogService_1 = require("../service/log/LogService");
|
|
54
55
|
async function deleteWallet(address, chainName) {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
56
|
+
try {
|
|
57
|
+
const config = (0, env_1.configDir)();
|
|
58
|
+
const walletPath = path_1.default.join(config, chainName);
|
|
59
|
+
const files = (0, fs_1.readdirSync)(walletPath).filter(file => file == address + '.json');
|
|
60
|
+
if (files.length == 0) {
|
|
61
|
+
(0, LogService_1.log)('Wallet not found').white();
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const walletFile = path_1.default.join(walletPath, files[0]);
|
|
65
|
+
(0, fs_1.rmSync)(walletFile);
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
(0, LogService_1.log)(`${err instanceof Error ? err.message : String(err)}`).red();
|
|
69
|
+
}
|
|
64
70
|
}
|
|
65
71
|
async function listWallet(chainName) {
|
|
66
72
|
try {
|
|
@@ -78,22 +84,27 @@ async function listWallet(chainName) {
|
|
|
78
84
|
});
|
|
79
85
|
// Display wallets
|
|
80
86
|
wallets.wallets.forEach((address) => {
|
|
81
|
-
|
|
87
|
+
(0, LogService_1.log)(address).white();
|
|
82
88
|
});
|
|
83
89
|
return wallets;
|
|
84
90
|
}
|
|
85
91
|
catch (error) {
|
|
86
|
-
|
|
92
|
+
(0, LogService_1.log)(`Failed to list wallets: ${error instanceof Error ? error.message : String(error)}`).red();
|
|
87
93
|
throw error;
|
|
88
94
|
}
|
|
89
95
|
}
|
|
90
96
|
async function importWalletSk(PrivateKey, chainName) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
97
|
+
try {
|
|
98
|
+
(0, cryptoProcess_1.ensureWalletDirectory)(chainName);
|
|
99
|
+
if (chainName == 'evm') {
|
|
100
|
+
await importEvmWallet(PrivateKey);
|
|
101
|
+
}
|
|
102
|
+
else if (chainName == 'svm') {
|
|
103
|
+
await importSvmWallet(PrivateKey);
|
|
104
|
+
}
|
|
94
105
|
}
|
|
95
|
-
|
|
96
|
-
|
|
106
|
+
catch (err) {
|
|
107
|
+
(0, LogService_1.log)(`${err instanceof Error ? err.message : String(err)}`).red();
|
|
97
108
|
}
|
|
98
109
|
}
|
|
99
110
|
async function importEvmWallet(PrivateKey) {
|
|
@@ -117,17 +128,22 @@ async function importSvmWallet(privateKey) {
|
|
|
117
128
|
}, null, 2));
|
|
118
129
|
}
|
|
119
130
|
async function exportWalletSk(address, chainName) {
|
|
120
|
-
const walletPath = (0, cryptoProcess_1.ensureWalletDirectory)(chainName);
|
|
121
|
-
let walletFile;
|
|
122
131
|
try {
|
|
123
|
-
|
|
132
|
+
const walletPath = (0, cryptoProcess_1.ensureWalletDirectory)(chainName);
|
|
133
|
+
let walletFile;
|
|
134
|
+
try {
|
|
135
|
+
walletFile = (0, fs_1.readFileSync)(path_1.default.join(walletPath, address + '.json'));
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
(0, LogService_1.log)('Wallet not found').white();
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const wallet = JSON.parse(walletFile.toString());
|
|
142
|
+
(0, LogService_1.log)(wallet.private_key).white();
|
|
124
143
|
}
|
|
125
|
-
catch (
|
|
126
|
-
|
|
127
|
-
return;
|
|
144
|
+
catch (err) {
|
|
145
|
+
(0, LogService_1.log)(`${err instanceof Error ? err.message : String(err)}`).red();
|
|
128
146
|
}
|
|
129
|
-
const wallet = JSON.parse(walletFile.toString());
|
|
130
|
-
console.log(wallet.private_key);
|
|
131
147
|
}
|
|
132
148
|
async function generateWallet(chainName) {
|
|
133
149
|
try {
|
|
@@ -143,11 +159,11 @@ async function generateWallet(chainName) {
|
|
|
143
159
|
throw new Error(`Unsupported chain: ${chainName}`);
|
|
144
160
|
}
|
|
145
161
|
});
|
|
146
|
-
|
|
162
|
+
(0, LogService_1.log)(`Generated ${chainName} wallet: ${walletData.address}`).green();
|
|
147
163
|
return walletData;
|
|
148
164
|
}
|
|
149
165
|
catch (error) {
|
|
150
|
-
|
|
166
|
+
(0, LogService_1.log)(`Failed to generate wallet: ${error instanceof Error ? error.message : String(error)}`).red();
|
|
151
167
|
throw error;
|
|
152
168
|
}
|
|
153
169
|
}
|
|
@@ -165,10 +181,10 @@ async function setDefaultWallet(address, chainName) {
|
|
|
165
181
|
throw new Error(`Unsupported chain: ${chainName}`);
|
|
166
182
|
}
|
|
167
183
|
});
|
|
168
|
-
|
|
184
|
+
(0, LogService_1.log)(`Set ${chainName} default wallet to: ${address}`).green();
|
|
169
185
|
}
|
|
170
186
|
catch (error) {
|
|
171
|
-
|
|
187
|
+
(0, LogService_1.log)(`Failed to set default wallet: ${error instanceof Error ? error.message : String(error)}`).red();
|
|
172
188
|
throw error;
|
|
173
189
|
}
|
|
174
190
|
}
|
|
@@ -186,11 +202,11 @@ async function getDefaultWallet(chainName) {
|
|
|
186
202
|
throw new Error(`Unsupported chain: ${chainName}`);
|
|
187
203
|
}
|
|
188
204
|
});
|
|
189
|
-
|
|
205
|
+
(0, LogService_1.log)(`Default ${chainName} wallet: ${walletData.address}`).white();
|
|
190
206
|
return walletData;
|
|
191
207
|
}
|
|
192
208
|
catch (error) {
|
|
193
|
-
|
|
209
|
+
(0, LogService_1.log)(`Failed to get default wallet: ${error instanceof Error ? error.message : String(error)}`).red();
|
|
194
210
|
throw error;
|
|
195
211
|
}
|
|
196
212
|
}
|
package/dist/config.json
CHANGED
package/dist/index.js
CHANGED
|
@@ -8,9 +8,10 @@ const create_1 = require("./cli/create");
|
|
|
8
8
|
const serve_1 = require("./cli/serve");
|
|
9
9
|
const upload_1 = require("./cli/upload");
|
|
10
10
|
const setup_1 = require("./cli/setup");
|
|
11
|
-
const
|
|
11
|
+
const dapp_1 = require("./cli/dapp");
|
|
12
12
|
const wallet_1 = require("./cli/wallet");
|
|
13
13
|
const config_json_1 = require("./config.json");
|
|
14
|
+
const LogService_1 = require("./service/log/LogService");
|
|
14
15
|
// Load environment from config
|
|
15
16
|
(0, env_1.loadEnvFromConfig)();
|
|
16
17
|
const program = new commander_1.Command();
|
|
@@ -21,42 +22,22 @@ program
|
|
|
21
22
|
program
|
|
22
23
|
.command('setup')
|
|
23
24
|
.description('Setup env with userAddress, apiKey, rpc')
|
|
24
|
-
.
|
|
25
|
-
.
|
|
26
|
-
.option('-n, --network <string>', 'network devnet|mainnet'
|
|
27
|
-
.option('-s, --status', 'check current credential status')
|
|
25
|
+
.requiredOption('-u, --user <string>', 'developer user')
|
|
26
|
+
.requiredOption('-k, --key <string>', 'API key')
|
|
27
|
+
.option('-n, --network <string>', 'network devnet|mainnet')
|
|
28
28
|
.action(opts => {
|
|
29
|
-
const { user, key, network
|
|
30
|
-
|
|
31
|
-
(0, setup_1.statusCommand)();
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
if (!user || !key) {
|
|
35
|
-
console.error('Error: --user and --key are required');
|
|
36
|
-
process.exit(1);
|
|
37
|
-
}
|
|
38
|
-
if (network) {
|
|
39
|
-
try {
|
|
40
|
-
(0, network_1.validateNetwork)(network);
|
|
41
|
-
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
44
|
-
process.exit(1);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
(0, setup_1.setupCommand)({ network, userId: user, apiKey: key });
|
|
48
|
-
}
|
|
29
|
+
const { user, key, network } = opts;
|
|
30
|
+
(0, setup_1.setupCommand)({ network, userId: user, apiKey: key });
|
|
49
31
|
});
|
|
50
32
|
program
|
|
51
33
|
.command('create')
|
|
52
34
|
.description('Initialize a new project')
|
|
53
35
|
.requiredOption('-N, --name <string>', 'Project name')
|
|
54
|
-
// .option('-n, --network <string>', 'network devnet|mainnet', 'devnet')
|
|
55
36
|
.option('-f, --app-path <string>', 'path where project will be created')
|
|
56
37
|
.option('--template', 'initialize project based on git quickstart')
|
|
57
|
-
.action(
|
|
38
|
+
.action(opts => {
|
|
58
39
|
const { name, appPath, template } = opts;
|
|
59
|
-
|
|
40
|
+
(0, create_1.createCommand)({ name, template, locationFolder: appPath });
|
|
60
41
|
});
|
|
61
42
|
program
|
|
62
43
|
.command('serve')
|
|
@@ -64,16 +45,16 @@ program
|
|
|
64
45
|
.option('-f, --index-app-path <string>', 'path for the index.html', './')
|
|
65
46
|
.option('--no-browser', 'stop browser from being open')
|
|
66
47
|
.option('-u, --app-url <string>', 'url where the app is running')
|
|
67
|
-
.action(
|
|
48
|
+
.action(opts => {
|
|
68
49
|
let { indexAppPath, browser, appUrl } = opts;
|
|
69
50
|
if (indexAppPath == './') {
|
|
70
51
|
indexAppPath = undefined;
|
|
71
52
|
}
|
|
72
53
|
if (indexAppPath && appUrl) {
|
|
73
|
-
|
|
54
|
+
(0, LogService_1.log)('both --index-app-path and --app-url must not be used simuntaniusly').red();
|
|
74
55
|
return;
|
|
75
56
|
}
|
|
76
|
-
|
|
57
|
+
(0, serve_1.serveCommand)({
|
|
77
58
|
noBrowser: !browser,
|
|
78
59
|
locationFolder: indexAppPath,
|
|
79
60
|
appUrl,
|
|
@@ -117,7 +98,7 @@ program
|
|
|
117
98
|
program
|
|
118
99
|
.command('upload')
|
|
119
100
|
.description('Publish the app to the DEGN Dapp Store')
|
|
120
|
-
.option('-n, --network <string>', 'network devnet|mainnet'
|
|
101
|
+
.option('-n, --network <string>', 'network devnet|mainnet')
|
|
121
102
|
.option('-f, --index-app-path <string>', 'path for the index.html', './')
|
|
122
103
|
.option('-i, --button-image <string>', 'path for the button images', 'assets')
|
|
123
104
|
.action(opts => {
|
|
@@ -125,21 +106,19 @@ program
|
|
|
125
106
|
if (indexAppPath == './') {
|
|
126
107
|
indexAppPath = undefined;
|
|
127
108
|
}
|
|
128
|
-
if (network) {
|
|
129
|
-
try {
|
|
130
|
-
(0, network_1.validateNetwork)(network);
|
|
131
|
-
}
|
|
132
|
-
catch (err) {
|
|
133
|
-
console.error('Error:', err instanceof Error ? err.message : String(err));
|
|
134
|
-
process.exit(1);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
109
|
(0, upload_1.uploadCommand)({
|
|
138
110
|
network,
|
|
139
111
|
locationFolder: indexAppPath,
|
|
140
112
|
buttonImages: buttonImage,
|
|
141
113
|
});
|
|
142
114
|
});
|
|
115
|
+
program
|
|
116
|
+
.command('dapp')
|
|
117
|
+
.description('Manage dapps')
|
|
118
|
+
.option('-s, --status', 'show all dapps list')
|
|
119
|
+
.action(() => {
|
|
120
|
+
(0, dapp_1.dappStatusCommand)();
|
|
121
|
+
});
|
|
143
122
|
program
|
|
144
123
|
.command('demo')
|
|
145
124
|
.option('-N, --name <string>', 'Project name')
|
|
@@ -7,6 +7,7 @@ exports.AirmoneyService = void 0;
|
|
|
7
7
|
const express_1 = __importDefault(require("express"));
|
|
8
8
|
const cors_1 = __importDefault(require("cors"));
|
|
9
9
|
const server_1 = require("../../util/server");
|
|
10
|
+
const LogService_1 = require("../log/LogService");
|
|
10
11
|
class AirmoneyService {
|
|
11
12
|
constructor(config) {
|
|
12
13
|
this.simulatorClient = null;
|
|
@@ -40,7 +41,7 @@ class AirmoneyService {
|
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
else {
|
|
43
|
-
|
|
44
|
+
(0, LogService_1.log)('No simulator client connected').white();
|
|
44
45
|
res.status(503).json({ error: 'Simulator not connected' });
|
|
45
46
|
return;
|
|
46
47
|
}
|
|
@@ -62,7 +63,7 @@ class AirmoneyService {
|
|
|
62
63
|
return new Promise(resolve => {
|
|
63
64
|
this.server = this.app.listen(this.config.port, () => {
|
|
64
65
|
const url = `http://localhost:${this.config.port}`;
|
|
65
|
-
|
|
66
|
+
(0, LogService_1.log)(`Starting airmoney service server at ${url}`).green();
|
|
66
67
|
resolve();
|
|
67
68
|
});
|
|
68
69
|
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DappService = void 0;
|
|
7
|
+
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
8
|
+
const network_1 = require("../../util/network");
|
|
9
|
+
/**
|
|
10
|
+
* Service for fetching and managing dapp information
|
|
11
|
+
*/
|
|
12
|
+
class DappService {
|
|
13
|
+
constructor(userId, apiKey, network) {
|
|
14
|
+
this.userId = userId;
|
|
15
|
+
this.apiKey = apiKey;
|
|
16
|
+
this.network = network;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parses JSON-RPC error response and extracts error message
|
|
20
|
+
* Combines error.message and error.data fields (message first, then data)
|
|
21
|
+
*/
|
|
22
|
+
parseJsonRpcError(json) {
|
|
23
|
+
if (!json.error) {
|
|
24
|
+
return 'Unknown error';
|
|
25
|
+
}
|
|
26
|
+
let errorMessageParts = [];
|
|
27
|
+
// Add message field first if it exists
|
|
28
|
+
if (json.error.message) {
|
|
29
|
+
errorMessageParts.push(json.error.message);
|
|
30
|
+
}
|
|
31
|
+
// Parse and add data field if it exists and is different from message
|
|
32
|
+
if (json.error.data !== undefined) {
|
|
33
|
+
let dataMessage = '';
|
|
34
|
+
if (typeof json.error.data === 'string') {
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(json.error.data);
|
|
37
|
+
dataMessage = parsed;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
dataMessage = json.error.data.replace(/^"|"$/g, '');
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
dataMessage = String(json.error.data);
|
|
45
|
+
}
|
|
46
|
+
// Only add data if it's different from message
|
|
47
|
+
if (dataMessage && dataMessage !== json.error.message) {
|
|
48
|
+
errorMessageParts.push(dataMessage);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Combine into final error message
|
|
52
|
+
return errorMessageParts.length > 0
|
|
53
|
+
? errorMessageParts.join(' - ')
|
|
54
|
+
: 'Unknown error';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Makes a JSON-RPC request and handles common response patterns
|
|
58
|
+
* Throws error for HTTP errors or JSON-RPC errors
|
|
59
|
+
*/
|
|
60
|
+
async makeJsonRpcRequest(method, params) {
|
|
61
|
+
const apiUrl = (0, network_1.networkToRpcUrl)(this.network);
|
|
62
|
+
const body = JSON.stringify({
|
|
63
|
+
jsonrpc: '2.0',
|
|
64
|
+
id: 1,
|
|
65
|
+
method,
|
|
66
|
+
params,
|
|
67
|
+
});
|
|
68
|
+
const res = await (0, node_fetch_1.default)(apiUrl, {
|
|
69
|
+
method: 'POST',
|
|
70
|
+
body,
|
|
71
|
+
headers: {
|
|
72
|
+
'Content-Type': 'application/json',
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
if (!res.ok) {
|
|
76
|
+
throw new Error(`HTTP ${res.status} - ${await res.text()}`);
|
|
77
|
+
}
|
|
78
|
+
const json = (await res.json());
|
|
79
|
+
if ('error' in json) {
|
|
80
|
+
throw new Error(this.parseJsonRpcError(json));
|
|
81
|
+
}
|
|
82
|
+
return json.result;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Validates API key before making dapp API calls
|
|
86
|
+
*/
|
|
87
|
+
async validateApiKey() {
|
|
88
|
+
return await this.makeJsonRpcRequest('checkApiKey', [this.userId, this.apiKey]);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Fetches dapp list from API
|
|
92
|
+
*/
|
|
93
|
+
async fetchDappList() {
|
|
94
|
+
return await this.makeJsonRpcRequest('getDappList', [this.userId, this.apiKey]);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Fetches dapp versions/builds from API
|
|
98
|
+
*/
|
|
99
|
+
async fetchDappVersions(dappName) {
|
|
100
|
+
return await this.makeJsonRpcRequest('checkDappVersions', [this.userId, this.apiKey, dappName]);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Fetches JSON from an external URL
|
|
104
|
+
* Used for fetching metadata from meta_url
|
|
105
|
+
*/
|
|
106
|
+
async fetchJsonFromUrl(url) {
|
|
107
|
+
try {
|
|
108
|
+
const res = await (0, node_fetch_1.default)(url);
|
|
109
|
+
if (!res.ok) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
return await res.json();
|
|
113
|
+
}
|
|
114
|
+
catch (err) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Fetches metadata for builds
|
|
120
|
+
*/
|
|
121
|
+
async fetchMetaForBuilds(builds) {
|
|
122
|
+
const updatedBuilds = [];
|
|
123
|
+
for (const b of builds) {
|
|
124
|
+
let metaAuthor = 'N/A';
|
|
125
|
+
let metaIdentifier = 'N/A';
|
|
126
|
+
let metaMaintainer = 'N/A';
|
|
127
|
+
if (b.meta_url) {
|
|
128
|
+
const metaJson = await this.fetchJsonFromUrl(b.meta_url);
|
|
129
|
+
if (metaJson) {
|
|
130
|
+
if (metaJson.author)
|
|
131
|
+
metaAuthor = metaJson.author;
|
|
132
|
+
if (metaJson.identifier)
|
|
133
|
+
metaIdentifier = metaJson.identifier;
|
|
134
|
+
if (metaJson.maintainer)
|
|
135
|
+
metaMaintainer = metaJson.maintainer;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
updatedBuilds.push({
|
|
139
|
+
...b,
|
|
140
|
+
author: metaAuthor,
|
|
141
|
+
identifier: metaIdentifier,
|
|
142
|
+
maintainer: metaMaintainer,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return updatedBuilds;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Fetches dapp details including builds with metadata
|
|
149
|
+
*/
|
|
150
|
+
async fetchDappDetails(dappName) {
|
|
151
|
+
const builds = await this.fetchDappVersions(dappName);
|
|
152
|
+
const buildsWithMeta = await this.fetchMetaForBuilds(builds);
|
|
153
|
+
// Sort by version (descending)
|
|
154
|
+
buildsWithMeta.sort((a, b) => {
|
|
155
|
+
const aVer = parseFloat(a.version || '0') || 0;
|
|
156
|
+
const bVer = parseFloat(b.version || '0') || 0;
|
|
157
|
+
return bVer - aVer;
|
|
158
|
+
});
|
|
159
|
+
return buildsWithMeta;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
exports.DappService = DappService;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Logging service with chainable API support
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.log = log;
|
|
7
|
+
/**
|
|
8
|
+
* LogBuilder class for chainable logging
|
|
9
|
+
*/
|
|
10
|
+
class LogBuilder {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
this.isBold = false;
|
|
13
|
+
this.isItalic = false;
|
|
14
|
+
this.color = null;
|
|
15
|
+
this.message = message;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Makes the message bold
|
|
19
|
+
*/
|
|
20
|
+
bold() {
|
|
21
|
+
this.isBold = true;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Makes the message italic
|
|
26
|
+
*/
|
|
27
|
+
italic() {
|
|
28
|
+
this.isItalic = true;
|
|
29
|
+
return this;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Sets the color to red and logs
|
|
33
|
+
*/
|
|
34
|
+
red() {
|
|
35
|
+
this.color = 'red';
|
|
36
|
+
this.execute();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Sets the color to green and logs
|
|
40
|
+
*/
|
|
41
|
+
green() {
|
|
42
|
+
this.color = 'green';
|
|
43
|
+
this.execute();
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Sets the color to white and logs
|
|
47
|
+
*/
|
|
48
|
+
white() {
|
|
49
|
+
this.color = 'white';
|
|
50
|
+
this.execute();
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Executes the log with all formatting applied
|
|
54
|
+
*/
|
|
55
|
+
execute() {
|
|
56
|
+
const codes = [];
|
|
57
|
+
if (this.isBold)
|
|
58
|
+
codes.push('1');
|
|
59
|
+
if (this.isItalic)
|
|
60
|
+
codes.push('3');
|
|
61
|
+
if (this.color === 'red') {
|
|
62
|
+
codes.push('31');
|
|
63
|
+
}
|
|
64
|
+
else if (this.color === 'green') {
|
|
65
|
+
codes.push('32');
|
|
66
|
+
}
|
|
67
|
+
else if (this.color === 'white') {
|
|
68
|
+
// White is default, no color code needed
|
|
69
|
+
}
|
|
70
|
+
if (codes.length > 0) {
|
|
71
|
+
const escapeCode = '\x1b[' + codes.join(';') + 'm';
|
|
72
|
+
console.log(escapeCode + this.message + '\x1b[0m');
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
console.log(this.message);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Creates a log builder for chainable logging
|
|
81
|
+
* Usage: log('message').italic().red()
|
|
82
|
+
*/
|
|
83
|
+
function log(message) {
|
|
84
|
+
return new LogBuilder(message);
|
|
85
|
+
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.PortManager = void 0;
|
|
4
4
|
const cryptoProcess_1 = require("../../util/cryptoProcess");
|
|
5
|
+
const LogService_1 = require("../log/LogService");
|
|
5
6
|
class PortManager {
|
|
6
7
|
/**
|
|
7
8
|
* Check if any of the required ports are in use
|
|
@@ -9,11 +10,11 @@ class PortManager {
|
|
|
9
10
|
static async checkPortConflicts(ports = this.DEFAULT_PORTS) {
|
|
10
11
|
const inUsePorts = await (0, cryptoProcess_1.checkPortsInUse)(ports);
|
|
11
12
|
if (inUsePorts.length > 0) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
(0, LogService_1.log)('Port conflict detected!').red();
|
|
14
|
+
(0, LogService_1.log)(`The following ports are already in use: ${inUsePorts.join(', ')}`).red();
|
|
15
|
+
(0, LogService_1.log)('\nPlease kill the processes using these ports before running serve:').red();
|
|
15
16
|
const killCommand = `lsof -ti:${inUsePorts.join(',')} | xargs kill -9`;
|
|
16
|
-
|
|
17
|
+
(0, LogService_1.log)(` ${killCommand}`).red();
|
|
17
18
|
process.exit(1);
|
|
18
19
|
}
|
|
19
20
|
}
|
|
@@ -10,6 +10,7 @@ const cryptoProcess_1 = require("../../util/cryptoProcess");
|
|
|
10
10
|
const PortManager_1 = require("../port/PortManager");
|
|
11
11
|
const SimulatorService_1 = require("../simulator/SimulatorService");
|
|
12
12
|
const AirmoneyService_1 = require("../airmoney/AirmoneyService");
|
|
13
|
+
const LogService_1 = require("../log/LogService");
|
|
13
14
|
class ServeOrchestrator {
|
|
14
15
|
constructor(config) {
|
|
15
16
|
this.config = config;
|
|
@@ -40,7 +41,7 @@ class ServeOrchestrator {
|
|
|
40
41
|
await PortManager_1.PortManager.checkPortConflicts();
|
|
41
42
|
// Validate metadata
|
|
42
43
|
if (!this.metadata) {
|
|
43
|
-
|
|
44
|
+
(0, LogService_1.log)('No metadata found. Skipping some possible checks.').white();
|
|
44
45
|
}
|
|
45
46
|
// Start simulator service
|
|
46
47
|
await this.simulatorService.start();
|
|
@@ -10,6 +10,7 @@ const express_ws_1 = __importDefault(require("express-ws"));
|
|
|
10
10
|
const cors_1 = __importDefault(require("cors"));
|
|
11
11
|
const open_1 = __importDefault(require("open"));
|
|
12
12
|
const http_proxy_middleware_1 = require("http-proxy-middleware");
|
|
13
|
+
const LogService_1 = require("../log/LogService");
|
|
13
14
|
class BaseSimulatorService {
|
|
14
15
|
constructor(config) {
|
|
15
16
|
this.simulatorClient = null;
|
|
@@ -37,7 +38,7 @@ class BaseSimulatorService {
|
|
|
37
38
|
this.onClientConnectedCallback(this.getClient());
|
|
38
39
|
}
|
|
39
40
|
ws.on('message', (msg) => {
|
|
40
|
-
|
|
41
|
+
(0, LogService_1.log)(String(msg)).white();
|
|
41
42
|
});
|
|
42
43
|
ws.on('close', () => {
|
|
43
44
|
this.simulatorClient = null;
|
|
@@ -47,7 +48,7 @@ class BaseSimulatorService {
|
|
|
47
48
|
}
|
|
48
49
|
});
|
|
49
50
|
ws.on('error', (error) => {
|
|
50
|
-
|
|
51
|
+
(0, LogService_1.log)(`WebSocket error: ${error}`).red();
|
|
51
52
|
this.simulatorClient = null;
|
|
52
53
|
// Notify callback about disconnection due to error
|
|
53
54
|
if (this.onClientConnectedCallback) {
|
|
@@ -81,7 +82,7 @@ class BaseSimulatorService {
|
|
|
81
82
|
await (0, open_1.default)(url);
|
|
82
83
|
}
|
|
83
84
|
catch (err) {
|
|
84
|
-
|
|
85
|
+
(0, LogService_1.log)(`Failed to open web browser ${err}`).red();
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
}
|
|
@@ -114,7 +115,7 @@ class BaseSimulatorService {
|
|
|
114
115
|
return new Promise(resolve => {
|
|
115
116
|
this.server = this.app.listen(this.config.port, () => {
|
|
116
117
|
const url = `http://localhost:${this.config.port}/simulator`;
|
|
117
|
-
|
|
118
|
+
(0, LogService_1.log)(`Starting simulator server at ${url}`).green();
|
|
118
119
|
this.openBrowser();
|
|
119
120
|
resolve();
|
|
120
121
|
});
|