ante-erp-cli 1.11.37 ā 1.11.39
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/bin/ante-cli.js +5 -0
- package/package.json +1 -1
- package/src/commands/set-domain.js +67 -0
- package/src/utils/nginx.js +13 -1
- package/src/utils/ssl.js +11 -1
package/bin/ante-cli.js
CHANGED
|
@@ -324,6 +324,11 @@ program
|
|
|
324
324
|
.description('Configure frontend and API domains')
|
|
325
325
|
.option('--frontend <url>', 'Frontend domain/URL')
|
|
326
326
|
.option('--api <url>', 'API domain/URL')
|
|
327
|
+
.option('--gate <url>', 'Gate App domain/URL (non-interactive mode)')
|
|
328
|
+
.option('--guardian <url>', 'Guardian App domain/URL (non-interactive mode)')
|
|
329
|
+
.option('--facial <url>', 'Facial Web domain/URL (non-interactive mode)')
|
|
330
|
+
.option('--pos <url>', 'POS App domain/URL (non-interactive mode)')
|
|
331
|
+
.option('--client <url>', 'Client App domain/URL (non-interactive mode)')
|
|
327
332
|
.option('--detect', 'Auto-detect public IP address')
|
|
328
333
|
.option('--ssl, --enable-ssl', 'Enable SSL certificate (Let\'s Encrypt)')
|
|
329
334
|
.option('--email <email>', 'Email for SSL certificate notifications')
|
package/package.json
CHANGED
|
@@ -611,6 +611,73 @@ export async function setDomain(options) {
|
|
|
611
611
|
console.log(chalk.red(`Error: Invalid API URL - ${apiValidation}`));
|
|
612
612
|
process.exit(1);
|
|
613
613
|
}
|
|
614
|
+
|
|
615
|
+
// Handle app URLs: use CLI options if provided, otherwise read from existing .env
|
|
616
|
+
if (hasGateApp) {
|
|
617
|
+
gateAppUrl = options.gate ? sanitizeUrl(options.gate) : getEnvValue(envPath, 'GATE_APP_URL');
|
|
618
|
+
if (gateAppUrl) {
|
|
619
|
+
const validation = validateUrl(gateAppUrl);
|
|
620
|
+
if (validation !== true) {
|
|
621
|
+
console.log(chalk.red(`Error: Invalid Gate App URL - ${validation}`));
|
|
622
|
+
process.exit(1);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
if (hasGuardianApp) {
|
|
628
|
+
guardianAppUrl = options.guardian ? sanitizeUrl(options.guardian) : getEnvValue(envPath, 'GUARDIAN_APP_URL');
|
|
629
|
+
if (guardianAppUrl) {
|
|
630
|
+
const validation = validateUrl(guardianAppUrl);
|
|
631
|
+
if (validation !== true) {
|
|
632
|
+
console.log(chalk.red(`Error: Invalid Guardian App URL - ${validation}`));
|
|
633
|
+
process.exit(1);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
if (hasFacialWeb) {
|
|
639
|
+
facialWebUrl = options.facial ? sanitizeUrl(options.facial) : getEnvValue(envPath, 'FACIAL_WEB_URL');
|
|
640
|
+
if (facialWebUrl) {
|
|
641
|
+
const validation = validateUrl(facialWebUrl);
|
|
642
|
+
if (validation !== true) {
|
|
643
|
+
console.log(chalk.red(`Error: Invalid Facial Web URL - ${validation}`));
|
|
644
|
+
process.exit(1);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (hasPosApp) {
|
|
650
|
+
posAppUrl = options.pos ? sanitizeUrl(options.pos) : getEnvValue(envPath, 'POS_APP_URL');
|
|
651
|
+
if (posAppUrl) {
|
|
652
|
+
const validation = validateUrl(posAppUrl);
|
|
653
|
+
if (validation !== true) {
|
|
654
|
+
console.log(chalk.red(`Error: Invalid POS App URL - ${validation}`));
|
|
655
|
+
process.exit(1);
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
if (hasClientApp) {
|
|
661
|
+
clientAppUrl = options.client ? sanitizeUrl(options.client) : getEnvValue(envPath, 'CLIENT_APP_URL');
|
|
662
|
+
if (clientAppUrl) {
|
|
663
|
+
const validation = validateUrl(clientAppUrl);
|
|
664
|
+
if (validation !== true) {
|
|
665
|
+
console.log(chalk.red(`Error: Invalid Client App URL - ${validation}`));
|
|
666
|
+
process.exit(1);
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Show what will be configured in non-interactive mode
|
|
672
|
+
console.log(chalk.cyan('\nš Non-interactive mode configuration:\n'));
|
|
673
|
+
console.log(chalk.gray(` Frontend: ${frontendUrl}`));
|
|
674
|
+
console.log(chalk.gray(` API: ${apiUrl}`));
|
|
675
|
+
if (hasGateApp && gateAppUrl) console.log(chalk.gray(` Gate App: ${gateAppUrl}`));
|
|
676
|
+
if (hasGuardianApp && guardianAppUrl) console.log(chalk.gray(` Guardian App: ${guardianAppUrl}`));
|
|
677
|
+
if (hasFacialWeb && facialWebUrl) console.log(chalk.gray(` Facial Web: ${facialWebUrl}`));
|
|
678
|
+
if (hasPosApp && posAppUrl) console.log(chalk.gray(` POS App: ${posAppUrl}`));
|
|
679
|
+
if (hasClientApp && clientAppUrl) console.log(chalk.gray(` Client App: ${clientAppUrl}`));
|
|
680
|
+
console.log('');
|
|
614
681
|
}
|
|
615
682
|
|
|
616
683
|
// Update .env file
|
package/src/utils/nginx.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { execa } from 'execa';
|
|
4
|
-
import { writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
4
|
+
import { writeFileSync, existsSync, mkdirSync, unlinkSync } from 'fs';
|
|
5
5
|
import { join } from 'path';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -818,6 +818,18 @@ export async function configureNginx(config) {
|
|
|
818
818
|
|
|
819
819
|
// Write configuration to sites-enabled (direct, not using sites-available)
|
|
820
820
|
const configPath = join(sitesEnabledDir, 'ante');
|
|
821
|
+
const backupPath = `${configPath}.backup`;
|
|
822
|
+
|
|
823
|
+
// Clean up any existing backup file to prevent "conflicting server name" warnings
|
|
824
|
+
// Nginx reads ALL files in sites-enabled, including .backup files
|
|
825
|
+
if (existsSync(backupPath)) {
|
|
826
|
+
try {
|
|
827
|
+
unlinkSync(backupPath);
|
|
828
|
+
} catch {
|
|
829
|
+
// Ignore cleanup errors
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
821
833
|
writeFileSync(configPath, nginxConfig);
|
|
822
834
|
|
|
823
835
|
spinner.text = 'Testing NGINX configuration...';
|
package/src/utils/ssl.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import ora from 'ora';
|
|
3
3
|
import { execa } from 'execa';
|
|
4
|
-
import { writeFileSync, existsSync, copyFileSync } from 'fs';
|
|
4
|
+
import { writeFileSync, existsSync, copyFileSync, unlinkSync } from 'fs';
|
|
5
5
|
import { generateNginxConfig } from './nginx.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -223,6 +223,16 @@ export async function updateNginxForSSL(config) {
|
|
|
223
223
|
throw new Error('NGINX failed to start after configuration update');
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
// Clean up backup file after successful reload
|
|
227
|
+
// This prevents nginx "conflicting server name" warnings since nginx reads all files in sites-enabled
|
|
228
|
+
if (existsSync(backupPath)) {
|
|
229
|
+
try {
|
|
230
|
+
unlinkSync(backupPath);
|
|
231
|
+
} catch {
|
|
232
|
+
// Ignore cleanup errors
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
226
236
|
spinner.succeed('NGINX configured for HTTPS');
|
|
227
237
|
|
|
228
238
|
// Show configuration info
|