@bigtyphoon/melo 1.7.6 ā 1.8.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/bin/commands/add-server.ts +288 -0
- package/bin/commands/doctor.ts +514 -0
- package/bin/utils/constants.ts +4 -0
- package/dist/bin/commands/add-server.js +248 -0
- package/dist/bin/commands/doctor.js +439 -0
- package/dist/bin/utils/constants.js +5 -2
- package/package.json +2 -2
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Check and validate project configuration
|
|
5
|
+
* Reports errors and warnings for common configuration issues
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
const fs = require("fs");
|
|
9
|
+
const path = require("path");
|
|
10
|
+
function default_1(program) {
|
|
11
|
+
program.command('doctor')
|
|
12
|
+
.description('Check project configuration for errors and warnings')
|
|
13
|
+
.option('-f, --fix', 'attempt to fix minor issues automatically', false)
|
|
14
|
+
.action(function (opts) {
|
|
15
|
+
runDoctor(opts.fix);
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
exports.default = default_1;
|
|
19
|
+
function runDoctor(autoFix) {
|
|
20
|
+
const cwd = process.cwd();
|
|
21
|
+
const results = [];
|
|
22
|
+
console.info('š Checking melo project configuration...\n');
|
|
23
|
+
// Check 1: Is this a valid melo project?
|
|
24
|
+
if (!isMeloProject(cwd)) {
|
|
25
|
+
results.push({
|
|
26
|
+
type: 'error',
|
|
27
|
+
message: 'Not a valid melo project.',
|
|
28
|
+
fix: 'Run "melo init" to create a new project.'
|
|
29
|
+
});
|
|
30
|
+
printResults(results);
|
|
31
|
+
process.exit(1);
|
|
32
|
+
}
|
|
33
|
+
results.push({
|
|
34
|
+
type: 'success',
|
|
35
|
+
message: 'Valid melo project structure found.'
|
|
36
|
+
});
|
|
37
|
+
// Check 2: Validate adminServer.json
|
|
38
|
+
results.push(...checkAdminServerJson(cwd));
|
|
39
|
+
// Check 3: Validate servers.json
|
|
40
|
+
results.push(...checkServersJson(cwd));
|
|
41
|
+
// Check 4: Validate app.ts
|
|
42
|
+
results.push(...checkAppTs(cwd));
|
|
43
|
+
// Check 5: Check server directories consistency
|
|
44
|
+
results.push(...checkServerDirectories(cwd));
|
|
45
|
+
// Check 6: Check for duplicate server IDs
|
|
46
|
+
results.push(...checkDuplicateServerIds(cwd));
|
|
47
|
+
// Check 7: Check port conflicts
|
|
48
|
+
results.push(...checkPortConflicts(cwd));
|
|
49
|
+
// Check 8: Check for missing handler/remote files
|
|
50
|
+
results.push(...checkMissingHandlers(cwd));
|
|
51
|
+
printResults(results);
|
|
52
|
+
const errors = results.filter(r => r.type === 'error').length;
|
|
53
|
+
const warnings = results.filter(r => r.type === 'warning').length;
|
|
54
|
+
const fixes = results.filter(r => r.fix).length;
|
|
55
|
+
console.info(`\nš Summary: ${errors} errors, ${warnings} warnings`);
|
|
56
|
+
if (errors === 0 && warnings === 0) {
|
|
57
|
+
console.info('ā
All checks passed! Your project looks good.');
|
|
58
|
+
}
|
|
59
|
+
else if (errors === 0) {
|
|
60
|
+
console.info('ā ļø Project has some warnings but should work.');
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
console.info('ā Please fix the errors above before starting the server.');
|
|
64
|
+
}
|
|
65
|
+
if (fixes > 0 && !autoFix) {
|
|
66
|
+
console.info(`\nš” Run "melo doctor --fix" to attempt automatic fixes for some issues.`);
|
|
67
|
+
}
|
|
68
|
+
process.exit(errors > 0 ? 1 : 0);
|
|
69
|
+
}
|
|
70
|
+
function isMeloProject(cwd) {
|
|
71
|
+
const requiredPaths = ['app.ts', 'config', 'app/servers'];
|
|
72
|
+
return requiredPaths.every(p => fs.existsSync(path.join(cwd, p)));
|
|
73
|
+
}
|
|
74
|
+
function checkAdminServerJson(cwd) {
|
|
75
|
+
const results = [];
|
|
76
|
+
const filePath = path.join(cwd, 'config', 'adminServer.json');
|
|
77
|
+
if (!fs.existsSync(filePath)) {
|
|
78
|
+
results.push({
|
|
79
|
+
type: 'error',
|
|
80
|
+
message: 'adminServer.json not found.',
|
|
81
|
+
file: 'config/adminServer.json',
|
|
82
|
+
fix: 'Create adminServer.json with at least master server configuration.'
|
|
83
|
+
});
|
|
84
|
+
return results;
|
|
85
|
+
}
|
|
86
|
+
let adminServers;
|
|
87
|
+
try {
|
|
88
|
+
adminServers = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
results.push({
|
|
92
|
+
type: 'error',
|
|
93
|
+
message: 'adminServer.json is not valid JSON.',
|
|
94
|
+
file: 'config/adminServer.json',
|
|
95
|
+
fix: 'Fix JSON syntax errors.'
|
|
96
|
+
});
|
|
97
|
+
return results;
|
|
98
|
+
}
|
|
99
|
+
if (!Array.isArray(adminServers)) {
|
|
100
|
+
results.push({
|
|
101
|
+
type: 'error',
|
|
102
|
+
message: 'adminServer.json must be an array.',
|
|
103
|
+
file: 'config/adminServer.json'
|
|
104
|
+
});
|
|
105
|
+
return results;
|
|
106
|
+
}
|
|
107
|
+
// Check for master
|
|
108
|
+
const hasMaster = adminServers.some(s => s.type === 'master');
|
|
109
|
+
if (!hasMaster) {
|
|
110
|
+
results.push({
|
|
111
|
+
type: 'error',
|
|
112
|
+
message: 'Missing "master" server type in adminServer.json.',
|
|
113
|
+
file: 'config/adminServer.json',
|
|
114
|
+
fix: 'Add master server configuration.'
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
// Check for connector
|
|
118
|
+
const hasConnector = adminServers.some(s => s.type === 'connector');
|
|
119
|
+
if (!hasConnector) {
|
|
120
|
+
results.push({
|
|
121
|
+
type: 'warning',
|
|
122
|
+
message: 'Missing "connector" server type. Project may not accept client connections.',
|
|
123
|
+
file: 'config/adminServer.json'
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Check for duplicate types
|
|
127
|
+
const types = adminServers.map(s => s.type);
|
|
128
|
+
const duplicates = types.filter((item, index) => types.indexOf(item) !== index);
|
|
129
|
+
if (duplicates.length > 0) {
|
|
130
|
+
results.push({
|
|
131
|
+
type: 'error',
|
|
132
|
+
message: `Duplicate server types found: ${[...new Set(duplicates)].join(', ')}`,
|
|
133
|
+
file: 'config/adminServer.json'
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Check for missing tokens
|
|
137
|
+
adminServers.forEach(server => {
|
|
138
|
+
if (!server.token) {
|
|
139
|
+
results.push({
|
|
140
|
+
type: 'warning',
|
|
141
|
+
message: `Server type "${server.type}" is missing a token.`,
|
|
142
|
+
file: 'config/adminServer.json',
|
|
143
|
+
fix: 'Add a secure token for this server type.'
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return results;
|
|
148
|
+
}
|
|
149
|
+
function checkServersJson(cwd) {
|
|
150
|
+
const results = [];
|
|
151
|
+
const filePath = path.join(cwd, 'config', 'servers.json');
|
|
152
|
+
if (!fs.existsSync(filePath)) {
|
|
153
|
+
results.push({
|
|
154
|
+
type: 'error',
|
|
155
|
+
message: 'servers.json not found.',
|
|
156
|
+
file: 'config/servers.json'
|
|
157
|
+
});
|
|
158
|
+
return results;
|
|
159
|
+
}
|
|
160
|
+
let servers;
|
|
161
|
+
try {
|
|
162
|
+
servers = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
results.push({
|
|
166
|
+
type: 'error',
|
|
167
|
+
message: 'servers.json is not valid JSON.',
|
|
168
|
+
file: 'config/servers.json'
|
|
169
|
+
});
|
|
170
|
+
return results;
|
|
171
|
+
}
|
|
172
|
+
// Check environments
|
|
173
|
+
['development', 'production'].forEach(env => {
|
|
174
|
+
if (!servers[env]) {
|
|
175
|
+
results.push({
|
|
176
|
+
type: 'warning',
|
|
177
|
+
message: `Missing "${env}" environment configuration.`,
|
|
178
|
+
file: 'config/servers.json'
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
// Check each environment
|
|
183
|
+
Object.keys(servers).forEach(env => {
|
|
184
|
+
const envConfig = servers[env];
|
|
185
|
+
// Check for master
|
|
186
|
+
if (!envConfig.master || envConfig.master.length === 0) {
|
|
187
|
+
results.push({
|
|
188
|
+
type: 'error',
|
|
189
|
+
message: `Missing master server in "${env}" environment.`,
|
|
190
|
+
file: 'config/servers.json'
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
// Validate server entries
|
|
194
|
+
Object.keys(envConfig).forEach(serverType => {
|
|
195
|
+
const serverList = envConfig[serverType];
|
|
196
|
+
if (!Array.isArray(serverList)) {
|
|
197
|
+
results.push({
|
|
198
|
+
type: 'error',
|
|
199
|
+
message: `Server type "${serverType}" in "${env}" must be an array.`,
|
|
200
|
+
file: 'config/servers.json'
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
serverList.forEach((server, index) => {
|
|
205
|
+
if (!server.id) {
|
|
206
|
+
results.push({
|
|
207
|
+
type: 'error',
|
|
208
|
+
message: `Server #${index + 1} of type "${serverType}" in "${env}" is missing an ID.`,
|
|
209
|
+
file: 'config/servers.json'
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
if (!server.host) {
|
|
213
|
+
results.push({
|
|
214
|
+
type: 'warning',
|
|
215
|
+
message: `Server "${server.id || index}" in "${env}" is missing host.`,
|
|
216
|
+
file: 'config/servers.json'
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (!server.port && server.port !== 0) {
|
|
220
|
+
results.push({
|
|
221
|
+
type: 'error',
|
|
222
|
+
message: `Server "${server.id || index}" in "${env}" is missing port.`,
|
|
223
|
+
file: 'config/servers.json'
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// Check frontend servers have clientPort
|
|
227
|
+
if (server.frontend && !server.clientPort && server.clientPort !== 0) {
|
|
228
|
+
results.push({
|
|
229
|
+
type: 'warning',
|
|
230
|
+
message: `Frontend server "${server.id}" in "${env}" is missing clientPort.`,
|
|
231
|
+
file: 'config/servers.json'
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|
|
237
|
+
return results;
|
|
238
|
+
}
|
|
239
|
+
function checkAppTs(cwd) {
|
|
240
|
+
const results = [];
|
|
241
|
+
const filePath = path.join(cwd, 'app.ts');
|
|
242
|
+
if (!fs.existsSync(filePath)) {
|
|
243
|
+
return results;
|
|
244
|
+
}
|
|
245
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
246
|
+
// Check for app.start()
|
|
247
|
+
if (!content.includes('app.start()')) {
|
|
248
|
+
results.push({
|
|
249
|
+
type: 'error',
|
|
250
|
+
message: 'app.ts is missing app.start() call.',
|
|
251
|
+
file: 'app.ts'
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
// Check for melo import
|
|
255
|
+
if (!content.includes('@bigtyphoon/melo') && !content.includes('melo')) {
|
|
256
|
+
results.push({
|
|
257
|
+
type: 'error',
|
|
258
|
+
message: 'app.ts is missing melo import.',
|
|
259
|
+
file: 'app.ts'
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
// Check for app.createApp()
|
|
263
|
+
if (!content.includes('createApp')) {
|
|
264
|
+
results.push({
|
|
265
|
+
type: 'error',
|
|
266
|
+
message: 'app.ts should call melo.createApp().',
|
|
267
|
+
file: 'app.ts'
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
return results;
|
|
271
|
+
}
|
|
272
|
+
function checkServerDirectories(cwd) {
|
|
273
|
+
const results = [];
|
|
274
|
+
const serversDir = path.join(cwd, 'app', 'servers');
|
|
275
|
+
if (!fs.existsSync(serversDir)) {
|
|
276
|
+
return results;
|
|
277
|
+
}
|
|
278
|
+
const serverTypes = fs.readdirSync(serversDir).filter(f => {
|
|
279
|
+
return fs.statSync(path.join(serversDir, f)).isDirectory();
|
|
280
|
+
});
|
|
281
|
+
// Check if each server type has handler or remote directory
|
|
282
|
+
serverTypes.forEach(serverType => {
|
|
283
|
+
const serverPath = path.join(serversDir, serverType);
|
|
284
|
+
const hasHandler = fs.existsSync(path.join(serverPath, 'handler'));
|
|
285
|
+
const hasRemote = fs.existsSync(path.join(serverPath, 'remote'));
|
|
286
|
+
if (!hasHandler && !hasRemote) {
|
|
287
|
+
results.push({
|
|
288
|
+
type: 'warning',
|
|
289
|
+
message: `Server type "${serverType}" has neither handler nor remote directory.`,
|
|
290
|
+
file: `app/servers/${serverType}`
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
// Check handler directory is not empty
|
|
294
|
+
if (hasHandler) {
|
|
295
|
+
const handlerFiles = fs.readdirSync(path.join(serverPath, 'handler'))
|
|
296
|
+
.filter(f => f.endsWith('.ts') || f.endsWith('.js'));
|
|
297
|
+
if (handlerFiles.length === 0) {
|
|
298
|
+
results.push({
|
|
299
|
+
type: 'warning',
|
|
300
|
+
message: `Handler directory for "${serverType}" is empty.`,
|
|
301
|
+
file: `app/servers/${serverType}/handler`
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
return results;
|
|
307
|
+
}
|
|
308
|
+
function checkDuplicateServerIds(cwd) {
|
|
309
|
+
const results = [];
|
|
310
|
+
const filePath = path.join(cwd, 'config', 'servers.json');
|
|
311
|
+
if (!fs.existsSync(filePath)) {
|
|
312
|
+
return results;
|
|
313
|
+
}
|
|
314
|
+
let servers;
|
|
315
|
+
try {
|
|
316
|
+
servers = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
317
|
+
}
|
|
318
|
+
catch (e) {
|
|
319
|
+
return results;
|
|
320
|
+
}
|
|
321
|
+
Object.keys(servers).forEach(env => {
|
|
322
|
+
const envConfig = servers[env];
|
|
323
|
+
const ids = [];
|
|
324
|
+
Object.keys(envConfig).forEach(serverType => {
|
|
325
|
+
const serverList = envConfig[serverType];
|
|
326
|
+
if (Array.isArray(serverList)) {
|
|
327
|
+
serverList.forEach((server) => {
|
|
328
|
+
if (server.id) {
|
|
329
|
+
if (ids.includes(server.id)) {
|
|
330
|
+
results.push({
|
|
331
|
+
type: 'error',
|
|
332
|
+
message: `Duplicate server ID "${server.id}" in "${env}" environment.`,
|
|
333
|
+
file: 'config/servers.json'
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
ids.push(server.id);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
});
|
|
342
|
+
return results;
|
|
343
|
+
}
|
|
344
|
+
function checkPortConflicts(cwd) {
|
|
345
|
+
const results = [];
|
|
346
|
+
const filePath = path.join(cwd, 'config', 'servers.json');
|
|
347
|
+
if (!fs.existsSync(filePath)) {
|
|
348
|
+
return results;
|
|
349
|
+
}
|
|
350
|
+
let servers;
|
|
351
|
+
try {
|
|
352
|
+
servers = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
353
|
+
}
|
|
354
|
+
catch (e) {
|
|
355
|
+
return results;
|
|
356
|
+
}
|
|
357
|
+
Object.keys(servers).forEach(env => {
|
|
358
|
+
const envConfig = servers[env];
|
|
359
|
+
const ports = [];
|
|
360
|
+
Object.keys(envConfig).forEach(serverType => {
|
|
361
|
+
const serverList = envConfig[serverType];
|
|
362
|
+
if (Array.isArray(serverList)) {
|
|
363
|
+
serverList.forEach((server) => {
|
|
364
|
+
if (server.port) {
|
|
365
|
+
const existing = ports.find(p => p.port === server.port);
|
|
366
|
+
if (existing) {
|
|
367
|
+
results.push({
|
|
368
|
+
type: 'error',
|
|
369
|
+
message: `Port conflict: "${server.id}" and "${existing.server}" both use port ${server.port} in "${env}".`,
|
|
370
|
+
file: 'config/servers.json'
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
ports.push({ port: server.port, server: server.id });
|
|
374
|
+
}
|
|
375
|
+
if (server.clientPort) {
|
|
376
|
+
const existingClient = ports.find(p => p.port === server.clientPort);
|
|
377
|
+
if (existingClient) {
|
|
378
|
+
results.push({
|
|
379
|
+
type: 'error',
|
|
380
|
+
message: `Client port conflict: "${server.id}" and "${existingClient.server}" both use clientPort ${server.clientPort} in "${env}".`,
|
|
381
|
+
file: 'config/servers.json'
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
ports.push({ port: server.clientPort, server: server.id });
|
|
385
|
+
}
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
});
|
|
390
|
+
return results;
|
|
391
|
+
}
|
|
392
|
+
function checkMissingHandlers(cwd) {
|
|
393
|
+
const results = [];
|
|
394
|
+
const adminServerPath = path.join(cwd, 'config', 'adminServer.json');
|
|
395
|
+
if (!fs.existsSync(adminServerPath)) {
|
|
396
|
+
return results;
|
|
397
|
+
}
|
|
398
|
+
let adminServers;
|
|
399
|
+
try {
|
|
400
|
+
adminServers = JSON.parse(fs.readFileSync(adminServerPath, 'utf8'));
|
|
401
|
+
}
|
|
402
|
+
catch (e) {
|
|
403
|
+
return results;
|
|
404
|
+
}
|
|
405
|
+
const serversDir = path.join(cwd, 'app', 'servers');
|
|
406
|
+
adminServers.forEach(server => {
|
|
407
|
+
if (server.type === 'master')
|
|
408
|
+
return; // master doesn't need handler
|
|
409
|
+
const serverPath = path.join(serversDir, server.type);
|
|
410
|
+
if (!fs.existsSync(serverPath)) {
|
|
411
|
+
results.push({
|
|
412
|
+
type: 'warning',
|
|
413
|
+
message: `Server type "${server.type}" is defined in adminServer.json but has no directory.`,
|
|
414
|
+
file: `app/servers/${server.type}`,
|
|
415
|
+
fix: `Run "melo add-server ${server.type}" to create the server directory.`
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
return results;
|
|
420
|
+
}
|
|
421
|
+
function printResults(results) {
|
|
422
|
+
const icons = {
|
|
423
|
+
error: 'ā',
|
|
424
|
+
warning: 'ā ļø ',
|
|
425
|
+
info: 'ā¹ļø ',
|
|
426
|
+
success: 'ā
'
|
|
427
|
+
};
|
|
428
|
+
results.forEach(result => {
|
|
429
|
+
console.info(`${icons[result.type]} ${result.message}`);
|
|
430
|
+
if (result.file) {
|
|
431
|
+
console.info(` š ${result.file}`);
|
|
432
|
+
}
|
|
433
|
+
if (result.fix) {
|
|
434
|
+
console.info(` š” ${result.fix}`);
|
|
435
|
+
}
|
|
436
|
+
console.info('');
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9jdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYmluL2NvbW1hbmRzL2RvY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBOzs7R0FHRzs7QUFFSCx5QkFBeUI7QUFDekIsNkJBQTZCO0FBVTdCLG1CQUF5QixPQUFnQjtJQUNyQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztTQUNwQixXQUFXLENBQUMscURBQXFELENBQUM7U0FDbEUsTUFBTSxDQUFDLFdBQVcsRUFBRSwyQ0FBMkMsRUFBRSxLQUFLLENBQUM7U0FDdkUsTUFBTSxDQUFDLFVBQVUsSUFBc0I7UUFDcEMsU0FBUyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN4QixDQUFDLENBQUMsQ0FBQztBQUNYLENBQUM7QUFQRCw0QkFPQztBQUVELFNBQVMsU0FBUyxDQUFDLE9BQWdCO0lBQy9CLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUMxQixNQUFNLE9BQU8sR0FBa0IsRUFBRSxDQUFDO0lBRWxDLE9BQU8sQ0FBQyxJQUFJLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUU1RCx5Q0FBeUM7SUFDekMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsRUFBRTtRQUNyQixPQUFPLENBQUMsSUFBSSxDQUFDO1lBQ1QsSUFBSSxFQUFFLE9BQU87WUFDYixPQUFPLEVBQUUsMkJBQTJCO1lBQ3BDLEdBQUcsRUFBRSwwQ0FBMEM7U0FDbEQsQ0FBQyxDQUFDO1FBQ0gsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7S0FDbkI7SUFFRCxPQUFPLENBQUMsSUFBSSxDQUFDO1FBQ1QsSUFBSSxFQUFFLFNBQVM7UUFDZixPQUFPLEVBQUUscUNBQXFDO0tBQ2pELENBQUMsQ0FBQztJQUVILHFDQUFxQztJQUNyQyxPQUFPLENBQUMsSUFBSSxD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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DAEMON_INFO = exports.COMMAND_ERROR = exports.MASTER_HA_NOT_FOUND = exports.SCRIPT_NOT_FOUND = exports.INIT_PROJ_NOTICE = exports.RESTART_SERVER_INFO = exports.ADD_SERVER_INFO = exports.CLOSEAPP_INFO = exports.FILEREAD_ERROR = exports.CONNECT_ERROR = exports.DEFAULT_MASTER_PORT = exports.DEFAULT_MASTER_HOST = exports.DEFAULT_ENV = exports.DEFAULT_PWD = exports.DEFAULT_USERNAME = exports.DEFAULT_GAME_SERVER_DIR = exports.CUR_DIR = exports.KILL_CMD_WIN = exports.KILL_CMD_LUX = exports.TIME_KILL_WAIT = exports.TIME_INIT = void 0;
|
|
3
|
+
exports.ADD_SERVER_TYPE_EXISTS = exports.ADD_SERVER_TYPE_INFO = exports.DAEMON_INFO = exports.COMMAND_ERROR = exports.MASTER_HA_NOT_FOUND = exports.SCRIPT_NOT_FOUND = exports.INIT_PROJ_NOTICE = exports.RESTART_SERVER_INFO = exports.ADD_SERVER_INFO = exports.CLOSEAPP_INFO = exports.FILEREAD_ERROR = exports.CONNECT_ERROR = exports.DEFAULT_MASTER_PORT = exports.DEFAULT_MASTER_HOST = exports.DEFAULT_ENV = exports.DEFAULT_PWD = exports.DEFAULT_USERNAME = exports.DEFAULT_GAME_SERVER_DIR = exports.CUR_DIR = exports.KILL_CMD_WIN = exports.KILL_CMD_LUX = exports.TIME_KILL_WAIT = exports.TIME_INIT = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* Constant Variables
|
|
6
6
|
*/
|
|
@@ -25,4 +25,7 @@ exports.SCRIPT_NOT_FOUND = 'Fail to find an appropriate script to run,\nplease c
|
|
|
25
25
|
exports.MASTER_HA_NOT_FOUND = 'Fail to find an appropriate masterha config file, \nplease check the current work directory or the arguments passed to.\n'.red;
|
|
26
26
|
exports.COMMAND_ERROR = 'Illegal command format. Use `melo --help` to get more info.\n'.red;
|
|
27
27
|
exports.DAEMON_INFO = 'The application is running in the background now.\n';
|
|
28
|
-
|
|
28
|
+
// Add server type command
|
|
29
|
+
exports.ADD_SERVER_TYPE_INFO = 'Successfully added server type "${serverName}".\n\nGenerated files:\n - app/servers/${serverName}/handler/${serverName}Handler.ts\n - app/servers/${serverName}/remote/${serverName}Remote.ts\n - Updated config/adminServer.json\n - Updated config/servers.json\n - Updated app.ts\n\nYou can now add server instances to config/servers.json.';
|
|
30
|
+
exports.ADD_SERVER_TYPE_EXISTS = 'Server type already exists. Use --force to overwrite or choose a different name.';
|
|
31
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vYmluL3V0aWxzL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQTs7R0FFRztBQUNRLFFBQUEsU0FBUyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDckIsUUFBQSxjQUFjLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUMxQixRQUFBLFlBQVksR0FBRywrQ0FBK0MsQ0FBQztBQUMvRCxRQUFBLFlBQVksR0FBRywwQkFBMEIsQ0FBQztBQUUxQyxRQUFBLE9BQU8sR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDeEIsUUFBQSx1QkFBdUIsR0FBRyxlQUFPLENBQUM7QUFDbEMsUUFBQSxnQkFBZ0IsR0FBRyxPQUFPLENBQUM7QUFDM0IsUUFBQSxXQUFXLEdBQUcsT0FBTyxDQUFDO0FBQ3RCLFFBQUEsV0FBVyxHQUFHLGFBQWEsQ0FBQztBQUM1QixRQUFBLG1CQUFtQixHQUFHLFdBQVcsQ0FBQztBQUNsQyxRQUFBLG1CQUFtQixHQUFHLElBQUksQ0FBQztBQUUzQixRQUFBLGFBQWEsR0FBRywwQ0FBMEMsQ0FBQztBQUMzRCxRQUFBLGNBQWMsR0FBRyw0RUFBNEUsQ0FBQztBQUM5RixRQUFBLGFBQWEsR0FBRyxrREFBa0QsQ0FBQztBQUNuRSxRQUFBLGVBQWUsR0FBRywwQkFBMEIsQ0FBQztBQUM3QyxRQUFBLG1CQUFtQixHQUFHLDhCQUE4QixDQUFDO0FBQ3JELFFBQUEsZ0JBQWdCLEdBQUcsQ0FBQyxtQ0FBbUMsR0FBRyxZQUFvQixDQUFBLENBQUMsS0FBSyxHQUFHLGFBQWEsR0FBSSxVQUFrQixDQUFDLEtBQUssR0FBRyw4RUFBOEUsQ0FBQztBQUNsTixRQUFBLGdCQUFnQixHQUFJLDJJQUFtSixDQUFDLEdBQUcsQ0FBQztBQUM1SyxRQUFBLG1CQUFtQixHQUFJLDJIQUFtSSxDQUFDLEdBQUcsQ0FBQztBQUMvSixRQUFBLGFBQWEsR0FBSSwrREFBdUUsQ0FBQyxHQUFHLENBQUM7QUFDN0YsUUFBQSxXQUFXLEdBQUcscURBQXFELENBQUM7QUFFL0UsMEJBQTBCO0FBQ2YsUUFBQSxvQkFBb0IsR0FBRyx1VkFBdVYsQ0FBQztBQUMvVyxRQUFBLHNCQUFzQixHQUFHLGtGQUFrRixDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bigtyphoon/melo",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"homepage": "https://github.com/node-melo/melo",
|
|
6
6
|
"repository": {
|
|
@@ -89,5 +89,5 @@
|
|
|
89
89
|
"publishConfig": {
|
|
90
90
|
"access": "public"
|
|
91
91
|
},
|
|
92
|
-
"gitHead": "
|
|
92
|
+
"gitHead": "7dfd3ca78ed6b051e34da595269efb623cd58d1b"
|
|
93
93
|
}
|