From ddf98bdf28daefc75c5a33490cd83ce499bd9030 Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Wed, 26 Nov 2025 15:36:09 +0100 Subject: [PATCH] refactor: Improve API header management via utility functions --- tools/server/webui/src/lib/services/chat.ts | 24 ++++--------------- tools/server/webui/src/lib/services/models.ts | 22 +++++------------ tools/server/webui/src/lib/services/props.ts | 16 +++---------- .../server/webui/src/lib/utils/api-headers.ts | 22 +++++++++++++++++ 4 files changed, 35 insertions(+), 49 deletions(-) create mode 100644 tools/server/webui/src/lib/utils/api-headers.ts diff --git a/tools/server/webui/src/lib/services/chat.ts b/tools/server/webui/src/lib/services/chat.ts index 49ec160db4..1225b3eda0 100644 --- a/tools/server/webui/src/lib/services/chat.ts +++ b/tools/server/webui/src/lib/services/chat.ts @@ -1,4 +1,5 @@ import { config } from '$lib/stores/settings.svelte'; +import { getJsonHeaders } from '$lib/utils/api-headers'; import { selectedModelName } from '$lib/stores/models.svelte'; import { isRouterMode, propsStore } from '$lib/stores/props.svelte'; import type { @@ -201,14 +202,9 @@ export class ChatService { } try { - const apiKey = currentConfig.apiKey?.toString().trim(); - const response = await fetch(`./v1/chat/completions`, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - }, + headers: getJsonHeaders(), body: JSON.stringify(requestBody), signal: abortController.signal }); @@ -706,14 +702,8 @@ export class ChatService { */ static async getServerProps(): Promise { try { - const currentConfig = config(); - const apiKey = currentConfig.apiKey?.toString().trim(); - const response = await fetch(`./props`, { - headers: { - 'Content-Type': 'application/json', - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - } + headers: getJsonHeaders() }); if (!response.ok) { @@ -733,14 +723,8 @@ export class ChatService { */ static async getModels(): Promise { try { - const currentConfig = config(); - const apiKey = currentConfig.apiKey?.toString().trim(); - const response = await fetch(`./models`, { - headers: { - 'Content-Type': 'application/json', - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - } + headers: getJsonHeaders() }); if (!response.ok) { diff --git a/tools/server/webui/src/lib/services/models.ts b/tools/server/webui/src/lib/services/models.ts index 2374036b68..bf248453ab 100644 --- a/tools/server/webui/src/lib/services/models.ts +++ b/tools/server/webui/src/lib/services/models.ts @@ -1,6 +1,6 @@ import { base } from '$app/paths'; -import { config } from '$lib/stores/settings.svelte'; import { ServerModelStatus } from '$lib/enums'; +import { getJsonHeaders } from '$lib/utils/api-headers'; import type { ApiModelListResponse, ApiModelDataEntry, @@ -26,16 +26,6 @@ import type { * - ModelsStore: Primary consumer for model state management */ export class ModelsService { - private static getHeaders(): Record { - const currentConfig = config(); - const apiKey = currentConfig.apiKey?.toString().trim(); - - return { - 'Content-Type': 'application/json', - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - }; - } - // ───────────────────────────────────────────────────────────────────────────── // MODEL + ROUTER mode - OpenAI-compatible API // ───────────────────────────────────────────────────────────────────────────── @@ -46,7 +36,7 @@ export class ModelsService { */ static async list(): Promise { const response = await fetch(`${base}/v1/models`, { - headers: this.getHeaders() + headers: getJsonHeaders() }); if (!response.ok) { @@ -66,7 +56,7 @@ export class ModelsService { */ static async listRouter(): Promise { const response = await fetch(`${base}/models`, { - headers: this.getHeaders() + headers: getJsonHeaders() }); if (!response.ok) { @@ -90,7 +80,7 @@ export class ModelsService { const response = await fetch(`${base}/models/load`, { method: 'POST', - headers: this.getHeaders(), + headers: getJsonHeaders(), body: JSON.stringify(payload) }); @@ -110,7 +100,7 @@ export class ModelsService { static async unload(modelId: string): Promise { const response = await fetch(`${base}/models/unload`, { method: 'POST', - headers: this.getHeaders(), + headers: getJsonHeaders(), body: JSON.stringify({ model: modelId }) }); @@ -128,7 +118,7 @@ export class ModelsService { */ static async getStatus(modelId: string): Promise { const response = await fetch(`${base}/models/status?model=${encodeURIComponent(modelId)}`, { - headers: this.getHeaders() + headers: getJsonHeaders() }); if (!response.ok) { diff --git a/tools/server/webui/src/lib/services/props.ts b/tools/server/webui/src/lib/services/props.ts index bc0dd7a965..80e1574b78 100644 --- a/tools/server/webui/src/lib/services/props.ts +++ b/tools/server/webui/src/lib/services/props.ts @@ -1,4 +1,4 @@ -import { config } from '$lib/stores/settings.svelte'; +import { getAuthHeaders } from '$lib/utils/api-headers'; /** * PropsService - Server properties management @@ -22,13 +22,8 @@ export class PropsService { * @throws {Error} If the request fails or returns invalid data */ static async fetch(): Promise { - const currentConfig = config(); - const apiKey = currentConfig.apiKey?.toString().trim(); - const response = await fetch('./props', { - headers: { - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - } + headers: getAuthHeaders() }); if (!response.ok) { @@ -49,16 +44,11 @@ export class PropsService { * @throws {Error} If the request fails or returns invalid data */ static async fetchForModel(modelId: string): Promise { - const currentConfig = config(); - const apiKey = currentConfig.apiKey?.toString().trim(); - const url = new URL('./props', window.location.href); url.searchParams.set('model', modelId); const response = await fetch(url.toString(), { - headers: { - ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}) - } + headers: getAuthHeaders() }); if (!response.ok) { diff --git a/tools/server/webui/src/lib/utils/api-headers.ts b/tools/server/webui/src/lib/utils/api-headers.ts new file mode 100644 index 0000000000..77ce3e88cb --- /dev/null +++ b/tools/server/webui/src/lib/utils/api-headers.ts @@ -0,0 +1,22 @@ +import { config } from '$lib/stores/settings.svelte'; + +/** + * Get authorization headers for API requests + * Includes Bearer token if API key is configured + */ +export function getAuthHeaders(): Record { + const currentConfig = config(); + const apiKey = currentConfig.apiKey?.toString().trim(); + + return apiKey ? { Authorization: `Bearer ${apiKey}` } : {}; +} + +/** + * Get standard JSON headers with optional authorization + */ +export function getJsonHeaders(): Record { + return { + 'Content-Type': 'application/json', + ...getAuthHeaders() + }; +}