import uwuzuError from "./lib/error"; import uwuzuFetch from "./lib/fetch"; export type parserType = ( data: any, type: "request" | "response", endpoint: string, ) => any; interface sdkOptions { /** uwuzuサーバーのorigin */ origin: string; /** * リクエスト/レスポンスのパーサー */ parser: parserType; /** * 通信に失敗した際の再試行回数です。 * 全て失敗した場合はエラーを発生します。 * 指定しない場合は5回が設定されます。 */ retry?: number; /** * 通信に失敗した際に動作する再試行間の待機時間(ミリ秒)です。 * 再試行毎に2倍にされます。 * 指定しない場合は500msが設定されます。 */ waiting?: number; } /* 必須かどうかの推論 */ type BodyArgs = M[E] extends { body: never } ? [] : M[E] extends { body: infer B } ? [body: B] : M[E] extends { body?: infer B } ? [body?: B] : []; export default class uwuzu< M extends { [K in keyof M]: { body?: any; response: any } } > { readonly origin: string; readonly parser: parserType; readonly retry: number; readonly waiting: number; private _token: string | null = null; constructor(options: sdkOptions) { this.origin = options.origin; this.parser = options.parser; this.retry = options.retry ?? 5; this.waiting = options.waiting ?? 500; if (!this.parser) throw new uwuzuError("Invalid parser."); if (this.retry < 1) throw new uwuzuError("Invalid retry count."); if (this.waiting < 1) throw new uwuzuError("Invalid base waiting time."); if (options.origin !== new URL(options.origin).origin) throw new uwuzuError("Invalid origin."); } /** APIトークン */ get token(): string | null { return this._token; } set token(token: string) { if (token.length !== 64) throw new uwuzuError("Invalid token."); this._token = token; } /** APIリクエスト */ // 型あり public async request( endpoint: E, ...args: BodyArgs ): Promise; // 型なし public async request( endpoint: string, body?: any ): Promise; public async request( endpoint: string, ...args: any[] ): Promise { let bodyParsed: any = args[0] ?? {}; if (typeof bodyParsed === "object") { bodyParsed = this.parser(bodyParsed, "request", endpoint); bodyParsed = { ...bodyParsed, token: this._token, }; bodyParsed = JSON.stringify(bodyParsed); } const req = await uwuzuFetch( this.origin, this.retry, this.waiting, "endpoint", endpoint as string, { method: "POST", cache: "no-store", body: bodyParsed, } ); const res = this.parser(await req.json(), "response", endpoint); return res; } }