feat(web): section-prefix all tool API calls

This commit is contained in:
SnapOtter
2026-06-20 12:35:10 +08:00
parent f80444791b
commit 22b4b5c3c1
31 changed files with 41 additions and 39 deletions
@@ -1,5 +1,6 @@
// apps/web/src/components/editor/common/export-dialog.tsx
import { apiToolPath } from "@snapotter/shared";
import {
Check,
ClipboardCopy,
@@ -190,7 +191,7 @@ export function ExportDialog({ onClose }: { onClose: () => void }) {
JSON.stringify({ format: settings.format, quality: settings.quality }),
);
try {
const res = await fetch("/api/v1/tools/convert", {
const res = await fetch(apiToolPath("convert"), {
method: "POST",
body: formData,
});
@@ -257,7 +258,7 @@ export function ExportDialog({ onClose }: { onClose: () => void }) {
"settings",
JSON.stringify({ format: settings.format, quality: settings.quality }),
);
const res = await fetch("/api/v1/tools/convert", { method: "POST", body: formData });
const res = await fetch(apiToolPath("convert"), { method: "POST", body: formData });
if (!res.ok) throw new Error("Server conversion failed");
const json = await res.json();
if (json.downloadUrl) {
@@ -36,7 +36,7 @@ export function BarcodeGenerateSettings() {
setResultUrl(null);
try {
const res = await fetch("/api/v1/tools/barcode-generate", {
const res = await fetch("/api/v1/tools/image/barcode-generate", {
method: "POST",
headers: {
...formatHeaders(),
@@ -99,7 +99,7 @@ function scanOneFile(
xhr.onerror = () => reject(new Error("Network error"));
xhr.ontimeout = () => reject(new Error("Request timed out"));
xhr.open("POST", "/api/v1/tools/barcode-read");
xhr.open("POST", "/api/v1/tools/image/barcode-read");
for (const [key, value] of formatHeaders()) {
xhr.setRequestHeader(key, value);
}
@@ -1328,7 +1328,7 @@ export function BeautifySettings({
formData.append("backgroundImage", bgImageFile);
formData.append("settings", JSON.stringify(settings));
const res = await fetch("/api/v1/tools/beautify", {
const res = await fetch("/api/v1/tools/image/beautify", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -25,7 +25,7 @@ export function BulkRenameSettings() {
}
formData.append("settings", JSON.stringify({ pattern, startIndex }));
const res = await fetch("/api/v1/tools/bulk-rename", {
const res = await fetch("/api/v1/tools/image/bulk-rename", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -106,7 +106,7 @@ export function CollageSettings() {
jobId: string;
}>((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("POST", "/api/v1/tools/collage");
xhr.open("POST", "/api/v1/tools/image/collage");
const headers = formatHeaders();
headers.forEach((value, key) => {
@@ -31,7 +31,7 @@ export function ColorPaletteSettings() {
formData.append("file", files[0]);
formData.append("settings", JSON.stringify({ count, format }));
const res = await fetch("/api/v1/tools/color-palette", {
const res = await fetch("/api/v1/tools/image/color-palette", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -24,7 +24,7 @@ export function CompareSettings() {
formData.append("file", files[0]);
formData.append("file", secondFile);
const res = await fetch("/api/v1/tools/compare", {
const res = await fetch("/api/v1/tools/image/compare", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -30,7 +30,7 @@ export function ComposeSettings() {
formData.append("overlay", overlayFile);
formData.append("settings", JSON.stringify({ x, y, opacity, blendMode }));
const res = await fetch("/api/v1/tools/compose", {
const res = await fetch("/api/v1/tools/image/compose", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -217,7 +217,7 @@ export function EditMetadataSettings() {
try {
const formData = new FormData();
formData.append("file", currentFile);
const res = await fetch("/api/v1/tools/edit-metadata/inspect", {
const res = await fetch("/api/v1/tools/image/edit-metadata/inspect", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -226,7 +226,7 @@ export function EraseObjectSettings({
stopProgress();
reject(new Error("Request timed out"));
};
xhr.open("POST", "/api/v1/tools/erase-object");
xhr.open("POST", "/api/v1/tools/image/erase-object");
for (const [key, value] of formatHeaders()) {
xhr.setRequestHeader(key, value);
}
@@ -365,7 +365,7 @@ export function EraseObjectSettings({
setError("Request timed out - the server may be overloaded. Try again.");
finishUi();
};
xhr.open("POST", "/api/v1/tools/erase-object");
xhr.open("POST", "/api/v1/tools/image/erase-object");
formatHeaders().forEach((value, key) => {
xhr.setRequestHeader(key, value);
});
@@ -156,7 +156,7 @@ export function FaviconSettings() {
cleanup();
};
xhr.open("POST", "/api/v1/tools/favicon");
xhr.open("POST", "/api/v1/tools/image/favicon");
formatHeaders().forEach((value, key) => {
xhr.setRequestHeader(key, value);
});
@@ -114,7 +114,7 @@ export function FindDuplicatesSettings() {
setScanning(false);
};
xhr.open("POST", "/api/v1/tools/find-duplicates");
xhr.open("POST", "/api/v1/tools/image/find-duplicates");
xhr.timeout = 300_000;
const headers = formatHeaders();
headers.forEach((value, key) => {
@@ -181,7 +181,7 @@ export function ImageEnhancementControls({
const formData = new FormData();
formData.append("file", files[0]);
fetch("/api/v1/tools/image-enhancement/analyze", {
fetch("/api/v1/tools/image/image-enhancement/analyze", {
method: "POST",
body: formData,
signal: controller.signal,
@@ -45,7 +45,7 @@ export function ImageToBase64Settings() {
formData.append("files", file);
formData.append("settings", settings);
const res = await fetch("/api/v1/tools/image-to-base64", {
const res = await fetch("/api/v1/tools/image/image-to-base64", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -236,7 +236,7 @@ export function ImageToPdfSettings() {
cleanup();
};
xhr.open("POST", "/api/v1/tools/image-to-pdf");
xhr.open("POST", "/api/v1/tools/image/image-to-pdf");
formatHeaders().forEach((value, key) => {
xhr.setRequestHeader(key, value);
});
@@ -63,7 +63,7 @@ export function InfoSettings() {
const formData = new FormData();
formData.append("file", file);
const res = await fetch("/api/v1/tools/info", {
const res = await fetch("/api/v1/tools/image/info", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -93,7 +93,7 @@ function ocrOneFile(
es.close();
reject(new Error("Network error"));
};
xhr.open("POST", "/api/v1/tools/ocr");
xhr.open("POST", "/api/v1/tools/image/ocr");
for (const [key, value] of formatHeaders()) {
xhr.setRequestHeader(key, value);
}
@@ -100,7 +100,7 @@ export function OptimizeForWebSettings() {
formData.append("file", file);
formData.append("settings", JSON.stringify(buildSettings()));
fetch("/api/v1/tools/optimize-for-web/preview", {
fetch("/api/v1/tools/image/optimize-for-web/preview", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -436,7 +436,7 @@ export function PassportPhotoSettings() {
formData.append("settings", JSON.stringify({}));
const headers = formatHeaders();
const response = await fetch("/api/v1/tools/passport-photo/analyze", {
const response = await fetch("/api/v1/tools/image/passport-photo/analyze", {
method: "POST",
headers,
body: formData,
@@ -505,7 +505,7 @@ export function PassportPhotoSettings() {
imageHeight: analyzeResult.imageHeight,
};
const response = await fetch("/api/v1/tools/passport-photo/generate", {
const response = await fetch("/api/v1/tools/image/passport-photo/generate", {
method: "POST",
headers,
body: JSON.stringify(body),
@@ -828,7 +828,7 @@ export function RemoveBgSettings({ onBgPreview }: RemoveBgSettingsProps = {}) {
}
const headers = formatHeaders();
const response = await fetch("/api/v1/tools/remove-background/effects", {
const response = await fetch("/api/v1/tools/image/remove-background/effects", {
method: "POST",
headers,
body: formData,
@@ -122,7 +122,7 @@ export function SplitSettings() {
formData.append("file", file);
formData.append("settings", settingsJson);
const res = await fetch("/api/v1/tools/split", {
const res = await fetch("/api/v1/tools/image/split", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -63,7 +63,7 @@ export function StitchSettings() {
processedSize: number;
}>((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("POST", "/api/v1/tools/stitch");
xhr.open("POST", "/api/v1/tools/image/stitch");
const headers = formatHeaders();
headers.forEach((value, key) => {
@@ -250,7 +250,7 @@ export function StripMetadataSettings() {
try {
const formData = new FormData();
formData.append("file", currentFile);
const res = await fetch("/api/v1/tools/strip-metadata/inspect", {
const res = await fetch("/api/v1/tools/image/strip-metadata/inspect", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -35,7 +35,7 @@ export function WatermarkImageSettings() {
formData.append("watermark", watermarkFile);
formData.append("settings", settingsJson);
const res = await fetch("/api/v1/tools/watermark-image", {
const res = await fetch("/api/v1/tools/image/watermark-image", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -70,7 +70,7 @@ export function WatermarkImageSettings() {
formData.append("watermark", watermarkFile);
formData.append("settings", settingsJson);
const res = await fetch("/api/v1/tools/watermark-image", {
const res = await fetch("/api/v1/tools/image/watermark-image", {
method: "POST",
headers: formatHeaders(),
body: formData,
+1 -1
View File
@@ -38,7 +38,7 @@ export function useGifInfo() {
const formData = new FormData();
formData.append("file", file);
fetch("/api/v1/tools/gif-tools/info", {
fetch("/api/v1/tools/image/gif-tools/info", {
method: "POST",
headers: formatHeaders(),
body: formData,
+3 -3
View File
@@ -1,4 +1,4 @@
import { PYTHON_SIDECAR_TOOLS, TOOLS } from "@snapotter/shared";
import { apiToolPath, PYTHON_SIDECAR_TOOLS, TOOLS } from "@snapotter/shared";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "@/contexts/i18n-context";
import { formatHeaders, parseApiError } from "@/lib/api";
@@ -497,7 +497,7 @@ export function useToolProcessor(toolId: string) {
clearActiveJob();
};
xhr.open("POST", `/api/v1/tools/${toolId}`);
xhr.open("POST", apiToolPath(toolId));
formatHeaders().forEach((value, key) => {
xhr.setRequestHeader(key, value);
});
@@ -578,7 +578,7 @@ export function useToolProcessor(toolId: string) {
try {
abortRef.current = new AbortController();
const response = await fetch(`/api/v1/tools/${toolId}/batch`, {
const response = await fetch(`${apiToolPath(toolId)}/batch`, {
method: "POST",
headers: formatHeaders(),
body: formData,
+2 -1
View File
@@ -1,4 +1,5 @@
// apps/web/src/pages/editor-page.tsx
import { apiToolPath } from "@snapotter/shared";
import { Monitor } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import { CanvasResizeDialog } from "@/components/editor/common/canvas-resize-dialog";
@@ -106,7 +107,7 @@ export function EditorPage() {
const formData = new FormData();
formData.append("file", file);
formData.append("settings", JSON.stringify({ format: "png" }));
const res = await fetch("/api/v1/tools/convert", { method: "POST", body: formData });
const res = await fetch(apiToolPath("convert"), { method: "POST", body: formData });
if (!res.ok) throw new Error("Server decode failed");
const json = await res.json();
if (json.downloadUrl) {
+1 -1
View File
@@ -66,7 +66,7 @@ export const useHtmlToImageStore = create<HtmlToImageState>((set, get) => ({
set({ capturing: true, error: null, resultUrl: null, resultSize: null });
try {
const res = await fetch("/api/v1/tools/html-to-image", {
const res = await fetch("/api/v1/tools/image/html-to-image", {
method: "POST",
headers: formatHeaders({ "Content-Type": "application/json" }),
body: JSON.stringify({
+2 -2
View File
@@ -312,13 +312,13 @@ export const useMemeStore = create<MemeState>((set, get) => ({
const formData = new FormData();
formData.append("file", state.customFile);
formData.append("settings", JSON.stringify(apiSettings));
response = await fetch("/api/v1/tools/meme-generator", {
response = await fetch("/api/v1/tools/image/meme-generator", {
method: "POST",
headers: formatHeaders(),
body: formData,
});
} else {
response = await fetch("/api/v1/tools/meme-generator", {
response = await fetch("/api/v1/tools/image/meme-generator", {
method: "POST",
headers: formatHeaders({ "Content-Type": "application/json" }),
body: JSON.stringify(apiSettings),
+2 -2
View File
@@ -189,7 +189,7 @@ export const usePdfToImageStore = create<PdfToImageState>((set, get) => ({
try {
const formData = new FormData();
formData.append("file", file);
const res = await fetch("/api/v1/tools/pdf-to-image/preview", {
const res = await fetch("/api/v1/tools/pdf/pdf-to-image/preview", {
method: "POST",
headers: formatHeaders(),
body: formData,
@@ -231,7 +231,7 @@ export const usePdfToImageStore = create<PdfToImageState>((set, get) => ({
"settings",
JSON.stringify({ format, dpi, quality, colorMode, pages: pagesValue }),
);
const res = await fetch("/api/v1/tools/pdf-to-image", {
const res = await fetch("/api/v1/tools/pdf/pdf-to-image", {
method: "POST",
headers: formatHeaders(),
body: formData,