fix: embedding migration, worker error handling, path traversal security, response mismatches (unread-count, plugins, manifests), frontend type safety
This commit is contained in:
+36
-14
@@ -5,22 +5,44 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||||
import { apiGet, apiPost, apiDelete } from './client';
|
||||
|
||||
// ── Types matching backend schemas ──
|
||||
|
||||
export interface Plugin {
|
||||
name: string;
|
||||
display_name?: string;
|
||||
description?: string;
|
||||
version?: string;
|
||||
display_name: string;
|
||||
version: string;
|
||||
status: 'discovered' | 'installed' | 'active' | 'inactive';
|
||||
installed?: boolean;
|
||||
active?: boolean;
|
||||
installed: boolean;
|
||||
active: boolean;
|
||||
description: string;
|
||||
dependencies: string[];
|
||||
events: string[];
|
||||
migrations: string[];
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
export interface PluginListResponse {
|
||||
plugins: Plugin[];
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface PluginActionResponse {
|
||||
name: string;
|
||||
display_name: string;
|
||||
version: string;
|
||||
status: string;
|
||||
installed: boolean;
|
||||
active: boolean;
|
||||
dropped_tables: string[];
|
||||
message: string;
|
||||
}
|
||||
|
||||
export function usePlugins() {
|
||||
return useQuery({
|
||||
queryKey: ['plugins'],
|
||||
queryFn: async () => {
|
||||
const data = await apiGet<any>('/plugins');
|
||||
return data;
|
||||
const data = await apiGet<PluginListResponse>('/plugins');
|
||||
return data.plugins;
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -28,7 +50,7 @@ export function usePlugins() {
|
||||
export function useInstallPlugin() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (name: string) => apiPost(`/plugins/${name}/install`),
|
||||
mutationFn: (name: string) => apiPost<PluginActionResponse>(`/plugins/${name}/install`),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
},
|
||||
@@ -38,7 +60,7 @@ export function useInstallPlugin() {
|
||||
export function useActivatePlugin() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (name: string) => apiPost(`/plugins/${name}/activate`),
|
||||
mutationFn: (name: string) => apiPost<PluginActionResponse>(`/plugins/${name}/activate`),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
},
|
||||
@@ -48,7 +70,7 @@ export function useActivatePlugin() {
|
||||
export function useDeactivatePlugin() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: (name: string) => apiPost(`/plugins/${name}/deactivate`),
|
||||
mutationFn: (name: string) => apiPost<PluginActionResponse>(`/plugins/${name}/deactivate`),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
},
|
||||
@@ -59,7 +81,7 @@ export function useUninstallPlugin() {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: ({ name, removeData }: { name: string; removeData: boolean }) =>
|
||||
apiDelete(`/plugins/${name}?remove_data=${removeData}`),
|
||||
apiDelete<PluginActionResponse>(`/plugins/${name}?remove_data=${removeData}`),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
},
|
||||
@@ -76,7 +98,7 @@ export function useUploadPlugin() {
|
||||
const res = await apiClient.post('/plugins/upload', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
return res.data;
|
||||
return res.data as PluginActionResponse;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
@@ -90,10 +112,10 @@ export function useInstallPluginFromUrl() {
|
||||
mutationFn: async (url: string) => {
|
||||
const { default: apiClient } = await import('./client');
|
||||
const res = await apiClient.post('/plugins/install-url', { url });
|
||||
return res.data;
|
||||
return res.data as PluginActionResponse;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: ['plugins'] });
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user