fix: validate and type source viewer response fields

This commit is contained in:
VAIO73
2026-10-21 08:56:56 +00:00
parent 08d2b22c14
commit 0d7c4554bc
3 changed files with 13 additions and 4 deletions
+3 -3
View File
@@ -19,7 +19,7 @@ import { SUPPORTED_LANGUAGES, useI18n } from "../lib/i18n/provider"
import { useIsPbs } from "../lib/use-platform"
import type { LanguageCode } from "../lib/i18n/languages"
import { NavTabOrderCard } from "./nav-tab-order-card"
import { optimizationSourceError, type OptimizationSourceError } from "../lib/optimization-source-errors"
import { optimizationSourceError, type OptimizationSourceError, type OptimizationSourceResponse } from "../lib/optimization-source-errors"
// GitHub Dark color palette for bash syntax highlighting
const BASH_KEYWORDS = new Set([
@@ -694,9 +694,9 @@ export function Settings() {
deprecated: !!tool.deprecated,
})
try {
const data = await fetchApi(`/api/proxmenux/tool-source/${tool.key}`)
const data = await fetchApi<OptimizationSourceResponse | null>(`/api/proxmenux/tool-source/${tool.key}`)
if (request !== codeRequest.current) return
if (data?.success && typeof data.source === "string" && data.source.trim()) {
if (data?.success === true && typeof data.source === "string" && data.source.trim()) {
setCodeModal(prev => ({ ...prev, loading: false, functionName: typeof data.function === "string" ? data.function : '', source: data.source, script: typeof data.script === "string" ? data.script : '', deprecated: !!data.deprecated }))
} else {
setCodeModal(prev => ({ ...prev, loading: false, error: { kind: "unavailable", detail: typeof data?.error === "string" ? data.error : undefined } }))
@@ -5,6 +5,15 @@ export interface OptimizationSourceError {
detail?: string
}
export interface OptimizationSourceResponse {
success?: unknown
source?: unknown
function?: unknown
script?: unknown
deprecated?: unknown
error?: unknown
}
// Keep the blueprint's English API contract intact; translate only its display.
export function optimizationSourceError(error: OptimizationSourceError, t: Translate): string {
const detail = error.detail || ""
+1 -1
View File
@@ -67,7 +67,7 @@ async function main(){
for(const locale of ['en','sk','de']){
const f=fixture(locale);f.render();await f.settle()
for(const [reply,key,param]of [
[{success:false},'sourceUnavailable'],[null,'sourceUnavailable'],[{success:true,source:''},'sourceUnavailable'],[{success:true,source:' '},'sourceUnavailable'],[{success:true,source:17},'sourceUnavailable'],
[{success:false},'sourceUnavailable'],[null,'sourceUnavailable'],[{success:'yes',source:'invalid'},'sourceUnavailable'],[{success:true,source:''},'sourceUnavailable'],[{success:true,source:' '},'sourceUnavailable'],[{success:true,source:17},'sourceUnavailable'],
[{http:404,body:{success:false,error:'Function not found in available scripts'}},'sourceFunctionMissing'],
[{http:404,body:{success:false,error:'Unknown tool: demo'}},'sourceUnknownTool',{tool:'demo'}],
[{http:404,body:{success:false,error:'No function mapping for demo'}},'sourceNoMapping',{tool:'demo'}],