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~

4 lines (3 loc) 27.4 kB
(function(l,T){typeof exports=="object"&&typeof module<"u"?T(exports):typeof define=="function"&&define.amd?define(["exports"],T):(l=typeof globalThis<"u"?globalThis:l||self,T(l.WikiSaikou={}))})(this,(function(l){"use strict";function T(n){if(typeof globalThis.structuredClone=="function")try{return globalThis.structuredClone(n)}catch{}return L(n,new WeakMap)}function L(n,t){if(typeof n!="object"||n===null)return n;const e=t.get(n);if(e)return e;if(n instanceof Date)return new Date(n.getTime());if(n instanceof RegExp)return new RegExp(n.source,n.flags);if(n instanceof URL)return new URL(n.toString());if(n instanceof URLSearchParams)return new URLSearchParams(n.toString());if(n instanceof ArrayBuffer)return n.slice(0);if(ArrayBuffer.isView(n)){if(n instanceof DataView)return new DataView(n.buffer.slice(0),n.byteOffset,n.byteLength);const a=n,f=a.constructor;return new f(a.buffer.slice(0),a.byteOffset,a.length)}if(n instanceof Map){const a=new Map;return t.set(n,a),n.forEach((f,i)=>{a.set(L(i,t),L(f,t))}),a}if(n instanceof Set){const a=new Set;return t.set(n,a),n.forEach(f=>a.add(L(f,t))),a}if(Array.isArray(n)){const a=new Array(n.length);t.set(n,a);for(let f=0;f<a.length;f++)a[f]=L(n[f],t);return a}const s=Object.getPrototypeOf(n),r=Object.create(s);t.set(n,r);const o=Object.getOwnPropertyDescriptors(n);for(const a of Reflect.ownKeys(o)){const f=o[a];"value"in f&&(f.value=L(f.value,t)),Object.defineProperty(r,a,f)}return r}function E(n){if(typeof n!="object"||n===null)return!1;const t=Object.getPrototypeOf(n);return t===Object.prototype||t===null}const F=function(n){const t=this.constructor.prototype,e=Reflect.get(t,n,t);function s(...r){return Reflect.apply(e,s,r)}Reflect.setPrototypeOf(s,t);for(const r of Reflect.ownKeys(e)){const o=Reflect.getOwnPropertyDescriptor(e,r);o&&Reflect.defineProperty(s,r,o)}return s};F.prototype=Object.create(Function.prototype);const H=F;function b(n,...t){const e=T(n||{});for(const s of t)if(s!=null)for(const r of Reflect.ownKeys(s)){const o=s[r];if(typeof o>"u")continue;if(o===null){delete e[r];continue}const a=e[r];E(a)&&E(o)?e[r]=b(a,o):e[r]=T(o)}return e}var R=(n=>(n.BODY_USED="BODY_USED",n.NO_BODY_READER="NO_BODY_READER",n.TIMEOUT="TIMEOUT",n.NETWORK_ERROR="NETWORK_ERROR",n.BODY_NOT_ALLOWED="BODY_NOT_ALLOWED",n.HOOK_CONTEXT_CHANGED="HOOK_CONTEXT_CHANGED",n.ABORTED_BY_HOOK="ABORTED_BY_HOOK",n.INVALID_HOOK_CALLBACK="INVALID_HOOK_CALLBACK",n.UNEXPECTED_HOOK_RETURN="UNEXPECTED_HOOK_RETURN",n.UNSUPPORTED_RESPONSE_TYPE="UNSUPPORTED_RESPONSE_TYPE",n.FEATURE_MOVED_TO_PLUGIN="FEATURE_MOVED_TO_PLUGIN",n.BODY_TRANSFORM_ERROR="BODY_TRANSFORM_ERROR",n))(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 D?!1:e?t.code===e:!0}}class D extends m{constructor(t,e,s){super(e.statusText,t,void 0,s),this.response=e}name="FexiosResponseError";static is(t){return t instanceof D}}const G=n=>m.is(n);l.FexiosQueryBuilder=void 0,(n=>{n.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=(h,d)=>{d!=null&&f.append(h,d)},c=(h,d)=>{d!=null&&f.set(h,d)},u=(h,d)=>{if(d!=null){if(Array.isArray(d)){for(const p of d)i(h,p?.toString());return}if(typeof d=="object"&&d.constructor===Object){for(const[p,y]of Object.entries(d)){if(y==null)continue;const M=p.endsWith("[]"),C=M?p.slice(0,-2):p,A=`${h}[${C}]`;if(M){const U=`${A}[]`;if(Array.isArray(y))for(const P of y)i(U,P?.toString());else typeof y=="object"&&y!==null&&y.constructor===Object?u(`${A}[]`,y):i(U,y?.toString())}else if(Array.isArray(y))for(const U of y)i(A,U?.toString());else typeof y=="object"&&y!==null&&y.constructor===Object?u(A,y):c(A,y?.toString())}return}c(h,d?.toString())}};for(const[h,d]of Object.entries(a))u(h,d);return f},n.makeQueryString=a=>(0,n.makeSearchParams)(a).toString(),n.makeURL=(a,f,i,c)=>{const u=typeof window<"u"&&window.location?.origin||"http://localhost",h=typeof a=="string"?new URL(a,c??u):new URL(a),d=(0,n.toQueryRecord)(h.searchParams),p=(0,n.mergeQueries)(d,f||{}),y=(0,n.makeSearchParams)(p);return h.search=y.toString(),typeof i<"u"&&(h.hash=i),h};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,h=!1;for(;c=t.exec(a);)c[1]===""?(u=!0,h=!0):(i.push(c[1]),h=!1);return u&&h&&(i[i.length-1]=i[i.length-1]+"[]"),{path:i,forceArray:u}}function s(a,f,i,c){let u=a;for(let d=0;d<f.length-1;d++){const p=f[d];(u[p]===void 0||typeof u[p]!="object"||Array.isArray(u[p]))&&(u[p]={}),u=u[p]}const h=f[f.length-1];u[h]===void 0?u[h]=c?[i]:i:Array.isArray(u[h])?u[h].push(i):u[h]=[u[h],i]}n.toQueryRecord=a=>{typeof a=="string"&&(a=(0,n.fromString)(a));const f={};for(const[i,c]of a.entries()){const{path:u,forceArray:h}=e(String(i));s(f,u,c?.toString(),h)}return f},n.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)},n.mergeQueries=(...a)=>{const f={};for(const i of a)i!=null&&o(f,r(i));return f};function r(a){if(!a)return{};if(a instanceof URLSearchParams||a instanceof FormData||a instanceof Map)return(0,n.toQueryRecord)(a);if(typeof a=="string")return(0,n.toQueryRecord)((0,n.fromString)(a));if(E(a))return a;throw new TypeError(`unsupported type transformation, got: ${Object.prototype.toString.call(a)}`)}function o(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];E(u)&&E(c)?o(u,c):a[i]=T(c)}}})(l.FexiosQueryBuilder||(l.FexiosQueryBuilder={}));class I{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=n=>{if(n){if(n.includes("application/json")||n.endsWith("+json"))return"json";if(n.startsWith("text/"))return"text";if(n.includes("multipart/form-data")||n.includes("application/x-www-form-urlencoded"))return"form";if(/^image\//.test(n)||/^video\//.test(n)||/^audio\//.test(n)||n.includes("application/pdf"))return"blob";if(n.includes("application/octet-stream")||n.includes("application/zip")||n.includes("application/x-tar")||n.includes("application/x-7z-compressed")||n.includes("application/x-gzip"))return"arrayBuffer"}};async function N(n,t,e,s){const r=n.clone(),o=n.headers.get("content-type")?.toLowerCase()??"",a=n.headers.get("upgrade")?.toLowerCase(),f=n.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(o.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(o)??"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 d=await r.text();c=d?JSON.parse(d):null}else if(i==="text"){const d=await r.text();if(t)c=d;else{const p=d.trim();if(p.startsWith("{")&&p.endsWith("}")||p.startsWith("[")&&p.endsWith("]"))try{c=JSON.parse(p),i="json"}catch{c=d}else c=d}}else{const d=await r.arrayBuffer();c=new Uint8Array(d)}}catch(d){if(!(d instanceof Error))throw d;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:d})}}const u=new I(n,c,i),h=e?.(u);if(typeof h=="boolean"?h:!u.ok)throw new D(u.statusText,u);return u}l.FexiosHeaderBuilder=void 0,(n=>{n.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 o of r)o!=null&&e.append(s,String(o));else e.append(s,String(r));return e}if(E(t)){for(const[s,r]of Object.entries(t))if(r!=null)if(Array.isArray(r))for(const o of r)o!=null&&e.append(s,String(o));else e.append(s,String(r));return e}throw new TypeError("only plain object, Map/ReadonlyMap, or Headers is supported")},n.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 o=r.filter(a=>a!=null).map(a=>String(a));o.length&&(e[s]=(e[s]??[]).concat(o))}else{const o=String(r);e[s]=e[s]?[...e[s],o]:[o]}return e}throw new TypeError(`unsupported type transformation, got: ${Object.prototype.toString.call(t)}`)},n.mergeHeaders=(...t)=>{const e=new Headers,s=r=>{for(const[o,a]of Object.entries(r))if(a!==void 0){if(a===null){e.delete(o);continue}if(Array.isArray(a)){e.delete(o);for(const f of a)f!=null&&e.append(o,String(f))}else e.set(o,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(E(r)){s(r);continue}const o=(0,n.toHeaderRecord)(r);for(const[a,f]of Object.entries(o)){e.delete(a);for(const i of f)e.append(a,i)}}return e}})(l.FexiosHeaderBuilder||(l.FexiosHeaderBuilder={}));class g extends H{static version="6.2.1";static FINAL_SYMBOL=Symbol("FEXIOS_FINAL_CONTEXT");baseConfigs;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=b(g.DEFAULT_CONFIGS,t),g.ALL_METHODS.forEach(e=>this.createMethodShortcut(e.toLowerCase()))}attachLegacyAliases(t){const e=()=>t.request,s=()=>t.runtime,r=(o,a)=>{try{Object.defineProperty(t,o,{configurable:!0,...a})}catch{}};r("url",{get:()=>e().url,set:o=>{e().url=o?.toString?.()??String(o)}}),r("method",{get:()=>e().method,set:o=>e().method=o}),r("headers",{get:()=>e().headers,set:o=>e().headers=o}),r("query",{get:()=>e().query,set:o=>e().query=o}),r("body",{get:()=>e().body,set:o=>e().body=o}),r("baseURL",{get:()=>e().baseURL,set:o=>e().baseURL=o}),r("timeout",{get:()=>e().timeout,set:o=>e().timeout=o}),r("credentials",{get:()=>e().credentials,set:o=>e().credentials=o}),r("cache",{get:()=>e().cache,set:o=>e().cache=o}),r("mode",{get:()=>e().mode,set:o=>e().mode=o}),r("fetch",{get:()=>e().fetch,set:o=>e().fetch=o}),r("shouldThrow",{get:()=>e().shouldThrow,set:o=>e().shouldThrow=o}),r("responseType",{get:()=>e().responseType,set:o=>e().responseType=o}),r("abortController",{get:()=>s().abortController,set:o=>s().abortController=o}),r("customEnv",{get:()=>s().customEnv,set:o=>s().customEnv=o}),r("rawRequest",{get:()=>e().rawRequest,set:o=>e().rawRequest=o}),r("data",{get:()=>t.response?t.response.data:void 0,set:o=>{t.response&&(t.response.data=o)}})}finalizeContext(t,e){const s=t.response,r=s?.rawResponse??t.rawResponse,o=t.request;Object.defineProperties(t,{url:{get:()=>r?.url||e},data:{get:()=>s.data},headers:{get:()=>r.headers},responseType:{get:()=>s.responseType},rawRequest:{get:()=>o.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:o,customEnv:a,...f}=r;let i={get app(){return s},request:{...f,url:r.url?.toString?.()??String(r.url)},runtime:{abortController:o,customEnv:a},response:void 0,rawResponse:void 0,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=b({},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={},h=i.request;if(typeof h.body<"u"&&h.body!==null&&(h.body instanceof Blob||h.body instanceof FormData||h.body instanceof URLSearchParams?c=h.body:typeof h.body=="object"&&h.body!==null?(c=JSON.stringify(h.body),h.headers=this.mergeHeaders(h.headers,{"Content-Type":"application/json"})):c=h.body),!l.FexiosHeaderBuilder.makeHeaders(h.headers||{}).get("content-type")&&c&&(c instanceof FormData||c instanceof URLSearchParams?u["content-type"]=null:typeof c=="string"&&typeof h.body=="object"?u["content-type"]="application/json":c instanceof Blob&&(u["content-type"]=c.type||"application/octet-stream")),h.body=c,i=await this.emit("afterBodyTransformed",i),i[g.FINAL_SYMBOL])return i;const p=i.runtime.abortController??(globalThis.AbortController?new AbortController:void 0),y=globalThis.location?.href||"http://localhost",M=new URL(i.request.baseURL||this.baseConfigs.baseURL||y,y),C=new URL(i.request.url,M),A=l.FexiosQueryBuilder.makeURL(C,i.request.query,C.hash).toString(),U=new Request(A,{method:i.request.method||"GET",credentials:i.request.credentials,cache:i.request.cache,mode:i.request.mode,headers:l.FexiosHeaderBuilder.mergeHeaders(this.baseConfigs.headers,i.request.headers||{},u),body:i.request.body,signal:p?.signal});if(i.request.rawRequest=U,i=await this.emit("beforeActualFetch",i),i[g.FINAL_SYMBOL])return i;const P=i.request.timeout??this.baseConfigs.timeout??60*1e3,Z=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 S;try{p&&(S=P>0?setTimeout(()=>{p.abort()},P):void 0);const z=await(i.request.fetch||this.baseConfigs.fetch||globalThis.fetch)(i.request.rawRequest).catch(x=>{throw S&&clearTimeout(S),p?.signal.aborted?new m(R.TIMEOUT,`Request timed out after ${P}ms`,i):new m(R.NETWORK_ERROR,x.message,i)});return S&&clearTimeout(S),i.rawResponse=z,await this.emit("afterRawResponse",i),i[g.FINAL_SYMBOL]?i:(i.response=await N(z,i.request.responseType,Z,P),i.rawResponse=i.response.rawResponse,this.finalizeContext(i,A),this.emit("afterResponse",i))}catch($){throw S&&clearTimeout(S),$}}mergeQueries=l.FexiosQueryBuilder.mergeQueries;mergeHeaders=l.FexiosHeaderBuilder.mergeHeaders;applyDefaults(t){const e=t,s=globalThis.location?.href||"http://localhost",r=e.baseURL||this.baseConfigs.baseURL||s,o=new URL(r,s),a=new URL(e.url.toString(),o),f=l.FexiosQueryBuilder.toQueryRecord(o.searchParams),i=l.FexiosQueryBuilder.toQueryRecord(a.searchParams),c=l.FexiosQueryBuilder.mergeQueries(f,i);a.search=l.FexiosQueryBuilder.makeSearchParams(c).toString(),e.url=a.toString();const u=l.FexiosQueryBuilder.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:E(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 o;if(e instanceof I?(o=e,r.rawResponse=o.rawResponse):(r.rawResponse=e,o=await N(e,t.request?.responseType,t.request?.shouldThrow??this.baseConfigs.shouldThrow,t.request?.timeout??this.baseConfigs.timeout??60*1e3)),r.response=o,r.rawResponse=o.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,o.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(o=>o.event===t);if(r.length===0)return e;for(let o=0;o<r.length;o++){const a=r[o],f=`${String(t)}#${a.action.name||`anonymous#${o}`}`,i=Symbol("FEXIOS_HOOK_CTX_MARK");try{e[i]=i}catch{}const c=await a.action.call(this,e),u=c===e,h=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||h){e=c;continue}if(this.isFinalContextLike(c))return c[g.FINAL_SYMBOL]=!0,c;if(c instanceof I)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(b(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=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}mergeQuery=this.mergeQueries}const W=g.create,Q=W();l.MwParamNormalizer=void 0,(n=>{function t(s){return Array.isArray(s)?s.join("|"):typeof s=="boolean"||s===null?s?"1":void 0:typeof s=="number"?""+s:s}n.normalizeParamValue=t;function e(s){const r=a=>a&&(a instanceof URLSearchParams||a instanceof FormData);if(s==null)return;const o=new FormData;if(r(s))return s.forEach((a,f)=>{const i=t(a);i!=null&&o.append(f,i)}),o;if(E(s))return Object.entries(s).forEach(([a,f])=>{const i=t(f);i!=null&&o.append(a,i)}),o}n.normalizeBody=e})(l.MwParamNormalizer||(l.MwParamNormalizer={}));var q=(n=>(n.HTTP_ERROR="HTTP_ERROR",n.LOGIN_FAILED="LOGIN_FAILED",n.LOGIN_RETRY_LIMIT_EXCEEDED="LOGIN_RETRY_LIMIT_EXCEEDED",n.TOKEN_RETRY_LIMIT_EXCEEDED="TOKEN_RETRY_LIMIT_EXCEEDED",n))(q||{});class w 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 O extends Error{constructor(t,e){super(),this.errors=t,this.cause=e,this.name="MediaWikiApiError",this.errors=O.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:""})}}(n=>{function t(o){if(o==null)return;if(o?.response?.data!==void 0)return o.response.data;if(o?.data!==void 0)return o.data;const a=o instanceof Error?o.cause:void 0;return a?.response?.data!==void 0?a.response.data:a?.data!==void 0?a.data:o||void 0}function e(o){return s(o).length>0}n.includesMediaWikiApiError=e,n.normalizeMwApiErrors=O.normalizeErrors;function s(o){let a=t(o);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,n.normalizeMwApiErrors)(c)}n.extractMediaWikiApiErrors=s;function r(o){if(O.is(o))return o.isBadTokenError();{const a=s(o);return new O(a).isBadTokenError()}}n.isBadTokenError=r})(w||(w={}));const K=Symbol.for("__FEXIOS_SAIKOU__");function j(n){const t=n instanceof g?n:new g({baseURL:n instanceof URL?n.toString():String(n),responseType:"json"});return t[K]||(Reflect.defineProperty(t,K,{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=l.MwParamNormalizer.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=l.FexiosQueryBuilder.mergeQueries({},l.MwParamNormalizer.normalizeBody(e.request.query)),e)),t.on("beforeRequest",e=>{const s=new URL(e.request.url),r=l.FexiosQueryBuilder.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 o=encodeURIComponent(r.origin).replace(/\./g,"%2E");delete r.origin,e.request.query=r,e.request.url=`${s.origin}${s.pathname}?origin=${o}`}else e.request.query=r;return e}),t._tokens=new Map,t.on("afterResponse",e=>{const{data:s}=e,r=e.runtime.customEnv?.mwTokenName;r&&w.isBadTokenError(s)&&t._tokens.delete(r);const o=s?.query?.tokens;o&&typeof o=="object"&&Object.entries(o).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 Y=(n,t,e)=>{let s={..._.DEFAULT_CONFIGS};if(typeof n=="string"?s=b(s,{baseURL:n,fexiosConfigs:t||{},defaultParams:e||{},throwOnApiError:!1}):typeof n=="object"&&n!==null&&(s=b(s,n)),!s.baseURL&&typeof window=="object"&&window.mediaWiki){const{wgServer:r,wgScriptPath:o}=window.mediaWiki?.config?.get(["wgServer","wgScriptPath"])||{};typeof r=="string"&&typeof o=="string"&&(s.baseURL=`${r}${o}/api.php`)}if(typeof s.baseURL!="string")throw new Error("baseURL is required");return s},X=()=>{},J=async(n,t)=>{let e=0;const{retry:s=3,onRetry:r=X,shouldRetry:o=()=>!0}=t;let a;do try{return await n()}catch(f){if(a=f,o(f,e))r(f,e),e++;else throw f}while(e<s);throw a||new Error("Retry failed")},k=class k{constructor(t,e,s){this.version="7.6.0",this.token=this.getToken;const r=this.config=Y(t,e,s);this.request=j(r.baseURL)}setBaseURL(t){return this.config.baseURL=t,this.request.baseConfigs.baseURL=t,this}async get(t,e){const s=b({},this.config.fexiosConfigs,{query:l.FexiosQueryBuilder.mergeQueries(this.config.defaultParams,t)},e);return this.runRequestWithApiErrorMapping(()=>this.request.get("",s))}async post(t,e){return this.runRequestWithApiErrorMapping(()=>this.request.post("",t,b({},this.config.fexiosConfigs,{query:this.config.defaultParams},e)))}async runRequestWithApiErrorMapping(t){try{const e=await t();return this.handleApiResponse(e)}catch(e){throw this.config.throwOnApiError&&w.includesMediaWikiApiError(e)?new O(w.extractMediaWikiApiErrors(e),e):e}}throwIfApiError(t){const e=w.extractMediaWikiApiErrors(t);if(e.length>0)throw new O(e,t)}handleApiResponse(t){return this.config.throwOnApiError&&this.throwIfApiError(t.data),t}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:o=3,noCache:a=!1,fexiosOptions:f}=s||{};if(o<1)throw new w(q.TOKEN_RETRY_LIMIT_EXCEEDED,"The limit of the number of times to automatically re-acquire the token has been exceeded");let i=0;return J(async()=>{const c=await this.getToken(t,a||i>0);try{const u=await this.post({[r]:c,...e},b(f||{},{customEnv:{mwTokenName:t}}));if(w.isBadTokenError(u.data))throw u;return u}catch(u){throw w.isBadTokenError(u)||u?.ok===!1||O.is(u)?u:new w(q.HTTP_ERROR,"Network/transport or SDK-internal error (not a MediaWiki API error)",u)}},{retry:o,onRetry:(c,u)=>{i=u+1},shouldRetry:c=>w.isBadTokenError(c)||c?.ok===!1}).catch(c=>{throw w.isBadTokenError(c)||c?.ok===!1?new w(q.TOKEN_RETRY_LIMIT_EXCEEDED,"Retry attempts for acquiring/using token exhausted",c):c})}postWithEditToken(t){return this.postWithToken("csrf",t)}get baseURL(){return this.config.baseURL}get defaultParams(){return this.config.defaultParams}get defaultOptions(){return this.config.fexiosConfigs}};k.INIT_DEFAULT_PARAMS={action:"query",errorformat:"plaintext",format:"json",formatversion:2},k.DEFAULT_CONFIGS={baseURL:void 0,fexiosConfigs:{responseType:"json"},defaultParams:k.INIT_DEFAULT_PARAMS,throwOnApiError:!1},k.createRequestHandler=j;let _=k;class B extends _{async clientLogin(t,e,s){s||={},!s.logincontinue&&!s.loginreturnurl&&(s.loginreturnurl=location?.origin);const r=await this.postWithToken("login",{action:"clientlogin",username:t,password:e,...s},{tokenName:"logintoken"});if(r?.data?.clientlogin?.status==="PASS")return r.data.clientlogin;throw new w(q.LOGIN_FAILED,r.data.clientlogin.message,r)}}class v extends B{constructor(t,e,s){const r=Y(t,{credentials:"include",mode:"cors",...e},{origin:location.origin,...s});super(r)}}l.CallableInstance=H,l.Fexios=g,l.FexiosError=m,l.FexiosErrorCodes=R,l.FexiosResponse=I,l.FexiosResponseContext=I,l.FexiosResponseError=D,l.ForeignApi=v,l.MediaWikiApi=B,l.MediaWikiApiError=O,l.MediaWikiForeignApi=v,l.MwApi=B,l.MwApiBase=_,l.WikiSaikouCore=_,l.WikiSaikouError=w,l.WikiSaikouErrorCode=q,l.clone=T,l.createFexios=W,l.createFexiosResponse=N,l.createFexiosSaikou=j,l.deepMerge=b,l.fexios=Q,l.isFexiosError=G,l.isPlainObject=E,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})})); //# sourceMappingURL=index.umd.js.map