From d249bd5ac8731c48a0f0eb99af3ce7e09e3efd27 Mon Sep 17 00:00:00 2001 From: t8y2 <1156263951@qq.com> Date: Thu, 2 Jul 2026 19:55:17 +0800 Subject: [PATCH] feat(settings): add interface font selection --- apps/desktop/src/App.vue | 27 ++++- .../editor/EditorSettingsDialog.vue | 105 ++++++++++++++---- .../ui/searchable-select/SearchableSelect.vue | 6 +- apps/desktop/src/i18n/locales/en.ts | 4 + apps/desktop/src/i18n/locales/es.ts | 4 + apps/desktop/src/i18n/locales/it.ts | 4 + apps/desktop/src/i18n/locales/ja.ts | 4 + apps/desktop/src/i18n/locales/pt-BR.ts | 4 + apps/desktop/src/i18n/locales/zh-CN.ts | 4 + apps/desktop/src/i18n/locales/zh-TW.ts | 4 + apps/desktop/src/lib/appFonts.ts | 6 + apps/desktop/src/stores/settingsStore.ts | 15 ++- packages/app-tests/settingsStore.test.ts | 13 +++ 13 files changed, 175 insertions(+), 25 deletions(-) create mode 100644 apps/desktop/src/lib/appFonts.ts diff --git a/apps/desktop/src/App.vue b/apps/desktop/src/App.vue index b215bc6384..2c848be099 100644 --- a/apps/desktop/src/App.vue +++ b/apps/desktop/src/App.vue @@ -73,6 +73,7 @@ import { buildHistoryAiAnalysisPrompt } from "@/lib/historyAiAnalysis"; import { countAvailableAgentDriverUpdates, type AgentDriverUpdateBadgeState } from "@/lib/agentDriverUpdateBadge"; import { safeLocalStorageGet, safeLocalStorageSet } from "@/lib/safeStorage"; import { apiUrl, webPath } from "@/lib/webPath"; +import { APP_FONT_SANS_CSS_VAR, DEFAULT_UI_FONT_FAMILY } from "@/lib/appFonts"; import { rankSavedSqlHistory } from "@/lib/savedSqlHistory"; import { isSchemaAware, isSingleDatabase, usesTreeSchemaMode } from "@/lib/databaseFeatureSupport"; import { codeMirrorSqlDialect, connectionUsesDatabaseObjectTreeMode, effectiveDatabaseTypeForConnection } from "@/lib/jdbcDialect"; @@ -383,6 +384,22 @@ function resetUiZoom() { setGlobalUiScale(1); } +function applyUiFontFamily(fontFamily: string) { + if (typeof document === "undefined") return; + const next = fontFamily || DEFAULT_UI_FONT_FAMILY; + // Override Tailwind's shared sans variable so app chrome and existing UI classes stay in sync. + document.documentElement.style.setProperty(APP_FONT_SANS_CSS_VAR, next); + document.body.style.fontFamily = `var(${APP_FONT_SANS_CSS_VAR}, ${DEFAULT_UI_FONT_FAMILY})`; +} + +const appUiFontFamilyStyle = computed>(() => { + const fontFamily = settingsStore.editorSettings.uiFontFamily || DEFAULT_UI_FONT_FAMILY; + return { + [APP_FONT_SANS_CSS_VAR]: fontFamily, + fontFamily: `var(${APP_FONT_SANS_CSS_VAR}, ${DEFAULT_UI_FONT_FAMILY})`, + }; +}); + function isGlobalUiZoomTarget(target: EventTarget | null): target is Element { if (!(target instanceof Element)) return false; if (target.closest("[data-query-editor-root], [data-cell-detail-editor-root], [data-object-source-editor]")) { @@ -428,6 +445,14 @@ watch( { immediate: true }, ); +watch( + () => settingsStore.editorSettings.uiFontFamily, + (fontFamily) => { + applyUiFontFamily(fontFamily); + }, + { immediate: true }, +); + function toggleAiPanel() { showAiPanel.value = !showAiPanel.value; safeLocalStorageSet("dbx-ai-panel-open", String(showAiPanel.value)); @@ -1675,7 +1700,7 @@ onUnmounted(() => {
-
+
([...settingsStore.editorSettings.customThemes]); @@ -260,6 +262,9 @@ const systemFonts = ref([]); const systemFontsLoading = ref(false); const systemFontsLoaded = ref(false); const uiScaleOptions = [0.75, 0.9, 1, 1.1, 1.25, 1.5, 1.75, 2]; +const fontSearchTriggerClass = + "h-8 w-full max-w-none justify-between gap-1.5 rounded-[6px] border border-input bg-transparent py-2 pl-2.5 pr-2 text-sm font-normal shadow-none hover:bg-transparent focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-expanded:bg-transparent dark:bg-input/30 dark:hover:bg-input/50"; +const fontSearchTriggerIconClass = "size-4 text-muted-foreground"; const disconnectTabHandlingModeDescriptionKey = computed(() => { switch (editDisconnectTabHandlingMode.value) { case "close-tabs": @@ -425,6 +430,7 @@ function confirmDeleteSnippet(snippet: SqlSnippet) { const presetFontLabels = new Map(FONT_FAMILIES.map((font) => [font.value, font.label])); const presetFontValues = new Set(FONT_FAMILIES.map((font) => font.value)); +const uiFontPreviewValues = new Set([DEFAULT_UI_FONT_FAMILY, SYSTEM_UI_FONT_FAMILY]); function cssFontFamilyForName(name: string): string { return `'${name.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}', monospace`; @@ -449,12 +455,24 @@ const systemFontOptions = computed(() => { return [...options]; }); +const uiFontOptions = computed(() => { + const options = new Set([SYSTEM_UI_FONT_FAMILY, DEFAULT_UI_FONT_FAMILY, ...systemFontOptions.value]); + if (editUiFontFamily.value) options.add(editUiFontFamily.value); + return [...options]; +}); + function displayFontFamily(value: string): string { return presetFontLabels.get(value) ?? readableFontFamily(value); } -function fontOptionStyle(value: string) { - return presetFontValues.has(value) || value === editFontFamily.value ? { fontFamily: value } : undefined; +function displayUiFontFamily(value: string): string { + if (value === SYSTEM_UI_FONT_FAMILY) return t("settings.uiFontSystemDefault"); + if (value === DEFAULT_UI_FONT_FAMILY) return t("settings.uiFontAppDefault"); + return displayFontFamily(value); +} + +function fontOptionStyle(value: string, selectedValue = editFontFamily.value) { + return presetFontValues.has(value) || uiFontPreviewValues.has(value) || value === selectedValue ? { fontFamily: value } : undefined; } async function loadSystemFontOptions() { @@ -485,6 +503,7 @@ watch( if (open) { editFontFamily.value = settingsStore.editorSettings.fontFamily; editFontSize.value = settingsStore.editorSettings.fontSize; + editUiFontFamily.value = settingsStore.editorSettings.uiFontFamily; editUiScale.value = settingsStore.editorSettings.uiScale; editTheme.value = settingsStore.editorSettings.theme; editCustomThemes.value = [...settingsStore.editorSettings.customThemes]; @@ -553,6 +572,7 @@ function hasChanges(): boolean { return ( editFontFamily.value !== settingsStore.editorSettings.fontFamily || editFontSize.value !== settingsStore.editorSettings.fontSize || + editUiFontFamily.value !== settingsStore.editorSettings.uiFontFamily || editUiScale.value !== settingsStore.editorSettings.uiScale || editTheme.value !== settingsStore.editorSettings.theme || JSON.stringify(editCustomThemes.value) !== JSON.stringify(settingsStore.editorSettings.customThemes) || @@ -607,6 +627,7 @@ async function persistSettings() { settingsStore.updateEditorSettings({ fontFamily: editFontFamily.value, fontSize: editFontSize.value, + uiFontFamily: editUiFontFamily.value, uiScale: editUiScale.value, theme: editTheme.value, customThemes: editCustomThemes.value, @@ -687,6 +708,7 @@ function resetDefaultsForTab(tab: SettingsCategory) { editSqlFormatter.value = normalizeSqlFormatterSettings(DEFAULT_EDITOR_SETTINGS.sqlFormatter); sqlFormatterConfigValid.value = true; } else if (tab === "appearance") { + editUiFontFamily.value = DEFAULT_EDITOR_SETTINGS.uiFontFamily; editUiScale.value = DEFAULT_EDITOR_SETTINGS.uiScale; editTheme.value = DEFAULT_EDITOR_SETTINGS.theme; editCustomThemes.value = [...DEFAULT_EDITOR_SETTINGS.customThemes]; @@ -734,6 +756,7 @@ function resetDefaultsForTab(tab: SettingsCategory) { function resetAllDefaults() { editFontFamily.value = DEFAULT_EDITOR_SETTINGS.fontFamily; editFontSize.value = DEFAULT_EDITOR_SETTINGS.fontSize; + editUiFontFamily.value = DEFAULT_EDITOR_SETTINGS.uiFontFamily; editUiScale.value = DEFAULT_EDITOR_SETTINGS.uiScale; editTheme.value = DEFAULT_EDITOR_SETTINGS.theme; editCustomThemes.value = [...DEFAULT_EDITOR_SETTINGS.customThemes]; @@ -919,6 +942,10 @@ function onFontFamilyChange(v: any) { if (typeof v === "string") editFontFamily.value = v; } +function onUiFontFamilyChange(v: any) { + if (typeof v === "string") editUiFontFamily.value = v; +} + const themeSelectValue = computed(() => { if (editTheme.value === "custom") { return `custom:${editActiveCustomThemeId.value}`; @@ -2044,7 +2071,8 @@ onUnmounted(cleanupPreviewEditor); allow-custom :display-name="displayFontFamily" :normalize-custom="normalizeCustomFontFamilyInput" - trigger-class="h-9 w-full max-w-none justify-between border bg-background px-3 text-sm shadow-xs hover:bg-accent" + :trigger-class="fontSearchTriggerClass" + :trigger-icon-class="fontSearchTriggerIconClass" content-class="w-[var(--reka-popover-trigger-width)] min-w-[260px]" @update:model-value="onFontFamilyChange" @update:open="(open: boolean) => open && loadSystemFontOptions()" @@ -2260,23 +2288,60 @@ onUnmounted(cleanupPreviewEditor);
-
- - +
+
+ + +
+ +
+ + + + + + +

{{ t("settings.uiFontFamilyDescription") }}

+
diff --git a/apps/desktop/src/components/ui/searchable-select/SearchableSelect.vue b/apps/desktop/src/components/ui/searchable-select/SearchableSelect.vue index 7fbce29880..4fc580527c 100644 --- a/apps/desktop/src/components/ui/searchable-select/SearchableSelect.vue +++ b/apps/desktop/src/components/ui/searchable-select/SearchableSelect.vue @@ -22,6 +22,7 @@ const props = withDefaults( allowCustom?: boolean; triggerVariant?: ButtonVariants["variant"]; triggerClass?: HTMLAttributes["class"]; + triggerIconClass?: HTMLAttributes["class"]; contentClass?: HTMLAttributes["class"]; itemClass?: HTMLAttributes["class"]; displayName?: (option: string) => string; @@ -35,6 +36,7 @@ const props = withDefaults( clearable: false, loadingText: "Loading...", triggerVariant: "ghost", + triggerIconClass: "h-3 w-3", displayName: (option: string) => option, normalizeCustom: (value: string) => value, }, @@ -158,8 +160,8 @@ function handleKeydown(event: KeyboardEvent) { {{ loading ? loadingText : selectedLabel }} - - + + diff --git a/apps/desktop/src/i18n/locales/en.ts b/apps/desktop/src/i18n/locales/en.ts index 0da5f520f2..ae2e0ef7f1 100644 --- a/apps/desktop/src/i18n/locales/en.ts +++ b/apps/desktop/src/i18n/locales/en.ts @@ -2591,6 +2591,10 @@ export default { securityTab: "Security", aboutTab: "About", fontFamily: "Font Family", + uiFontFamily: "Interface Font", + uiFontAppDefault: "DBX Default", + uiFontSystemDefault: "System Default", + uiFontFamilyDescription: "Applies to app chrome such as the toolbar, tabs, sidebar, dialogs, and other non-editor UI.", selectFont: "Select font...", searchFont: "Search fonts...", loadingFonts: "Loading fonts...", diff --git a/apps/desktop/src/i18n/locales/es.ts b/apps/desktop/src/i18n/locales/es.ts index db49421e46..11449f965d 100644 --- a/apps/desktop/src/i18n/locales/es.ts +++ b/apps/desktop/src/i18n/locales/es.ts @@ -2594,6 +2594,10 @@ export default withEnglishFallback({ securityTab: "Seguridad", aboutTab: "Acerca de", fontFamily: "Familia tipográfica", + uiFontFamily: "Fuente de la interfaz", + uiFontAppDefault: "Predeterminada de DBX", + uiFontSystemDefault: "Predeterminada del sistema", + uiFontFamilyDescription: "Se aplica a la barra superior, pestañas, barra lateral, diálogos y demás UI fuera del editor.", selectFont: "Seleccionar fuente...", searchFont: "Buscar fuentes...", loadingFonts: "Cargando fuentes...", diff --git a/apps/desktop/src/i18n/locales/it.ts b/apps/desktop/src/i18n/locales/it.ts index b8fe034d0e..0a857b8e77 100644 --- a/apps/desktop/src/i18n/locales/it.ts +++ b/apps/desktop/src/i18n/locales/it.ts @@ -2592,6 +2592,10 @@ export default withEnglishFallback({ securityTab: "Sicurezza", aboutTab: "Informazioni", fontFamily: "Famiglia Carattere (Font)", + uiFontFamily: "Carattere interfaccia", + uiFontAppDefault: "Predefinito DBX", + uiFontSystemDefault: "Predefinito di sistema", + uiFontFamilyDescription: "Si applica a barra strumenti, schede, barra laterale, finestre di dialogo e altra UI fuori dall'editor.", selectFont: "Seleziona font...", searchFont: "Cerca font...", loadingFonts: "Caricamento font...", diff --git a/apps/desktop/src/i18n/locales/ja.ts b/apps/desktop/src/i18n/locales/ja.ts index 74823f5a95..86a62b239e 100644 --- a/apps/desktop/src/i18n/locales/ja.ts +++ b/apps/desktop/src/i18n/locales/ja.ts @@ -2592,6 +2592,10 @@ export default withEnglishFallback({ securityTab: "セキュリティ", aboutTab: "バージョン情報", fontFamily: "フォントファミリー", + uiFontFamily: "インターフェイスフォント", + uiFontAppDefault: "DBX デフォルト", + uiFontSystemDefault: "システムデフォルト", + uiFontFamilyDescription: "ツールバー、タブ、サイドバー、ダイアログなど、エディター以外のUIに適用します。", selectFont: "フォントを選択...", searchFont: "フォントを検索...", loadingFonts: "フォントを読み込み中...", diff --git a/apps/desktop/src/i18n/locales/pt-BR.ts b/apps/desktop/src/i18n/locales/pt-BR.ts index edf319cd37..8e84fedbe9 100644 --- a/apps/desktop/src/i18n/locales/pt-BR.ts +++ b/apps/desktop/src/i18n/locales/pt-BR.ts @@ -2593,6 +2593,10 @@ export default withEnglishFallback({ securityTab: "Segurança", aboutTab: "Sobre", fontFamily: "Família da fonte", + uiFontFamily: "Fonte da interface", + uiFontAppDefault: "Padrão do DBX", + uiFontSystemDefault: "Padrão do sistema", + uiFontFamilyDescription: "Aplica-se à barra superior, abas, barra lateral, diálogos e demais UI fora do editor.", selectFont: "Selecionar fonte...", searchFont: "Pesquisar fontes...", loadingFonts: "Carregando fontes...", diff --git a/apps/desktop/src/i18n/locales/zh-CN.ts b/apps/desktop/src/i18n/locales/zh-CN.ts index 6853c4b31f..8d5f23b426 100644 --- a/apps/desktop/src/i18n/locales/zh-CN.ts +++ b/apps/desktop/src/i18n/locales/zh-CN.ts @@ -2593,6 +2593,10 @@ export default withEnglishFallback({ securityTab: "安全", aboutTab: "关于我们", fontFamily: "字体", + uiFontFamily: "界面字体", + uiFontAppDefault: "DBX 默认", + uiFontSystemDefault: "系统默认", + uiFontFamilyDescription: "用于顶部栏、标签页、侧边栏、弹窗等非编辑器界面。", selectFont: "选择字体...", searchFont: "搜索字体...", loadingFonts: "正在加载字体...", diff --git a/apps/desktop/src/i18n/locales/zh-TW.ts b/apps/desktop/src/i18n/locales/zh-TW.ts index 4134e842a4..51669372de 100644 --- a/apps/desktop/src/i18n/locales/zh-TW.ts +++ b/apps/desktop/src/i18n/locales/zh-TW.ts @@ -2495,6 +2495,10 @@ export default withEnglishFallback({ aboutTab: "關於我們", dataTab: "資料", fontFamily: "字型", + uiFontFamily: "介面字型", + uiFontAppDefault: "DBX 預設", + uiFontSystemDefault: "系統預設", + uiFontFamilyDescription: "套用於工具列、分頁、側邊欄、對話框等非編輯器介面。", selectFont: "選擇字型……", searchFont: "搜尋字型……", loadingFonts: "正在載入字型……", diff --git a/apps/desktop/src/lib/appFonts.ts b/apps/desktop/src/lib/appFonts.ts new file mode 100644 index 0000000000..47bd7584bc --- /dev/null +++ b/apps/desktop/src/lib/appFonts.ts @@ -0,0 +1,6 @@ +export const APP_FONT_SANS_CSS_VAR = "--font-sans"; + +export const DEFAULT_UI_FONT_FAMILY = `"Geist Variable", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Segoe UI", system-ui, sans-serif`; + +// Native-feeling UI option without DBX's bundled/brand font at the front of the stack. +export const SYSTEM_UI_FONT_FAMILY = `system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif`; diff --git a/apps/desktop/src/stores/settingsStore.ts b/apps/desktop/src/stores/settingsStore.ts index e1cf70cd27..8664bebe49 100644 --- a/apps/desktop/src/stores/settingsStore.ts +++ b/apps/desktop/src/stores/settingsStore.ts @@ -11,6 +11,7 @@ import type { SqlSnippet } from "@/types/database"; import { DEFAULT_SQL_SNIPPETS } from "@/lib/sqlCompletion"; import { setDebugLoggingEnabled } from "@/lib/debugLog"; import { DEFAULT_TABLE_COLUMN_TEMPLATE_FIELDS, normalizeTableColumnTemplateFields } from "@/lib/tableColumnTemplates"; +import { DEFAULT_UI_FONT_FAMILY } from "@/lib/appFonts"; export type AiProvider = "claude" | "openai" | "gemini" | "deepseek" | "qwen" | "ollama" | "openai-compatible" | "codex-cli" | "custom"; export type AiApiStyle = "completions" | "responses" | "anthropic-messages"; @@ -324,6 +325,7 @@ export const DEFAULT_CUSTOM_THEMES: CustomTheme[] = [{ id: "default", name: "Cus export interface EditorSettings { fontFamily: string; fontSize: number; + uiFontFamily: string; uiScale: number; theme: EditorTheme; customThemeColors: CustomThemeColors; @@ -435,6 +437,7 @@ export const FONT_FAMILIES: { value: string; label: string }[] = [ export const DEFAULT_EDITOR_SETTINGS: EditorSettings = { fontFamily: "'JetBrains Mono', 'Fira Code', monospace", fontSize: 13, + uiFontFamily: DEFAULT_UI_FONT_FAMILY, uiScale: 1, theme: "app", customThemeColors: { ...DEFAULT_CUSTOM_THEME_COLORS }, @@ -501,6 +504,12 @@ function normalizeUiScale(value: unknown): number { return Math.min(MAX_UI_SCALE, Math.max(MIN_UI_SCALE, Math.round(value * 100) / 100)); } +function normalizeFontFamily(value: unknown, fallback: string): string { + if (typeof value !== "string") return fallback; + const trimmed = value.trim(); + return trimmed || fallback; +} + function normalizeDrawerWidth(value: unknown, min: number, fallback: number): number { if (typeof value !== "number" || !Number.isFinite(value)) return fallback; return Math.min(900, Math.max(min, Math.round(value))); @@ -615,8 +624,9 @@ function normalizeToolbarItems(items: Partial | undefined): Toolba export function normalizeEditorSettings(settings: Partial, existing?: EditorSettings): EditorSettings { const sqlSemanticDiagnosticsMode = normalizeSqlSemanticDiagnosticsMode(settings.sqlSemanticDiagnosticsMode, settings.sqlSemanticDiagnosticsEnabled); return { - fontFamily: settings.fontFamily ?? DEFAULT_EDITOR_SETTINGS.fontFamily, + fontFamily: normalizeFontFamily(settings.fontFamily, DEFAULT_EDITOR_SETTINGS.fontFamily), fontSize: settings.fontSize ?? DEFAULT_EDITOR_SETTINGS.fontSize, + uiFontFamily: normalizeFontFamily(settings.uiFontFamily, DEFAULT_EDITOR_SETTINGS.uiFontFamily), uiScale: normalizeUiScale(settings.uiScale), theme: settings.theme && EDITOR_THEME_VALUES.has(settings.theme) ? settings.theme : DEFAULT_EDITOR_SETTINGS.theme, customThemeColors: { @@ -838,8 +848,9 @@ export const useSettingsStore = defineStore("settings", () => { } function updateEditorSettings(partial: Partial) { - if (partial.fontFamily !== undefined) editorSettings.value.fontFamily = partial.fontFamily; + if (partial.fontFamily !== undefined) editorSettings.value.fontFamily = normalizeFontFamily(partial.fontFamily, DEFAULT_EDITOR_SETTINGS.fontFamily); if (partial.fontSize !== undefined) editorSettings.value.fontSize = partial.fontSize; + if (partial.uiFontFamily !== undefined) editorSettings.value.uiFontFamily = normalizeFontFamily(partial.uiFontFamily, DEFAULT_EDITOR_SETTINGS.uiFontFamily); if (partial.uiScale !== undefined) editorSettings.value.uiScale = normalizeUiScale(partial.uiScale); if (partial.theme !== undefined) editorSettings.value.theme = partial.theme; if (partial.customThemeColors !== undefined) { diff --git a/packages/app-tests/settingsStore.test.ts b/packages/app-tests/settingsStore.test.ts index fd04726787..fb3c81ac90 100644 --- a/packages/app-tests/settingsStore.test.ts +++ b/packages/app-tests/settingsStore.test.ts @@ -3,6 +3,7 @@ import assert from "node:assert/strict"; import { createPinia, setActivePinia } from "pinia"; import { DEFAULT_SQL_FORMATTER_SETTINGS } from "../../apps/desktop/src/lib/sqlFormatterConfig.ts"; import { DEFAULT_TABLE_COLUMN_TEMPLATE_FIELDS } from "../../apps/desktop/src/lib/tableColumnTemplates.ts"; +import { DEFAULT_UI_FONT_FAMILY, SYSTEM_UI_FONT_FAMILY } from "../../apps/desktop/src/lib/appFonts.ts"; import { AI_PROVIDER_PRESETS, DEFAULT_EDITOR_SETTINGS, normalizeAiConfig, normalizeEditorSettings, useSettingsStore } from "../../apps/desktop/src/stores/settingsStore.ts"; const OLD_FONT_SIZE_KEY = "dbx-query-editor-font-size"; @@ -101,6 +102,18 @@ test("normalizes editor theme settings", () => { assert.equal(normalizeEditorSettings({ theme: "invalid" as any }).theme, DEFAULT_EDITOR_SETTINGS.theme); }); +test("defaults UI font family to the app sans stack", () => { + assert.equal(DEFAULT_EDITOR_SETTINGS.uiFontFamily, DEFAULT_UI_FONT_FAMILY); + assert.equal(normalizeEditorSettings({}).uiFontFamily, DEFAULT_UI_FONT_FAMILY); + assert.equal(normalizeEditorSettings({ uiFontFamily: "" as any }).uiFontFamily, DEFAULT_UI_FONT_FAMILY); +}); + +test("keeps saved UI font family", () => { + const uiFontFamily = `"Aptos", system-ui, sans-serif`; + assert.equal(normalizeEditorSettings({ uiFontFamily } as any).uiFontFamily, uiFontFamily); + assert.equal(normalizeEditorSettings({ uiFontFamily: SYSTEM_UI_FONT_FAMILY } as any).uiFontFamily, SYSTEM_UI_FONT_FAMILY); +}); + test("defaults dangerous SQL confirmation to enabled", () => { assert.equal(DEFAULT_EDITOR_SETTINGS.confirmDangerousSqlExecution, true); assert.equal(normalizeEditorSettings({}).confirmDangerousSqlExecution, true);