wedos-cli 1.0.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/LICENSE +21 -0
- package/README.md +179 -0
- package/package.json +52 -0
- package/src/commands/config.js +196 -0
- package/src/commands/contact.js +210 -0
- package/src/commands/dns.js +384 -0
- package/src/commands/domain.js +329 -0
- package/src/index.js +240 -0
- package/src/lib/config.js +72 -0
- package/src/lib/locale.js +112 -0
- package/src/lib/output.js +191 -0
- package/src/lib/ui.js +263 -0
- package/src/lib/wapi.js +323 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { WapiClient, isSuccess } from '../lib/wapi.js';
|
|
6
|
+
import { getCredentials, getConfig } from '../lib/config.js';
|
|
7
|
+
import { formatResponse, printError, printSuccess, printWarning, printInfo } from '../lib/output.js';
|
|
8
|
+
|
|
9
|
+
export function createDomainCommand() {
|
|
10
|
+
const domain = new Command('domain')
|
|
11
|
+
.description('Správa domén');
|
|
12
|
+
|
|
13
|
+
// List domains
|
|
14
|
+
domain
|
|
15
|
+
.command('list')
|
|
16
|
+
.alias('ls')
|
|
17
|
+
.description('Seznam všech domén v účtu')
|
|
18
|
+
.option('-s, --status <status>', 'Filtrovat podle stavu (active, expired, deleted)')
|
|
19
|
+
.option('--json', 'Výstup jako JSON')
|
|
20
|
+
.action(async (options) => {
|
|
21
|
+
const spinner = ora('Načítám domény...').start();
|
|
22
|
+
try {
|
|
23
|
+
const client = new WapiClient(getCredentials());
|
|
24
|
+
const response = await client.domainsList(options.status);
|
|
25
|
+
spinner.stop();
|
|
26
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
27
|
+
} catch (error) {
|
|
28
|
+
spinner.stop();
|
|
29
|
+
printError(error);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Check domain availability
|
|
35
|
+
domain
|
|
36
|
+
.command('check <domains...>')
|
|
37
|
+
.description('Kontrola dostupnosti domény (lze zadat více)')
|
|
38
|
+
.option('--json', 'Výstup jako JSON')
|
|
39
|
+
.action(async (domains, options) => {
|
|
40
|
+
const spinner = ora('Kontroluji dostupnost...').start();
|
|
41
|
+
try {
|
|
42
|
+
const client = new WapiClient(getCredentials());
|
|
43
|
+
const response = await client.domainCheck(domains);
|
|
44
|
+
spinner.stop();
|
|
45
|
+
|
|
46
|
+
if (options.json) {
|
|
47
|
+
formatResponse(response, { format: 'json' });
|
|
48
|
+
} else {
|
|
49
|
+
const code = parseInt(response.code);
|
|
50
|
+
if (isSuccess(code) && response.data) {
|
|
51
|
+
console.log(chalk.bold('\nDostupnost domén:\n'));
|
|
52
|
+
for (const [domain, info] of Object.entries(response.data)) {
|
|
53
|
+
const status = info.avail === '1' || info.avail === 1;
|
|
54
|
+
const icon = status ? chalk.green('✓') : chalk.red('✗');
|
|
55
|
+
const text = status ? chalk.green('Volná') : chalk.red('Zaregistrovaná');
|
|
56
|
+
console.log(`${icon} ${domain} - ${text}`);
|
|
57
|
+
}
|
|
58
|
+
} else {
|
|
59
|
+
formatResponse(response);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
} catch (error) {
|
|
63
|
+
spinner.stop();
|
|
64
|
+
printError(error);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
// Get domain info
|
|
70
|
+
domain
|
|
71
|
+
.command('info <domains...>')
|
|
72
|
+
.description('Detailní informace o doméně')
|
|
73
|
+
.option('--json', 'Výstup jako JSON')
|
|
74
|
+
.action(async (domains, options) => {
|
|
75
|
+
const spinner = ora('Načítám informace o doméně...').start();
|
|
76
|
+
try {
|
|
77
|
+
const client = new WapiClient(getCredentials());
|
|
78
|
+
const response = await client.domainInfo(domains);
|
|
79
|
+
spinner.stop();
|
|
80
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
81
|
+
} catch (error) {
|
|
82
|
+
spinner.stop();
|
|
83
|
+
printError(error);
|
|
84
|
+
process.exit(1);
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Register new domain
|
|
89
|
+
domain
|
|
90
|
+
.command('register <domain>')
|
|
91
|
+
.alias('create')
|
|
92
|
+
.description('Registrace nové domény')
|
|
93
|
+
.option('-p, --period <years>', 'Délka registrace v letech', '1')
|
|
94
|
+
.option('-c, --contact <id>', 'ID kontaktu vlastníka')
|
|
95
|
+
.option('-n, --nsset <nsset>', 'Název NSSET (např. WEDOS)')
|
|
96
|
+
.option('-d, --dns <servers>', 'Vlastní DNS servery (oddělené čárkou, např. "ns1.example.com,ns2.example.com")')
|
|
97
|
+
.option('-r, --rules <name>', 'Osoba, která souhlasila s podmínkami (povinné)')
|
|
98
|
+
.option('-i, --interactive', 'Interaktivní režim')
|
|
99
|
+
.option('--json', 'Výstup jako JSON')
|
|
100
|
+
.action(async (domainName, options) => {
|
|
101
|
+
try {
|
|
102
|
+
const client = new WapiClient(getCredentials());
|
|
103
|
+
const config = getConfig();
|
|
104
|
+
|
|
105
|
+
// First check availability
|
|
106
|
+
const spinner = ora('Kontroluji dostupnost domény...').start();
|
|
107
|
+
const checkResponse = await client.domainCheck(domainName);
|
|
108
|
+
spinner.stop();
|
|
109
|
+
|
|
110
|
+
const checkCode = parseInt(checkResponse.code);
|
|
111
|
+
if (!isSuccess(checkCode)) {
|
|
112
|
+
formatResponse(checkResponse);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const domainData = checkResponse.data?.[domainName];
|
|
117
|
+
if (!domainData || domainData.avail !== '1') {
|
|
118
|
+
printError(`Doména ${domainName} není k dispozici pro registraci`);
|
|
119
|
+
if (domainData?.reason) {
|
|
120
|
+
printInfo(`Důvod: ${domainData.reason}`);
|
|
121
|
+
}
|
|
122
|
+
process.exit(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
printSuccess(`Doména ${domainName} je volná!`);
|
|
126
|
+
|
|
127
|
+
// Get contact if not provided
|
|
128
|
+
let ownerContact = options.contact || config.defaultContact;
|
|
129
|
+
let rules = options.rules;
|
|
130
|
+
|
|
131
|
+
if (!ownerContact || !rules) {
|
|
132
|
+
if (!options.interactive) {
|
|
133
|
+
printError('ID kontaktu a jméno pro pravidla jsou povinné. Použij --contact a --rules, nebo --interactive');
|
|
134
|
+
console.log('\nPříklad:');
|
|
135
|
+
console.log(` wedos domain register ${domainName} --contact MYCONTACT-CZ --rules "Jan Novák"`);
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Interactive mode
|
|
140
|
+
const answers = await inquirer.prompt([
|
|
141
|
+
{
|
|
142
|
+
type: 'input',
|
|
143
|
+
name: 'contact',
|
|
144
|
+
message: 'ID kontaktu vlastníka:',
|
|
145
|
+
when: !ownerContact,
|
|
146
|
+
validate: (input) => input.length > 0 || 'ID kontaktu je povinné',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: 'input',
|
|
150
|
+
name: 'rules',
|
|
151
|
+
message: 'Celé jméno osoby souhlasící s podmínkami:',
|
|
152
|
+
when: !rules,
|
|
153
|
+
validate: (input) => input.length > 0 || 'Jméno je povinné',
|
|
154
|
+
},
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
ownerContact = ownerContact || answers.contact;
|
|
158
|
+
rules = rules || answers.rules;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Register domain
|
|
162
|
+
const registerSpinner = ora('Registruji doménu...').start();
|
|
163
|
+
|
|
164
|
+
// Build DNS configuration
|
|
165
|
+
const createOptions = {
|
|
166
|
+
name: domainName,
|
|
167
|
+
period: parseInt(options.period),
|
|
168
|
+
ownerContact,
|
|
169
|
+
rules,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// Use custom DNS servers if provided, otherwise use NSSET
|
|
173
|
+
if (options.dns) {
|
|
174
|
+
// Parse comma-separated DNS servers into proper format
|
|
175
|
+
const servers = options.dns.split(',').map(s => s.trim());
|
|
176
|
+
createOptions.dns = servers.map(server => ({ name: server }));
|
|
177
|
+
printInfo(`Používám vlastní DNS: ${servers.join(', ')}`);
|
|
178
|
+
} else {
|
|
179
|
+
createOptions.nsset = options.nsset || config.defaultNsset || 'WEDOS';
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const response = await client.domainCreate(createOptions);
|
|
183
|
+
registerSpinner.stop();
|
|
184
|
+
|
|
185
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
186
|
+
|
|
187
|
+
if (isSuccess(parseInt(response.code))) {
|
|
188
|
+
printSuccess(`Doména ${domainName} úspěšně zaregistrována!`);
|
|
189
|
+
if (response.data?.expiration) {
|
|
190
|
+
printInfo(`Expirace: ${response.data.expiration}`);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
} catch (error) {
|
|
194
|
+
printError(error);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Renew domain
|
|
200
|
+
domain
|
|
201
|
+
.command('renew <domain>')
|
|
202
|
+
.description('Prodloužení registrace domény')
|
|
203
|
+
.option('-p, --period <years>', 'Délka prodloužení v letech', '1')
|
|
204
|
+
.option('--json', 'Výstup jako JSON')
|
|
205
|
+
.action(async (domainName, options) => {
|
|
206
|
+
const spinner = ora('Prodlužuji doménu...').start();
|
|
207
|
+
try {
|
|
208
|
+
const client = new WapiClient(getCredentials());
|
|
209
|
+
const response = await client.domainRenew(domainName, parseInt(options.period));
|
|
210
|
+
spinner.stop();
|
|
211
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
212
|
+
} catch (error) {
|
|
213
|
+
spinner.stop();
|
|
214
|
+
printError(error);
|
|
215
|
+
process.exit(1);
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// Update DNS/NSSET
|
|
220
|
+
domain
|
|
221
|
+
.command('update-ns <domain>')
|
|
222
|
+
.description('Aktualizace DNS serverů domény')
|
|
223
|
+
.option('-n, --nsset <nsset>', 'Název NSSET')
|
|
224
|
+
.option('--json', 'Výstup jako JSON')
|
|
225
|
+
.action(async (domainName, options) => {
|
|
226
|
+
if (!options.nsset) {
|
|
227
|
+
printError('NSSET je povinný. Použij --nsset <název>');
|
|
228
|
+
process.exit(1);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
const spinner = ora('Aktualizuji DNS...').start();
|
|
232
|
+
try {
|
|
233
|
+
const client = new WapiClient(getCredentials());
|
|
234
|
+
const response = await client.domainUpdateNs(domainName, options.nsset);
|
|
235
|
+
spinner.stop();
|
|
236
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
237
|
+
} catch (error) {
|
|
238
|
+
spinner.stop();
|
|
239
|
+
printError(error);
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Transfer check
|
|
245
|
+
domain
|
|
246
|
+
.command('transfer-check <domain>')
|
|
247
|
+
.description('Kontrola možnosti transferu domény')
|
|
248
|
+
.option('--json', 'Výstup jako JSON')
|
|
249
|
+
.action(async (domainName, options) => {
|
|
250
|
+
const spinner = ora('Kontroluji možnost transferu...').start();
|
|
251
|
+
try {
|
|
252
|
+
const client = new WapiClient(getCredentials());
|
|
253
|
+
const response = await client.domainTransferCheck(domainName);
|
|
254
|
+
spinner.stop();
|
|
255
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
256
|
+
} catch (error) {
|
|
257
|
+
spinner.stop();
|
|
258
|
+
printError(error);
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
// Transfer domain
|
|
264
|
+
domain
|
|
265
|
+
.command('transfer <domain>')
|
|
266
|
+
.description('Transfer domény od jiného registrátora')
|
|
267
|
+
.requiredOption('-a, --auth <authInfo>', 'AUTH-ID domény')
|
|
268
|
+
.option('-c, --contact <id>', 'ID kontaktu vlastníka (pro non-CZ domény)')
|
|
269
|
+
.option('-n, --nsset <nsset>', 'Název NSSET')
|
|
270
|
+
.requiredOption('-r, --rules <name>', 'Osoba, která souhlasila s podmínkami')
|
|
271
|
+
.option('--json', 'Výstup jako JSON')
|
|
272
|
+
.action(async (domainName, options) => {
|
|
273
|
+
const spinner = ora('Zahajuji transfer...').start();
|
|
274
|
+
try {
|
|
275
|
+
const client = new WapiClient(getCredentials());
|
|
276
|
+
const response = await client.domainTransfer({
|
|
277
|
+
name: domainName,
|
|
278
|
+
authInfo: options.auth,
|
|
279
|
+
ownerContact: options.contact,
|
|
280
|
+
nsset: options.nsset,
|
|
281
|
+
rules: options.rules,
|
|
282
|
+
});
|
|
283
|
+
spinner.stop();
|
|
284
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
285
|
+
} catch (error) {
|
|
286
|
+
spinner.stop();
|
|
287
|
+
printError(error);
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
// Send AUTH-ID
|
|
293
|
+
domain
|
|
294
|
+
.command('send-auth <domain>')
|
|
295
|
+
.description('Odeslání AUTH-ID na e-mail vlastníka')
|
|
296
|
+
.action(async (domainName) => {
|
|
297
|
+
const spinner = ora('Odesílám AUTH-ID...').start();
|
|
298
|
+
try {
|
|
299
|
+
const client = new WapiClient(getCredentials());
|
|
300
|
+
const response = await client.domainSendAuthInfo(domainName);
|
|
301
|
+
spinner.stop();
|
|
302
|
+
formatResponse(response);
|
|
303
|
+
} catch (error) {
|
|
304
|
+
spinner.stop();
|
|
305
|
+
printError(error);
|
|
306
|
+
process.exit(1);
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Check TLD period
|
|
311
|
+
domain
|
|
312
|
+
.command('period-check <tld> <years>')
|
|
313
|
+
.description('Kontrola platnosti délky registrace pro TLD')
|
|
314
|
+
.action(async (tld, years) => {
|
|
315
|
+
const spinner = ora('Kontroluji...').start();
|
|
316
|
+
try {
|
|
317
|
+
const client = new WapiClient(getCredentials());
|
|
318
|
+
const response = await client.domainTldPeriodCheck(tld, parseInt(years));
|
|
319
|
+
spinner.stop();
|
|
320
|
+
formatResponse(response);
|
|
321
|
+
} catch (error) {
|
|
322
|
+
spinner.stop();
|
|
323
|
+
printError(error);
|
|
324
|
+
process.exit(1);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
|
|
328
|
+
return domain;
|
|
329
|
+
}
|
package/src/index.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import ora from 'ora';
|
|
6
|
+
import boxen from 'boxen';
|
|
7
|
+
|
|
8
|
+
import { createDomainCommand } from './commands/domain.js';
|
|
9
|
+
import { createDnsCommand } from './commands/dns.js';
|
|
10
|
+
import { createContactCommand } from './commands/contact.js';
|
|
11
|
+
import { createConfigCommand } from './commands/config.js';
|
|
12
|
+
import { WapiClient, isSuccess } from './lib/wapi.js';
|
|
13
|
+
import { getCredentials, hasCredentials } from './lib/config.js';
|
|
14
|
+
import { formatResponse, printError, printSuccess, printInfo, printHeader, printDomainCheck, printSuccessBox, printErrorBox } from './lib/output.js';
|
|
15
|
+
import { formatDateTime } from './lib/locale.js';
|
|
16
|
+
import { printBanner, wedosGradient } from './lib/ui.js';
|
|
17
|
+
|
|
18
|
+
const program = new Command();
|
|
19
|
+
|
|
20
|
+
program
|
|
21
|
+
.name('wedos')
|
|
22
|
+
.description('CLI nástroj pro WEDOS WAPI - registrace domén, správa DNS a další')
|
|
23
|
+
.version('1.0.0')
|
|
24
|
+
.hook('preAction', (thisCommand) => {
|
|
25
|
+
// Show banner for main commands (not subcommands)
|
|
26
|
+
const commandName = thisCommand.args[0];
|
|
27
|
+
if (!commandName || ['--help', '-h', '--version', '-V'].includes(commandName)) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Add subcommands
|
|
33
|
+
program.addCommand(createDomainCommand());
|
|
34
|
+
program.addCommand(createDnsCommand());
|
|
35
|
+
program.addCommand(createContactCommand());
|
|
36
|
+
program.addCommand(createConfigCommand());
|
|
37
|
+
|
|
38
|
+
// Ping command
|
|
39
|
+
program
|
|
40
|
+
.command('ping')
|
|
41
|
+
.description('Test připojení k API a ověření autentizace')
|
|
42
|
+
.action(async () => {
|
|
43
|
+
if (!hasCredentials()) {
|
|
44
|
+
printErrorBox('Přihlašovací údaje nejsou nastaveny', 'Spusť: wedos config init');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
printBanner();
|
|
49
|
+
|
|
50
|
+
const spinner = ora({
|
|
51
|
+
text: 'Testuji připojení k WAPI...',
|
|
52
|
+
spinner: 'dots12',
|
|
53
|
+
color: 'cyan',
|
|
54
|
+
}).start();
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const client = new WapiClient(getCredentials());
|
|
58
|
+
const response = await client.ping();
|
|
59
|
+
spinner.stop();
|
|
60
|
+
|
|
61
|
+
if (isSuccess(parseInt(response.code))) {
|
|
62
|
+
const time = formatDateTime(new Date(response.timestamp * 1000));
|
|
63
|
+
|
|
64
|
+
console.log(boxen(
|
|
65
|
+
chalk.green.bold('✓ Připojení úspěšné!\n\n') +
|
|
66
|
+
chalk.gray('Server: ') + chalk.white('api.wedos.com\n') +
|
|
67
|
+
chalk.gray('Čas: ') + chalk.white(time + '\n') +
|
|
68
|
+
chalk.gray('Transakce: ') + chalk.white(response.svTRID || 'N/A'),
|
|
69
|
+
{
|
|
70
|
+
padding: 1,
|
|
71
|
+
borderStyle: 'round',
|
|
72
|
+
borderColor: 'green',
|
|
73
|
+
title: '🌐 WAPI Status',
|
|
74
|
+
titleAlignment: 'center',
|
|
75
|
+
}
|
|
76
|
+
));
|
|
77
|
+
} else {
|
|
78
|
+
formatResponse(response);
|
|
79
|
+
}
|
|
80
|
+
} catch (error) {
|
|
81
|
+
spinner.stop();
|
|
82
|
+
printError(error);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// Poll command (for async operations)
|
|
88
|
+
program
|
|
89
|
+
.command('poll')
|
|
90
|
+
.description('Kontrola čekajících notifikací')
|
|
91
|
+
.option('--ack <msgid>', 'Potvrdit notifikaci podle ID')
|
|
92
|
+
.option('--json', 'Výstup jako JSON')
|
|
93
|
+
.action(async (options) => {
|
|
94
|
+
if (!hasCredentials()) {
|
|
95
|
+
printErrorBox('Přihlašovací údaje nejsou nastaveny', 'Spusť: wedos config init');
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const spinner = ora({
|
|
100
|
+
text: 'Kontroluji notifikace...',
|
|
101
|
+
spinner: 'dots12',
|
|
102
|
+
color: 'cyan',
|
|
103
|
+
}).start();
|
|
104
|
+
|
|
105
|
+
try {
|
|
106
|
+
const client = new WapiClient(getCredentials());
|
|
107
|
+
|
|
108
|
+
if (options.ack) {
|
|
109
|
+
const response = await client.pollAck(options.ack);
|
|
110
|
+
spinner.stop();
|
|
111
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
112
|
+
} else {
|
|
113
|
+
const response = await client.pollReq();
|
|
114
|
+
spinner.stop();
|
|
115
|
+
|
|
116
|
+
if (parseInt(response.code) === 1300) {
|
|
117
|
+
printInfo('Žádné čekající notifikace');
|
|
118
|
+
} else {
|
|
119
|
+
formatResponse(response, { format: options.json ? 'json' : undefined });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
} catch (error) {
|
|
123
|
+
spinner.stop();
|
|
124
|
+
printError(error);
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
// Quick check command (shortcut)
|
|
130
|
+
program
|
|
131
|
+
.command('check <domains...>')
|
|
132
|
+
.description('Rychlá kontrola dostupnosti domény')
|
|
133
|
+
.option('--json', 'Výstup jako JSON')
|
|
134
|
+
.action(async (domains, options) => {
|
|
135
|
+
if (!hasCredentials()) {
|
|
136
|
+
printErrorBox('Přihlašovací údaje nejsou nastaveny', 'Spusť: wedos config init');
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const spinner = ora({
|
|
141
|
+
text: `Kontroluji ${domains.length} doména(y)...`,
|
|
142
|
+
spinner: 'dots12',
|
|
143
|
+
color: 'cyan',
|
|
144
|
+
}).start();
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
const client = new WapiClient(getCredentials());
|
|
148
|
+
const response = await client.domainCheck(domains);
|
|
149
|
+
spinner.stop();
|
|
150
|
+
|
|
151
|
+
if (options.json) {
|
|
152
|
+
formatResponse(response, { format: 'json' });
|
|
153
|
+
} else {
|
|
154
|
+
const code = parseInt(response.code);
|
|
155
|
+
if (isSuccess(code) && response.data) {
|
|
156
|
+
printHeader('Dostupnost domén', '🔍');
|
|
157
|
+
console.log('');
|
|
158
|
+
|
|
159
|
+
for (const [domain, info] of Object.entries(response.data)) {
|
|
160
|
+
const available = info.avail === '1' || info.avail === 1;
|
|
161
|
+
printDomainCheck(domain, available, info.reason);
|
|
162
|
+
}
|
|
163
|
+
console.log('');
|
|
164
|
+
} else {
|
|
165
|
+
formatResponse(response);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
spinner.stop();
|
|
170
|
+
printError(error);
|
|
171
|
+
process.exit(1);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Quick register command (shortcut)
|
|
176
|
+
program
|
|
177
|
+
.command('register <domain>')
|
|
178
|
+
.description('Rychlá registrace domény')
|
|
179
|
+
.option('-p, --period <years>', 'Délka registrace v letech', '1')
|
|
180
|
+
.option('-c, --contact <id>', 'ID kontaktu vlastníka')
|
|
181
|
+
.option('-n, --nsset <nsset>', 'Název NSSET')
|
|
182
|
+
.option('-d, --dns <servers>', 'Vlastní DNS servery (oddělené čárkou)')
|
|
183
|
+
.option('-r, --rules <name>', 'Osoba, která souhlasila s podmínkami')
|
|
184
|
+
.option('-i, --interactive', 'Interaktivní režim')
|
|
185
|
+
.action(async (domain, options) => {
|
|
186
|
+
// Delegate to domain register
|
|
187
|
+
const args = ['domain', 'register', domain];
|
|
188
|
+
if (options.period) args.push('-p', options.period);
|
|
189
|
+
if (options.contact) args.push('-c', options.contact);
|
|
190
|
+
if (options.nsset) args.push('-n', options.nsset);
|
|
191
|
+
if (options.dns) args.push('-d', options.dns);
|
|
192
|
+
if (options.rules) args.push('-r', options.rules);
|
|
193
|
+
if (options.interactive) args.push('-i');
|
|
194
|
+
|
|
195
|
+
process.argv = [process.argv[0], process.argv[1], ...args];
|
|
196
|
+
await program.parseAsync(process.argv);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// Custom help
|
|
200
|
+
program.configureHelp({
|
|
201
|
+
sortSubcommands: true,
|
|
202
|
+
subcommandTerm: (cmd) => chalk.cyan(cmd.name()) + (cmd.alias() ? chalk.gray(` (${cmd.alias()})`) : ''),
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Help with examples
|
|
206
|
+
program.on('--help', () => {
|
|
207
|
+
console.log('');
|
|
208
|
+
console.log(chalk.gray('─'.repeat(55)));
|
|
209
|
+
console.log('');
|
|
210
|
+
console.log(chalk.bold.cyan(' Příklady:'));
|
|
211
|
+
console.log('');
|
|
212
|
+
console.log(chalk.gray(' # Počáteční nastavení'));
|
|
213
|
+
console.log(' $ ' + chalk.white('wedos config init'));
|
|
214
|
+
console.log('');
|
|
215
|
+
console.log(chalk.gray(' # Test připojení'));
|
|
216
|
+
console.log(' $ ' + chalk.white('wedos ping'));
|
|
217
|
+
console.log('');
|
|
218
|
+
console.log(chalk.gray(' # Kontrola dostupnosti domény'));
|
|
219
|
+
console.log(' $ ' + chalk.white('wedos check mojedomena.cz'));
|
|
220
|
+
console.log('');
|
|
221
|
+
console.log(chalk.gray(' # Seznam domén'));
|
|
222
|
+
console.log(' $ ' + chalk.white('wedos domain list'));
|
|
223
|
+
console.log('');
|
|
224
|
+
console.log(chalk.gray(' # Přidání DNS záznamu'));
|
|
225
|
+
console.log(' $ ' + chalk.white('wedos dns quick-add domena.cz -a 1.2.3.4'));
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(chalk.gray('─'.repeat(55)));
|
|
228
|
+
console.log('');
|
|
229
|
+
console.log(chalk.gray(' 📖 Nápověda k příkazu: ') + chalk.cyan('wedos <příkaz> --help'));
|
|
230
|
+
console.log('');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Show banner before help
|
|
234
|
+
const originalHelp = program.helpInformation.bind(program);
|
|
235
|
+
program.helpInformation = function() {
|
|
236
|
+
printBanner();
|
|
237
|
+
return originalHelp();
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
program.parse();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { existsSync, readFileSync } from 'fs';
|
|
5
|
+
|
|
6
|
+
const config = new Conf({
|
|
7
|
+
projectName: 'wedos-cli',
|
|
8
|
+
schema: {
|
|
9
|
+
username: { type: 'string' },
|
|
10
|
+
password: { type: 'string' },
|
|
11
|
+
testMode: { type: 'boolean', default: false },
|
|
12
|
+
defaultNsset: { type: 'string', default: 'WEDOS' },
|
|
13
|
+
defaultContact: { type: 'string' },
|
|
14
|
+
outputFormat: { type: 'string', enum: ['table', 'json'], default: 'table' },
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Also check for .wedosrc in home directory or current directory
|
|
19
|
+
function loadRcFile() {
|
|
20
|
+
const paths = [
|
|
21
|
+
join(process.cwd(), '.wedosrc'),
|
|
22
|
+
join(homedir(), '.wedosrc'),
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
for (const path of paths) {
|
|
26
|
+
if (existsSync(path)) {
|
|
27
|
+
try {
|
|
28
|
+
const content = readFileSync(path, 'utf-8');
|
|
29
|
+
return JSON.parse(content);
|
|
30
|
+
} catch {
|
|
31
|
+
// Ignore parse errors
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export function getConfig() {
|
|
39
|
+
const rcConfig = loadRcFile();
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
username: process.env.WEDOS_USERNAME || rcConfig?.username || config.get('username'),
|
|
43
|
+
password: process.env.WEDOS_PASSWORD || rcConfig?.password || config.get('password'),
|
|
44
|
+
testMode: process.env.WEDOS_TEST_MODE === '1' || rcConfig?.testMode || config.get('testMode'),
|
|
45
|
+
defaultNsset: rcConfig?.defaultNsset || config.get('defaultNsset'),
|
|
46
|
+
defaultContact: rcConfig?.defaultContact || config.get('defaultContact'),
|
|
47
|
+
outputFormat: rcConfig?.outputFormat || config.get('outputFormat'),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function setConfig(key, value) {
|
|
52
|
+
config.set(key, value);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function clearConfig() {
|
|
56
|
+
config.clear();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function hasCredentials() {
|
|
60
|
+
const cfg = getConfig();
|
|
61
|
+
return !!(cfg.username && cfg.password);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function getCredentials() {
|
|
65
|
+
const cfg = getConfig();
|
|
66
|
+
if (!cfg.username || !cfg.password) {
|
|
67
|
+
throw new Error('WEDOS credentials not configured. Run: wedos config --username <email> --password <wapi-password>');
|
|
68
|
+
}
|
|
69
|
+
return { username: cfg.username, password: cfg.password, testMode: cfg.testMode };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export default config;
|