UNPKG

wiki-saikou

Version:

The library provides the out of box accessing to MediaWiki API in both browsers & Node.js, and the syntax is very similar to vanilla `new mw.Api()`. TypeScript definition included~

1,142 lines (1,141 loc) 36.5 kB
function N(o) { if (typeof globalThis.structuredClone == "function") try { return globalThis.structuredClone(o); } catch { } return S(o, /* @__PURE__ */ new WeakMap()); } function S(o, t) { if (typeof o != "object" || o === null) return o; const e = t.get(o); if (e) return e; if (o instanceof Date) return new Date(o.getTime()); if (o instanceof RegExp) return new RegExp(o.source, o.flags); if (o instanceof URL) return new URL(o.toString()); if (o instanceof URLSearchParams) return new URLSearchParams(o.toString()); if (o instanceof ArrayBuffer) return o.slice(0); if (ArrayBuffer.isView(o)) { if (o instanceof DataView) return new DataView( o.buffer.slice(0), o.byteOffset, o.byteLength ); const a = o, f = a.constructor; return new f(a.buffer.slice(0), a.byteOffset, a.length); } if (o instanceof Map) { const a = /* @__PURE__ */ new Map(); return t.set(o, a), o.forEach((f, i) => { a.set(S(i, t), S(f, t)); }), a; } if (o instanceof Set) { const a = /* @__PURE__ */ new Set(); return t.set(o, a), o.forEach((f) => a.add(S(f, t))), a; } if (Array.isArray(o)) { const a = new Array(o.length); t.set(o, a); for (let f = 0; f < a.length; f++) a[f] = S(o[f], t); return a; } const s = Object.getPrototypeOf(o), r = Object.create(s); t.set(o, r); const n = Object.getOwnPropertyDescriptors(o); for (const a of Reflect.ownKeys(n)) { const f = n[a]; "value" in f && (f.value = S(f.value, t)), Object.defineProperty(r, a, f); } return r; } function b(o) { if (typeof o != "object" || o === null) return !1; const t = Object.getPrototypeOf(o); return t === Object.prototype || t === null; } const v = function(o) { const t = this.constructor.prototype, e = Reflect.get(t, o, t); function s(...r) { return Reflect.apply(e, s, r); } Reflect.setPrototypeOf(s, t); for (const r of Reflect.ownKeys(e)) { const n = Reflect.getOwnPropertyDescriptor(e, r); n && Reflect.defineProperty(s, r, n); } return s; }; v.prototype = Object.create(Function.prototype); const G = v; function E(o, ...t) { const e = N(o || {}); for (const s of t) if (s != null) for (const r of Reflect.ownKeys(s)) { const n = s[r]; if (typeof n > "u") continue; if (n === null) { delete e[r]; continue; } const a = e[r]; b(a) && b(n) ? e[r] = E(a, n) : e[r] = N(n); } return e; } var R = /* @__PURE__ */ ((o) => (o.BODY_USED = "BODY_USED", o.NO_BODY_READER = "NO_BODY_READER", o.TIMEOUT = "TIMEOUT", o.NETWORK_ERROR = "NETWORK_ERROR", o.BODY_NOT_ALLOWED = "BODY_NOT_ALLOWED", o.HOOK_CONTEXT_CHANGED = "HOOK_CONTEXT_CHANGED", o.ABORTED_BY_HOOK = "ABORTED_BY_HOOK", o.INVALID_HOOK_CALLBACK = "INVALID_HOOK_CALLBACK", o.UNEXPECTED_HOOK_RETURN = "UNEXPECTED_HOOK_RETURN", o.UNSUPPORTED_RESPONSE_TYPE = "UNSUPPORTED_RESPONSE_TYPE", o.FEATURE_MOVED_TO_PLUGIN = "FEATURE_MOVED_TO_PLUGIN", o.BODY_TRANSFORM_ERROR = "BODY_TRANSFORM_ERROR", o))(R || {}); class m extends Error { constructor(t, e, s, r) { super(e, r), this.code = t, this.context = s; } name = "FexiosError"; static is(t, e) { return !(t instanceof m) || t instanceof C ? !1 : e ? t.code === e : !0; } } class C extends m { constructor(t, e, s) { super(e.statusText, t, void 0, s), this.response = e; } name = "FexiosResponseError"; static is(t) { return t instanceof C; } } const J = (o) => m.is(o); var w; ((o) => { o.makeSearchParams = (a) => { if (!a) return new URLSearchParams(); if (a instanceof URLSearchParams) return a; if (typeof a != "object" || a?.constructor !== Object) throw new TypeError("only plain object is supported"); const f = new URLSearchParams(), i = (l, h) => { h != null && f.append(l, h); }, c = (l, h) => { h != null && f.set(l, h); }, u = (l, h) => { if (h != null) { if (Array.isArray(h)) { for (const d of h) i(l, d?.toString()); return; } if (typeof h == "object" && h.constructor === Object) { for (const [d, p] of Object.entries(h)) { if (p == null) continue; const U = d.endsWith("[]"), D = U ? d.slice(0, -2) : d, O = `${l}[${D}]`; if (U) { const q = `${O}[]`; if (Array.isArray(p)) for (const A of p) i(q, A?.toString()); else typeof p == "object" && p !== null && p.constructor === Object ? u(`${O}[]`, p) : i(q, p?.toString()); } else if (Array.isArray(p)) for (const q of p) i(O, q?.toString()); else typeof p == "object" && p !== null && p.constructor === Object ? u(O, p) : c(O, p?.toString()); } return; } c(l, h?.toString()); } }; for (const [l, h] of Object.entries(a)) u(l, h); return f; }, o.makeQueryString = (a) => (0, o.makeSearchParams)(a).toString(), o.makeURL = (a, f, i, c) => { const u = typeof window < "u" && window.location?.origin || "http://localhost", l = typeof a == "string" ? new URL(a, c ?? u) : new URL(a), h = (0, o.toQueryRecord)(l.searchParams), d = (0, o.mergeQueries)(h, f || {}), p = (0, o.makeSearchParams)(d); return l.search = p.toString(), typeof i < "u" && (l.hash = i), l; }; const t = /\[([^\]]*)\]/g; function e(a) { if (!a.includes("[")) return { path: [a], forceArray: !1 }; const i = [a.slice(0, a.indexOf("["))]; t.lastIndex = 0; let c, u = !1, l = !1; for (; c = t.exec(a); ) c[1] === "" ? (u = !0, l = !0) : (i.push(c[1]), l = !1); return u && l && (i[i.length - 1] = i[i.length - 1] + "[]"), { path: i, forceArray: u }; } function s(a, f, i, c) { let u = a; for (let h = 0; h < f.length - 1; h++) { const d = f[h]; (u[d] === void 0 || typeof u[d] != "object" || Array.isArray(u[d])) && (u[d] = {}), u = u[d]; } const l = f[f.length - 1]; u[l] === void 0 ? u[l] = c ? [i] : i : Array.isArray(u[l]) ? u[l].push(i) : u[l] = [u[l], i]; } o.toQueryRecord = (a) => { typeof a == "string" && (a = (0, o.fromString)(a)); const f = {}; for (const [i, c] of a.entries()) { const { path: u, forceArray: l } = e(String(i)); s(f, u, c?.toString(), l); } return f; }, o.fromString = (a) => { const f = a.trim(); if (!f) return new URLSearchParams(); if (f.startsWith("?")) return new URLSearchParams(f.slice(1)); const i = f.indexOf("?"); if (i >= 0) { const c = f.indexOf("#", i + 1), u = f.slice(i + 1, c >= 0 ? c : void 0); return new URLSearchParams(u); } return new URLSearchParams(f); }, o.mergeQueries = (...a) => { const f = {}; for (const i of a) i != null && n(f, r(i)); return f; }; function r(a) { if (!a) return {}; if (a instanceof URLSearchParams || a instanceof FormData || a instanceof Map) return (0, o.toQueryRecord)(a); if (typeof a == "string") return (0, o.toQueryRecord)((0, o.fromString)(a)); if (b(a)) return a; throw new TypeError( `unsupported type transformation, got: ${Object.prototype.toString.call( a )}` ); } function n(a, f) { for (const [i, c] of Object.entries(f)) { if (c === void 0) continue; if (c === null) { delete a[i]; continue; } const u = a[i]; b(u) && b(c) ? n(u, c) : a[i] = N(c); } } })(w || (w = {})); class M { constructor(t, e, s) { this.rawResponse = t, this.data = e, this.responseType = s, ["ok", "status", "statusText", "headers", "url", "redirected"].forEach( (r) => { Reflect.defineProperty(this, r, { get: () => t[r] }); } ); } ok; status; statusText; headers; url; redirected; } const V = (o) => { if (o) { if (o.includes("application/json") || o.endsWith("+json")) return "json"; if (o.startsWith("text/")) return "text"; if (o.includes("multipart/form-data") || o.includes("application/x-www-form-urlencoded")) return "form"; if (/^image\//.test(o) || /^video\//.test(o) || /^audio\//.test(o) || o.includes("application/pdf")) return "blob"; if (o.includes("application/octet-stream") || o.includes("application/zip") || o.includes("application/x-tar") || o.includes("application/x-7z-compressed") || o.includes("application/x-gzip")) return "arrayBuffer"; } }; async function K(o, t, e, s) { const r = o.clone(), n = o.headers.get("content-type")?.toLowerCase() ?? "", a = o.headers.get("upgrade")?.toLowerCase(), f = o.headers.get("connection")?.toLowerCase(); if (t === "ws" || t === "stream") throw new m( R.FEATURE_MOVED_TO_PLUGIN, `responseType "${String( t )}" has been moved to plugins. Use "fexios/plugins" (fx.plugin(pluginWebSocket) / fx.plugin(pluginSSE)) and call fx.ws()/fx.sse() instead.` ); if (a === "websocket" && f === "upgrade") throw new m( R.FEATURE_MOVED_TO_PLUGIN, 'WebSocket upgrade response detected. WebSocket support has been moved to plugins. Please use "fexios/plugins" and call fx.ws().' ); if (n.includes("text/event-stream")) throw new m( R.FEATURE_MOVED_TO_PLUGIN, 'SSE (text/event-stream) response detected. SSE support has been moved to plugins. Please use "fexios/plugins" and call fx.sse().' ); let i = t ?? V(n) ?? "text", c; try { if (i === "form") c = await r.formData(); else if (i === "arrayBuffer") c = await r.arrayBuffer(); else if (i === "blob") c = await r.blob(); else if (i === "json") { const h = await r.text(); c = h ? JSON.parse(h) : null; } else if (i === "text") { const h = await r.text(); if (t) c = h; else { const d = h.trim(); if (d.startsWith("{") && d.endsWith("}") || d.startsWith("[") && d.endsWith("]")) try { c = JSON.parse(d), i = "json"; } catch { c = h; } else c = h; } } else { const h = await r.arrayBuffer(); c = new Uint8Array(h); } } catch (h) { if (!(h instanceof Error)) throw h; try { c = await r.text(), i = "text"; } catch { throw new m( R.BODY_TRANSFORM_ERROR, `Failed to transform response body to ${i}`, void 0, { cause: h } ); } } const u = new M( o, c, i ), l = e?.(u); if (typeof l == "boolean" ? l : !u.ok) throw new C(u.statusText, u); return u; } var k; ((o) => { o.makeHeaders = (t) => { if (!t) return new Headers(); if (t instanceof Headers) return new Headers(t); const e = new Headers(); if (t instanceof Map) { for (const [s, r] of t.entries()) if (r != null) if (Array.isArray(r)) for (const n of r) n != null && e.append(s, String(n)); else e.append(s, String(r)); return e; } if (b(t)) { for (const [s, r] of Object.entries(t)) if (r != null) if (Array.isArray(r)) for (const n of r) n != null && e.append(s, String(n)); else e.append(s, String(r)); return e; } throw new TypeError( "only plain object, Map/ReadonlyMap, or Headers is supported" ); }, o.toHeaderRecord = (t) => { if (t instanceof Headers) { const e = {}; return t.forEach((s, r) => { e[r] = e[r] ? [...e[r], s] : [s]; }), e; } if (t instanceof Map) { const e = {}; for (const [s, r] of t.entries()) if (r != null) if (Array.isArray(r)) { const n = r.filter((a) => a != null).map((a) => String(a)); n.length && (e[s] = (e[s] ?? []).concat(n)); } else { const n = String(r); e[s] = e[s] ? [...e[s], n] : [n]; } return e; } throw new TypeError( `unsupported type transformation, got: ${Object.prototype.toString.call( t )}` ); }, o.mergeHeaders = (...t) => { const e = new Headers(), s = (r) => { for (const [n, a] of Object.entries(r)) if (a !== void 0) { if (a === null) { e.delete(n); continue; } if (Array.isArray(a)) { e.delete(n); for (const f of a) f != null && e.append(n, String(f)); } else e.set(n, String(a)); } }; for (const r of t) { if (r == null) continue; if (r instanceof Headers) { r.forEach((a, f) => { e.set(f, a); }); continue; } if (b(r)) { s(r); continue; } const n = (0, o.toHeaderRecord)(r); for (const [a, f] of Object.entries(n)) { e.delete(a); for (const i of f) e.append(a, i); } } return e; }; })(k || (k = {})); class g extends G { static version = "6.2.1"; static FINAL_SYMBOL = /* @__PURE__ */ Symbol("FEXIOS_FINAL_CONTEXT"); baseConfigs; // for axios compatibility get defaults() { return this.baseConfigs; } set defaults(t) { this.baseConfigs = t; } static DEFAULT_CONFIGS = { baseURL: "", timeout: 0, credentials: void 0, headers: {}, query: {}, responseType: void 0, shouldThrow(t) { return !t.ok; }, fetch: globalThis.fetch }; hooks = []; static ALL_METHODS = [ "get", "post", "put", "patch", "delete", "head", "options", "trace" ]; static METHODS_WITHOUT_BODY = [ "get", "head", "options", "trace" ]; constructor(t = {}) { super("request"), this.baseConfigs = E(g.DEFAULT_CONFIGS, t), g.ALL_METHODS.forEach( (e) => this.createMethodShortcut(e.toLowerCase()) ); } attachLegacyAliases(t) { const e = () => t.request, s = () => t.runtime, r = (n, a) => { try { Object.defineProperty(t, n, { configurable: !0, ...a }); } catch { } }; r("url", { get: () => e().url, set: (n) => { e().url = n?.toString?.() ?? String(n); } }), r("method", { get: () => e().method, set: (n) => e().method = n }), r("headers", { get: () => e().headers, set: (n) => e().headers = n }), r("query", { get: () => e().query, set: (n) => e().query = n }), r("body", { get: () => e().body, set: (n) => e().body = n }), r("baseURL", { get: () => e().baseURL, set: (n) => e().baseURL = n }), r("timeout", { get: () => e().timeout, set: (n) => e().timeout = n }), r("credentials", { get: () => e().credentials, set: (n) => e().credentials = n }), r("cache", { get: () => e().cache, set: (n) => e().cache = n }), r("mode", { get: () => e().mode, set: (n) => e().mode = n }), r("fetch", { get: () => e().fetch, set: (n) => e().fetch = n }), r("shouldThrow", { get: () => e().shouldThrow, set: (n) => e().shouldThrow = n }), r("responseType", { get: () => e().responseType, set: (n) => e().responseType = n }), r("abortController", { get: () => s().abortController, set: (n) => s().abortController = n }), r("customEnv", { get: () => s().customEnv, set: (n) => s().customEnv = n }), r("rawRequest", { get: () => e().rawRequest, set: (n) => e().rawRequest = n }), r("data", { get: () => t.response ? t.response.data : void 0, set: (n) => { t.response && (t.response.data = n); } }); } finalizeContext(t, e) { const s = t.response, r = s?.rawResponse ?? t.rawResponse, n = t.request; Object.defineProperties(t, { url: { get: () => r?.url || e }, data: { get: () => s.data }, headers: { get: () => r.headers }, responseType: { get: () => s.responseType }, rawRequest: { get: () => n.rawRequest } }); } async request(t, e) { const s = this; let r = e || {}; typeof t == "string" || t instanceof URL ? r = { ...e || {}, url: t } : typeof t == "object" && (r = t); const { abortController: n, customEnv: a, ...f } = r; let i = { get app() { return s; }, request: { ...f, url: r.url?.toString?.() ?? String(r.url) }, runtime: { abortController: n, customEnv: a }, response: void 0, rawResponse: void 0, // legacy fields are attached via defineProperty url: "", headers: {}, query: {} }; if (this.attachLegacyAliases(i), i = await this.emit("beforeInit", i), i[g.FINAL_SYMBOL]) return i; if ("customEnv" in this.baseConfigs && (i.runtime.customEnv = E( {}, // ensure we don't mutate baseConfigs this.baseConfigs.customEnv, i.runtime.customEnv )), i.request = this.applyDefaults(i.request), g.METHODS_WITHOUT_BODY.includes( i.request.method?.toLocaleLowerCase?.() ) && i.request.body) throw new m( R.BODY_NOT_ALLOWED, `Request method "${i.request.method}" does not allow body` ); if (i = await this.emit("beforeRequest", i), i[g.FINAL_SYMBOL]) return i; let c; const u = {}, l = i.request; if (typeof l.body < "u" && l.body !== null && (l.body instanceof Blob || l.body instanceof FormData || l.body instanceof URLSearchParams ? c = l.body : typeof l.body == "object" && l.body !== null ? (c = JSON.stringify(l.body), l.headers = this.mergeHeaders(l.headers, { "Content-Type": "application/json" })) : c = l.body), !k.makeHeaders(l.headers || {}).get("content-type") && c && (c instanceof FormData || c instanceof URLSearchParams ? u["content-type"] = null : typeof c == "string" && typeof l.body == "object" ? u["content-type"] = "application/json" : c instanceof Blob && (u["content-type"] = c.type || "application/octet-stream")), l.body = c, i = await this.emit("afterBodyTransformed", i), i[g.FINAL_SYMBOL]) return i; const d = i.runtime.abortController ?? (globalThis.AbortController ? new AbortController() : void 0), p = globalThis.location?.href || "http://localhost", U = new URL( i.request.baseURL || this.baseConfigs.baseURL || p, p ), D = new URL(i.request.url, U), O = w.makeURL( D, i.request.query, D.hash // 保留 hash ).toString(), q = new Request(O, { method: i.request.method || "GET", credentials: i.request.credentials, cache: i.request.cache, mode: i.request.mode, headers: k.mergeHeaders( this.baseConfigs.headers, i.request.headers || {}, u ), body: i.request.body, signal: d?.signal }); if (i.request.rawRequest = q, i = await this.emit("beforeActualFetch", i), i[g.FINAL_SYMBOL]) return i; const A = i.request.timeout ?? this.baseConfigs.timeout ?? 60 * 1e3, $ = i.request.shouldThrow ?? this.baseConfigs.shouldThrow; if (i.request.url.startsWith("ws") || i.request.responseType === "ws") throw new m( R.FEATURE_MOVED_TO_PLUGIN, 'WebSocket support has been moved to plugins. Use "fexios/plugins" and call fx.ws() instead.', i ); if (i.request.responseType === "stream") throw new m( R.FEATURE_MOVED_TO_PLUGIN, 'SSE support has been moved to plugins. Use "fexios/plugins" and call fx.sse() instead.', i ); let L; try { d && (L = A > 0 ? setTimeout(() => { d.abort(); }, A) : void 0); const B = await (i.request.fetch || this.baseConfigs.fetch || globalThis.fetch)(i.request.rawRequest).catch( (F) => { throw L && clearTimeout(L), d?.signal.aborted ? new m( R.TIMEOUT, `Request timed out after ${A}ms`, i ) : new m( R.NETWORK_ERROR, F.message, i ); } ); return L && clearTimeout(L), i.rawResponse = B, await this.emit("afterRawResponse", i), i[g.FINAL_SYMBOL] ? i : (i.response = await K( B, i.request.responseType, $, A ), i.rawResponse = i.response.rawResponse, this.finalizeContext(i, O), this.emit("afterResponse", i)); } catch (H) { throw L && clearTimeout(L), H; } } mergeQueries = w.mergeQueries; mergeHeaders = k.mergeHeaders; applyDefaults(t) { const e = t, s = globalThis.location?.href || "http://localhost", r = e.baseURL || this.baseConfigs.baseURL || s, n = new URL(r, s), a = new URL(e.url.toString(), n), f = w.toQueryRecord( n.searchParams ), i = w.toQueryRecord( a.searchParams ), c = w.mergeQueries( f, i ); a.search = w.makeSearchParams(c).toString(), e.url = a.toString(); const u = w.mergeQueries( this.baseConfigs.query, e.query ); return e.query && this.restoreNulls(u, e.query), e.query = u, e; } restoreNulls(t, e) { if (!(!e || typeof e != "object")) for (const [s, r] of Object.entries(e)) r === null ? t[s] = null : b(r) && ((!t[s] || typeof t[s] != "object") && (t[s] = {}), this.restoreNulls(t[s], r)); } isFinalContextLike(t) { if (!t || typeof t != "object") return !1; const e = t.request, s = t.response, r = t.rawResponse; return !e || !s || !r || typeof e.url != "string" ? !1 : r instanceof Response || s?.rawResponse instanceof Response || s?.rawResponse?.constructor?.name === "Response"; } async resolveShortCircuit(t, e, s) { const r = t; let n; if (e instanceof M ? (n = e, r.rawResponse = n.rawResponse) : (r.rawResponse = e, n = await K( e, t.request?.responseType, t.request?.shouldThrow ?? this.baseConfigs.shouldThrow, t.request?.timeout ?? this.baseConfigs.timeout ?? 60 * 1e3 )), r.response = n, r.rawResponse = n.rawResponse, !r.request?.rawRequest) try { r.request.rawRequest = new Request(r.request.url, { method: r.request.method || "GET", headers: r.request.headers, body: r.request.body }); } catch { } if (this.finalizeContext(r, n.rawResponse?.url || ""), s !== "afterResponse") { const a = await this.emit("afterResponse", r); return a[g.FINAL_SYMBOL] = !0, a; } else return r[g.FINAL_SYMBOL] = !0, r; } async emit(t, e, s = { shouldHandleShortCircuitResponse: !0 }) { const r = this.hooks.filter((n) => n.event === t); if (r.length === 0) return e; for (let n = 0; n < r.length; n++) { const a = r[n], f = `${String(t)}#${a.action.name || `anonymous#${n}`}`, i = /* @__PURE__ */ Symbol("FEXIOS_HOOK_CTX_MARK"); try { e[i] = i; } catch { } const c = await a.action.call(this, e), u = c === e, l = c && typeof c == "object" && c[i] === i; try { delete e[i]; } catch { } if (c === !1) throw new m( R.ABORTED_BY_HOOK, `Request aborted by hook "${f}"`, e ); if (u || l) { e = c; continue; } if (this.isFinalContextLike(c)) return c[g.FINAL_SYMBOL] = !0, c; if (c instanceof M) return this.resolveShortCircuit(e, c, t); if (c instanceof Response) { if (s.shouldHandleShortCircuitResponse !== !1) return this.resolveShortCircuit(e, c, t); e.rawResponse = c; } } return e; } on(t, e, s = !1) { if (typeof e != "function") throw new m( R.INVALID_HOOK_CALLBACK, `Hook should be a function, but got "${typeof e}"` ); return this.hooks[s ? "unshift" : "push"]({ event: t, action: e }), this; } off(t, e) { return t === "*" || !t ? this.hooks = this.hooks.filter((s) => s.action !== e) : this.hooks = this.hooks.filter( (s) => s.event !== t || s.action !== e ), this; } createInterceptor(t) { return { handlers: () => this.hooks.filter((e) => e.event === t).map((e) => e.action), use: (e, s = !1) => this.on(t, e, s), clear: () => { this.hooks = this.hooks.filter((e) => e.event !== t); } }; } interceptors = { request: this.createInterceptor("beforeRequest"), response: this.createInterceptor("afterResponse") }; createMethodShortcut(t) { return Reflect.defineProperty(this, t, { get: () => (e, s, r) => (g.METHODS_WITHOUT_BODY.includes( t.toLocaleLowerCase() ) ? r = s : (r = r || {}, r.body = s), this.request(e, { ...r, method: t })) }), this; } extends(t) { const e = new g(E(this.baseConfigs, t)); return e.hooks = [...this.hooks], e._plugins = new Map(this._plugins), e._plugins.forEach(async (s) => { await e.plugin(s); }), e; } create = g.create; static create(t) { return new g(t); } _plugins = /* @__PURE__ */ new Map(); plugin(t) { if (typeof t?.name == "string" && typeof t?.install == "function") { if (this._plugins.has(t.name)) return this; const e = t.install(this); if (this._plugins.set(t.name, t), e instanceof g) return e; } return this; } uninstall(t) { return typeof t == "string" && (t = this._plugins.get(t)), t && (t?.uninstall?.(this), this._plugins.delete(t.name)), this; } // 版本弃子们.jpg /** @deprecated Use `mergeQueries` instead */ mergeQuery = this.mergeQueries; } const z = g.create, Z = z(); var P; ((o) => { function t(s) { return Array.isArray(s) ? s.join("|") : typeof s == "boolean" || s === null ? s ? "1" : void 0 : typeof s == "number" ? "" + s : s; } o.normalizeParamValue = t; function e(s) { const r = (a) => a && (a instanceof URLSearchParams || a instanceof FormData); if (s == null) return; const n = new FormData(); if (r(s)) return s.forEach((a, f) => { const i = t(a); i != null && n.append(f, i); }), n; if (b(s)) return Object.entries(s).forEach(([a, f]) => { const i = t(f); i != null && n.append(a, i); }), n; } o.normalizeBody = e; })(P || (P = {})); var I = /* @__PURE__ */ ((o) => (o.HTTP_ERROR = "HTTP_ERROR", o.LOGIN_FAILED = "LOGIN_FAILED", o.LOGIN_RETRY_LIMIT_EXCEEDED = "LOGIN_RETRY_LIMIT_EXCEEDED", o.TOKEN_RETRY_LIMIT_EXCEEDED = "TOKEN_RETRY_LIMIT_EXCEEDED", o))(I || {}); class y extends Error { constructor(t, e = "", s) { super(), this.code = t, this.message = e, this.cause = s, this.name = "WikiSaikouError"; } static is(t, e) { return t instanceof this && (e === void 0 || t.code === e); } } class T extends Error { constructor(t, e) { super(), this.errors = t, this.cause = e, this.name = "MediaWikiApiError", this.errors = T.normalizeErrors(t), this.message = t.map((s) => s.text).filter(Boolean).join(` `), this.code = this.isBadTokenError() ? "badtoken" : this.errors[0]?.code || "Unknown Error"; } get firstError() { return this.errors[0]; } isBadTokenError() { return this.errors.some((t) => t.code === "badtoken") || ["NeedToken", "WrongToken"].includes(this.cause?.data?.login?.result); } toString() { return `[${this.name} ${this.code}]`; } static is(t) { return t instanceof this; } static normalizeErrors(t) { return Array.isArray(t) === !1 ? [] : t.filter((e) => typeof e == "object" && !!e?.code).map((e) => e.text ? e : e.info ? { ...e, text: e.info } : e["*"] ? { ...e, text: e["*"] } : { ...e, text: "" }); } } ((o) => { function t(n) { if (n == null) return; if (n?.response?.data !== void 0) return n.response.data; if (n?.data !== void 0) return n.data; const a = n instanceof Error ? n.cause : void 0; return a?.response?.data !== void 0 ? a.response.data : a?.data !== void 0 ? a.data : n || void 0; } function e(n) { return s(n).length > 0; } o.includesMediaWikiApiError = e, o.normalizeMwApiErrors = T.normalizeErrors; function s(n) { let a = t(n); if (typeof a != "object" || a === null) return []; const f = a?.error, i = a?.errors, c = []; return f && c.push(f), Array.isArray(i) && c.push(...i), (0, o.normalizeMwApiErrors)(c); } o.extractMediaWikiApiErrors = s; function r(n) { if (T.is(n)) return n.isBadTokenError(); { const a = s(n); return new T(a).isBadTokenError(); } } o.isBadTokenError = r; })(y || (y = {})); const Y = /* @__PURE__ */ Symbol.for("__FEXIOS_SAIKOU__"); function W(o) { const t = o instanceof g ? o : new g({ baseURL: o instanceof URL ? o.toString() : String(o), responseType: "json" }); return t[Y] || (Reflect.defineProperty(t, Y, { get: () => !0, enumerable: !1, configurable: !1 }), t.on("beforeInit", (e) => { if (e.request.method?.toLowerCase() !== "post") return e; if (e.request.body === void 0 || e.request.body === null) return e.request.body = void 0, e; const s = e.request.body = P.normalizeBody( e.request.body ), r = new URLSearchParams(e.request.query); return s.has("format") && r.delete("format"), s.has("formatversion") && r.delete("formatversion"), s.has("action") && r.delete("action"), s.has("origin") && (r.set("origin", "" + s.get("origin")), s.delete("origin")), e.request.query = Object.fromEntries(r.entries()), e; }), t.on("beforeInit", (e) => (e.request.query = w.mergeQueries( {}, P.normalizeBody(e.request.query) ), e)), t.on("beforeRequest", (e) => { const s = new URL(e.request.url), r = w.mergeQueries(s.searchParams, e.query); if (globalThis.location && (!r.origin && location.origin !== s.origin ? (r.origin = location.origin, t.baseConfigs.credentials = "include", t.baseConfigs.mode = "cors") : location.origin === s.origin && (delete r.origin, t.baseConfigs.credentials = void 0, t.baseConfigs.mode = void 0)), r.origin) { const n = encodeURIComponent(r.origin).replace(/\./g, "%2E"); delete r.origin, e.request.query = r, e.request.url = `${s.origin}${s.pathname}?origin=${n}`; } else e.request.query = r; return e; }), t._tokens = /* @__PURE__ */ new Map(), t.on("afterResponse", (e) => { const { data: s } = e, r = e.runtime.customEnv?.mwTokenName; r && y.isBadTokenError(s) && t._tokens.delete(r); const n = s?.query?.tokens; n && typeof n == "object" && Object.entries(n).forEach(([f, i]) => { typeof i == "string" && t._tokens.set(f.replace(/token$/i, "").toLowerCase(), i); }); const a = s?.login?.token; return typeof a == "string" && t._tokens.set("login", a), e; })), t; } const X = (o, t, e) => { let s = { ...j.DEFAULT_CONFIGS }; if (typeof o == "string" ? s = E(s, { baseURL: o, fexiosConfigs: t || {}, defaultParams: e || {}, throwOnApiError: !1 // Set a default value for throwOnApiError }) : typeof o == "object" && o !== null && (s = E(s, o)), !s.baseURL && typeof window == "object" && window.mediaWiki) { const { wgServer: r, wgScriptPath: n } = window.mediaWiki?.config?.get(["wgServer", "wgScriptPath"]) || {}; typeof r == "string" && typeof n == "string" && (s.baseURL = `${r}${n}/api.php`); } if (typeof s.baseURL != "string") throw new Error("baseURL is required"); return s; }, x = () => { }, Q = async (o, t) => { let e = 0; const { retry: s = 3, onRetry: r = x, shouldRetry: n = () => !0 } = t; let a; do try { return await o(); } catch (f) { if (a = f, n(f, e)) r(f, e), e++; else throw f; } while (e < s); throw a || new Error("Retry failed"); }, _ = class _ { constructor(t, e, s) { this.version = "7.6.0", this.token = this.getToken; const r = this.config = X( t, e, s ); this.request = W(r.baseURL); } setBaseURL(t) { return this.config.baseURL = t, this.request.baseConfigs.baseURL = t, this; } /** Base methods encapsulation */ async get(t, e) { const s = E( {}, this.config.fexiosConfigs, { query: w.mergeQueries( this.config.defaultParams, t ) }, e ); return this.runRequestWithApiErrorMapping( () => this.request.get("", s) ); } async post(t, e) { return this.runRequestWithApiErrorMapping( () => this.request.post( "", t, E( {}, this.config.fexiosConfigs, { query: this.config.defaultParams }, e ) ) ); } /** * Wrap a request to map non-2xx responses containing MediaWiki API error bodies * into MediaWikiApiError when throwOnApiError=true, and then pass 2xx responses * through handleApiResponse for unified processing. */ async runRequestWithApiErrorMapping(t) { try { const e = await t(); return this.handleApiResponse(e); } catch (e) { throw this.config.throwOnApiError && y.includesMediaWikiApiError(e) ? new T( y.extractMediaWikiApiErrors(e), e ) : e; } } throwIfApiError(t) { const e = y.extractMediaWikiApiErrors(t); if (e.length > 0) throw new T(e, t); } handleApiResponse(t) { return this.config.throwOnApiError && this.throwIfApiError(t.data), t; } /** Token Handler */ get tokens() { return this.request._tokens; } async fetchTokens(t = ["csrf"]) { return this.config.fexiosConfigs.credentials = "include", await this.get({ action: "query", meta: "tokens", type: t }), this.tokens; } async getToken(t = "csrf", e = !1) { return (!this.tokens.get(t) || e) && (this.tokens.delete(t), await this.fetchTokens([t])), this.tokens.get(t); } badToken(t) { return this.tokens.delete(t), this.tokens; } async postWithToken(t, e, s) { const { tokenName: r = "token", retry: n = 3, noCache: a = !1, fexiosOptions: f } = s || {}; if (n < 1) throw new y( I.TOKEN_RETRY_LIMIT_EXCEEDED, "The limit of the number of times to automatically re-acquire the token has been exceeded" ); let i = 0; return Q( async () => { const c = await this.getToken( t, a || i > 0 ); try { const u = await this.post( { [r]: c, ...e }, E(f || {}, { customEnv: { mwTokenName: t } }) ); if (y.isBadTokenError(u.data)) throw u; return u; } catch (u) { throw y.isBadTokenError(u) || u?.ok === !1 || T.is(u) ? u : new y( I.HTTP_ERROR, "Network/transport or SDK-internal error (not a MediaWiki API error)", u ); } }, { retry: n, onRetry: (c, u) => { i = u + 1; }, shouldRetry: (c) => y.isBadTokenError(c) || c?.ok === !1 } ).catch((c) => { throw y.isBadTokenError(c) || c?.ok === !1 ? new y( I.TOKEN_RETRY_LIMIT_EXCEEDED, "Retry attempts for acquiring/using token exhausted", c ) : c; }); } postWithEditToken(t) { return this.postWithToken("csrf", t); } // for backward compatibility /** @deprecated Use `this.config.baseURL` instead */ get baseURL() { return this.config.baseURL; } /** @deprecated Use `this.config.defaultParams` instead */ get defaultParams() { return this.config.defaultParams; } /** @deprecated Use `this.config.fexiosConfigs` instead */ get defaultOptions() { return this.config.fexiosConfigs; } }; _.INIT_DEFAULT_PARAMS = { action: "query", errorformat: "plaintext", format: "json", formatversion: 2 }, _.DEFAULT_CONFIGS = { baseURL: void 0, fexiosConfigs: { responseType: "json" }, defaultParams: _.INIT_DEFAULT_PARAMS, throwOnApiError: !1 }, _.createRequestHandler = W; let j = _; export { G as C, g as F, T as M, j as W, y as a, I as b, W as c, P as d, z as e, Z as f, M as g, K as h, m as i, R as j, C as k, J as l, k as m, w as n, E as o, N as p, b as q, X as r }; //# sourceMappingURL=WikiSaikou-DPIdN41C.js.map