feat: wire Monaco editor to real file read/write
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,10 @@
|
||||
import { useQuery, type UseQueryResult } from "@tanstack/react-query";
|
||||
import {
|
||||
useMutation,
|
||||
useQuery,
|
||||
useQueryClient,
|
||||
type UseMutationResult,
|
||||
type UseQueryResult,
|
||||
} from "@tanstack/react-query";
|
||||
|
||||
import { apiClient } from "@/lib/api/client";
|
||||
|
||||
@@ -31,6 +37,11 @@ export function inferLanguage(name: string): string | undefined {
|
||||
return ext ? LANGUAGE_BY_EXTENSION[ext] : undefined;
|
||||
}
|
||||
|
||||
export interface ReadFileResponse {
|
||||
path: string;
|
||||
content: string;
|
||||
}
|
||||
|
||||
function fileListQueryKey(workspaceId: string, path: string) {
|
||||
return ["workspaces", workspaceId, "files", path || "."] as const;
|
||||
}
|
||||
@@ -50,6 +61,35 @@ async function fetchFileList(
|
||||
return (await res.json()) as FileEntry[];
|
||||
}
|
||||
|
||||
export function fileReadQueryKey(workspaceId: string, path: string) {
|
||||
return ["workspaces", workspaceId, "files", "read", path] as const;
|
||||
}
|
||||
|
||||
async function fetchFileRead(
|
||||
workspaceId: string,
|
||||
path: string,
|
||||
): Promise<ReadFileResponse> {
|
||||
const url =
|
||||
`/api/workspaces/${encodeURIComponent(workspaceId)}/files/read?` +
|
||||
new URLSearchParams({ path }).toString();
|
||||
const res = await apiClient(url);
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to read file: ${res.status}`);
|
||||
}
|
||||
return (await res.json()) as ReadFileResponse;
|
||||
}
|
||||
|
||||
export function useFileRead(
|
||||
workspaceId: string | null,
|
||||
path: string | null,
|
||||
): UseQueryResult<ReadFileResponse, Error> {
|
||||
return useQuery({
|
||||
queryKey: fileReadQueryKey(workspaceId ?? "", path ?? ""),
|
||||
queryFn: () => fetchFileRead(workspaceId!, path!),
|
||||
enabled: !!workspaceId && !!path,
|
||||
});
|
||||
}
|
||||
|
||||
export function useFileList(
|
||||
workspaceId: string | null,
|
||||
path: string,
|
||||
@@ -62,3 +102,29 @@ export function useFileList(
|
||||
enabled: !!workspaceId && enabled,
|
||||
});
|
||||
}
|
||||
|
||||
export function useFileWrite(): UseMutationResult<
|
||||
void,
|
||||
Error,
|
||||
{ path: string; content: string; workspaceId: string }
|
||||
> {
|
||||
const queryClient = useQueryClient();
|
||||
return useMutation({
|
||||
mutationFn: async ({ workspaceId, path, content }) => {
|
||||
const url = `/api/workspaces/${encodeURIComponent(workspaceId)}/files/write`;
|
||||
const res = await apiClient(url, {
|
||||
method: "PUT",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ path, content }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`Failed to save file: ${res.status}`);
|
||||
}
|
||||
},
|
||||
onSuccess: (_, variables) => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: fileReadQueryKey(variables.workspaceId, variables.path),
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user