diff --git a/src/lib/components/Actions.svelte b/src/lib/components/Actions.svelte index 983e6618..ffcfc534 100644 --- a/src/lib/components/Actions.svelte +++ b/src/lib/components/Actions.svelte @@ -199,7 +199,10 @@ ${svgString}`); }; }; - const onCopyClipboard = async (event: Event) => { + const onCopyClipboard = async (event?: Event) => { + if (!event) { + return; + } await exportImage(event, clipboardCopy); logEvent('copyClipboard'); }; diff --git a/src/lib/components/DesktopEditor.svelte b/src/lib/components/DesktopEditor.svelte index e945a1fa..df31818f 100644 --- a/src/lib/components/DesktopEditor.svelte +++ b/src/lib/components/DesktopEditor.svelte @@ -115,7 +115,7 @@ throw new Error('divEl is undefined'); } - monaco.languages.json.jsonDefaults.setDiagnosticsOptions({ + monaco.json.jsonDefaults.setDiagnosticsOptions({ validate: true, enableSchemaRequest: true, schemas: [ diff --git a/src/lib/components/DiagramDocumentationButton.svelte b/src/lib/components/DiagramDocumentationButton.svelte index 20081632..5e301e47 100644 --- a/src/lib/components/DiagramDocumentationButton.svelte +++ b/src/lib/components/DiagramDocumentationButton.svelte @@ -97,7 +97,9 @@ return { key: '', url: docURLBase }; } const key = standardizeDiagramType(diagramType); - const docConfig = docMap[key] ?? { code: '' }; + const docConfig: { code: string; config?: string } = docMap[key as keyof typeof docMap] ?? { + code: '' + }; const url = docURLBase + (docConfig[editorMode] ?? docConfig.code ?? ''); return { key, url }; }); diff --git a/src/lib/components/MainMenu.svelte b/src/lib/components/MainMenu.svelte index 251ea2da..814f467f 100644 --- a/src/lib/components/MainMenu.svelte +++ b/src/lib/components/MainMenu.svelte @@ -28,7 +28,7 @@ sharesData?: boolean; checkDiagramType?: boolean; isSectionEnd?: boolean; - renderer: (item: Omit) => ReturnType; + renderer: Snippet<[Omit]>; } const menuItems: MenuItem[] = $derived([ @@ -89,7 +89,7 @@ ]); -{#snippet menuItem(options: MenuItem)} +{#snippet menuItem(options: Omit)} {/snippet} -{#snippet mcMenuItem(item: MenuItem)} +{#snippet mcMenuItem(item: Omit)} {/snippet} -{#snippet darkModeMenuItem(options: MenuItem)} +{#snippet darkModeMenuItem(options: Omit)}
(hidePromotion ? undefined : getActivePromotion()))); const trackBannerClick = () => { if (!activePromotion) { @@ -84,7 +84,7 @@
- + {#if !mobileToggle} Mermaid {/if} diff --git a/src/lib/components/Preset.svelte b/src/lib/components/Preset.svelte index 5ca72758..2b0d5a08 100644 --- a/src/lib/components/Preset.svelte +++ b/src/lib/components/Preset.svelte @@ -35,7 +35,7 @@ const samples = { ...getSampleDiagrams(), ...extras } as const; const loadSampleDiagram = (diagramType: string): void => { - updateCode(samples[diagramType], { + updateCode(samples[diagramType as keyof typeof samples], { resetPanZoom: true, updateDiagram: true }); diff --git a/src/lib/components/Privacy.svelte b/src/lib/components/Privacy.svelte index 07e5444a..b62c0d98 100644 --- a/src/lib/components/Privacy.svelte +++ b/src/lib/components/Privacy.svelte @@ -1,4 +1,4 @@ - +
diff --git a/src/lib/util/promos/promo.ts b/src/lib/util/promos/promo.ts index 6af7b2e6..48c82782 100644 --- a/src/lib/util/promos/promo.ts +++ b/src/lib/util/promos/promo.ts @@ -1,7 +1,7 @@ import { env } from '$lib/util/env'; import dayjs from 'dayjs'; import duration from 'dayjs/plugin/duration'; -import type { Component } from 'svelte'; +import type { Component, Snippet } from 'svelte'; import { get, writable, type Writable } from 'svelte/store'; import { localStorage, persist } from '../persist'; import April2025 from './April2025.svelte'; @@ -12,7 +12,7 @@ dayjs.extend(duration); interface Promotion { startDate: Date; endDate: Date; - component: Component; + component: Component<{ closeBanner: Snippet }>; hideDurationMs: number; } diff --git a/src/lib/util/state.ts b/src/lib/util/state.ts index 5707dbfa..e87c9677 100644 --- a/src/lib/util/state.ts +++ b/src/lib/util/state.ts @@ -189,7 +189,7 @@ function getUnsafePaths(object: object, unsafeKeys: string[], path: string[] = [ } } Object.keys(object).forEach((key) => { - const value = object[key] as unknown; + const value = (object as Record)[key]; const currentPath = [...path, key]; // Prototype pollution check. if (key.startsWith('__')) { diff --git a/tests/history.spec.ts b/tests/history.spec.ts index 452b6dbc..17a8ac0a 100644 --- a/tests/history.spec.ts +++ b/tests/history.spec.ts @@ -1,5 +1,4 @@ import { expect, test, type Page } from '@playwright/test'; -import { typeInEditor } from './utils'; const config = '{\n "theme": "default"\n}'; @@ -93,8 +92,9 @@ test.describe('History', () => { await expect(page.getByText('State already saved.')).toBeVisible(); await expect(page.locator('#historyList li')).toHaveCount(1); - // A real edit produces a new entry. - await typeInEditor(page, ' Z[Extra]', { newline: true }); + // Loading a different sample changes the state, so it saves as a new entry. + await page.getByRole('button', { name: 'Sequence', exact: true }).click(); + await expect(page.locator('#view')).not.toContainText('Christmas'); await page.locator('#saveHistory').click(); await expect(page.locator('#historyList li')).toHaveCount(2); }); @@ -112,7 +112,8 @@ test.describe('History', () => { test('deletes a single entry and clears all after confirmation', async ({ page }) => { await openHistory(page); await page.locator('#saveHistory').click(); - await typeInEditor(page, ' Z[Another]', { newline: true }); + await page.getByRole('button', { name: 'Sequence', exact: true }).click(); + await expect(page.locator('#view')).not.toContainText('Christmas'); await page.locator('#saveHistory').click(); await expect(page.locator('#historyList li')).toHaveCount(2);