@instawp/cli 0.0.1-beta.1
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 +129 -0
- package/dist/commands/exec.d.ts +3 -0
- package/dist/commands/exec.js +126 -0
- package/dist/commands/exec.js.map +1 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +63 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/sites.d.ts +3 -0
- package/dist/commands/sites.js +343 -0
- package/dist/commands/sites.js.map +1 -0
- package/dist/commands/ssh.d.ts +2 -0
- package/dist/commands/ssh.js +41 -0
- package/dist/commands/ssh.js.map +1 -0
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +131 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/teams.d.ts +2 -0
- package/dist/commands/teams.js +122 -0
- package/dist/commands/teams.js.map +1 -0
- package/dist/commands/whoami.d.ts +2 -0
- package/dist/commands/whoami.js +60 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +101 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +4 -0
- package/dist/lib/api.js +45 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/auth.d.ts +1 -0
- package/dist/lib/auth.js +75 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/lib/config.d.ts +11 -0
- package/dist/lib/config.js +66 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/output.d.ts +14 -0
- package/dist/lib/output.js +63 -0
- package/dist/lib/output.js.map +1 -0
- package/dist/lib/site-resolver.d.ts +2 -0
- package/dist/lib/site-resolver.js +78 -0
- package/dist/lib/site-resolver.js.map +1 -0
- package/dist/lib/ssh-connection.d.ts +8 -0
- package/dist/lib/ssh-connection.js +70 -0
- package/dist/lib/ssh-connection.js.map +1 -0
- package/dist/lib/ssh-keys.d.ts +2 -0
- package/dist/lib/ssh-keys.js +232 -0
- package/dist/lib/ssh-keys.js.map +1 -0
- package/dist/types.d.ts +76 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import chalk from 'chalk';
|
|
2
|
+
import { requireAuth, getClient } from '../lib/api.js';
|
|
3
|
+
import { resolveSite } from '../lib/site-resolver.js';
|
|
4
|
+
import { success, error, table, spinner, info, isJsonMode } from '../lib/output.js';
|
|
5
|
+
export function registerSitesCommand(program) {
|
|
6
|
+
const sites = program
|
|
7
|
+
.command('sites')
|
|
8
|
+
.description('Manage WordPress sites');
|
|
9
|
+
// sites list
|
|
10
|
+
sites
|
|
11
|
+
.command('list')
|
|
12
|
+
.description('List all sites')
|
|
13
|
+
.option('--status <status>', 'Filter by status')
|
|
14
|
+
.option('--page <page>', 'Page number', '1')
|
|
15
|
+
.option('--per-page <count>', 'Results per page', '20')
|
|
16
|
+
.action(async (opts) => {
|
|
17
|
+
requireAuth();
|
|
18
|
+
const spin = spinner('Fetching sites...');
|
|
19
|
+
spin.start();
|
|
20
|
+
try {
|
|
21
|
+
const client = getClient();
|
|
22
|
+
const params = {
|
|
23
|
+
page: parseInt(opts.page),
|
|
24
|
+
per_page: parseInt(opts.perPage),
|
|
25
|
+
};
|
|
26
|
+
if (opts.status)
|
|
27
|
+
params.status = opts.status;
|
|
28
|
+
const res = await client.get('/sites', { params });
|
|
29
|
+
spin.stop();
|
|
30
|
+
const sites = res.data?.data || [];
|
|
31
|
+
if (sites.length === 0) {
|
|
32
|
+
if (isJsonMode()) {
|
|
33
|
+
console.log(JSON.stringify([]));
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
info('No sites found.');
|
|
37
|
+
}
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const rows = sites.map((s) => ({
|
|
41
|
+
id: s.id,
|
|
42
|
+
name: s.name || '',
|
|
43
|
+
domain: s.domain?.name || s.sub_domain || '',
|
|
44
|
+
url: s.url || '',
|
|
45
|
+
status: s.status === 0 ? 'Active' : s.is_expired ? 'Expired' : s.status || 'Unknown',
|
|
46
|
+
wp_version: s.wp_version || '',
|
|
47
|
+
php_version: s.php_version || '',
|
|
48
|
+
created_at: s.created_at || '',
|
|
49
|
+
}));
|
|
50
|
+
table(['ID', 'Name', 'URL', 'Status', 'WP Version', 'PHP Version'], rows);
|
|
51
|
+
}
|
|
52
|
+
catch (err) {
|
|
53
|
+
spin.fail('Failed to fetch sites');
|
|
54
|
+
error('Could not list sites', err.response?.data?.message || err.message);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
// sites create
|
|
59
|
+
sites
|
|
60
|
+
.command('create')
|
|
61
|
+
.description('Create a new WordPress site')
|
|
62
|
+
.requiredOption('--name <name>', 'Site name')
|
|
63
|
+
.option('--php <version>', 'PHP version (e.g., 8.2)')
|
|
64
|
+
.option('--config <id>', 'Configuration ID')
|
|
65
|
+
.option('--no-wait', 'Do not wait for site to become active')
|
|
66
|
+
.action(createSiteAction);
|
|
67
|
+
// sites delete
|
|
68
|
+
sites
|
|
69
|
+
.command('delete <site>')
|
|
70
|
+
.description('Delete a site (by ID, name, or domain)')
|
|
71
|
+
.option('--force', 'Skip confirmation')
|
|
72
|
+
.action(async (siteIdentifier, opts) => {
|
|
73
|
+
requireAuth();
|
|
74
|
+
const spin = spinner('Resolving site...');
|
|
75
|
+
spin.start();
|
|
76
|
+
let site;
|
|
77
|
+
try {
|
|
78
|
+
site = await resolveSite(siteIdentifier);
|
|
79
|
+
spin.stop();
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
spin.fail('Site resolution failed');
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const label = site.name || site.sub_domain || String(site.id);
|
|
86
|
+
if (!opts.force) {
|
|
87
|
+
if (isJsonMode()) {
|
|
88
|
+
error('Use --force flag to delete in JSON mode');
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
// Interactive confirmation
|
|
92
|
+
const readline = await import('node:readline');
|
|
93
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
94
|
+
const answer = await new Promise((resolve) => {
|
|
95
|
+
rl.question(`Are you sure you want to delete site "${label}" (ID: ${site.id})? (y/N) `, resolve);
|
|
96
|
+
});
|
|
97
|
+
rl.close();
|
|
98
|
+
if (answer.toLowerCase() !== 'y') {
|
|
99
|
+
info('Cancelled.');
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const spin2 = spinner(`Deleting site ${label}...`);
|
|
104
|
+
spin2.start();
|
|
105
|
+
try {
|
|
106
|
+
const client = getClient();
|
|
107
|
+
await client.delete(`/sites/${site.id}`);
|
|
108
|
+
spin2.stop();
|
|
109
|
+
success(`Site "${label}" (ID: ${site.id}) has been deleted`);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
spin2.fail('Failed to delete site');
|
|
113
|
+
error('Could not delete site', err.response?.data?.message || err.message);
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
// Shared create action used by both `sites create` and top-level `create`
|
|
119
|
+
async function createSiteAction(opts) {
|
|
120
|
+
requireAuth();
|
|
121
|
+
const json = isJsonMode();
|
|
122
|
+
const startTime = Date.now();
|
|
123
|
+
const elapsed = () => ((Date.now() - startTime) / 1000).toFixed(1);
|
|
124
|
+
// Step indicator helpers for human mode
|
|
125
|
+
const step = (msg) => { if (!json)
|
|
126
|
+
console.log(chalk.green('\u2713') + ' ' + msg); };
|
|
127
|
+
const heading = (msg) => { if (!json)
|
|
128
|
+
console.log('\n' + chalk.dim('#') + ' ' + msg); };
|
|
129
|
+
const spin = spinner('Submitting site request...');
|
|
130
|
+
spin.start();
|
|
131
|
+
try {
|
|
132
|
+
const client = getClient();
|
|
133
|
+
const payload = {
|
|
134
|
+
site_name: opts.name,
|
|
135
|
+
};
|
|
136
|
+
if (opts.php)
|
|
137
|
+
payload.php_version = opts.php;
|
|
138
|
+
if (opts.config)
|
|
139
|
+
payload.configuration_id = parseInt(opts.config);
|
|
140
|
+
const res = await client.post('/sites', payload);
|
|
141
|
+
const site = res.data?.data;
|
|
142
|
+
if (!site?.id) {
|
|
143
|
+
spin.fail('Site creation failed');
|
|
144
|
+
error('Unexpected response from API', res.data);
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
spin.stop();
|
|
148
|
+
// If --no-wait or JSON mode without wait, return immediately
|
|
149
|
+
if (!opts.wait) {
|
|
150
|
+
if (json) {
|
|
151
|
+
console.log(JSON.stringify({ success: true, data: { id: site.id, status: 'provisioning' } }));
|
|
152
|
+
}
|
|
153
|
+
else {
|
|
154
|
+
success('Site creation initiated', {
|
|
155
|
+
id: site.id,
|
|
156
|
+
status: site.status || 'provisioning',
|
|
157
|
+
});
|
|
158
|
+
info('Use --wait to wait for provisioning (default). Pass --no-wait to skip.');
|
|
159
|
+
}
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Progressive provisioning output
|
|
163
|
+
heading(`Provisioning WordPress...`);
|
|
164
|
+
const maxWait = 5 * 60 * 1000; // 5 minutes
|
|
165
|
+
const pollInterval = 3000; // 3 seconds
|
|
166
|
+
const taskId = site.task_id;
|
|
167
|
+
// Fetch site details once for php_version (available immediately at creation)
|
|
168
|
+
let phpVersion = opts.php || '8.x';
|
|
169
|
+
try {
|
|
170
|
+
const initDetail = await client.get(`/sites/${site.id}/details`);
|
|
171
|
+
phpVersion = initDetail.data?.data?.php_version || phpVersion;
|
|
172
|
+
}
|
|
173
|
+
catch { /* use fallback */ }
|
|
174
|
+
const provSpin = spinner('Setting up server environment...');
|
|
175
|
+
provSpin.start();
|
|
176
|
+
// Track which steps we've shown based on task percentage:
|
|
177
|
+
// ~38% = server environment ready (PHP configured)
|
|
178
|
+
// ~66% = domain/SSL setup done
|
|
179
|
+
// ~79% = WordPress being installed
|
|
180
|
+
// 100% = completed
|
|
181
|
+
const shown = { php: false, ssl: false, wp: false };
|
|
182
|
+
// Helper to update spinner with percentage
|
|
183
|
+
const spinText = (label, pct) => pct > 0 ? `${label} ${chalk.dim(`(${Math.round(pct)}%)`)}` : label;
|
|
184
|
+
while (Date.now() - startTime < maxWait) {
|
|
185
|
+
try {
|
|
186
|
+
// Poll task status for real provisioning progress
|
|
187
|
+
let pct = 0;
|
|
188
|
+
let taskDone = false;
|
|
189
|
+
if (taskId) {
|
|
190
|
+
try {
|
|
191
|
+
const taskRes = await client.get(`/tasks/${taskId}/status`);
|
|
192
|
+
const task = taskRes.data?.data;
|
|
193
|
+
pct = parseFloat(task?.percentage_complete) || 0;
|
|
194
|
+
taskDone = task?.status === 'completed';
|
|
195
|
+
if (task?.status === 'error') {
|
|
196
|
+
provSpin.fail('Provisioning failed');
|
|
197
|
+
error('Site provisioning failed', task?.comment || 'Unknown error');
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch { /* task endpoint may not be available, fall through */ }
|
|
202
|
+
}
|
|
203
|
+
// Update spinner with current percentage
|
|
204
|
+
if (!shown.php) {
|
|
205
|
+
provSpin.text = spinText('Setting up server environment...', pct);
|
|
206
|
+
}
|
|
207
|
+
else if (!shown.ssl) {
|
|
208
|
+
provSpin.text = spinText('Issuing SSL certificate...', pct);
|
|
209
|
+
}
|
|
210
|
+
else if (!shown.wp) {
|
|
211
|
+
provSpin.text = spinText('Installing WordPress...', pct);
|
|
212
|
+
}
|
|
213
|
+
// Show progressive steps based on actual task percentage
|
|
214
|
+
if (!shown.php && pct >= 38) {
|
|
215
|
+
provSpin.text = 'Setting up server environment...';
|
|
216
|
+
provSpin.stop();
|
|
217
|
+
step(`PHP ${phpVersion} configured`);
|
|
218
|
+
shown.php = true;
|
|
219
|
+
provSpin.start();
|
|
220
|
+
}
|
|
221
|
+
if (!shown.ssl && pct >= 66) {
|
|
222
|
+
if (!shown.php) {
|
|
223
|
+
provSpin.text = 'Setting up server environment...';
|
|
224
|
+
provSpin.stop();
|
|
225
|
+
step(`PHP ${phpVersion} configured`);
|
|
226
|
+
shown.php = true;
|
|
227
|
+
}
|
|
228
|
+
provSpin.text = 'Issuing SSL certificate...';
|
|
229
|
+
provSpin.stop();
|
|
230
|
+
step('SSL certificate issued');
|
|
231
|
+
shown.ssl = true;
|
|
232
|
+
provSpin.start();
|
|
233
|
+
}
|
|
234
|
+
if (taskDone || pct >= 100) {
|
|
235
|
+
if (!shown.php) {
|
|
236
|
+
provSpin.stop();
|
|
237
|
+
step(`PHP ${phpVersion} configured`);
|
|
238
|
+
shown.php = true;
|
|
239
|
+
provSpin.start();
|
|
240
|
+
}
|
|
241
|
+
if (!shown.ssl) {
|
|
242
|
+
provSpin.stop();
|
|
243
|
+
step('SSL certificate issued');
|
|
244
|
+
shown.ssl = true;
|
|
245
|
+
provSpin.start();
|
|
246
|
+
}
|
|
247
|
+
provSpin.stop();
|
|
248
|
+
step('WordPress installed');
|
|
249
|
+
// Fetch final site details for the output
|
|
250
|
+
const detailRes = await client.get(`/sites/${site.id}/details`);
|
|
251
|
+
const siteData = detailRes.data?.data;
|
|
252
|
+
const siteInfo = siteData?.site || siteData;
|
|
253
|
+
const meta = siteInfo?.site_meta || siteData?.site_meta || {};
|
|
254
|
+
const siteUrl = siteInfo?.url || site.wp_url || '';
|
|
255
|
+
const domain = siteInfo?.main_domain || siteInfo?.sub_domain
|
|
256
|
+
|| siteInfo?.domain?.name || siteInfo?.domain
|
|
257
|
+
|| siteData?.domain?.name || siteData?.domain || '';
|
|
258
|
+
const wpVersion = siteInfo?.wp_version || '';
|
|
259
|
+
if (json) {
|
|
260
|
+
// If credentials not yet in details, try list endpoint
|
|
261
|
+
let creds = meta;
|
|
262
|
+
if (!creds.wp_username) {
|
|
263
|
+
try {
|
|
264
|
+
const listRes = await client.get('/sites', { params: { per_page: 50 } });
|
|
265
|
+
const match = (listRes.data?.data || []).find((s) => s.id === site.id);
|
|
266
|
+
if (match?.site_meta?.wp_username)
|
|
267
|
+
creds = match.site_meta;
|
|
268
|
+
}
|
|
269
|
+
catch { /* ignore */ }
|
|
270
|
+
}
|
|
271
|
+
console.log(JSON.stringify({
|
|
272
|
+
success: true,
|
|
273
|
+
data: {
|
|
274
|
+
id: site.id,
|
|
275
|
+
url: siteUrl,
|
|
276
|
+
domain,
|
|
277
|
+
wp_version: wpVersion,
|
|
278
|
+
php_version: siteInfo?.php_version || '',
|
|
279
|
+
wp_username: creds.wp_username || '',
|
|
280
|
+
wp_password: creds.wp_password || '',
|
|
281
|
+
wp_admin_url: siteUrl ? `${siteUrl}/wp-admin` : '',
|
|
282
|
+
magic_login_url: creds.wp_magic_login_url || (siteUrl ? `${siteUrl}/wp-login.php?instawp-magic-login=1` : ''),
|
|
283
|
+
status: 'Active',
|
|
284
|
+
elapsed: elapsed() + 's',
|
|
285
|
+
},
|
|
286
|
+
}));
|
|
287
|
+
}
|
|
288
|
+
else {
|
|
289
|
+
// Fetch credentials for human output too
|
|
290
|
+
let creds = meta;
|
|
291
|
+
if (!creds.wp_username) {
|
|
292
|
+
try {
|
|
293
|
+
const listRes = await client.get('/sites', { params: { per_page: 50 } });
|
|
294
|
+
const match = (listRes.data?.data || []).find((s) => s.id === site.id);
|
|
295
|
+
if (match?.site_meta?.wp_username)
|
|
296
|
+
creds = match.site_meta;
|
|
297
|
+
}
|
|
298
|
+
catch { /* ignore */ }
|
|
299
|
+
}
|
|
300
|
+
const displayUrl = siteUrl || (domain ? `https://${domain}` : '');
|
|
301
|
+
console.log(`\n${chalk.bold.green('Ready')} in ${elapsed()}s ${chalk.dim('\u2192')} ${chalk.cyan.underline(displayUrl)}`);
|
|
302
|
+
if (creds.wp_username) {
|
|
303
|
+
console.log(`\n ${chalk.dim('Username:')} ${creds.wp_username}`);
|
|
304
|
+
console.log(` ${chalk.dim('Password:')} ${creds.wp_password}`);
|
|
305
|
+
}
|
|
306
|
+
const adminUrl = displayUrl ? `${displayUrl}/wp-admin` : '';
|
|
307
|
+
if (adminUrl) {
|
|
308
|
+
console.log(` ${chalk.dim('WP Admin:')} ${chalk.cyan.underline(adminUrl)}`);
|
|
309
|
+
}
|
|
310
|
+
const magicUrl = creds.wp_magic_login_url || (siteUrl ? `${siteUrl}/wp-login.php?instawp-magic-login=1` : '');
|
|
311
|
+
if (magicUrl) {
|
|
312
|
+
console.log(` ${chalk.dim('Magic Login:')} ${chalk.cyan.underline(magicUrl)}`);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Ignore polling errors, keep trying
|
|
320
|
+
}
|
|
321
|
+
await new Promise(resolve => setTimeout(resolve, pollInterval));
|
|
322
|
+
}
|
|
323
|
+
provSpin.fail('Timed out waiting for site');
|
|
324
|
+
info(`Site ID ${site.id} was created but may still be provisioning.`);
|
|
325
|
+
info(`Check status with: instawp sites list`);
|
|
326
|
+
}
|
|
327
|
+
catch (err) {
|
|
328
|
+
error('Could not create site', err.response?.data?.message || err.message);
|
|
329
|
+
process.exit(1);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// Register top-level `create` alias
|
|
333
|
+
export function registerCreateAlias(program) {
|
|
334
|
+
program
|
|
335
|
+
.command('create')
|
|
336
|
+
.description('Create a new WordPress site (alias for sites create)')
|
|
337
|
+
.requiredOption('--name <name>', 'Site name')
|
|
338
|
+
.option('--php <version>', 'PHP version (e.g., 8.2)')
|
|
339
|
+
.option('--config <id>', 'Configuration ID')
|
|
340
|
+
.option('--no-wait', 'Do not wait for site to become active')
|
|
341
|
+
.action(createSiteAction);
|
|
342
|
+
}
|
|
343
|
+
//# sourceMappingURL=sites.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sites.js","sourceRoot":"","sources":["../../src/commands/sites.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { requireAuth } from '../lib/api.js';
|
|
2
|
+
import { resolveSite } from '../lib/site-resolver.js';
|
|
3
|
+
import { ensureSshAccess } from '../lib/ssh-keys.js';
|
|
4
|
+
import { spawnInteractiveSsh } from '../lib/ssh-connection.js';
|
|
5
|
+
import { spinner, isJsonMode } from '../lib/output.js';
|
|
6
|
+
export function registerSshCommand(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('ssh <site>')
|
|
9
|
+
.description('Open an interactive SSH shell on a site')
|
|
10
|
+
.action(async (siteIdentifier) => {
|
|
11
|
+
requireAuth();
|
|
12
|
+
const spin = spinner('Resolving site...');
|
|
13
|
+
spin.start();
|
|
14
|
+
let site;
|
|
15
|
+
try {
|
|
16
|
+
site = await resolveSite(siteIdentifier);
|
|
17
|
+
spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
spin.fail('Site resolution failed');
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
const conn = await ensureSshAccess(site.id);
|
|
24
|
+
if (isJsonMode()) {
|
|
25
|
+
console.log(JSON.stringify({
|
|
26
|
+
success: true,
|
|
27
|
+
data: {
|
|
28
|
+
host: conn.host,
|
|
29
|
+
username: conn.username,
|
|
30
|
+
port: conn.port,
|
|
31
|
+
private_key: conn.privateKeyPath,
|
|
32
|
+
command: `ssh -i ${conn.privateKeyPath} -p ${conn.port} ${conn.username}@${conn.host}`,
|
|
33
|
+
},
|
|
34
|
+
}));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const exitCode = spawnInteractiveSsh(conn);
|
|
38
|
+
process.exit(exitCode);
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=ssh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh.js","sourceRoot":"","sources":["../../src/commands/ssh.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAS,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9D,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,KAAK,EAAE,cAAsB,EAAE,EAAE;QACvC,WAAW,EAAE,CAAC;QAEd,MAAM,IAAI,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;QAEb,IAAI,IAAI,CAAC;QACT,IAAI,CAAC;YACH,IAAI,GAAG,MAAM,WAAW,CAAC,cAAc,CAAC,CAAC;YACzC,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,UAAU,SAAS,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;YACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAE5C,IAAI,UAAU,EAAE,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;gBACzB,OAAO,EAAE,IAAI;gBACb,IAAI,EAAE;oBACJ,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;oBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,WAAW,EAAE,IAAI,CAAC,cAAc;oBAChC,OAAO,EAAE,UAAU,IAAI,CAAC,cAAc,OAAO,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE;iBACvF;aACF,CAAC,CAAC,CAAC;YACJ,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;QAC3C,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { requireAuth } from '../lib/api.js';
|
|
3
|
+
import { resolveSite } from '../lib/site-resolver.js';
|
|
4
|
+
import { ensureSshAccess } from '../lib/ssh-keys.js';
|
|
5
|
+
import { rsyncViaSsh } from '../lib/ssh-connection.js';
|
|
6
|
+
import { success, error, spinner, info } from '../lib/output.js';
|
|
7
|
+
function checkRsync() {
|
|
8
|
+
const result = spawnSync('which', ['rsync'], { stdio: 'ignore' });
|
|
9
|
+
return result.status === 0;
|
|
10
|
+
}
|
|
11
|
+
function getRsyncInstallInstructions() {
|
|
12
|
+
const platform = process.platform;
|
|
13
|
+
if (platform === 'darwin')
|
|
14
|
+
return 'Install rsync: brew install rsync';
|
|
15
|
+
if (platform === 'linux')
|
|
16
|
+
return 'Install rsync: sudo apt install rsync (or equivalent for your distro)';
|
|
17
|
+
return 'Install rsync for your platform.';
|
|
18
|
+
}
|
|
19
|
+
function buildRemotePath(conn) {
|
|
20
|
+
return `/home/${conn.username}/web/${conn.domain}/public_html/wp-content/`;
|
|
21
|
+
}
|
|
22
|
+
export function registerSyncCommand(program) {
|
|
23
|
+
const sync = program
|
|
24
|
+
.command('sync')
|
|
25
|
+
.description('Sync wp-content files with a remote site via rsync');
|
|
26
|
+
sync
|
|
27
|
+
.command('push <site>')
|
|
28
|
+
.description('Push local wp-content/ to remote site')
|
|
29
|
+
.option('--path <path>', 'Local wp-content path', './wp-content/')
|
|
30
|
+
.option('--exclude <pattern...>', 'Additional exclude patterns')
|
|
31
|
+
.option('--include <pattern...>', 'Include patterns')
|
|
32
|
+
.option('--dry-run', 'Show what would be transferred')
|
|
33
|
+
.action(async (siteIdentifier, opts) => {
|
|
34
|
+
requireAuth();
|
|
35
|
+
if (!checkRsync()) {
|
|
36
|
+
error('rsync is required for sync.');
|
|
37
|
+
info(getRsyncInstallInstructions());
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const spin = spinner('Resolving site...');
|
|
41
|
+
spin.start();
|
|
42
|
+
let site;
|
|
43
|
+
try {
|
|
44
|
+
site = await resolveSite(siteIdentifier);
|
|
45
|
+
spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
spin.fail('Site resolution failed');
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
const conn = await ensureSshAccess(site.id);
|
|
52
|
+
const localPath = opts.path.endsWith('/') ? opts.path : opts.path + '/';
|
|
53
|
+
const remotePath = buildRemotePath(conn);
|
|
54
|
+
const remoteTarget = `${conn.username}@${conn.host}:${remotePath}`;
|
|
55
|
+
const extraArgs = [];
|
|
56
|
+
if (opts.exclude) {
|
|
57
|
+
for (const pattern of opts.exclude) {
|
|
58
|
+
extraArgs.push(`--exclude=${pattern}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (opts.include) {
|
|
62
|
+
for (const pattern of opts.include) {
|
|
63
|
+
extraArgs.push(`--include=${pattern}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
info(`Pushing ${localPath} -> ${conn.host}:${remotePath}`);
|
|
67
|
+
if (opts.dryRun)
|
|
68
|
+
info('(dry run)');
|
|
69
|
+
const exitCode = rsyncViaSsh(conn, localPath, remoteTarget, extraArgs, !!opts.dryRun, true);
|
|
70
|
+
if (exitCode === 0) {
|
|
71
|
+
success('Push complete');
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
error(`rsync exited with code ${exitCode}`);
|
|
75
|
+
process.exit(exitCode);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
sync
|
|
79
|
+
.command('pull <site>')
|
|
80
|
+
.description('Pull remote wp-content/ to local')
|
|
81
|
+
.option('--path <path>', 'Local destination path', './wp-content/')
|
|
82
|
+
.option('--exclude <pattern...>', 'Additional exclude patterns')
|
|
83
|
+
.option('--include <pattern...>', 'Include patterns')
|
|
84
|
+
.option('--dry-run', 'Show what would be transferred')
|
|
85
|
+
.action(async (siteIdentifier, opts) => {
|
|
86
|
+
requireAuth();
|
|
87
|
+
if (!checkRsync()) {
|
|
88
|
+
error('rsync is required for sync.');
|
|
89
|
+
info(getRsyncInstallInstructions());
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
const spin = spinner('Resolving site...');
|
|
93
|
+
spin.start();
|
|
94
|
+
let site;
|
|
95
|
+
try {
|
|
96
|
+
site = await resolveSite(siteIdentifier);
|
|
97
|
+
spin.succeed(`Site: ${site.name || site.sub_domain} (ID: ${site.id})`);
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
spin.fail('Site resolution failed');
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
const conn = await ensureSshAccess(site.id);
|
|
104
|
+
const localPath = opts.path.endsWith('/') ? opts.path : opts.path + '/';
|
|
105
|
+
const remotePath = buildRemotePath(conn);
|
|
106
|
+
const remoteSource = `${conn.username}@${conn.host}:${remotePath}`;
|
|
107
|
+
const extraArgs = [];
|
|
108
|
+
if (opts.exclude) {
|
|
109
|
+
for (const pattern of opts.exclude) {
|
|
110
|
+
extraArgs.push(`--exclude=${pattern}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (opts.include) {
|
|
114
|
+
for (const pattern of opts.include) {
|
|
115
|
+
extraArgs.push(`--include=${pattern}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
info(`Pulling ${conn.host}:${remotePath} -> ${localPath}`);
|
|
119
|
+
if (opts.dryRun)
|
|
120
|
+
info('(dry run)');
|
|
121
|
+
const exitCode = rsyncViaSsh(conn, remoteSource, localPath, extraArgs, !!opts.dryRun, true);
|
|
122
|
+
if (exitCode === 0) {
|
|
123
|
+
success('Pull complete');
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
error(`rsync exited with code ${exitCode}`);
|
|
127
|
+
process.exit(exitCode);
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=sync.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
|