import { createConfig, type HttpClientConfig } from './options.js'; import type { HttpClientOptions } from './options.js'; import { createGql, type Gql } from './gql/plugin.js'; import { createWs, type Ws } from './ws.js'; import { createRestful, type Restful } from './restful.js'; /** HTTP client 插件 */ export type HttpClientPlugin = (client: HttpClient) => HttpClient & TExtends; /** HTTP client */ export class HttpClient { /** 创建 HTTP 配置 */ static createConfig(options?: HttpClientOptions): HttpClientConfig { return createConfig(options); } constructor(options?: HttpClientOptions) { this.config = new.target.createConfig(options); } /** 已加载的插件 */ protected readonly _plugins = new Set>(); /** 已加载的插件 */ get plugins(): ReadonlyArray> { return [...this._plugins]; } /** 加载插件 */ use(plugin: HttpClientPlugin): this & T { if (typeof plugin != 'function') { throw new TypeError(`Invalid plugin: ${String(plugin)}`); } if (this._plugins.has(plugin)) { return this as this & T; } const mixin = plugin(this); if ((mixin as unknown) !== this) { throw new TypeError(`Invalid plugin: ${plugin.name}`); } this._plugins.add(plugin); return this as this & T; } /** 配置 */ readonly config: HttpClientConfig; private __gql?: Gql = undefined; /** * 发送 gql 请求 * * 可预期的异常包括 `RequestError` `RequestResponseError` 和 `GraphqlError` */ get gql(): Gql { this.__gql ??= createGql(this); return this.__gql; } private __restful?: Restful = undefined; /** * 发送 restful 请求 * * 可预期的异常包括 `RequestError` 和 `RequestResponseError` */ get restful(): Restful { this.__restful ??= createRestful(this); return this.__restful; } private __ws?: Ws = undefined; /** 创建 WebSocket */ get ws(): Ws { this.__ws ??= createWs(this); return this.__ws; } } export { type RequestResponse, RequestError, RequestResponseError } from './request.js'; export type { HttpClientOptions, HttpFetcher, HttpClientConfig } from './options.js'; export * from './gql/index.js'; export type { Gql } from './gql/plugin.js'; export { type RestfulResponse, type Restful } from './restful.js'; export { type Ws } from './ws.js';