refactor: switch from Axios for Fetch API (#840)

* refactor: switch ExternalAPI to Fetch API

* fix: add missing auth token in Plex request

* fix: send proper URL params

* ci: try to fix format checker

* ci: ci: try to fix format checker

* ci: try to fix format checker

* refactor: make tautulli use the ExternalAPI class

* refactor: add rate limit to fetch api

* refactor: add rate limit to fetch api

* refactor: switch server from axios to fetch api

* refactor: switch frontend from axios to fetch api

* fix: switch from URL objects to strings

* fix: use the right search params for ExternalAPI

* fix: better log for ExternalAPI errors

* feat: add retry to external API requests

* fix: try to fix network errors with IPv6

* fix: imageProxy rate limit

* revert: remove retry to external API requests

* feat: set IPv4 first as an option

* fix(jellyfinapi): add missing argument in JellyfinAPI constructor

* refactor: clean the rate limit utility
This commit is contained in:
Gauthier
2024-07-14 19:04:36 +02:00
committed by GitHub
parent ae955e9e7c
commit b36bb3fa58
100 changed files with 5380 additions and 10870 deletions

View File

@@ -4,7 +4,6 @@ import type { User } from '@app/hooks/useUser';
import { useUser } from '@app/hooks/useUser';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import axios from 'axios';
import { useEffect, useState } from 'react';
import { useIntl } from 'react-intl';
import { useToasts } from 'react-toast-notifications';
@@ -45,10 +44,18 @@ const BulkEditModal = ({
const updateUsers = async () => {
try {
setIsSaving(true);
const { data: updated } = await axios.put<User[]>(`/api/v1/user`, {
ids: selectedUserIds,
permissions: currentPermission,
const res = await fetch('/api/v1/user', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
ids: selectedUserIds,
permissions: currentPermission,
}),
});
if (!res.ok) throw new Error();
const updated: User[] = await res.json();
if (onComplete) {
onComplete(updated);
}

View File

@@ -4,7 +4,6 @@ import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import type { UserResultsResponse } from '@server/interfaces/api/userInterfaces';
import axios from 'axios';
import getConfig from 'next/config';
import Image from 'next/image';
import { useState } from 'react';
@@ -69,10 +68,17 @@ const JellyfinImportModal: React.FC<JellyfinImportProps> = ({
setImporting(true);
try {
const { data: createdUsers } = await axios.post(
'/api/v1/user/import-from-jellyfin',
{ jellyfinUserIds: selectedUsers }
);
const res = await fetch('/api/v1/user/import-from-jellyfin', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
jellyfinUserIds: selectedUsers,
}),
});
if (!res.ok) throw new Error();
const { data: createdUsers } = await res.json();
if (!createdUsers.length) {
throw new Error('No users were imported from Jellyfin.');

View File

@@ -3,7 +3,6 @@ import Modal from '@app/components/Common/Modal';
import useSettings from '@app/hooks/useSettings';
import globalMessages from '@app/i18n/globalMessages';
import defineMessages from '@app/utils/defineMessages';
import axios from 'axios';
import Image from 'next/image';
import { useState } from 'react';
import { useIntl } from 'react-intl';
@@ -48,10 +47,17 @@ const PlexImportModal = ({ onCancel, onComplete }: PlexImportProps) => {
setImporting(true);
try {
const { data: createdUsers } = await axios.post(
'/api/v1/user/import-from-plex',
{ plexIds: selectedUsers }
);
const res = await fetch('/api/v1/user/import-from-plex', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
plexIds: selectedUsers,
}),
});
if (!res.ok) throw new Error();
const { data: createdUsers } = await res.json();
if (!createdUsers.length) {
throw new Error('No users were imported from Plex.');

View File

@@ -27,7 +27,6 @@ import {
import { MediaServerType } from '@server/constants/server';
import type { UserResultsResponse } from '@server/interfaces/api/userInterfaces';
import { hasPermission } from '@server/lib/permissions';
import axios from 'axios';
import { Field, Form, Formik } from 'formik';
import getConfig from 'next/config';
import Image from 'next/image';
@@ -183,7 +182,10 @@ const UserList = () => {
setDeleting(true);
try {
await axios.delete(`/api/v1/user/${deleteModal.user?.id}`);
const res = await fetch(`/api/v1/user/${deleteModal.user?.id}`, {
method: 'DELETE',
});
if (!res.ok) throw new Error();
addToast(intl.formatMessage(messages.userdeleted), {
autoDismiss: true,
@@ -282,11 +284,18 @@ const UserList = () => {
validationSchema={CreateUserSchema}
onSubmit={async (values) => {
try {
await axios.post('/api/v1/user', {
username: values.displayName,
email: values.email,
password: values.genpassword ? null : values.password,
const res = await fetch('/api/v1/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: values.displayName,
email: values.email,
password: values.genpassword ? null : values.password,
}),
});
if (!res.ok) throw new Error();
addToast(intl.formatMessage(messages.usercreatedsuccess), {
appearance: 'success',
autoDismiss: true,