hostfn 0.1.1 → 0.1.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/__tests__/core/backup.test.d.ts +2 -0
- package/dist/__tests__/core/backup.test.d.ts.map +1 -0
- package/dist/__tests__/core/backup.test.js +108 -0
- package/dist/__tests__/core/backup.test.js.map +1 -0
- package/dist/__tests__/core/health.test.d.ts +2 -0
- package/dist/__tests__/core/health.test.d.ts.map +1 -0
- package/dist/__tests__/core/health.test.js +97 -0
- package/dist/__tests__/core/health.test.js.map +1 -0
- package/dist/__tests__/core/lock.test.d.ts +2 -0
- package/dist/__tests__/core/lock.test.d.ts.map +1 -0
- package/dist/__tests__/core/lock.test.js +136 -0
- package/dist/__tests__/core/lock.test.js.map +1 -0
- package/dist/__tests__/core/nginx-multi-domain.test.d.ts +2 -0
- package/dist/__tests__/core/nginx-multi-domain.test.d.ts.map +1 -0
- package/dist/__tests__/core/nginx-multi-domain.test.js +158 -0
- package/dist/__tests__/core/nginx-multi-domain.test.js.map +1 -0
- package/dist/__tests__/runtimes/pm2.test.d.ts +2 -0
- package/dist/__tests__/runtimes/pm2.test.d.ts.map +1 -0
- package/dist/__tests__/runtimes/pm2.test.js +111 -0
- package/dist/__tests__/runtimes/pm2.test.js.map +1 -0
- package/dist/__tests__/utils/validation.test.d.ts +2 -0
- package/dist/__tests__/utils/validation.test.d.ts.map +1 -0
- package/dist/__tests__/utils/validation.test.js +136 -0
- package/dist/__tests__/utils/validation.test.js.map +1 -0
- package/dist/commands/deploy.d.ts +11 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +636 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/env.d.ts +21 -0
- package/dist/commands/env.d.ts.map +1 -0
- package/dist/commands/env.js +317 -0
- package/dist/commands/env.js.map +1 -0
- package/dist/commands/expose.d.ts +6 -0
- package/dist/commands/expose.d.ts.map +1 -0
- package/dist/commands/expose.js +379 -0
- package/dist/commands/expose.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +175 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/logs.d.ts +10 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +75 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/rollback.d.ts +6 -0
- package/dist/commands/rollback.d.ts.map +1 -0
- package/dist/commands/rollback.js +113 -0
- package/dist/commands/rollback.js.map +1 -0
- package/dist/commands/server/info.d.ts +2 -0
- package/dist/commands/server/info.d.ts.map +1 -0
- package/dist/commands/server/info.js +104 -0
- package/dist/commands/server/info.js.map +1 -0
- package/dist/commands/server/setup.d.ts +11 -0
- package/dist/commands/server/setup.d.ts.map +1 -0
- package/dist/commands/server/setup.js +161 -0
- package/dist/commands/server/setup.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +120 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/loader.d.ts +21 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +54 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +323 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +108 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/core/backup.d.ts +34 -0
- package/dist/core/backup.d.ts.map +1 -0
- package/dist/core/backup.js +95 -0
- package/dist/core/backup.js.map +1 -0
- package/dist/core/health.d.ts +31 -0
- package/dist/core/health.d.ts.map +1 -0
- package/dist/core/health.js +78 -0
- package/dist/core/health.js.map +1 -0
- package/dist/core/local.d.ts +19 -0
- package/dist/core/local.d.ts.map +1 -0
- package/dist/core/local.js +50 -0
- package/dist/core/local.js.map +1 -0
- package/dist/core/lock.d.ts +28 -0
- package/dist/core/lock.d.ts.map +1 -0
- package/dist/core/lock.js +89 -0
- package/dist/core/lock.js.map +1 -0
- package/dist/core/nginx.d.ts +43 -0
- package/dist/core/nginx.d.ts.map +1 -0
- package/dist/core/nginx.js +131 -0
- package/dist/core/nginx.js.map +1 -0
- package/dist/core/ssh.d.ts +79 -0
- package/dist/core/ssh.d.ts.map +1 -0
- package/dist/core/ssh.js +264 -0
- package/dist/core/ssh.js.map +1 -0
- package/dist/core/sync.d.ts +25 -0
- package/dist/core/sync.d.ts.map +1 -0
- package/dist/core/sync.js +117 -0
- package/dist/core/sync.js.map +1 -0
- package/dist/core/workspace.d.ts +13 -0
- package/dist/core/workspace.d.ts.map +1 -0
- package/dist/core/workspace.js +141 -0
- package/dist/core/workspace.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +232 -0
- package/dist/index.js.map +1 -0
- package/dist/runtimes/base.d.ts +115 -0
- package/dist/runtimes/base.d.ts.map +1 -0
- package/dist/runtimes/base.js +16 -0
- package/dist/runtimes/base.js.map +1 -0
- package/dist/runtimes/nodejs/detector.d.ts +47 -0
- package/dist/runtimes/nodejs/detector.d.ts.map +1 -0
- package/dist/runtimes/nodejs/detector.js +143 -0
- package/dist/runtimes/nodejs/detector.js.map +1 -0
- package/dist/runtimes/nodejs/index.d.ts +14 -0
- package/dist/runtimes/nodejs/index.d.ts.map +1 -0
- package/dist/runtimes/nodejs/index.js +213 -0
- package/dist/runtimes/nodejs/index.js.map +1 -0
- package/dist/runtimes/nodejs/pm2.d.ts +17 -0
- package/dist/runtimes/nodejs/pm2.d.ts.map +1 -0
- package/dist/runtimes/nodejs/pm2.js +60 -0
- package/dist/runtimes/nodejs/pm2.js.map +1 -0
- package/dist/runtimes/registry.d.ts +34 -0
- package/dist/runtimes/registry.d.ts.map +1 -0
- package/dist/runtimes/registry.js +58 -0
- package/dist/runtimes/registry.js.map +1 -0
- package/dist/utils/logger.d.ts +47 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +76 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +125 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +33 -16
- package/LICENSE +0 -21
- package/README.md +0 -1136
- package/_conduct/specs/1.v0.spec.md +0 -1041
- package/examples/express-api/package.json +0 -22
- package/examples/express-api/src/index.ts +0 -16
- package/examples/express-api/tsconfig.json +0 -11
- package/examples/github-actions-deploy.yml +0 -40
- package/examples/monorepo-config.json +0 -76
- package/examples/monorepo-multi-server-config.json +0 -74
- package/packages/cli/package.json +0 -40
- package/turbo.json +0 -24
- /package/{packages/cli/src → src}/__tests__/core/backup.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/health.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/lock.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/core/nginx-multi-domain.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/runtimes/pm2.test.ts +0 -0
- /package/{packages/cli/src → src}/__tests__/utils/validation.test.ts +0 -0
- /package/{packages/cli/src → src}/commands/deploy.ts +0 -0
- /package/{packages/cli/src → src}/commands/env.ts +0 -0
- /package/{packages/cli/src → src}/commands/expose.ts +0 -0
- /package/{packages/cli/src → src}/commands/init.ts +0 -0
- /package/{packages/cli/src → src}/commands/logs.ts +0 -0
- /package/{packages/cli/src → src}/commands/rollback.ts +0 -0
- /package/{packages/cli/src → src}/commands/server/info.ts +0 -0
- /package/{packages/cli/src → src}/commands/server/setup.ts +0 -0
- /package/{packages/cli/src → src}/commands/status.ts +0 -0
- /package/{packages/cli/src → src}/config/loader.ts +0 -0
- /package/{packages/cli/src → src}/config/schema.ts +0 -0
- /package/{packages/cli/src → src}/core/backup.ts +0 -0
- /package/{packages/cli/src → src}/core/health.ts +0 -0
- /package/{packages/cli/src → src}/core/local.ts +0 -0
- /package/{packages/cli/src → src}/core/lock.ts +0 -0
- /package/{packages/cli/src → src}/core/nginx.ts +0 -0
- /package/{packages/cli/src → src}/core/ssh.ts +0 -0
- /package/{packages/cli/src → src}/core/sync.ts +0 -0
- /package/{packages/cli/src → src}/core/workspace.ts +0 -0
- /package/{packages/cli/src → src}/index.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/base.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/detector.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/index.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/nodejs/pm2.ts +0 -0
- /package/{packages/cli/src → src}/runtimes/registry.ts +0 -0
- /package/{packages/cli/src → src}/utils/logger.ts +0 -0
- /package/{packages/cli/src → src}/utils/validation.ts +0 -0
- /package/{packages/cli/tsconfig.json → tsconfig.json} +0 -0
- /package/{packages/cli/vitest.config.ts → vitest.config.ts} +0 -0
|
@@ -0,0 +1,379 @@
|
|
|
1
|
+
import ora from 'ora';
|
|
2
|
+
import { Logger } from '../utils/logger.js';
|
|
3
|
+
import { ConfigLoader } from '../config/loader.js';
|
|
4
|
+
import { createSSHConnection } from '../core/ssh.js';
|
|
5
|
+
import { NginxConfigGenerator } from '../core/nginx.js';
|
|
6
|
+
export async function exposeCommand(environment, options) {
|
|
7
|
+
Logger.header('Expose Services via Nginx');
|
|
8
|
+
// Load configuration
|
|
9
|
+
const config = ConfigLoader.load();
|
|
10
|
+
const envConfig = config.environments[environment];
|
|
11
|
+
if (!envConfig) {
|
|
12
|
+
throw new Error(`Environment '${environment}' not found in configuration\n` +
|
|
13
|
+
`Available: ${Object.keys(config.environments).join(', ')}`);
|
|
14
|
+
}
|
|
15
|
+
const host = options.host || envConfig.server;
|
|
16
|
+
const domainConfig = envConfig.domain;
|
|
17
|
+
// Handle both single domain string and array of domains
|
|
18
|
+
const domains = domainConfig ? (Array.isArray(domainConfig) ? domainConfig : [domainConfig]) : [];
|
|
19
|
+
const sslEmail = envConfig.sslEmail;
|
|
20
|
+
const shouldSetupSsl = !options.skipSsl && domains.length > 0 && !!sslEmail;
|
|
21
|
+
Logger.kv('Environment', environment);
|
|
22
|
+
Logger.kv('Server', host);
|
|
23
|
+
Logger.kv('Domain(s)', domains.length > 0 ? domains.join(', ') : 'None (using IP)');
|
|
24
|
+
Logger.kv('SSL', shouldSetupSsl ? `Yes (${sslEmail})` : 'No');
|
|
25
|
+
Logger.br();
|
|
26
|
+
let ssh = null;
|
|
27
|
+
try {
|
|
28
|
+
// Connect to server
|
|
29
|
+
const connectSpinner = ora('Connecting to server...').start();
|
|
30
|
+
ssh = await createSSHConnection(host);
|
|
31
|
+
connectSpinner.succeed('Connected to server');
|
|
32
|
+
Logger.br();
|
|
33
|
+
// Check if nginx is installed
|
|
34
|
+
Logger.section('Checking Prerequisites');
|
|
35
|
+
Logger.br();
|
|
36
|
+
const nginxCheck = await ssh.exec('command -v nginx || echo "missing"');
|
|
37
|
+
if (nginxCheck.stdout.includes('missing')) {
|
|
38
|
+
throw new Error('Nginx is not installed on the server.\n' +
|
|
39
|
+
'Run: hostfn server setup <host> --env ' + environment);
|
|
40
|
+
}
|
|
41
|
+
const nginxSpinner = ora('Checking nginx installation...').start();
|
|
42
|
+
nginxSpinner.succeed('Nginx is installed');
|
|
43
|
+
if (shouldSetupSsl) {
|
|
44
|
+
const certbotCheck = await ssh.exec('command -v certbot || echo "missing"');
|
|
45
|
+
if (certbotCheck.stdout.includes('missing')) {
|
|
46
|
+
throw new Error('Certbot is not installed on the server.\n' +
|
|
47
|
+
'Run: hostfn server setup <host> --env ' + environment);
|
|
48
|
+
}
|
|
49
|
+
const certbotSpinner = ora('Checking certbot installation...').start();
|
|
50
|
+
certbotSpinner.succeed('Certbot is installed');
|
|
51
|
+
}
|
|
52
|
+
Logger.br();
|
|
53
|
+
// Determine nginx config system (sites-available vs conf.d)
|
|
54
|
+
const sitesAvailableCheck = await ssh.exec('test -d /etc/nginx/sites-available && echo "exists"');
|
|
55
|
+
const useSitesAvailable = sitesAvailableCheck.stdout.trim() === 'exists';
|
|
56
|
+
// Disable default site if using sites-available and domain is configured
|
|
57
|
+
// This prevents conflicts when certbot modifies the default site
|
|
58
|
+
if (useSitesAvailable && domains.length > 0) {
|
|
59
|
+
const defaultSiteCheck = await ssh.exec('test -L /etc/nginx/sites-enabled/default && echo "exists"');
|
|
60
|
+
if (defaultSiteCheck.stdout.trim() === 'exists') {
|
|
61
|
+
const disableSpinner = ora('Disabling default nginx site...').start();
|
|
62
|
+
await ssh.exec('sudo unlink /etc/nginx/sites-enabled/default');
|
|
63
|
+
disableSpinner.succeed('Default site disabled');
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Check if SSL certificates already exist for all domains
|
|
67
|
+
let certsExist = false;
|
|
68
|
+
if (shouldSetupSsl && domains.length > 0) {
|
|
69
|
+
// Check if certificate exists for the primary domain (first in the list)
|
|
70
|
+
const primaryDomain = domains[0];
|
|
71
|
+
const safePrimaryDomain = `'${primaryDomain.replace(/'/g, "'\\''")}'`;
|
|
72
|
+
const certCheck = await ssh.exec(`sudo test -d /etc/letsencrypt/live/${safePrimaryDomain} && echo "exists"`);
|
|
73
|
+
certsExist = certCheck.stdout.trim() === 'exists';
|
|
74
|
+
}
|
|
75
|
+
// Prepare services configuration
|
|
76
|
+
const services = [];
|
|
77
|
+
if (config.services && Object.keys(config.services).length > 0) {
|
|
78
|
+
// Multiple services (monorepo)
|
|
79
|
+
Logger.section('Configuring Multiple Services');
|
|
80
|
+
Logger.br();
|
|
81
|
+
for (const [serviceName, serviceConfig] of Object.entries(config.services)) {
|
|
82
|
+
const serviceEnvConfig = {
|
|
83
|
+
...envConfig,
|
|
84
|
+
server: serviceConfig.server || envConfig.server,
|
|
85
|
+
};
|
|
86
|
+
// Only include services on this server
|
|
87
|
+
if (serviceEnvConfig.server === host) {
|
|
88
|
+
const port = serviceConfig.port;
|
|
89
|
+
// Validate port
|
|
90
|
+
if (!port || isNaN(Number(port)) || Number(port) < 1 || Number(port) > 65535) {
|
|
91
|
+
throw new Error(`Invalid port for service '${serviceName}': ${port}. Must be between 1 and 65535.`);
|
|
92
|
+
}
|
|
93
|
+
const isDefault = !serviceConfig.exposePath;
|
|
94
|
+
services.push({
|
|
95
|
+
name: `${config.name}-${serviceName}`,
|
|
96
|
+
port: Number(port),
|
|
97
|
+
exposePath: serviceConfig.exposePath,
|
|
98
|
+
isDefault,
|
|
99
|
+
});
|
|
100
|
+
Logger.kv(serviceName, serviceConfig.exposePath
|
|
101
|
+
? `Port ${serviceConfig.port} → ${serviceConfig.exposePath}`
|
|
102
|
+
: `Port ${serviceConfig.port} → / (default)`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
Logger.br();
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Single service
|
|
109
|
+
Logger.section('Configuring Single Service');
|
|
110
|
+
Logger.br();
|
|
111
|
+
const port = envConfig.port;
|
|
112
|
+
// Validate port
|
|
113
|
+
if (!port || isNaN(Number(port)) || Number(port) < 1 || Number(port) > 65535) {
|
|
114
|
+
throw new Error(`Invalid port for environment '${environment}': ${port}. Must be between 1 and 65535.`);
|
|
115
|
+
}
|
|
116
|
+
services.push({
|
|
117
|
+
name: `${config.name}-${environment}`,
|
|
118
|
+
port: Number(port),
|
|
119
|
+
isDefault: true,
|
|
120
|
+
});
|
|
121
|
+
Logger.kv('Service', `${config.name}-${environment}`);
|
|
122
|
+
Logger.kv('Port', envConfig.port.toString());
|
|
123
|
+
Logger.br();
|
|
124
|
+
}
|
|
125
|
+
if (services.length === 0) {
|
|
126
|
+
Logger.warn('No services found to expose on this server');
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Generate nginx configuration
|
|
130
|
+
Logger.section('Generating Nginx Configuration');
|
|
131
|
+
Logger.br();
|
|
132
|
+
// Only enable SSL in nginx config if certificates already exist
|
|
133
|
+
// Certbot will update the config to add SSL when obtaining new certificates
|
|
134
|
+
const enableSslInConfig = shouldSetupSsl && certsExist;
|
|
135
|
+
if (shouldSetupSsl && !certsExist) {
|
|
136
|
+
Logger.info('SSL certificates not found - will configure after obtaining certificates');
|
|
137
|
+
Logger.br();
|
|
138
|
+
}
|
|
139
|
+
const nginxConfig = NginxConfigGenerator.generate({
|
|
140
|
+
domain: domains.length > 0 ? domains : undefined,
|
|
141
|
+
ssl: enableSslInConfig,
|
|
142
|
+
services,
|
|
143
|
+
environment,
|
|
144
|
+
});
|
|
145
|
+
const configPath = NginxConfigGenerator.getConfigPath(environment, useSitesAvailable);
|
|
146
|
+
Logger.info('Configuration preview:');
|
|
147
|
+
Logger.br();
|
|
148
|
+
Logger.log(nginxConfig);
|
|
149
|
+
Logger.br();
|
|
150
|
+
// Check if config already exists
|
|
151
|
+
const existsCheck = await ssh.exec(`test -f ${configPath} && echo "exists"`);
|
|
152
|
+
const configExists = existsCheck.stdout.trim() === 'exists';
|
|
153
|
+
let shouldWrite = !configExists || options.force;
|
|
154
|
+
// If config exists, check if domain has changed
|
|
155
|
+
if (configExists && !options.force && domains.length > 0) {
|
|
156
|
+
const currentConfigResult = await ssh.exec(`cat ${configPath}`);
|
|
157
|
+
const currentConfig = currentConfigResult.stdout;
|
|
158
|
+
// Check if the current config has a different server_name or uses catch-all
|
|
159
|
+
const serverNameMatch = currentConfig.match(/server_name\s+([^;]+);/);
|
|
160
|
+
if (serverNameMatch) {
|
|
161
|
+
const currentServerName = serverNameMatch[1].trim();
|
|
162
|
+
const newServerName = domains.join(' ');
|
|
163
|
+
// If current is catch-all (_) or different domain(s), force update
|
|
164
|
+
if (currentServerName === '_' || currentServerName !== newServerName) {
|
|
165
|
+
Logger.info(`Updating server_name from "${currentServerName}" to "${newServerName}"`);
|
|
166
|
+
Logger.br();
|
|
167
|
+
shouldWrite = true;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (configExists && !shouldWrite) {
|
|
172
|
+
Logger.warn(`Configuration already exists at ${configPath}`);
|
|
173
|
+
Logger.info('Use --force to overwrite');
|
|
174
|
+
Logger.br();
|
|
175
|
+
Logger.info('Skipping to SSL setup...');
|
|
176
|
+
Logger.br();
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
const writeSpinner = ora('Writing nginx configuration...').start();
|
|
180
|
+
// Write nginx config
|
|
181
|
+
await ssh.exec(`sudo tee ${configPath} > /dev/null << 'EOF'
|
|
182
|
+
${nginxConfig}
|
|
183
|
+
EOF`);
|
|
184
|
+
// Enable site if using sites-available
|
|
185
|
+
const enableCmd = NginxConfigGenerator.getEnableCommand(environment, useSitesAvailable);
|
|
186
|
+
if (enableCmd) {
|
|
187
|
+
await ssh.exec(`sudo ${enableCmd}`);
|
|
188
|
+
}
|
|
189
|
+
writeSpinner.succeed(`Configuration written to ${configPath}`);
|
|
190
|
+
}
|
|
191
|
+
// Test nginx configuration
|
|
192
|
+
const testSpinner = ora('Testing nginx configuration...').start();
|
|
193
|
+
const testResult = await ssh.exec('sudo nginx -t');
|
|
194
|
+
if (testResult.exitCode !== 0) {
|
|
195
|
+
testSpinner.fail('Nginx configuration test failed');
|
|
196
|
+
Logger.error(testResult.stderr);
|
|
197
|
+
throw new Error('Invalid nginx configuration');
|
|
198
|
+
}
|
|
199
|
+
testSpinner.succeed('Nginx configuration is valid');
|
|
200
|
+
// Reload nginx
|
|
201
|
+
const reloadSpinner = ora('Reloading nginx...').start();
|
|
202
|
+
await ssh.exec('sudo systemctl reload nginx');
|
|
203
|
+
reloadSpinner.succeed('Nginx reloaded');
|
|
204
|
+
Logger.br();
|
|
205
|
+
// Setup SSL if domains are configured
|
|
206
|
+
if (shouldSetupSsl && domains.length > 0 && sslEmail) {
|
|
207
|
+
await setupSSL(ssh, host, domains, sslEmail, environment);
|
|
208
|
+
}
|
|
209
|
+
// Success summary
|
|
210
|
+
Logger.br();
|
|
211
|
+
Logger.success('Services exposed successfully!');
|
|
212
|
+
Logger.br();
|
|
213
|
+
if (shouldSetupSsl && domains.length > 0) {
|
|
214
|
+
for (const domain of domains) {
|
|
215
|
+
Logger.kv('URL', `https://${domain}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else if (domains.length > 0) {
|
|
219
|
+
for (const domain of domains) {
|
|
220
|
+
Logger.kv('URL', `http://${domain}`);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
const hostname = host.includes('@') ? host.split('@')[1] : host;
|
|
225
|
+
Logger.kv('URL', `http://${hostname}`);
|
|
226
|
+
}
|
|
227
|
+
Logger.br();
|
|
228
|
+
Logger.info('Service endpoints:');
|
|
229
|
+
for (const service of services) {
|
|
230
|
+
const path = service.exposePath || '/';
|
|
231
|
+
Logger.log(` ${service.name}: ${path}`);
|
|
232
|
+
}
|
|
233
|
+
Logger.br();
|
|
234
|
+
}
|
|
235
|
+
catch (error) {
|
|
236
|
+
Logger.br();
|
|
237
|
+
Logger.error('Failed to expose services');
|
|
238
|
+
Logger.error(error instanceof Error ? error.message : String(error));
|
|
239
|
+
process.exit(1);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
if (ssh) {
|
|
243
|
+
ssh.disconnect();
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Setup SSL certificate using certbot
|
|
249
|
+
*/
|
|
250
|
+
async function setupSSL(ssh, host, domains, email, environment) {
|
|
251
|
+
Logger.section('Setting up SSL Certificates');
|
|
252
|
+
Logger.br();
|
|
253
|
+
// Use the primary domain (first in the list) for certificate name
|
|
254
|
+
const primaryDomain = domains[0];
|
|
255
|
+
Logger.info(`Primary domain: ${primaryDomain}`);
|
|
256
|
+
if (domains.length > 1) {
|
|
257
|
+
Logger.info(`Additional domains: ${domains.slice(1).join(', ')}`);
|
|
258
|
+
}
|
|
259
|
+
Logger.br();
|
|
260
|
+
// Check if certificate already exists for primary domain
|
|
261
|
+
const certCheckSpinner = ora('Checking for existing certificate...').start();
|
|
262
|
+
const certCheck = await ssh.exec(`sudo test -d /etc/letsencrypt/live/${primaryDomain} && echo "exists"`);
|
|
263
|
+
const certExists = certCheck.stdout.trim() === 'exists';
|
|
264
|
+
if (certExists) {
|
|
265
|
+
certCheckSpinner.succeed('Certificate already exists');
|
|
266
|
+
// Check if certificate contains all required domains
|
|
267
|
+
const checkDomainsSpinner = ora('Checking certificate domains...').start();
|
|
268
|
+
const certInfoResult = await ssh.exec(`sudo certbot certificates --cert-name ${primaryDomain} 2>/dev/null | grep "Domains:" || echo ""`);
|
|
269
|
+
const certDomainsLine = certInfoResult.stdout.trim();
|
|
270
|
+
let needsExpansion = false;
|
|
271
|
+
if (certDomainsLine) {
|
|
272
|
+
// Extract domains from "Domains: domain1 domain2 domain3"
|
|
273
|
+
const existingDomains = certDomainsLine
|
|
274
|
+
.replace(/^.*Domains:\s*/, '')
|
|
275
|
+
.split(/\s+/)
|
|
276
|
+
.filter(d => d.length > 0);
|
|
277
|
+
// Check if all required domains are in the certificate
|
|
278
|
+
needsExpansion = domains.some(domain => !existingDomains.includes(domain));
|
|
279
|
+
if (needsExpansion) {
|
|
280
|
+
checkDomainsSpinner.info(`Certificate missing domains: ${domains.filter(d => !existingDomains.includes(d)).join(', ')}`);
|
|
281
|
+
}
|
|
282
|
+
else {
|
|
283
|
+
checkDomainsSpinner.succeed('Certificate contains all required domains');
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
checkDomainsSpinner.warn('Could not verify certificate domains, will attempt expansion');
|
|
288
|
+
needsExpansion = true;
|
|
289
|
+
}
|
|
290
|
+
if (needsExpansion) {
|
|
291
|
+
// Expand certificate to include all domains
|
|
292
|
+
const expandSpinner = ora(`Expanding certificate to include ${domains.length} domain(s)...`).start();
|
|
293
|
+
expandSpinner.text = 'This may take a minute...';
|
|
294
|
+
const domainFlags = domains.map(d => `-d ${d}`).join(' ');
|
|
295
|
+
const expandCmd = [
|
|
296
|
+
'sudo certbot --nginx',
|
|
297
|
+
domainFlags,
|
|
298
|
+
`--email ${email}`,
|
|
299
|
+
'--non-interactive',
|
|
300
|
+
'--agree-tos',
|
|
301
|
+
'--redirect',
|
|
302
|
+
'--expand',
|
|
303
|
+
].join(' ');
|
|
304
|
+
const expandResult = await ssh.exec(expandCmd, { streaming: false });
|
|
305
|
+
if (expandResult.exitCode === 0) {
|
|
306
|
+
expandSpinner.succeed(`Certificate expanded successfully for all ${domains.length} domain(s)`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
expandSpinner.fail('Failed to expand SSL certificate');
|
|
310
|
+
Logger.br();
|
|
311
|
+
Logger.error('Certbot error:');
|
|
312
|
+
Logger.log(expandResult.stderr || expandResult.stdout);
|
|
313
|
+
Logger.br();
|
|
314
|
+
Logger.warn('SSL expansion failed');
|
|
315
|
+
Logger.info('You can manually run certbot with --expand:');
|
|
316
|
+
const manualDomainFlags = domains.map(d => `-d ${d}`).join(' ');
|
|
317
|
+
Logger.command(`ssh ${host} "sudo certbot --nginx ${manualDomainFlags} --expand"`);
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
// Just renew the existing certificate
|
|
323
|
+
const renewSpinner = ora('Renewing certificate...').start();
|
|
324
|
+
const renewResult = await ssh.exec(`sudo certbot renew --cert-name ${primaryDomain} --nginx --non-interactive`);
|
|
325
|
+
if (renewResult.exitCode === 0) {
|
|
326
|
+
renewSpinner.succeed('Certificate renewed (or still valid)');
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
renewSpinner.warn('Certificate renewal skipped (likely still valid)');
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
certCheckSpinner.succeed('No existing certificate found');
|
|
335
|
+
// Obtain new certificate for all domains
|
|
336
|
+
const obtainSpinner = ora(`Obtaining SSL certificate for ${domains.length} domain(s)...`).start();
|
|
337
|
+
obtainSpinner.text = 'This may take a minute...';
|
|
338
|
+
// Build certbot command with all domains
|
|
339
|
+
const domainFlags = domains.map(d => `-d ${d}`).join(' ');
|
|
340
|
+
const certbotCmd = [
|
|
341
|
+
'sudo certbot --nginx',
|
|
342
|
+
domainFlags,
|
|
343
|
+
`--email ${email}`,
|
|
344
|
+
'--non-interactive',
|
|
345
|
+
'--agree-tos',
|
|
346
|
+
'--redirect',
|
|
347
|
+
].join(' ');
|
|
348
|
+
const certbotResult = await ssh.exec(certbotCmd, { streaming: false });
|
|
349
|
+
if (certbotResult.exitCode === 0) {
|
|
350
|
+
obtainSpinner.succeed(`SSL certificate obtained successfully for all ${domains.length} domain(s)`);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
obtainSpinner.fail('Failed to obtain SSL certificate');
|
|
354
|
+
Logger.br();
|
|
355
|
+
Logger.error('Certbot error:');
|
|
356
|
+
Logger.log(certbotResult.stderr || certbotResult.stdout);
|
|
357
|
+
Logger.br();
|
|
358
|
+
Logger.warn('SSL setup failed, but nginx is still configured for HTTP');
|
|
359
|
+
Logger.info('You can manually run certbot later:');
|
|
360
|
+
const manualDomainFlags = domains.map(d => `-d ${d}`).join(' ');
|
|
361
|
+
Logger.command(`ssh ${host} "sudo certbot --nginx ${manualDomainFlags}"`);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
// Verify SSL is working
|
|
366
|
+
const verifySpinner = ora('Verifying SSL configuration...').start();
|
|
367
|
+
const sslCheck = await ssh.exec(`sudo nginx -t`);
|
|
368
|
+
if (sslCheck.exitCode === 0) {
|
|
369
|
+
verifySpinner.succeed('SSL configuration verified');
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
verifySpinner.warn('SSL verification had warnings (may still work)');
|
|
373
|
+
}
|
|
374
|
+
Logger.br();
|
|
375
|
+
Logger.success('SSL certificate configured!');
|
|
376
|
+
Logger.info('Auto-renewal is enabled via certbot');
|
|
377
|
+
Logger.br();
|
|
378
|
+
}
|
|
379
|
+
//# sourceMappingURL=expose.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expose.js","sourceRoot":"","sources":["../../src/commands/expose.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAQA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAuLjD"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { writeFileSync } from 'fs';
|
|
2
|
+
import inquirer from 'inquirer';
|
|
3
|
+
import ora from 'ora';
|
|
4
|
+
import { Logger } from '../utils/logger.js';
|
|
5
|
+
import { ConfigLoader } from '../config/loader.js';
|
|
6
|
+
import { RuntimeRegistry } from '../runtimes/registry.js';
|
|
7
|
+
export async function initCommand() {
|
|
8
|
+
Logger.header('Initialize hostfn');
|
|
9
|
+
// Check if config already exists
|
|
10
|
+
if (ConfigLoader.exists()) {
|
|
11
|
+
const { overwrite } = await inquirer.prompt([
|
|
12
|
+
{
|
|
13
|
+
type: 'confirm',
|
|
14
|
+
name: 'overwrite',
|
|
15
|
+
message: 'Configuration file already exists. Overwrite?',
|
|
16
|
+
default: false,
|
|
17
|
+
},
|
|
18
|
+
]);
|
|
19
|
+
if (!overwrite) {
|
|
20
|
+
Logger.info('Initialization cancelled');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
// Detect runtime
|
|
25
|
+
const spinner = ora('Detecting project runtime...').start();
|
|
26
|
+
const detection = await RuntimeRegistry.detect(process.cwd());
|
|
27
|
+
if (!detection) {
|
|
28
|
+
spinner.fail('Could not detect project runtime');
|
|
29
|
+
Logger.error('No supported runtime detected in this directory');
|
|
30
|
+
Logger.info('Supported runtimes: nodejs, python, go, ruby, rust');
|
|
31
|
+
Logger.info('Make sure your project has the appropriate configuration files:');
|
|
32
|
+
Logger.info(' - Node.js: package.json');
|
|
33
|
+
Logger.info(' - Python: requirements.txt or pyproject.toml');
|
|
34
|
+
Logger.info(' - Go: go.mod');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
spinner.succeed(`Detected ${detection.runtime} (confidence: ${detection.confidence}%)`);
|
|
38
|
+
if (detection.confidence < 80) {
|
|
39
|
+
Logger.warn('Low confidence detection. Please verify the generated config.');
|
|
40
|
+
}
|
|
41
|
+
// Get default config from adapter
|
|
42
|
+
const adapter = detection.adapter;
|
|
43
|
+
const defaults = await adapter.getDefaultConfig(process.cwd());
|
|
44
|
+
// Prompt for configuration
|
|
45
|
+
Logger.br();
|
|
46
|
+
Logger.section('Project Configuration');
|
|
47
|
+
const answers = await inquirer.prompt([
|
|
48
|
+
{
|
|
49
|
+
type: 'input',
|
|
50
|
+
name: 'name',
|
|
51
|
+
message: 'Application name:',
|
|
52
|
+
default: defaults.name,
|
|
53
|
+
validate: (input) => input.length > 0 || 'Name is required',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: 'input',
|
|
57
|
+
name: 'version',
|
|
58
|
+
message: `${detection.runtime} version:`,
|
|
59
|
+
default: defaults.version || '18',
|
|
60
|
+
},
|
|
61
|
+
]);
|
|
62
|
+
Logger.br();
|
|
63
|
+
Logger.section('Environment Configuration');
|
|
64
|
+
const envAnswers = await inquirer.prompt([
|
|
65
|
+
{
|
|
66
|
+
type: 'input',
|
|
67
|
+
name: 'server',
|
|
68
|
+
message: 'Production server (user@host):',
|
|
69
|
+
validate: (input) => {
|
|
70
|
+
if (!input)
|
|
71
|
+
return 'Server is required';
|
|
72
|
+
if (!input.includes('@'))
|
|
73
|
+
return 'Format: user@host';
|
|
74
|
+
return true;
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
type: 'number',
|
|
79
|
+
name: 'port',
|
|
80
|
+
message: 'Production port:',
|
|
81
|
+
default: 3000,
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
type: 'input',
|
|
85
|
+
name: 'domain',
|
|
86
|
+
message: 'Domain (optional):',
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
Logger.br();
|
|
90
|
+
Logger.section('Build & Start Configuration');
|
|
91
|
+
const buildAnswers = await inquirer.prompt([
|
|
92
|
+
{
|
|
93
|
+
type: 'input',
|
|
94
|
+
name: 'buildCommand',
|
|
95
|
+
message: 'Build command:',
|
|
96
|
+
default: defaults.build?.command || 'npm run build',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
type: 'input',
|
|
100
|
+
name: 'startCommand',
|
|
101
|
+
message: 'Start command:',
|
|
102
|
+
default: defaults.start?.command || 'npm start',
|
|
103
|
+
},
|
|
104
|
+
]);
|
|
105
|
+
// Generate configuration
|
|
106
|
+
const config = {
|
|
107
|
+
name: answers.name,
|
|
108
|
+
runtime: detection.runtime,
|
|
109
|
+
version: answers.version,
|
|
110
|
+
environments: {
|
|
111
|
+
production: {
|
|
112
|
+
server: envAnswers.server,
|
|
113
|
+
port: envAnswers.port,
|
|
114
|
+
instances: 'max',
|
|
115
|
+
...(envAnswers.domain && { domain: envAnswers.domain }),
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
build: {
|
|
119
|
+
command: buildAnswers.buildCommand,
|
|
120
|
+
directory: 'dist',
|
|
121
|
+
nodeModules: 'production',
|
|
122
|
+
},
|
|
123
|
+
start: {
|
|
124
|
+
command: buildAnswers.startCommand,
|
|
125
|
+
entry: defaults.start?.entry,
|
|
126
|
+
},
|
|
127
|
+
env: {
|
|
128
|
+
required: [],
|
|
129
|
+
optional: [],
|
|
130
|
+
},
|
|
131
|
+
health: {
|
|
132
|
+
path: '/health',
|
|
133
|
+
timeout: 60,
|
|
134
|
+
retries: 10,
|
|
135
|
+
interval: 3,
|
|
136
|
+
},
|
|
137
|
+
sync: {
|
|
138
|
+
exclude: [
|
|
139
|
+
'node_modules',
|
|
140
|
+
'.git',
|
|
141
|
+
'.github',
|
|
142
|
+
'dist',
|
|
143
|
+
'build',
|
|
144
|
+
'.env',
|
|
145
|
+
'.env.*',
|
|
146
|
+
'*.log',
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
backup: {
|
|
150
|
+
keep: 5,
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
// Write configuration file
|
|
154
|
+
const configPath = ConfigLoader.getConfigPath();
|
|
155
|
+
const spinner2 = ora('Writing configuration...').start();
|
|
156
|
+
try {
|
|
157
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
158
|
+
spinner2.succeed('Configuration created');
|
|
159
|
+
Logger.br();
|
|
160
|
+
Logger.success('hostfn initialized successfully!');
|
|
161
|
+
Logger.br();
|
|
162
|
+
Logger.kv('Config file', configPath);
|
|
163
|
+
Logger.kv('Runtime', detection.runtime);
|
|
164
|
+
Logger.kv('Environment', 'production');
|
|
165
|
+
Logger.br();
|
|
166
|
+
Logger.info('Next steps:');
|
|
167
|
+
Logger.command('hostfn server setup ' + envAnswers.server);
|
|
168
|
+
Logger.command('hostfn deploy production');
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
spinner2.fail('Failed to write configuration');
|
|
172
|
+
throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface LogsOptions {
|
|
2
|
+
lines: string;
|
|
3
|
+
errors: boolean;
|
|
4
|
+
follow?: boolean;
|
|
5
|
+
output?: string;
|
|
6
|
+
service?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function logsCommand(environment: string, options: LogsOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=logs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AASA,UAAU,WAAW;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,IAAI,CAAC,CAoCf"}
|