This commit is contained in:
tamaina 2023-05-21 13:53:55 +00:00
parent 13fe20d47e
commit 0853b2fe42
4 changed files with 29 additions and 23 deletions

View File

@ -1,21 +1,25 @@
import { Endpoints } from 'misskey-js/built/api.types'; import type { Endpoints, SchemaOrUndefined, ResponseOf, IEndpointMeta } from 'misskey-js/built/endpoints.types';
import { ref } from 'vue'; import { ref } from 'vue';
import { apiUrl } from '@/config'; import { apiUrl } from '@/config';
import { $i } from '@/account'; import { $i } from '@/account';
export const pendingApiRequestsCount = ref(0); export const pendingApiRequestsCount = ref(0);
// Implements Misskey.api.ApiClient.request // Implements Misskey.api.ApiClient.request
export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Endpoints[E]['res']> { export function api<E extends keyof Endpoints, P extends SchemaOrUndefined<Endpoints[E]['defines'][number]['req']>, D extends IEndpointMeta = Endpoints[E]>(
endpoint: E, params?: P, token?: string | null | undefined, signal?: AbortSignal
): Promise<ResponseOf<D, P>> {
const data: (P | Record<string, any>) & { i?: string | null } = params ?? {};
pendingApiRequestsCount.value++; pendingApiRequestsCount.value++;
const onFinally = () => { const onFinally = () => {
pendingApiRequestsCount.value--; pendingApiRequestsCount.value--;
}; };
const promise = new Promise<Endpoints[E]['res'] | void>((resolve, reject) => { const promise = new Promise<ResponseOf<D, P> | void>((resolve, reject) => {
// Append a credential // Append a credential
if ($i) (data as any).i = $i.token; if ($i) data.i = $i.token;
if (token !== undefined) (data as any).i = token; if (token !== undefined) data.i = token;
// Send request // Send request
window.fetch(endpoint.indexOf('://') > -1 ? endpoint : `${apiUrl}/${endpoint}`, { window.fetch(endpoint.indexOf('://') > -1 ? endpoint : `${apiUrl}/${endpoint}`, {
@ -42,20 +46,22 @@ export function api<E extends keyof Endpoints, P extends Endpoints[E]['req']>(en
promise.then(onFinally, onFinally); promise.then(onFinally, onFinally);
return promise; return promise as Promise<ResponseOf<D, P>>;
} }
// Implements Misskey.api.ApiClient.request // Implements Misskey.api.ApiClient.request
export function apiGet <E extends keyof Endpoints, P extends Endpoints[E]['req']>(endpoint: E, data: P = {} as any): Promise<Endpoints[E]['res']> { export function apiGet<E extends keyof Endpoints, P extends SchemaOrUndefined<Endpoints[E]['defines'][number]['req']>, D extends IEndpointMeta = Endpoints[E]>(
endpoint: E, params?: P, token?: string | null | undefined, signal?: AbortSignal
): Promise<ResponseOf<D, P>> {
pendingApiRequestsCount.value++; pendingApiRequestsCount.value++;
const onFinally = () => { const onFinally = () => {
pendingApiRequestsCount.value--; pendingApiRequestsCount.value--;
}; };
const query = new URLSearchParams(data as any); const query = new URLSearchParams((params ?? {}) as Record<string, string>);
const promise = new Promise<Endpoints[E]['res'] | void>((resolve, reject) => { const promise = new Promise<ResponseOf<D, P> | void>((resolve, reject) => {
// Send request // Send request
window.fetch(`${apiUrl}/${endpoint}?${query}`, { window.fetch(`${apiUrl}/${endpoint}?${query}`, {
method: 'GET', method: 'GET',
@ -76,5 +82,5 @@ export function apiGet <E extends keyof Endpoints, P extends Endpoints[E]['req']
promise.then(onFinally, onFinally); promise.then(onFinally, onFinally);
return promise; return promise as Promise<ResponseOf<D, P>>;
} }

View File

@ -1,4 +1,4 @@
import type { Endpoints, SchemaOrUndefined, IEndpointMeta, EndpointDefines } from './endpoints.types'; import type { Endpoints, SchemaOrUndefined, IEndpointMeta, ResponseOf } from './endpoints.types';
const MK_API_ERROR = Symbol(); const MK_API_ERROR = Symbol();
@ -25,9 +25,6 @@ export type FetchLike = (input: string, init?: {
json(): Promise<any>; json(): Promise<any>;
}>; }>;
type Response<D extends IEndpointMeta, P extends SchemaOrUndefined<D['defines'][number]['req']>, DD extends EndpointDefines[number] = D['defines'][number]> =
P extends DD['req'] ? SchemaOrUndefined<DD['res']> : never;
export class APIClient { export class APIClient {
public origin: string; public origin: string;
public credential: string | null | undefined; public credential: string | null | undefined;
@ -45,8 +42,8 @@ export class APIClient {
this.fetch = opts.fetch ?? ((...args) => fetch(...args)); this.fetch = opts.fetch ?? ((...args) => fetch(...args));
} }
public request<E extends keyof Endpoints, P extends SchemaOrUndefined<D['defines'][number]['req']>, D extends IEndpointMeta = Endpoints[E], R = Response<D, P>>( public request<E extends keyof Endpoints, P extends SchemaOrUndefined<D['defines'][number]['req']>, D extends IEndpointMeta = Endpoints[E], R = ResponseOf<D, P>>(
endpoint: E, params: P = {} as P, credential?: string | null | undefined, endpoint: E, params: P, credential?: string | null | undefined,
): Promise<R> ): Promise<R>
{ {
const promise = new Promise((resolve, reject) => { const promise = new Promise((resolve, reject) => {

View File

@ -37,7 +37,7 @@ export interface IEndpointMeta {
}; };
}; };
readonly defines: EndpointDefines; readonly defines: ReadonlyArray<{ req: JSONSchema7 | undefined; res: JSONSchema7 | undefined; }>;
/** /**
* *
@ -123,6 +123,9 @@ export interface IEndpointMeta {
readonly cacheSec?: number; readonly cacheSec?: number;
} }
export type SchemaOrUndefined<T extends JSONSchema7 | undefined> = T extends JSONSchema7 ? SchemaType<T, References> : never; export type SchemaOrUndefined<T extends JSONSchema7 | undefined> = T extends JSONSchema7 ? SchemaType<T, References> : (void | Record<string, never>);
export type ResponseOf<D extends IEndpointMeta, P, DD extends D['defines'][number] = D['defines'][number]> =
P extends SchemaOrUndefined<DD['req']> ? SchemaOrUndefined<DD['res']> : never;
export type Endpoints = typeof endpoints; export type Endpoints = typeof endpoints;

View File

@ -626,7 +626,7 @@ importers:
version: 29.5.0 version: 29.5.0
schema-type: schema-type:
specifier: github:misskey-dev/schema-type specifier: github:misskey-dev/schema-type
version: github.com/misskey-dev/schema-type/428153dc8034004951ad8a309c65f4e3fe579441(typescript@5.0.4) version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4)
packages/frontend: packages/frontend:
dependencies: dependencies:
@ -1026,7 +1026,7 @@ importers:
version: 4.4.0 version: 4.4.0
schema-type: schema-type:
specifier: github:misskey-dev/schema-type specifier: github:misskey-dev/schema-type
version: github.com/misskey-dev/schema-type/428153dc8034004951ad8a309c65f4e3fe579441(typescript@5.0.4) version: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4)
ts-essentials: ts-essentials:
specifier: ^9.3.2 specifier: ^9.3.2
version: 9.3.2(typescript@5.0.4) version: 9.3.2(typescript@5.0.4)
@ -20455,9 +20455,9 @@ packages:
version: 0.0.0 version: 0.0.0
dev: false dev: false
github.com/misskey-dev/schema-type/428153dc8034004951ad8a309c65f4e3fe579441(typescript@5.0.4): github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3(typescript@5.0.4):
resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/428153dc8034004951ad8a309c65f4e3fe579441} resolution: {tarball: https://codeload.github.com/misskey-dev/schema-type/tar.gz/e24efd7bba40f638b3b687298873fa56de56aab3}
id: github.com/misskey-dev/schema-type/428153dc8034004951ad8a309c65f4e3fe579441 id: github.com/misskey-dev/schema-type/e24efd7bba40f638b3b687298873fa56de56aab3
name: schema-type name: schema-type
version: 1.0.0 version: 1.0.0
dependencies: dependencies: