型レベルでのswitch-case機構をmisskey-jsからfrontendに持ち込めるようにした
This commit is contained in:
parent
5f88d62f87
commit
de37897f92
|
|
@ -10,7 +10,12 @@ import { $i } from '@/account.js';
|
|||
export const pendingApiRequestsCount = ref(0);
|
||||
|
||||
// Implements Misskey.api.ApiClient.request
|
||||
export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(endpoint: E, data: P = {} as any, token?: string | null | undefined, signal?: AbortSignal): Promise<Misskey.Endpoints[E]['res']> {
|
||||
export function api<E extends keyof Misskey.Endpoints, P extends Misskey.Endpoints[E]['req']>(
|
||||
endpoint: E,
|
||||
data: P = {} as any,
|
||||
token?: string | null | undefined,
|
||||
signal?: AbortSignal,
|
||||
): Promise<Misskey.api.SwitchCaseResponseType<E, P>> {
|
||||
if (endpoint.includes('://')) throw new Error('invalid endpoint');
|
||||
pendingApiRequestsCount.value++;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,10 @@
|
|||
import { SwitchCase } from './api.types';
|
||||
import { SwitchCaseResponseType } from './api.types';
|
||||
import type { Endpoints } from './api.types';
|
||||
|
||||
export {
|
||||
SwitchCaseResponseType,
|
||||
} from './api.types';
|
||||
|
||||
const MK_API_ERROR = Symbol();
|
||||
|
||||
export type APIError = {
|
||||
|
|
@ -16,28 +20,15 @@ export function isAPIError(reason: any): reason is APIError {
|
|||
}
|
||||
|
||||
export type FetchLike = (input: string, init?: {
|
||||
method?: string;
|
||||
body?: string;
|
||||
credentials?: RequestCredentials;
|
||||
cache?: RequestCache;
|
||||
headers: {[key in string]: string}
|
||||
}) => Promise<{
|
||||
status: number;
|
||||
json(): Promise<any>;
|
||||
}>;
|
||||
|
||||
type IsNeverType<T> = [T] extends [never] ? true : false;
|
||||
type StrictExtract<Union, Cond> = Cond extends Union ? Union : never;
|
||||
|
||||
type IsCaseMatched<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
|
||||
Endpoints[E]['res'] extends SwitchCase
|
||||
? IsNeverType<StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>> extends false ? true : false
|
||||
: false
|
||||
|
||||
type GetCaseResult<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
|
||||
Endpoints[E]['res'] extends SwitchCase
|
||||
? StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>[1]
|
||||
: never
|
||||
method?: string;
|
||||
body?: string;
|
||||
credentials?: RequestCredentials;
|
||||
cache?: RequestCache;
|
||||
headers: { [key in string]: string }
|
||||
}) => Promise<{
|
||||
status: number;
|
||||
json(): Promise<any>;
|
||||
}>;
|
||||
|
||||
export class APIClient {
|
||||
public origin: string;
|
||||
|
|
@ -60,20 +51,7 @@ export class APIClient {
|
|||
endpoint: E,
|
||||
params: P = {} as P,
|
||||
credential?: string | null,
|
||||
): Promise<Endpoints[E]['res'] extends SwitchCase
|
||||
?
|
||||
IsCaseMatched<E, P, 0> extends true ? GetCaseResult<E, P, 0> :
|
||||
IsCaseMatched<E, P, 1> extends true ? GetCaseResult<E, P, 1> :
|
||||
IsCaseMatched<E, P, 2> extends true ? GetCaseResult<E, P, 2> :
|
||||
IsCaseMatched<E, P, 3> extends true ? GetCaseResult<E, P, 3> :
|
||||
IsCaseMatched<E, P, 4> extends true ? GetCaseResult<E, P, 4> :
|
||||
IsCaseMatched<E, P, 5> extends true ? GetCaseResult<E, P, 5> :
|
||||
IsCaseMatched<E, P, 6> extends true ? GetCaseResult<E, P, 6> :
|
||||
IsCaseMatched<E, P, 7> extends true ? GetCaseResult<E, P, 7> :
|
||||
IsCaseMatched<E, P, 8> extends true ? GetCaseResult<E, P, 8> :
|
||||
IsCaseMatched<E, P, 9> extends true ? GetCaseResult<E, P, 9> :
|
||||
Endpoints[E]['res']['$switch']['$default'] :
|
||||
Endpoints[E]['res']> {
|
||||
): Promise<SwitchCaseResponseType<E, P>> {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.fetch(`${this.origin}/api/${endpoint}`, {
|
||||
method: 'POST',
|
||||
|
|
|
|||
|
|
@ -2,18 +2,44 @@ import { Endpoints as Gen } from './autogen/endpoint';
|
|||
import { UserDetailed } from './autogen/models';
|
||||
import { UsersShowRequest } from './autogen/entities';
|
||||
|
||||
export type Overwrite<T, U extends { [Key in keyof T]?: unknown }> = Omit<
|
||||
type Overwrite<T, U extends { [Key in keyof T]?: unknown }> = Omit<
|
||||
T,
|
||||
keyof U
|
||||
> & U;
|
||||
|
||||
export type SwitchCase = {
|
||||
type SwitchCase = {
|
||||
$switch: {
|
||||
$cases: [any, any][],
|
||||
$default: any;
|
||||
};
|
||||
};
|
||||
|
||||
type IsNeverType<T> = [T] extends [never] ? true : false;
|
||||
type StrictExtract<Union, Cond> = Cond extends Union ? Union : never;
|
||||
|
||||
type IsCaseMatched<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
|
||||
Endpoints[E]['res'] extends SwitchCase
|
||||
? IsNeverType<StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>> extends false ? true : false
|
||||
: false
|
||||
|
||||
type GetCaseResult<E extends keyof Endpoints, P extends Endpoints[E]['req'], C extends number> =
|
||||
Endpoints[E]['res'] extends SwitchCase
|
||||
? StrictExtract<Endpoints[E]['res']['$switch']['$cases'][C], [P, any]>[1]
|
||||
: never
|
||||
|
||||
export type SwitchCaseResponseType<E extends keyof Endpoints, P extends Endpoints[E]['req']> = Endpoints[E]['res'] extends SwitchCase
|
||||
? IsCaseMatched<E, P, 0> extends true ? GetCaseResult<E, P, 0> :
|
||||
IsCaseMatched<E, P, 1> extends true ? GetCaseResult<E, P, 1> :
|
||||
IsCaseMatched<E, P, 2> extends true ? GetCaseResult<E, P, 2> :
|
||||
IsCaseMatched<E, P, 3> extends true ? GetCaseResult<E, P, 3> :
|
||||
IsCaseMatched<E, P, 4> extends true ? GetCaseResult<E, P, 4> :
|
||||
IsCaseMatched<E, P, 5> extends true ? GetCaseResult<E, P, 5> :
|
||||
IsCaseMatched<E, P, 6> extends true ? GetCaseResult<E, P, 6> :
|
||||
IsCaseMatched<E, P, 7> extends true ? GetCaseResult<E, P, 7> :
|
||||
IsCaseMatched<E, P, 8> extends true ? GetCaseResult<E, P, 8> :
|
||||
IsCaseMatched<E, P, 9> extends true ? GetCaseResult<E, P, 9> :
|
||||
Endpoints[E]['res']['$switch']['$default'] : Endpoints[E]['res'];
|
||||
|
||||
export type Endpoints = Overwrite<
|
||||
Gen,
|
||||
{
|
||||
|
|
@ -22,7 +48,9 @@ export type Endpoints = Overwrite<
|
|||
res: {
|
||||
$switch: {
|
||||
$cases: [[
|
||||
{ userIds: string[]; }, UserDetailed[],
|
||||
{
|
||||
userIds?: string[];
|
||||
}, UserDetailed[],
|
||||
]];
|
||||
$default: UserDetailed;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue