/* * SPDX-FileCopyrightText: syuilo and other misskey contributors * SPDX-License-Identifier: AGPL-3.0-only */ import * as Misskey from 'misskey-js'; import { ref } from 'vue'; import { apiUrl } from '@/config.js'; import { $i } from '@/account.js'; export const pendingApiRequestsCount = ref(0); // Implements Misskey.api.ApiClient.request export function api(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise { if (endpoint.includes('://')) throw new Error('invalid endpoint'); pendingApiRequestsCount.value++; const onFinally = () => { pendingApiRequestsCount.value--; }; const promise = new Promise((resolve, reject) => { // Append a credential if ($i) (data as any).i = $i.token; if (token !== undefined) (data as any).i = token; // Send request window.fetch(`${apiUrl}/${endpoint}`, { method: 'POST', body: JSON.stringify(data), credentials: 'omit', cache: 'no-cache', headers: { 'Content-Type': 'application/json', }, signal, }).then(async (res) => { const body = res.status === 204 ? null : await res.json(); if (res.status === 200) { resolve(body); } else if (res.status === 204) { resolve(); } else { reject(body.error); } }).catch(reject); }); promise.then(onFinally, onFinally); return promise; } export function apiExternal(hostUrl: string, endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise { if (!/^https?:\/\//.test(hostUrl)) throw new Error('invalid host name'); if (endpoint.includes('://')) throw new Error('invalid endpoint'); pendingApiRequestsCount.value++; const onFinally = () => { pendingApiRequestsCount.value--; }; const promise = new Promise((resolve, reject) => { // Append a credential (data as any).i = token; const fullUrl = (hostUrl.slice(-1) === '/' ? hostUrl.slice(0, -1) : hostUrl) + '/api/' + (endpoint.slice(0, 1) === '/' ? endpoint.slice(1) : endpoint); // Send request window.fetch(fullUrl, { method: 'POST', body: JSON.stringify(data), credentials: 'omit', cache: 'no-cache', headers: { 'Content-Type': 'application/json', }, signal, }).then(async (res) => { const body = res.status === 204 ? null : await res.json(); if (res.status === 200) { resolve(body); } else if (res.status === 204) { resolve(); } else { reject(body.error); } }).catch(reject); }); promise.then(onFinally, onFinally); return promise; } // Implements Misskey.api.ApiClient.request export function apiGet (endpoint: E, data: P = {} as any): Promise { pendingApiRequestsCount.value++; const onFinally = () => { pendingApiRequestsCount.value--; }; const query = new URLSearchParams(data as any); const promise = new Promise((resolve, reject) => { // Send request window.fetch(`${apiUrl}/${endpoint}?${query}`, { method: 'GET', credentials: 'omit', cache: 'default', }).then(async (res) => { const body = res.status === 204 ? null : await res.json(); if (res.status === 200) { resolve(body); } else if (res.status === 204) { resolve(); } else { reject(body.error); } }).catch(reject); }); promise.then(onFinally, onFinally); return promise; }