import { useMutation } from "@tanstack/react-query";
import { useRouter } from "@tanstack/react-router";
import { errorMessage } from "~/lib/error-message";
import { upsellFromResponse } from "~/lib/upsell";
async function postAsset(owner: string, repo: string, releaseId: string, file: File): Promise<void> {
const response = await fetch(`/${owner}/${repo}/releases/${releaseId}/assets?name=${encodeURIComponent(file.name)}`, {
method: "POST",
headers: { "x-gitfor-csrf": "1", "content-type": file.type || "application/octet-stream" },
body: file,
});
if (!response.ok) {
const text = await response.text();
let message = text;
try {
const payload = JSON.parse(text) as { error?: string };
upsellFromResponse(response.status, payload);
message = payload.error ?? text;
} catch {
// Plain-text error.
}
throw new Error(message || "Upload failed");
}
}
/** Release assets stream to a raw Worker route (binary body) rather than a server function. */
export function useReleaseAssetUpload(owner: string, repo: string, releaseId: string) {
const router = useRouter();
const mutation = useMutation({
mutationFn: (file: File) => postAsset(owner, repo, releaseId, file),
onSuccess: () => router.invalidate({ sync: true }),
});
return {
upload: (file: File) => mutation.mutateAsync(file).catch(() => undefined),
pending: mutation.isPending,
error: mutation.isError ? errorMessage(mutation.error) : null,
};
}