fix: extract types from .svelte files for proper named re-exports

Svelte 5 .svelte modules only expose a default export, so 'export type { X } from "./X.svelte"' fails type-check. Move shared interfaces into adjacent .ts type files.

- shared-ui/navigation: SpotlightAction, ContentSearcher, ContentSearch{Result,Group} → types.ts
- shared-auth-ui: PasskeyManagerTranslations, TwoFactorSetupTranslations, SessionManagerTranslations → types.ts
- mana/web/page-carousel: CarouselPage → new types.ts
- mana/web: bump @vitest/* to 4.1.2 (matches lockfile)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-04-07 13:53:13 +02:00
parent fc743a494b
commit 440f6507f1
12 changed files with 143 additions and 135 deletions

View file

@ -26,8 +26,8 @@
"@tailwindcss/vite": "^4.1.7",
"@types/node": "^22.10.5",
"@vite-pwa/sveltekit": "^1.1.0",
"@vitest/coverage-v8": "^4.0.14",
"@vitest/ui": "^4.0.14",
"@vitest/coverage-v8": "^4.1.2",
"@vitest/ui": "^4.1.2",
"autoprefixer": "^10.4.20",
"fake-indexeddb": "^6.2.5",
"postcss": "^8.4.49",
@ -40,7 +40,7 @@
"tslib": "^2.8.1",
"typescript": "^5.9.3",
"vite": "^6.0.7",
"vitest": "^4.0.14"
"vitest": "^4.1.2"
},
"dependencies": {
"@calc/shared": "workspace:*",

View file

@ -6,16 +6,7 @@
import { _ } from 'svelte-i18n';
import { Plus, X, ArrowsOut } from '@mana/shared-icons';
import type { Snippet } from 'svelte';
export interface CarouselPage {
id: string;
minimized: boolean;
maximized?: boolean;
widthPx: number;
heightPx?: number;
title: string;
color: string;
}
import type { CarouselPage } from './types';
interface Props {
pages: CarouselPage[];

View file

@ -1,3 +1,3 @@
export { default as PageShell } from './PageShell.svelte';
export { default as PageCarousel } from './PageCarousel.svelte';
export type { CarouselPage } from './PageCarousel.svelte';
export type { CarouselPage } from './types';

View file

@ -0,0 +1,9 @@
export interface CarouselPage {
id: string;
minimized: boolean;
maximized?: boolean;
widthPx: number;
heightPx?: number;
title: string;
color: string;
}

View file

@ -1,31 +1,5 @@
<script lang="ts">
/** Translation strings for the PasskeyManager */
export interface PasskeyManagerTranslations {
title: string;
noPasskeys: string;
registerButton: string;
renameButton: string;
deleteButton: string;
cancelButton: string;
saveButton: string;
confirmDeleteTitle: string;
confirmDeleteMessage: string;
created: string;
lastUsed: string;
never: string;
backedUp: string;
notBackedUp: string;
browserNotSupported: string;
registerNamePlaceholder: string;
registerNameLabel: string;
registerTitle: string;
renamePlaceholder: string;
errorGeneric: string;
daysAgo: (days: number) => string;
hoursAgo: (hours: number) => string;
minutesAgo: (minutes: number) => string;
justNow: string;
}
import type { PasskeyManagerTranslations } from '../types';
interface Passkey {
id: string;

View file

@ -1,26 +1,6 @@
<script lang="ts">
import { parseUserAgent, getDeviceType } from '../utils/userAgent';
export interface SessionManagerTranslations {
title?: string;
subtitle?: string;
current?: string;
revoke?: string;
revokeAll?: string;
lastActivity?: string;
confirmRevoke?: string;
confirmRevokeAll?: string;
noSessions?: string;
unknown?: string;
refresh?: string;
revokeError?: string;
revokeAllError?: string;
justNow?: string;
minutesAgo?: string;
hoursAgo?: string;
yesterday?: string;
daysAgo?: string;
}
import type { SessionManagerTranslations } from '../types';
interface Session {
id: string;

View file

@ -1,32 +1,6 @@
<script lang="ts">
import QRCode from 'qrcode';
import type { AuthResult } from '../types';
export interface TwoFactorSetupTranslations {
title: string;
statusEnabled: string;
statusDisabled: string;
enableButton: string;
disableButton: string;
regenerateButton: string;
passwordLabel: string;
passwordPlaceholder: string;
confirmButton: string;
cancelButton: string;
setupTitle: string;
setupStep1: string;
setupStep2: string;
manualEntryLabel: string;
copyButton: string;
copiedButton: string;
doneButton: string;
disableConfirmTitle: string;
disableConfirmText: string;
backupCodesTitle: string;
backupCodesWarning: string;
copyCodesButton: string;
copiedCodesButton: string;
}
import type { AuthResult, TwoFactorSetupTranslations } from '../types';
const defaultTranslations: TwoFactorSetupTranslations = {
title: 'Zwei-Faktor-Authentifizierung',

View file

@ -53,7 +53,7 @@ export type {
GuestWelcomeTranslations,
AuthGateAction,
AuthGateTranslations,
PasskeyManagerTranslations,
TwoFactorSetupTranslations,
SessionManagerTranslations,
} from './types';
export type { PasskeyManagerTranslations } from './components/PasskeyManager.svelte';
export type { TwoFactorSetupTranslations } from './components/TwoFactorSetup.svelte';
export type { SessionManagerTranslations } from './components/SessionManager.svelte';

View file

@ -76,3 +76,80 @@ export interface AuthGateTranslations {
/** Function to generate migration info text */
migrationInfo: (count: number) => string;
}
/**
* Translation strings for the PasskeyManager
*/
export interface PasskeyManagerTranslations {
title: string;
noPasskeys: string;
registerButton: string;
renameButton: string;
deleteButton: string;
cancelButton: string;
saveButton: string;
confirmDeleteTitle: string;
confirmDeleteMessage: string;
created: string;
lastUsed: string;
never: string;
backedUp: string;
notBackedUp: string;
browserNotSupported: string;
registerNamePlaceholder: string;
registerNameLabel: string;
registerTitle: string;
renamePlaceholder: string;
errorGeneric: string;
daysAgo: (days: number) => string;
hoursAgo: (hours: number) => string;
minutesAgo: (minutes: number) => string;
justNow: string;
}
export interface TwoFactorSetupTranslations {
title: string;
statusEnabled: string;
statusDisabled: string;
enableButton: string;
disableButton: string;
regenerateButton: string;
passwordLabel: string;
passwordPlaceholder: string;
confirmButton: string;
cancelButton: string;
setupTitle: string;
setupStep1: string;
setupStep2: string;
manualEntryLabel: string;
copyButton: string;
copiedButton: string;
doneButton: string;
disableConfirmTitle: string;
disableConfirmText: string;
backupCodesTitle: string;
backupCodesWarning: string;
copyCodesButton: string;
copiedCodesButton: string;
}
export interface SessionManagerTranslations {
title?: string;
subtitle?: string;
current?: string;
revoke?: string;
revokeAll?: string;
lastActivity?: string;
confirmRevoke?: string;
confirmRevokeAll?: string;
noSessions?: string;
unknown?: string;
refresh?: string;
revokeError?: string;
revokeAllError?: string;
justNow?: string;
minutesAgo?: string;
hoursAgo?: string;
yesterday?: string;
daysAgo?: string;
}

View file

@ -1,43 +1,13 @@
<script lang="ts">
import type { PillAppItem } from './types';
import type {
PillAppItem,
SpotlightAction,
ContentSearchResult,
ContentSearchGroup,
ContentSearcher,
} from './types';
import { createAppNavigationStore } from './appNavigationStore.svelte';
export interface SpotlightAction {
id: string;
label: string;
description?: string;
icon?: string;
shortcut?: string;
category?: string;
onExecute: () => void;
}
export interface ContentSearchResult {
id: string;
type: string;
appId: string;
title: string;
subtitle?: string;
appIcon?: string;
appColor?: string;
href: string;
score: number;
matchedField?: string;
}
export interface ContentSearchGroup {
appId: string;
appName: string;
appIcon?: string;
appColor?: string;
results: ContentSearchResult[];
}
export type ContentSearcher = (
query: string,
signal: AbortSignal
) => Promise<ContentSearchGroup[]>;
interface Props {
open: boolean;
onClose: () => void;

View file

@ -6,12 +6,6 @@ export { default as PillNavigation } from './PillNavigation.svelte';
export { default as PillDropdown } from './PillDropdown.svelte';
export { default as AppDrawer } from './AppDrawer.svelte';
export { default as GlobalSpotlight } from './GlobalSpotlight.svelte';
export type {
SpotlightAction,
ContentSearcher,
ContentSearchResult,
ContentSearchGroup,
} from './GlobalSpotlight.svelte';
export { createGlobalSpotlightState } from './useGlobalSpotlight.svelte';
export {
createAppNavigationStore,
@ -49,4 +43,8 @@ export type {
PillTagSelectorConfig,
PillDivider,
PillNavElement,
SpotlightAction,
ContentSearchResult,
ContentSearchGroup,
ContentSearcher,
} from './types';

View file

@ -254,3 +254,38 @@ export interface NavLinkProps {
/** Additional CSS classes */
class?: string;
}
// ============ Global Spotlight Types ============
export interface SpotlightAction {
id: string;
label: string;
description?: string;
icon?: string;
shortcut?: string;
category?: string;
onExecute: () => void;
}
export interface ContentSearchResult {
id: string;
type: string;
appId: string;
title: string;
subtitle?: string;
appIcon?: string;
appColor?: string;
href: string;
score: number;
matchedField?: string;
}
export interface ContentSearchGroup {
appId: string;
appName: string;
appIcon?: string;
appColor?: string;
results: ContentSearchResult[];
}
export type ContentSearcher = (query: string, signal: AbortSignal) => Promise<ContentSearchGroup[]>;