72 lines · 2.5 KB · TypeScript
RawDownload
import { ServerSettings, type ServerSettingsPatch } from "@t3tools/contracts";import { Schema } from "effect";import { deepMerge } from "./Struct.ts";import { fromLenientJson } from "./schemaJson.ts"; const ServerSettingsJson = fromLenientJson(ServerSettings); export interface PersistedServerObservabilitySettings {  readonly otlpTracesUrl: string | undefined;  readonly otlpMetricsUrl: string | undefined;} export function normalizePersistedServerSettingString(  value: string | null | undefined,): string | undefined {  const trimmed = value?.trim();  return trimmed && trimmed.length > 0 ? trimmed : undefined;} export function extractPersistedServerObservabilitySettings(input: {  readonly observability?: {    readonly otlpTracesUrl?: string;    readonly otlpMetricsUrl?: string;  };}): PersistedServerObservabilitySettings {  return {    otlpTracesUrl: normalizePersistedServerSettingString(input.observability?.otlpTracesUrl),    otlpMetricsUrl: normalizePersistedServerSettingString(input.observability?.otlpMetricsUrl),  };} export function parsePersistedServerObservabilitySettings(  raw: string,): PersistedServerObservabilitySettings {  try {    const decoded = Schema.decodeUnknownSync(ServerSettingsJson)(raw);    return extractPersistedServerObservabilitySettings(decoded);  } catch {    return { otlpTracesUrl: undefined, otlpMetricsUrl: undefined };  }} function shouldReplaceTextGenerationModelSelection(  patch: ServerSettingsPatch["textGenerationModelSelection"] | undefined,): boolean {  return Boolean(patch && (patch.provider !== undefined || patch.model !== undefined));} /** * Applies a server settings patch while treating textGenerationModelSelection as * replace-on-provider/model updates. This prevents stale nested options from * surviving a reset patch that intentionally omits options. */export function applyServerSettingsPatch(  current: ServerSettings,  patch: ServerSettingsPatch,): ServerSettings {  const selectionPatch = patch.textGenerationModelSelection;  const next = deepMerge(current, patch);  if (!selectionPatch || !shouldReplaceTextGenerationModelSelection(selectionPatch)) {    return next;  }   return {    ...next,    textGenerationModelSelection: {      provider: selectionPatch.provider ?? current.textGenerationModelSelection.provider,      model: selectionPatch.model ?? current.textGenerationModelSelection.model,      ...(selectionPatch.options ? { options: selectionPatch.options } : {}),    },  };}