Comparing version 1.7.0 to 1.8.0
@@ -41,3 +41,3 @@ 'use strict'; | ||
if (all_error_count === 0) { | ||
CeL.info('check_tests: All ' + all_tests + ' test groups done.' + elapsed_message); | ||
CeL.info(`check_tests: All ${all_tests} test groups done.${elapsed_message}`); | ||
// normal done. No error. | ||
@@ -108,10 +108,12 @@ return; | ||
function handle_edit_error(assert, result) { | ||
function handle_edit_error(assert, error) { | ||
const result = error.result; | ||
if (edit_blocked(result)) { | ||
// IP is blocked. | ||
CeL.log('Skip blocked edit: ' + result.message); | ||
CeL.log(`Skip blocked edit: ${result.message}`); | ||
return; | ||
} | ||
assert([result.message, 'OK'], 'test edit page result'); | ||
assert(error.message === '[blocked] You have been blocked from editing.' | ||
|| error.message === 'OK', 'test edit page result'); | ||
} | ||
@@ -145,5 +147,5 @@ | ||
assert(page_data.wikitext.endsWith(test_wikitext), 'test edit page result'); | ||
} catch (result) { | ||
} catch (error) { | ||
// failed to edit | ||
handle_edit_error(assert, result); | ||
handle_edit_error(assert, error); | ||
} | ||
@@ -239,8 +241,8 @@ // CeL.set_debug(0); | ||
assert([result.from, move_from_title], 'move page from: [[testwiki:' + move_from_title + ']]'); | ||
assert([result.to, move_to_title], 'move page to: [[testwiki:' + move_to_title + ']]'); | ||
assert([result.from, move_from_title], `move page from: [[testwiki:${move_from_title}]]`); | ||
assert([result.to, move_to_title], `move page to: [[testwiki:${move_to_title}]]`); | ||
} catch (e) { | ||
if (e.code !== 'missingtitle' && e.code !== 'articleexists') { | ||
if (e.code) { | ||
CeL.error('[' + e.code + '] ' + e.info); | ||
CeL.error(`[${e.code}] ${e.info}`); | ||
} else { | ||
@@ -252,3 +254,3 @@ console.trace(e); | ||
|| e.code && e.code !== 'missingtitle' && e.code !== 'articleexists', | ||
'move page from: [[testwiki:' + move_from_title + ']]'); | ||
`move page from: [[testwiki:${move_from_title}]]`); | ||
} | ||
@@ -277,5 +279,5 @@ | ||
// You may also using: | ||
//page_data = await testwiki.purge(/* no options */); | ||
// page_data = await testwiki.purge(/* no options */); | ||
//console.log(page_data); | ||
// console.log(page_data); | ||
assert(Array.isArray(page_data) && page_data.length === 1, 'purge page: [[meta:Meta:Babel]]: multi return {Array}'); | ||
@@ -297,4 +299,4 @@ page_data = page_data[0]; | ||
}); | ||
//CeL.info('page:'); | ||
//console.log(page); | ||
// CeL.info('page:'); | ||
// console.log(page); | ||
@@ -350,4 +352,4 @@ // Work with other language | ||
const to_exit = parsed.each.exit; | ||
//console.log(page_data.revisions[0].slots.main['*']); | ||
//console.log(parsed); | ||
// console.log(page_data.revisions[0].slots.main['*']); | ||
// console.log(parsed); | ||
parsed.each('category', (token) => { | ||
@@ -360,4 +362,4 @@ if (token.name === 'Wikimedia Cloud Services') { | ||
}); | ||
//console.log(page_list_proto); | ||
//console.log([page_list_proto.length, has_category_count]); | ||
// console.log(page_list_proto); | ||
// console.log([page_list_proto.length, has_category_count]); | ||
@@ -376,3 +378,3 @@ assert([page_list_proto.length, has_category_count], 'Count of [[w:en:Category:Wikimedia Cloud Services]] using for_each'); | ||
const parsed = page_data.parse(); | ||
//console.log(parsed); | ||
// console.log(parsed); | ||
assert([page_data.wikitext, parsed.toString()], 'wikitext parser check'); | ||
@@ -388,6 +390,4 @@ let has_category; | ||
} | ||
}, { | ||
no_edit: true | ||
}); | ||
//console.log([page_list.length, has_category_count]); | ||
// console.log([page_list.length, has_category_count]); | ||
@@ -400,2 +400,14 @@ assert([page_list.length, has_category_count], 'Count of [[w:en:Category:Wikimedia Cloud Services]] using for_each_page'); | ||
add_test('list category tree', async (assert, setup_test, finish_test) => { | ||
setup_test('list category tree: Countries in North America'); | ||
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.subcategories, 'list category tree: [[Category:Mexico]] is a subcategory of [[Category:Countries in North America]]'); | ||
finish_test('list category tree: Countries in North America'); | ||
}); | ||
// ------------------------------------------------------------------ | ||
add_test('search key', async (assert, setup_test, finish_test) => { | ||
@@ -402,0 +414,0 @@ setup_test('search key: 霍金'); |
{ | ||
"name": "wikiapi", | ||
"title": "JavaScript MediaWiki API for node.js", | ||
"version": "1.7.0", | ||
"version": "1.8.0", | ||
"description": "A simple way to access MediaWiki API via JavaScript with simple wikitext parser.", | ||
@@ -6,0 +6,0 @@ "keywords": [ "MediaWiki", "MediaWiki API", "wikitext", "ECMAScript 2017", "wikidata", "wdq", "sparql" ], |
@@ -13,3 +13,3 @@ [![npm version](https://badge.fury.io/js/wikiapi.svg)](https://www.npmjs.com/package/wikiapi) | ||
A simple way to access MediaWiki API via JavaScript with simple wikitext parser. | ||
This is basically a modern syntax version of [MediaWiki module](https://github.com/kanasimi/CeJS/blob/master/application/net/wiki). For example, using [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). | ||
This is basically a modern syntax version of [CeJS MediaWiki module](https://github.com/kanasimi/CeJS/blob/master/application/net/wiki). For example, using [async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function). | ||
@@ -16,0 +16,0 @@ ## Features |
167
wikiapi.js
@@ -8,3 +8,3 @@ 'use strict'; | ||
CeL = require('cejs'); | ||
} catch (e) /* istanbul ignore next: only for debugging locally */ { | ||
} catch (e) /* istanbul ignore next: Only for debugging locally */ { | ||
// https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md | ||
@@ -18,3 +18,4 @@ // const wikiapi = require('./wikiapi.js'); | ||
// Load modules. | ||
// @see `wiki loader.js`: https://github.com/kanasimi/wikibot/blob/master/wiki%20loader.js | ||
// @see `wiki loader.js`: | ||
// https://github.com/kanasimi/wikibot/blob/master/wiki%20loader.js | ||
CeL.run(['interact.DOM', 'application.debug', | ||
@@ -44,3 +45,5 @@ // 載入不同地區語言的功能 for wiki.work()。 | ||
* main wikiapi operator 操作子. | ||
* @param {String}[API_URL] language code or API URL of MediaWiki project | ||
* | ||
* @param {String}[API_URL] | ||
* language code or API URL of MediaWiki project | ||
*/ | ||
@@ -95,7 +98,8 @@ function wikiapi(API_URL) { | ||
const wiki = this[KEY_wiki]; | ||
wiki.page(title, function callback(page_data, error) { | ||
wiki.page(title, (page_data, error) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
Object.defineProperties(page_data, page_data_attributes); | ||
if (page_data) | ||
Object.defineProperties(page_data, page_data_attributes); | ||
resolve(page_data); | ||
@@ -114,2 +118,3 @@ } | ||
// for page list, you had better use wiki.for_each_page(page_list) | ||
function wikiapi_edit_page(title, content, options) { | ||
@@ -122,6 +127,12 @@ function wikiapi_edit_page_executor(resolve, reject) { | ||
// wiki.edit(page contents, options, callback) | ||
wiki.edit(content, options, function callback(title, error, result) { | ||
if (error) { | ||
result.message = error; | ||
reject(result); | ||
wiki.edit(content, options, (title, error, result) => { | ||
// skip_edit is not error | ||
if (error && error !== /* 'skip' */ wikiapi.skip_edit[1]) { | ||
if (typeof error === 'string') { | ||
error = new Error(error); | ||
error.from_string = true; | ||
} | ||
if (typeof error === 'object') | ||
error.result = result; | ||
reject(error); | ||
} else { | ||
@@ -136,3 +147,4 @@ resolve(title); | ||
// return Wikiapi.skip_edit as a symbol to skip this edit, do not generate warning message. | ||
// `return Wikiapi.skip_edit;` as a symbol to skip this edit, do not generate | ||
// warning message. | ||
// 可以利用 ((return [ CeL.wiki.edit.cancel, 'reason' ];)) 來回傳 reason。 | ||
@@ -153,3 +165,3 @@ // ((return [ CeL.wiki.edit.cancel, 'skip' ];)) 來跳過 (skip) 本次編輯動作,不特別顯示或處理。 | ||
* </code> | ||
* </code> | ||
* | ||
@@ -160,10 +172,5 @@ * @param {Object|String}[move_to_title] | ||
function wikiapi_move_to(move_to_title, options) { | ||
if (!options || !options.reason) { | ||
/* istanbul ignore next: warning message */ | ||
CeL.warn('wikiapi_move_to: Should set reason when moving page!'); | ||
} | ||
function wikiapi_move_to_executor(resolve, reject) { | ||
const wiki = this[KEY_wiki]; | ||
if (!wiki.last_page) /* istanbul ignore next: error exit */ { | ||
if (!wiki.last_page) { | ||
reject(new Error('wikiapi_move_to: Must call .page() first!' | ||
@@ -174,9 +181,21 @@ + ' Can not move to ' + CeL.wiki.title_link_of(move_to_title))); | ||
// using wiki_API.move_to | ||
wiki.move_to(move_to_title, options, function callback(data, error) { | ||
wiki.move_to(move_to_title, options, (data, error) => { | ||
if (error) { | ||
// e.g., { code: 'articleexists', info: 'A page of that name already exists, or the name you have chosen is not valid. Please choose another name.', '*': '...' } | ||
// e.g., { code: 'missingtitle', info: "The page you specified doesn't exist.", '*': '...' } | ||
/** | ||
* <code> | ||
e.g., { code: 'articleexists', info: 'A page of that name already exists, or the name you have chosen is not valid. Please choose another name.', '*': '...' } | ||
e.g., { code: 'missingtitle', info: "The page you specified doesn't exist.", '*': '...' } | ||
</code> | ||
*/ | ||
reject(error); | ||
} else { | ||
// e.g., { from: 'from', to: 'to', reason: 'move', redirectcreated: '' } | ||
/** | ||
* <code> | ||
e.g., { from: 'from', to: 'to', reason: 'move', redirectcreated: '' } | ||
</code> | ||
*/ | ||
resolve(data); | ||
@@ -204,3 +223,3 @@ } | ||
// using wiki_API.purge | ||
wiki.purge(function callback(data, error) { | ||
wiki.purge((data, error) => { | ||
if (error) { | ||
@@ -228,3 +247,3 @@ reject(error); | ||
// using wikidata_entity() → wikidata_datavalue() | ||
wiki.data(key, property, function callback(data, error) { | ||
wiki.data(key, property, (data, error) => { | ||
if (error) { | ||
@@ -248,3 +267,3 @@ reject(error); | ||
CeL.wiki.list(title, (list/* , target, options */) => { | ||
//console.trace(list); | ||
// console.trace(list); | ||
if (list.error) { | ||
@@ -259,7 +278,8 @@ reject(list.error); | ||
type: list_type, | ||
//namespace: '0|1', | ||
// namespace: '0|1', | ||
...options | ||
}); | ||
/** <code> | ||
/** | ||
* <code> | ||
@@ -284,3 +304,3 @@ // method 2: 使用循環取得資料版: | ||
// NG: 不應使用單次版 | ||
wiki[list_type](title, function callback(list, error) { | ||
wiki[list_type](title, (list, error) => { | ||
if (error) { | ||
@@ -295,3 +315,4 @@ reject(error); | ||
</code> */ | ||
</code> | ||
*/ | ||
} | ||
@@ -302,2 +323,3 @@ | ||
// functions for several kinds of lists | ||
function wikiapi_for_each(type, title, for_each, options) { | ||
@@ -312,2 +334,25 @@ return wikiapi_list.call(this, type, title, { | ||
function wikiapi_category_tree(root_category, options) { | ||
function wikiapi_category_tree_executor(resolve, reject) { | ||
const wiki = this[KEY_wiki]; | ||
// using CeL.wiki.prototype.category_tree | ||
wiki.category_tree(root_category, (list, error) => { | ||
if (error) { | ||
reject(error); | ||
} else { | ||
resolve(list); | ||
} | ||
}, options); | ||
} | ||
return new Promise(wikiapi_category_tree_executor.bind(this)); | ||
} | ||
// export 子分類 subcategory | ||
wikiapi.KEY_subcategories = wiki_API.KEY_subcategories; | ||
// To use: | ||
//const KEY_subcategories = Wikiapi.KEY_subcategories; | ||
// -------------------------------------------------------- | ||
function wikiapi_search(key, options) { | ||
@@ -317,3 +362,3 @@ function wikiapi_search_executor(resolve, reject) { | ||
// using wiki_API.search | ||
wiki.search(key, function callback(list, error) { | ||
wiki.search(key, (list, error) => { | ||
if (error) { | ||
@@ -333,28 +378,37 @@ reject(error); | ||
/** | ||
* Edit pages list in page_list | ||
* Edit / process pages listing in `page_list`. | ||
* | ||
* @param {Array}page_list | ||
* title list or page_data list | ||
* @param {Function}for_each_page | ||
* @param {Object}[options] e.g., { page_options: { rvprop: 'ids|content|timestamp|user' } } | ||
* processor for each page. for_each_page(page_data with contents) | ||
* @param {Object}[options] | ||
* e.g., { no_message: true, no_warning: true, | ||
* page_options: { redirects: true, rvprop: 'ids|content|timestamp|user' } } | ||
*/ | ||
function wikiapi_for_each_page(page_list, for_each_page, options) { | ||
if (!options || !options.summary && !options.no_edit) { | ||
/* istanbul ignore next: warning message */ | ||
CeL.warn('wikiapi_for_each_page: Did not set options.summary!'); | ||
} | ||
function wikiapi_for_each_page_executor(resolve, reject) { | ||
const wiki = this[KEY_wiki]; | ||
const promises = []; | ||
// 一次取得多個頁面內容,以節省傳輸次數。 | ||
wiki.work({ | ||
//no_edit: true, | ||
log_to: null, | ||
// log_to: null, | ||
// no_edit: true, | ||
no_message: options && options.no_edit, | ||
...options, | ||
each(page_data/* , messages, config*/) { | ||
Object.defineProperties(page_data, page_data_attributes); | ||
each(page_data/* , messages, config */) { | ||
try { | ||
return for_each_page.call(this, page_data | ||
// , messages, config | ||
); | ||
// `page_data` maybe non-object when error occurres. | ||
if (page_data) | ||
Object.defineProperties(page_data, page_data_attributes); | ||
const result = for_each_page.call(this, page_data | ||
/* , messages, config */); | ||
// Promise.isPromise() | ||
if (result && typeof result.then === 'function') { | ||
promises.push(result); | ||
} else { | ||
return result; | ||
} | ||
} catch (e) { | ||
@@ -364,5 +418,5 @@ reject(e); | ||
}, | ||
// Run after all list got. | ||
last() { | ||
// Run after all list got. | ||
resolve(); | ||
Promise.all(promises).then(resolve).catch(reject); | ||
} | ||
@@ -382,3 +436,3 @@ }, page_list); | ||
function run_callback() { | ||
wiki.SQL_session.SQL(SQL, function (error, rows/* , fields */) { | ||
wiki.SQL_session.SQL(SQL, (error, rows/* , fields */) => { | ||
if (error) { | ||
@@ -409,2 +463,3 @@ reject(error); | ||
// -------------------------------------------------------- | ||
// exports | ||
@@ -422,2 +477,3 @@ Object.assign(wikiapi.prototype, { | ||
category_tree: wikiapi_category_tree, | ||
search: wikiapi_search, | ||
@@ -436,5 +492,20 @@ | ||
// Can not use `= (title, options) {}` ! | ||
// arrow function expression DO NOT has this, arguments, super, or new.target keywords. | ||
// arrow function expression DO NOT has this, arguments, super, or | ||
// new.target keywords. | ||
wikiapi.prototype[type] = function (title, options) { | ||
return wikiapi_list.call(this, type, title, options); | ||
var _this = this; | ||
/** | ||
* @example <code> | ||
const page_list = await wiki.embeddedin(template_name, options); | ||
await page_list.each((page_data) => { }, options); | ||
* </code> | ||
*/ | ||
return wikiapi_list.call(this, type, title, options) | ||
.then((page_list) => { | ||
// console.log(page_list); | ||
page_list.each = wikiapi_for_each_page.bind(_this, page_list); | ||
return page_list; | ||
}); | ||
}; | ||
@@ -441,0 +512,0 @@ } |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
33462
755