From 13fe20d47e6806cb7669672cc043c714a78b3d9b Mon Sep 17 00:00:00 2001 From: tamaina Date: Sun, 21 May 2023 12:54:39 +0000 Subject: [PATCH] wip --- packages/misskey-js/src/api.ts | 30 +---- packages/misskey-js/src/endpoints.ts | 123 +------------------- packages/misskey-js/src/endpoints.types.ts | 128 +++++++++++++++++++++ packages/misskey-js/src/schemas.ts | 2 +- 4 files changed, 135 insertions(+), 148 deletions(-) create mode 100644 packages/misskey-js/src/endpoints.types.ts diff --git a/packages/misskey-js/src/api.ts b/packages/misskey-js/src/api.ts index 974cb35ac..19aa9f630 100644 --- a/packages/misskey-js/src/api.ts +++ b/packages/misskey-js/src/api.ts @@ -1,4 +1,4 @@ -import type { Endpoints } from './api.types.js'; +import type { Endpoints, SchemaOrUndefined, IEndpointMeta, EndpointDefines } from './endpoints.types'; const MK_API_ERROR = Symbol(); @@ -25,15 +25,8 @@ export type FetchLike = (input: string, init?: { json(): Promise; }>; -type IsNeverType = [T] extends [never] ? true : false; - -type StrictExtract = Cond extends Union ? Union : never; - -type IsCaseMatched = - IsNeverType> extends false ? true : false; - -type GetCaseResult = - StrictExtract[1]; +type Response, DD extends EndpointDefines[number] = D['defines'][number]> = + P extends DD['req'] ? SchemaOrUndefined : never; export class APIClient { public origin: string; @@ -52,22 +45,9 @@ export class APIClient { this.fetch = opts.fetch ?? ((...args) => fetch(...args)); } - public request( + public request, D extends IEndpointMeta = Endpoints[E], R = Response>( endpoint: E, params: P = {} as P, credential?: string | null | undefined, - ): Promise extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - IsCaseMatched extends true ? GetCaseResult : - Endpoints[E]['res']['$switch']['$default'] - : Endpoints[E]['res']> + ): Promise { const promise = new Promise((resolve, reject) => { this.fetch(`${this.origin}/api/${endpoint}`, { diff --git a/packages/misskey-js/src/endpoints.ts b/packages/misskey-js/src/endpoints.ts index 6de8146a1..0836e813a 100644 --- a/packages/misskey-js/src/endpoints.ts +++ b/packages/misskey-js/src/endpoints.ts @@ -1,126 +1,5 @@ +import { IEndpointMeta } from "./endpoints.types"; import { localUsernameSchema, passwordSchema } from "./schemas/user"; -import type { JSONSchema7 } from 'schema-type'; - -export type RolePolicies = { - gtlAvailable: boolean; - ltlAvailable: boolean; - canPublicNote: boolean; - canInvite: boolean; - canManageCustomEmojis: boolean; - canSearchNotes: boolean; - canHideAds: boolean; - driveCapacityMb: number; - pinLimit: number; - antennaLimit: number; - wordMuteLimit: number; - webhookLimit: number; - clipLimit: number; - noteEachClipsLimit: number; - userListLimit: number; - userEachUserListsLimit: number; - rateLimitFactor: number; -}; - -export type EndpointDefines = ReadonlyArray<{ req: JSONSchema7 | undefined; res: JSONSchema7 | undefined; }>; - -export interface IEndpointMeta { - readonly stability?: 'deprecated' | 'experimental' | 'stable'; - - readonly tags?: ReadonlyArray; - - readonly errors?: { - readonly [key: string]: { - readonly message: string; - readonly code: string; - readonly id: string; - }; - }; - - readonly defines: EndpointDefines; - - /** - * このエンドポイントにリクエストするのにユーザー情報が必須か否か - * 省略した場合は false として解釈されます。 - */ - readonly requireCredential?: boolean; - - /** - * isModeratorなロールを必要とするか - */ - readonly requireModerator?: boolean; - - /** - * isAdministratorなロールを必要とするか - */ - readonly requireAdmin?: boolean; - - readonly requireRolePolicy?: keyof RolePolicies; - - /** - * 引っ越し済みのユーザーによるリクエストを禁止するか - * 省略した場合は false として解釈されます。 - */ - readonly prohibitMoved?: boolean; - - /** - * エンドポイントのリミテーションに関するやつ - * 省略した場合はリミテーションは無いものとして解釈されます。 - */ - readonly limit?: { - - /** - * 複数のエンドポイントでリミットを共有したい場合に指定するキー - */ - readonly key?: string; - - /** - * リミットを適用する期間(ms) - * このプロパティを設定する場合、max プロパティも設定する必要があります。 - */ - readonly duration?: number; - - /** - * durationで指定した期間内にいくつまでリクエストできるのか - * このプロパティを設定する場合、duration プロパティも設定する必要があります。 - */ - readonly max?: number; - - /** - * 最低でもどれくらいの間隔を開けてリクエストしなければならないか(ms) - */ - readonly minInterval?: number; - }; - - /** - * ファイルの添付を必要とするか否か - * 省略した場合は false として解釈されます。 - */ - readonly requireFile?: boolean; - - /** - * サードパーティアプリからはリクエストすることができないか否か - * 省略した場合は false として解釈されます。 - */ - readonly secure?: boolean; - - /** - * エンドポイントの種類 - * パーミッションの実現に利用されます。 - */ - readonly kind?: string; - - readonly description?: string; - - /** - * GETでのリクエストを許容するか否か - */ - readonly allowGet?: boolean; - - /** - * 正常応答をキャッシュ (Cache-Control: public) する秒数 - */ - readonly cacheSec?: number; -} export const endpoints = { "admin/accounts/create": { diff --git a/packages/misskey-js/src/endpoints.types.ts b/packages/misskey-js/src/endpoints.types.ts new file mode 100644 index 000000000..5f1d8405d --- /dev/null +++ b/packages/misskey-js/src/endpoints.types.ts @@ -0,0 +1,128 @@ +import type { JSONSchema7, SchemaType } from 'schema-type'; +import type { References } from './schemas'; +import type { endpoints } from './endpoints'; + +export type RolePolicies = { + gtlAvailable: boolean; + ltlAvailable: boolean; + canPublicNote: boolean; + canInvite: boolean; + canManageCustomEmojis: boolean; + canSearchNotes: boolean; + canHideAds: boolean; + driveCapacityMb: number; + pinLimit: number; + antennaLimit: number; + wordMuteLimit: number; + webhookLimit: number; + clipLimit: number; + noteEachClipsLimit: number; + userListLimit: number; + userEachUserListsLimit: number; + rateLimitFactor: number; +}; + +export type EndpointDefines = ReadonlyArray<{ req: JSONSchema7 | undefined; res: JSONSchema7 | undefined; }>; + +export interface IEndpointMeta { + readonly stability?: 'deprecated' | 'experimental' | 'stable'; + + readonly tags?: ReadonlyArray; + + readonly errors?: { + readonly [key: string]: { + readonly message: string; + readonly code: string; + readonly id: string; + }; + }; + + readonly defines: EndpointDefines; + + /** + * このエンドポイントにリクエストするのにユーザー情報が必須か否か + * 省略した場合は false として解釈されます。 + */ + readonly requireCredential?: boolean; + + /** + * isModeratorなロールを必要とするか + */ + readonly requireModerator?: boolean; + + /** + * isAdministratorなロールを必要とするか + */ + readonly requireAdmin?: boolean; + + readonly requireRolePolicy?: keyof RolePolicies; + + /** + * 引っ越し済みのユーザーによるリクエストを禁止するか + * 省略した場合は false として解釈されます。 + */ + readonly prohibitMoved?: boolean; + + /** + * エンドポイントのリミテーションに関するやつ + * 省略した場合はリミテーションは無いものとして解釈されます。 + */ + readonly limit?: { + + /** + * 複数のエンドポイントでリミットを共有したい場合に指定するキー + */ + readonly key?: string; + + /** + * リミットを適用する期間(ms) + * このプロパティを設定する場合、max プロパティも設定する必要があります。 + */ + readonly duration?: number; + + /** + * durationで指定した期間内にいくつまでリクエストできるのか + * このプロパティを設定する場合、duration プロパティも設定する必要があります。 + */ + readonly max?: number; + + /** + * 最低でもどれくらいの間隔を開けてリクエストしなければならないか(ms) + */ + readonly minInterval?: number; + }; + + /** + * ファイルの添付を必要とするか否か + * 省略した場合は false として解釈されます。 + */ + readonly requireFile?: boolean; + + /** + * サードパーティアプリからはリクエストすることができないか否か + * 省略した場合は false として解釈されます。 + */ + readonly secure?: boolean; + + /** + * エンドポイントの種類 + * パーミッションの実現に利用されます。 + */ + readonly kind?: string; + + readonly description?: string; + + /** + * GETでのリクエストを許容するか否か + */ + readonly allowGet?: boolean; + + /** + * 正常応答をキャッシュ (Cache-Control: public) する秒数 + */ + readonly cacheSec?: number; +} + +export type SchemaOrUndefined = T extends JSONSchema7 ? SchemaType : never; + +export type Endpoints = typeof endpoints; diff --git a/packages/misskey-js/src/schemas.ts b/packages/misskey-js/src/schemas.ts index 5558b01ba..e51ddb190 100644 --- a/packages/misskey-js/src/schemas.ts +++ b/packages/misskey-js/src/schemas.ts @@ -76,7 +76,7 @@ export const refs = { Announcement: packedAnnouncementSchema, } as const satisfies { [x: string]: JSONSchema7Definition }; -type References = GetRefs; +export type References = GetRefs; export type Packed> = GetDef; export type Def> = GetDef;