@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,78 @@
|
|
|
1
|
+
import { getClient } from './api.js';
|
|
2
|
+
import { error, info } from './output.js';
|
|
3
|
+
export async function resolveSite(identifier) {
|
|
4
|
+
const client = getClient();
|
|
5
|
+
// If purely numeric, fetch directly by ID
|
|
6
|
+
if (/^\d+$/.test(identifier)) {
|
|
7
|
+
try {
|
|
8
|
+
const res = await client.get(`/sites/${identifier}/details`);
|
|
9
|
+
const data = res.data?.data;
|
|
10
|
+
const site = data?.site || data;
|
|
11
|
+
return normalizeSite(site, data);
|
|
12
|
+
}
|
|
13
|
+
catch (err) {
|
|
14
|
+
if (err.response?.status === 404) {
|
|
15
|
+
error(`No site found with ID ${identifier}. Use \`instawp sites list\` to see your sites.`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
error('Failed to fetch site details', err.response?.data?.message || err.message);
|
|
19
|
+
}
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Otherwise, search by name/domain
|
|
24
|
+
try {
|
|
25
|
+
const res = await client.get('/sites', { params: { per_page: 100 } });
|
|
26
|
+
const sites = res.data?.data || [];
|
|
27
|
+
const needle = identifier.toLowerCase();
|
|
28
|
+
const matches = sites.filter((s) => {
|
|
29
|
+
const name = (s.name || '').toLowerCase();
|
|
30
|
+
const subDomain = (s.sub_domain || '').toLowerCase();
|
|
31
|
+
const domainName = (s.domain?.name || '').toLowerCase();
|
|
32
|
+
return name === needle || subDomain === needle || domainName === needle;
|
|
33
|
+
});
|
|
34
|
+
if (matches.length === 0) {
|
|
35
|
+
error(`No site found matching '${identifier}'. Use \`instawp sites list\` to see your sites.`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
if (matches.length > 1) {
|
|
39
|
+
error(`Multiple sites match '${identifier}':`);
|
|
40
|
+
for (const s of matches) {
|
|
41
|
+
info(` ID ${s.id}: ${s.name || s.sub_domain} (${s.url || s.domain?.name || s.sub_domain})`);
|
|
42
|
+
}
|
|
43
|
+
info('Use the site ID to be specific.');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
// Single match — fetch full details
|
|
47
|
+
const match = matches[0];
|
|
48
|
+
try {
|
|
49
|
+
const detailRes = await client.get(`/sites/${match.id}/details`);
|
|
50
|
+
const data = detailRes.data?.data;
|
|
51
|
+
const site = data?.site || data;
|
|
52
|
+
return normalizeSite(site, data);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Fall back to list data if details endpoint fails
|
|
56
|
+
return normalizeSite(match, match);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
error('Failed to search sites', err.response?.data?.message || err.message);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function normalizeSite(site, raw) {
|
|
65
|
+
return {
|
|
66
|
+
id: site.id,
|
|
67
|
+
name: site.name || '',
|
|
68
|
+
sub_domain: site.sub_domain || site.main_domain || raw?.sub_domain || '',
|
|
69
|
+
url: site.url || '',
|
|
70
|
+
status: site.status ?? 0,
|
|
71
|
+
wp_version: site.wp_version || '',
|
|
72
|
+
php_version: site.php_version || '',
|
|
73
|
+
domain: site.domain || raw?.domain,
|
|
74
|
+
server_username: site.server_username || raw?.server_username || '',
|
|
75
|
+
main_domain: site.main_domain || raw?.main_domain || '',
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=site-resolver.js.map
|
|
@@ -0,0 +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,KAAK,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAG1C,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAE3B,0CAA0C;IAC1C,IAAI,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,UAAU,UAAU,CAAC,CAAC;YAC7D,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YAChC,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,GAAG,EAAE,CAAC;gBACjC,KAAK,CAAC,yBAAyB,UAAU,iDAAiD,CAAC,CAAC;YAC9F,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;YACpF,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;QACtE,MAAM,KAAK,GAAU,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAE1C,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE;YACtC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAC1C,MAAM,SAAS,GAAG,CAAC,CAAC,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACrD,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YACxD,OAAO,IAAI,KAAK,MAAM,IAAI,SAAS,KAAK,MAAM,IAAI,UAAU,KAAK,MAAM,CAAC;QAC1E,CAAC,CAAC,CAAC;QAEH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,KAAK,CAAC,2BAA2B,UAAU,kDAAkD,CAAC,CAAC;YAC/F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,KAAK,CAAC,yBAAyB,UAAU,IAAI,CAAC,CAAC;YAC/C,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;YAC/F,CAAC;YACD,IAAI,CAAC,iCAAiC,CAAC,CAAC;YACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,oCAAoC;QACpC,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC;YACjE,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC;YAClC,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,IAAI,CAAC;YAChC,OAAO,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,mDAAmD;YACnD,OAAO,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAS,EAAE,GAAQ;IACxC,OAAO;QACL,EAAE,EAAE,IAAI,CAAC,EAAE;QACX,IAAI,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE;QACrB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,UAAU,IAAI,EAAE;QACxE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,EAAE;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,CAAC;QACxB,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,EAAE;QACjC,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,EAAE;QACnC,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,MAAM;QAClC,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,GAAG,EAAE,eAAe,IAAI,EAAE;QACnE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,GAAG,EAAE,WAAW,IAAI,EAAE;KACxD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SshConnection } from '../types.js';
|
|
2
|
+
export declare function spawnInteractiveSsh(conn: SshConnection): number;
|
|
3
|
+
export declare function execViaSsh(conn: SshConnection, command: string): {
|
|
4
|
+
stdout: string;
|
|
5
|
+
stderr: string;
|
|
6
|
+
exitCode: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function rsyncViaSsh(conn: SshConnection, source: string, dest: string, extraArgs: string[], dryRun: boolean, stream: boolean): number;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { existsSync, mkdirSync } from 'node:fs';
|
|
5
|
+
const KNOWN_HOSTS = path.join(homedir(), '.instawp', 'known_hosts');
|
|
6
|
+
function ensureKnownHosts() {
|
|
7
|
+
const dir = path.dirname(KNOWN_HOSTS);
|
|
8
|
+
if (!existsSync(dir)) {
|
|
9
|
+
mkdirSync(dir, { recursive: true });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
function sshArgs(conn) {
|
|
13
|
+
ensureKnownHosts();
|
|
14
|
+
return [
|
|
15
|
+
'-i', conn.privateKeyPath,
|
|
16
|
+
'-p', String(conn.port),
|
|
17
|
+
'-o', 'StrictHostKeyChecking=accept-new',
|
|
18
|
+
'-o', `UserKnownHostsFile=${KNOWN_HOSTS}`,
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function sshTarget(conn) {
|
|
22
|
+
return `${conn.username}@${conn.host}`;
|
|
23
|
+
}
|
|
24
|
+
export function spawnInteractiveSsh(conn) {
|
|
25
|
+
const result = spawnSync('ssh', [...sshArgs(conn), sshTarget(conn)], {
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
});
|
|
28
|
+
return result.status ?? 1;
|
|
29
|
+
}
|
|
30
|
+
export function execViaSsh(conn, command) {
|
|
31
|
+
// Pipe command via stdin with -T (no PTY) — InstaWP servers require this
|
|
32
|
+
// instead of passing command as SSH args
|
|
33
|
+
const result = spawnSync('ssh', ['-T', ...sshArgs(conn), sshTarget(conn)], {
|
|
34
|
+
input: command + '\n',
|
|
35
|
+
encoding: 'utf-8',
|
|
36
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
37
|
+
});
|
|
38
|
+
return {
|
|
39
|
+
stdout: result.stdout || '',
|
|
40
|
+
stderr: result.stderr || '',
|
|
41
|
+
exitCode: result.status ?? 1,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function rsyncViaSsh(conn, source, dest, extraArgs, dryRun, stream) {
|
|
45
|
+
ensureKnownHosts();
|
|
46
|
+
const sshCmd = `ssh -i ${conn.privateKeyPath} -p ${conn.port} -o StrictHostKeyChecking=accept-new -o UserKnownHostsFile=${KNOWN_HOSTS}`;
|
|
47
|
+
const args = [
|
|
48
|
+
'-avz',
|
|
49
|
+
'--exclude=.git',
|
|
50
|
+
'--exclude=node_modules',
|
|
51
|
+
'--exclude=.DS_Store',
|
|
52
|
+
...(dryRun ? ['--dry-run'] : []),
|
|
53
|
+
...extraArgs,
|
|
54
|
+
'-e', sshCmd,
|
|
55
|
+
source,
|
|
56
|
+
dest,
|
|
57
|
+
];
|
|
58
|
+
const result = spawnSync('rsync', args, {
|
|
59
|
+
stdio: stream ? 'inherit' : ['pipe', 'pipe', 'pipe'],
|
|
60
|
+
encoding: stream ? undefined : 'utf-8',
|
|
61
|
+
});
|
|
62
|
+
if (!stream && result.stdout) {
|
|
63
|
+
console.log(result.stdout);
|
|
64
|
+
}
|
|
65
|
+
if (!stream && result.stderr && result.status !== 0) {
|
|
66
|
+
console.error(result.stderr);
|
|
67
|
+
}
|
|
68
|
+
return result.status ?? 1;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=ssh-connection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-connection.js","sourceRoot":"","sources":["../../src/lib/ssh-connection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import { existsSync, readFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { getClient } from './api.js';
|
|
6
|
+
import { getSshCache, setSshCache, clearSshCache } from './config.js';
|
|
7
|
+
import { error, spinner } from './output.js';
|
|
8
|
+
const INSTAWP_DIR = path.join(homedir(), '.instawp');
|
|
9
|
+
const CLI_KEY_PATH = path.join(INSTAWP_DIR, 'cli_key');
|
|
10
|
+
const CLI_KEY_PUB_PATH = CLI_KEY_PATH + '.pub';
|
|
11
|
+
function ensureInstawpDir() {
|
|
12
|
+
if (!existsSync(INSTAWP_DIR)) {
|
|
13
|
+
mkdirSync(INSTAWP_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
function findLocalPubKeys() {
|
|
17
|
+
const keys = [];
|
|
18
|
+
const sshDir = path.join(homedir(), '.ssh');
|
|
19
|
+
// Check CLI-managed key first
|
|
20
|
+
if (existsSync(CLI_KEY_PUB_PATH) && existsSync(CLI_KEY_PATH)) {
|
|
21
|
+
keys.push({ privatePath: CLI_KEY_PATH, pubContent: readFileSync(CLI_KEY_PUB_PATH, 'utf-8').trim() });
|
|
22
|
+
}
|
|
23
|
+
// Check common SSH key locations (RSA first — API only accepts ssh-rsa/ssh-dss)
|
|
24
|
+
for (const name of ['id_rsa', 'id_ed25519']) {
|
|
25
|
+
const privPath = path.join(sshDir, name);
|
|
26
|
+
const pubPath = privPath + '.pub';
|
|
27
|
+
if (existsSync(pubPath) && existsSync(privPath)) {
|
|
28
|
+
keys.push({ privatePath: privPath, pubContent: readFileSync(pubPath, 'utf-8').trim() });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return keys;
|
|
32
|
+
}
|
|
33
|
+
function parseKeyMaterial(pubContent) {
|
|
34
|
+
// Extract "type base64data" ignoring comment
|
|
35
|
+
const parts = pubContent.trim().split(/\s+/);
|
|
36
|
+
if (parts.length >= 2) {
|
|
37
|
+
return `${parts[0]} ${parts[1]}`;
|
|
38
|
+
}
|
|
39
|
+
return pubContent.trim();
|
|
40
|
+
}
|
|
41
|
+
function generateCliKey() {
|
|
42
|
+
ensureInstawpDir();
|
|
43
|
+
try {
|
|
44
|
+
// Use yes to auto-overwrite if an old key exists (e.g. wrong type)
|
|
45
|
+
execSync(`yes | ssh-keygen -t rsa -b 4096 -f "${CLI_KEY_PATH}" -N "" -C "instawp-cli"`, {
|
|
46
|
+
stdio: 'ignore',
|
|
47
|
+
shell: '/bin/sh',
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
error('Failed to generate SSH key. Ensure ssh-keygen (OpenSSH) is installed.');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
privatePath: CLI_KEY_PATH,
|
|
56
|
+
pubContent: readFileSync(CLI_KEY_PUB_PATH, 'utf-8').trim(),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export async function ensureSshAccess(siteId) {
|
|
60
|
+
// 1. Check cache
|
|
61
|
+
const cached = getSshCache(siteId);
|
|
62
|
+
if (cached) {
|
|
63
|
+
// Verify the private key still exists
|
|
64
|
+
if (existsSync(cached.connection.privateKeyPath)) {
|
|
65
|
+
return cached.connection;
|
|
66
|
+
}
|
|
67
|
+
clearSshCache(siteId);
|
|
68
|
+
}
|
|
69
|
+
const client = getClient();
|
|
70
|
+
const spin = spinner('Setting up SSH access...');
|
|
71
|
+
spin.start();
|
|
72
|
+
try {
|
|
73
|
+
// 2. Find local keys
|
|
74
|
+
let localKeys = findLocalPubKeys();
|
|
75
|
+
// 3. Fetch uploaded keys from API
|
|
76
|
+
let uploadedKeys = [];
|
|
77
|
+
try {
|
|
78
|
+
const res = await client.get('/ssh-keys');
|
|
79
|
+
uploadedKeys = (res.data?.data || []).map((k) => ({
|
|
80
|
+
id: k.id,
|
|
81
|
+
label: k.label || '',
|
|
82
|
+
ssh_key: k.ssh_key || '',
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// SSH keys endpoint might not exist; proceed to upload
|
|
87
|
+
}
|
|
88
|
+
// 4. Find a matching key (local key already uploaded)
|
|
89
|
+
let matchedKey = null;
|
|
90
|
+
for (const local of localKeys) {
|
|
91
|
+
const localMaterial = parseKeyMaterial(local.pubContent);
|
|
92
|
+
for (const uploaded of uploadedKeys) {
|
|
93
|
+
const uploadedMaterial = parseKeyMaterial(uploaded.ssh_key);
|
|
94
|
+
if (localMaterial === uploadedMaterial) {
|
|
95
|
+
matchedKey = { privatePath: local.privatePath, keyId: uploaded.id };
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (matchedKey)
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
// 5. If no match, generate CLI key if needed, then upload
|
|
103
|
+
if (!matchedKey) {
|
|
104
|
+
let keyToUpload;
|
|
105
|
+
const cliKeyExists = existsSync(CLI_KEY_PUB_PATH) && existsSync(CLI_KEY_PATH);
|
|
106
|
+
const cliKeyIsRsa = cliKeyExists && readFileSync(CLI_KEY_PUB_PATH, 'utf-8').trim().startsWith('ssh-rsa ');
|
|
107
|
+
if (cliKeyExists && cliKeyIsRsa) {
|
|
108
|
+
keyToUpload = {
|
|
109
|
+
privatePath: CLI_KEY_PATH,
|
|
110
|
+
pubContent: readFileSync(CLI_KEY_PUB_PATH, 'utf-8').trim(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
spin.text = 'Generating SSH key...';
|
|
115
|
+
keyToUpload = generateCliKey();
|
|
116
|
+
}
|
|
117
|
+
spin.text = 'Uploading SSH key...';
|
|
118
|
+
try {
|
|
119
|
+
const uploadRes = await client.post('/ssh-keys', {
|
|
120
|
+
label: 'InstaWP CLI',
|
|
121
|
+
ssh_key: keyToUpload.pubContent,
|
|
122
|
+
});
|
|
123
|
+
const keyId = uploadRes.data?.data?.id;
|
|
124
|
+
if (!keyId) {
|
|
125
|
+
spin.fail('SSH key upload failed');
|
|
126
|
+
error('Unexpected response when uploading SSH key');
|
|
127
|
+
process.exit(1);
|
|
128
|
+
}
|
|
129
|
+
matchedKey = { privatePath: keyToUpload.privatePath, keyId };
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
spin.fail('SSH key upload failed');
|
|
133
|
+
const msg = err.response?.data?.message || err.message;
|
|
134
|
+
if (err.response?.status === 403) {
|
|
135
|
+
error('Payment method required. Add one at app.instawp.io/billing');
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
error('Failed to upload SSH key', msg);
|
|
139
|
+
}
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// 6. Enable SSH + SFTP on site (must happen before attach — creates Server_ssh record)
|
|
144
|
+
// SFTP is required for rsync to work (enables the remote command subsystem)
|
|
145
|
+
spin.text = 'Enabling SSH...';
|
|
146
|
+
let sshDetails;
|
|
147
|
+
try {
|
|
148
|
+
const enableRes = await client.post(`/sites/${siteId}/update-ssh-status`, { status: 1 });
|
|
149
|
+
// API returns host/username at top level or inside data
|
|
150
|
+
const resp = enableRes.data || {};
|
|
151
|
+
const data = resp.data && typeof resp.data === 'object' && !Array.isArray(resp.data) ? resp.data : {};
|
|
152
|
+
sshDetails = {
|
|
153
|
+
host: resp.host || data.host || data.ip || '',
|
|
154
|
+
username: resp.username || data.username || '',
|
|
155
|
+
port: resp.port || data.port || 22,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
spin.fail('Failed to enable SSH');
|
|
160
|
+
const msg = err.response?.data?.message || err.message;
|
|
161
|
+
if (err.response?.status === 403) {
|
|
162
|
+
error('SSH requires a paid plan. Upgrade at app.instawp.io/billing');
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
error('Could not enable SSH on site', msg);
|
|
166
|
+
}
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
// Also enable SFTP (needed for rsync remote command execution)
|
|
170
|
+
try {
|
|
171
|
+
await client.post(`/sites/${siteId}/update-sftp-status`, { status: 1 });
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
// Non-fatal — SFTP may already be enabled or not available
|
|
175
|
+
}
|
|
176
|
+
// 7. Attach key to site (after SSH enabled so Server_ssh record exists)
|
|
177
|
+
spin.text = 'Attaching SSH key to site...';
|
|
178
|
+
try {
|
|
179
|
+
await client.post(`/sites/${siteId}/ssh-keys/${matchedKey.keyId}`);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
// 409/duplicate is fine — key already attached
|
|
183
|
+
if (err.response?.status !== 409 && err.response?.status !== 422) {
|
|
184
|
+
spin.fail('Failed to attach SSH key');
|
|
185
|
+
const msg = err.response?.data?.message || err.message;
|
|
186
|
+
if (err.response?.status === 403) {
|
|
187
|
+
error('Payment method required. Add one at app.instawp.io/billing');
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
error('Could not attach SSH key to site', msg);
|
|
191
|
+
}
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
if (!sshDetails.host || !sshDetails.username) {
|
|
196
|
+
spin.fail('SSH details incomplete');
|
|
197
|
+
error('Could not get SSH connection details from API');
|
|
198
|
+
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
// 8. Build and cache connection
|
|
201
|
+
const connection = {
|
|
202
|
+
host: sshDetails.host,
|
|
203
|
+
username: sshDetails.username,
|
|
204
|
+
port: sshDetails.port,
|
|
205
|
+
privateKeyPath: matchedKey.privatePath,
|
|
206
|
+
siteId,
|
|
207
|
+
domain: '',
|
|
208
|
+
};
|
|
209
|
+
// Fetch domain for remote path construction
|
|
210
|
+
try {
|
|
211
|
+
const siteRes = await client.get(`/sites/${siteId}/details`);
|
|
212
|
+
const siteData = siteRes.data?.data;
|
|
213
|
+
const site = siteData?.site || siteData;
|
|
214
|
+
connection.domain = site?.main_domain || site?.sub_domain || site?.domain?.name || '';
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Non-fatal; domain used only for rsync path
|
|
218
|
+
}
|
|
219
|
+
setSshCache(siteId, { connection, cachedAt: Date.now() });
|
|
220
|
+
spin.succeed('SSH access ready');
|
|
221
|
+
return connection;
|
|
222
|
+
}
|
|
223
|
+
catch (err) {
|
|
224
|
+
// Re-throw if already handled (process.exit above)
|
|
225
|
+
if (err.code === 'ERR_PROCESS_EXIT')
|
|
226
|
+
throw err;
|
|
227
|
+
spin.fail('SSH setup failed');
|
|
228
|
+
error('Unexpected error during SSH setup', err.message);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
//# sourceMappingURL=ssh-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssh-keys.js","sourceRoot":"","sources":["../../src/lib/ssh-keys.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
export interface CliConfig {
|
|
2
|
+
api_url: string;
|
|
3
|
+
token: string | null;
|
|
4
|
+
user: UserInfo | null;
|
|
5
|
+
}
|
|
6
|
+
export interface UserInfo {
|
|
7
|
+
id: number;
|
|
8
|
+
name: string;
|
|
9
|
+
email: string;
|
|
10
|
+
}
|
|
11
|
+
export interface Site {
|
|
12
|
+
id: number;
|
|
13
|
+
domain: string;
|
|
14
|
+
url: string;
|
|
15
|
+
status: string;
|
|
16
|
+
wp_version: string;
|
|
17
|
+
php_version: string;
|
|
18
|
+
created_at: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SiteCreateParams {
|
|
21
|
+
site_name: string;
|
|
22
|
+
php_version?: string;
|
|
23
|
+
plan_id?: number;
|
|
24
|
+
configuration_id?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface SftpCredentials {
|
|
27
|
+
host: string;
|
|
28
|
+
username: string;
|
|
29
|
+
password: string;
|
|
30
|
+
port: number;
|
|
31
|
+
}
|
|
32
|
+
export interface RunCmdResult {
|
|
33
|
+
output: string;
|
|
34
|
+
exit_code: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ApiResponse<T = any> {
|
|
37
|
+
status: boolean;
|
|
38
|
+
data: T;
|
|
39
|
+
message?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface SiteDetails {
|
|
42
|
+
id: number;
|
|
43
|
+
name: string;
|
|
44
|
+
sub_domain: string;
|
|
45
|
+
url: string;
|
|
46
|
+
status: number;
|
|
47
|
+
wp_version: string;
|
|
48
|
+
php_version: string;
|
|
49
|
+
domain?: {
|
|
50
|
+
name: string;
|
|
51
|
+
};
|
|
52
|
+
server_username?: string;
|
|
53
|
+
main_domain?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface SshKeyInfo {
|
|
56
|
+
id: number;
|
|
57
|
+
label: string;
|
|
58
|
+
ssh_key: string;
|
|
59
|
+
}
|
|
60
|
+
export interface SshConnection {
|
|
61
|
+
host: string;
|
|
62
|
+
username: string;
|
|
63
|
+
port: number;
|
|
64
|
+
privateKeyPath: string;
|
|
65
|
+
siteId: number;
|
|
66
|
+
domain: string;
|
|
67
|
+
}
|
|
68
|
+
export interface SshConnectionCache {
|
|
69
|
+
connection: SshConnection;
|
|
70
|
+
cachedAt: number;
|
|
71
|
+
}
|
|
72
|
+
export interface TeamInfo {
|
|
73
|
+
id: number;
|
|
74
|
+
name: string;
|
|
75
|
+
created_at: string;
|
|
76
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@instawp/cli",
|
|
3
|
+
"version": "0.0.1-beta.1",
|
|
4
|
+
"description": "InstaWP CLI - Create and manage WordPress sites from the terminal",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"instawp": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"!dist/__tests__"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "tsc",
|
|
15
|
+
"dev": "tsc --watch",
|
|
16
|
+
"prepublishOnly": "npm run build",
|
|
17
|
+
"test": "vitest run",
|
|
18
|
+
"test:watch": "vitest"
|
|
19
|
+
},
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=18"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"instawp",
|
|
25
|
+
"wordpress",
|
|
26
|
+
"wp-cli",
|
|
27
|
+
"cli",
|
|
28
|
+
"hosting",
|
|
29
|
+
"devtools"
|
|
30
|
+
],
|
|
31
|
+
"homepage": "https://github.com/InstaWP/cli#readme",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "git+https://github.com/InstaWP/cli.git"
|
|
35
|
+
},
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/InstaWP/cli/issues"
|
|
38
|
+
},
|
|
39
|
+
"author": "InstaWP <vikas@instawp.com>",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"axios": "^1.7.0",
|
|
43
|
+
"chalk": "^5.3.0",
|
|
44
|
+
"cli-table3": "^0.6.5",
|
|
45
|
+
"commander": "^12.1.0",
|
|
46
|
+
"conf": "^13.0.0",
|
|
47
|
+
"open": "^10.1.0",
|
|
48
|
+
"ora": "^8.1.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^20.0.0",
|
|
52
|
+
"typescript": "^5.5.0",
|
|
53
|
+
"vitest": "^4.0.18"
|
|
54
|
+
}
|
|
55
|
+
}
|