@instawp/cli 0.0.1-beta.1 → 0.0.1-beta.2
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/commands/local.d.ts +2 -0
- package/dist/commands/local.js +672 -0
- package/dist/commands/local.js.map +1 -0
- package/dist/commands/sites.js +26 -8
- package/dist/commands/sites.js.map +1 -1
- package/dist/commands/teams.js +52 -3
- package/dist/commands/teams.js.map +1 -1
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/api.js +6 -1
- package/dist/lib/api.js.map +1 -1
- package/dist/lib/config.d.ts +10 -1
- package/dist/lib/config.js +47 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/local-env.d.ts +35 -0
- package/dist/lib/local-env.js +296 -0
- package/dist/lib/local-env.js.map +1 -0
- package/dist/lib/site-resolver.js +32 -11
- package/dist/lib/site-resolver.js.map +1 -1
- package/dist/lib/ssh-connection.d.ts +8 -0
- package/dist/lib/ssh-connection.js +26 -2
- package/dist/lib/ssh-connection.js.map +1 -1
- package/dist/types.d.ts +8 -0
- package/package.json +3 -2
- package/scripts/mysql2sqlite +289 -0
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
2
|
+
import { closeSync, existsSync, mkdirSync, openSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { homedir } from 'node:os';
|
|
5
|
+
import net from 'node:net';
|
|
6
|
+
const LOCAL_BASE_DIR = join(homedir(), '.instawp', 'local');
|
|
7
|
+
const DEFAULT_PORT_START = 9400;
|
|
8
|
+
/**
|
|
9
|
+
* Returns [command, prefixArgs] for running wp-playground-cli.
|
|
10
|
+
* Prefers the global binary (faster) over npx (slower).
|
|
11
|
+
*/
|
|
12
|
+
function getPlaygroundCommand() {
|
|
13
|
+
// Check for globally installed binary first (0.7s vs 1.4s npx overhead)
|
|
14
|
+
const result = spawnSync('which', ['wp-playground-cli'], { stdio: 'pipe' });
|
|
15
|
+
if (result.status === 0) {
|
|
16
|
+
return ['wp-playground-cli', []];
|
|
17
|
+
}
|
|
18
|
+
return ['npx', ['--yes', '@wp-playground/cli']];
|
|
19
|
+
}
|
|
20
|
+
export function getLocalBaseDir() {
|
|
21
|
+
return LOCAL_BASE_DIR;
|
|
22
|
+
}
|
|
23
|
+
export function getInstanceDir(name) {
|
|
24
|
+
return join(LOCAL_BASE_DIR, name);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if downloads.w.org is reachable (WordPress Playground downloads from here).
|
|
28
|
+
* Returns null if OK, or an error message string.
|
|
29
|
+
*/
|
|
30
|
+
export async function checkPlaygroundConnectivity() {
|
|
31
|
+
try {
|
|
32
|
+
const controller = new AbortController();
|
|
33
|
+
const timer = setTimeout(() => controller.abort(), 8000);
|
|
34
|
+
await fetch('https://downloads.w.org', { signal: controller.signal, method: 'HEAD' });
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Check if the alternative domain works
|
|
40
|
+
try {
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timer = setTimeout(() => controller.abort(), 8000);
|
|
43
|
+
await fetch('https://downloads.wordpress.org', { signal: controller.signal, method: 'HEAD' });
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
return 'downloads.w.org is unreachable from your network (downloads.wordpress.org works).\n' +
|
|
46
|
+
'WordPress Playground CLI requires access to downloads.w.org.\n' +
|
|
47
|
+
'Try: adding "192.0.77.48 downloads.w.org" to /etc/hosts, or use a VPN/different network.';
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return 'Cannot reach WordPress download servers (downloads.w.org and downloads.wordpress.org).\n' +
|
|
51
|
+
'Check your internet connection.';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function isPortAvailable(port) {
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
const server = net.createServer();
|
|
58
|
+
server.once('error', () => resolve(false));
|
|
59
|
+
server.once('listening', () => {
|
|
60
|
+
server.close(() => resolve(true));
|
|
61
|
+
});
|
|
62
|
+
server.listen(port, '127.0.0.1');
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
export async function getNextPort(instances) {
|
|
66
|
+
const usedPorts = new Set(Object.values(instances).map(i => i.port));
|
|
67
|
+
let port = DEFAULT_PORT_START;
|
|
68
|
+
while (usedPorts.has(port) || !(await isPortAvailable(port))) {
|
|
69
|
+
port++;
|
|
70
|
+
if (port > 9500)
|
|
71
|
+
throw new Error('No available ports in range 9400-9500');
|
|
72
|
+
}
|
|
73
|
+
return port;
|
|
74
|
+
}
|
|
75
|
+
const AUTO_LOGIN_MU_PLUGIN = `<?php
|
|
76
|
+
/**
|
|
77
|
+
* Auto-login for local development. Injected by InstaWP CLI.
|
|
78
|
+
* Visit /?instawp-login to set the auth cookie and redirect to wp-admin.
|
|
79
|
+
*/
|
|
80
|
+
error_reporting(E_ERROR | E_PARSE);
|
|
81
|
+
@ini_set('display_errors', '0');
|
|
82
|
+
add_action('plugins_loaded', function() {
|
|
83
|
+
if (!isset(\$_GET['instawp-login'])) return;
|
|
84
|
+
\$user = get_user_by('login', 'admin');
|
|
85
|
+
if (!\$user) {
|
|
86
|
+
\$admins = get_users(['role' => 'administrator', 'number' => 1]);
|
|
87
|
+
\$user = \$admins[0] ?? null;
|
|
88
|
+
}
|
|
89
|
+
if (\$user) {
|
|
90
|
+
wp_set_current_user(\$user->ID);
|
|
91
|
+
wp_set_auth_cookie(\$user->ID, true);
|
|
92
|
+
wp_safe_redirect(admin_url());
|
|
93
|
+
exit;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
`;
|
|
97
|
+
export function createInstanceDir(name) {
|
|
98
|
+
const dir = getInstanceDir(name);
|
|
99
|
+
if (existsSync(dir)) {
|
|
100
|
+
throw new Error(`Instance "${name}" already exists at ${dir}`);
|
|
101
|
+
}
|
|
102
|
+
const wpContentDir = join(dir, 'wp-content');
|
|
103
|
+
const muPluginsDir = join(wpContentDir, 'mu-plugins');
|
|
104
|
+
mkdirSync(muPluginsDir, { recursive: true });
|
|
105
|
+
writeFileSync(join(muPluginsDir, '0-instawp-auto-login.php'), AUTO_LOGIN_MU_PLUGIN);
|
|
106
|
+
return dir;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Ensure auto-login mu-plugin exists (for instances created before this was added).
|
|
110
|
+
*/
|
|
111
|
+
export function ensureAutoLogin(instance) {
|
|
112
|
+
const muPluginsDir = join(instance.path, 'wp-content', 'mu-plugins');
|
|
113
|
+
const pluginPath = join(muPluginsDir, '0-instawp-auto-login.php');
|
|
114
|
+
if (!existsSync(pluginPath)) {
|
|
115
|
+
mkdirSync(muPluginsDir, { recursive: true });
|
|
116
|
+
writeFileSync(pluginPath, AUTO_LOGIN_MU_PLUGIN);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
export function deleteInstanceDir(name) {
|
|
120
|
+
const dir = getInstanceDir(name);
|
|
121
|
+
if (existsSync(dir)) {
|
|
122
|
+
rmSync(dir, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function buildServerArgs(instance, blueprint) {
|
|
126
|
+
const wpContentDir = join(instance.path, 'wp-content');
|
|
127
|
+
const isClone = existsSync(join(instance.path, 'sqlite-import.sql')) ||
|
|
128
|
+
existsSync(join(wpContentDir, 'database', '.ht.sqlite'));
|
|
129
|
+
const args = [
|
|
130
|
+
'server',
|
|
131
|
+
`--port=${instance.port}`,
|
|
132
|
+
`--php=${instance.php}`,
|
|
133
|
+
`--wp=${instance.wp}`,
|
|
134
|
+
'--login',
|
|
135
|
+
];
|
|
136
|
+
if (isClone) {
|
|
137
|
+
// For cloned sites: mount subdirs individually AFTER install.
|
|
138
|
+
// This lets Playground set up db.php internally while our data persists.
|
|
139
|
+
const subdirs = ['database', 'plugins', 'themes', 'uploads', 'mu-plugins'];
|
|
140
|
+
for (const subdir of subdirs) {
|
|
141
|
+
const hostDir = join(wpContentDir, subdir);
|
|
142
|
+
if (existsSync(hostDir)) {
|
|
143
|
+
args.push(`--mount=${hostDir}:/wordpress/wp-content/${subdir}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Mount non-core root files (CLAUDE.md, .htaccess, etc.)
|
|
147
|
+
const skipFiles = new Set(['wp-content', 'database.sql', 'sqlite-import.sql', 'clone-blueprint.json', 'import-blueprint.json', 'import-db.php']);
|
|
148
|
+
for (const file of readdirSync(instance.path)) {
|
|
149
|
+
if (skipFiles.has(file) || file.startsWith('.'))
|
|
150
|
+
continue;
|
|
151
|
+
const filePath = join(instance.path, file);
|
|
152
|
+
const stat = statSync(filePath);
|
|
153
|
+
if (stat.isFile()) {
|
|
154
|
+
args.push(`--mount=${filePath}:/wordpress/${file}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Use clone blueprint if it exists (has AST driver + login step)
|
|
158
|
+
if (!blueprint) {
|
|
159
|
+
const cloneBlueprintPath = join(instance.path, 'clone-blueprint.json');
|
|
160
|
+
if (existsSync(cloneBlueprintPath)) {
|
|
161
|
+
blueprint = cloneBlueprintPath;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// For fresh sites: mount entire wp-content before install for persistence
|
|
167
|
+
args.push(`--mount-before-install=${wpContentDir}:/wordpress/wp-content`);
|
|
168
|
+
}
|
|
169
|
+
if (blueprint) {
|
|
170
|
+
args.push(`--blueprint=${blueprint}`);
|
|
171
|
+
}
|
|
172
|
+
return args;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Starts the Playground server in the foreground.
|
|
176
|
+
* Watches stdout for the ready URL and calls onReady when detected.
|
|
177
|
+
* Returns a promise that resolves when the server exits.
|
|
178
|
+
*/
|
|
179
|
+
export function startServer(instance, opts) {
|
|
180
|
+
const args = buildServerArgs(instance, opts?.blueprint);
|
|
181
|
+
const [cmd, prefixArgs] = getPlaygroundCommand();
|
|
182
|
+
return new Promise((resolve, reject) => {
|
|
183
|
+
const child = spawn(cmd, [...prefixArgs, ...args], {
|
|
184
|
+
stdio: ['inherit', 'pipe', 'pipe'],
|
|
185
|
+
cwd: instance.path,
|
|
186
|
+
});
|
|
187
|
+
let readyFired = false;
|
|
188
|
+
// Watch stdout for the server URL to detect readiness
|
|
189
|
+
child.stdout?.on('data', (data) => {
|
|
190
|
+
const text = data.toString();
|
|
191
|
+
process.stdout.write(data);
|
|
192
|
+
if (!readyFired && opts?.onReady) {
|
|
193
|
+
// Playground CLI prints the URL when ready (e.g. "http://127.0.0.1:9400")
|
|
194
|
+
const urlMatch = text.match(/https?:\/\/127\.0\.0\.1:\d+/);
|
|
195
|
+
if (urlMatch) {
|
|
196
|
+
readyFired = true;
|
|
197
|
+
opts.onReady(urlMatch[0]);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
child.stderr?.on('data', (data) => {
|
|
202
|
+
process.stderr.write(data);
|
|
203
|
+
});
|
|
204
|
+
child.on('error', (err) => {
|
|
205
|
+
reject(err);
|
|
206
|
+
});
|
|
207
|
+
child.on('close', (code) => {
|
|
208
|
+
// Restore terminal state — Playground CLI can leave it in raw mode
|
|
209
|
+
if (process.stdin.isTTY) {
|
|
210
|
+
process.stdin.setRawMode?.(false);
|
|
211
|
+
}
|
|
212
|
+
spawnSync('stty', ['sane'], { stdio: 'inherit' });
|
|
213
|
+
resolve(code ?? 0);
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Starts the Playground server in the background.
|
|
219
|
+
* Spawns detached with output going to a log file.
|
|
220
|
+
* Polls until the server is ready, then returns.
|
|
221
|
+
*/
|
|
222
|
+
export async function startServerBackground(instance, blueprint) {
|
|
223
|
+
const args = buildServerArgs(instance, blueprint);
|
|
224
|
+
const [cmd, prefixArgs] = getPlaygroundCommand();
|
|
225
|
+
const logFile = join(instance.path, 'server.log');
|
|
226
|
+
const pidFile = join(instance.path, 'server.pid');
|
|
227
|
+
// Spawn fully detached with output to log file
|
|
228
|
+
const logFd = openSync(logFile, 'w');
|
|
229
|
+
const child = spawn(cmd, [...prefixArgs, ...args], {
|
|
230
|
+
stdio: ['ignore', logFd, logFd],
|
|
231
|
+
cwd: instance.path,
|
|
232
|
+
detached: true,
|
|
233
|
+
});
|
|
234
|
+
const pid = child.pid;
|
|
235
|
+
writeFileSync(pidFile, String(pid));
|
|
236
|
+
child.unref();
|
|
237
|
+
closeSync(logFd);
|
|
238
|
+
// Poll the log file for the ready URL
|
|
239
|
+
const url = `http://127.0.0.1:${instance.port}`;
|
|
240
|
+
const maxWait = 120000;
|
|
241
|
+
const start = Date.now();
|
|
242
|
+
while (Date.now() - start < maxWait) {
|
|
243
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
244
|
+
// Check if process is still alive
|
|
245
|
+
try {
|
|
246
|
+
process.kill(pid, 0);
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
const log = existsSync(logFile) ? readFileSync(logFile, 'utf-8') : '';
|
|
250
|
+
throw new Error(`Server exited unexpectedly. Log:\n${log.slice(-500)}`);
|
|
251
|
+
}
|
|
252
|
+
// Check if server is responding
|
|
253
|
+
try {
|
|
254
|
+
const controller = new AbortController();
|
|
255
|
+
const timer = setTimeout(() => controller.abort(), 2000);
|
|
256
|
+
const res = await fetch(url, { signal: controller.signal, redirect: 'manual' });
|
|
257
|
+
clearTimeout(timer);
|
|
258
|
+
if (res.status === 200 || res.status === 302) {
|
|
259
|
+
return { pid, url };
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
// Not ready yet
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
throw new Error(`Server did not become ready within 120s. Check ${logFile}`);
|
|
267
|
+
}
|
|
268
|
+
export function stopServer(instance) {
|
|
269
|
+
const pidFile = join(instance.path, 'server.pid');
|
|
270
|
+
if (!existsSync(pidFile))
|
|
271
|
+
return false;
|
|
272
|
+
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
273
|
+
try {
|
|
274
|
+
process.kill(pid, 'SIGTERM');
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
// Already dead
|
|
278
|
+
}
|
|
279
|
+
rmSync(pidFile, { force: true });
|
|
280
|
+
return true;
|
|
281
|
+
}
|
|
282
|
+
export function isServerRunning(instance) {
|
|
283
|
+
const pidFile = join(instance.path, 'server.pid');
|
|
284
|
+
if (!existsSync(pidFile))
|
|
285
|
+
return false;
|
|
286
|
+
const pid = parseInt(readFileSync(pidFile, 'utf-8').trim(), 10);
|
|
287
|
+
try {
|
|
288
|
+
process.kill(pid, 0);
|
|
289
|
+
return true;
|
|
290
|
+
}
|
|
291
|
+
catch {
|
|
292
|
+
rmSync(pidFile, { force: true });
|
|
293
|
+
return false;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=local-env.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-env.js","sourceRoot":"","sources":["../../src/lib/local-env.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { getClient } from './api.js';
|
|
2
|
+
import { getSiteCache, setSiteCache } from './config.js';
|
|
2
3
|
import { error, info } from './output.js';
|
|
4
|
+
async function fetchSiteById(client, id) {
|
|
5
|
+
const res = await client.get(`/sites/${id}/details`);
|
|
6
|
+
const data = res.data?.data;
|
|
7
|
+
const site = data?.site || data;
|
|
8
|
+
return normalizeSite(site, data);
|
|
9
|
+
}
|
|
3
10
|
export async function resolveSite(identifier) {
|
|
4
11
|
const client = getClient();
|
|
5
12
|
// If purely numeric, fetch directly by ID
|
|
6
13
|
if (/^\d+$/.test(identifier)) {
|
|
7
14
|
try {
|
|
8
|
-
|
|
9
|
-
const data = res.data?.data;
|
|
10
|
-
const site = data?.site || data;
|
|
11
|
-
return normalizeSite(site, data);
|
|
15
|
+
return await fetchSiteById(client, identifier);
|
|
12
16
|
}
|
|
13
17
|
catch (err) {
|
|
14
18
|
if (err.response?.status === 404) {
|
|
@@ -20,7 +24,19 @@ export async function resolveSite(identifier) {
|
|
|
20
24
|
process.exit(1);
|
|
21
25
|
}
|
|
22
26
|
}
|
|
23
|
-
//
|
|
27
|
+
// Check cache for name/domain → ID mapping
|
|
28
|
+
const cachedId = getSiteCache(identifier);
|
|
29
|
+
if (cachedId) {
|
|
30
|
+
try {
|
|
31
|
+
return await fetchSiteById(client, cachedId);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
// Cache stale (site deleted?), fall through to fresh lookup
|
|
35
|
+
if (err.response?.status !== 404)
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Search by name/domain
|
|
24
40
|
try {
|
|
25
41
|
const res = await client.get('/sites', { params: { per_page: 100 } });
|
|
26
42
|
const sites = res.data?.data || [];
|
|
@@ -43,16 +59,21 @@ export async function resolveSite(identifier) {
|
|
|
43
59
|
info('Use the site ID to be specific.');
|
|
44
60
|
process.exit(1);
|
|
45
61
|
}
|
|
46
|
-
// Single match — fetch full details
|
|
62
|
+
// Single match — cache the mapping and fetch full details
|
|
47
63
|
const match = matches[0];
|
|
64
|
+
setSiteCache(identifier, match.id);
|
|
48
65
|
try {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
66
|
+
const details = await fetchSiteById(client, match.id);
|
|
67
|
+
// Also cache by name and domain for future lookups
|
|
68
|
+
if (match.name)
|
|
69
|
+
setSiteCache(match.name, match.id);
|
|
70
|
+
if (match.sub_domain)
|
|
71
|
+
setSiteCache(match.sub_domain, match.id);
|
|
72
|
+
if (match.domain?.name)
|
|
73
|
+
setSiteCache(match.domain.name, match.id);
|
|
74
|
+
return details;
|
|
53
75
|
}
|
|
54
76
|
catch {
|
|
55
|
-
// Fall back to list data if details endpoint fails
|
|
56
77
|
return normalizeSite(match, match);
|
|
57
78
|
}
|
|
58
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site-resolver.js","sourceRoot":"","sources":["../../src/lib/site-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"site-resolver.js","sourceRoot":"","sources":["../../src/lib/site-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,4 +5,12 @@ export declare function execViaSsh(conn: SshConnection, command: string): {
|
|
|
5
5
|
stderr: string;
|
|
6
6
|
exitCode: number;
|
|
7
7
|
};
|
|
8
|
+
/**
|
|
9
|
+
* Execute a command via SSH and stream stdout directly to a file.
|
|
10
|
+
* Useful for large outputs like database dumps.
|
|
11
|
+
*/
|
|
12
|
+
export declare function execViaSshToFile(conn: SshConnection, command: string, outputPath: string): {
|
|
13
|
+
exitCode: number;
|
|
14
|
+
stderr: string;
|
|
15
|
+
};
|
|
8
16
|
export declare function rsyncViaSsh(conn: SshConnection, source: string, dest: string, extraArgs: string[], dryRun: boolean, stream: boolean): number;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { spawnSync } from 'node:child_process';
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
-
import { existsSync, mkdirSync } from 'node:fs';
|
|
4
|
+
import { existsSync, mkdirSync, openSync, closeSync } from 'node:fs';
|
|
5
5
|
const KNOWN_HOSTS = path.join(homedir(), '.instawp', 'known_hosts');
|
|
6
6
|
function ensureKnownHosts() {
|
|
7
7
|
const dir = path.dirname(KNOWN_HOSTS);
|
|
@@ -41,11 +41,35 @@ export function execViaSsh(conn, command) {
|
|
|
41
41
|
exitCode: result.status ?? 1,
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Execute a command via SSH and stream stdout directly to a file.
|
|
46
|
+
* Useful for large outputs like database dumps.
|
|
47
|
+
*/
|
|
48
|
+
export function execViaSshToFile(conn, command, outputPath) {
|
|
49
|
+
ensureKnownHosts();
|
|
50
|
+
const fd = openSync(outputPath, 'w');
|
|
51
|
+
try {
|
|
52
|
+
const result = spawnSync('ssh', ['-T', ...sshArgs(conn), sshTarget(conn)], {
|
|
53
|
+
input: command + '\n',
|
|
54
|
+
stdio: ['pipe', fd, 'pipe'],
|
|
55
|
+
encoding: 'utf-8',
|
|
56
|
+
maxBuffer: 500 * 1024 * 1024, // 500MB
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
exitCode: result.status ?? 1,
|
|
60
|
+
stderr: result.stderr || '',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
closeSync(fd);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
44
67
|
export function rsyncViaSsh(conn, source, dest, extraArgs, dryRun, stream) {
|
|
45
68
|
ensureKnownHosts();
|
|
46
69
|
const sshCmd = `ssh -i ${conn.privateKeyPath} -p ${conn.port} -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${KNOWN_HOSTS}`;
|
|
47
70
|
const args = [
|
|
48
|
-
'-
|
|
71
|
+
'-arz',
|
|
72
|
+
'--itemize-changes',
|
|
49
73
|
'--exclude=.git',
|
|
50
74
|
'--exclude=node_modules',
|
|
51
75
|
'--exclude=.DS_Store',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssh-connection.js","sourceRoot":"","sources":["../../src/lib/ssh-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"ssh-connection.js","sourceRoot":"","sources":["../../src/lib/ssh-connection.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instawp/cli",
|
|
3
|
-
"version": "0.0.1-beta.
|
|
3
|
+
"version": "0.0.1-beta.2",
|
|
4
4
|
"description": "InstaWP CLI - Create and manage WordPress sites from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"!dist/__tests__"
|
|
11
|
+
"!dist/__tests__",
|
|
12
|
+
"scripts/mysql2sqlite"
|
|
12
13
|
],
|
|
13
14
|
"scripts": {
|
|
14
15
|
"build": "tsc",
|