feat(!): return 204 instead of useless json responses, add fastFetch

This commit is contained in:
Sam 2023-03-30 16:05:40 +02:00
parent abc78f3a9a
commit 9c8b6a8f91
No known key found for this signature in database
GPG Key ID: B4EF20DDE721CAA1
16 changed files with 63 additions and 31 deletions

View File

@ -42,7 +42,7 @@ func (s *Server) cancelDelete(w http.ResponseWriter, r *http.Request) error {
log.Errorf("executing undelete query: %v", err) log.Errorf("executing undelete query: %v", err)
} }
render.JSON(w, r, map[string]any{"success": true}) render.NoContent(w, r)
return nil return nil
} }
@ -104,6 +104,6 @@ func (s *Server) forceDelete(w http.ResponseWriter, r *http.Request) error {
return errors.Wrap(err, "deleting user") return errors.Wrap(err, "deleting user")
} }
render.JSON(w, r, map[string]any{"success": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -47,6 +47,6 @@ func (s *Server) deleteMember(w http.ResponseWriter, r *http.Request) error {
} }
} }
render.JSON(w, r, map[string]any{"deleted": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -51,13 +51,13 @@ func (s *Server) createUserReport(w http.ResponseWriter, r *http.Request) error
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"} return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
} }
report, err := s.DB.CreateReport(ctx, claims.UserID, u.ID, nil, req.Reason) _, err = s.DB.CreateReport(ctx, claims.UserID, u.ID, nil, req.Reason)
if err != nil { if err != nil {
log.Errorf("creating report for %v: %v", u.ID, err) log.Errorf("creating report for %v: %v", u.ID, err)
return errors.Wrap(err, "creating report") return errors.Wrap(err, "creating report")
} }
render.JSON(w, r, map[string]any{"created": true, "created_at": report.CreatedAt}) render.NoContent(w, r)
return nil return nil
} }
@ -100,12 +100,12 @@ func (s *Server) createMemberReport(w http.ResponseWriter, r *http.Request) erro
return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"} return server.APIError{Code: server.ErrBadRequest, Details: "Reason cannot exceed 2000 characters"}
} }
report, err := s.DB.CreateReport(ctx, claims.UserID, u.ID, &m.ID, req.Reason) _, err = s.DB.CreateReport(ctx, claims.UserID, u.ID, &m.ID, req.Reason)
if err != nil { if err != nil {
log.Errorf("creating report for %v: %v", m.ID, err) log.Errorf("creating report for %v: %v", m.ID, err)
return errors.Wrap(err, "creating report") return errors.Wrap(err, "creating report")
} }
render.JSON(w, r, map[string]any{"created": true, "created_at": report.CreatedAt}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -108,6 +108,6 @@ func (s *Server) resolveReport(w http.ResponseWriter, r *http.Request) error {
return errors.Wrap(err, "committing transaction") return errors.Wrap(err, "committing transaction")
} }
render.JSON(w, r, map[string]any{"success": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -58,6 +58,6 @@ func (s *Server) ackWarning(w http.ResponseWriter, r *http.Request) (err error)
return server.APIError{Code: server.ErrNotFound} return server.APIError{Code: server.ErrNotFound}
} }
render.JSON(w, r, map[string]any{"ok": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -37,6 +37,6 @@ func (s *Server) deleteUser(w http.ResponseWriter, r *http.Request) error {
return errors.Wrap(err, "committing transaction") return errors.Wrap(err, "committing transaction")
} }
render.JSON(w, r, map[string]any{"deleted": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -43,7 +43,7 @@ func (s *Server) startExport(w http.ResponseWriter, r *http.Request) error {
} }
} }
render.JSON(w, r, map[string]any{"started": true}) render.NoContent(w, r)
return nil return nil
} }

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { APIError } from "./entities"; import type { APIError } from "./entities";
import { PUBLIC_BASE_URL } from "$env/static/public"; import { PUBLIC_BASE_URL } from "$env/static/public";
@ -21,9 +22,36 @@ export async function apiFetch<T>(
}); });
const data = await resp.json(); const data = await resp.json();
if (resp.status < 200 || resp.status >= 300) throw data as APIError; if (resp.status < 200 || resp.status >= 400) throw data as APIError;
return data as T; return data as T;
} }
export const apiFetchClient = async <T>(path: string, method: string = "GET", body: any = null) => export const apiFetchClient = async <T>(path: string, method = "GET", body: any = null) =>
apiFetch<T>(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined }); apiFetch<T>(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined });
/** Fetches the specified path without parsing the response body. */
export async function fastFetch(
path: string,
{
method,
body,
token,
headers,
}: { method?: string; body?: any; token?: string; headers?: Record<string, string> },
) {
const resp = await fetch(`${PUBLIC_BASE_URL}/api/v1${path}`, {
method: method || "GET",
headers: {
...(token ? { Authorization: token } : {}),
...(headers ? headers : {}),
"Content-Type": "application/json",
},
body: body ? JSON.stringify(body) : null,
});
if (resp.status < 200 || resp.status >= 400) throw (await resp.json()) as APIError;
}
/** Fetches the specified path without parsing the response body. */
export const fastFetchClient = async (path: string, method = "GET", body: any = null) =>
fastFetch(path, { method, body, token: localStorage.getItem("pronouns-token") || undefined });

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { APIError } from "$lib/api/entities"; import type { APIError } from "$lib/api/entities";
import { apiFetchClient } from "$lib/api/fetch"; import { fastFetchClient } from "$lib/api/fetch";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
import { Button, FormGroup, Icon, Modal, ModalBody, ModalFooter } from "sveltestrap"; import { Button, FormGroup, Icon, Modal, ModalBody, ModalFooter } from "sveltestrap";
@ -18,7 +18,7 @@
const doReport = async () => { const doReport = async () => {
try { try {
await apiFetchClient<any>(reportUrl, "POST", { reason: reason }); await fastFetchClient(reportUrl, "POST", { reason: reason });
error = null; error = null;
addToast({ header: "Sent report", body: "Successfully sent report!" }); addToast({ header: "Sent report", body: "Successfully sent report!" });
toggle(); toggle();

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import type { APIError, MeUser } from "$lib/api/entities"; import type { APIError, MeUser } from "$lib/api/entities";
import { apiFetch } from "$lib/api/fetch"; import { fastFetch } from "$lib/api/fetch";
import { usernameRegex } from "$lib/api/regex"; import { usernameRegex } from "$lib/api/regex";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { userStore } from "$lib/store"; import { userStore } from "$lib/store";
@ -58,7 +58,7 @@
const forceDeleteAccount = async () => { const forceDeleteAccount = async () => {
try { try {
await apiFetch<any>("/auth/force-delete", { await fastFetch("/auth/force-delete", {
method: "GET", method: "GET",
headers: { headers: {
"X-Delete-Token": token!, "X-Delete-Token": token!,
@ -75,7 +75,7 @@
const cancelDelete = async () => { const cancelDelete = async () => {
try { try {
await apiFetch<any>("/auth/cancel-delete", { await fastFetch("/auth/cancel-delete", {
method: "GET", method: "GET",
headers: { headers: {
"X-Delete-Token": token!, "X-Delete-Token": token!,

View File

@ -22,7 +22,7 @@
ModalFooter, ModalFooter,
} from "sveltestrap"; } from "sveltestrap";
import { encode } from "base64-arraybuffer"; import { encode } from "base64-arraybuffer";
import { apiFetchClient } from "$lib/api/fetch"; import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
import IconButton from "$lib/components/IconButton.svelte"; import IconButton from "$lib/components/IconButton.svelte";
import EditableField from "../../EditableField.svelte"; import EditableField from "../../EditableField.svelte";
import EditableName from "../../EditableName.svelte"; import EditableName from "../../EditableName.svelte";
@ -242,9 +242,13 @@
const deleteMember = async () => { const deleteMember = async () => {
try { try {
await apiFetchClient<any>(`/members/${data.member.id}`, "DELETE"); await fastFetchClient(`/members/${data.member.id}`, "DELETE");
toggleDeleteOpen(); toggleDeleteOpen();
addToast({
header: "Deleted member",
body: `Successfully deleted member ${data.member.name}!`,
});
goto(`/@${data.member.user.name}`); goto(`/@${data.member.user.name}`);
} catch (e) { } catch (e) {
deleteName = ""; deleteName = "";

View File

@ -11,7 +11,7 @@
} from "$lib/api/entities"; } from "$lib/api/entities";
import FallbackImage from "$lib/components/FallbackImage.svelte"; import FallbackImage from "$lib/components/FallbackImage.svelte";
import { userStore } from "$lib/store"; import { userStore } from "$lib/store";
import { Alert, Button, ButtonGroup, FormGroup, Icon, Input, Popover } from "sveltestrap"; import { Button, ButtonGroup, FormGroup, Icon, Input, Popover } from "sveltestrap";
import { encode } from "base64-arraybuffer"; import { encode } from "base64-arraybuffer";
import { apiFetchClient } from "$lib/api/fetch"; import { apiFetchClient } from "$lib/api/fetch";
import IconButton from "$lib/components/IconButton.svelte"; import IconButton from "$lib/components/IconButton.svelte";

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { APIError } from "$lib/api/entities"; import type { APIError } from "$lib/api/entities";
import { apiFetchClient } from "$lib/api/fetch"; import { fastFetchClient } from "$lib/api/fetch";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
import { Button, FormGroup, Modal, ModalBody, ModalFooter } from "sveltestrap"; import { Button, FormGroup, Modal, ModalBody, ModalFooter } from "sveltestrap";
@ -42,7 +42,7 @@
const warnUser = async () => { const warnUser = async () => {
try { try {
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", { await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
warn: true, warn: true,
reason: reason, reason: reason,
}); });
@ -58,7 +58,7 @@
const deactivateUser = async () => { const deactivateUser = async () => {
try { try {
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", { await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
warn: true, warn: true,
ban: true, ban: true,
delete: deleteUser, delete: deleteUser,
@ -76,7 +76,7 @@
const ignoreReport = async () => { const ignoreReport = async () => {
try { try {
await apiFetchClient<any>(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", { await fastFetchClient(`/admin/reports/${data.reports[reportIndex].id}`, "PATCH", {
reason: reason, reason: reason,
}); });
error = null; error = null;

View File

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { goto } from "$app/navigation"; import { goto } from "$app/navigation";
import { type MeUser, userAvatars, type APIError, MAX_MEMBERS } from "$lib/api/entities"; import { type MeUser, userAvatars, type APIError, MAX_MEMBERS } from "$lib/api/entities";
import { apiFetchClient } from "$lib/api/fetch"; import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
import { usernameRegex } from "$lib/api/regex"; import { usernameRegex } from "$lib/api/regex";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import FallbackImage from "$lib/components/FallbackImage.svelte"; import FallbackImage from "$lib/components/FallbackImage.svelte";
@ -37,7 +37,7 @@
const deleteAccount = async () => { const deleteAccount = async () => {
try { try {
await apiFetchClient<any>("/users/@me", "DELETE"); await fastFetchClient("/users/@me", "DELETE");
userStore.set(null); userStore.set(null);
localStorage.removeItem("pronouns-token"); localStorage.removeItem("pronouns-token");

View File

@ -3,7 +3,7 @@
import { DateTime, Duration } from "luxon"; import { DateTime, Duration } from "luxon";
import { Alert, Button } from "sveltestrap"; import { Alert, Button } from "sveltestrap";
import { PUBLIC_BASE_URL } from "$env/static/public"; import { PUBLIC_BASE_URL } from "$env/static/public";
import { apiFetchClient } from "$lib/api/fetch"; import { fastFetchClient } from "$lib/api/fetch";
import type { APIError } from "$lib/api/entities"; import type { APIError } from "$lib/api/entities";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
@ -23,7 +23,7 @@
const requestExport = async () => { const requestExport = async () => {
try { try {
await apiFetchClient<any>("/users/@me/export/start"); await fastFetchClient("/users/@me/export/start");
addToast({ addToast({
header: "Export in progress", header: "Export in progress",

View File

@ -1,6 +1,6 @@
<script lang="ts"> <script lang="ts">
import type { APIError } from "$lib/api/entities"; import type { APIError } from "$lib/api/entities";
import { apiFetchClient } from "$lib/api/fetch"; import { apiFetchClient, fastFetchClient } from "$lib/api/fetch";
import ErrorAlert from "$lib/components/ErrorAlert.svelte"; import ErrorAlert from "$lib/components/ErrorAlert.svelte";
import { addToast } from "$lib/toast"; import { addToast } from "$lib/toast";
import { DateTime } from "luxon"; import { DateTime } from "luxon";
@ -12,7 +12,7 @@
const acknowledgeWarning = async (idx: number) => { const acknowledgeWarning = async (idx: number) => {
try { try {
await apiFetchClient<any>(`/auth/warnings/${data.warnings[idx].id}/ack`, "POST"); await fastFetchClient(`/auth/warnings/${data.warnings[idx].id}/ack`, "POST");
addToast({ addToast({
header: "Acknowledged", header: "Acknowledged",
body: `Marked warning #${data.warnings[idx].id} as read.`, body: `Marked warning #${data.warnings[idx].id} as read.`,