Rework browser launch functionality (#4143) * Add browser selection to auto-launch * Update readmes * Update readme * Display browser name in a console

87f618d15cb03b2cf755e98d498295ceacc8283f

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
12 files changed, +307 -166Showing whitespace changes
.github/readme-de_de.md+9 -9
@@ -321,24 +321,24 @@ Start.bat --port 8000 --listen false
321### Unterstützte Argumente321### Unterstützte Argumente
322322
323| Option | Beschreibung | Typ |323| Option | Beschreibung | Typ |
324|-------------------------|----------------------------------------------------------------------------------------------------|----------|324|----------------------------------|--------------------------------------------------------------------------------------------------|----------|
325| `--version` | Versionsnummer anzeigen | boolean |325| `--version` | Versionsnummer anzeigen | boolean |
326| `--enableIPv6` | Aktiviert IPv6. | boolean |326| `--enableIPv6` | Aktiviert IPv6. | boolean |
327| `--enableIPv4` | Aktiviert IPv4. | boolean |327| `--enableIPv4` | Aktiviert IPv4. | boolean |
328| `--port` | Legt den Port fest, unter dem SillyTavern ausgeführt wird. Wenn nicht angegeben, wird auf YAML-Konfiguration „Port“ zurückgegriffen. | number |328| `--port` | Legt den Port fest, unter dem SillyTavern ausgeführt wird. | number |
329| „--dnsPreferIPv6“ | Bevorzugt IPv6 für DNS. Wenn nicht angegeben, wird auf YAML-Konfiguration „preferIPv6“ zurückgegriffen. | boolean |329| `--dnsPreferIPv6` | Bevorzugt IPv6 für DNS. Wenn nicht angegeben. | boolean |
330| „--autorun“ | Startet SillyTavern automatisch im Browser. Wenn nicht angegeben, wird auf YAML-Konfiguration „autorun“ zurückgegriffen.| boolean |330| `--browserLaunchEnabled` | Startet SillyTavern automatisch im Browser. | boolean |
331| „--autorunHostname“ | Der Autorun-Hostname, am besten auf „auto“ belassen. | string |331| `--browserLaunchHostname` | Der Autorun-Hostname, am besten auf „auto" belassen. | string |
332| „--autorunPortOverride“ | Überschreibt den Port für Autorun. | string |332| `--browserLaunchPort` | Überschreibt den Port für Autorun. | string |
333| „--listen“ | SillyTavern lauscht auf allen Netzwerkschnittstellen. Wenn nicht angegeben, wird auf YAML-Konfiguration „listen“ zurückgegriffen.| boolean |333| `--browserLaunchAvoidLocalhost` | Vermeidet die Verwendung von „localhost" für Autorun im Auto-Modus. | boolean |
334| „--corsProxy“ | Aktiviert CORS-Proxy. Wenn nicht angegeben, wird auf YAML-Konfiguration „enableCorsProxy“ zurückgegriffen. | boolean |334| `--listen` | SillyTavern lauscht auf allen Netzwerkschnittstellen. | boolean |
335| `--corsProxy` | Aktiviert CORS-Proxy. Wenn nicht angegeben. | boolean |
335| `--disableCsrf` | Deaktiviert CSRF-Schutz | boolean |336| `--disableCsrf` | Deaktiviert CSRF-Schutz | boolean |
336| `--ssl` | Aktiviert SSL | boolean |337| `--ssl` | Aktiviert SSL | boolean |
337| `--certPath` | Pfad zu Ihrer Zertifikatsdatei. | string |338| `--certPath` | Pfad zu Ihrer Zertifikatsdatei. | string |
338| `--keyPath` | Pfad zu Ihrer privaten Schlüsseldatei. | string |339| `--keyPath` | Pfad zu Ihrer privaten Schlüsseldatei. | string |
339| `--whitelist` | Aktiviert den Whitelist-Modus | boolean |340| `--whitelist` | Aktiviert den Whitelist-Modus | boolean |
340| `--dataRoot` | Stammverzeichnis für Datenspeicherung | string |341| `--dataRoot` | Stammverzeichnis für Datenspeicherung | string |
341| `--avoidLocalhost` | Vermeidet die Verwendung von „localhost“ für Autorun im Auto-Modus. | boolean |
342| `--basicAuthMode` | Aktiviert die grundlegende Authentifizierung | boolean |342| `--basicAuthMode` | Aktiviert die grundlegende Authentifizierung | boolean |
343| `--requestProxyEnabled` | Aktiviert die Verwendung eines Proxys für ausgehende Anfragen | boolean |343| `--requestProxyEnabled` | Aktiviert die Verwendung eines Proxys für ausgehende Anfragen | boolean |
344| `--requestProxyUrl` | Proxy-URL anfordern (HTTP- oder SOCKS-Protokolle) | string |344| `--requestProxyUrl` | Proxy-URL anfordern (HTTP- oder SOCKS-Protokolle) | string |
.github/readme-ko_kr.md+9 -9
@@ -335,24 +335,24 @@ Start.bat --port 8000 --listen false
335### 지원되는 인수335### 지원되는 인수
336336
337| 옵션 | 설명 | 타입 |337| 옵션 | 설명 | 타입 |
338|-------------------------|------------------------------------------------------------------------------------------------------|----------|338|-----------------------------------|--------------------------------------------------------------------------------------|----------|
339| `--version` | 버전 표시 | boolean |339| `--version` | 버전 표시 | boolean |
340| `--enableIPv6` | IPv6 활성화 | boolean |340| `--enableIPv6` | IPv6 활성화 | boolean |
341| `--enableIPv4` | IPv4 활성화 | boolean |341| `--enableIPv4` | IPv4 활성화 | boolean |
342| `--port` | SillyTavern이 실행될 포트를 설정합니다. 설정되지 않은 경우 yaml config 'port'를 불러옵니다. | number |342| `--port` | SillyTavern이 실행될 포트를 설정합니다. | number |
343| `--dnsPreferIPv6` | DNS에 IPv6를 우선으로 할당합니다. 설정되지 않은 경우 yaml config를 불러옵니다. | boolean |343| `--dnsPreferIPv6` | DNS에 IPv6를 우선으로 할당합니다. | boolean |
344| `--autorun` | 브라우저에서 SillyTavern을 자동으로 실행합니다. 설정되지 않은 경우 yaml config 'autorun'를 불러옵니다. | boolean |344| `--browserLaunchEnabled` | 브라우저에서 SillyTavern을 자동으로 실행합니다. | boolean |
345| `--autorunHostname` | 자동 실행 호스트 이름, 'auto'가 최적의 설정일 것입니다. | string |345| `--browserLaunchHostname` | 자동 실행 호스트 이름, 'auto'가 최적의 설정일 것입니다. | string |
346| `--autorunPortOverride` | 자동 실행 포트 덮어쓰기 | string |346| `--browserLaunchPort` | 자동 실행 포트 덮어쓰기 | string |
347| `--listen` | SillyTavern이 모든 네트워크 인터페이스에서 수신 대기합니다. 설정되지 않은 경우 yaml 구성 'listen'을 불러옵니다. | boolean |347| `--browserLaunchAvoidLocalhost` | 자동 모드에서 자동 실행 시 'localhost' 사용 방지 | boolean |
348| `--corsProxy` | CORS 프록시 활성화. 설정되지 않은 경우 yaml 구성 'enableCorsProxy'을 불러옵니다. | boolean |348| `--listen` | SillyTavern이 모든 네트워크 인터페이스에서 수신 대기합니다. | boolean |
349| `--corsProxy` | CORS 프록시 활성화. | boolean |
349| `--disableCsrf` | CSRF 보호 비활성화 | boolean |350| `--disableCsrf` | CSRF 보호 비활성화 | boolean |
350| `--ssl` | SSL 활성화 | boolean |351| `--ssl` | SSL 활성화 | boolean |
351| `--certPath` | 인증서 파일 경로 | string |352| `--certPath` | 인증서 파일 경로 | string |
352| `--keyPath` | 프라이빗 키 파일 경로 | string |353| `--keyPath` | 프라이빗 키 파일 경로 | string |
353| `--whitelist` | 화이트리스트 모드 활성화 | boolean |354| `--whitelist` | 화이트리스트 모드 활성화 | boolean |
354| `--dataRoot` | 데이터 스토리지의 루트 디렉토리 | string |355| `--dataRoot` | 데이터 스토리지의 루트 디렉토리 | string |
355| `--avoidLocalhost` | 자동 모드에서 자동 실행 시 'localhost' 사용 방지 | boolean |
356| `--basicAuthMode` | 기본 인증 활성화 | boolean |356| `--basicAuthMode` | 기본 인증 활성화 | boolean |
357| `--requestProxyEnabled` | 외부 리퀘스트 프록시 활성화 | boolean |357| `--requestProxyEnabled` | 외부 리퀘스트 프록시 활성화 | boolean |
358| `--requestProxyUrl` | 프록시 URL 리퀘스트 (HTTP 혹은 SOCKS 프로토콜) | string |358| `--requestProxyUrl` | 프록시 URL 리퀘스트 (HTTP 혹은 SOCKS 프로토콜) | string |
.github/readme-ru_ru.md+9 -9
@@ -284,24 +284,24 @@ Start.bat --port 8000 --listen false
284### Поддерживаемые аргументы284### Поддерживаемые аргументы
285285
286| Аргумент | Описание | Тип |286| Аргумент | Описание | Тип |
287|-------------------------|----------------------------------------------------------------------------------------------------------------|----------|287|------------------------------|-----------------------------------------------------------------------------------------------------------|---------|
288| `--version` | Показывает номер версии. | boolean |288| `--version` | Показывает номер версии. | boolean |
289| `--enableIPv6` | Включает IPv6. | boolean |289| `--enableIPv6` | Включает IPv6. | boolean |
290| `--enableIPv4` | Включает IPv4. | boolean |290| `--enableIPv4` | Включает IPv4. | boolean |
291| `--port` | Устанавливает порт, котрый будет использовать SillyTavern. Если не указан, то используется yaml-конфиг 'port'. | number |291| `--port` | Устанавливает порт, который будет использовать SillyTavern. | number |
292| `--dnsPreferIPv6` | Отдает предпочтение IPv6 для dns. Если не указан, то используется yaml-конфиг 'preferIPv6'. | boolean |292| `--dnsPreferIPv6` | Отдает предпочтение IPv6 для dns. | boolean |
293| `--autorun` | Автоматический запуск SillyTavern в браузере. Если не указан, то используется yaml-конфиг 'autorun'. | boolean |293| `--browserLaunchEnabled` | Автоматический запуск SillyTavern в браузере. | boolean |
294| `--autorunHostname` | Имя хоста автозапуска, лучше оставить на 'auto'. | string |294| `--browserLaunchHostname` | Имя хоста автозапуска, лучше оставить на 'auto'. | string |
295| `--autorunPortOverride` | Переопределяет порт для автозапуска. | string |295| `--browserLaunchPort` | Переопределяет порт для автозапуска. | string |
296| `--listen` | SillyTavern будет прослушивать все сетевые интерфейсы. Если не указан, то используется yaml-конфиг 'listen'. | boolean |296| `--browserLaunchAvoidLocalhost`| Избегает использования 'localhost' для автозапуска в режиме 'auto'. | boolean |
297| `--corsProxy` | Включает CORS-прокси. Если не указан, то используется yaml-конфиг 'enableCorsProxy'. | boolean |297| `--listen` | SillyTavern будет прослушивать все сетевые интерфейсы. | boolean |
298| `--corsProxy` | Включает CORS-прокси. | boolean |
298| `--disableCsrf` | Отключает защиту от CSRF. | boolean |299| `--disableCsrf` | Отключает защиту от CSRF. | boolean |
299| `--ssl` | Включает SSL. | boolean |300| `--ssl` | Включает SSL. | boolean |
300| `--certPath` | Путь к файлу c сертификатом. | string |301| `--certPath` | Путь к файлу c сертификатом. | string |
301| `--keyPath` | Путь к файлу с закрытым ключом. | string |302| `--keyPath` | Путь к файлу с закрытым ключом. | string |
302| `--whitelist` | Включает режим белого списка. | boolean |303| `--whitelist` | Включает режим белого списка. | boolean |
303| `--dataRoot` | Корневой каталог для хранения данных. | string |304| `--dataRoot` | Корневой каталог для хранения данных. | string |
304| `--avoidLocalhost` | Избегает использования 'localhost' для автозапуска в режиме 'auto'. | boolean |
305| `--basicAuthMode` | Включает простую аутентификацию. | boolean |305| `--basicAuthMode` | Включает простую аутентификацию. | boolean |
306| `--requestProxyEnabled` | Разрешает использование прокси для исходящих запросов. | boolean |306| `--requestProxyEnabled` | Разрешает использование прокси для исходящих запросов. | boolean |
307| `--requestProxyUrl` | URL-адрес прокси (протоколы HTTP или SOCKS). | string |307| `--requestProxyUrl` | URL-адрес прокси (протоколы HTTP или SOCKS). | string |
.github/readme-zh_cn.md+5 -5
@@ -337,7 +337,7 @@ Start.bat --port 8000 --listen false
337> 所有参数都不是必需的。如果您不提供它们,SillyTavern 将使用 `config.yaml` 中的设置。337> 所有参数都不是必需的。如果您不提供它们,SillyTavern 将使用 `config.yaml` 中的设置。
338338
339| 选项 | 描述 | 类型 |339| 选项 | 描述 | 类型 |
340| ----------------------- | --------------------------------------------- | ------- |340| -------------------------------- | ---------------------------------------------- | ------- |
341| `--version` | 显示版本号 | boolean |341| `--version` | 显示版本号 | boolean |
342| `--configPath` | 覆盖 config.yaml 文件的路径 | string |342| `--configPath` | 覆盖 config.yaml 文件的路径 | string |
343| `--dataRoot` | 数据存储的根目录 | string |343| `--dataRoot` | 数据存储的根目录 | string |
@@ -353,10 +353,10 @@ Start.bat --port 8000 --listen false
353| `--ssl` | 启用 SSL | boolean |353| `--ssl` | 启用 SSL | boolean |
354| `--certPath` | 您的证书文件路径 | string |354| `--certPath` | 您的证书文件路径 | string |
355| `--keyPath` | 您的私钥文件路径 | string |355| `--keyPath` | 您的私钥文件路径 | string |
356| `--autorun` | 自动在浏览器中启动 SillyTavern | boolean |356| `--browserLaunchEnabled` | 自动在浏览器中启动 SillyTavern | boolean |
357| `--autorunHostname` | 自动运行主机名 | string |357| `--browserLaunchHostname` | 自动运行主机名 | string |
358| `--autorunPortOverride` | 覆盖自动运行的端口 | string |358| `--browserLaunchPort` | 覆盖自动运行的端口 | string |
359| `--avoidLocalhost` | 在自动模式下避免使用 'localhost' 进行自动运行 | boolean |359| `--browserLaunchAvoidLocalhost` | 在自动模式下避免使用 'localhost' 进行自动运行 | boolean |
360| `--corsProxy` | 启用 CORS 代理 | boolean |360| `--corsProxy` | 启用 CORS 代理 | boolean |
361| `--requestProxyEnabled` | 为传出请求启用代理 | boolean |361| `--requestProxyEnabled` | 为传出请求启用代理 | boolean |
362| `--requestProxyUrl` | 请求代理 URL(HTTP 或 SOCKS 协议) | string |362| `--requestProxyUrl` | 请求代理 URL(HTTP 或 SOCKS 协议) | string |
.github/readme-zh_tw.md+9 -9
@@ -320,24 +320,24 @@ Start.bat --port 8000 --listen false
320### Supported arguments320### Supported arguments
321321
322| Option | Description | Type |322| Option | Description | Type |
323|-------------------------|------------------------------------------------------------------------------------------------------|----------|323|----------------------------------|---------------------------------------------|---------|
324| `--version` | 顯示版本序號 | boolean |324| `--version` | 顯示版本序號 | boolean |
325| `--enableIPv6` | 啟用 IPv6 | boolean |325| `--enableIPv6` | 啟用 IPv6 | boolean |
326| `--enableIPv4` | 啟用 IPv4 | boolean |326| `--enableIPv4` | 啟用 IPv4 | boolean |
327| `--port` | 設定 SillyTavern 運行的端口。若未提供,則預設使用 `config.yaml` 中的 'port' | number327| `--port` | 設定 SillyTavern 運行的端口。 | number |
328| `--dnsPreferIPv6` | 偏好使用 IPv6 解析 DNS。未提供則默認使用 `config.yaml` 中的 'preferIPv6' | boolean |328| `--dnsPreferIPv6` | 偏好使用 IPv6 解析 DNS。 | boolean |
329| `--autorun` | 自動在瀏覽器中啟動 SillyTavern。未提供則默認使用 `config.yaml` 中的 'autorun' | boolean |329| `--browserLaunchEnabled` | 自動在瀏覽器中啟動 SillyTavern。 | boolean |
330| `--autorunHostname` | 自動啟動時的主機名稱,通常建議保持為 'auto' | string |330| `--browserLaunchHostname` | 自動啟動時的主機名稱,通常建議保持為 'auto' | string |
331| `--autorunPortOverride` | 覆蓋自動啟動的端口設定 | string |331| `--browserLaunchPort` | 覆蓋自動啟動的端口設定 | string |
332| `--listen` | SillyTavern 是否可監聽所有網路接口。若未提供,則默認使用 `config.yaml` 中的 'listen' | boolean |332| `--browserLaunchAvoidLocalhost` | 在自動模式下避免使用 'localhost' | boolean |
333| `--corsProxy` | 啟用 CORS 代理。若未提供,則默認使用 `config.yaml` 中的 'enableCorsProxy' | boolean |333| `--listen` | SillyTavern 是否可監聽所有網路接口。 | boolean |
334| `--corsProxy` | 啟用 CORS 代理。 | boolean |
334| `--disableCsrf` | 停用 CSRF 保護 | boolean |335| `--disableCsrf` | 停用 CSRF 保護 | boolean |
335| `--ssl` | 啟用 SSL | boolean |336| `--ssl` | 啟用 SSL | boolean |
336| `--certPath` | 設定您證書文件的路徑 | string |337| `--certPath` | 設定您證書文件的路徑 | string |
337| `--keyPath` | 設定您私人金鑰文件的路徑 | string |338| `--keyPath` | 設定您私人金鑰文件的路徑 | string |
338| `--whitelist` | 啟用白名單模式 | boolean |339| `--whitelist` | 啟用白名單模式 | boolean |
339| `--dataRoot` | 設定數據儲存的根目錄 | string |340| `--dataRoot` | 設定數據儲存的根目錄 | string |
340| `--avoidLocalhost` | 在自動模式下避免使用 'localhost' | boolean |
341| `--basicAuthMode` | 啟用基本身份驗證模式 | boolean |341| `--basicAuthMode` | 啟用基本身份驗證模式 | boolean |
342| `--requestProxyEnabled` | 啟用代理以處理外部請求 | boolean |342| `--requestProxyEnabled` | 啟用代理以處理外部請求 | boolean |
343| `--requestProxyUrl` | 設定請求代理的 URL(支持 HTTP 或 SOCKS 協議)| string |343| `--requestProxyUrl` | 設定請求代理的 URL(支持 HTTP 或 SOCKS 協議)| string |
.github/readme.md+5 -5
@@ -334,7 +334,7 @@ Start.bat --port 8000 --listen false
334> None of the arguments are required. If you don't provide them, SillyTavern will use the settings in `config.yaml`.334> None of the arguments are required. If you don't provide them, SillyTavern will use the settings in `config.yaml`.
335335
336| Option | Description | Type |336| Option | Description | Type |
337|-------------------------|----------------------------------------------------------------------|----------|337|---------------------------------|----------------------------------------------------------------------|----------|
338| `--version` | Show version number | boolean |338| `--version` | Show version number | boolean |
339| `--configPath` | Override the path to the config.yaml file | string |339| `--configPath` | Override the path to the config.yaml file | string |
340| `--dataRoot` | Root directory for data storage | string |340| `--dataRoot` | Root directory for data storage | string |
@@ -350,10 +350,10 @@ Start.bat --port 8000 --listen false
350| `--ssl` | Enables SSL | boolean |350| `--ssl` | Enables SSL | boolean |
351| `--certPath` | Path to your certificate file | string |351| `--certPath` | Path to your certificate file | string |
352| `--keyPath` | Path to your private key file | string |352| `--keyPath` | Path to your private key file | string |
353| `--autorun` | Automatically launch SillyTavern in the browser | boolean |353| `--browserLaunchEnabled` | Automatically launch SillyTavern in the browser | boolean |
354| `--autorunHostname` | Autorun hostname | string |354| `--browserLaunchHostname` | Browser launch hostname | string |
355| `--autorunPortOverride` | Overrides the port for autorun | string |355| `--browserLaunchPort` | Overrides the port for browser launch | string |
356| `--avoidLocalhost` | Avoids using 'localhost' for autorun in auto mode | boolean |356| `--browserLaunchAvoidLocalhost` | Avoids using 'localhost' for browser launch in auto mode | boolean |
357| `--corsProxy` | Enables CORS proxy | boolean |357| `--corsProxy` | Enables CORS proxy | boolean |
358| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean |358| `--requestProxyEnabled` | Enables a use of proxy for outgoing requests | boolean |
359| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string |359| `--requestProxyUrl` | Request proxy URL (HTTP or SOCKS protocols) | string |
default/config.yaml+17 -12
@@ -16,16 +16,27 @@ protocol:
16 ipv6: false16 ipv6: false
17# Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv617# Prefers IPv6 for DNS. Enable this on ISPs that don't have issues with IPv6
18dnsPreferIPv6: false18dnsPreferIPv6: false
19# The hostname that autorun opens.19# -- BROWSER LAUNCH CONFIGURATION --
20browserLaunch:
21 # Open the browser automatically on server startup.
22 enabled: true
23 # Browser to use for opening the URL.
24 # - Use "default" to use the system default browser
25 # - Use "firefox", "chrome", "edge"
26 browser: 'default'
27 # Overrides the hostname that opens in the browser.
20 # - Use "auto" to let the server decide28 # - Use "auto" to let the server decide
21 # - Use options like 'localhost', 'st.example.com'29 # - Use options like 'localhost', 'st.example.com'
22autorunHostname: "auto"30 hostname: 'auto'
23# Server port31 # Overrides the port for run in the browser.
24port: 8000
25# Overrides the port for autorun in browser.
26 # - Use -1 to use the server port.32 # - Use -1 to use the server port.
27 # - Specify a port to override the default.33 # - Specify a port to override the default.
28autorunPortOverride: -134 port: -1
35 # Avoids using 'localhost' as the hostname in auto mode.
36 # Use if you don't have 'localhost' in your hosts file
37 avoidLocalhost: false
38# Server port
39port: 8000
29# -- SSL options --40# -- SSL options --
30ssl:41ssl:
31 enabled: false42 enabled: false
@@ -98,12 +109,6 @@ rateLimiting:
98 # Use X-Real-IP header instead of socket IP for rate limiting109 # Use X-Real-IP header instead of socket IP for rate limiting
99 # Only enable this if you are using a properly configured reverse proxy (like Nginx/traefik/Caddy)110 # Only enable this if you are using a properly configured reverse proxy (like Nginx/traefik/Caddy)
100 preferRealIpHeader: false111 preferRealIpHeader: false
101# -- ADVANCED CONFIGURATION --
102# Open the browser automatically
103autorun: true
104# Avoids using 'localhost' for autorun in auto mode.
105# use if you don't have 'localhost' in your hosts file
106avoidLocalhost: false
107112
108## BACKUP CONFIGURATION113## BACKUP CONFIGURATION
109backups:114backups:
package-lock.json+94 -44
@@ -77,7 +77,7 @@
77 "multer": "^2.0.1",77 "multer": "^2.0.1",
78 "node-fetch": "^3.3.2",78 "node-fetch": "^3.3.2",
79 "node-persist": "^4.0.4",79 "node-persist": "^4.0.4",
80 "open": "^8.4.2",80 "open": "^10.1.2",
81 "png-chunk-text": "^1.0.0",81 "png-chunk-text": "^1.0.0",
82 "png-chunks-extract": "^1.0.0",82 "png-chunks-extract": "^1.0.0",
83 "proxy-agent": "^6.5.0",83 "proxy-agent": "^6.5.0",
@@ -2991,6 +2991,21 @@
2991 "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",2991 "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
2992 "license": "MIT"2992 "license": "MIT"
2993 },2993 },
2994 "node_modules/bundle-name": {
2995 "version": "4.1.0",
2996 "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
2997 "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
2998 "license": "MIT",
2999 "dependencies": {
3000 "run-applescript": "^7.0.0"
3001 },
3002 "engines": {
3003 "node": ">=18"
3004 },
3005 "funding": {
3006 "url": "https://github.com/sponsors/sindresorhus"
3007 }
3008 },
2994 "node_modules/busboy": {3009 "node_modules/busboy": {
2995 "version": "1.6.0",3010 "version": "1.6.0",
2996 "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",3011 "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -3764,6 +3779,34 @@
3764 "dev": true,3779 "dev": true,
3765 "license": "MIT"3780 "license": "MIT"
3766 },3781 },
3782 "node_modules/default-browser": {
3783 "version": "5.2.1",
3784 "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
3785 "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
3786 "license": "MIT",
3787 "dependencies": {
3788 "bundle-name": "^4.1.0",
3789 "default-browser-id": "^5.0.0"
3790 },
3791 "engines": {
3792 "node": ">=18"
3793 },
3794 "funding": {
3795 "url": "https://github.com/sponsors/sindresorhus"
3796 }
3797 },
3798 "node_modules/default-browser-id": {
3799 "version": "5.0.0",
3800 "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
3801 "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
3802 "license": "MIT",
3803 "engines": {
3804 "node": ">=18"
3805 },
3806 "funding": {
3807 "url": "https://github.com/sponsors/sindresorhus"
3808 }
3809 },
3767 "node_modules/defer-to-connect": {3810 "node_modules/defer-to-connect": {
3768 "version": "2.0.1",3811 "version": "2.0.1",
3769 "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",3812 "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
@@ -3791,12 +3834,15 @@
3791 }3834 }
3792 },3835 },
3793 "node_modules/define-lazy-prop": {3836 "node_modules/define-lazy-prop": {
3794 "version": "2.0.0",3837 "version": "3.0.0",
3795 "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",3838 "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
3796 "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",3839 "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
3797 "license": "MIT",3840 "license": "MIT",
3798 "engines": {3841 "engines": {
3799 "node": ">=8"3842 "node": ">=12"
3843 },
3844 "funding": {
3845 "url": "https://github.com/sponsors/sindresorhus"
3800 }3846 }
3801 },3847 },
3802 "node_modules/degenerator": {3848 "node_modules/degenerator": {
@@ -5545,6 +5591,24 @@
5545 "node": ">=0.10.0"5591 "node": ">=0.10.0"
5546 }5592 }
5547 },5593 },
5594 "node_modules/is-inside-container": {
5595 "version": "1.0.0",
5596 "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
5597 "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
5598 "license": "MIT",
5599 "dependencies": {
5600 "is-docker": "^3.0.0"
5601 },
5602 "bin": {
5603 "is-inside-container": "cli.js"
5604 },
5605 "engines": {
5606 "node": ">=14.16"
5607 },
5608 "funding": {
5609 "url": "https://github.com/sponsors/sindresorhus"
5610 }
5611 },
5548 "node_modules/is-path-inside": {5612 "node_modules/is-path-inside": {
5549 "version": "3.0.3",5613 "version": "3.0.3",
5550 "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",5614 "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -5567,27 +5631,15 @@
5567 }5631 }
5568 },5632 },
5569 "node_modules/is-wsl": {5633 "node_modules/is-wsl": {
5570 "version": "2.2.0",5634 "version": "3.1.0",
5571 "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz",5635 "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
5572 "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==",5636 "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
5573 "license": "MIT",5637 "license": "MIT",
5574 "dependencies": {5638 "dependencies": {
5575 "is-docker": "^2.0.0"5639 "is-inside-container": "^1.0.0"
5576 },
5577 "engines": {
5578 "node": ">=8"
5579 }
5580 },
5581 "node_modules/is-wsl/node_modules/is-docker": {
5582 "version": "2.2.1",
5583 "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
5584 "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
5585 "license": "MIT",
5586 "bin": {
5587 "is-docker": "cli.js"
5588 },5640 },
5589 "engines": {5641 "engines": {
5590 "node": ">=8"5642 "node": ">=16"
5591 },5643 },
5592 "funding": {5644 "funding": {
5593 "url": "https://github.com/sponsors/sindresorhus"5645 "url": "https://github.com/sponsors/sindresorhus"
@@ -6367,32 +6419,18 @@
6367 }6419 }
6368 },6420 },
6369 "node_modules/open": {6421 "node_modules/open": {
6370 "version": "8.4.2",6422 "version": "10.1.2",
6371 "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",6423 "resolved": "https://registry.npmjs.org/open/-/open-10.1.2.tgz",
6372 "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",6424 "integrity": "sha512-cxN6aIDPz6rm8hbebcP7vrQNhvRcveZoJU72Y7vskh4oIm+BZwBECnx5nTmrlres1Qapvx27Qo1Auukpf8PKXw==",
6373 "license": "MIT",6425 "license": "MIT",
6374 "dependencies": {6426 "dependencies": {
6375 "define-lazy-prop": "^2.0.0",6427 "default-browser": "^5.2.1",
6376 "is-docker": "^2.1.1",6428 "define-lazy-prop": "^3.0.0",
6377 "is-wsl": "^2.2.0"6429 "is-inside-container": "^1.0.0",
6430 "is-wsl": "^3.1.0"
6378 },6431 },
6379 "engines": {6432 "engines": {
6380 "node": ">=12"6433 "node": ">=18"
6381 },
6382 "funding": {
6383 "url": "https://github.com/sponsors/sindresorhus"
6384 }
6385 },
6386 "node_modules/open/node_modules/is-docker": {
6387 "version": "2.2.1",
6388 "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
6389 "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
6390 "license": "MIT",
6391 "bin": {
6392 "is-docker": "cli.js"
6393 },
6394 "engines": {
6395 "node": ">=8"
6396 },6434 },
6397 "funding": {6435 "funding": {
6398 "url": "https://github.com/sponsors/sindresorhus"6436 "url": "https://github.com/sponsors/sindresorhus"
@@ -7219,6 +7257,18 @@
7219 "url": "https://github.com/sponsors/isaacs"7257 "url": "https://github.com/sponsors/isaacs"
7220 }7258 }
7221 },7259 },
7260 "node_modules/run-applescript": {
7261 "version": "7.0.0",
7262 "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
7263 "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
7264 "license": "MIT",
7265 "engines": {
7266 "node": ">=18"
7267 },
7268 "funding": {
7269 "url": "https://github.com/sponsors/sindresorhus"
7270 }
7271 },
7222 "node_modules/run-parallel": {7272 "node_modules/run-parallel": {
7223 "version": "1.2.0",7273 "version": "1.2.0",
7224 "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",7274 "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
package.json+1 -1
@@ -67,7 +67,7 @@
67 "multer": "^2.0.1",67 "multer": "^2.0.1",
68 "node-fetch": "^3.3.2",68 "node-fetch": "^3.3.2",
69 "node-persist": "^4.0.4",69 "node-persist": "^4.0.4",
70 "open": "^8.4.2",70 "open": "^10.1.2",
71 "png-chunk-text": "^1.0.0",71 "png-chunk-text": "^1.0.0",
72 "png-chunks-extract": "^1.0.0",72 "png-chunks-extract": "^1.0.0",
73 "proxy-agent": "^6.5.0",73 "proxy-agent": "^6.5.0",
src/command-line.js+97 -54
@@ -15,24 +15,24 @@ import { initConfig } from './config-init.js';
15 * @property {boolean|string} enableIPv4 If enable IPv4 protocol ("auto" is also allowed)15 * @property {boolean|string} enableIPv4 If enable IPv4 protocol ("auto" is also allowed)
16 * @property {boolean|string} enableIPv6 If enable IPv6 protocol ("auto" is also allowed)16 * @property {boolean|string} enableIPv6 If enable IPv6 protocol ("auto" is also allowed)
17 * @property {boolean} dnsPreferIPv6 If prefer IPv6 for DNS17 * @property {boolean} dnsPreferIPv6 If prefer IPv6 for DNS
18 * @property {boolean} autorun If automatically launch SillyTavern in the browser18 * @property {boolean} browserLaunchEnabled If automatically launch SillyTavern in the browser
19 * @property {string} autorunHostname Autorun hostname19 * @property {string} browserLaunchHostname Browser launch hostname
20 * @property {number} autorunPortOverride Autorun port override (-1 is use server port)20 * @property {number} browserLaunchPort Browser launch port override (-1 is use server port)
21 * @property {boolean} browserLaunchAvoidLocalhost If avoid using 'localhost' for browser launch in auto mode
21 * @property {boolean} enableCorsProxy If enable CORS proxy22 * @property {boolean} enableCorsProxy If enable CORS proxy
22 * @property {boolean} disableCsrf If disable CSRF protection23 * @property {boolean} disableCsrf If disable CSRF protection
23 * @property {boolean} ssl If enable SSL24 * @property {boolean} ssl If enable SSL
24 * @property {string} certPath Path to certificate25 * @property {string} certPath Path to certificate
25 * @property {string} keyPath Path to private key26 * @property {string} keyPath Path to private key
26 * @property {boolean} whitelistMode If enable whitelist mode27 * @property {boolean} whitelistMode If enable whitelist mode
27 * @property {boolean} avoidLocalhost If avoid using 'localhost' for autorun in auto mode
28 * @property {boolean} basicAuthMode If enable basic authentication28 * @property {boolean} basicAuthMode If enable basic authentication
29 * @property {boolean} requestProxyEnabled If enable outgoing request proxy29 * @property {boolean} requestProxyEnabled If enable outgoing request proxy
30 * @property {string} requestProxyUrl Request proxy URL30 * @property {string} requestProxyUrl Request proxy URL
31 * @property {string[]} requestProxyBypass Request proxy bypass list31 * @property {string[]} requestProxyBypass Request proxy bypass list
32 * @property {function(): URL} getIPv4ListenUrl Get IPv4 listen URL32 * @property {function(): URL} getIPv4ListenUrl Get IPv4 listen URL
33 * @property {function(): URL} getIPv6ListenUrl Get IPv6 listen URL33 * @property {function(): URL} getIPv6ListenUrl Get IPv6 listen URL
34 * @property {function(import('./server-startup.js').ServerStartupResult): Promise<string>} getAutorunHostname Get autorun hostname34 * @property {function(import('./server-startup.js').ServerStartupResult): Promise<string>} getBrowserLaunchHostname Get browser launch hostname
35 * @property {function(string): URL} getAutorunUrl Get autorun URL35 * @property {function(string): URL} getBrowserLaunchUrl Get browser launch URL
36 */36 */
3737
38/**38/**
@@ -51,16 +51,16 @@ export class CommandLineParser {
51 enableIPv4: true,51 enableIPv4: true,
52 enableIPv6: false,52 enableIPv6: false,
53 dnsPreferIPv6: false,53 dnsPreferIPv6: false,
54 autorun: false,54 browserLaunchEnabled: false,
55 autorunHostname: 'auto',55 browserLaunchHostname: 'auto',
56 autorunPortOverride: -1,56 browserLaunchPort: -1,
57 browserLaunchAvoidLocalhost: false,
57 enableCorsProxy: false,58 enableCorsProxy: false,
58 disableCsrf: false,59 disableCsrf: false,
59 ssl: false,60 ssl: false,
60 certPath: 'certs/cert.pem',61 certPath: 'certs/cert.pem',
61 keyPath: 'certs/privkey.pem',62 keyPath: 'certs/privkey.pem',
62 whitelistMode: true,63 whitelistMode: true,
63 avoidLocalhost: false,
64 basicAuthMode: false,64 basicAuthMode: false,
65 requestProxyEnabled: false,65 requestProxyEnabled: false,
66 requestProxyUrl: '',66 requestProxyUrl: '',
@@ -71,11 +71,11 @@ export class CommandLineParser {
71 getIPv6ListenUrl: function () {71 getIPv6ListenUrl: function () {
72 throw new Error('getIPv6ListenUrl is not implemented');72 throw new Error('getIPv6ListenUrl is not implemented');
73 },73 },
74 getAutorunHostname: async function () {74 getBrowserLaunchHostname: async function () {
75 throw new Error('getAutorunHostname is not implemented');75 throw new Error('getBrowserLaunchHostname is not implemented');
76 },76 },
77 getAutorunUrl: function () {77 getBrowserLaunchUrl: function () {
78 throw new Error('getAutorunUrl is not implemented');78 throw new Error('getBrowserLaunchUrl is not implemented');
79 },79 },
80 });80 });
8181
@@ -100,90 +100,133 @@ export class CommandLineParser {
100 type: 'string',100 type: 'string',
101 default: null,101 default: null,
102 describe: 'Enables IPv6 protocol',102 describe: 'Enables IPv6 protocol',
103 }).option('enableIPv4', {103 })
104 .option('enableIPv4', {
104 type: 'string',105 type: 'string',
105 default: null,106 default: null,
106 describe: 'Enables IPv4 protocol',107 describe: 'Enables IPv4 protocol',
107 }).option('port', {108 })
109 .option('port', {
108 type: 'number',110 type: 'number',
109 default: null,111 default: null,
110 describe: 'Sets the server listening port',112 describe: 'Sets the server listening port',
111 }).option('dnsPreferIPv6', {113 })
114 .option('dnsPreferIPv6', {
112 type: 'boolean',115 type: 'boolean',
113 default: null,116 default: null,
114 describe: 'Prefers IPv6 for DNS\nYou should probably have the enabled if you\'re on an IPv6 only network',117 describe: 'Prefers IPv6 for DNS\nYou should probably have the enabled if you\'re on an IPv6 only network',
115 }).option('autorun', {118 })
119 .option('browserLaunchEnabled', {
116 type: 'boolean',120 type: 'boolean',
117 default: null,121 default: null,
118 describe: 'Automatically launch SillyTavern in the browser',122 describe: 'Automatically launch SillyTavern in the browser',
119 }).option('autorunHostname', {123 })
124 .option('browserLaunchHostname', {
120 type: 'string',125 type: 'string',
121 default: null,126 default: null,
122 describe: 'Sets the autorun hostname, probably best left on \'auto\'.\nUse values like \'localhost\', \'st.example.com\'',127 describe: 'Sets the browser launch hostname, best left on \'auto\'.\nUse values like \'localhost\', \'st.example.com\'',
123 }).option('autorunPortOverride', {128 })
124 type: 'string',129 .option('browserLaunchPort', {
130 type: 'number',
131 default: null,
132 describe: 'Overrides the port for browser launch with open your browser with this port and ignore what port the server is running on. -1 is use server port',
133 })
134 .option('browserLaunchAvoidLocalhost', {
135 type: 'boolean',
125 default: null,136 default: null,
126 describe: 'Overrides the port for autorun with open your browser with this port and ignore what port the server is running on. -1 is use server port',137 describe: 'Avoids using \'localhost\' for browser launch in auto mode.\nUse if you don\'t have \'localhost\' in your hosts file',
127 }).option('listen', {138 })
139 .option('listen', {
128 type: 'boolean',140 type: 'boolean',
129 default: null,141 default: null,
130 describe: 'Whether to listen on all network interfaces',142 describe: 'Whether to listen on all network interfaces',
131 }).option('listenAddressIPv6', {143 })
144 .option('listenAddressIPv6', {
132 type: 'string',145 type: 'string',
133 default: null,146 default: null,
134 describe: 'Specific IPv6 address to listen to',147 describe: 'Specific IPv6 address to listen to',
135 }).option('listenAddressIPv4', {148 })
149 .option('listenAddressIPv4', {
136 type: 'string',150 type: 'string',
137 default: null,151 default: null,
138 describe: 'Specific IPv4 address to listen to',152 describe: 'Specific IPv4 address to listen to',
139 }).option('corsProxy', {153 })
154 .option('corsProxy', {
140 type: 'boolean',155 type: 'boolean',
141 default: null,156 default: null,
142 describe: 'Enables CORS proxy',157 describe: 'Enables CORS proxy',
143 }).option('disableCsrf', {158 })
159 .option('disableCsrf', {
144 type: 'boolean',160 type: 'boolean',
145 default: null,161 default: null,
146 describe: 'Disables CSRF protection - NOT RECOMMENDED',162 describe: 'Disables CSRF protection - NOT RECOMMENDED',
147 }).option('ssl', {163 })
164 .option('ssl', {
148 type: 'boolean',165 type: 'boolean',
149 default: null,166 default: null,
150 describe: 'Enables SSL',167 describe: 'Enables SSL',
151 }).option('certPath', {168 })
169 .option('certPath', {
152 type: 'string',170 type: 'string',
153 default: null,171 default: null,
154 describe: 'Path to SSL certificate file',172 describe: 'Path to SSL certificate file',
155 }).option('keyPath', {173 })
174 .option('keyPath', {
156 type: 'string',175 type: 'string',
157 default: null,176 default: null,
158 describe: 'Path to SSL private key file',177 describe: 'Path to SSL private key file',
159 }).option('whitelist', {178 })
179 .option('whitelist', {
160 type: 'boolean',180 type: 'boolean',
161 default: null,181 default: null,
162 describe: 'Enables whitelist mode',182 describe: 'Enables whitelist mode',
163 }).option('dataRoot', {183 })
184 .option('dataRoot', {
164 type: 'string',185 type: 'string',
165 default: null,186 default: null,
166 describe: 'Root directory for data storage',187 describe: 'Root directory for data storage',
167 }).option('avoidLocalhost', {188 })
168 type: 'boolean',189 .option('basicAuthMode', {
169 default: null,
170 describe: 'Avoids using \'localhost\' for autorun in auto mode.\nUse if you don\'t have \'localhost\' in your hosts file',
171 }).option('basicAuthMode', {
172 type: 'boolean',190 type: 'boolean',
173 default: null,191 default: null,
174 describe: 'Enables basic authentication',192 describe: 'Enables basic authentication',
175 }).option('requestProxyEnabled', {193 })
194 .option('requestProxyEnabled', {
176 type: 'boolean',195 type: 'boolean',
177 default: null,196 default: null,
178 describe: 'Enables a use of proxy for outgoing requests',197 describe: 'Enables a use of proxy for outgoing requests',
179 }).option('requestProxyUrl', {198 })
199 .option('requestProxyUrl', {
180 type: 'string',200 type: 'string',
181 default: null,201 default: null,
182 describe: 'Request proxy URL (HTTP or SOCKS protocols)',202 describe: 'Request proxy URL (HTTP or SOCKS protocols)',
183 }).option('requestProxyBypass', {203 })
204 .option('requestProxyBypass', {
184 type: 'array',205 type: 'array',
185 describe: 'Request proxy bypass list (space separated list of hosts)',206 describe: 'Request proxy bypass list (space separated list of hosts)',
186 }).parseSync();207 })
208 /* DEPRECATED options */
209 .option('autorun', {
210 type: 'boolean',
211 default: null,
212 describe: 'DEPRECATED: Use "browserLaunchEnabled" instead.',
213 })
214 .option('autorunHostname', {
215 type: 'string',
216 default: null,
217 describe: 'DEPRECATED: Use "browserLaunchHostname" instead.',
218 })
219 .option('autorunPortOverride', {
220 type: 'number',
221 default: null,
222 describe: 'DEPRECATED: Use "browserLaunchPort" instead.',
223 })
224 .option('avoidLocalhost', {
225 type: 'boolean',
226 default: null,
227 describe: 'DEPRECATED: Use "browserLaunchAvoidLocalhost" instead.',
228 })
229 .parseSync();
187230
188 const configPath = cliArguments.configPath ?? this.default.configPath;231 const configPath = cliArguments.configPath ?? this.default.configPath;
189 initConfig(configPath);232 initConfig(configPath);
@@ -198,16 +241,16 @@ export class CommandLineParser {
198 enableIPv4: stringToBool(cliArguments.enableIPv4) ?? stringToBool(getConfigValue('protocol.ipv4', this.default.enableIPv4)) ?? this.default.enableIPv4,241 enableIPv4: stringToBool(cliArguments.enableIPv4) ?? stringToBool(getConfigValue('protocol.ipv4', this.default.enableIPv4)) ?? this.default.enableIPv4,
199 enableIPv6: stringToBool(cliArguments.enableIPv6) ?? stringToBool(getConfigValue('protocol.ipv6', this.default.enableIPv6)) ?? this.default.enableIPv6,242 enableIPv6: stringToBool(cliArguments.enableIPv6) ?? stringToBool(getConfigValue('protocol.ipv6', this.default.enableIPv6)) ?? this.default.enableIPv6,
200 dnsPreferIPv6: cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv6', this.default.dnsPreferIPv6, 'boolean'),243 dnsPreferIPv6: cliArguments.dnsPreferIPv6 ?? getConfigValue('dnsPreferIPv6', this.default.dnsPreferIPv6, 'boolean'),
201 autorun: cliArguments.autorun ?? getConfigValue('autorun', this.default.autorun, 'boolean'),244 browserLaunchEnabled: cliArguments.browserLaunchEnabled ?? cliArguments.autorun ?? getConfigValue('browserLaunch.enabled', this.default.browserLaunchEnabled, 'boolean'),
202 autorunHostname: cliArguments.autorunHostname ?? getConfigValue('autorunHostname', this.default.autorunHostname),245 browserLaunchHostname: cliArguments.browserLaunchHostname ?? cliArguments.autorunHostname ?? getConfigValue('browserLaunch.hostname', this.default.browserLaunchHostname),
203 autorunPortOverride: cliArguments.autorunPortOverride ?? getConfigValue('autorunPortOverride', this.default.autorunPortOverride, 'number'),246 browserLaunchPort: cliArguments.browserLaunchPort ?? cliArguments.autorunPortOverride ?? getConfigValue('browserLaunch.port', this.default.browserLaunchPort, 'number'),
247 browserLaunchAvoidLocalhost: cliArguments.browserLaunchAvoidLocalhost ?? cliArguments.avoidLocalhost ?? getConfigValue('browserLaunch.avoidLocalhost', this.default.browserLaunchAvoidLocalhost, 'boolean'),
204 enableCorsProxy: cliArguments.corsProxy ?? getConfigValue('enableCorsProxy', this.default.enableCorsProxy, 'boolean'),248 enableCorsProxy: cliArguments.corsProxy ?? getConfigValue('enableCorsProxy', this.default.enableCorsProxy, 'boolean'),
205 disableCsrf: cliArguments.disableCsrf ?? getConfigValue('disableCsrfProtection', this.default.disableCsrf, 'boolean'),249 disableCsrf: cliArguments.disableCsrf ?? getConfigValue('disableCsrfProtection', this.default.disableCsrf, 'boolean'),
206 ssl: cliArguments.ssl ?? getConfigValue('ssl.enabled', this.default.ssl, 'boolean'),250 ssl: cliArguments.ssl ?? getConfigValue('ssl.enabled', this.default.ssl, 'boolean'),
207 certPath: cliArguments.certPath ?? getConfigValue('ssl.certPath', this.default.certPath),251 certPath: cliArguments.certPath ?? getConfigValue('ssl.certPath', this.default.certPath),
208 keyPath: cliArguments.keyPath ?? getConfigValue('ssl.keyPath', this.default.keyPath),252 keyPath: cliArguments.keyPath ?? getConfigValue('ssl.keyPath', this.default.keyPath),
209 whitelistMode: cliArguments.whitelist ?? getConfigValue('whitelistMode', this.default.whitelistMode, 'boolean'),253 whitelistMode: cliArguments.whitelist ?? getConfigValue('whitelistMode', this.default.whitelistMode, 'boolean'),
210 avoidLocalhost: cliArguments.avoidLocalhost ?? getConfigValue('avoidLocalhost', this.default.avoidLocalhost, 'boolean'),
211 basicAuthMode: cliArguments.basicAuthMode ?? getConfigValue('basicAuthMode', this.default.basicAuthMode, 'boolean'),254 basicAuthMode: cliArguments.basicAuthMode ?? getConfigValue('basicAuthMode', this.default.basicAuthMode, 'boolean'),
212 requestProxyEnabled: cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', this.default.requestProxyEnabled, 'boolean'),255 requestProxyEnabled: cliArguments.requestProxyEnabled ?? getConfigValue('requestProxy.enabled', this.default.requestProxyEnabled, 'boolean'),
213 requestProxyUrl: cliArguments.requestProxyUrl ?? getConfigValue('requestProxy.url', this.default.requestProxyUrl),256 requestProxyUrl: cliArguments.requestProxyUrl ?? getConfigValue('requestProxy.url', this.default.requestProxyUrl),
@@ -228,12 +271,12 @@ export class CommandLineParser {
228 (':' + this.port),271 (':' + this.port),
229 );272 );
230 },273 },
231 getAutorunHostname: async function ({ useIPv6, useIPv4 }) {274 getBrowserLaunchHostname: async function ({ useIPv6, useIPv4 }) {
232 if (this.autorunHostname === 'auto') {275 if (this.browserLaunchHostname === 'auto') {
233 let localhostResolve = await canResolve('localhost', useIPv6, useIPv4);276 const localhostResolve = await canResolve('localhost', useIPv6, useIPv4);
234277
235 if (useIPv6 && useIPv4) {278 if (useIPv6 && useIPv4) {
236 return (this.avoidLocalhost || !localhostResolve) ? '[::1]' : 'localhost';279 return (this.browserLaunchAvoidLocalhost || !localhostResolve) ? '[::1]' : 'localhost';
237 }280 }
238281
239 if (useIPv6) {282 if (useIPv6) {
@@ -245,15 +288,15 @@ export class CommandLineParser {
245 }288 }
246 }289 }
247290
248 return this.autorunHostname;291 return this.browserLaunchHostname;
249 },292 },
250 getAutorunUrl: function (hostname) {293 getBrowserLaunchUrl: function (hostname) {
251 const autorunPort = (this.autorunPortOverride >= 0) ? this.autorunPortOverride : this.port;294 const browserLaunchPort = (this.browserLaunchPort >= 0) ? this.browserLaunchPort : this.port;
252 return new URL(295 return new URL(
253 (this.ssl ? 'https://' : 'http://') +296 (this.ssl ? 'https://' : 'http://') +
254 (hostname) +297 (hostname) +
255 (':') +298 (':') +
256 (autorunPort),299 (browserLaunchPort),
257 );300 );
258 },301 },
259 };302 };
src/config-init.js+33 -1
@@ -4,7 +4,7 @@ import yaml from 'yaml';
4import color from 'chalk';4import color from 'chalk';
5import _ from 'lodash';5import _ from 'lodash';
6import { serverDirectory } from './server-directory.js';6import { serverDirectory } from './server-directory.js';
7import { setConfigFilePath } from './util.js';7import { keyToEnv, setConfigFilePath } from './util.js';
88
9const keyMigrationMap = [9const keyMigrationMap = [
10 {10 {
@@ -98,6 +98,26 @@ const keyMigrationMap = [
98 migrate: () => void 0,98 migrate: () => void 0,
99 remove: true,99 remove: true,
100 },100 },
101 {
102 oldKey: 'autorun',
103 newKey: 'browserLaunch.enabled',
104 migrate: (value) => value,
105 },
106 {
107 oldKey: 'autorunHostname',
108 newKey: 'browserLaunch.hostname',
109 migrate: (value) => value,
110 },
111 {
112 oldKey: 'autorunPortOverride',
113 newKey: 'browserLaunch.port',
114 migrate: (value) => value,
115 },
116 {
117 oldKey: 'avoidLocalhost',
118 newKey: 'browserLaunch.avoidLocalhost',
119 migrate: (value) => value,
120 },
101];121];
102122
103/**123/**
@@ -133,6 +153,18 @@ export function addMissingConfigValues(configPath) {
133 // Migrate old keys to new keys153 // Migrate old keys to new keys
134 const migratedKeys = [];154 const migratedKeys = [];
135 for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) {155 for (const { oldKey, newKey, migrate, remove } of keyMigrationMap) {
156 // Migrate environment variables
157 const oldEnvKey = keyToEnv(oldKey);
158 const newEnvKey = keyToEnv(newKey);
159 if (process.env[oldEnvKey] && !process.env[newEnvKey]) {
160 const oldValue = process.env[oldEnvKey];
161 const newValue = migrate(oldValue);
162 process.env[newEnvKey] = newValue;
163 delete process.env[oldEnvKey];
164 console.warn(color.yellow(`Warning: Using a deprecated environment variable: ${oldEnvKey}. Please use ${newEnvKey} instead.`));
165 console.log(`Redirecting ${color.blue(oldEnvKey)}=${oldValue} -> ${color.blue(newEnvKey)}=${newValue}`);
166 }
167
136 if (_.has(config, oldKey)) {168 if (_.has(config, oldKey)) {
137 if (remove) {169 if (remove) {
138 _.unset(config, oldKey);170 _.unset(config, oldKey);
src/server-main.js+19 -8
@@ -14,7 +14,7 @@ import multer from 'multer';
14import responseTime from 'response-time';14import responseTime from 'response-time';
15import helmet from 'helmet';15import helmet from 'helmet';
16import bodyParser from 'body-parser';16import bodyParser from 'body-parser';
17import open from 'open';17import open, { apps } from 'open';
1818
19// local library imports19// local library imports
20import './fetch-patch.js';20import './fetch-patch.js';
@@ -65,6 +65,7 @@ import {
65 safeReadFileSync,65 safeReadFileSync,
66 setupLogLevel,66 setupLogLevel,
67 setWindowTitle,67 setWindowTitle,
68 getConfigValue,
68} from './util.js';69} from './util.js';
69import { UPLOADS_DIRECTORY } from './constants.js';70import { UPLOADS_DIRECTORY } from './constants.js';
70import { ensureThumbnailCache } from './endpoints/thumbnails.js';71import { ensureThumbnailCache } from './endpoints/thumbnails.js';
@@ -83,6 +84,7 @@ util.inspect.defaultOptions.maxArrayLength = null;
83util.inspect.defaultOptions.maxStringLength = null;84util.inspect.defaultOptions.maxStringLength = null;
84util.inspect.defaultOptions.depth = 4;85util.inspect.defaultOptions.depth = 4;
8586
87/** @type {import('./command-line.js').CommandLineArguments} */
86const cliArgs = globalThis.COMMAND_LINE_ARGS;88const cliArgs = globalThis.COMMAND_LINE_ARGS;
8789
88if (!cliArgs.enableIPv6 && !cliArgs.enableIPv4) {90if (!cliArgs.enableIPv6 && !cliArgs.enableIPv4) {
@@ -321,13 +323,22 @@ async function preSetupTasks() {
321 * @returns {Promise<void>}323 * @returns {Promise<void>}
322 */324 */
323async function postSetupTasks(result) {325async function postSetupTasks(result) {
324 const autorunHostname = await cliArgs.getAutorunHostname(result);326 const browserLaunchHostname = await cliArgs.getBrowserLaunchHostname(result);
325 const autorunUrl = cliArgs.getAutorunUrl(autorunHostname);327 const browserLaunchUrl = cliArgs.getBrowserLaunchUrl(browserLaunchHostname);
328 const browserLaunchApp = String(getConfigValue('browserLaunch.browser', 'default') ?? '');
326329
327 if (cliArgs.autorun) {330 if (cliArgs.browserLaunchEnabled) {
328 try {331 try {
329 console.log('Launching in a browser...');332 const validBrowsers = {
330 await open(autorunUrl.toString());333 'firefox': apps.firefox,
334 'chrome': apps.chrome,
335 'edge': apps.edge,
336 };
337 const appName = validBrowsers[browserLaunchApp.trim().toLowerCase()];
338 const openOptions = appName ? { app: { name: appName } } : {};
339
340 console.log(`Launching in a browser: ${browserLaunchApp}...`);
341 await open(browserLaunchUrl.toString(), openOptions);
331 } catch (error) {342 } catch (error) {
332 console.error('Failed to launch the browser. Open the URL manually.');343 console.error('Failed to launch the browser. Open the URL manually.');
333 }344 }
@@ -349,7 +360,7 @@ async function postSetupTasks(result) {
349 );360 );
350 }361 }
351362
352 const goToLog = 'Go to: ' + color.blue(autorunUrl) + ' to open SillyTavern';363 const goToLog = `Go to: ${color.blue(browserLaunchUrl)} to open SillyTavern`;
353 const plainGoToLog = removeColorFormatting(goToLog);364 const plainGoToLog = removeColorFormatting(goToLog);
354365
355 console.log(logListen);366 console.log(logListen);
@@ -363,7 +374,7 @@ async function postSetupTasks(result) {
363 console.log('\n' + getSeparator(plainGoToLog.length) + '\n');374 console.log('\n' + getSeparator(plainGoToLog.length) + '\n');
364375
365 setupLogLevel();376 setupLogLevel();
366 serverEvents.emit(EVENT_NAMES.SERVER_STARTED, { url: autorunUrl });377 serverEvents.emit(EVENT_NAMES.SERVER_STARTED, { url: browserLaunchUrl });
367}378}
368379
369/**380/**