diff --git a/src/export_command/wikimedia_function/bot.ts b/src/export_command/wikimedia_function/bot.ts index d5ef806..40381bd 100644 --- a/src/export_command/wikimedia_function/bot.ts +++ b/src/export_command/wikimedia_function/bot.ts @@ -23,7 +23,7 @@ export function logoutFactory() { await bot?.request({ 'action': Action.logout, 'token': bot.editToken - }); + }, { method: 'POST' }); // clear bot bot = undefined; vscode.window.showInformationMessage('result: Success'); @@ -99,7 +99,7 @@ export async function getLoggedInBot(): Promise { case 'Always': return await login() ? bot : undefined; case 'Never': - vscode.window.showWarningMessage('You are not logged in. Please log in and try again.'); + vscode.window.showWarningMessage('Notice: You are not logged in.'); return undefined; case 'Ask me': default: @@ -131,7 +131,7 @@ export async function compareVersion(tBot: MWBot, major: number, minor: number, meta: Meta.siteInfo, }; - const result: unknown = await tBot.request(args); + const result: unknown = await tBot.request(args, { method: 'GET' }); const re: any = result as any; // TODO: cast diff --git a/src/export_command/wikimedia_function/page.ts b/src/export_command/wikimedia_function/page.ts index 16e056f..31afc4b 100644 --- a/src/export_command/wikimedia_function/page.ts +++ b/src/export_command/wikimedia_function/page.ts @@ -31,7 +31,7 @@ export function postPageFactory() { meta: 'tokens', type: 'csrf' }; - const result: unknown = await bot.request(args); + const result: unknown = await bot.request(args, { method: 'GET' }); const reNew: TokensResult = TokensConvert.toResult(result); const token: string | undefined = reNew.query?.tokens?.csrftoken; if (token) { @@ -47,7 +47,7 @@ export function postPageFactory() { action: "tokens", type: "edit" }; - const result: unknown = await bot.request(args); + const result: unknown = await bot.request(args, { method: 'GET' }); const reOld: OldTokensResult = OldTokensConvert.toResult(result); const token: string | undefined = reOld.tokens?.edittoken; if (token) { @@ -120,7 +120,7 @@ export function postPageFactory() { // if (config.get("redirect")) { // args['redirect'] = "true"; // } - const result: any = await tBot.request(args); + const result: any = await tBot.request(args, { method: 'POST' }); // TODO: Convert if (result.edit.nochange !== undefined) { vscode.window.showWarningMessage( @@ -253,7 +253,7 @@ ${infoLine} const barMessage: vscode.Disposable = vscode.window.setStatusBarMessage("Wikitext: Getting code..."); try { // get request result - const result: unknown = await tBot.request(args); + const result: unknown = await tBot.request(args, { method: 'GET' }); // console.log(result); // Convert result as class const re: ReadPageResult = ReadPageConvert.toResult(result); @@ -361,7 +361,7 @@ async function getValidTagList(tBot: MWBot): Promise<(number | string)[]> { const tagList: (number | string)[] = []; for (; ;) { - const result: unknown = await tBot.request(args); + const result: unknown = await tBot.request(args, { method: 'GET' }); const re: TagsResult = TagsConvert.toResult(result); tagList.push( diff --git a/src/export_command/wikimedia_function/view.ts b/src/export_command/wikimedia_function/view.ts index 0ca659d..d9d54a0 100644 --- a/src/export_command/wikimedia_function/view.ts +++ b/src/export_command/wikimedia_function/view.ts @@ -116,7 +116,7 @@ export async function showViewer(currentPanel: vscode.WebviewPanel | string, vie const barMessage: vscode.Disposable = vscode.window.setStatusBarMessage("Wikitext: Getting view..."); try { - const result: unknown = await tBot.request(args); + const result: unknown = await tBot.request(args, { method: 'GET' }); const re: GetViewResult = ViewConvert.toResult(result); if (!re.parse) { return undefined; } diff --git a/src/extension-node.ts b/src/extension-node.ts index 2e95a64..7978c99 100644 --- a/src/extension-node.ts +++ b/src/extension-node.ts @@ -11,6 +11,7 @@ import { baseUriProcess } from './export_command/uri_function/uri'; import { addWebCiteFactory } from './export_command/cite_function/web'; import { WikitextCommandRegistrar } from './export_command/commandRegistrar'; import { client, restartLspFactory } from './export_command/vscode_function/wikiparser'; +import './mwbot-patch'; export async function activate(context: vscode.ExtensionContext): Promise { console.log("Wikitext Extension is active."); diff --git a/src/extension-web.ts b/src/extension-web.ts index e9d30d4..5f443a0 100644 --- a/src/extension-web.ts +++ b/src/extension-web.ts @@ -7,6 +7,7 @@ import * as vscode from 'vscode'; import { closeEditorFactory } from './export_command/wikimedia_function/page'; import { WikitextCommandRegistrar } from './export_command/commandRegistrar'; import { client, restartLspFactory } from './export_command/vscode_function/wikiparser'; +import './mwbot-patch'; export async function activate(context: vscode.ExtensionContext): Promise { function showUnsupportedMessageFactory() { diff --git a/src/interface_definition/mwbot.d.ts b/src/interface_definition/mwbot.d.ts index 58c60ea..0afa81f 100644 --- a/src/interface_definition/mwbot.d.ts +++ b/src/interface_definition/mwbot.d.ts @@ -5,375 +5,386 @@ declare module 'mwbot' { - interface CounterInterface { - total: number; - resolved: number; - fulfilled: number; - rejected: number; - } - - /** - * MWBot library - * - * @author Simon Heimler - */ - class MWBot { - - ////////////////////////////////////////// - // FIELD // - ////////////////////////////////////////// - - state: object; - editToken: string; - loggedIn: boolean; - createaccountToken: string; - counter: CounterInterface; - // defaultOptions: - - ////////////////////////////////////////// - // CONSTRUCTOR // - ////////////////////////////////////////// + interface CounterInterface { + total: number; + resolved: number; + fulfilled: number; + rejected: number; + } /** - * Constructs a new MWBot instance - * It is advised to create one bot instance for every API to use - * A bot instance has its own state (e.g. tokens) that is - necessary for some operations + * MWBot library * - * @param {{}} [customOptions] Custom options - * @param {{}} [customRequestOptions] Custom request options + * @author Simon Heimler */ - constructor(customOptions?: object, customRequestOptions?: object); - - ////////////////////////////////////////// - // GETTER & SETTER // - ////////////////////////////////////////// - - /** - * Get mwbot version number - * Uses ES5 getter - */ - get version(): any; - - - /** - * Set and overwrite mwbot options - * - * @param {Object} customOptions - */ - public setOptions(customOptions: object): void; - - /** - * Sets and overwrites the raw request options, used by the "request" library - * See https://www.npmjs.com/package/request - * - * @param {{}} customRequestOptions - */ - setGlobalRequestOptions(customRequestOptions: object): void; - - /** - * Sets the API URL for MediaWiki requests - * This can be uses instead of a login, if no actions are used that require one. - * - * @param {String} apiUrl API Url to MediaWiki, e.g. 'https://www.semantic-mediawiki.org/w/api.php' - */ - setApiUrl(apiUrl: string): void; - - ////////////////////////////////////////// - // CORE REQUESTS // - ////////////////////////////////////////// - - /** - * Executes a promisified raw request - * Uses the npm request library - * - * @param {object} requestOptions - * - * @returns {PromiseLike} - */ - rawRequest(requestOptions: object): PromiseLike; - - /** - *Executes a request with the ability to use custom parameters and custom request options - * - * @param {object} params Request Parameters - * @param {object} customRequestOptions Custom request options - * - * @returns {PromiseLike} - */ - request(params: object, customRequestOptions?: object): PromiseLike; - - ////////////////////////////////////////// - // CORE FUNCTIONS // - ////////////////////////////////////////// - - /** - * Executes a Login - * - * @see https://www.mediawiki.org/wiki/API:Login - * - * @param {object} [loginOptions] - * - * @returns {PromiseLike} - */ - login(loginOptions?: object): PromiseLike; - - /** - * Gets an edit token - * This is currently only compatible with MW >= 1.24 - * - * @returns {PromiseLike} - */ - getEditToken(): PromiseLike; - - /** - * Gets an edit token - * Requires MW 1.27+ - * - * @returns {PromiseLike} - */ - getCreateaccountToken(): PromiseLike; - - /** - * Combines Login with GetEditToken - * - * @param {object} loginOptions - * - * @returns {PromiseLike} - */ - loginGetEditToken(loginOptions: object): PromiseLike; - - /** - * Combines Login with GetCreateAccountToken - * - * @param {object} loginOptions - * - * @returns {PromiseLike} - */ - loginGetCreateaccountToken(loginOptions: object): PromiseLike; - - ////////////////////////////////////////// - // CRUD OPERATIONS // - ////////////////////////////////////////// - - /** - * Creates a new wiki pages. Does not edit existing ones - * - * @param {string} title - * @param {string} content - * @param {string} [summary] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - create(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; - - /** - * Reads the content / and meta-data of one (or many) wikipages - * - * Wrapper for readWithProps - * - * @param {string} title For multiple Pages use: PageA|PageB|PageC - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - read(title: string,/*redirect?: boolean, */ customRequestOptions?: object): PromiseLike; - - // /** - // * Reads the content / and meta-data of one (or many) wikipages - // * - // * Wrapper for readWithPropsFromID - // * - // * @param {number} pageid For multiple Pages use: PageA|PageB|PageC - // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page - // * @param {object} [customRequestOptions] - // * - // * @returns {PromiseLike} - // */ - // readFromID(pageid: number, redirect: boolean, customRequestOptions?: object): PromiseLike; - - // /** - // * Reads the content / and meta-data of one (or many) wikipages based on specific parameters - // * - // * @param {string} title For multiple Pages use: PageA|PageB|PageC - // * @param {string} props For multiple Props use: user|userid|content - // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page - // * @param {object} [customRequestOptions] - // * - // * @returns {PromiseLike} - // */ - // readWithProps(title: string, props: string, redirect: boolean, customRequestOptions?: object): PromiseLike; - - // /** - // * Reads the content / and meta-data of one (or many) wikipages based on specific parameters - // * - // * @param {number} pageid For multiple Pages use: PageA|PageB|PageC - // * @param {string} props For multiple Props use: user|userid|content - // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page - // * @param {object} [customRequestOptions] - // * - // * @returns {PromiseLike} - // */ - // readWithPropsFromID(pageid: number, props: string, redirect: boolean, customRequestOptions?: object): PromiseLike; - - /** - * Edits a new wiki pages. Creates a new page if it does not exist yet. - * - * @param {string} title - * @param {string} content - * @param {string} [summary] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - edit(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; - - /** - * Updates existing wiki pages. Does not create new ones. - * - * @param {string} title - * @param {string} content - * @param {string} [summary] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - update(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; - - /** - * Updates existing wiki pages. Does not create new ones. - * - * @param {number} pageid - * @param {string} content - * @param {string} [summary] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - updateFromID(pageid: number, content: string, summary?: string, customRequestOptions?: object): PromiseLike; - - /** - * Deletes a new wiki page - * - * @param {string} title - * @param {string} [reason] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - delete(title: string, reason?: string, customRequestOptions?: object): PromiseLike; - - /** - * Moves a wiki page - * - * @param {string} oldName - * @param {string} newName - * @param {string} [reason] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - move(oldTitle: string, newTitle: string, reason?: string, customRequestOptions?: object): PromiseLike; - - /** - * Uploads a file - * - * @param {string} [title] nullable, if null, it will be the same as the basename of pathToFile arg. - * @param {string} pathToFile - * @param {string} [comment] - * @param {object} [customParams] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - upload(title: string, pathToFile: string, comment?: string, customParams?: object, customRequestOptions?: object): PromiseLike; - - /** - * Uploads a file and overwrites existing ones - * - * @param {string} [title] nullable, if null, it will be the same as the basename of pathToFile arg. - * @param {string} pathToFile - * @param {string} [comment] - * @param {object} [customParams] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - uploadOverwrite(title: string, pathToFile: string, comment?: string, customParams?: object, customRequestOptions?: object): PromiseLike; - - - ////////////////////////////////////////// - // CONVENIENCE FUNCTIONS // - ////////////////////////////////////////// - - /** - * Combines all standard CRUD operations into one concurrent batch operation - * The batch request will also print log messages about the current job status - * It includes some more detailed error handling - * - * If the concurrency is set to 1, it ensures a sequential order - * by switching from Promise.map to Promise.mapSeries - * - * @param {object|array} jobs - * @param {string} [summary] - * @param {number} [concurrency] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - batch(jobs: object | any[], summary?: string, concurrency?: number, customRequestOptions?: object): PromiseLike; - - /** - * Execute an ASK Query - * - * @param {string} query - * @param {string} [apiUrl] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - askQuery(query: string, apiUrl?: string, customRequestOptions?: object): PromiseLike; - - /** - * Executes a SPARQL Query - * Defaults to use the wikidata endpoint - * - * @param {string} query - * @param {string} [endpointUrl] - * @param {object} [customRequestOptions] - * - * @returns {PromiseLike} - */ - sparqlQuery(query: string, endpointUrl?: string, customRequestOptions?: object): PromiseLike; - - ////////////////////////////////////////// - // HELPER FUNCTIONS // - ////////////////////////////////////////// - - /** - * Recursively merges two objects - * Takes care that the two objects are not mutated - * - * @param {object} parent Parent Object - * @param {object} child Child Object; overwrites parent properties - * - * @returns {object} Merged Object - */ - static merge(parent: object, child: object): object; - - /** - * Prints status information about a completed request - * - * @param status - * @param currentCounter - * @param totalCounter - * @param operation - * @param pageName - * @param reason - */ - static logStatus(status: any, currentCounter: any, totalCounter: any, operation: any, pageName: any, reason: any): void; - } + class MWBot { + + ////////////////////////////////////////// + // FIELD // + ////////////////////////////////////////// + + state: object; + editToken: string; + loggedIn: boolean; + createaccountToken: string; + counter: CounterInterface; + // defaultOptions: + + ////////////////////////////////////////// + // CONSTRUCTOR // + ////////////////////////////////////////// + + /** + * Constructs a new MWBot instance + * It is advised to create one bot instance for every API to use + * A bot instance has its own state (e.g. tokens) that is + necessary for some operations + * + * @param {{}} [customOptions] Custom options + * @param {{}} [customRequestOptions] Custom request options + */ + constructor(customOptions?: object, customRequestOptions?: object); + + ////////////////////////////////////////// + // GETTER & SETTER // + ////////////////////////////////////////// + + /** + * Get mwbot version number + * Uses ES5 getter + */ + get version(): any; + + + /** + * Set and overwrite mwbot options + * + * @param {Object} customOptions + */ + public setOptions(customOptions: object): void; + + /** + * Sets and overwrites the raw request options, used by the "request" library + * See https://www.npmjs.com/package/request + * + * @param {{}} customRequestOptions + */ + setGlobalRequestOptions(customRequestOptions: RequestOptions): void; + + /** + * Sets the API URL for MediaWiki requests + * This can be uses instead of a login, if no actions are used that require one. + * + * @param {String} apiUrl API Url to MediaWiki, e.g. 'https://www.semantic-mediawiki.org/w/api.php' + */ + setApiUrl(apiUrl: string): void; + + ////////////////////////////////////////// + // CORE REQUESTS // + ////////////////////////////////////////// + + /** + * Executes a promisified raw request + * Uses the npm request library + * + * @param {object} requestOptions + * + * @returns {PromiseLike} + */ + rawRequest(requestOptions: object): PromiseLike; + + /** + *Executes a request with the ability to use custom parameters and custom request options + * + * @param {object} params Request Parameters + * @param {object} customRequestOptions Custom request options + * + * @returns {PromiseLike} + */ + request(params: object, customRequestOptions?: RequestOptions): PromiseLike; + + ////////////////////////////////////////// + // CORE FUNCTIONS // + ////////////////////////////////////////// + + /** + * Executes a Login + * + * @see https://www.mediawiki.org/wiki/API:Login + * + * @param {object} [loginOptions] + * + * @returns {PromiseLike} + */ + login(loginOptions?: object): PromiseLike; + + /** + * Gets an edit token + * This is currently only compatible with MW >= 1.24 + * + * @returns {PromiseLike} + */ + getEditToken(): PromiseLike; + + /** + * Gets an edit token + * Requires MW 1.27+ + * + * @returns {PromiseLike} + */ + getCreateaccountToken(): PromiseLike; + + /** + * Combines Login with GetEditToken + * + * @param {object} loginOptions + * + * @returns {PromiseLike} + */ + loginGetEditToken(loginOptions: object): PromiseLike; + + /** + * Combines Login with GetCreateAccountToken + * + * @param {object} loginOptions + * + * @returns {PromiseLike} + */ + loginGetCreateaccountToken(loginOptions: object): PromiseLike; + + ////////////////////////////////////////// + // CRUD OPERATIONS // + ////////////////////////////////////////// + + /** + * Creates a new wiki pages. Does not edit existing ones + * + * @param {string} title + * @param {string} content + * @param {string} [summary] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + create(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; + + /** + * Reads the content / and meta-data of one (or many) wikipages + * + * Wrapper for readWithProps + * + * @param {string} title For multiple Pages use: PageA|PageB|PageC + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + read(title: string,/*redirect?: boolean, */ customRequestOptions?: object): PromiseLike; + + // /** + // * Reads the content / and meta-data of one (or many) wikipages + // * + // * Wrapper for readWithPropsFromID + // * + // * @param {number} pageid For multiple Pages use: PageA|PageB|PageC + // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page + // * @param {object} [customRequestOptions] + // * + // * @returns {PromiseLike} + // */ + // readFromID(pageid: number, redirect: boolean, customRequestOptions?: object): PromiseLike; + + // /** + // * Reads the content / and meta-data of one (or many) wikipages based on specific parameters + // * + // * @param {string} title For multiple Pages use: PageA|PageB|PageC + // * @param {string} props For multiple Props use: user|userid|content + // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page + // * @param {object} [customRequestOptions] + // * + // * @returns {PromiseLike} + // */ + // readWithProps(title: string, props: string, redirect: boolean, customRequestOptions?: object): PromiseLike; + + // /** + // * Reads the content / and meta-data of one (or many) wikipages based on specific parameters + // * + // * @param {number} pageid For multiple Pages use: PageA|PageB|PageC + // * @param {string} props For multiple Props use: user|userid|content + // * @param {boolean} redirect If the page is a redirection, follow it or stay in the page + // * @param {object} [customRequestOptions] + // * + // * @returns {PromiseLike} + // */ + // readWithPropsFromID(pageid: number, props: string, redirect: boolean, customRequestOptions?: object): PromiseLike; + + /** + * Edits a new wiki pages. Creates a new page if it does not exist yet. + * + * @param {string} title + * @param {string} content + * @param {string} [summary] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + edit(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; + + /** + * Updates existing wiki pages. Does not create new ones. + * + * @param {string} title + * @param {string} content + * @param {string} [summary] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + update(title: string, content: string, summary?: string, customRequestOptions?: object): PromiseLike; + + /** + * Updates existing wiki pages. Does not create new ones. + * + * @param {number} pageid + * @param {string} content + * @param {string} [summary] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + updateFromID(pageid: number, content: string, summary?: string, customRequestOptions?: object): PromiseLike; + + /** + * Deletes a new wiki page + * + * @param {string} title + * @param {string} [reason] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + delete(title: string, reason?: string, customRequestOptions?: object): PromiseLike; + + /** + * Moves a wiki page + * + * @param {string} oldName + * @param {string} newName + * @param {string} [reason] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + move(oldTitle: string, newTitle: string, reason?: string, customRequestOptions?: object): PromiseLike; + + /** + * Uploads a file + * + * @param {string} [title] nullable, if null, it will be the same as the basename of pathToFile arg. + * @param {string} pathToFile + * @param {string} [comment] + * @param {object} [customParams] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + upload(title: string, pathToFile: string, comment?: string, customParams?: object, customRequestOptions?: object): PromiseLike; + + /** + * Uploads a file and overwrites existing ones + * + * @param {string} [title] nullable, if null, it will be the same as the basename of pathToFile arg. + * @param {string} pathToFile + * @param {string} [comment] + * @param {object} [customParams] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + uploadOverwrite(title: string, pathToFile: string, comment?: string, customParams?: object, customRequestOptions?: object): PromiseLike; + + + ////////////////////////////////////////// + // CONVENIENCE FUNCTIONS // + ////////////////////////////////////////// + + /** + * Combines all standard CRUD operations into one concurrent batch operation + * The batch request will also print log messages about the current job status + * It includes some more detailed error handling + * + * If the concurrency is set to 1, it ensures a sequential order + * by switching from Promise.map to Promise.mapSeries + * + * @param {object|array} jobs + * @param {string} [summary] + * @param {number} [concurrency] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + batch(jobs: object | any[], summary?: string, concurrency?: number, customRequestOptions?: object): PromiseLike; + + /** + * Execute an ASK Query + * + * @param {string} query + * @param {string} [apiUrl] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + askQuery(query: string, apiUrl?: string, customRequestOptions?: object): PromiseLike; + + /** + * Executes a SPARQL Query + * Defaults to use the wikidata endpoint + * + * @param {string} query + * @param {string} [endpointUrl] + * @param {object} [customRequestOptions] + * + * @returns {PromiseLike} + */ + sparqlQuery(query: string, endpointUrl?: string, customRequestOptions?: object): PromiseLike; + + ////////////////////////////////////////// + // HELPER FUNCTIONS // + ////////////////////////////////////////// + + /** + * Recursively merges two objects + * Takes care that the two objects are not mutated + * + * @param {object} parent Parent Object + * @param {object} child Child Object; overwrites parent properties + * + * @returns {object} Merged Object + */ + static merge(parent: object, child: object): object; + + /** + * Prints status information about a completed request + * + * @param status + * @param currentCounter + * @param totalCounter + * @param operation + * @param pageName + * @param reason + */ + static logStatus(status: any, currentCounter: any, totalCounter: any, operation: any, pageName: any, reason: any): void; + } + + export = MWBot; +} - export = MWBot; +type RequestOptions = { + method?: 'POST' | 'GET', + headers?: Record, + qs?: Record, + form?: unknown, + timeout?: number, + jar?: unknown, + time?: boolean, + json?: boolean } diff --git a/src/mwbot-patch.ts b/src/mwbot-patch.ts new file mode 100644 index 0000000..4dc516d --- /dev/null +++ b/src/mwbot-patch.ts @@ -0,0 +1,21 @@ +import MWBot from "mwbot"; + +const originalRequest = MWBot.prototype.request; + +MWBot.prototype.request = function (this: unknown, params: object = {}, customRequestOptions: RequestOptions = {}) { + const method = customRequestOptions.method?.toUpperCase(); + if (method === 'GET') { + const modifiedOptions: RequestOptions = { + ...customRequestOptions, + method: 'GET', + qs: { + ...(customRequestOptions.qs || {}), + ...params, + format: 'json' + } + }; + + return originalRequest.call(this, {}, modifiedOptions); + } + return originalRequest.call(this, params, customRequestOptions); +};