115 lines
3.0 KiB
TypeScript
115 lines
3.0 KiB
TypeScript
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 keyof M> =
|
|
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<E extends keyof M>(
|
|
endpoint: E,
|
|
...args: BodyArgs<M, E>
|
|
): Promise<M[E]["response"]>;
|
|
// 型なし
|
|
public async request(
|
|
endpoint: string,
|
|
body?: any
|
|
): Promise<any>;
|
|
|
|
public async request(
|
|
endpoint: string,
|
|
...args: any[]
|
|
): Promise<any> {
|
|
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;
|
|
}
|
|
} |