mirror of
https://github.com/0xJacky/nginx-ui.git
synced 2026-05-06 22:12:23 +08:00
fix: improve error handling and path resolution in license generation
This commit is contained in:
@@ -34,7 +34,7 @@ msgstr "[Nginx UI] 証明書の失効に成功しました"
|
||||
|
||||
#: src/language/generate.ts:41
|
||||
msgid "[Nginx UI] Certificate was used for server, reloading server TLS certificate"
|
||||
msgstr "[Nginx UI] サーバーで証明書が使用されました、サーバーのTLS証明書を再読み込み中"
|
||||
msgstr "[Nginx UI] サーバーで証明書が使用されました、サーバーのTLS 証明書を再読み込み中"
|
||||
|
||||
#: src/language/generate.ts:42
|
||||
msgid "[Nginx UI] Creating client facilitates communication with the CA server"
|
||||
@@ -113,7 +113,7 @@ msgstr "* グループ %{groupName} のノードと手動で選択したノー
|
||||
msgid ""
|
||||
"* Index files are stored in the \"log-index\" directory within your Nginx "
|
||||
"UI config path by default."
|
||||
msgstr "* インデックスファイルはデフォルトでNGINX UI設定パス内の「log-index」ディレクトリに保存されます。"
|
||||
msgstr "* インデックスファイルはデフォルトでNGINX UI 設定パス内の「log-index」ディレクトリに保存されます。"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:217
|
||||
msgid ""
|
||||
@@ -129,7 +129,7 @@ msgstr "%{total} 項目中 %{start}~%{end}"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:49
|
||||
msgid "1 core minimum"
|
||||
msgstr "最小1コア"
|
||||
msgstr "最小 1コア"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:55
|
||||
msgid "1GB RAM minimum"
|
||||
@@ -142,7 +142,7 @@ msgstr "2+ コア推奨"
|
||||
#: src/views/nginx_log/dashboard/components/HourlyChart.vue:67
|
||||
#: src/views/nginx_log/dashboard/components/HourlyChart.vue:68
|
||||
msgid "24-Hour UV/PV Statistics"
|
||||
msgstr "24時間UV/PV統計"
|
||||
msgstr "24 時間 UV/PV 統計"
|
||||
|
||||
#: src/views/user/userColumns.tsx:30
|
||||
msgid "2FA"
|
||||
@@ -154,7 +154,7 @@ msgstr "ニ要素認証設定"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:56
|
||||
msgid "4GB+ RAM recommended"
|
||||
msgstr "4GB以上のRAMを推奨"
|
||||
msgstr "4GB 以上のRAMを推奨"
|
||||
|
||||
#: src/routes/modules/system.ts:38
|
||||
msgid "About"
|
||||
@@ -392,7 +392,7 @@ msgstr "新しいリカバリーコードを生成してもよろしいですか
|
||||
|
||||
#: src/views/preference/components/AuthSettings/TOTP.vue:87
|
||||
msgid "Are you sure to reset 2FA?"
|
||||
msgstr "2要素認証をリセットしてもよろしいですか?"
|
||||
msgstr "2 要素認証をリセットしてもよろしいですか?"
|
||||
|
||||
#: src/components/Notification/Notification.vue:117
|
||||
#: src/views/notification/Notification.vue:40
|
||||
@@ -546,7 +546,7 @@ msgstr "平均レイテンシ"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/SummaryStats.vue:33
|
||||
msgid "Avg Daily UV"
|
||||
msgstr "平均日間UV"
|
||||
msgstr "平均日間 UV"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:793
|
||||
msgid "Avg/PV"
|
||||
@@ -844,7 +844,7 @@ msgstr "証明書 %{name} は %{days} 日後に期限切れになります"
|
||||
|
||||
#: src/components/Notification/notifications.ts:58
|
||||
msgid "Certificate %{name} will expire in 1 day"
|
||||
msgstr "証明書 %{name} は1日で期限切れになります"
|
||||
msgstr "証明書 %{name} は1 日で期限切れになります"
|
||||
|
||||
#: src/views/certificate/components/CertificateDownload.vue:37
|
||||
msgid "Certificate content and private key content cannot be empty"
|
||||
@@ -1416,11 +1416,11 @@ msgstr "CPUステータス"
|
||||
|
||||
#: src/views/dashboard/components/ResourceUsageCard.vue:27
|
||||
msgid "CPU Usage"
|
||||
msgstr "CPU使用率"
|
||||
msgstr "CPU 使用率"
|
||||
|
||||
#: src/views/dashboard/components/ResourceUsageCard.vue:38
|
||||
msgid "CPU usage is relatively high, consider optimizing Nginx configuration"
|
||||
msgstr "CPU使用率が比較的高いため、Nginxの設定を最適化することを検討してください"
|
||||
msgstr "CPU 使用率が比較的高いため、Nginxの設定を最適化することを検討してください"
|
||||
|
||||
#: src/views/dashboard/ServerAnalytic.vue:200
|
||||
msgid "CPU:"
|
||||
@@ -1480,7 +1480,7 @@ msgstr "認証情報"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/CronEditor.vue:194
|
||||
msgid "Cron Expression"
|
||||
msgstr "Cron式"
|
||||
msgstr "Cron 式"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:266
|
||||
msgid "Cross-file timeline correlation"
|
||||
@@ -2031,7 +2031,7 @@ msgstr "ドライランモードが有効です"
|
||||
msgid ""
|
||||
"Due to the security policies of some browsers, you cannot use passkeys on "
|
||||
"non-HTTPS websites, except when running on localhost."
|
||||
msgstr "一部のブラウザのセキュリティポリシーのため、localhostで実行している場合を除き、非HTTPSウェブサイトではパスキーを使用できません。"
|
||||
msgstr "一部のブラウザのセキュリティポリシーのため、localhostで実行している場合を除き、非 HTTPSウェブサイトではパスキーを使用できません。"
|
||||
|
||||
#: src/components/LLM/LLMSessionTabs.vue:287
|
||||
#: src/components/LLM/LLMSessionTabs.vue:378
|
||||
@@ -2058,7 +2058,7 @@ msgstr "動的シャード管理"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/CronEditor.vue:197
|
||||
msgid "e.g., 0 0 * * * (daily at midnight)"
|
||||
msgstr "例: 0 0 * * * (毎日深夜0時)"
|
||||
msgstr "例: 0 0 * * * (毎日深夜 0 時)"
|
||||
|
||||
#: src/views/certificate/ACMEUser.vue:100
|
||||
msgid "EAB HMAC Key"
|
||||
@@ -2436,7 +2436,7 @@ msgstr "exec インスタンスへのアタッチに失敗しました: {0}"
|
||||
|
||||
#: src/constants/errors/backup.ts:5
|
||||
msgid "Failed to backup Nginx config files: {0}"
|
||||
msgstr "Nginx設定ファイルのバックアップに失敗しました: {0}"
|
||||
msgstr "Nginx 設定ファイルのバックアップに失敗しました: {0}"
|
||||
|
||||
#: src/constants/errors/backup.ts:4
|
||||
msgid "Failed to backup Nginx UI files: {0}"
|
||||
@@ -2476,7 +2476,7 @@ msgstr "ファイルの内容のコピーに失敗しました: {0}"
|
||||
|
||||
#: src/constants/errors/backup.ts:19
|
||||
msgid "Failed to copy Nginx config directory: {0}"
|
||||
msgstr "Nginx設定ディレクトリのコピーに失敗しました: {0}"
|
||||
msgstr "Nginx 設定ディレクトリのコピーに失敗しました: {0}"
|
||||
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:33
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:114
|
||||
@@ -2723,7 +2723,7 @@ msgstr "ZIPファイルを開けませんでした: {0}"
|
||||
|
||||
#: src/constants/errors/performance.ts:7
|
||||
msgid "Failed to parse nginx config: {0}"
|
||||
msgstr "nginx設定の解析に失敗しました: {0}"
|
||||
msgstr "nginx 設定の解析に失敗しました: {0}"
|
||||
|
||||
#: src/constants/errors/self_check.ts:5
|
||||
msgid "Failed to parse nginx.conf"
|
||||
@@ -2787,7 +2787,7 @@ msgstr "サイトの更新に失敗しました"
|
||||
|
||||
#: src/constants/errors/backup.ts:37
|
||||
msgid "Failed to restore Nginx configs: {0}"
|
||||
msgstr "Nginx設定の復元に失敗しました: {0}"
|
||||
msgstr "Nginx 設定の復元に失敗しました: {0}"
|
||||
|
||||
#: src/views/certificate/components/RemoveCert.vue:59
|
||||
msgid "Failed to revoke certificate"
|
||||
@@ -3068,7 +3068,7 @@ msgstr "データの取得に失敗しました"
|
||||
|
||||
#: src/constants/errors/cert.ts:12
|
||||
msgid "Get dns credential error: {0}"
|
||||
msgstr "DNS認証情報の取得エラー: {0}"
|
||||
msgstr "DNS 認証情報の取得エラー: {0}"
|
||||
|
||||
#: src/views/node/BatchUpgrader.vue:182 src/views/system/Upgrade.vue:188
|
||||
msgid "Get release information error"
|
||||
@@ -3110,20 +3110,20 @@ msgid ""
|
||||
"gRPCS uses TLS encryption. Server must implement gRPC Health Check service. "
|
||||
"For testing, SSL validation is disabled by default."
|
||||
msgstr ""
|
||||
"gRPCSはTLS暗号化を使用します。サーバーはgRPCヘルスチェックサービスを実装する必要があります。テストでは、SSL検証はデフォルトで無効になって"
|
||||
"gRPCSはTLS 暗号化を使用します。サーバーはgRPCヘルスチェックサービスを実装する必要があります。テストでは、SSL 検証はデフォルトで無効になって"
|
||||
"います。"
|
||||
|
||||
#: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:67
|
||||
msgid "GZIP Compression"
|
||||
msgstr "GZIP圧縮"
|
||||
msgstr "GZIP 圧縮"
|
||||
|
||||
#: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:87
|
||||
msgid "GZIP Compression Level"
|
||||
msgstr "GZIP圧縮レベル"
|
||||
msgstr "GZIP 圧縮レベル"
|
||||
|
||||
#: src/views/dashboard/components/ParamsOpt/PerformanceConfig.vue:80
|
||||
msgid "GZIP Min Length"
|
||||
msgstr "GZIP最小長"
|
||||
msgstr "GZIP 最小長"
|
||||
|
||||
#: src/views/upstream/SocketList.vue:60
|
||||
msgid "Health Check"
|
||||
@@ -3221,7 +3221,7 @@ msgstr "https://..."
|
||||
|
||||
#: src/views/preference/tabs/NodeSettings.vue:34
|
||||
msgid "ICP Number"
|
||||
msgstr "ICP番号"
|
||||
msgstr "ICP 番号"
|
||||
|
||||
#: src/views/preference/tabs/AuthSettings.vue:109
|
||||
msgid ""
|
||||
@@ -3366,13 +3366,13 @@ msgstr "インストール"
|
||||
|
||||
#: src/constants/errors/system.ts:3
|
||||
msgid "Installation is not allowed after 10 minutes of system startup"
|
||||
msgstr "システム起動後10分経過するとインストールは許可されません"
|
||||
msgstr "システム起動後 10 分経過するとインストールは許可されません"
|
||||
|
||||
#: src/views/install/components/TimeoutAlert.vue:11
|
||||
msgid ""
|
||||
"Installation is not allowed after 10 minutes of system startup, please "
|
||||
"restart the Nginx UI."
|
||||
msgstr "システム起動から10分後はインストールが許可されません。Nginx UIを再起動してください。"
|
||||
msgstr "システム起動から10 分後はインストールが許可されません。Nginx UIを再起動してください。"
|
||||
|
||||
#: src/views/dns/DDNSManager.vue:79
|
||||
#: src/views/preference/tabs/LogrotateSettings.vue:26
|
||||
@@ -3389,7 +3389,7 @@ msgstr "無効"
|
||||
|
||||
#: src/constants/errors/backup.ts:41
|
||||
msgid "Invalid AES IV format: {0}"
|
||||
msgstr "無効なAES IV形式: {0}"
|
||||
msgstr "無効なAES IV 形式: {0}"
|
||||
|
||||
#: src/constants/errors/backup.ts:40
|
||||
msgid "Invalid AES key format: {0}"
|
||||
@@ -3427,7 +3427,7 @@ msgstr "無効なフォルダ名"
|
||||
|
||||
#: src/constants/errors/notification.ts:4
|
||||
msgid "Invalid notification ID"
|
||||
msgstr "無効な通知ID"
|
||||
msgstr "無効な通知 ID"
|
||||
|
||||
#: src/constants/errors/notification.ts:3
|
||||
msgid "Invalid notifier config"
|
||||
@@ -3490,7 +3490,7 @@ msgstr "IPアドレス"
|
||||
|
||||
#: src/components/AutoCertForm/AutoCertForm.vue:123
|
||||
msgid "IP Certificate Notice"
|
||||
msgstr "IP証明書の通知"
|
||||
msgstr "IP 証明書の通知"
|
||||
|
||||
#: src/views/certificate/CertificateList/Certificate.vue:37
|
||||
msgid "Issue certificate"
|
||||
@@ -3545,41 +3545,41 @@ msgstr "Lark カスタム"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:315
|
||||
msgid "Last 12 hours"
|
||||
msgstr "過去12時間"
|
||||
msgstr "過去 12 時間"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/DateRangeSelector.vue:22
|
||||
msgid "Last 14 days"
|
||||
msgstr "過去14日間"
|
||||
msgstr "過去 14 日間"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:311
|
||||
msgid "Last 15 minutes"
|
||||
msgstr "過去15分"
|
||||
msgstr "過去 15 分"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:316
|
||||
msgid "Last 24 hours"
|
||||
msgstr "過去24時間"
|
||||
msgstr "過去 24 時間"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/DateRangeSelector.vue:23
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:318
|
||||
msgid "Last 30 days"
|
||||
msgstr "過去30日間"
|
||||
msgstr "過去 30 日間"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:312
|
||||
msgid "Last 30 minutes"
|
||||
msgstr "過去30分"
|
||||
msgstr "過去 30 分"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:314
|
||||
msgid "Last 4 hours"
|
||||
msgstr "過去4時間"
|
||||
msgstr "過去 4 時間"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/DateRangeSelector.vue:21
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:317
|
||||
msgid "Last 7 days"
|
||||
msgstr "過去7日間"
|
||||
msgstr "過去 7 日間"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/DateRangeSelector.vue:24
|
||||
msgid "Last 90 days"
|
||||
msgstr "過去90日間"
|
||||
msgstr "過去 90 日間"
|
||||
|
||||
#: src/views/backup/AutoBackup/AutoBackup.vue:190
|
||||
msgid "Last Backup Status"
|
||||
@@ -3599,7 +3599,7 @@ msgstr "最終確認日時"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:313
|
||||
msgid "Last hour"
|
||||
msgstr "過去1時間"
|
||||
msgstr "過去 1 時間"
|
||||
|
||||
#: src/views/nginx_log/NginxLogList.vue:258
|
||||
msgid "Last Indexed"
|
||||
@@ -4229,35 +4229,35 @@ msgstr "Nginx および Nginx UI 設定"
|
||||
|
||||
#: src/constants/errors/self_check.ts:6
|
||||
msgid "Nginx conf no http block"
|
||||
msgstr "Nginx設定にhttpブロックがありません"
|
||||
msgstr "Nginx 設定にhttpブロックがありません"
|
||||
|
||||
#: src/constants/errors/self_check.ts:8
|
||||
msgid "Nginx conf no stream block"
|
||||
msgstr "Nginx設定にストリームブロックがありません"
|
||||
msgstr "Nginx 設定にストリームブロックがありません"
|
||||
|
||||
#: src/constants/errors/self_check.ts:15
|
||||
msgid "Nginx conf not include conf.d directory"
|
||||
msgstr "Nginx設定にconf.dディレクトリが含まれていません"
|
||||
msgstr "Nginx 設定にconf.dディレクトリが含まれていません"
|
||||
|
||||
#: src/constants/errors/self_check.ts:7
|
||||
msgid "Nginx conf not include sites-enabled"
|
||||
msgstr "Nginx設定にsites-enabledが含まれていません"
|
||||
msgstr "Nginx 設定にsites-enabledが含まれていません"
|
||||
|
||||
#: src/constants/errors/self_check.ts:9
|
||||
msgid "Nginx conf not include stream-enabled"
|
||||
msgstr "Nginx設定にstream-enabledが含まれていません"
|
||||
msgstr "Nginx 設定にstream-enabledが含まれていません"
|
||||
|
||||
#: src/constants/errors/backup.ts:18
|
||||
msgid "Nginx config directory is not set"
|
||||
msgstr "Nginx設定ディレクトリが設定されていません"
|
||||
msgstr "Nginx 設定ディレクトリが設定されていません"
|
||||
|
||||
#: src/language/generate.ts:28
|
||||
msgid "Nginx configuration directory exists"
|
||||
msgstr "Nginx設定ディレクトリが存在します"
|
||||
msgstr "Nginx 設定ディレクトリが存在します"
|
||||
|
||||
#: src/language/generate.ts:29
|
||||
msgid "Nginx configuration entry file exists"
|
||||
msgstr "Nginx設定エントリファイルが存在します"
|
||||
msgstr "Nginx 設定エントリファイルが存在します"
|
||||
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:138
|
||||
msgid "Nginx configuration has been restored"
|
||||
@@ -4266,7 +4266,7 @@ msgstr "Nginxの設定が復元されました"
|
||||
#: src/views/site/site_edit/components/SiteEditor/SiteEditor.vue:135
|
||||
#: src/views/stream/components/StreamEditor.vue:105
|
||||
msgid "Nginx Configuration Parse Error"
|
||||
msgstr "Nginx設定解析エラー"
|
||||
msgstr "Nginx 設定解析エラー"
|
||||
|
||||
#: src/views/preference/tabs/NginxSettings.vue:22
|
||||
msgid "Nginx Configuration Path"
|
||||
@@ -4287,7 +4287,7 @@ msgstr "Nginx 制御モード"
|
||||
#: src/composables/usePerformanceMetrics.ts:149
|
||||
#: src/views/dashboard/components/PerformanceTablesCard.vue:105
|
||||
msgid "Nginx CPU usage rate"
|
||||
msgstr "NginxのCPU使用率"
|
||||
msgstr "NginxのCPU 使用率"
|
||||
|
||||
#: src/views/preference/tabs/NginxSettings.vue:16
|
||||
msgid "Nginx Error Log Path"
|
||||
@@ -4547,7 +4547,7 @@ msgstr "まだ実行されていません"
|
||||
|
||||
#: src/components/AutoCertForm/AutoCertForm.vue:230
|
||||
msgid "Not supported for IP certificates"
|
||||
msgstr "IP証明書には対応していません"
|
||||
msgstr "IP 証明書には対応していません"
|
||||
|
||||
#: src/components/CertInfo/CertInfo.vue:41
|
||||
msgid "Not Valid Before: %{date}"
|
||||
@@ -4818,7 +4818,7 @@ msgstr "パスワードが間違っています"
|
||||
|
||||
#: src/views/install/components/InstallForm.vue:45
|
||||
msgid "Password length cannot exceed 20 characters"
|
||||
msgstr "パスワードの長さは20文字を超えることはできません"
|
||||
msgstr "パスワードの長さは20 文字を超えることはできません"
|
||||
|
||||
#: src/views/user/UserProfile.vue:96
|
||||
msgid "Password updated successfully"
|
||||
@@ -4963,13 +4963,13 @@ msgstr "すべての項目を正しく入力してください"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:23
|
||||
msgid "Please fill in required S3 configuration fields"
|
||||
msgstr "必要なS3設定項目を入力してください"
|
||||
msgstr "必要なS3 設定項目を入力してください"
|
||||
|
||||
#: src/views/dns/DNSCredential.vue:93
|
||||
msgid ""
|
||||
"Please fill in the API authentication credentials provided by your DNS "
|
||||
"provider."
|
||||
msgstr "DNSプロバイダーから提供されたAPI認証情報を入力してください。"
|
||||
msgstr "DNSプロバイダーから提供されたAPI 認証情報を入力してください。"
|
||||
|
||||
#: src/components/AutoCertForm/AutoCertForm.vue:168
|
||||
msgid ""
|
||||
@@ -5202,7 +5202,7 @@ msgstr "プロキシターゲット"
|
||||
|
||||
#: src/components/AutoCertForm/AutoCertForm.vue:192
|
||||
msgid "Public CA Requirements:"
|
||||
msgstr "公開CAの要件:"
|
||||
msgstr "公開 CAの要件:"
|
||||
|
||||
#: src/views/preference/tabs/NodeSettings.vue:46
|
||||
msgid "Public Security Number"
|
||||
@@ -5644,7 +5644,7 @@ msgstr "バックアップから復元"
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:223
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:300
|
||||
msgid "Restore Nginx Configuration"
|
||||
msgstr "Nginx設定を復元"
|
||||
msgstr "Nginx 設定を復元"
|
||||
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:234
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:311
|
||||
@@ -5737,15 +5737,15 @@ msgstr "S3バケット名"
|
||||
|
||||
#: src/constants/errors/backup.ts:56
|
||||
msgid "S3 configuration is incomplete: missing {0}"
|
||||
msgstr "S3設定が不完全です: {0}が不足しています"
|
||||
msgstr "S3 設定が不完全です: {0}が不足しています"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:34
|
||||
msgid "S3 connection test failed"
|
||||
msgstr "S3接続テストが失敗しました"
|
||||
msgstr "S3 接続テストが失敗しました"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:30
|
||||
msgid "S3 connection test successful"
|
||||
msgstr "S3接続テストが成功しました"
|
||||
msgstr "S3 接続テストが成功しました"
|
||||
|
||||
#: src/views/backup/AutoBackup/AutoBackup.vue:243
|
||||
#: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:66
|
||||
@@ -6121,7 +6121,7 @@ msgstr "パスキーでサインイン"
|
||||
|
||||
#: src/views/nginx_log/components/IndexingSettingsModal.vue:76
|
||||
msgid "SIMD-optimized stream processing"
|
||||
msgstr "SIMD最適化されたストリーム処理"
|
||||
msgstr "SIMD 最適化されたストリーム処理"
|
||||
|
||||
#: src/components/NgxConfigEditor/directive/DirectiveAdd.vue:48
|
||||
msgid "Single Directive"
|
||||
@@ -6205,7 +6205,7 @@ msgstr "並べ替え基準"
|
||||
|
||||
#: src/views/dashboard/components/SiteHealthCheckModal.vue:683
|
||||
msgid "Source IP"
|
||||
msgstr "送信元IP"
|
||||
msgstr "送信元 IP"
|
||||
|
||||
#: src/views/system/About.vue:46
|
||||
msgid "Sponsor"
|
||||
@@ -6218,33 +6218,33 @@ msgstr "I/O パフォーマンス向上のための SSD ストレージ"
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:209
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:214
|
||||
msgid "SSL Certificate Content"
|
||||
msgstr "SSL証明書の内容"
|
||||
msgstr "SSL 証明書の内容"
|
||||
|
||||
#: src/constants/errors/system.ts:8
|
||||
msgid "SSL certificate file must be under Nginx configuration directory: {0}"
|
||||
msgstr "SSL証明書ファイルはNginx設定ディレクトリの下にある必要があります: {0}"
|
||||
msgstr "SSL 証明書ファイルはNginx 設定ディレクトリの下にある必要があります: {0}"
|
||||
|
||||
#: src/constants/errors/system.ts:6
|
||||
msgid "SSL certificate file not found"
|
||||
msgstr "SSL証明書ファイルが見つかりません"
|
||||
msgstr "SSL 証明書ファイルが見つかりません"
|
||||
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:270
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:275
|
||||
msgid "SSL Certificate Key Content"
|
||||
msgstr "SSL証明書キーの内容"
|
||||
msgstr "SSL 証明書キーの内容"
|
||||
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:112
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:126
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:138
|
||||
msgid "SSL Certificate Key Path"
|
||||
msgstr "SSL証明書キーパス"
|
||||
msgstr "SSL 証明書キーパス"
|
||||
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:104
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:78
|
||||
#: src/views/certificate/components/CertificateBasicInfo.vue:92
|
||||
#: src/views/preference/tabs/ServerSettings.vue:37
|
||||
msgid "SSL Certificate Path"
|
||||
msgstr "SSL証明書のパス"
|
||||
msgstr "SSL 証明書のパス"
|
||||
|
||||
#: src/constants/errors/system.ts:4
|
||||
msgid "SSL certificate path is required when HTTPS is enabled"
|
||||
@@ -6252,7 +6252,7 @@ msgstr "HTTPS を有効にするには SSL 証明書のパスが必要です"
|
||||
|
||||
#: src/constants/errors/system.ts:9
|
||||
msgid "SSL key file must be under Nginx configuration directory: {0}"
|
||||
msgstr "SSLキーファイルはNginx設定ディレクトリの下にある必要があります: {0}"
|
||||
msgstr "SSLキーファイルはNginx 設定ディレクトリの下にある必要があります: {0}"
|
||||
|
||||
#: src/constants/errors/system.ts:7
|
||||
msgid "SSL key file not found"
|
||||
@@ -6579,7 +6579,7 @@ msgstr "テストメッセージが正常に送信されました"
|
||||
|
||||
#: src/views/backup/AutoBackup/components/StorageConfigEditor.vue:141
|
||||
msgid "Test S3 Connection"
|
||||
msgstr "S3接続をテスト"
|
||||
msgstr "S3 接続をテスト"
|
||||
|
||||
#: src/views/dashboard/components/SiteHealthCheckModal.vue:448
|
||||
msgid "Test successful! Response time: %{response_time}ms"
|
||||
@@ -6590,7 +6590,7 @@ msgid ""
|
||||
"The certificate for the domain will be checked 30 minutes, and will be "
|
||||
"renewed if it has been more than 1 week or the period you set in settings "
|
||||
"since it was last issued."
|
||||
msgstr "ドメインの証明書は30分ごとにチェックされ、最後に発行されてから1週間以上経過しているか、設定で指定した期間が経過している場合に更新されます。"
|
||||
msgstr "ドメインの証明書は30 分ごとにチェックされ、最後に発行されてから1 週間以上経過しているか、設定で指定した期間が経過している場合に更新されます。"
|
||||
|
||||
#: src/components/GeoLiteDownload/GeoLiteDownload.vue:158
|
||||
msgid ""
|
||||
@@ -6608,15 +6608,15 @@ msgstr "GeoLite2 データベースは、IP アドレスの地理情報を提供
|
||||
msgid ""
|
||||
"The ICP Number should only contain letters, unicode, numbers, hyphens, "
|
||||
"dashes, colons, and dots."
|
||||
msgstr "ICP番号には、文字、Unicode、数字、ハイフン、ダッシュ、コロン、およびドットのみを含める必要があります。"
|
||||
msgstr "ICP 番号には、文字、Unicode、数字、ハイフン、ダッシュ、コロン、およびドットのみを含める必要があります。"
|
||||
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:205
|
||||
msgid "The input is not a SSL Certificate"
|
||||
msgstr "入力はSSL証明書ではありません"
|
||||
msgstr "入力はSSL 証明書ではありません"
|
||||
|
||||
#: src/views/certificate/components/CertificateContentEditor.vue:266
|
||||
msgid "The input is not a SSL Certificate Key"
|
||||
msgstr "入力はSSL証明書キーではありません"
|
||||
msgstr "入力はSSL 証明書キーではありません"
|
||||
|
||||
#: src/constants/errors/nginx_log.ts:2
|
||||
msgid ""
|
||||
@@ -6694,7 +6694,7 @@ msgstr "理論上の最大同時接続数:"
|
||||
|
||||
#: src/views/dashboard/components/PerformanceTablesCard.vue:189
|
||||
msgid "Theoretical maximum RPS (Requests Per Second):"
|
||||
msgstr "理論上の最大RPS(リクエスト/秒):"
|
||||
msgstr "理論上の最大 RPS(リクエスト/秒):"
|
||||
|
||||
#: src/views/preference/components/AuthSettings/RecoveryCodes.vue:105
|
||||
msgid ""
|
||||
@@ -6741,13 +6741,13 @@ msgstr "このフィールドは空にできません"
|
||||
|
||||
#: src/constants/form_errors.ts:6
|
||||
msgid "This field should only contain letters, unicode characters, numbers, and -_."
|
||||
msgstr "このフィールドには、文字、Unicode文字、数字、および -_ のみを含める必要があります。"
|
||||
msgstr "このフィールドには、文字、Unicode 文字、数字、および -_ のみを含める必要があります。"
|
||||
|
||||
#: src/language/curd.ts:46
|
||||
msgid ""
|
||||
"This field should only contain letters, unicode characters, numbers, and "
|
||||
"-_./:"
|
||||
msgstr "このフィールドには、文字、Unicode文字、数字、および -_./: のみを含める必要があります"
|
||||
msgstr "このフィールドには、文字、Unicode 文字、数字、および -_./: のみを含める必要があります"
|
||||
|
||||
#: src/components/Notification/notifications.ts:94
|
||||
msgid "This is a test message sent at %{timestamp} from Nginx UI."
|
||||
@@ -6780,7 +6780,7 @@ msgid ""
|
||||
"may not be available with all ACME providers."
|
||||
msgstr ""
|
||||
"このサイトはHTTPS(ポート443)のデフォルトサーバー(default_"
|
||||
"server)として設定されています。IP証明書には認証局(CA)のサポートが必要であり、すべてのACMEプロバイダーで利用可能とは限りません。"
|
||||
"server)として設定されています。IP 証明書には認証局(CA)のサポートが必要であり、すべてのACMEプロバイダーで利用可能とは限りません。"
|
||||
|
||||
#: src/components/AutoCertForm/AutoCertForm.vue:132
|
||||
msgid ""
|
||||
@@ -6789,7 +6789,7 @@ msgid ""
|
||||
"support and may not be available with all ACME providers."
|
||||
msgstr ""
|
||||
"このサイトはワイルドカードサーバー名(_"
|
||||
")を使用しており、通常はIPベースの証明書を示しています。IP証明書には認証局(CA)のサポートが必要であり、すべてのACMEプロバイダーで利用可能では"
|
||||
")を使用しており、通常はIPベースの証明書を示しています。IP 証明書には認証局(CA)のサポートが必要であり、すべてのACMEプロバイダーで利用可能では"
|
||||
"ない場合があります。"
|
||||
|
||||
#: src/views/backup/components/BackupCreator.vue:141
|
||||
@@ -6823,7 +6823,7 @@ msgstr "この特定のファイルのインデックスデータを再構築し
|
||||
msgid ""
|
||||
"This will restore all Nginx configuration files. Nginx will restart after "
|
||||
"the restoration is complete."
|
||||
msgstr "これにより、すべてのNginx設定ファイルが復元されます。復元が完了すると、Nginxが再起動します。"
|
||||
msgstr "これにより、すべてのNginx 設定ファイルが復元されます。復元が完了すると、Nginxが再起動します。"
|
||||
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:238
|
||||
#: src/components/SystemRestore/SystemRestoreContent.vue:315
|
||||
@@ -6976,7 +6976,7 @@ msgstr "Nginxプロセスの合計"
|
||||
|
||||
#: src/views/nginx_log/dashboard/components/SummaryStats.vue:24
|
||||
msgid "Total PV"
|
||||
msgstr "総PV"
|
||||
msgstr "総 PV"
|
||||
|
||||
#: src/views/dashboard/ServerAnalytic.vue:284
|
||||
msgid "Total Receive"
|
||||
@@ -7248,7 +7248,7 @@ msgstr "ユーザー名 (*)"
|
||||
|
||||
#: src/views/install/components/InstallForm.vue:35
|
||||
msgid "Username length cannot exceed 255 characters"
|
||||
msgstr "ユーザー名の長さは255文字を超えることはできません"
|
||||
msgstr "ユーザー名の長さは255 文字を超えることはできません"
|
||||
|
||||
#: src/views/nginx_log/structured/StructuredLogViewer.vue:775
|
||||
msgid "UV"
|
||||
@@ -7262,7 +7262,7 @@ msgstr "有効"
|
||||
|
||||
#: src/views/dashboard/components/SiteHealthCheckModal.vue:658
|
||||
msgid "Validate SSL Certificate"
|
||||
msgstr "SSL証明書を検証"
|
||||
msgstr "SSL 証明書を検証"
|
||||
|
||||
#: src/views/dashboard/components/PerformanceTablesCard.vue:22
|
||||
#: src/views/dns/components/DNSRecordForm.vue:66
|
||||
@@ -7375,7 +7375,7 @@ msgstr "WebAuthn 設定が構成されていません"
|
||||
|
||||
#: src/views/certificate/components/RemoveCert.vue:65
|
||||
msgid "WebSocket connection error"
|
||||
msgstr "WebSocket接続エラー"
|
||||
msgstr "WebSocket 接続エラー"
|
||||
|
||||
#: src/views/preference/components/ExternalNotify/wecom.ts:5
|
||||
msgid "WeCom"
|
||||
@@ -7484,7 +7484,7 @@ msgstr "はい"
|
||||
msgid ""
|
||||
"You are accessing this terminal over an insecure HTTP connection on a "
|
||||
"non-localhost domain. This may expose sensitive information."
|
||||
msgstr "あなたは非localhostドメインで安全でないHTTP接続を介してこのターミナルにアクセスしています。これにより機密情報が漏洩する可能性があります。"
|
||||
msgstr "あなたは非 localhostドメインで安全でないHTTP 接続を介してこのターミナルにアクセスしています。これにより機密情報が漏洩する可能性があります。"
|
||||
|
||||
#: src/constants/errors/config.ts:8
|
||||
msgid "You are not allowed to delete a file outside of the nginx config path"
|
||||
@@ -7572,7 +7572,7 @@ msgstr "ゼロアロケーションパイプライン"
|
||||
#~ msgstr "M2 Pro(12コア)でのテストに基づく"
|
||||
|
||||
#~ msgid "CPU Utilization"
|
||||
#~ msgstr "CPU使用率"
|
||||
#~ msgstr "CPU 使用率"
|
||||
|
||||
#~ msgid "Indexing Throughput"
|
||||
#~ msgstr "インデックス処理能力"
|
||||
@@ -7656,7 +7656,7 @@ msgstr "ゼロアロケーションパイプライン"
|
||||
#~ msgstr "S3バケットへのアクセスが拒否されました: {0}"
|
||||
|
||||
#~ msgid "S3 connection test failed: {0}"
|
||||
#~ msgstr "S3接続テストが失敗しました: {0}"
|
||||
#~ msgstr "S3 接続テストが失敗しました: {0}"
|
||||
|
||||
#~ msgid "S3 credentials are invalid: {0}"
|
||||
#~ msgstr "S3の認証情報が無効です: {0}"
|
||||
@@ -7751,7 +7751,7 @@ msgstr "ゼロアロケーションパイプライン"
|
||||
#~ msgstr "両方の設定"
|
||||
|
||||
#~ msgid "Nginx Config"
|
||||
#~ msgstr "Nginx設定"
|
||||
#~ msgstr "Nginx 設定"
|
||||
|
||||
#~ msgid "Nginx UI Config"
|
||||
#~ msgstr "Nginx UI 設定"
|
||||
|
||||
@@ -1579,7 +1579,7 @@ msgstr ""
|
||||
" JP: \"Reactを使う\" → \"React を使う\"\n"
|
||||
" KO: \"Node.js설치\" → \"Node.js 설치\"\n"
|
||||
" TH: \"ติดตั้งPython3.9\" → \"ติดตั้ง Python 3.9\"\n"
|
||||
" - Винятки: числа/одиниці/оператори (200GB硬盘 → 200GB 硬盘)\n"
|
||||
" - Винятки: числа/одиниці/оператори (200GB 硬盘 → 200GB 硬盘)\n"
|
||||
"\n"
|
||||
"# Вихідні дані\n"
|
||||
" - Повертати лише результат перекладу\n"
|
||||
@@ -1838,7 +1838,7 @@ msgstr ""
|
||||
" JP: \"Reactを使う\" → \"React を使う\"\n"
|
||||
" KO: \"Node.js설치\" → \"Node.js 설치\"\n"
|
||||
" TH: \"ติดตั้งPython3.9\" → \"ติดตั้ง Python 3.9\"\n"
|
||||
" - Винятки: числа/одиниці/оператори (200GB硬盘 → 200GB 硬盘)\n"
|
||||
" - Винятки: числа/одиниці/оператори (200GB 硬盘 → 200GB 硬盘)\n"
|
||||
"\n"
|
||||
"# Вихідні дані:\n"
|
||||
" - Повертати лише результат перекладу\n"
|
||||
|
||||
@@ -1891,7 +1891,7 @@ msgstr "DNS 域名"
|
||||
|
||||
#: src/views/dns/components/DNSRecordTable.vue:81
|
||||
msgid "DNS Only"
|
||||
msgstr "仅DNS"
|
||||
msgstr "仅 DNS"
|
||||
|
||||
#: src/components/AutoCertForm/DNSChallenge.vue:121
|
||||
#: src/views/dns/components/DNSChallenge.vue:60
|
||||
@@ -7107,7 +7107,7 @@ msgstr "升级器核心摘要为空"
|
||||
|
||||
#: src/constants/errors/upgrader.ts:2
|
||||
msgid "Upgrader core downloadUrl is empty"
|
||||
msgstr "升级器核心下载URL为空"
|
||||
msgstr "升级器核心下载 URL 为空"
|
||||
|
||||
#: src/views/node/BatchUpgrader.vue:88 src/views/system/Upgrade.vue:80
|
||||
msgid "Upgrading Nginx UI, please wait..."
|
||||
|
||||
@@ -1895,7 +1895,7 @@ msgstr "DNS 網域"
|
||||
|
||||
#: src/views/dns/components/DNSRecordTable.vue:81
|
||||
msgid "DNS Only"
|
||||
msgstr "僅DNS"
|
||||
msgstr "僅 DNS"
|
||||
|
||||
#: src/components/AutoCertForm/DNSChallenge.vue:121
|
||||
#: src/views/dns/components/DNSChallenge.vue:60
|
||||
@@ -4128,7 +4128,7 @@ msgstr "命名空間"
|
||||
msgid ""
|
||||
"Need more DNS providers? Support us through donations or contact us for "
|
||||
"commercial collaboration"
|
||||
msgstr "需要更多DNS供應商?透過捐贈支持我們或聯繫我們進行商業合作"
|
||||
msgstr "需要更多 DNS 供應商?透過捐贈支持我們或聯繫我們進行商業合作"
|
||||
|
||||
#: src/views/dashboard/NginxDashBoard.vue:195
|
||||
msgid "Need to enable the stub_status module"
|
||||
@@ -7113,7 +7113,7 @@ msgstr "升級器核心摘要為空"
|
||||
|
||||
#: src/constants/errors/upgrader.ts:2
|
||||
msgid "Upgrader core downloadUrl is empty"
|
||||
msgstr "升級器核心下載URL為空"
|
||||
msgstr "升級器核心下載 URL 為空"
|
||||
|
||||
#: src/views/node/BatchUpgrader.vue:88 src/views/system/Upgrade.vue:80
|
||||
msgid "Upgrading Nginx UI, please wait..."
|
||||
|
||||
Binary file not shown.
@@ -34,10 +34,16 @@ type ComponentInfo struct {
|
||||
func main() {
|
||||
log.Println("Generating license information...")
|
||||
|
||||
repoRoot, err := locateRepoRoot()
|
||||
if err != nil {
|
||||
log.Fatalf("Error locating repository root: %v", err)
|
||||
}
|
||||
log.Printf("INFO: Repository root resolved to %s", repoRoot)
|
||||
|
||||
var info ComponentInfo
|
||||
|
||||
// Generate backend licenses
|
||||
backendLicenses, err := generateBackendLicenses()
|
||||
backendLicenses, err := generateBackendLicenses(repoRoot)
|
||||
if err != nil {
|
||||
log.Printf("Error generating backend licenses: %v", err)
|
||||
} else {
|
||||
@@ -46,7 +52,7 @@ func main() {
|
||||
}
|
||||
|
||||
// Generate frontend licenses
|
||||
frontendLicenses, err := generateFrontendLicenses()
|
||||
frontendLicenses, err := generateFrontendLicenses(repoRoot)
|
||||
if err != nil {
|
||||
log.Printf("Error generating frontend licenses: %v", err)
|
||||
} else {
|
||||
@@ -83,7 +89,7 @@ func main() {
|
||||
compressed.Len(), float64(compressed.Len())/float64(len(jsonData))*100)
|
||||
|
||||
// Write compressed data to file
|
||||
outputPath := "internal/license/licenses.xz"
|
||||
outputPath := filepath.Join(repoRoot, "internal", "license", "licenses.xz")
|
||||
log.Printf("INFO: Writing compressed data to %s", outputPath)
|
||||
err = os.MkdirAll(filepath.Dir(outputPath), 0755)
|
||||
if err != nil {
|
||||
@@ -103,16 +109,19 @@ func main() {
|
||||
log.Printf(" - Output file: %s", outputPath)
|
||||
}
|
||||
|
||||
func generateBackendLicenses() ([]License, error) {
|
||||
func generateBackendLicenses(repoRoot string) ([]License, error) {
|
||||
var licenses []License
|
||||
|
||||
log.Println("INFO: Collecting backend Go modules...")
|
||||
|
||||
// Read go.mod file directly
|
||||
goModPath := "go.mod"
|
||||
goModPath := filepath.Join(repoRoot, "go.mod")
|
||||
if _, err := os.Stat(goModPath); err != nil {
|
||||
return nil, fmt.Errorf("failed to locate go.mod at %s: %v", goModPath, err)
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(goModPath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read go.mod: %v", err)
|
||||
return nil, fmt.Errorf("failed to read go.mod at %s: %v", goModPath, err)
|
||||
}
|
||||
|
||||
// Parse go.mod content to extract dependencies
|
||||
@@ -120,12 +129,12 @@ func generateBackendLicenses() ([]License, error) {
|
||||
lines := strings.Split(string(data), "\n")
|
||||
inRequireBlock := false
|
||||
inReplaceBlock := false
|
||||
|
||||
|
||||
replaceMap := make(map[string]string) // original -> replacement
|
||||
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
|
||||
// Handle require block
|
||||
if strings.HasPrefix(line, "require (") {
|
||||
inRequireBlock = true
|
||||
@@ -148,10 +157,10 @@ func generateBackendLicenses() ([]License, error) {
|
||||
if len(parts) == 2 {
|
||||
original := strings.TrimSpace(parts[0])
|
||||
replacement := strings.TrimSpace(parts[1])
|
||||
|
||||
|
||||
// Remove "replace " prefix if present
|
||||
original = strings.TrimPrefix(original, "replace ")
|
||||
|
||||
|
||||
// Extract module path (before version if present)
|
||||
if strings.Contains(original, " ") {
|
||||
original = strings.Fields(original)[0]
|
||||
@@ -159,7 +168,7 @@ func generateBackendLicenses() ([]License, error) {
|
||||
if strings.Contains(replacement, " ") {
|
||||
replacement = strings.Fields(replacement)[0]
|
||||
}
|
||||
|
||||
|
||||
replaceMap[original] = replacement
|
||||
}
|
||||
}
|
||||
@@ -170,13 +179,13 @@ func generateBackendLicenses() ([]License, error) {
|
||||
if inRequireBlock || strings.HasPrefix(line, "require ") {
|
||||
// Remove "require " prefix if present
|
||||
line = strings.TrimPrefix(line, "require ")
|
||||
|
||||
|
||||
// Remove comments
|
||||
if idx := strings.Index(line, "//"); idx != -1 {
|
||||
line = line[:idx]
|
||||
}
|
||||
line = strings.TrimSpace(line)
|
||||
|
||||
|
||||
if line == "" {
|
||||
continue
|
||||
}
|
||||
@@ -186,16 +195,16 @@ func generateBackendLicenses() ([]License, error) {
|
||||
if len(parts) >= 2 {
|
||||
path := parts[0]
|
||||
version := parts[1]
|
||||
|
||||
|
||||
if path == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
// Apply replacements if they exist
|
||||
if replacement, exists := replaceMap[path]; exists {
|
||||
path = replacement
|
||||
}
|
||||
|
||||
|
||||
depMap[path] = version
|
||||
}
|
||||
}
|
||||
@@ -303,13 +312,13 @@ func generateBackendLicenses() ([]License, error) {
|
||||
return licenses, nil
|
||||
}
|
||||
|
||||
func generateFrontendLicenses() ([]License, error) {
|
||||
func generateFrontendLicenses(repoRoot string) ([]License, error) {
|
||||
var licenses []License
|
||||
|
||||
log.Println("INFO: Collecting frontend npm packages...")
|
||||
|
||||
// Read package.json
|
||||
packagePath := "app/package.json"
|
||||
packagePath := filepath.Join(repoRoot, "app", "package.json")
|
||||
if _, err := os.Stat(packagePath); os.IsNotExist(err) {
|
||||
return nil, fmt.Errorf("package.json not found at %s", packagePath)
|
||||
}
|
||||
@@ -760,3 +769,48 @@ func getGoVersion() string {
|
||||
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
// locateRepoRoot returns the directory containing go.mod so relative paths stay stable.
|
||||
func locateRepoRoot() (string, error) {
|
||||
goModPath, err := locateGoModPath()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Dir(goModPath), nil
|
||||
}
|
||||
|
||||
// locateGoModPath finds the module root so the tool works from any working directory.
|
||||
func locateGoModPath() (string, error) {
|
||||
// Prefer go env GOMOD which respects module-aware mode.
|
||||
cmd := exec.Command("go", "env", "GOMOD")
|
||||
output, err := cmd.Output()
|
||||
if err == nil {
|
||||
path := strings.TrimSpace(string(output))
|
||||
if path != "" {
|
||||
if _, statErr := os.Stat(path); statErr == nil {
|
||||
return path, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: walk upwards from the current working directory.
|
||||
dir, err := os.Getwd()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for {
|
||||
candidate := filepath.Join(dir, "go.mod")
|
||||
if info, statErr := os.Stat(candidate); statErr == nil && !info.IsDir() {
|
||||
return candidate, nil
|
||||
}
|
||||
|
||||
parent := filepath.Dir(dir)
|
||||
if parent == dir {
|
||||
break
|
||||
}
|
||||
dir = parent
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("go.mod not found from current directory or parents")
|
||||
}
|
||||
|
||||
174
cmd/language_spacing/main.go
Normal file
174
cmd/language_spacing/main.go
Normal file
@@ -0,0 +1,174 @@
|
||||
//go:generate go run .
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
type fileReport struct {
|
||||
path string
|
||||
insertions int
|
||||
}
|
||||
|
||||
var (
|
||||
dryRun = flag.Bool("dry-run", false, "only report issues without modifying files")
|
||||
targetDir string
|
||||
rootDir string
|
||||
)
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
log.SetFlags(0)
|
||||
|
||||
if err := resolvePaths(); err != nil {
|
||||
log.Fatalf("resolve paths: %v", err)
|
||||
}
|
||||
|
||||
reports, totalInsertions, err := processDirectory(*dryRun)
|
||||
if err != nil {
|
||||
log.Fatalf("scan failed: %v", err)
|
||||
}
|
||||
|
||||
if len(reports) == 0 {
|
||||
log.Println("No spacing issues detected.")
|
||||
return
|
||||
}
|
||||
|
||||
for _, r := range reports {
|
||||
relative := r.path
|
||||
if rel, err := filepath.Rel(rootDir, r.path); err == nil {
|
||||
relative = rel
|
||||
}
|
||||
fmt.Printf("%s: inserted %d space(s)\n", relative, r.insertions)
|
||||
}
|
||||
|
||||
if *dryRun {
|
||||
log.Printf("Dry run complete. %d potential insertion(s) across %d file(s).", totalInsertions, len(reports))
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Completed fixes. Inserted %d space(s) across %d file(s).", totalInsertions, len(reports))
|
||||
}
|
||||
|
||||
func resolvePaths() error {
|
||||
_, file, _, ok := runtime.Caller(0)
|
||||
if !ok {
|
||||
return fmt.Errorf("unable to determine caller")
|
||||
}
|
||||
|
||||
rootDir = filepath.Clean(filepath.Join(filepath.Dir(file), "../.."))
|
||||
targetDir = filepath.Join(rootDir, "app/src/language")
|
||||
|
||||
info, err := os.Stat(targetDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("stat language directory: %w", err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
return fmt.Errorf("language path is not a directory: %s", targetDir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func processDirectory(dryRun bool) ([]fileReport, int, error) {
|
||||
reports := make([]fileReport, 0)
|
||||
totalInsertions := 0
|
||||
|
||||
err := filepath.Walk(targetDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if !isSupportedFile(path) {
|
||||
return nil
|
||||
}
|
||||
|
||||
original, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("read %s: %w", path, err)
|
||||
}
|
||||
|
||||
fixed, insertions := fixContent(string(original))
|
||||
if insertions == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if !dryRun {
|
||||
if err := os.WriteFile(path, []byte(fixed), info.Mode().Perm()); err != nil {
|
||||
return fmt.Errorf("write %s: %w", path, err)
|
||||
}
|
||||
}
|
||||
|
||||
reports = append(reports, fileReport{
|
||||
path: path,
|
||||
insertions: insertions,
|
||||
})
|
||||
totalInsertions += insertions
|
||||
return nil
|
||||
})
|
||||
|
||||
return reports, totalInsertions, err
|
||||
}
|
||||
|
||||
func isSupportedFile(path string) bool {
|
||||
switch strings.ToLower(filepath.Ext(path)) {
|
||||
case ".po", ".pot", ".ts":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func fixContent(text string) (string, int) {
|
||||
runes := []rune(text)
|
||||
if len(runes) == 0 {
|
||||
return text, 0
|
||||
}
|
||||
|
||||
var builder strings.Builder
|
||||
builder.Grow(len(runes) + 16)
|
||||
insertions := 0
|
||||
|
||||
for i := 0; i < len(runes); i++ {
|
||||
current := runes[i]
|
||||
builder.WriteRune(current)
|
||||
|
||||
if i == len(runes)-1 {
|
||||
break
|
||||
}
|
||||
|
||||
next := runes[i+1]
|
||||
if needsSpace(current, next) {
|
||||
builder.WriteRune(' ')
|
||||
insertions++
|
||||
}
|
||||
}
|
||||
|
||||
return builder.String(), insertions
|
||||
}
|
||||
|
||||
func needsSpace(left, right rune) bool {
|
||||
if isHan(left) && isASCIIAlphaNum(right) {
|
||||
return true
|
||||
}
|
||||
if isASCIIAlphaNum(left) && isHan(right) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func isHan(r rune) bool {
|
||||
return unicode.Is(unicode.Han, r)
|
||||
}
|
||||
|
||||
func isASCIIAlphaNum(r rune) bool {
|
||||
return r <= unicode.MaxASCII && ((r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9'))
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user