Fix Hytale prometheus metrics and config editor syntax highlighting
All checks were successful
Deploy GSM / deploy (push) Successful in 27s
All checks were successful
Deploy GSM / deploy (push) Successful in 27s
- Add missing "hytale" entry to SERVER_JOBS in prometheus.js - Fix config editor regex bug that was corrupting CSS class names (e.g. text-cyan-400 becoming text-cyan-<span>400</span>) - Use placeholder tokens to prevent numbers regex from matching inside already-replaced spans Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,8 @@ const SERVER_JOBS = {
|
||||
"zomboid": "zomboid",
|
||||
"palworld": "palworld",
|
||||
"terraria": "terraria",
|
||||
"openttd": "openttd"
|
||||
"openttd": "openttd",
|
||||
"hytale": "hytale"
|
||||
};
|
||||
|
||||
export async function queryPrometheus(query) {
|
||||
|
||||
@@ -83,24 +83,44 @@ export default function HytaleConfigEditor({ token }) {
|
||||
function highlightSyntax(text) {
|
||||
if (!text) return ''
|
||||
|
||||
return text
|
||||
// Escape HTML first
|
||||
let result = text
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
// Strings
|
||||
.replace(/"([^"\\]|\\.)*"/g, (match) => {
|
||||
// Check if it's a key (followed by :)
|
||||
if (match.endsWith('"') && text.indexOf(match + ':') !== -1) {
|
||||
return `<span class="text-blue-400">${match}</span>`
|
||||
}
|
||||
return `<span class="text-amber-300">${match}</span>`
|
||||
})
|
||||
// Numbers
|
||||
.replace(/\b(-?\d+\.?\d*)\b/g, '<span class="text-cyan-400">$1</span>')
|
||||
// Booleans and null
|
||||
.replace(/\b(true|false|null)\b/g, '<span class="text-purple-400">$1</span>')
|
||||
// Brackets
|
||||
.replace(/([{}\[\]])/g, '<span class="text-gray-500">$1</span>')
|
||||
|
||||
// Use placeholder tokens to avoid regex conflicts
|
||||
const tokens = []
|
||||
let tokenIndex = 0
|
||||
|
||||
// Replace strings with placeholders
|
||||
result = result.replace(/"([^"\\]|\\.)*"/g, (match) => {
|
||||
const isKey = result.indexOf(match + ':') !== -1
|
||||
const className = isKey ? 'text-blue-400' : 'text-amber-300'
|
||||
tokens.push(`<span class="${className}">${match}</span>`)
|
||||
return `\x00${tokenIndex++}\x00`
|
||||
})
|
||||
|
||||
// Replace booleans and null
|
||||
result = result.replace(/\b(true|false|null)\b/g, (match) => {
|
||||
tokens.push(`<span class="text-purple-400">${match}</span>`)
|
||||
return `\x00${tokenIndex++}\x00`
|
||||
})
|
||||
|
||||
// Replace numbers (only standalone, not inside placeholders)
|
||||
result = result.replace(/(?<!\x00)(-?\d+\.?\d*)(?!\x00)/g, (match) => {
|
||||
if (match === '' || match === '-') return match
|
||||
tokens.push(`<span class="text-cyan-400">${match}</span>`)
|
||||
return `\x00${tokenIndex++}\x00`
|
||||
})
|
||||
|
||||
// Replace brackets
|
||||
result = result.replace(/([{}\[\]])/g, '<span class="text-gray-500">$1</span>')
|
||||
|
||||
// Restore tokens
|
||||
result = result.replace(/\x00(\d+)\x00/g, (_, idx) => tokens[parseInt(idx)])
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
|
||||
Reference in New Issue
Block a user