mw.js
Version:
Typed MediaWiki API client for node.js using TypeScript.
1 lines • 49.7 kB
Source Map (JSON)
{"version":3,"sources":["../src/errors/InvalidInterwiki.ts","../src/errors/MediaWikiError.ts","../src/mediawiki/_base/Bot.ts","../src/mediawiki/_base/Wiki.ts","../src/utils/CookieJar.ts","../src/utils/RequestManager.ts","../src/utils/sleep.ts","../src/mediawiki/fandom/FandomBot.ts","../src/mediawiki/fandom/FandomWiki.ts","../src/mediawiki/fandom/Fandom.ts"],"names":["InvalidInterwikiError","interwiki","MediaWikiError","error","msg","k","v","_password","_username","_wiki","Bot","password","username","wiki","__privateAdd","__privateSet","__privateGet","params","force","token","lgtoken","res","titles","fs","tough","_storage","_store","_prettify","_CookieJar","prettify","store","_a","jsonCookies","host","hostCookies","cookiedata","cookie","url","hosts","collection","key","shouldDelete","storage","toughcookie","regex","pathname","lang","cookies","CookieJar","FormData","request","_jar","RequestManager","agent","headers","jarOptions","qs","body","form","formData","prop","fetchOptions","cookiesList","sleep","ms","r","Wiki","api","value","values","userparams","method","response","statusCode","interwikis","result","iw","properties","_titles","pages","page","content","type","title","base","siteinfo","req","item","limit","generator","counter","results","continuekey","i","__wikis","FandomBot","FandomWiki","Fandom","prettyCookies","requestOptions","_interwiki","wikiname","nolangRegex","nolang","langRegex","userId","usernames","user","bot"],"mappings":"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","sourcesContent":["export class InvalidInterwikiError extends Error {\r\n\tpublic constructor( interwiki: string ) {\r\n\t\tsuper( `Invalid interwiki: ${ interwiki }` )\r\n\t}\r\n}\r\n","export class MediaWikiError extends Error {\r\n\tpublic data: unknown\r\n\r\n\tpublic constructor( error: unknown ) {\r\n\t\tconst msg = typeof error === 'object' && error !== null\r\n\t\t\t? Object.entries( error ).map( ( [\r\n\t\t\t\tk, v\r\n\t\t\t] ) => `\\t${ k } = ${ v }` )\r\n\t\t\t\t.join( '\\n' )\r\n\t\t\t: ''\r\n\t\tsuper( `Your request returned an error object.\\n${ msg }` )\r\n\t}\r\n}\r\n","import type { BlockRequest, BlockResponse, DeleteRequest, DeleteResponse, EditRequest, EditResponse, LoginRequest, LoginResponse, MoveRequest, MoveResponse, NoActionToken, ProtectRequest, ProtectResponse, RollbackRequest, RollbackResponse, UnblockRequest, UnblockResponse, UndeleteRequest, UndeleteResponse, UploadRequest, UploadResponse } from '../../types'\r\nimport { MediaWikiError } from '../../errors'\r\nimport type { Wiki } from './Wiki'\r\n\r\nexport class Bot<WikiType extends Wiki = Wiki> {\r\n\treadonly #password: string\r\n\treadonly #username: string\r\n\t#wiki: WikiType\r\n\r\n\tprotected csrf: string | null = null\r\n\r\n\tpublic constructor( { password, username, wiki }: { password: string, username: string, wiki: WikiType } ) {\r\n\t\tthis.#password = password.trim()\r\n\t\tthis.#username = username.trim()\r\n\t\tthis.#wiki = wiki\r\n\t}\r\n\r\n\tprotected get wiki(): WikiType {\r\n\t\treturn this.#wiki\r\n\t}\r\n\tprotected set wiki( wiki: WikiType ) {\r\n\t\tthis.#wiki = wiki\r\n\t}\r\n\r\n\tpublic async block( params: NoActionToken<BlockRequest> ): Promise<BlockResponse> {\r\n\t\treturn this.wiki.post<BlockResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'block',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async delete( params: NoActionToken<DeleteRequest> ): Promise<DeleteResponse> {\r\n\t\treturn this.#wiki.post<DeleteResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'delete',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async edit( params: NoActionToken<EditRequest> ): Promise<EditResponse> {\r\n\t\treturn this.#wiki.post<EditResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'edit',\r\n\t\t\tassert: params.bot ? 'bot' : 'user',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async getCSRFToken( force = false ): Promise<string> {\r\n\t\tif ( force || !this.csrf ) {\r\n\t\t\tconst token = await this.#wiki.getToken( 'csrf' )\r\n\t\t\tthis.csrf = token.query.tokens.csrftoken\r\n\t\t}\r\n\t\treturn this.csrf\r\n\t}\r\n\r\n\tpublic async isLoggedIn(): Promise<boolean> {\r\n\t\tconst whoami = await this.whoAmI()\r\n\t\treturn whoami.query.userinfo.id !== 0\r\n\t}\r\n\r\n\tpublic async login( force = false ): Promise<void> {\r\n\t\tif ( !force ) {\r\n\t\t\tconst isLoggedIn = await this.isLoggedIn()\r\n\t\t\tif ( isLoggedIn ) return\r\n\t\t}\r\n\t\tthis.#wiki.request.clear( this.#wiki.api )\r\n\r\n\t\tconst tokenreq = await this.#wiki.getToken( 'login' )\r\n\t\tconst lgtoken = tokenreq.query.tokens.logintoken\r\n\r\n\t\tconst res = await this.#wiki.post<LoginResponse, LoginRequest>( {\r\n\t\t\taction: 'login',\r\n\t\t\tlgname: this.#username,\r\n\t\t\tlgpassword: this.#password,\r\n\t\t\tlgtoken\r\n\t\t} )\r\n\r\n\t\tif ( res.login.result !== 'Success' ) {\r\n\t\t\tthrow new MediaWikiError( res.login )\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async logout(): Promise<void> {\r\n\t\tawait this.#wiki.post( {\r\n\t\t\taction: 'logout',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t\tthis.#wiki.request.clear( this.#wiki.api )\r\n\t}\r\n\r\n\tpublic async move( params: NoActionToken<MoveRequest> ): Promise<MoveResponse> {\r\n\t\treturn this.#wiki.post<MoveResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'move',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async protect( params: NoActionToken<ProtectRequest> ): Promise<ProtectResponse> {\r\n\t\treturn this.wiki.post( {\r\n\t\t\t...params,\r\n\t\t\taction: 'protect',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic purge( titles: string[] ): Promise<Record<string, boolean>> {\r\n\t\treturn this.wiki.purge( titles )\r\n\t}\r\n\r\n\tpublic async rollback( params: NoActionToken<RollbackRequest> ): Promise<RollbackResponse> {\r\n\t\treturn this.wiki.post<RollbackResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'rollback',\r\n\t\t\ttoken: ( await this.wiki.getToken( 'rollback' ) ).query.tokens.rollbacktoken\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic touch( titles: string[] ): Promise<Record<string, boolean>> {\r\n\t\treturn this.wiki.purge( titles )\r\n\t}\r\n\r\n\tpublic async unblock( params: NoActionToken<UnblockRequest> ): Promise<UnblockResponse> {\r\n\t\treturn this.wiki.post( {\r\n\t\t\t...params,\r\n\t\t\taction: 'unblock',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async undelete( params: NoActionToken<UndeleteRequest> ): Promise<UndeleteResponse> {\r\n\t\treturn this.wiki.post( {\r\n\t\t\t...params,\r\n\t\t\taction: 'undelete',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async upload( params: UploadRequest ): Promise<UploadResponse> {\r\n\t\treturn this.#wiki.post<UploadResponse>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'upload',\r\n\t\t\ttoken: await this.getCSRFToken()\r\n\t\t} )\r\n\t}\r\n\r\n\t/**\r\n\t * @param { Object } params.filename - Name to use for the uploaded file.\r\n\t * @param { Object } params.url - URL of the file to upload.\r\n\t * @description Upload an image by an URL. \\\r\n\t * Not to be confused with the `uploadByUrl` method, which uses MediaWiki's extension. \\\r\n\t * It will store the image locally in order to upload it.\r\n\t */\r\n\t/*\r\n\tpublic async uploadFromUrl( {\r\n\t\tfilename, url\r\n\t}: { filename: string, url: string } ): Promise<UploadResponse | undefined> {\r\n\t\tconst image = await fetch( url )\r\n\t\tif ( !image.ok ) return undefined\r\n\r\n\t\tconst tmpfile = await tmp.file()\r\n\t\tconst filepath = tmpfile.path\r\n\t\tconst buffer = await image.buffer()\r\n\t\tfs.writeFileSync(\r\n\t\t\tfilepath,\r\n\t\t\tbuffer\r\n\t\t)\r\n\r\n\t\tconst file = fs.createReadStream( filepath )\r\n\t\tconst res = await this.upload( {\r\n\t\t\tfile,\r\n\t\t\tfilename\r\n\t\t} )\r\n\t\tawait tmpfile.cleanup()\r\n\r\n\t\treturn res\r\n\t}\r\n\t*/\r\n\r\n\tpublic whoAmI(): Promise<{ query: { userinfo: { id: number, name: string } } }> {\r\n\t\treturn this.#wiki.get<{ query: { userinfo: { id: number, name: string } } }>( {\r\n\t\t\taction: 'query',\r\n\t\t\tmeta: 'userinfo',\r\n\t\t\tuiprop: 'groups'\r\n\t\t} )\r\n\t}\r\n}\r\n","import type { AddActionQueryToken, APIError, ListQuery, NoActionToken, OpenSearchRequest, OpenSearchResponse, ParseRequest, ParseResponse, PropQuery, PurgeRequest, PurgeResponse, Request, RevisionsRequest, RevisionsResponse, SiteInfoRequest, SiteInfoResponse, TokensRequest, TokensResponse, TokenType } from '../../types'\r\nimport fs from 'fs'\r\nimport { MediaWikiError } from '../../errors'\r\nimport { RequestManager } from '../../utils'\r\n\r\nexport type Loaded<T extends Wiki = Wiki> = Required<T>\r\n\r\nexport class Wiki {\r\n\tpublic readonly api: string\r\n\tpublic readonly request: RequestManager\r\n\r\n\tpublic mainpage?: string\r\n\tpublic base?: string\r\n\tpublic sitename?: string\r\n\tpublic lang?: string\r\n\tpublic readonly?: boolean\r\n\tpublic writeapi?: boolean\r\n\tpublic articlepath?: string\r\n\tpublic scriptpath?: string\r\n\tpublic script?: string\r\n\tpublic server?: string\r\n\tpublic servername?: string\r\n\tpublic wikiid?: string\r\n\r\n\tpublic constructor( { api, request }: { api: string, request?: RequestManager } ) {\r\n\t\tthis.api = api.trim()\r\n\t\tthis.request = request ?? new RequestManager()\r\n\t}\r\n\r\n\tprivate querystring<T extends Request>( params: T ): Record<keyof T, string | fs.ReadStream> {\r\n\t\tconst qs = {} as Record<keyof T, string | fs.ReadStream>\r\n\r\n\t\tlet prop: keyof T\r\n\t\tfor ( prop in params ) {\r\n\t\t\tconst value = params[ prop ]\r\n\t\t\tif ( typeof value === 'boolean' ) {\r\n\t\t\t\tqs[ prop ] = value ? '1' : '0'\r\n\t\t\t} else if ( Array.isArray( value ) ) {\r\n\t\t\t\tconst values = value as unknown[]\r\n\t\t\t\tqs[ prop ] = values.join( '|' )\r\n\t\t\t} else if ( value instanceof fs.ReadStream ) {\r\n\t\t\t\tqs[ prop ] = value\r\n\t\t\t} else {\r\n\t\t\t\tqs[ prop ] = `${ value }`\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn qs\r\n\t}\r\n\r\n\tprotected async raw<T, U extends Request>( userparams: U, method: 'GET' | 'POST' ): Promise<T> {\r\n\t\tconst params = {\r\n\t\t\t...userparams,\r\n\t\t\tformat: 'json',\r\n\t\t\tformatversion: 2\r\n\t\t} as const\r\n\t\tconst qs = this.querystring( params )\r\n\r\n\t\tconst response: T | APIError = method === 'GET'\r\n\t\t\t? await this.request.get( {\r\n\t\t\t\tqs: qs as Record<string, string>,\r\n\t\t\t\turl: this.api\r\n\t\t\t} )\r\n\t\t\t: await this.request.post( {\r\n\t\t\t\tform: qs,\r\n\t\t\t\turl: this.api\r\n\t\t\t} )\r\n\r\n\t\tif ( 'error' in response ) {\r\n\t\t\tthrow new MediaWikiError( response.error )\r\n\t\t}\r\n\r\n\t\treturn response\r\n\t}\r\n\r\n\tpublic get<T, U extends Request = Request>( userparams: U | U & AddActionQueryToken ): Promise<T> {\r\n\t\treturn this.raw( userparams, 'GET' )\r\n\t}\r\n\r\n\tpublic post<T, U extends Request = Request>( userparams: U | U & AddActionQueryToken ): Promise<T> {\r\n\t\treturn this.raw( userparams, 'POST' )\r\n\t}\r\n\r\n\tpublic async exists(): Promise<boolean> {\r\n\t\tconst { statusCode } = await this.request.raw( this.api )\r\n\t\treturn statusCode === 200\r\n\t}\r\n\r\n\tpublic async getInterwikis(): Promise<Record<string, string>> {\r\n\t\tconst req = await this.get<SiteInfoResponse, SiteInfoRequest>( {\r\n\t\t\taction: 'query',\r\n\t\t\tmeta: 'siteinfo',\r\n\t\t\tsiprop: [ 'interwikimap' ]\r\n\t\t} )\r\n\r\n\t\tconst interwikis = req.query.interwikimap.filter( i => 'language' in i )\r\n\r\n\t\tconst result: Record<string, string> = {\r\n\t\t}\r\n\t\tfor ( const iw of interwikis ) {\r\n\t\t\ttry {\r\n\t\t\t\tresult[ iw.prefix ] = iw.url\r\n\t\t\t} catch ( e ) {\r\n\t\t\t\tcontinue\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn result\r\n\t}\r\n\r\n\tpublic getSiteInfo<T extends keyof SiteInfoResponse[ 'query' ]>( ...properties: T[] ): Promise<SiteInfoResponse> {\r\n\t\treturn this.get<SiteInfoResponse, SiteInfoRequest>( {\r\n\t\t\taction: 'query',\r\n\t\t\tmeta: 'siteinfo',\r\n\t\t\tsiprop: properties\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async getPages<T extends string>( _titles: T ): Promise<string>\r\n\tpublic async getPages<T extends string>( _titles: T[] ): Promise<{ [ key in T ]?: string }>\r\n\tpublic async getPages<T extends string>( _titles: T | T[] ): Promise<T | { [ key in T ]?: string }> {\r\n\t\tconst titles = Array.isArray( _titles ) ? _titles : [ _titles ]\r\n\r\n\t\tconst pages: { [ key in T ]?: string } = {\r\n\t\t}\r\n\r\n\t\twhile ( titles.length !== 0 ) {\r\n\t\t\tconst res = await this.get<RevisionsResponse, RevisionsRequest>( {\r\n\t\t\t\taction: 'query',\r\n\t\t\t\tprop: 'revisions',\r\n\t\t\t\trvprop: [ 'content' ],\r\n\t\t\t\trvslots: 'main',\r\n\t\t\t\ttitles: titles.splice( 0, 50 ).join( '|' )\r\n\t\t\t} )\r\n\r\n\t\t\tfor ( const page of res.query.pages ) {\r\n\t\t\t\tif ( !page.missing ) {\r\n\t\t\t\t\tconst { content } = page.revisions[ 0 ].slots.main\r\n\t\t\t\t\tif ( content ) pages[ page.title as T ] = content\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn Array.isArray( _titles ) ? pages : Object.values( pages )[ 0 ] ?? {}\r\n\t}\r\n\r\n\tpublic async getToken<Token extends TokenType>( type: Token ): Promise<TokensResponse<Token>> {\r\n\t\tconst req = await this.get<TokensResponse<Token>, TokensRequest>( {\r\n\t\t\taction: 'query',\r\n\t\t\tmeta: 'tokens',\r\n\t\t\ttype\r\n\t\t} )\r\n\r\n\t\treturn req\r\n\t}\r\n\r\n\tpublic getURL( title: string ): string {\r\n\t\ttitle = title.replace( / /g, '_' )\r\n\t\tconst base = new URL( this.api ).origin\r\n\t\tconst articlepath = new URL( this.articlepath ?? '/wiki/$1', base ).href\r\n\t\treturn articlepath.replace( '$1', encodeURI( title ) )\r\n\t}\r\n\r\n\tpublic async load(): Promise<Loaded<this>> {\r\n\t\tconst siteinfo = await this.getSiteInfo( 'general' )\r\n\r\n\t\tthis.mainpage = siteinfo.query.general.mainpage\r\n\t\tthis.base = siteinfo.query.general.base\r\n\t\tthis.sitename = siteinfo.query.general.sitename\r\n\t\tthis.lang = siteinfo.query.general.lang\r\n\t\tthis.readonly = siteinfo.query.general.readonly\r\n\t\tthis.writeapi = siteinfo.query.general.writeapi\r\n\t\tthis.articlepath = siteinfo.query.general.articlepath\r\n\t\tthis.scriptpath = siteinfo.query.general.scriptpath\r\n\t\tthis.script = siteinfo.query.general.script\r\n\t\tthis.server = siteinfo.query.general.server\r\n\t\tthis.servername = siteinfo.query.general.servername\r\n\t\tthis.wikiid = siteinfo.query.general.wikiid\r\n\r\n\t\treturn this as Loaded<this>\r\n\t}\r\n\r\n\tpublic async pagesExist( _titles: string ): Promise<boolean>\r\n\tpublic async pagesExist<T extends string>( _titles: T[] ): Promise<Record<T, boolean>>\r\n\tpublic async pagesExist<T extends string>( _titles: T ): Promise<boolean | Record<string, boolean>> {\r\n\t\tconst titles = Array.isArray( _titles ) ? _titles : [ _titles ]\r\n\r\n\t\tconst pages: Record<string, boolean> = {\r\n\t\t}\r\n\r\n\t\twhile ( titles.length !== 0 ) {\r\n\t\t\tconst res = await this.get<RevisionsResponse, RevisionsRequest>( {\r\n\t\t\t\taction: 'query',\r\n\t\t\t\tprop: 'revisions',\r\n\t\t\t\trvprop: [ 'content' ],\r\n\t\t\t\trvslots: 'main',\r\n\t\t\t\ttitles: titles.splice( 0, 50 ).join( '|' )\r\n\t\t\t} )\r\n\r\n\t\t\tfor ( const page of res.query.pages ) {\r\n\t\t\t\tif ( typeof _titles === 'string' ) {\r\n\t\t\t\t\treturn !page.missing\r\n\t\t\t\t}\r\n\t\t\t\tpages[ page.title ] = !page.missing\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn pages\r\n\t}\r\n\r\n\tpublic parse( params: NoActionToken<ParseRequest> ): Promise<ParseResponse> {\r\n\t\treturn this.get<ParseResponse, ParseRequest>( {\r\n\t\t\t...params,\r\n\t\t\taction: 'parse'\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async purge<T extends string>( titles: T[] ): Promise<Record<T, boolean>> {\r\n\t\tconst result: Record<string, boolean> = {\r\n\t\t}\r\n\r\n\t\twhile ( titles.length !== 0 ) {\r\n\t\t\tconst req = await this.post<PurgeResponse, PurgeRequest>( {\r\n\t\t\t\taction: 'purge',\r\n\t\t\t\ttitles: titles.splice( 0, 50 ).join( '|' )\r\n\t\t\t} )\r\n\r\n\t\t\tfor ( const item of req.purge ) {\r\n\t\t\t\tif ( 'missing' in item ) {\r\n\t\t\t\t\tresult[ item.title ] = false\r\n\t\t\t\t} else {\r\n\t\t\t\t\tresult[ item.title ] = true\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn result\r\n\t}\r\n\r\n\tpublic search( params: NoActionToken<OpenSearchRequest> ): Promise<OpenSearchResponse> {\r\n\t\treturn this.get( {\r\n\t\t\t...params,\r\n\t\t\taction: 'opensearch'\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async queryList<ListName extends keyof ListQuery = keyof ListQuery>( params: { list: ListName } & ListQuery[ ListName ][ 0 ], limit?: number ): Promise<Array<ListQuery[ ListName ][ 2 ]>> {\r\n\t\tconst generator = this.iterQueryList<ListName>( params, limit )\r\n\t\tconst result: Array<ListQuery[ ListName ][ 2 ]> = []\r\n\t\tfor await ( const item of generator ) {\r\n\t\t\tresult.push( item )\r\n\t\t}\r\n\t\treturn result\r\n\t}\r\n\r\n\tpublic async *iterQueryList<ListName extends keyof ListQuery = keyof ListQuery>( params: { list: ListName } & ListQuery[ ListName ][ 0 ], limit?: number ): AsyncGenerator<ListQuery[ ListName ][ 2 ]> {\r\n\t\tlet counter = 0\r\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\t\twhile ( true ) {\r\n\t\t\tconst req = await this.get<ListQuery[ ListName ][ 1 ] & { query: { [ key in ListName ]: Array<ListQuery[ ListName ][ 2 ]> } }>( {\r\n\t\t\t\taction: 'query',\r\n\t\t\t\t...params\r\n\t\t\t} )\r\n\r\n\t\t\tconst results = req.query[ params.list ] as Array<ListQuery[ ListName ][ 2 ]> | undefined\r\n\t\t\tif ( results ) {\r\n\t\t\t\tfor ( const item of results ) {\r\n\t\t\t\t\tyield item\r\n\t\t\t\t\tcounter++\r\n\t\t\t\t\tif ( limit && counter === limit ) return\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif ( !req.continue ) break\r\n\t\t\tconst continuekey = Object.keys( req.continue ).find( i => i !== 'continue' )\r\n\t\t\tif ( !continuekey ) break\r\n\t\t\t// @ts-expect-error - faulty typing i don't know how to fix\r\n\t\t\tparams[ continuekey ] = req.continue[ continuekey ] // eslint-disable-line @typescript-eslint/no-unsafe-assignment\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async queryProp<PropName extends keyof PropQuery = keyof PropQuery>( params: { prop: PropName } & PropQuery[ PropName ][ 0 ], limit?: number ): Promise<Array<PropQuery[ PropName ][ 2 ]>> {\r\n\t\tconst generator = this.iterQueryProp<PropName>( params, limit )\r\n\t\tconst result: Array<PropQuery[ PropName ][ 2 ]> = []\r\n\t\tfor await ( const item of generator ) {\r\n\t\t\tresult.push( item )\r\n\t\t}\r\n\t\treturn result.flat()\r\n\t}\r\n\r\n\tpublic async rawQueryProp<PropName extends keyof PropQuery = keyof PropQuery>( params: { prop: PropName } & PropQuery[ PropName ][ 0 ] ): Promise<PropQuery[ PropName ][ 1 ][ 'query' ]> {\r\n\t\tconst res = await this.get<PropQuery[ PropName ][ 1 ]>( {\r\n\t\t\taction: 'query',\r\n\t\t\t...params\r\n\t\t} )\r\n\t\treturn res.query\r\n\t}\r\n\r\n\tpublic async *iterQueryProp<PropName extends keyof PropQuery = keyof PropQuery>( params: { prop: PropName } & PropQuery[ PropName ][ 0 ], limit?: number ): AsyncGenerator<PropQuery[ PropName ][ 2 ]> {\r\n\t\tlet counter = 0\r\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\r\n\t\twhile ( true ) {\r\n\t\t\tconst req = await this.get<PropQuery[ PropName ][ 1 ] & { query: { [ key in PropName ]: Array<PropQuery[ PropName ][ 2 ]> } }>( {\r\n\t\t\t\taction: 'query',\r\n\t\t\t\t...params\r\n\t\t\t} )\r\n\r\n\t\t\tconst results = req.query.pages\r\n\t\t\tfor ( const item of results ) {\r\n\t\t\t\tyield item as PropQuery[ PropName ][ 2 ]\r\n\t\t\t\tcounter++\r\n\t\t\t\tif ( limit && counter === limit ) return\r\n\t\t\t}\r\n\r\n\t\t\tif ( !req.continue ) break\r\n\t\t\tconst continuekey = Object.keys( req.continue ).find( i => i !== 'continue' )\r\n\t\t\tif ( !continuekey ) break\r\n\t\t\t// @ts-expect-error - faulty typing i don't know how to fix\r\n\t\t\tparams[ continuekey ] = req.continue[ continuekey ] // eslint-disable-line @typescript-eslint/no-unsafe-assignment\r\n\t\t}\r\n\t}\r\n\r\n\tpublic async *iterPages( titles: string[] ): AsyncGenerator<RevisionsResponse[ 'query' ][ 'pages' ][ 0 ], void, unknown> {\r\n\t\twhile ( titles.length !== 0 ) {\r\n\t\t\tconst res = await this.get<RevisionsResponse, RevisionsRequest>( {\r\n\t\t\t\taction: 'query',\r\n\t\t\t\tprop: 'revisions',\r\n\t\t\t\trvprop: [ 'content' ],\r\n\t\t\t\trvslots: 'main',\r\n\t\t\t\ttitles: titles.splice( 0, 50 ).join( '|' )\r\n\t\t\t} )\r\n\r\n\t\t\tfor ( const page of res.query.pages ) {\r\n\t\t\t\tif ( page.missing === true ) {\r\n\t\t\t\t\tcontinue\r\n\t\t\t\t}\r\n\r\n\t\t\t\tyield page\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n","import fs from 'fs-extra'\r\nimport tough from 'tough-cookie'\r\n\r\ndeclare module 'tough-cookie' {\r\n\tinterface CookieJar {\r\n\t\tstore: tough.Store\r\n\t}\r\n}\r\n\r\nexport interface ICookieStoreOptions {\r\n\tregex: RegExp | RegExp[]\r\n\tpath: string\r\n}\r\n\r\nexport interface ICookieStorage {\r\n\t[ url: string ]: Map<string, tough.Cookie>\r\n}\r\n\r\nexport interface ICookieStorageJSON {\r\n\t[ url: string ]: Array<Record<string, unknown>>\r\n}\r\n\r\nexport interface ICookieJarOptions {\r\n\tprettify?: boolean\r\n\tstore?: ICookieStoreOptions | undefined\r\n}\r\n\r\nexport class CookieJar {\r\n\t#storage: ICookieStorage\r\n\t#store?: ICookieStoreOptions\r\n\t#prettify: boolean\r\n\r\n\tpublic constructor( { prettify = false, store }: ICookieJarOptions = {} ) {\r\n\t\tthis.#prettify = prettify\r\n\t\tthis.#storage = {}\r\n\t\tif ( store ) this.#store = store\r\n\r\n\t\tif ( !this.#store || !fs.existsSync( this.#store.path ) ) return\r\n\t\tconst jsonCookies = fs.readJsonSync( this.#store.path ) as ICookieStorageJSON\r\n\r\n\t\tfor ( const host in jsonCookies ) {\r\n\t\t\tthis.#storage[ host ] = new Map()\r\n\t\t\tconst hostCookies = jsonCookies[ host ]\r\n\t\t\tif ( !hostCookies ) continue\r\n\t\t\tfor ( const cookiedata of hostCookies ) {\r\n\t\t\t\tconst cookie = tough.Cookie.fromJSON( cookiedata )\r\n\t\t\t\tif ( !cookie ) continue\r\n\t\t\t\tif ( cookie.expiryTime() < Date.now() ) continue\r\n\t\t\t\tthis.#storage[ host ]?.set( cookie.key, cookie )\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.expire()\r\n\t}\r\n\r\n\tpublic clear( url: string ): void {\r\n\t\tconst host = CookieJar.getHost( url )\r\n\t\tif ( !this.#storage[ host ] ) return\r\n\t\tthis.#storage[ host ]?.clear()\r\n\t}\r\n\r\n\tpublic clearAll(): void {\r\n\t\tthis.#storage = {}\r\n\t}\r\n\r\n\tpublic expire( url?: string ): void {\r\n\t\tconst hosts = url ?? Object.keys( this.#storage )\r\n\t\tfor ( const host of hosts ) {\r\n\t\t\tconst collection = this.#storage[ host ]\r\n\t\t\tif ( !collection ) continue\r\n\t\t\tfor ( const [\r\n\t\t\t\tkey, cookie\r\n\t\t\t] of collection ) {\r\n\t\t\t\tlet shouldDelete = false\r\n\t\t\t\tconst isMaxAged = cookie.creation\r\n\t\t\t\t\t&& typeof cookie.maxAge === 'number'\r\n\t\t\t\t\t&& cookie.creation.getTime() + cookie.maxAge * 1000 < Date.now()\r\n\t\t\t\tif ( isMaxAged ) shouldDelete = false\r\n\t\t\t\tif ( typeof cookie.maxAge === 'string' ) shouldDelete = true\r\n\r\n\t\t\t\tconst isExpired = cookie.expires instanceof Date\r\n\t\t\t\t\t&& cookie.expires.getTime() < Date.now()\r\n\t\t\t\tif ( isExpired ) shouldDelete = false\r\n\r\n\t\t\t\tif ( shouldDelete ) collection.delete( key )\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\tpublic get( url: string ): string {\r\n\t\tconst host = CookieJar.getHost( url )\r\n\t\tthis.expire( host )\r\n\t\tconst storage = this.#storage[ host ]\r\n\t\tif ( !storage ) return ''\r\n\t\treturn [ ...storage.values() ].join( ';' )\r\n\t}\r\n\r\n\tpublic set( { cookie, url }: { cookie: string, url: string } ): void {\r\n\t\tconst toughcookie = tough.parse( cookie )\r\n\r\n\t\tif ( !toughcookie || !this.allowCookie( toughcookie ) ) return\r\n\r\n\t\tconst host = CookieJar.getHost( url )\r\n\t\tif ( !this.#storage[ host ] ) this.#storage[ host ] = new Map()\r\n\t\tthis.#storage[ host ]?.set( toughcookie.key, toughcookie )\r\n\r\n\t\tthis.save()\r\n\t}\r\n\r\n\tprivate allowCookie( cookie: tough.Cookie ): boolean {\r\n\t\tif ( !this.#store?.regex ) return true\r\n\t\tconst regexes = Array.isArray( this.#store.regex ) ? this.#store.regex : [ this.#store.regex ]\r\n\t\tconst match = regexes.find( regex => cookie.key.match( regex ) )\r\n\t\treturn match !== undefined\r\n\t}\r\n\r\n\tprivate static getHost( url: string ): string {\r\n\t\tconst { host, pathname } = new URL( url )\r\n\t\tconst lang = pathname.match( /\\/([a-z-]+)\\// )?.[ 1 ]\r\n\r\n\t\tif ( lang ) {\r\n\t\t\treturn `${ host }/${ lang }`\r\n\t\t}\r\n\t\treturn host\r\n\t}\r\n\r\n\tprivate save(): void {\r\n\t\tif ( !this.#store ) return\r\n\r\n\t\tfs.ensureFileSync( this.#store.path )\r\n\t\tconst jsonCookies: ICookieStorageJSON = {}\r\n\t\tfor ( const host in this.#storage ) {\r\n\t\t\tjsonCookies[ host ] = []\r\n\t\t\tconst cookies = this.#storage[ host ]\r\n\t\t\tif ( !cookies ) continue\r\n\t\t\tfor ( const cookie of cookies.values() ) {\r\n\t\t\t\tjsonCookies[ host ]?.push( cookie.toJSON() )\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tfs.writeJSONSync( this.#store.path, jsonCookies, {\r\n\t\t\tspaces: this.#prettify ? '\\t' : undefined\r\n\t\t} )\r\n\t}\r\n}\r\n","import { CookieJar, type ICookieJarOptions } from './CookieJar'\r\nimport { type Dispatcher, FormData, request } from 'undici'\r\nimport type { Agent } from 'undici'\r\nimport type fs from 'fs'\r\nimport { type IncomingHttpHeaders } from 'http'\r\n\r\ntype RequestOptions = Omit<Dispatcher.RequestOptions, 'path'>\r\ntype Response = Dispatcher.ResponseData\r\n\r\nexport class RequestManager {\r\n\tpublic agent: Agent | undefined\r\n\t#jar: CookieJar\r\n\tpublic headers: IncomingHttpHeaders\r\n\r\n\tpublic constructor( { agent, headers, jarOptions }: { agent?: Agent, headers?: IncomingHttpHeaders, jarOptions?: ICookieJarOptions } = {} ) {\r\n\t\tthis.agent = agent\r\n\t\tthis.#jar = new CookieJar( jarOptions )\r\n\t\tthis.headers = headers ?? {}\r\n\t}\r\n\r\n\tpublic get jar(): Readonly<CookieJar> {\r\n\t\treturn this.#jar\r\n\t}\r\n\r\n\tpublic clear( url: string ): void {\r\n\t\tthis.#jar.clear( url )\r\n\t}\r\n\r\n\tpublic async get<T>( { url, qs }: { url: string, qs: Record<string, string> } ): Promise<T> {\r\n\t\tconst params = new URLSearchParams( qs )\r\n\t\tconst { body, headers } = await this.raw( `${ url }?${ params }` )\r\n\r\n\t\tconst cookies: string[] = headers[ 'set-cookie' ] || []\r\n\t\tthis.addCookies( url, cookies )\r\n\r\n\t\treturn body.json() as unknown as T\r\n\t}\r\n\r\n\tpublic async post<T>( { url, form }: { url: string, form: Record<string, string | fs.ReadStream> } ): Promise<T> {\r\n\t\tconst formData = new FormData()\r\n\t\tfor ( const prop in form ) {\r\n\t\t\tformData.set( prop, form[ prop ] )\r\n\t\t}\r\n\r\n\t\tconst { body, headers } = await this.raw( url, {\r\n\t\t\tbody: formData,\r\n\t\t\tmethod: 'POST'\r\n\t\t} )\r\n\r\n\t\tthis.addCookies( url, headers[ 'set-cookie' ] )\r\n\r\n\t\treturn body.json() as unknown as T\r\n\t}\r\n\r\n\tpublic raw( url: string, fetchOptions: RequestOptions = { method: 'GET' } ): Promise<Response> {\r\n\t\treturn request( url, {\r\n\t\t\t...fetchOptions,\r\n\t\t\tdispatcher: this.agent,\r\n\t\t\theaders: {\r\n\t\t\t\t...this.headers,\r\n\t\t\t\tcookie: this.#jar.get( url )\r\n\t\t\t}\r\n\t\t} )\r\n\t}\r\n\r\n\tprivate addCookies( url: string, cookies: string | string[] | undefined ): void {\r\n\t\tif ( !cookies ) return\r\n\t\tconst cookiesList = Array.isArray( cookies ) ? cookies : [ cookies ]\r\n\t\tfor ( const cookie of cookiesList ) {\r\n\t\t\tthis.#jar.set( {\r\n\t\t\t\tcookie,\r\n\t\t\t\turl\r\n\t\t\t} )\r\n\t\t}\r\n\t}\r\n}\r\n","export const sleep = ( ms: number ): Promise<never> => new Promise<never>( r => setTimeout( r, ms ) )\r\n","import { Bot } from '../_base'\r\nimport type { FandomWiki } from './FandomWiki'\r\n\r\nexport class FandomBot extends Bot<FandomWiki> {\r\n\t#_wikis = new Set<string>()\r\n\r\n\tpublic constructor( {\r\n\t\tpassword, username, wiki\r\n\t}: { password: string, username: string, wiki: FandomWiki } ) {\r\n\t\tsuper( {\r\n\t\t\tpassword,\r\n\t\t\tusername,\r\n\t\t\twiki\r\n\t\t} )\r\n\t\tthis.#_wikis.add( wiki.interwiki )\r\n\t}\r\n\r\n\tpublic async setWiki( wiki: FandomWiki ): Promise<void> {\r\n\t\tthis.wiki = wiki\r\n\r\n\t\tif ( !this.#_wikis.has( wiki.interwiki ) ) {\r\n\t\t\tawait this.login()\r\n\t\t\tthis.#_wikis.add( wiki.interwiki )\r\n\t\t}\r\n\r\n\t\tthis.csrf = null\r\n\t}\r\n}\r\n","import { Fandom } from './Fandom'\r\nimport type { Loaded } from '../_base'\r\nimport type { RequestManager } from '../../utils'\r\nimport { Wiki } from '../_base'\r\n\r\nexport class FandomWiki extends Wiki {\r\n\tpublic readonly interwiki: string\r\n\tpublic id?: number\r\n\r\n\tpublic constructor( {\r\n\t\tinterwiki, request\r\n\t}: { interwiki: string, request: RequestManager } ) {\r\n\t\tsuper( {\r\n\t\t\tapi: Fandom.interwiki2api( interwiki ),\r\n\t\t\trequest\r\n\t\t} )\r\n\r\n\t\tthis.interwiki = interwiki\r\n\t}\r\n\r\n\tpublic override getURL( title: string ): string {\r\n\t\ttitle = title.replace( / /g, '_' )\r\n\t\tconst base = this.api.replace( '/api.php', '/wiki/' )\r\n\t\treturn new URL( title, base ).href\r\n\t}\r\n\r\n\tpublic override async load(): Promise<Loaded<this>> {\r\n\t\tif ( this.id ) return this as Loaded<this>\r\n\r\n\t\tconst siteinfo = await this.getSiteInfo( 'general', 'variables' )\r\n\r\n\t\tthis.mainpage = siteinfo.query.general.mainpage\r\n\t\tthis.base = siteinfo.query.general.base\r\n\t\tthis.sitename = siteinfo.query.general.sitename\r\n\t\tthis.lang = siteinfo.query.general.lang\r\n\t\tthis.readonly = siteinfo.query.general.readonly\r\n\t\tthis.writeapi = siteinfo.query.general.writeapi\r\n\t\tthis.articlepath = siteinfo.query.general.articlepath\r\n\t\tthis.scriptpath = siteinfo.query.general.scriptpath\r\n\t\tthis.script = siteinfo.query.general.script\r\n\t\tthis.server = siteinfo.query.general.server\r\n\t\tthis.servername = siteinfo.query.general.servername\r\n\t\tthis.wikiid = siteinfo.query.general.wikiid\r\n\r\n\t\tthis.id = siteinfo.query.variables.find( i => i.id === 'wgCityId' )?.[ '*' ] as number\r\n\r\n\t\treturn this as Loaded<this>\r\n\t}\r\n}\r\n","import { FandomBot } from './FandomBot'\r\nimport { FandomWiki } from './FandomWiki'\r\nimport type { ICookieJarOptions } from '../../utils'\r\nimport { InvalidInterwikiError } from '../../errors'\r\nimport { RequestManager } from '../../utils'\r\n\r\nexport class Fandom {\r\n\tpublic static request?: RequestManager\r\n\r\n\tpublic readonly request: RequestManager\r\n\r\n\tpublic constructor( { cookies, prettyCookies = false, requestOptions = {} }: { cookies?: string, prettyCookies?: boolean, requestOptions?: ConstructorParameters<typeof RequestManager>[ 0 ] } = {} ) {\r\n\t\tconst jarOptions: ICookieJarOptions = {\r\n\t\t\tprettify: prettyCookies\r\n\t\t}\r\n\t\tif ( cookies ) {\r\n\t\t\tjarOptions.store = {\r\n\t\t\t\tpath: cookies,\r\n\t\t\t\tregex: [ /^wiki(a|cities)_/ ]\r\n\t\t\t}\r\n\t\t}\r\n\t\tthis.request = new RequestManager( {\r\n\t\t\t...requestOptions,\r\n\t\t\tjarOptions\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic static interwiki2path( _interwiki: string ): string {\r\n\t\tconst interwiki = _interwiki.toLowerCase()\r\n\r\n\t\tif ( interwiki.match( /[a-z0-9-]+\\.[a-z0-9-]+/ ) ) {\r\n\t\t\tconst [\r\n\t\t\t\tlang, wikiname\r\n\t\t\t] = interwiki.split( '.' )\r\n\t\t\treturn `https://${ wikiname }.fandom.com/${ lang }`\r\n\t\t} else if ( interwiki.match( /^[a-z0-9-]+$/ ) ) {\r\n\t\t\treturn `https://${ interwiki }.fandom.com`\r\n\t\t}\r\n\t\tthrow new InvalidInterwikiError( interwiki )\r\n\t}\r\n\r\n\tpublic static getWiki( interwiki: string ): FandomWiki {\r\n\t\tif ( !this.request ) this.request = new RequestManager()\r\n\t\treturn new FandomWiki( {\r\n\t\t\tinterwiki,\r\n\t\t\trequest: this.request\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic static interwiki2api( interwiki: string ): string {\r\n\t\tconst path = Fandom.interwiki2path( interwiki )\r\n\t\treturn `${ path }/api.php`\r\n\t}\r\n\r\n\tpublic static interwiki2url( interwiki: string ): string {\r\n\t\tconst path = Fandom.interwiki2path( interwiki )\r\n\t\treturn `${ path }/wiki/`\r\n\t}\r\n\r\n\tpublic static url2interwiki( url: string ): string {\r\n\t\tconst nolangRegex = /https?:\\/\\/([a-z0-9-]+)\\.fandom\\.com\\/(wiki|api|index)/\r\n\t\tconst nolang = url.match( nolangRegex )?.[ 1 ]\r\n\t\tif ( nolang ) {\r\n\t\t\treturn nolang\r\n\t\t}\r\n\r\n\t\tconst langRegex = /https?:\\/\\/([a-z0-9-]+)\\.fandom\\.com\\/([a-z-]+)\\/(wiki|api|index)/\r\n\t\tconst lang = url.match( langRegex )\r\n\r\n\t\tif ( lang ) {\r\n\t\t\treturn `${ lang[ 2 ] }.${ lang[ 1 ] }`\r\n\t\t}\r\n\r\n\t\tthrow new InvalidInterwikiError( url )\r\n\t}\r\n\r\n\tpublic async getUserAvatar( username: string ): Promise<string | null> {\r\n\t\tconst userId = await this.getUserId( username )\r\n\t\tif ( !userId ) return null\r\n\r\n\t\tconst { body } = await this.request.raw( `https://services.fandom.com/user-attribute/user/${ userId }/attr/avatar` )\r\n\t\tconst res = await body.json() as unknown as { value?: string }\r\n\r\n\t\treturn res.value ?? null\r\n\t}\r\n\r\n\tpublic async getUserDiscordTag( username: string ): Promise<string | null> {\r\n\t\tconst userId = await this.getUserId( username )\r\n\t\tif ( !userId ) return null\r\n\r\n\t\tconst { body } = await this.request.raw( `https://services.fandom.com/user-attribute/user/${ userId }/attr/discordHandle` )\r\n\t\tconst res = await body.json() as unknown as { value?: string }\r\n\r\n\t\treturn res.value ?? null\r\n\t}\r\n\r\n\tpublic async getUserId( username: string ): Promise<number | null> {\r\n\t\tconst wiki = this.getWiki( 'community' )\r\n\t\tconst query = await wiki.queryList( {\r\n\t\t\tlist: 'users',\r\n\t\t\tususers: username\r\n\t\t} )\r\n\t\treturn query[ 0 ]?.userid ?? null\r\n\t}\r\n\r\n\tpublic async getUsersIds( usernames: string[] ): Promise<Record<string, number>> {\r\n\t\tconst wiki = this.getWiki( 'community' )\r\n\t\tconst query = await wiki.queryList( {\r\n\t\t\tlist: 'users',\r\n\t\t\tususers: usernames\r\n\t\t} )\r\n\t\treturn query.reduce( ( result, user ) => {\r\n\t\t\tresult[ user.name ] = user.userid\r\n\t\t\treturn result\r\n\t\t}, {} as Record<string, number> )\r\n\t}\r\n\r\n\tpublic getWiki( interwiki: string ): FandomWiki {\r\n\t\treturn new FandomWiki( {\r\n\t\t\tinterwiki,\r\n\t\t\trequest: this.request\r\n\t\t} )\r\n\t}\r\n\r\n\tpublic async login( {\r\n\t\tpassword, username, wiki\r\n\t}: { password: string, username: string, wiki?: FandomWiki } ): Promise<FandomBot> {\r\n\t\tconst bot = new FandomBot( {\r\n\t\t\tpassword,\r\n\t\t\tusername,\r\n\t\t\twiki: wiki ?? this.getWiki( 'community' )\r\n\t\t} )\r\n\r\n\t\tawait bot.login()\r\n\r\n\t\treturn bot\r\n\t}\r\n}\r\n"]}