import type { afterRequestPlugin, beforeRequestPlugin, PluginObject, } from "./type/PluginType"; import type { BodyTypes } from "./type/BodyTypes"; import type { ResponseRecord } from "./type/ResponseType"; import { Headers } from "./adapter"; import { bodyTransform } from "./utils/bodyTransform"; import { createURL } from "./utils/createURL"; import { ResponseWrapper } from "./ResponseTransform"; import { singleTypeObject, setSingleTypeObject } from "./singleTypeObject"; import { fetchRequester } from "./Requester/fetch"; import { Method, Requester } from "./type/Requester"; import { useCookie } from "./plugins/cookies"; export type LinkMassage = { url: string | URL; params?: singleTypeObject; headers?: singleTypeObject; body?: BodyTypes; method?: Method; requester?: Requester; autoRedirect?: boolean; cookie?: { tag?: string; read?: boolean; write?: boolean; }; }; export type LinkResult = Awaited>; export class Link { /** 默认的请求器 */ static DefaultRequester = fetchRequester; /** 更改全局的请求器 */ static registerRequester(requester: Requester) { Link.DefaultRequester = requester; } url: URL; autoRedirect = true; cookie: LinkMassage["cookie"]; /** 用于不同环境的请求模块 */ requester = Link.DefaultRequester; constructor(input: LinkMassage) { const { method = "get", params, headers, url, body, requester = this.requester, autoRedirect = true, cookie = {}, } = input; this.url = createURL(url); params && this.setParams(params); headers && this.setHeaders(headers); Object.assign(this, { body, method, requester, autoRedirect, cookie, }); this.useDefaultPlugin(); } private useDefaultPlugin = () => { this.use(useCookie(this.cookie)); }; get searchParams() { return this.url.searchParams; } /** 直接设置 URLsearchParams, * @params valueOfParams 值为数组时,为插入多个,值为单个时,表示覆盖 * @description setParams({ * a:['这是添加'], * b:"这是覆盖原来 Params 中的参数" * }) */ setParams(params: singleTypeObject) { setSingleTypeObject(this.url.searchParams, params); return this; } headers = new Headers(); /** * 直接设置 Headers, * @params valueOfParams 值为数组时,为插入多个,值为单个时,表示覆盖 * @description setParams({ * a: [ '这是添加' ], * b: "这是覆盖原来的参数", * c: [ '这是', '多个', '值' ] * }) */ setHeaders(params: singleTypeObject) { setSingleTypeObject(this.headers, params); return this; } /** 直接设置即可 */ method: Method = "get"; /** 直接设置即可 */ body: BodyTypes | null = null; /** 请求堆栈 */ responses: ResponseRecord[] = []; // receive() { // return this.responses.length ? this.responses[0] : undefined; // } /** 发送请求,并封装成一个可以使用的 */ async send() { const startTime = Date.now(); // 发送请求 const options = { autoRedirect: this.autoRedirect }; const data = await this.requester( this.url, this.method, this.headers, bodyTransform(this.body, this.headers), options ); const endTime = Date.now(); const parsedRes = this.plugins.afterRequest.reduce( (res, i) => i(res), ResponseWrapper(data) ); this.responses.push({ startTime, endTime, ...parsedRes, }); return parsedRes; } plugins = { /** 等待返回之后进行的返回参数调整的插件 */ afterRequest: [] as afterRequestPlugin[], }; use(plugin: beforeRequestPlugin | PluginObject) { if (typeof plugin === "function") { const { url, body, headers } = this; const output = plugin({ url, body, headers, }); Object.assign(this, output); } else { const { beforeRequest, afterRequest } = plugin; if (beforeRequest) this.use(beforeRequest); if (afterRequest) this.plugins.afterRequest.push(afterRequest); } return this; } }