# Wikiapi

#### new Wikiapi(API_URLopt)

Source:
  - wikiapi.js, line 91

main Wikiapi operator 操作子.

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`API_URL` | String | Object | <optional> | language code or service endpoint of MediaWiki project. Input {Object} will be treat as options.

### Members

#### (static) KEY_subcategories

Source:
  - wikiapi.js, line 1114

export key for subcategory 子分類 used in Wikiapi#category_tree

##### Example

    // <code>
    const KEY_subcategories = Wikiapi.KEY_subcategories;
    // </code>

#### (static) skip_edit

Source:
  - wikiapi.js, line 525

Return `Wikiapi.skip_edit` when we running edit function, but do not want to edit current page.

### Methods

#### category_tree(root_category, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1090

Get structural category tree with sub-categories of `root_category`. This is powerful than categorymembers. Get sub-categories with Wikiapi.KEY_subcategories.

##### Examples

Checking if [[Category:Countries in North America]] including [[Mexico]].

    // <code>
    const enwiki = new Wikiapi('en');
    const page_list = await enwiki.category_tree('Countries in North America', 1);
    assert(page_list.some(page_data => page_data.title === 'United States'), 'list category tree: [[Category:Countries in North America]] must includes [[United States]]');
    assert('Mexico' in page_list[Wikiapi.KEY_subcategories], 'list category tree: [[Category:Mexico]] is a subcategory of [[Category:Countries in North America]]');
    // </code>

Get all sub-categories of [[Category:Echinodermata]] with depth=2.

    // <code>
    const wiki = new Wikiapi('commons');
    const all_sub_categories = (await wiki.category_tree('Echinodermata', { depth: 2, cmtype: 'subcat', get_flated_subcategories: true })).flated_subcategories;
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`root_category` | String |  | category name
`options` | Object | <optional> | options to run this function.

##### Returns:

Promise object represents {Array} category_tree.

Type
  Promise

#### convert_Chinese(text, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1607

convert text to traditional Chinese / simplified Chinese.

##### Example

繁簡轉換

    // <code>
    const wiki = new Wikiapi('en');
    await wiki.convert_Chinese('中国', { uselang: 'zh-hant' });
    await wiki.convert_Chinese('中國', { uselang: 'zh-hans' });
    await wiki.convert_Chinese(['繁體', '簡體'], { uselang: 'zh-hans' });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`text` | String | Array | Object |  | text or objects to convert. Will convert to {String} using JSON.stringify().
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents the converted text.

Type
  Promise

#### data(data_entity, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 832

Get wikidata entity / property

##### Examples

Get wikidata entity method 1

    // <code>
    const wiki = new Wikiapi;
    const data_entity = await wiki.data('Q1');
    // Work with other language
    console.assert(CeL.wiki.data.value_of(data_entity.labels.zh) === '宇宙');
    // </code>

Get wikidata entity of [[Human]]

    // <code>
    const wiki = new Wikiapi;
    const page_data = await wiki.page('Human');
    const data_entity = await wiki.data(page_data);
    console.assert(CeL.wiki.data.value_of(data_entity.labels.zh) === '人類');
    // </code>

Get wikidata entity method 2: Get P1419 of wikidata entity: 'Universe'

    // <code>
    const wiki = new Wikiapi;
    // Read, access by title (English), access property P1419
    let data = await wiki.data('Universe', 'P1419');
    // assert: {Array}data = [ 'shape of the universe', '', ... ]
    console.assert(data.includes('shape of the universe'));
    // </code>

update wikidata

    // <code>
    // Just for test
    delete CeL.wiki.query.default_maxlag;
    const wiki = new Wikiapi;
    await wiki.login('user', 'password', 'test');

    // Get https://test.wikidata.org/wiki/Q7
    let entity = await wiki.data('Q7');
    // search [ language, label ]
    //entity = await wiki.data(['en', 'Earth']);

    // Update claim
    await entity.modify({ claims: [{ P17: 'Q213280' }] }, { bot: 1, summary: '' });
    // Update claim: set country (P17) to 'Test Country 1' (Q213280) ([language, label] as entity)
    await entity.modify({ claims: [{ language: 'en', country: [, 'Test Country 1'] }] }, { summary: '' });
    // Remove country (P17) : 'Test Country 1' (Q213280)
    await entity.modify({ claims: [{ language: 'en', country: [, 'Test Country 1'], remove: true }] }, { summary: '' });

    // Update label
    await entity.modify({ labels: [{ language: 'zh-tw', value: '地球' }] }, { summary: '' });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`data_entity` | Object |  | wiki_API data entity
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} wikidata entity / property

Type
  Promise

#### download(file_title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1466

Download file to local path.

##### Examples

Download original file / media to current directory.

    // <code>
    const wiki = new Wikiapi('commons');
    await wiki.download('File:Example.svg');
    // </code>

Download file / media with options

    // <code>
    const wiki = new Wikiapi('commons');

    // Download non-vector version of .svg
    await wiki.download('File:Example.svg', { width: 80 });

    // Change width / height
    await wiki.download('File:Example.png', {
    	file_name: 'example.png', directory: '/tmp/',
    	// reget and overwrite existed file.
    	reget: true,
    	width: 80,// height: 80
    });

    // Download all files from a (Commons) category and its subcategories WITH directory structure.
    const file_data_list = await wiki.download('Category:name', {
    	directory: './',
    	max_threads: 4,
    	// depth of categories
    	depth: 4,
    	// Only download files with these formats.
    	//download_derivatives : ['wav', 'mp3', 'ogg'],
    	// Warning: Will skip downloading if there is no new file!
    	download_derivatives : 'mp3',
    	// A function to filter result pages. Return `true` if you want to keep the element.
    	page_filter(page_data) {
    		return page_data.title.includes('word');
    	}
    });

    // Download all files from a (Commons) category WITHOUT directory structure.
    for (const page_data of await wiki.categorymembers('Category:name', { namespace: 'File' })) {
    	try {
    		//if (wiki.is_namespace(page_data, 'File'))
    		const file_data = await wiki.download(page_data, { directory: './' });
    	} catch (e) { console.error(e); }
    }
    // also
    const categorymembers = await wiki.categorymembers('Category:name', { namespace: 'File' });
    const file_data_list = await wiki.download(categorymembers, { directory: './', no_category_tree: true });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`file_title` | String |  | file title starts with "File:"
`options` | Object | <optional> | options to run this function. Refer to example codes.

##### Returns:

Promise object represents [ {Object}file informations ]

Type
  Promise

#### edit(content, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1792

edits content of target page.
MUST using after Wikiapi#page!
Note: for multiple pages, you should use Wikiapi#for_each_page.
Note: The function will check sections of [[User talk:user name/Stop]] if somebody tells us needed to stop edit. See mechanism to stop operations.

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`content` | String | function |  | 'wikitext page content' || page_data => 'wikitext'
`options` | Object | <optional> | options to run this function. e.g., { summary: '', bot: 1, nocreate: 1, minor: 1 }

##### Returns:

Promise object represents {Object} result of MediaWiki API

Type
  Promise

#### edit_page(title, content, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 465

edits content of target page.
Note: for multiple pages, you should use Wikiapi#for_each_page.
Note: The function will check sections of [[User talk:user name/Stop]] if somebody tells us needed to stop edit. See mechanism to stop operations.

##### Examples

edit page: method 1: basic operation

    // <code>
    const enwiki = new Wikiapi;
    await enwiki.login('bot name', 'password', 'en');

    const SB_page_data = await enwiki.page('Wikipedia:Sandbox');
    // You may do some operations on SB_page_data
    const parsed = SB_page_data.parse();
    parsed.each('template', template_token => {
    	// modify template token
    });
    // and then edit it. ** You MUST call enwiki.page() before enwiki.edit()! **
    await enwiki.edit(parsed.toString(), { bot: 1, minor: 1, nocreate: 1 });

    // exmaple 2: append text in the tail of page content
    await enwiki.edit(page_data => {
    	return page_data.wikitext
    		+ '\nTest edit using {{GitHub|kanasimi/wikiapi}}.';
    }, { bot: 1 });

    // exmaple 3: replace page content
    await enwiki.edit('Just replace by this wikitext', { bot: 1, minor: 1, nocreate: 1, summary: 'test edit' });

    // exmaple 4: append a new section
    await enwiki.edit('section content', {
    	section: 'new',
    	sectiontitle: 'section title',
    	nocreate : 1,
    	summary: 'test edit',
    });
    // </code>

edit page: method 2: modufy summary inside function

    // <code>
    const enwiki = new Wikiapi;
    await enwiki.login('bot name', 'password', 'en');
    await enwiki.edit_page('Wikipedia:Sandbox', function (page_data) {
    	this.summary += ': You may set additional summary inside the function';
    	delete this.minor;
    	return page_data.wikitext
    		+ '\nTest edit using {{GitHub|kanasimi/wikiapi}}.';
    }, { bot: 1, nocreate: 1, minor: 1, redirects: 1, summary: 'test edit' });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | String |  | page title
`content` | String | function |  | 'wikitext page content' || page_data => 'wikitext'
`options` | Object | <optional> | options to run this function. e.g., { summary: '', bot: 1, nocreate: 1, minor: 1 }

##### Returns:

Promise object represents {Object} result of MediaWiki API

Type
  Promise

#### for_each_page(page_list, for_each_page, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1535

Edit / process pages listing in `page_list`. Will get the content of multiple pages at once to save transmission times. 一次取得多個頁面內容，以節省傳輸次數。

##### Example

read / edit multiple pages

    // <code>
    const enwiki = new Wikiapi('en');
    const link_from = await wiki.redirects_here('ABC');
    await wiki.for_each_page(link_from, page_data => {
    	// Return `Wikiapi.skip_edit` if you just want to get the page data.
    	return Wikiapi.skip_edit;
    	return 'You may also modify page contents for each page';
    }, {
    	// The options below are sample, not default configuration.

    	// denotes we do not edit pages
    	no_edit: true,

    	// Only needed if you want to modify page.
    	summary: 'test edit',
    	// Allow content to be emptied. 允許內容被清空。白紙化。
    	allow_empty: true,
    	tags: 'bot trial',
    	// prevent creating new pages
    	// Throw an error if the page doesn't exist.
    	// 若頁面不存在/已刪除，則產生錯誤。
    	nocreate: 1,
    	// denotes this is a bot edit. 標記此編輯為機器人編輯。
    	bot: 1,
    	minor: 1,

    	// options to get page revisions
    	page_options: { redirects: 1, rvprop: 'ids|content|timestamp|user' }

    	// <code>.for_each_page()</code> will generate a report. It can be written to the specified page.
    	log_to: 'log to this page',
    	// no warning messages on console. e.g., hide "wiki_API_page: No contents: [[title]]" messages
    	no_warning: true,
    	// no warning messages and debug messages on console
    	no_message: true,
    });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`page_list` | Array |  | title list or page_data list
`for_each_page` | function |  | processor for each page. for_each_page(page_data with contents)
`options` | Object | <optional> | options to run this function. Refer to example codes.

##### Returns:

Promise object represents the operations are done.

Type
  Promise

#### get_featured_content(optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1700

Get featured content.

##### Example

Get featured content of current wiki site.

    // <code>
    // MUST including wiki.featured_content first to get featured content!
    CeL.run('application.net.wiki.featured_content');

    // ...

    const FC_data_hash = await wiki.get_featured_content();
    console.assert(FC_data_hash === wiki.FC_data_hash);
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`options` | String | Object | <optional> | options to run this function. {String}type (FFA|GA|FA|FL) || {type,on_conflict(FC_title, {from,to})}

##### Returns:

Promise object represents {Object} featured content data hash

Type
  Promise

#### listen(listener, optionsopt)

Source:
  - wikiapi.js, line 1825

Listen to page modification. 監視最近更改的頁面。
wrapper for wiki_API#listen

##### Example

listen to new edits

    // <code>
    const wiki = new Wikiapi;
    wiki.listen(function for_each_row() {
    	// ...
    }, {
    	// 檢查的延遲時間。
    	delay: '2m',
    	filter: function filter_row(row) {
    		// row is the same format as page_data
    	},
    	// also get diff
    	with_diff: { LCS: true, line: true },
    	// only for articles (0:main namespace) and talk pages
    	namespace: '0|talk',
    });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`listener` | function |  | function(page_data) { return quit_listening; }
`options` | Object | <optional> | options to run this function. e.g., { summary: '', bot: 1, nocreate: 1, minor: 1 }

#### login(user_name, password, API_URLopt) → {Promise}

Source:
  - wikiapi.js, line 146

login into the target MediaWiki API using the provided username and password. For bots, see [[Special:BotPasswords]] on your wiki.

##### Examples

Login to wiki site method 1.

    // <code>
    const wiki = new Wikiapi;
    const login_options = {
    	user_name: '', password: '', API_URL: 'en',
    	// Ror lingualibre only. @see https://github.com/kanasimi/wikibot/blob/master/wiki%20configuration.sample.js
    	//data_API_URL: 'https://lingualibre.org/api.php',
    	//SPARQL_API_URL: 'https://lingualibre.org/bigdata/namespace/wdq/sparql',
    	// Calling in another domain
    	origin: '*'
    };
    await wiki.login(login_options);
    // </code>

Login to wiki site method 2.

    // <code>
    const wiki = new Wikiapi;
    await wiki.login('user_name', 'password', 'en');
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`user_name` | String |  | Account username.
`password` | String |  | Account's password.
`API_URL` | String | <optional> | API URL of target wiki site.

##### Returns:

Promise object represents {String} login_name

Type
  Promise

#### move_page(move_from_title, move_to_title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 546

Move page `move_from_title` to `move_to_title`.

##### Example

Move `move_from_title` to `move_to_title`.

    // <code>
    await wiki.move_page(move_from_title, move_to_title, { reason, noredirect: true, movetalk: true });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`move_from_title` | Object | String |  | move from title
`move_to_title` | Object | String |  | move to title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {String} result of MediaWiki API

Type
  Promise

#### move_to(move_to_title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 595

Move to `move_to_title`. Must call Wikiapi#page first!

##### Example

Move `move_from_title` to `move_to_title`.

    // <code>
    page_data = await wiki.page(move_from_title);
    await wiki.move_to(move_to_title, { reason: reason, noredirect: true, movetalk: true });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`move_to_title` | Object | String |  | move to title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {String} result of MediaWiki API

Type
  Promise

#### new_data_entity(data_to_modify, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 881

Create new entity or property

##### Example

Create new entity

    // <code>
    const new_entity = await wiki.new_data_entity({ labels: { en: "Evolution in Mendelian Populations" }, P698: "17246615", P932: "1201091" }, { new: 'item' });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`data_to_modify` | Object |  | Initial data.
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} new entity or property.

Type
  Promise

#### page(title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 318

given a title, returns the page's data.

##### Examples

load page

    // <code>
    // on Wikipedia...
    const wiki = new Wikiapi('en');
    // ...or other MediaWiki websites
    //const wiki = new Wikiapi('https://awoiaf.westeros.org/api.php');
    let page_data = await wiki.page('Universe', {
    	// You may also set rvprop.
    	//rvprop: 'ids|content|timestamp|user',
    });
    console.log(page_data.wikitext);
    // </code>

Get multi revisions

    // <code>
    const wiki = new Wikiapi;
    let page_data = await wiki.page('Universe', {
    	// Get multi revisions
    	revisions: 2
    });
    console.log(page_data.wikitext);
    // </code>

parse wiki page (The parser is more powerful than the example. Please refer to link of wikitext parser examples showing in "Features" section of README.md.)

    // <code>
    // Usage with other language
    const zhwiki = new Wikiapi('zh');
    await zhwiki.login('user', 'password');
    let page_data = await zhwiki.page('Universe');

    // `page_data.parse(options)` will startup the parser process, create page_data.parsed. After .parse(), we can use parsed.each().
    const parsed = page_data.parse();

    // See all type in wiki_toString @ https://github.com/kanasimi/CeJS/tree/master/application/net/wiki/parser/wikitext.js
    // List all template name.
    parsed.each('template', token => console.log(token.name));
    // List all [[Template:Tl]] token.
    parsed.each('Template:Tl', token => console.log(token));
    // </code>

Get information from Infobox template

    // <code>
    const wiki = new Wikiapi('en');
    const page_data = await wiki.page('JavaScript');
    const parsed = page_data.parse();
    let infobox;
    // Read Infobox templates, convert to JSON.
    parsed.each('template', template_token => {
    	if (template_token.name.startsWith('Infobox')) {
    		infobox = template_token.parameters;
    		return parsed.each.exit;
    	}
    });
    for (const [key, value] of Object.entries(infobox))
    	infobox[key] = value.toString();
    // print json of the infobox
    console.log(infobox);
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | String |  | page title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} page's data

Type
  Promise

#### purge(title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 694

Purge the cache for the given title.

##### Example

query flow-parsoid-utils

    // <code>
    const metawiki = new Wikiapi('meta');
    let page_data = await metawiki.purge('Project:Sandbox');
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | Object |  | page title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} page_data

Type
  Promise

#### query(parameters, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 657

query MediaWiki API manually

##### Example

query flow-parsoid-utils

    // <code>
    const wiki = new Wikiapi('mediawiki');
    const results = await wiki.query({
    	action: "flow-parsoid-utils",
    	content: "<b>bold</b> &amp; <i>italic</i>",
    	title: "MediaWiki", from: "html", to: "wikitext"
    });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`parameters` | Object |  | parameters to call MediaWiki API
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} result of MediaWiki API

Type
  Promise

#### redirects_here(title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1206

Get all pages redirects to `title`.

##### Example

Get all pages redirects to [[Wikipedia:Sandbox]]

    // <code>
    const redirects_list = await enwiki.redirects_here('Wikipedia:Sandbox');
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | String |  | page title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Array} redirect_list

Type
  Promise

#### redirects_root(title, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1169

Get redirects target of `title`.

##### Example

Get redirects target of [[WP:SB]]

    // <code>
    const redirects_taregt = await enwiki.redirects_root('WP:SB', { get_page_data: true });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | String |  | page title
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {String} page title or {Object} page data

Type
  Promise

#### register_redirects(page_title_list, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1280

register page alias. usually used for templates

##### Example

Register template redirects and get tokens of the templates.

    // <code>
    const wiki_session = new Wikiapi;
    // e.g., await wiki_session.register_redirects(['Section link', 'Broken anchors'], { namespace: 'Template' });
    await wiki_session.register_redirects([template_name_1, template_name_2, template_name_3], { namespace: 'Template' });

    // ...

    const page_data = await wiki_session.page(page_title);
    // {Array} parsed page content 頁面解析後的結構。
    const parsed = page_data.parse();

    parsed.each('Template:' + template_name_1, function (token, index, parent) {
    	// ...
    });

    parsed.each('template', function (token, index, parent) {
    	if (wiki_session.is_template(template_name_1, token)) {
    		// ...
    		return;
    	}
    	if (wiki_session.is_template(template_name_2, token)) {
    		// ...
    		return;
    	}

    	// alternative method:
    	switch (wiki_session.redirect_target_of(token)) {
    		case wiki_session.redirect_target_of(template_name_1):
    			break;
    		case wiki_session.redirect_target_of(template_name_2):
    			break;
    		case wiki_session.redirect_target_of(template_name_3):
    			break;
    	}
    });
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`page_title_list` | Array | String |  | list of page titles
`options` | Object | <optional> | options to run this function.

##### Returns:

Promise object represents the operations are done.

Type
  Promise

#### search(key, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 1135

search pages include `key`

##### Example

search pages include key: 霍金

    // <code>
    const zhwikinews = new Wikiapi('zh.wikinews');
    const page_list = await zhwikinews.search('"霍金"');
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`key` | String |  | key to search
`options` | Object | <optional> | options to run this function.

##### Returns:

Promise object represents {Array} page_list.

Type
  Promise

#### site_name(languageopt, optionsopt) → {String}

Source:
  - wikiapi.js, line 1754

Get site name / project name of this {Wikiapi}.

##### Example

Get site name of {Wikiapi}.

    // <code>
    console.log(Wikiapi.site_name('zh', { get_all_properties: true }));

    const wiki = new Wikiapi('en');
    console.assert(wiki.site_name() === 'enwiki');
    console.log(wiki.site_name({ get_all_properties: true }));
    console.assert(wiki.site_name({ get_all_properties: true }).language === 'en');
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`language` | String | <optional> | language code of wiki session
`options` | Object | <optional> | options to run this function

##### Returns:

site name

Type
  String

#### SPARQL(SPARQL, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 957

Query wikidata via SPARQL

##### Examples

Get cats

    // <code>
    const wikidata_item_list = await wiki.SPARQL(`
    SELECT ?item ?itemLabel WHERE {
      ?item wdt:P31 wd:Q146.
      SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". }
    }
    `);
    // </code>

Get specific DOI

    // <code>
    // for case-insensitive DOI
    const wikidata_item_list = await wiki.search('haswbstatement:' + JSON.stringify('P356=10.1371/journal.pone.0029797'), { namespace: 0 });
    //wikidata_item_list.map(item => item.title)

    // for case-sensitive DOI
    const wikidata_item_list = await wiki.SPARQL(`
    SELECT ?doi ?item ?itemLabel WHERE {
    	VALUES ?doi { "10.1371/JOURNAL.PONE.0029797" }
    	?item wdt:P356 ?doi.
    	SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
    }`, {
    	// options.API_URL: custom SPARQL endpoint
    	API_URL: ''
    });
    //wikidata_item_list.id_list()
    // </code>

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`SPARQL` | Object |  | SPARQL to query. Please test it on Wikidata Query Service first.
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Array} query result of `SPARQL`.

Type
  Promise

#### tracking_revisions(title, to_search, optionsopt) → {Promise}

Source:
  - wikiapi.js, line 352

tracking revisions to lookup what revision had added / removed `to_search`.

##### Parameters:

Name | Type | Attributes | Description
--- | --- | --- | ---
`title` | String |  | page title
`to_search` | String |  | filter / text to search. to_search(diff, revision, old_revision): `diff` 為從舊的版本 `old_revision` 改成 `revision` 時的差異。
`options` | Object | <optional> | options to run this function

##### Returns:

Promise object represents {Object} newer_revision, newer_revision.page: page_data

Type
  Promise

#### upload(file_data) → {Promise}

Source:
  - wikiapi.js, line 1387

Upload specified local file to the target wiki.

##### Examples

Upload file / media

    // <code>
    const wiki = new Wikiapi;
    await wiki.login('user', 'password', 'test');
    // Upload a local file directly:
    //let result = await wiki.upload({ file_path: '/local/file/path', comment: '', text: '' || {description: '', ...} });
    let result = await wiki.upload({
    	file_path: '/local/file/path', comment: '',
    	filename: 'Will set via .file_path or .media_url if not settled.',
    	description: '', date: new Date() || '2021-01-01', source_url: 'https://github.com/kanasimi/wikiapi', author: '[[User:user]]', permission: '{{cc-by-sa-2.5}}', other_versions: '', other_fields: '',
    	license: ['{{cc-by-sa-2.5}}'], categories: ['[[Category:test images]]'],
    	bot: 1, tags: "tag1|tag2",
    	// To overwrite existing file
    	ignorewarnings: 1,
    });
    // Upload file from URL:
    result = await wiki.upload({ media_url: 'https://media.url/name.jpg', comment: '', text: '' });
    // </code>

Upload file and then update content of file page

    // <code>
    const wiki = new Wikiapi;
    await wiki.login('user', 'password', 'test');

    const variable_Map = new CeL.wiki.Variable_Map();
    variable_Map.set('description', '...');
    //variable_Map.set('date', '...');
    // ...
    //variable_Map.set('other_fields', '...');

    let result = await wiki.upload({
    	file_path: '/local/file/path',
    	// The <code>comment</code> will only show in the file page when updating file. It is read-only and cannot be modified.
    	comment: '',

    	// <code>CeL.wiki.Variable_Map</code> is used to update content when update pages or files. It will insert comments around the value, prevent others from accidentally editing the text that will be overwritten.
    	// <code>description</code> till <code>other_fields</code> will be auto-setted as values assigned above.
    	// The code to do the conversion is in <code>wiki_API.upload</code> @ https://github.com/kanasimi/CeJS/blob/master/application/net/wiki/edit.js
    	// There are some examples: https://github.com/kanasimi/wikibot/blob/master/routine/20181016.import_earthquake_shakemap.js https://github.com/kanasimi/wikibot/blob/master/routine/20190629.import_hurricane_track_maps.js
    	// More examples to use <code>CeL.wiki.Variable_Map</code>: https://github.com/kanasimi/wikibot/blob/master/routine/20191129.check_language_convention.js
    	variable_Map,
    	// When set .variable_Map, after successful update, the content of file page will be auto-updated too.

    	// To overwrite existing file
    	ignorewarnings: 1,
    });
    // </code>

##### Parameters:

Name | Type | Description
--- | --- | ---

`file_data`

Object

Upload configurations.
Warning: When you are update a file, only the file content will changed. The `comment` will only show in the file page. The `text`, ... till `categories` will all ignored. If you want to update the content of file page, please consider `Variable_Map` as mentioned in the sample code.
{

- `file_path`: string - Local path.
- `media_url`: string - URL path. Alternative to `file_path`.
- `comment`: string - Upload comment.
- `text`: string or {Object} - Either {String}wikitext to fill the file's page,
  or {Object}parameters of {{Information}}:
  {
  - `description`: string - File description.
  - `date`: date string - YYYY-MM-DD, e.g., `new Date()` || `'2021-01-01'`.
  - `source_url`: string - Source where the file comes from, typically an URL.
  - `author`: string - Author's name or username in wikicode, e.g., URL or `'[[User:Yoda|Yoda]]'`.
  - `permission`: string - License and other usage limitations and warnings, e.g., `'{{cc-by-sa-2.5}}'`.
  - `other_versions`: string - Wikicode links to files with very similar content or derived files.
  - `other_fields`: string - Additional table fields added on the bottom of the template.
  }
- `license`: array of strings - License under which the file is uploaded, e.g., `['{{cc-by-sa-2.5}}']`.
- `additional_text`: string - Additional wikitext to place before `categories`.
- `categories`: array of strings - Categories for this file, e.g., `['[[Category:test images]]']`.
- `ignorewarnings`: boolean - Set to 1 will overwrite existing files.

}
See edit.js and search for file_data for other `file_data` options.

##### Returns:

Promise object represents {String} result of MediaWiki API

Type
  Promise