2023-10-05 16:06:19 +02:00
|
|
|
/*
|
|
|
|
GoToSocial
|
|
|
|
Copyright (C) GoToSocial Authors admin@gotosocial.org
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU Affero General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU Affero General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Affero General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
|
|
|
|
import type {
|
|
|
|
BaseQueryFn,
|
|
|
|
FetchArgs,
|
|
|
|
FetchBaseQueryError,
|
|
|
|
} from '@reduxjs/toolkit/query/react';
|
|
|
|
import { serialize as serializeForm } from "object-to-formdata";
|
2024-05-01 15:11:22 +02:00
|
|
|
import type { FetchBaseQueryMeta } from "@reduxjs/toolkit/dist/query/fetchBaseQuery";
|
2023-10-05 16:06:19 +02:00
|
|
|
import type { RootState } from '../../redux/store';
|
2023-10-17 12:46:06 +02:00
|
|
|
import { InstanceV1 } from '../types/instance';
|
2023-10-05 16:06:19 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* GTSFetchArgs extends standard FetchArgs used by
|
|
|
|
* RTK Query with a couple helpers of our own.
|
|
|
|
*/
|
|
|
|
export interface GTSFetchArgs extends FetchArgs {
|
|
|
|
/**
|
|
|
|
* If provided, will be used as base URL. Else,
|
|
|
|
* will fall back to authorized instance as baseUrl.
|
|
|
|
*/
|
|
|
|
baseUrl?: string;
|
|
|
|
/**
|
|
|
|
* If true, and no args.body is set, or args.body is empty,
|
|
|
|
* then a null response will be returned from the API call.
|
|
|
|
*/
|
|
|
|
discardEmpty?: boolean;
|
|
|
|
/**
|
|
|
|
* If true, then args.body will be serialized
|
|
|
|
* as FormData before submission.
|
|
|
|
*/
|
|
|
|
asForm?: boolean;
|
2024-07-31 16:03:34 +02:00
|
|
|
/**
|
|
|
|
* If set, then Accept header will
|
|
|
|
* be set to the provided contentType.
|
|
|
|
*/
|
|
|
|
acceptContentType?: string;
|
2023-10-05 16:06:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* gtsBaseQuery wraps the redux toolkit fetchBaseQuery with some helper functionality.
|
|
|
|
*
|
|
|
|
* For an explainer of what's happening in this function, see:
|
|
|
|
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#customizing-queries-with-basequery
|
|
|
|
* - https://redux-toolkit.js.org/rtk-query/usage/customizing-queries#constructing-a-dynamic-base-url-using-redux-state
|
|
|
|
*
|
|
|
|
* @param args
|
|
|
|
* @param api
|
|
|
|
* @param extraOptions
|
|
|
|
* @returns
|
|
|
|
*/
|
|
|
|
const gtsBaseQuery: BaseQueryFn<
|
|
|
|
string | GTSFetchArgs,
|
|
|
|
any,
|
2024-05-01 15:11:22 +02:00
|
|
|
FetchBaseQueryError,
|
|
|
|
{},
|
|
|
|
FetchBaseQueryMeta
|
2023-10-05 16:06:19 +02:00
|
|
|
> = async (args, api, extraOptions) => {
|
|
|
|
// Retrieve state at the moment
|
|
|
|
// this function was called.
|
|
|
|
const state = api.getState() as RootState;
|
|
|
|
const { instanceUrl, token } = state.oauth;
|
|
|
|
|
|
|
|
// Derive baseUrl dynamically.
|
2023-10-17 12:46:06 +02:00
|
|
|
let baseUrl: string | undefined;
|
2023-10-05 16:06:19 +02:00
|
|
|
|
2024-07-31 16:03:34 +02:00
|
|
|
// Assume Accept value of
|
|
|
|
// "application/json" by default.
|
|
|
|
let accept = "application/json";
|
|
|
|
|
2023-10-05 16:06:19 +02:00
|
|
|
// Check if simple string baseUrl provided
|
|
|
|
// as args, or if more complex args provided.
|
|
|
|
if (typeof args === "string") {
|
|
|
|
baseUrl = args;
|
|
|
|
} else {
|
|
|
|
if (args.baseUrl != undefined) {
|
|
|
|
baseUrl = args.baseUrl;
|
|
|
|
} else {
|
|
|
|
baseUrl = instanceUrl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.discardEmpty) {
|
|
|
|
if (args.body == undefined || Object.keys(args.body).length == 0) {
|
|
|
|
return { data: null };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (args.asForm) {
|
|
|
|
args.body = serializeForm(args.body, {
|
|
|
|
// Array indices, for profile fields.
|
|
|
|
indices: true,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-07-31 16:03:34 +02:00
|
|
|
if (args.acceptContentType !== undefined) {
|
|
|
|
accept = args.acceptContentType;
|
|
|
|
}
|
|
|
|
|
2023-10-05 16:06:19 +02:00
|
|
|
// Delete any of our extended arguments
|
|
|
|
// to avoid confusing fetchBaseQuery.
|
|
|
|
delete args.baseUrl;
|
|
|
|
delete args.discardEmpty;
|
|
|
|
delete args.asForm;
|
2024-07-31 16:03:34 +02:00
|
|
|
delete args.acceptContentType;
|
2023-10-05 16:06:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!baseUrl) {
|
|
|
|
return {
|
|
|
|
error: {
|
|
|
|
status: 400,
|
|
|
|
statusText: 'Bad Request',
|
|
|
|
data: {"error":"No baseUrl set for request"},
|
|
|
|
},
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetchBaseQuery({
|
|
|
|
baseUrl: baseUrl,
|
|
|
|
prepareHeaders: (headers) => {
|
|
|
|
if (token != undefined) {
|
|
|
|
headers.set('Authorization', token);
|
|
|
|
}
|
2024-07-31 16:03:34 +02:00
|
|
|
|
|
|
|
headers.set("Accept", accept);
|
2023-10-05 16:06:19 +02:00
|
|
|
return headers;
|
|
|
|
},
|
2024-07-31 16:03:34 +02:00
|
|
|
responseHandler: (response) => {
|
|
|
|
// Return just text if caller has
|
|
|
|
// set a custom accept content-type.
|
|
|
|
if (accept !== "application/json") {
|
|
|
|
return response.text();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else return good old
|
|
|
|
// fashioned JSON baby!
|
|
|
|
return response.json();
|
|
|
|
},
|
2023-10-05 16:06:19 +02:00
|
|
|
})(args, api, extraOptions);
|
|
|
|
};
|
|
|
|
|
|
|
|
export const gtsApi = createApi({
|
|
|
|
reducerPath: "api",
|
|
|
|
baseQuery: gtsBaseQuery,
|
|
|
|
tagTypes: [
|
|
|
|
"Auth",
|
|
|
|
"Emoji",
|
2024-06-18 18:18:00 +02:00
|
|
|
"Report",
|
2023-10-05 16:06:19 +02:00
|
|
|
"Account",
|
|
|
|
"InstanceRules",
|
2024-05-05 13:47:22 +02:00
|
|
|
"HTTPHeaderAllows",
|
|
|
|
"HTTPHeaderBlocks",
|
2024-07-17 16:46:52 +02:00
|
|
|
"DefaultInteractionPolicies",
|
2024-08-24 11:49:37 +02:00
|
|
|
"InteractionRequest",
|
2024-11-21 14:09:58 +01:00
|
|
|
"DomainPermissionDraft",
|
|
|
|
"DomainPermissionExclude"
|
2023-10-05 16:06:19 +02:00
|
|
|
],
|
2023-10-17 12:46:06 +02:00
|
|
|
endpoints: (build) => ({
|
|
|
|
instanceV1: build.query<InstanceV1, void>({
|
2023-10-05 16:06:19 +02:00
|
|
|
query: () => ({
|
|
|
|
url: `/api/v1/instance`
|
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
});
|
|
|
|
|
2023-10-17 12:46:06 +02:00
|
|
|
/**
|
|
|
|
* Query /api/v1/instance to retrieve basic instance information.
|
|
|
|
* This endpoint does not require authentication/authorization.
|
|
|
|
* TODO: move this to ./instance.
|
|
|
|
*/
|
|
|
|
const useInstanceV1Query = gtsApi.useInstanceV1Query;
|
|
|
|
|
|
|
|
export { useInstanceV1Query };
|