From c79afa9541b26557b1843e54a55e14799ed02dec Mon Sep 17 00:00:00 2001 From: archipelago Date: Thu, 11 Jun 2026 01:30:49 -0400 Subject: [PATCH] frontend: fix strict production build typing --- neode-ui/src/views/Discover.vue | 3 +-- .../views/__tests__/CloudPeersRefresh.test.ts | 1 + .../src/views/appDetails/AppHeroSection.vue | 24 ++++++++++++++++++- neode-ui/src/views/appDetails/AppSidebar.vue | 2 +- .../__tests__/AppContentSection.test.ts | 8 +++---- .../apps/__tests__/appCredentials.test.ts | 2 +- .../web5/__tests__/Web5ConnectedNodes.test.ts | 2 +- .../web5/__tests__/Web5Federation.test.ts | 4 ++-- 8 files changed, 34 insertions(+), 12 deletions(-) diff --git a/neode-ui/src/views/Discover.vue b/neode-ui/src/views/Discover.vue index d6404a85..6cfcbd37 100644 --- a/neode-ui/src/views/Discover.vue +++ b/neode-ui/src/views/Discover.vue @@ -224,7 +224,7 @@ import { useMarketplaceApp } from '@/composables/useMarketplaceApp' import { useAppLauncherStore } from '@/stores/appLauncher' import { useToast } from '@/composables/useToast' import { useCollapsingHeaderTabs } from '@/composables/useCollapsingHeaderTabs' -import { APP_STORE_CATEGORIES, APP_STORE_SECTIONS } from './appStoreCategories' +import { APP_STORE_SECTIONS } from './appStoreCategories' import DiscoverHero from './discover/DiscoverHero.vue' import FeaturedApps from './discover/FeaturedApps.vue' import AppGrid from './discover/AppGrid.vue' @@ -253,7 +253,6 @@ const { collapsed: collapseCategories } = useCollapsingHeaderTabs( 144 ) -const categories = computed(() => APP_STORE_CATEGORIES) const appStoreSections = computed(() => APP_STORE_SECTIONS) // Installation state — uses global store so it persists across navigation. diff --git a/neode-ui/src/views/__tests__/CloudPeersRefresh.test.ts b/neode-ui/src/views/__tests__/CloudPeersRefresh.test.ts index a65a8f62..2825f23e 100644 --- a/neode-ui/src/views/__tests__/CloudPeersRefresh.test.ts +++ b/neode-ui/src/views/__tests__/CloudPeersRefresh.test.ts @@ -35,6 +35,7 @@ function makePeer() { onion: 'peer.onion', name: 'Peer Alpha', trust_level: 'trusted', + added_at: '2026-06-10T10:00:00Z', } } diff --git a/neode-ui/src/views/appDetails/AppHeroSection.vue b/neode-ui/src/views/appDetails/AppHeroSection.vue index 725e8445..e68b1b82 100644 --- a/neode-ui/src/views/appDetails/AppHeroSection.vue +++ b/neode-ui/src/views/appDetails/AppHeroSection.vue @@ -172,7 +172,29 @@ const actionItems = computed(() => { }) function emitAction(action: ActionEmit) { - emit(action) + switch (action) { + case 'launch': + emit('launch') + break + case 'start': + emit('start') + break + case 'stop': + emit('stop') + break + case 'restart': + emit('restart') + break + case 'uninstall': + emit('uninstall') + break + case 'update': + emit('update') + break + case 'channels': + emit('channels') + break + } } function handleImageError(e: Event) { diff --git a/neode-ui/src/views/appDetails/AppSidebar.vue b/neode-ui/src/views/appDetails/AppSidebar.vue index e9289436..cba4231f 100644 --- a/neode-ui/src/views/appDetails/AppSidebar.vue +++ b/neode-ui/src/views/appDetails/AppSidebar.vue @@ -104,7 +104,7 @@

Loading credentials...

-
+
{{ cred.label }} diff --git a/neode-ui/src/views/appDetails/__tests__/AppContentSection.test.ts b/neode-ui/src/views/appDetails/__tests__/AppContentSection.test.ts index caed07f2..eb180949 100644 --- a/neode-ui/src/views/appDetails/__tests__/AppContentSection.test.ts +++ b/neode-ui/src/views/appDetails/__tests__/AppContentSection.test.ts @@ -82,9 +82,9 @@ describe('AppContentSection', () => { expect(wrapper.text()).toContain('Screenshots') expect(images).toHaveLength(2) - expect(images[0].attributes('src')).toBe('/assets/screenshots/example-dashboard.png') - expect(images[0].attributes('alt')).toBe('Example screenshot 1') - expect(images[1].attributes('src')).toBe('/assets/screenshots/example-settings.png') - expect(images[1].attributes('alt')).toBe('Settings screen') + expect(images[0]?.attributes('src')).toBe('/assets/screenshots/example-dashboard.png') + expect(images[0]?.attributes('alt')).toBe('Example screenshot 1') + expect(images[1]?.attributes('src')).toBe('/assets/screenshots/example-settings.png') + expect(images[1]?.attributes('alt')).toBe('Settings screen') }) }) diff --git a/neode-ui/src/views/apps/__tests__/appCredentials.test.ts b/neode-ui/src/views/apps/__tests__/appCredentials.test.ts index db45feee..c4b49947 100644 --- a/neode-ui/src/views/apps/__tests__/appCredentials.test.ts +++ b/neode-ui/src/views/apps/__tests__/appCredentials.test.ts @@ -6,7 +6,7 @@ describe('resolveAppCredentials', () => { expect(resolveAppCredentials('filebrowser', { title: 'Backend credentials', credentials: [{ label: 'Password', value: 'secret' }], - })?.credentials[0].value).toBe('secret') + })?.credentials[0]?.value).toBe('secret') }) it('falls back to File Browser default credentials when backend data is not available', () => { diff --git a/neode-ui/src/views/web5/__tests__/Web5ConnectedNodes.test.ts b/neode-ui/src/views/web5/__tests__/Web5ConnectedNodes.test.ts index 34f94b6f..04da57fc 100644 --- a/neode-ui/src/views/web5/__tests__/Web5ConnectedNodes.test.ts +++ b/neode-ui/src/views/web5/__tests__/Web5ConnectedNodes.test.ts @@ -73,7 +73,7 @@ describe('Web5ConnectedNodes', () => { messageState.loadingMessages.value = true const wrapper = mount(Web5ConnectedNodes) - wrapper.vm.nodesContainerTab = 'messages' + ;(wrapper.vm as unknown as { nodesContainerTab: string }).nodesContainerTab = 'messages' await wrapper.vm.$nextTick() expect(wrapper.text()).toContain('Existing message') diff --git a/neode-ui/src/views/web5/__tests__/Web5Federation.test.ts b/neode-ui/src/views/web5/__tests__/Web5Federation.test.ts index 8e5034b2..bafbeda2 100644 --- a/neode-ui/src/views/web5/__tests__/Web5Federation.test.ts +++ b/neode-ui/src/views/web5/__tests__/Web5Federation.test.ts @@ -49,7 +49,7 @@ describe('Web5Federation', () => { nodes: [{ status: 'online' }, { status: 'offline' }], pending_requests: [{}], }) - vi.mocked(rpcClient.getNodeDid).mockResolvedValueOnce({ did: 'did:key:node' }) + vi.mocked(rpcClient.getNodeDid).mockResolvedValueOnce({ did: 'did:key:node', pubkey: 'node-pubkey' }) const wrapper = mountFederation() await flushPromises() @@ -60,7 +60,7 @@ describe('Web5Federation', () => { const pending = deferred<{ nodes: []; pending_requests: [] }>() vi.mocked(rpcClient.call).mockReturnValueOnce(pending.promise) - vi.mocked(rpcClient.getNodeDid).mockResolvedValueOnce({ did: 'did:key:node' }) + vi.mocked(rpcClient.getNodeDid).mockResolvedValueOnce({ did: 'did:key:node', pubkey: 'node-pubkey' }) const refresh = (wrapper.vm as unknown as { loadFederationSummary: () => Promise }).loadFederationSummary() await wrapper.vm.$nextTick()