v1.0 du site web

This commit is contained in:
22107988t
2023-09-25 13:27:24 +02:00
parent 20cb812095
commit a94f68f22a
2787 changed files with 864804 additions and 0 deletions

1
app/node_modules/wikijs/.github/FUNDING.yml generated vendored Normal file
View File

@@ -0,0 +1 @@
custom: https://www.buymeacoffee.com/2tmRKi9

20
app/node_modules/wikijs/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,20 @@
Copyright (c) 2013 Richard van der Dys <http://richardvanderdys.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

143
app/node_modules/wikijs/README.md generated vendored Normal file
View File

@@ -0,0 +1,143 @@
<img height="150" src="img/wikijs.png">
[![NPM Version](https://img.shields.io/npm/v/wikijs.svg)](https://www.npmjs.com/package/wikijs)
[![Build Status](https://travis-ci.org/dijs/wiki.svg)](https://travis-ci.org/dijs/wiki)
[![Coverage Status](https://coveralls.io/repos/dijs/wiki/badge.svg)](https://coveralls.io/r/dijs/wiki)
<a href="https://www.buymeacoffee.com/2tmRKi9" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-yellow.png" alt="Buy Me A Coffee" height="41" width="174"></a>
WikiJs is a node.js library which serves as an interface to Wikipedia (or any MediaWiki).
## What can it do?
- Search wiki articles
- Fetch article content
- Find all links/images/categories in a article page
- Get parsed information about articles
- Find articles by geographical location
- and much more!
## Documentation
<https://dijs.github.io/wiki>
## Install
```bash
npm install wikijs
```
## Usage
```javascript
import wiki from 'wikijs';
// const wiki = require('wikijs').default;
wiki()
.page('Batman')
.then(page => page.info('alterEgo'))
.then(console.log); // Bruce Wayne
```
## Build yourself
You can run these commands in order to build and test WikiJs:
```bash
git clone git@github.com:dijs/wiki.git
cd wiki
npm install
npm run build
npm test
```
## Usage with webpack
In order for webpack to build wikijs properly, you must add an option to
your webpack configuration file. [Documentation](https://webpack.js.org/configuration/externals/#externals)
```json
externals: {
"isomorphic-fetch": "fetch"
}
```
## Usage with other MediaWiki's
You can use the API options configuration:
```js
wiki({
apiUrl: 'https://awoiaf.westeros.org/api.php',
origin: null
}).search('Winterfell');
```
## Usage with other languages
You just need to change the API to the proper URL. This is normally just changing the subdomain of wikipedia.
```js
wiki({ apiUrl: 'https://es.wikipedia.org/w/api.php' })
.page('Cristiano Ronaldo')
.then(page => page.info())
.then(console.log);
```
Read more about Cross Domain Requests [here](https://www.mediawiki.org/wiki/API:Main_module)
## Usage with custom headers
If you need to pass authentication headers or anything else.
```js
wiki({
headers: {
Cookie: 'name=value; name2=value2; name3=value3'
}
}).search('Winterfell');
```
## Chain data requests together for more efficient applications
Query a specific page:
```js
wiki()
.page('albert einstein')
.then(page =>
page
.chain()
.summary()
.image()
.links()
.request()
);
```
Or query many pages at once:
```js
wiki()
.chain()
.geosearch(52.52437, 13.41053)
.summary()
.image()
.coordinates()
.request();
```
## Parsing Wiki Infobox Data
The code Wikipedia uses for infobox data is strange and complex. So I have split the parsing code into another library. You can find it [here](https://github.com/dijs/infobox-parser).
[![NPM Version](https://img.shields.io/npm/v/wikijs.svg)](https://www.npmjs.com/package/infobox-parser)
We not only parse out the information, but also try to transform the data into a convenient structure for data processing.
## Contribute!
I always welcome help. Please just stick to the lint rules and write tests with each feature/fix.
## Artwork
Thanks to [Heather van der Dys](http://heathervanderdys.com/) for the awesome logo!

88
app/node_modules/wikijs/dist/cjs/chain.d.ts generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/**
* Chain API requests together
* @example
* // Get page summary and images in same request
* wiki.page('batman').then(page => page.chain().summary().image().request()).then(console.log);
* @namespace QueryChain
*/
export default class QueryChain {
constructor(apiOptions: any, id: any);
id: any;
apiOptions: any;
_params: {
pageids: any;
};
props: Set<any>;
params(): {
pageids: any;
} & {
prop: string;
};
direct(key: any, ...args: any[]): any;
/**
* Make combined API request
* @method QueryChain#request
* @returns {Object|Array} - Data object(s) depending on where the chain was created from
*/
request(): Object | any[];
chain(prop: any, params?: {}): QueryChain;
/**
* @summary Finds pages near a specific point
* @method QueryChain#geosearch
* @returns {QueryChain}
*/
geosearch(latitude: any, longitude: any, radius: any): QueryChain;
search(query: any, limit?: number): QueryChain;
/**
* @summary Useful for extracting structured section content
* @method QueryChain#content
* @returns {QueryChain}
*/
content(): QueryChain;
/**
* @summary Useful for extracting summary content
* @method QueryChain#summary
* @returns {QueryChain}
*/
summary(): QueryChain;
/**
* @summary Extract image
* @method QueryChain#image
* @returns {QueryChain}
*/
image(types?: {
thumbnail: boolean;
original: boolean;
name: boolean;
}): QueryChain;
/**
* @summary Extract external links
* @method QueryChain#extlinks
* @returns {QueryChain}
*/
extlinks(): QueryChain;
/**
* @summary Extract page links
* @method QueryChain#links
* @returns {QueryChain}
*/
links(limit?: number): QueryChain;
/**
* @summary Extract categories
* @method QueryChain#categories
* @returns {QueryChain}
*/
categories(limit?: number): QueryChain;
/**
* @summary Extract coordinates
* @method QueryChain#coordinates
* @returns {QueryChain}
*/
coordinates(): QueryChain;
/**
* @summary Get list of links to different translations
* @method QueryChain#langlinks
* @returns {QueryChain}
*/
langlinks(): QueryChain;
}

214
app/node_modules/wikijs/dist/cjs/chain.js generated vendored Normal file
View File

@@ -0,0 +1,214 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const util_js_1 = require("./util.js");
const processors = {
extracts: data => {
return { extract: data.extract };
},
links: data => {
return { links: data.links.map(e => e.title) };
},
extlinks: data => {
return { extlinks: data.extlinks.map(e => e['*']) };
},
langlinks: data => {
return {
langlinks: data.langlinks.map(link => {
return {
lang: link.lang,
title: link['*'],
url: link.url
};
})
};
},
coordinates: data => {
if (data.coordinates) {
return { coordinates: data.coordinates[0] };
}
else {
return {};
}
},
categories: data => {
return { categories: data.categories.map(e => e.title) };
},
pageimages: data => {
return {
image: {
name: data.pageimage,
thumbnail: data.thumbnail,
original: data.original
}
};
}
};
function process(props, rawPageData) {
const data = { title: rawPageData.title };
return props.reduce((memo, prop) => {
if (processors[prop])
Object.assign(memo, processors[prop](rawPageData));
return memo;
}, data);
}
/**
* Chain API requests together
* @example
* // Get page summary and images in same request
* wiki.page('batman').then(page => page.chain().summary().image().request()).then(console.log);
* @namespace QueryChain
*/
class QueryChain {
constructor(apiOptions, id) {
this.id = id;
this.apiOptions = apiOptions;
this._params = { pageids: id };
this.props = new Set();
}
params() {
const prop = [...this.props].join('|');
return Object.assign({}, this._params, { prop });
}
direct(key, ...args) {
return this[key](...args)
.request()
.then(res => res[key]);
}
// TODO: Add page searches for root calls - generators
// TODO: Add pagination helper method
/**
* Make combined API request
* @method QueryChain#request
* @returns {Object|Array} - Data object(s) depending on where the chain was created from
*/
request() {
const props = [...this.props];
return (0, util_js_1.api)(this.apiOptions, this.params())
.then(res => {
if (this.id) {
return res.query.pages[this.id];
}
else {
return Object.values(res.query.pages);
}
})
.then(data => {
if (Array.isArray(data)) {
return data.map(e => process(props, e));
}
else {
return process(props, data);
}
});
}
chain(prop, params = {}) {
if (prop) {
this.props.add(prop);
}
Object.assign(this._params, params);
return this;
}
/**
* @summary Finds pages near a specific point
* @method QueryChain#geosearch
* @returns {QueryChain}
*/
geosearch(latitude, longitude, radius) {
return this.chain(undefined, {
generator: 'geosearch',
ggsradius: radius,
ggscoord: `${latitude}|${longitude}`
});
}
search(query, limit = 50) {
return this.chain(undefined, {
list: 'search',
srsearch: query,
srlimit: limit
});
}
/**
* @summary Useful for extracting structured section content
* @method QueryChain#content
* @returns {QueryChain}
*/
content() {
return this.chain('extracts', {
explaintext: '1'
});
}
/**
* @summary Useful for extracting summary content
* @method QueryChain#summary
* @returns {QueryChain}
*/
summary() {
return this.chain('extracts', {
explaintext: '1',
exintro: '1'
});
}
/**
* @summary Extract image
* @method QueryChain#image
* @returns {QueryChain}
*/
image(types = { thumbnail: true, original: false, name: true }) {
return this.chain('pageimages', {
piprop: Object.keys(types)
.filter(k => types[k])
.join('|')
});
}
/**
* @summary Extract external links
* @method QueryChain#extlinks
* @returns {QueryChain}
*/
extlinks() {
return this.chain('extlinks', {
ellimit: 'max'
});
}
/**
* @summary Extract page links
* @method QueryChain#links
* @returns {QueryChain}
*/
links(limit = 100) {
return this.chain('links', {
plnamespace: 0,
pllimit: limit
});
}
/**
* @summary Extract categories
* @method QueryChain#categories
* @returns {QueryChain}
*/
categories(limit = 100) {
return this.chain('categories', {
pllimit: limit
});
}
/**
* @summary Extract coordinates
* @method QueryChain#coordinates
* @returns {QueryChain}
*/
coordinates() {
return this.chain('coordinates');
}
/**
* @summary Get list of links to different translations
* @method QueryChain#langlinks
* @returns {QueryChain}
*/
langlinks() {
return this.chain('langlinks', {
lllimit: 'max',
llprop: 'url'
});
}
}
exports.default = QueryChain;

7
app/node_modules/wikijs/dist/cjs/coordinates.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/**
* @ignore
* @description Parses Coordinates for pages where the default Wiki Infobox Parser fails.
* @param {Object} infoboxData - raw data object from Wiki Infobox Parser
* @returns {Object} - formatted object containing coordinates, or null object if none.
*/
export function parseCoordinates(infoboxData: Object): Object;

106
app/node_modules/wikijs/dist/cjs/coordinates.js generated vendored Normal file
View File

@@ -0,0 +1,106 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseCoordinates = void 0;
/**
* @ignore
* @description Parses Coordinates for pages where the default Wiki Infobox Parser fails.
* @param {Object} infoboxData - raw data object from Wiki Infobox Parser
* @returns {Object} - formatted object containing coordinates, or null object if none.
*/
function parseCoordinates(infoboxData) {
if (infoboxData.coordinates) {
return parseInfoboxCoords(infoboxData.coordinates);
}
if (infoboxData.latd && infoboxData.longd) {
return parseDeprecatedCoords(infoboxData);
}
return {
lat: null,
lon: null,
error: 'No coordinates on page.'
};
}
exports.parseCoordinates = parseCoordinates;
/**
* @ignore
* @description Parses coordinates which are in Wikipedia Deprecated Format.
* @example
* parseDeprecatedCoords('00 |latm=47 |lats=59 |latNS=S','100 |longm=39 |longs=58 |longEW=E');
* @param {String} latString - Deprecated coordinate string for latitutde (from latd property)
* @param {String} lonString - Deprecated coordinate string for longitude (from longd property)
* @returns {Object} - Wiki formatted object containing lat and lon
*/
function parseDeprecatedCoords(data) {
const latitude = dmsToDecimal(floatOrDefault(data.latd), floatOrDefault(data.latm), floatOrDefault(data.lats), data.latNs);
const longitude = dmsToDecimal(floatOrDefault(data.longd), floatOrDefault(data.longm), floatOrDefault(data.longs), data.longEw);
return wikiCoordinates(latitude, longitude);
}
// regex to match coordinate string in infobox
const infoboxCoordinatePattern = /(\d{1,2})\|(\d{1,2})\|(\d{1,2})?\|?([NSEW])\|(\d{1,3})\|(\d{1,2})\|(\d{1,2})?\|?([NSEW])/;
/**
* @ignore
* @description Parses coordinates which are embedded in infobox instead of in the page.
* @example
* parseInfoboxCoord('{{coord|38|54|N|16|36|E|type:region:IT_type:city(94969)|display=inline}}')
* @param {String} coord - coordinate string from infobox.
* @return {Object} - Wiki formatted object containing lat and lon
*/
function parseInfoboxCoords(coord) {
let matches, latitude, longitude;
matches = coord.match(infoboxCoordinatePattern);
latitude = convertCoordinatesFromStrings(matches.slice(0, 4));
longitude = convertCoordinatesFromStrings(matches.slice(4));
return wikiCoordinates(latitude, longitude);
}
/**
* @ignore
* @description Converts coordinates after they've been separated into components by regex matching.
* Missing or undefined elements in array will be treated as 0. Missing direction will
* result in positive coordinate.
* @example
* convertCoordinatesFromStrings(['38','54','23','N'])
* @param {Array} matches - array in format ['degrees','minutes','seconds','direction']
* @returns {Number} - coordinate in decimal form, with proper positive / negative sign applied.
*/
function convertCoordinatesFromStrings(matches) {
return dmsToDecimal(floatOrDefault(matches[1]), floatOrDefault(matches[2]), floatOrDefault(matches[3]), matches[4]);
}
// simplifies positive / negative calculation in decimal conversion
const directions = { N: 1, S: -1, E: 1, W: -1 };
/**
* @ignore
* @description Converts coordinates from degrees, minutes, seconds, direction to decimal.
* @example
* dmsToDecimal(100,39,58,'W') == -100.6661111
* @returns {Number} - coordinate in decimal form, with proper positive / negative sign applied.
*/
function dmsToDecimal(degrees, minutes, seconds, direction) {
return ((degrees + (1 / 60) * minutes + (1 / 3600) * seconds) *
(directions[direction] || 1));
}
/**
* @ignore
* @description Returns latitude and longitude in format Wikipedia Parser would do so.
* Rounds to 4 decimal places.
* @param {Number} latitude - latitude in decimal form
* @param {Number} longitude - longitude in decimal form
* @returns {Object} - {lat: latitude, lon: longitude}
*/
function wikiCoordinates(latitude, longitude) {
return {
lat: Number(latitude.toFixed(4)),
lon: Number(longitude.toFixed(4))
};
}
/**
* @ignore
* @description Convert numeric string to Number or return 0 if not possible
* @example
* floatOrDefault("5") == 5; floatOrDefault(undefined) == 0;
* @param {String} numStr - input number string (or undefined)
* @returns {Number} - returns numStr converted to Number or 0 if NaN
*/
function floatOrDefault(numStr) {
const num = Number(numStr);
return !isNaN(num) ? num : 0;
}

3
app/node_modules/wikijs/dist/cjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "commonjs"
}

5
app/node_modules/wikijs/dist/cjs/page.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
/**
* WikiPage
* @namespace WikiPage
*/
export default function wikiPage(rawPageInfo: any, apiOptions: any): any;

457
app/node_modules/wikijs/dist/cjs/page.js generated vendored Normal file
View File

@@ -0,0 +1,457 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const infobox_parser_1 = __importDefault(require("infobox-parser"));
const hyntax_1 = require("hyntax");
const util_js_1 = require("./util.js");
const coordinates_js_1 = require("./coordinates.js");
const chain_js_1 = __importDefault(require("./chain.js"));
const get = (obj, first, ...rest) => {
if (obj === undefined || first === undefined)
return obj;
if (typeof first === 'function') {
return get(first(obj), ...rest);
}
return get(obj[first], ...rest);
};
const firstValue = obj => {
if (typeof obj === 'object')
return obj[Object.keys(obj)[0]];
return obj[0];
};
const getFileName = text => {
if (Array.isArray(text))
text = text[0];
if (!text)
return undefined;
if (text.indexOf(':') !== -1) {
const [, name] = text.split(':');
return name;
}
return text;
};
/**
* WikiPage
* @namespace WikiPage
*/
function wikiPage(rawPageInfo, apiOptions) {
const raw = rawPageInfo;
/**
* HTML from page
* @example
* wiki.page('batman').then(page => page.html()).then(console.log);
* @method WikiPage#html
* @return {Promise}
*/
function html() {
return (0, util_js_1.api)(apiOptions, {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
rvparse: '',
titles: raw.title
}).then(res => res.query.pages[raw.pageid].revisions[0]['*']);
}
/**
* @summary Useful for extracting structured section content from the page
* @alias sections
* @example
* wiki.page('batman').then(page => page.content()).then(console.log);
* @method WikiPage#content
* @return {Promise}
*/
function content() {
return rawContent().then(util_js_1.parseContent);
}
/**
* Raw content from page
* @example
* wiki.page('batman').then(page => page.rawContent()).then(console.log);
* @method WikiPage#rawContent
* @return {Promise}
*/
function rawContent() {
return chain()
.content()
.request()
.then(res => res.extract);
}
/**
* Text summary from page
* @example
* wiki.page('batman').then(page => page.summary()).then(console.log);
* @method WikiPage#summary
* @return {Promise}
*/
function summary() {
return chain()
.summary()
.request()
.then(res => res.extract);
}
/**
* Main page image directly from API
* @method WikiPage#pageImage
* @returns URL
*/
function pageImage() {
return chain()
.image({ original: true, name: true })
.request()
.then(res => get(res, 'image', 'original', 'source'));
}
/**
* Raw data from images from page
* @example
* wiki.page('batman').then(page => page.rawImages()).then(console.log);
* @method WikiPage#rawImages
* @return {Promise}
*/
function rawImages() {
return (0, util_js_1.api)(apiOptions, {
generator: 'images',
gimlimit: 'max',
prop: 'imageinfo',
iiprop: 'url',
titles: raw.title
}).then(res => {
if (res.query) {
return Object.keys(res.query.pages).map(id => res.query.pages[id]);
}
return [];
});
}
/**
* Main image URL from infobox on page
* @example
* wiki.page('batman').then(page => page.mainImage()).then(console.log);
* @method WikiPage#mainImage
* @return {Promise}
*/
function mainImage() {
return Promise.all([rawImages(), info()]).then(([images, info]) => {
// Handle different translations of "image" here
const mainImageName = getFileName(info.image ||
info.bildname ||
info.imagen ||
info.Immagine ||
info.badge ||
info.logo);
// Handle case where no info box exists
if (!mainImageName) {
return rawInfo().then(text => {
if (!images.length)
return undefined;
// Sort images by what is seen first in page's info text
images.sort((a, b) => text.indexOf(b.title) - text.indexOf(a.title));
const image = images[0];
const fallback = image && image.imageinfo.length > 0
? image.imageinfo[0].url
: undefined;
// If no image could be found, fallback to page image api result
return pageImage().then(url => url || fallback);
});
}
const image = images.find(({ title }) => {
const filename = getFileName(title);
// Some wikis use underscores for spaces, some don't
return (filename.toUpperCase() === mainImageName.toUpperCase() ||
filename.replace(/\s/g, '_') === mainImageName);
});
const fallback = image && image.imageinfo.length > 0
? image.imageinfo[0].url
: undefined;
// If no image could be found, fallback to page image api result
return pageImage().then(url => url || fallback);
});
}
/**
* Image URL's from page
* @example
* wiki.page('batman').then(page => page.image()).then(console.log);
* @method WikiPage#images
* @return {Promise}
*/
function images() {
return rawImages().then(images => {
return images
.map(image => image.imageinfo)
.reduce((imageInfos, list) => [...imageInfos, ...list], [])
.map(info => info.url);
});
}
/**
* External links from page
* @example
* wiki().page('batman').then(page => page.externalLinks()).then(console.log);
* // or
* wiki().chain().search('batman').extlinks().request()
* @method WikiPage#externalLinks
* @return {Promise}
*/
function externalLinks() {
return chain().direct('extlinks');
}
function hasClass(node, className) {
return (node.content.attributes &&
node.content.attributes.some(attr => attr.key.content === 'class' &&
attr.value.content.indexOf(className) !== -1));
}
function isTag(node) {
return node.nodeType === 'tag';
}
function hasName(node, name) {
return node.content.name === name;
}
function findNode(node, predicate) {
if (predicate(node))
return node;
// search through children as well
if (node.content.children) {
for (let child of node.content.children) {
const found = findNode(child, predicate);
if (found) {
return found;
}
}
}
return null;
}
function findNodes(node, predicate, nodes) {
if (predicate(node)) {
nodes.push(node);
}
if (node.content.children) {
for (let child of node.content.children) {
findNodes(child, predicate, nodes);
}
}
}
/**
* References from page
* @example
* wiki().page('batman').then(page => page.references()).then(console.log);
* @method WikiPage#references
* @return {Promise}
*/
function references() {
return html()
.then(inputHTML => {
const { tokens } = (0, hyntax_1.tokenize)(inputHTML);
const { ast } = (0, hyntax_1.constructTree)(tokens);
return ast;
})
.then(ast => {
const links = [];
const refs = [];
// There can be mulitple reference sections
findNodes(ast, node => isTag(node) && hasName(node, 'ol') && hasClass(node, 'references'), refs);
for (let ref of refs) {
const items = ref.content.children.filter(el => isTag(el) && hasName(el, 'li') && el.content.children);
for (let item of items) {
// The reference was moved under a span under li
const span = item.content.children[2];
const cite = findNode(span, node => isTag(node) && hasName(node, 'cite'));
if (cite) {
for (let el of cite.content.children) {
if (isTag(el) && hasName(el, 'a') && hasClass(el, 'external')) {
const linkAttr = el.content.attributes.find(attr => attr.key.content === 'href');
links.push(linkAttr.value.content);
}
}
}
}
}
return links;
});
}
/**
* Paginated links from page
* @example
* wiki().page('batman').then(page => page.links()).then(console.log);
* @method WikiPage#links
* @param {Boolean} [aggregated] - return all links (default is true)
* @param {Number} [limit] - number of links per page
* @return {Promise} - returns results if aggregated [and next function for more results if not aggregated]
*/
function links(aggregated = true, limit = 100) {
const _pagination = (0, util_js_1.pagination)(apiOptions, {
prop: 'links',
plnamespace: 0,
pllimit: limit,
titles: raw.title
}, res => (res.query.pages[raw.pageid].links || []).map(link => link.title));
if (aggregated) {
return (0, util_js_1.aggregatePagination)(_pagination);
}
return _pagination;
}
/**
* Paginated categories from page
* @example
* wiki().page('batman').then(page => page.categories()).then(console.log);
* @method WikiPage#categories
* @param {Boolean} [aggregated] - return all categories (default is true)
* @param {Number} [limit] - number of categories per page
* @return {Promise} - returns results if aggregated [and next function for more results if not aggregated]
*/
function categories(aggregated = true, limit = 100) {
const _pagination = (0, util_js_1.pagination)(apiOptions, chain()
.categories(limit)
.params(), res => (res.query.pages[raw.pageid].categories || []).map(category => category.title));
if (aggregated) {
return (0, util_js_1.aggregatePagination)(_pagination);
}
return _pagination;
}
/**
* Geographical coordinates from page
* @example
* wiki().page('Texas').then(texas => texas.coordinates())
* @method WikiPage#coordinates
* @return {Promise}
*/
function coordinates() {
return chain()
.direct('coordinates')
.then(coords => {
if (coords)
return coords;
// No coordinates for this page, check infobox for deprecated version
return info().then(data => (0, coordinates_js_1.parseCoordinates)(data));
});
}
function rawInfo(title) {
return (0, util_js_1.api)(apiOptions, {
prop: 'revisions',
rvprop: 'content',
rvsection: 0,
titles: title || raw.title
}).then(res => get(res, 'query', 'pages', firstValue, 'revisions', 0, '*'));
}
/**
* Fetch and parse tables within page
* @method WikiPage#tables
* @return {Promise} Resolves to a collection of tables
*/
function tables() {
return (0, util_js_1.api)(apiOptions, {
prop: 'revisions',
rvprop: 'content',
titles: raw.title
})
.then(res => get(res, 'query', 'pages', firstValue, 'revisions', 0, '*'))
.then(wikitext => (0, infobox_parser_1.default)(wikitext, apiOptions.parser).tables);
}
/**
* Get general information from page, with optional specifc property
* @deprecated This method will be dropped and replaced with the `fullInfo` implementation in v5
* @example
* wiki().page('Batman').then(page => page.info('alter_ego'));
* @method WikiPage#info
* @param {String} [key] - Information key. Falsy keys are ignored
* @return {Promise} - info Object contains key/value pairs of infobox data, or specific value if key given
*/
function info(key) {
return rawInfo()
.then(wikitext => {
// Use general data for now...
const info = (0, infobox_parser_1.default)(wikitext, apiOptions.parser).general;
if (Object.keys(info).length === 0) {
// If empty, check to see if this page has a templated infobox
return rawInfo(`Template:Infobox ${raw.title.toLowerCase()}`).then(_wikitext => (0, infobox_parser_1.default)(_wikitext || '', apiOptions.parser).general);
}
return info;
})
.then(metadata => {
if (!key) {
return metadata;
}
if (metadata.hasOwnProperty(key)) {
return metadata[key];
}
});
}
/**
* Get the full infobox data, parsed in a easy to use manner
* @example
* new Wiki().page('Batman').then(page => page.fullInfo()).then(info => info.general.aliases);
* @method WikiPage#fullInfo
* @return {Promise} - Parsed object of all infobox data
*/
function fullInfo() {
return rawInfo().then(wikitext => (0, infobox_parser_1.default)(wikitext, apiOptions.parser));
}
/**
* Paginated backlinks from page
* @method WikiPage#backlinks
* @param {Boolean} [aggregated] - return all backlinks (default is true)
* @param {Number} [limit] - number of backlinks per page
* @return {Promise} - includes results [and next function for more results if not aggregated]
*/
function backlinks(aggregated = true, limit = 100) {
const _pagination = (0, util_js_1.pagination)(apiOptions, {
list: 'backlinks',
bllimit: limit,
bltitle: raw.title
}, res => (res.query.backlinks || []).map(link => link.title));
if (aggregated) {
return (0, util_js_1.aggregatePagination)(_pagination);
}
return _pagination;
}
/**
* Get list of links to different translations
* @method WikiPage#langlinks
* @return {Promise} - includes link objects { lang, title, url }
*/
function langlinks() {
return chain().direct('langlinks');
}
/**
* Get URL for wiki page
* @method WikiPage#url
* @return {String}
*/
function url() {
return raw.canonicalurl;
}
const page = Object.assign({}, raw);
/**
* Returns a QueryChain for the page
* @method WikiPage#chain
* @returns {QueryChain}
*/
function chain() {
return new chain_js_1.default(apiOptions, raw.pageid);
}
Object.assign(page, {
raw,
html,
rawContent,
content,
sections: content,
summary,
images,
references,
links,
externalLinks,
categories,
coordinates,
info,
backlinks,
rawImages,
mainImage,
langlinks,
rawInfo,
fullInfo,
pageImage,
tables,
url,
chain
});
return page;
}
exports.default = wikiPage;

9
app/node_modules/wikijs/dist/cjs/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
export function api(apiOptions: any, params?: {}): Promise<any>;
export function pagination(apiOptions: any, params: any, parseResults: any): Promise<{
results: any;
query: any;
next(): Promise<any>;
}>;
export function aggregatePagination(pagination: any, previousResults?: any[]): any;
export function aggregate(apiOptions: any, params: any, list: any, key: any, prefix: any, results?: any[]): any;
export function parseContent(source: any): never[];

160
app/node_modules/wikijs/dist/cjs/util.js generated vendored Normal file
View File

@@ -0,0 +1,160 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseContent = exports.aggregate = exports.aggregatePagination = exports.pagination = exports.api = void 0;
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const querystring_1 = __importDefault(require("querystring"));
const fetchOptions = {
method: 'GET',
mode: 'cors',
credentials: 'omit'
};
function api(apiOptions, params = {}) {
const qs = Object.assign({
format: 'json',
action: 'query',
redirects: '1'
}, params);
// Remove undefined properties
Object.keys(qs).forEach(key => {
if (qs[key] === undefined) {
delete qs[key];
}
});
if (apiOptions.origin) {
qs.origin = apiOptions.origin;
}
const url = `${apiOptions.apiUrl}?${querystring_1.default.stringify(qs)}`;
const headers = Object.assign({ 'User-Agent': 'WikiJS Bot v1.0' }, apiOptions.headers);
return (0, cross_fetch_1.default)(url, Object.assign({ headers }, fetchOptions))
.then(res => {
if (res.ok) {
return res.json();
}
throw new Error(`${res.status}: ${res.statusText}`);
})
.then(res => {
if (res.error) {
throw new Error(res.error.info);
}
return res;
});
}
exports.api = api;
function pagination(apiOptions, params, parseResults) {
return api(apiOptions, params).then(res => {
let resolution = {};
resolution.results = parseResults(res);
resolution.query = params.srsearch;
if (res['continue']) {
const continueType = Object.keys(res['continue']).filter(key => key !== 'continue')[0];
const continueKey = res['continue'][continueType];
params[continueType] = continueKey;
resolution.next = () => pagination(apiOptions, params, parseResults);
}
return resolution;
});
}
exports.pagination = pagination;
function aggregatePagination(pagination, previousResults = []) {
return pagination.then(res => {
const results = [...previousResults, ...res.results];
if (res.next) {
return aggregatePagination(res.next(), results);
}
else {
return results;
}
});
}
exports.aggregatePagination = aggregatePagination;
const pageLimit = 500;
function aggregate(apiOptions, params, list, key, prefix, results = []) {
params.list = list;
params[prefix + 'limit'] = pageLimit;
return api(apiOptions, params).then(res => {
const nextResults = [...results, ...res.query[list].map(e => e[key])];
const continueWith = res['query-continue'] || res.continue;
if (continueWith) {
const nextFromKey = (continueWith[list] && continueWith[list][prefix + 'from']) ||
(continueWith[list] && continueWith[list][prefix + 'continue']) ||
continueWith[prefix + 'continue'];
params[prefix + 'continue'] = nextFromKey;
params[prefix + 'from'] = nextFromKey;
return aggregate(apiOptions, params, list, key, prefix, nextResults);
}
return nextResults;
});
}
exports.aggregate = aggregate;
const headingPattern = /(==+)(?:(?!\n)\s?)((?:(?!==|\n)[^])+)(?:(?!\n)\s?)(==+)/g;
function getHeadings(text) {
let match;
const matches = [];
while ((match = headingPattern.exec(text)) !== null) {
matches.push({
level: match[1].trim().length,
text: match[2].trim(),
start: match.index,
end: match.index + match[0].length
});
}
return matches;
}
function parseContent(source) {
const headings = getHeadings(source);
const minLevel = Math.min(...headings.map(({ level }) => level));
const sections = headings.map((heading, index) => {
const next = headings[index + 1];
const content = source
.substring(heading.end, next ? next.start : undefined)
.trim();
return {
title: heading.text,
level: heading.level - minLevel,
id: index,
content,
items: []
};
});
const lastParentLevel = (index, level) => {
if (level === 0)
return null;
for (let i = index - 1; i >= 0; i--) {
if (sections[i].level < level) {
return sections[i].id;
}
}
return null;
};
// Set parents
sections.forEach((section, index) => {
section.parent = lastParentLevel(index, section.level);
});
const root = {
items: []
};
const findSection = id => sections.find(s => id === s.id);
// Organize
sections.forEach(section => {
if (section.parent === null) {
root.items.push(section);
}
else {
findSection(section.parent).items.push(section);
}
});
// Clean up
sections.forEach(section => {
delete section.id;
delete section.parent;
delete section.level;
if (!section.items.length) {
delete section.items;
}
});
return root.items;
}
exports.parseContent = parseContent;

9
app/node_modules/wikijs/dist/cjs/wiki.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* wiki
* @example
* wiki({ apiUrl: 'http://fr.wikipedia.org/w/api.php' }).search(...);
* @namespace Wiki
* @param {Object} options
* @return {Object} - wiki (for chaining methods)
*/
export default function wiki(options?: Object): Object;

325
app/node_modules/wikijs/dist/cjs/wiki.js generated vendored Normal file
View File

@@ -0,0 +1,325 @@
'use strict';
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const cross_fetch_1 = __importDefault(require("cross-fetch"));
const querystring_1 = __importDefault(require("querystring"));
const util_js_1 = require("./util.js");
const page_js_1 = __importDefault(require("./page.js"));
const chain_js_1 = __importDefault(require("./chain.js"));
/**
* @namespace
* @constant
* @property {string} apiUrl - URL of Wikipedia API
* @property {string} headers - Headers to pass through to the API request
* @property {string} origin - When accessing the API using a cross-domain AJAX
* request (CORS), set this to the originating domain. This must be included in
* any pre-flight request, and therefore must be part of the request URI (not
* the POST body). This must match one of the origins in the Origin header
* exactly, so it has to be set to something like https://en.wikipedia.org or
* https://meta.wikimedia.org. If this parameter does not match the Origin
* header, a 403 response will be returned. If this parameter matches the Origin
* header and the origin is whitelisted, an Access-Control-Allow-Origin header
* will be set.
*/
const defaultOptions = {
apiUrl: 'http://en.wikipedia.org/w/api.php',
origin: '*'
};
/**
* wiki
* @example
* wiki({ apiUrl: 'http://fr.wikipedia.org/w/api.php' }).search(...);
* @namespace Wiki
* @param {Object} options
* @return {Object} - wiki (for chaining methods)
*/
function wiki(options = {}) {
if (this instanceof wiki) {
// eslint-disable-next-line
console.log('Please do not use wikijs ^1.0.0 as a class. Please see the new README.');
}
const apiOptions = Object.assign({}, defaultOptions, options);
function handleRedirect(res) {
if (res.query.redirects && res.query.redirects.length === 1) {
return (0, util_js_1.api)(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
titles: res.query.redirects[0].to
});
}
return res;
}
/**
* Search articles
* @example
* wiki.search('star wars').then(data => console.log(data.results.length));
* @example
* wiki.search('star wars').then(data => {
* data.next().then(...);
* });
* @method Wiki#search
* @param {string} query - keyword query
* @param {Number} [limit] - limits the number of results
* @param {Boolean} [all] - returns entire article objects instead of just titles
* @return {Promise} - pagination promise with results and next page function
*/
function search(query, limit = 50, all = false) {
return (0, util_js_1.pagination)(apiOptions, {
list: 'search',
srsearch: query,
srlimit: limit
}, res => res.query.search.map(article => {
return all ? article : article.title;
})).catch(err => {
if (err.message === '"text" search is disabled.') {
// Try backup search method
return opensearch(query, limit);
}
throw err;
});
}
/**
* Search articles using "fuzzy" prefixsearch
* @example
* wiki.prefixSearch('star wars').then(data => console.log(data.results.length));
* @example
* wiki.prefixSearch('star wars').then(data => {
* data.next().then(...);
* });
* @method Wiki#prefixSearch
* @param {string} query - keyword query
* @param {Number} [limit] - limits the number of results
* @return {Promise} - pagination promise with results and next page function
*/
function prefixSearch(query, limit = 50) {
return (0, util_js_1.pagination)(apiOptions, {
list: 'prefixsearch',
pslimit: limit,
psprofile: 'fuzzy',
pssearch: query
}, res => res.query.prefixsearch.map(article => article.title));
}
/**
* Opensearch (mainly used as a backup to normal text search)
* @param {string} query - keyword query
* @param {Number} limit - limits the number of results
* @return {Array} List of page title results
*/
function opensearch(query, limit = 50) {
return (0, util_js_1.api)(apiOptions, {
search: query,
limit,
namespace: 0,
action: 'opensearch',
redirects: undefined
}).then(res => res[1]);
}
/**
* Random articles
* @example
* wiki.random(3).then(results => console.log(results[0]));
* @method Wiki#random
* @param {Number} [limit] - limits the number of random articles
* @return {Promise} - List of page titles
*/
function random(limit = 1) {
return (0, util_js_1.api)(apiOptions, {
list: 'random',
rnnamespace: 0,
rnlimit: limit
}).then(res => res.query.random.map(article => article.title));
}
/**
* Get Page
* @example
* wiki.page('Batman').then(page => console.log(page.pageid));
* @method Wiki#page
* @param {string} title - title of article
* @return {Promise}
*/
function page(title) {
return (0, util_js_1.api)(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
titles: title
})
.then(handleRedirect)
.then(res => {
const id = Object.keys(res.query.pages)[0];
if (!id || id === '-1') {
throw new Error('No article found');
}
return (0, page_js_1.default)(res.query.pages[id], apiOptions);
});
}
/**
* Get Page by PageId
* @example
* wiki.findById(4335).then(page => console.log(page.title));
* @method Wiki#findById
* @param {integer} pageid, id of the page
* @return {Promise}
*/
function findById(pageid) {
return (0, util_js_1.api)(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
pageids: pageid
})
.then(handleRedirect)
.then(res => {
const id = Object.keys(res.query.pages)[0];
if (!id || id === '-1') {
throw new Error('No article found');
}
return (0, page_js_1.default)(res.query.pages[id], apiOptions);
});
}
/**
* Find page by query and optional predicate
* @example
* wiki.find('luke skywalker').then(page => console.log(page.title));
* @method Wiki#find
* @param {string} search query
* @param {function} [predicate] - testing function for choosing which page result to fetch. Default is first result.
* @return {Promise}
*/
function find(query, predicate = results => results[0]) {
return search(query)
.then(res => predicate(res.results))
.then(name => page(name));
}
/**
* Geographical Search
* @example
* wiki.geoSearch(32.329, -96.136).then(titles => console.log(titles.length));
* @method Wiki#geoSearch
* @param {Number} lat - latitude
* @param {Number} lon - longitude
* @param {Number} [radius=1000] - search radius in meters (default: 1km)
* @param {Number} [limit=10] - number of results (default: 10 results)
* @return {Promise} - List of page titles
*/
function geoSearch(lat, lon, radius = 1000, limit = 10) {
return (0, util_js_1.api)(apiOptions, {
list: 'geosearch',
gsradius: radius,
gscoord: `${lat}|${lon}`,
gslimit: limit
}).then(res => res.query.geosearch.map(article => article.title));
}
/**
* @summary Find the most viewed pages with counts
* @example
* wiki.mostViewed().then(list => console.log(`${list[0].title}: ${list[0].count}`))
* @method Wiki#mostViewed
* @returns {Promise} - Array of {title,count}
*/
function mostViewed() {
return (0, util_js_1.api)(apiOptions, {
list: 'mostviewed'
}).then(res => {
return res.query.mostviewed.map(({ title, count }) => ({ title, count }));
});
}
/**
* Fetch all page titles in wiki
* @method Wiki#allPages
* @return {Array} Array of pages
*/
function allPages() {
return (0, util_js_1.aggregate)(apiOptions, {}, 'allpages', 'title', 'ap');
}
/**
* Fetch all categories in wiki
* @method Wiki#allCategories
* @return {Array} Array of categories
*/
function allCategories() {
return (0, util_js_1.aggregate)(apiOptions, {}, 'allcategories', '*', 'ac');
}
/**
* Fetch all pages in category
* @method Wiki#pagesInCategory
* @param {String} category Category to fetch from
* @return {Array} Array of pages
*/
function pagesInCategory(category) {
return (0, util_js_1.aggregate)(apiOptions, {
cmtitle: category
}, 'categorymembers', 'title', 'cm');
}
/**
* @summary Helper function to query API directly
* @method Wiki#api
* @param {Object} params [https://www.mediawiki.org/wiki/API:Query](https://www.mediawiki.org/wiki/API:Query)
* @returns {Promise} Query Response
* @example
* wiki().api({
* action: 'parse',
* page: 'Pet_door'
* }).then(res => res.parse.title.should.equal('Pet door'));
*/
function rawApi(params) {
return (0, util_js_1.api)(apiOptions, params);
}
/**
* @summary Returns a QueryChain to efficiently query specific data
* @method Wiki#chain
* @returns {QueryChain}
* @example
* // Find summaries and images of places near a specific location
* wiki()
* .chain()
* .geosearch(52.52437, 13.41053)
* .summary()
* .image()
* .coordinates()
* .request()
*/
function chain() {
return new chain_js_1.default(apiOptions);
}
/**
* @summary Returns the Export XML for a page to be used for importing into another MediaWiki
* @method Wiki#exportXml
* @param {string} pageName
* @returns {Promise<string>} Export XML
*/
function exportXml(pageName) {
const qs = {
title: 'Special:Export',
pages: pageName
};
// The replace here is kinda hacky since
// the export action does not use
// the normal api endpoint.
const url = `${apiOptions.apiUrl.replace('api', 'index')}?${querystring_1.default.stringify(qs)}`;
const headers = Object.assign({ 'User-Agent': 'WikiJS Bot v1.0' }, apiOptions.headers);
return (0, cross_fetch_1.default)(url, { headers }).then(res => res.text());
}
return {
search,
random,
page,
geoSearch,
options,
findById,
find,
allPages,
allCategories,
pagesInCategory,
opensearch,
prefixSearch,
mostViewed,
api: rawApi,
chain,
exportXml
};
}
exports.default = wiki;

88
app/node_modules/wikijs/dist/mjs/chain.d.ts generated vendored Normal file
View File

@@ -0,0 +1,88 @@
/**
* Chain API requests together
* @example
* // Get page summary and images in same request
* wiki.page('batman').then(page => page.chain().summary().image().request()).then(console.log);
* @namespace QueryChain
*/
export default class QueryChain {
constructor(apiOptions: any, id: any);
id: any;
apiOptions: any;
_params: {
pageids: any;
};
props: Set<any>;
params(): {
pageids: any;
} & {
prop: string;
};
direct(key: any, ...args: any[]): any;
/**
* Make combined API request
* @method QueryChain#request
* @returns {Object|Array} - Data object(s) depending on where the chain was created from
*/
request(): Object | any[];
chain(prop: any, params?: {}): QueryChain;
/**
* @summary Finds pages near a specific point
* @method QueryChain#geosearch
* @returns {QueryChain}
*/
geosearch(latitude: any, longitude: any, radius: any): QueryChain;
search(query: any, limit?: number): QueryChain;
/**
* @summary Useful for extracting structured section content
* @method QueryChain#content
* @returns {QueryChain}
*/
content(): QueryChain;
/**
* @summary Useful for extracting summary content
* @method QueryChain#summary
* @returns {QueryChain}
*/
summary(): QueryChain;
/**
* @summary Extract image
* @method QueryChain#image
* @returns {QueryChain}
*/
image(types?: {
thumbnail: boolean;
original: boolean;
name: boolean;
}): QueryChain;
/**
* @summary Extract external links
* @method QueryChain#extlinks
* @returns {QueryChain}
*/
extlinks(): QueryChain;
/**
* @summary Extract page links
* @method QueryChain#links
* @returns {QueryChain}
*/
links(limit?: number): QueryChain;
/**
* @summary Extract categories
* @method QueryChain#categories
* @returns {QueryChain}
*/
categories(limit?: number): QueryChain;
/**
* @summary Extract coordinates
* @method QueryChain#coordinates
* @returns {QueryChain}
*/
coordinates(): QueryChain;
/**
* @summary Get list of links to different translations
* @method QueryChain#langlinks
* @returns {QueryChain}
*/
langlinks(): QueryChain;
}

211
app/node_modules/wikijs/dist/mjs/chain.js generated vendored Normal file
View File

@@ -0,0 +1,211 @@
import { api } from './util.js';
const processors = {
extracts: data => {
return { extract: data.extract };
},
links: data => {
return { links: data.links.map(e => e.title) };
},
extlinks: data => {
return { extlinks: data.extlinks.map(e => e['*']) };
},
langlinks: data => {
return {
langlinks: data.langlinks.map(link => {
return {
lang: link.lang,
title: link['*'],
url: link.url
};
})
};
},
coordinates: data => {
if (data.coordinates) {
return { coordinates: data.coordinates[0] };
}
else {
return {};
}
},
categories: data => {
return { categories: data.categories.map(e => e.title) };
},
pageimages: data => {
return {
image: {
name: data.pageimage,
thumbnail: data.thumbnail,
original: data.original
}
};
}
};
function process(props, rawPageData) {
const data = { title: rawPageData.title };
return props.reduce((memo, prop) => {
if (processors[prop])
Object.assign(memo, processors[prop](rawPageData));
return memo;
}, data);
}
/**
* Chain API requests together
* @example
* // Get page summary and images in same request
* wiki.page('batman').then(page => page.chain().summary().image().request()).then(console.log);
* @namespace QueryChain
*/
export default class QueryChain {
constructor(apiOptions, id) {
this.id = id;
this.apiOptions = apiOptions;
this._params = { pageids: id };
this.props = new Set();
}
params() {
const prop = [...this.props].join('|');
return Object.assign({}, this._params, { prop });
}
direct(key, ...args) {
return this[key](...args)
.request()
.then(res => res[key]);
}
// TODO: Add page searches for root calls - generators
// TODO: Add pagination helper method
/**
* Make combined API request
* @method QueryChain#request
* @returns {Object|Array} - Data object(s) depending on where the chain was created from
*/
request() {
const props = [...this.props];
return api(this.apiOptions, this.params())
.then(res => {
if (this.id) {
return res.query.pages[this.id];
}
else {
return Object.values(res.query.pages);
}
})
.then(data => {
if (Array.isArray(data)) {
return data.map(e => process(props, e));
}
else {
return process(props, data);
}
});
}
chain(prop, params = {}) {
if (prop) {
this.props.add(prop);
}
Object.assign(this._params, params);
return this;
}
/**
* @summary Finds pages near a specific point
* @method QueryChain#geosearch
* @returns {QueryChain}
*/
geosearch(latitude, longitude, radius) {
return this.chain(undefined, {
generator: 'geosearch',
ggsradius: radius,
ggscoord: `${latitude}|${longitude}`
});
}
search(query, limit = 50) {
return this.chain(undefined, {
list: 'search',
srsearch: query,
srlimit: limit
});
}
/**
* @summary Useful for extracting structured section content
* @method QueryChain#content
* @returns {QueryChain}
*/
content() {
return this.chain('extracts', {
explaintext: '1'
});
}
/**
* @summary Useful for extracting summary content
* @method QueryChain#summary
* @returns {QueryChain}
*/
summary() {
return this.chain('extracts', {
explaintext: '1',
exintro: '1'
});
}
/**
* @summary Extract image
* @method QueryChain#image
* @returns {QueryChain}
*/
image(types = { thumbnail: true, original: false, name: true }) {
return this.chain('pageimages', {
piprop: Object.keys(types)
.filter(k => types[k])
.join('|')
});
}
/**
* @summary Extract external links
* @method QueryChain#extlinks
* @returns {QueryChain}
*/
extlinks() {
return this.chain('extlinks', {
ellimit: 'max'
});
}
/**
* @summary Extract page links
* @method QueryChain#links
* @returns {QueryChain}
*/
links(limit = 100) {
return this.chain('links', {
plnamespace: 0,
pllimit: limit
});
}
/**
* @summary Extract categories
* @method QueryChain#categories
* @returns {QueryChain}
*/
categories(limit = 100) {
return this.chain('categories', {
pllimit: limit
});
}
/**
* @summary Extract coordinates
* @method QueryChain#coordinates
* @returns {QueryChain}
*/
coordinates() {
return this.chain('coordinates');
}
/**
* @summary Get list of links to different translations
* @method QueryChain#langlinks
* @returns {QueryChain}
*/
langlinks() {
return this.chain('langlinks', {
lllimit: 'max',
llprop: 'url'
});
}
}

7
app/node_modules/wikijs/dist/mjs/coordinates.d.ts generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/**
* @ignore
* @description Parses Coordinates for pages where the default Wiki Infobox Parser fails.
* @param {Object} infoboxData - raw data object from Wiki Infobox Parser
* @returns {Object} - formatted object containing coordinates, or null object if none.
*/
export function parseCoordinates(infoboxData: Object): Object;

102
app/node_modules/wikijs/dist/mjs/coordinates.js generated vendored Normal file
View File

@@ -0,0 +1,102 @@
/**
* @ignore
* @description Parses Coordinates for pages where the default Wiki Infobox Parser fails.
* @param {Object} infoboxData - raw data object from Wiki Infobox Parser
* @returns {Object} - formatted object containing coordinates, or null object if none.
*/
export function parseCoordinates(infoboxData) {
if (infoboxData.coordinates) {
return parseInfoboxCoords(infoboxData.coordinates);
}
if (infoboxData.latd && infoboxData.longd) {
return parseDeprecatedCoords(infoboxData);
}
return {
lat: null,
lon: null,
error: 'No coordinates on page.'
};
}
/**
* @ignore
* @description Parses coordinates which are in Wikipedia Deprecated Format.
* @example
* parseDeprecatedCoords('00 |latm=47 |lats=59 |latNS=S','100 |longm=39 |longs=58 |longEW=E');
* @param {String} latString - Deprecated coordinate string for latitutde (from latd property)
* @param {String} lonString - Deprecated coordinate string for longitude (from longd property)
* @returns {Object} - Wiki formatted object containing lat and lon
*/
function parseDeprecatedCoords(data) {
const latitude = dmsToDecimal(floatOrDefault(data.latd), floatOrDefault(data.latm), floatOrDefault(data.lats), data.latNs);
const longitude = dmsToDecimal(floatOrDefault(data.longd), floatOrDefault(data.longm), floatOrDefault(data.longs), data.longEw);
return wikiCoordinates(latitude, longitude);
}
// regex to match coordinate string in infobox
const infoboxCoordinatePattern = /(\d{1,2})\|(\d{1,2})\|(\d{1,2})?\|?([NSEW])\|(\d{1,3})\|(\d{1,2})\|(\d{1,2})?\|?([NSEW])/;
/**
* @ignore
* @description Parses coordinates which are embedded in infobox instead of in the page.
* @example
* parseInfoboxCoord('{{coord|38|54|N|16|36|E|type:region:IT_type:city(94969)|display=inline}}')
* @param {String} coord - coordinate string from infobox.
* @return {Object} - Wiki formatted object containing lat and lon
*/
function parseInfoboxCoords(coord) {
let matches, latitude, longitude;
matches = coord.match(infoboxCoordinatePattern);
latitude = convertCoordinatesFromStrings(matches.slice(0, 4));
longitude = convertCoordinatesFromStrings(matches.slice(4));
return wikiCoordinates(latitude, longitude);
}
/**
* @ignore
* @description Converts coordinates after they've been separated into components by regex matching.
* Missing or undefined elements in array will be treated as 0. Missing direction will
* result in positive coordinate.
* @example
* convertCoordinatesFromStrings(['38','54','23','N'])
* @param {Array} matches - array in format ['degrees','minutes','seconds','direction']
* @returns {Number} - coordinate in decimal form, with proper positive / negative sign applied.
*/
function convertCoordinatesFromStrings(matches) {
return dmsToDecimal(floatOrDefault(matches[1]), floatOrDefault(matches[2]), floatOrDefault(matches[3]), matches[4]);
}
// simplifies positive / negative calculation in decimal conversion
const directions = { N: 1, S: -1, E: 1, W: -1 };
/**
* @ignore
* @description Converts coordinates from degrees, minutes, seconds, direction to decimal.
* @example
* dmsToDecimal(100,39,58,'W') == -100.6661111
* @returns {Number} - coordinate in decimal form, with proper positive / negative sign applied.
*/
function dmsToDecimal(degrees, minutes, seconds, direction) {
return ((degrees + (1 / 60) * minutes + (1 / 3600) * seconds) *
(directions[direction] || 1));
}
/**
* @ignore
* @description Returns latitude and longitude in format Wikipedia Parser would do so.
* Rounds to 4 decimal places.
* @param {Number} latitude - latitude in decimal form
* @param {Number} longitude - longitude in decimal form
* @returns {Object} - {lat: latitude, lon: longitude}
*/
function wikiCoordinates(latitude, longitude) {
return {
lat: Number(latitude.toFixed(4)),
lon: Number(longitude.toFixed(4))
};
}
/**
* @ignore
* @description Convert numeric string to Number or return 0 if not possible
* @example
* floatOrDefault("5") == 5; floatOrDefault(undefined) == 0;
* @param {String} numStr - input number string (or undefined)
* @returns {Number} - returns numStr converted to Number or 0 if NaN
*/
function floatOrDefault(numStr) {
const num = Number(numStr);
return !isNaN(num) ? num : 0;
}

3
app/node_modules/wikijs/dist/mjs/package.json generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"type": "module"
}

5
app/node_modules/wikijs/dist/mjs/page.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
/**
* WikiPage
* @namespace WikiPage
*/
export default function wikiPage(rawPageInfo: any, apiOptions: any): any;

451
app/node_modules/wikijs/dist/mjs/page.js generated vendored Normal file
View File

@@ -0,0 +1,451 @@
import infoboxParser from 'infobox-parser';
import { tokenize, constructTree } from 'hyntax';
import { aggregatePagination, pagination, api, parseContent } from './util.js';
import { parseCoordinates } from './coordinates.js';
import QueryChain from './chain.js';
const get = (obj, first, ...rest) => {
if (obj === undefined || first === undefined)
return obj;
if (typeof first === 'function') {
return get(first(obj), ...rest);
}
return get(obj[first], ...rest);
};
const firstValue = obj => {
if (typeof obj === 'object')
return obj[Object.keys(obj)[0]];
return obj[0];
};
const getFileName = text => {
if (Array.isArray(text))
text = text[0];
if (!text)
return undefined;
if (text.indexOf(':') !== -1) {
const [, name] = text.split(':');
return name;
}
return text;
};
/**
* WikiPage
* @namespace WikiPage
*/
export default function wikiPage(rawPageInfo, apiOptions) {
const raw = rawPageInfo;
/**
* HTML from page
* @example
* wiki.page('batman').then(page => page.html()).then(console.log);
* @method WikiPage#html
* @return {Promise}
*/
function html() {
return api(apiOptions, {
prop: 'revisions',
rvprop: 'content',
rvlimit: 1,
rvparse: '',
titles: raw.title
}).then(res => res.query.pages[raw.pageid].revisions[0]['*']);
}
/**
* @summary Useful for extracting structured section content from the page
* @alias sections
* @example
* wiki.page('batman').then(page => page.content()).then(console.log);
* @method WikiPage#content
* @return {Promise}
*/
function content() {
return rawContent().then(parseContent);
}
/**
* Raw content from page
* @example
* wiki.page('batman').then(page => page.rawContent()).then(console.log);
* @method WikiPage#rawContent
* @return {Promise}
*/
function rawContent() {
return chain()
.content()
.request()
.then(res => res.extract);
}
/**
* Text summary from page
* @example
* wiki.page('batman').then(page => page.summary()).then(console.log);
* @method WikiPage#summary
* @return {Promise}
*/
function summary() {
return chain()
.summary()
.request()
.then(res => res.extract);
}
/**
* Main page image directly from API
* @method WikiPage#pageImage
* @returns URL
*/
function pageImage() {
return chain()
.image({ original: true, name: true })
.request()
.then(res => get(res, 'image', 'original', 'source'));
}
/**
* Raw data from images from page
* @example
* wiki.page('batman').then(page => page.rawImages()).then(console.log);
* @method WikiPage#rawImages
* @return {Promise}
*/
function rawImages() {
return api(apiOptions, {
generator: 'images',
gimlimit: 'max',
prop: 'imageinfo',
iiprop: 'url',
titles: raw.title
}).then(res => {
if (res.query) {
return Object.keys(res.query.pages).map(id => res.query.pages[id]);
}
return [];
});
}
/**
* Main image URL from infobox on page
* @example
* wiki.page('batman').then(page => page.mainImage()).then(console.log);
* @method WikiPage#mainImage
* @return {Promise}
*/
function mainImage() {
return Promise.all([rawImages(), info()]).then(([images, info]) => {
// Handle different translations of "image" here
const mainImageName = getFileName(info.image ||
info.bildname ||
info.imagen ||
info.Immagine ||
info.badge ||
info.logo);
// Handle case where no info box exists
if (!mainImageName) {
return rawInfo().then(text => {
if (!images.length)
return undefined;
// Sort images by what is seen first in page's info text
images.sort((a, b) => text.indexOf(b.title) - text.indexOf(a.title));
const image = images[0];
const fallback = image && image.imageinfo.length > 0
? image.imageinfo[0].url
: undefined;
// If no image could be found, fallback to page image api result
return pageImage().then(url => url || fallback);
});
}
const image = images.find(({ title }) => {
const filename = getFileName(title);
// Some wikis use underscores for spaces, some don't
return (filename.toUpperCase() === mainImageName.toUpperCase() ||
filename.replace(/\s/g, '_') === mainImageName);
});
const fallback = image && image.imageinfo.length > 0
? image.imageinfo[0].url
: undefined;
// If no image could be found, fallback to page image api result
return pageImage().then(url => url || fallback);
});
}
/**
* Image URL's from page
* @example
* wiki.page('batman').then(page => page.image()).then(console.log);
* @method WikiPage#images
* @return {Promise}
*/
function images() {
return rawImages().then(images => {
return images
.map(image => image.imageinfo)
.reduce((imageInfos, list) => [...imageInfos, ...list], [])
.map(info => info.url);
});
}
/**
* External links from page
* @example
* wiki().page('batman').then(page => page.externalLinks()).then(console.log);
* // or
* wiki().chain().search('batman').extlinks().request()
* @method WikiPage#externalLinks
* @return {Promise}
*/
function externalLinks() {
return chain().direct('extlinks');
}
function hasClass(node, className) {
return (node.content.attributes &&
node.content.attributes.some(attr => attr.key.content === 'class' &&
attr.value.content.indexOf(className) !== -1));
}
function isTag(node) {
return node.nodeType === 'tag';
}
function hasName(node, name) {
return node.content.name === name;
}
function findNode(node, predicate) {
if (predicate(node))
return node;
// search through children as well
if (node.content.children) {
for (let child of node.content.children) {
const found = findNode(child, predicate);
if (found) {
return found;
}
}
}
return null;
}
function findNodes(node, predicate, nodes) {
if (predicate(node)) {
nodes.push(node);
}
if (node.content.children) {
for (let child of node.content.children) {
findNodes(child, predicate, nodes);
}
}
}
/**
* References from page
* @example
* wiki().page('batman').then(page => page.references()).then(console.log);
* @method WikiPage#references
* @return {Promise}
*/
function references() {
return html()
.then(inputHTML => {
const { tokens } = tokenize(inputHTML);
const { ast } = constructTree(tokens);
return ast;
})
.then(ast => {
const links = [];
const refs = [];
// There can be mulitple reference sections
findNodes(ast, node => isTag(node) && hasName(node, 'ol') && hasClass(node, 'references'), refs);
for (let ref of refs) {
const items = ref.content.children.filter(el => isTag(el) && hasName(el, 'li') && el.content.children);
for (let item of items) {
// The reference was moved under a span under li
const span = item.content.children[2];
const cite = findNode(span, node => isTag(node) && hasName(node, 'cite'));
if (cite) {
for (let el of cite.content.children) {
if (isTag(el) && hasName(el, 'a') && hasClass(el, 'external')) {
const linkAttr = el.content.attributes.find(attr => attr.key.content === 'href');
links.push(linkAttr.value.content);
}
}
}
}
}
return links;
});
}
/**
* Paginated links from page
* @example
* wiki().page('batman').then(page => page.links()).then(console.log);
* @method WikiPage#links
* @param {Boolean} [aggregated] - return all links (default is true)
* @param {Number} [limit] - number of links per page
* @return {Promise} - returns results if aggregated [and next function for more results if not aggregated]
*/
function links(aggregated = true, limit = 100) {
const _pagination = pagination(apiOptions, {
prop: 'links',
plnamespace: 0,
pllimit: limit,
titles: raw.title
}, res => (res.query.pages[raw.pageid].links || []).map(link => link.title));
if (aggregated) {
return aggregatePagination(_pagination);
}
return _pagination;
}
/**
* Paginated categories from page
* @example
* wiki().page('batman').then(page => page.categories()).then(console.log);
* @method WikiPage#categories
* @param {Boolean} [aggregated] - return all categories (default is true)
* @param {Number} [limit] - number of categories per page
* @return {Promise} - returns results if aggregated [and next function for more results if not aggregated]
*/
function categories(aggregated = true, limit = 100) {
const _pagination = pagination(apiOptions, chain()
.categories(limit)
.params(), res => (res.query.pages[raw.pageid].categories || []).map(category => category.title));
if (aggregated) {
return aggregatePagination(_pagination);
}
return _pagination;
}
/**
* Geographical coordinates from page
* @example
* wiki().page('Texas').then(texas => texas.coordinates())
* @method WikiPage#coordinates
* @return {Promise}
*/
function coordinates() {
return chain()
.direct('coordinates')
.then(coords => {
if (coords)
return coords;
// No coordinates for this page, check infobox for deprecated version
return info().then(data => parseCoordinates(data));
});
}
function rawInfo(title) {
return api(apiOptions, {
prop: 'revisions',
rvprop: 'content',
rvsection: 0,
titles: title || raw.title
}).then(res => get(res, 'query', 'pages', firstValue, 'revisions', 0, '*'));
}
/**
* Fetch and parse tables within page
* @method WikiPage#tables
* @return {Promise} Resolves to a collection of tables
*/
function tables() {
return api(apiOptions, {
prop: 'revisions',
rvprop: 'content',
titles: raw.title
})
.then(res => get(res, 'query', 'pages', firstValue, 'revisions', 0, '*'))
.then(wikitext => infoboxParser(wikitext, apiOptions.parser).tables);
}
/**
* Get general information from page, with optional specifc property
* @deprecated This method will be dropped and replaced with the `fullInfo` implementation in v5
* @example
* wiki().page('Batman').then(page => page.info('alter_ego'));
* @method WikiPage#info
* @param {String} [key] - Information key. Falsy keys are ignored
* @return {Promise} - info Object contains key/value pairs of infobox data, or specific value if key given
*/
function info(key) {
return rawInfo()
.then(wikitext => {
// Use general data for now...
const info = infoboxParser(wikitext, apiOptions.parser).general;
if (Object.keys(info).length === 0) {
// If empty, check to see if this page has a templated infobox
return rawInfo(`Template:Infobox ${raw.title.toLowerCase()}`).then(_wikitext => infoboxParser(_wikitext || '', apiOptions.parser).general);
}
return info;
})
.then(metadata => {
if (!key) {
return metadata;
}
if (metadata.hasOwnProperty(key)) {
return metadata[key];
}
});
}
/**
* Get the full infobox data, parsed in a easy to use manner
* @example
* new Wiki().page('Batman').then(page => page.fullInfo()).then(info => info.general.aliases);
* @method WikiPage#fullInfo
* @return {Promise} - Parsed object of all infobox data
*/
function fullInfo() {
return rawInfo().then(wikitext => infoboxParser(wikitext, apiOptions.parser));
}
/**
* Paginated backlinks from page
* @method WikiPage#backlinks
* @param {Boolean} [aggregated] - return all backlinks (default is true)
* @param {Number} [limit] - number of backlinks per page
* @return {Promise} - includes results [and next function for more results if not aggregated]
*/
function backlinks(aggregated = true, limit = 100) {
const _pagination = pagination(apiOptions, {
list: 'backlinks',
bllimit: limit,
bltitle: raw.title
}, res => (res.query.backlinks || []).map(link => link.title));
if (aggregated) {
return aggregatePagination(_pagination);
}
return _pagination;
}
/**
* Get list of links to different translations
* @method WikiPage#langlinks
* @return {Promise} - includes link objects { lang, title, url }
*/
function langlinks() {
return chain().direct('langlinks');
}
/**
* Get URL for wiki page
* @method WikiPage#url
* @return {String}
*/
function url() {
return raw.canonicalurl;
}
const page = Object.assign({}, raw);
/**
* Returns a QueryChain for the page
* @method WikiPage#chain
* @returns {QueryChain}
*/
function chain() {
return new QueryChain(apiOptions, raw.pageid);
}
Object.assign(page, {
raw,
html,
rawContent,
content,
sections: content,
summary,
images,
references,
links,
externalLinks,
categories,
coordinates,
info,
backlinks,
rawImages,
mainImage,
langlinks,
rawInfo,
fullInfo,
pageImage,
tables,
url,
chain
});
return page;
}

9
app/node_modules/wikijs/dist/mjs/util.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
export function api(apiOptions: any, params?: {}): Promise<any>;
export function pagination(apiOptions: any, params: any, parseResults: any): Promise<{
results: any;
query: any;
next(): Promise<any>;
}>;
export function aggregatePagination(pagination: any, previousResults?: any[]): any;
export function aggregate(apiOptions: any, params: any, list: any, key: any, prefix: any, results?: any[]): any;
export function parseContent(source: any): never[];

149
app/node_modules/wikijs/dist/mjs/util.js generated vendored Normal file
View File

@@ -0,0 +1,149 @@
import fetch from 'cross-fetch';
import querystring from 'querystring';
const fetchOptions = {
method: 'GET',
mode: 'cors',
credentials: 'omit'
};
export function api(apiOptions, params = {}) {
const qs = Object.assign({
format: 'json',
action: 'query',
redirects: '1'
}, params);
// Remove undefined properties
Object.keys(qs).forEach(key => {
if (qs[key] === undefined) {
delete qs[key];
}
});
if (apiOptions.origin) {
qs.origin = apiOptions.origin;
}
const url = `${apiOptions.apiUrl}?${querystring.stringify(qs)}`;
const headers = Object.assign({ 'User-Agent': 'WikiJS Bot v1.0' }, apiOptions.headers);
return fetch(url, Object.assign({ headers }, fetchOptions))
.then(res => {
if (res.ok) {
return res.json();
}
throw new Error(`${res.status}: ${res.statusText}`);
})
.then(res => {
if (res.error) {
throw new Error(res.error.info);
}
return res;
});
}
export function pagination(apiOptions, params, parseResults) {
return api(apiOptions, params).then(res => {
let resolution = {};
resolution.results = parseResults(res);
resolution.query = params.srsearch;
if (res['continue']) {
const continueType = Object.keys(res['continue']).filter(key => key !== 'continue')[0];
const continueKey = res['continue'][continueType];
params[continueType] = continueKey;
resolution.next = () => pagination(apiOptions, params, parseResults);
}
return resolution;
});
}
export function aggregatePagination(pagination, previousResults = []) {
return pagination.then(res => {
const results = [...previousResults, ...res.results];
if (res.next) {
return aggregatePagination(res.next(), results);
}
else {
return results;
}
});
}
const pageLimit = 500;
export function aggregate(apiOptions, params, list, key, prefix, results = []) {
params.list = list;
params[prefix + 'limit'] = pageLimit;
return api(apiOptions, params).then(res => {
const nextResults = [...results, ...res.query[list].map(e => e[key])];
const continueWith = res['query-continue'] || res.continue;
if (continueWith) {
const nextFromKey = (continueWith[list] && continueWith[list][prefix + 'from']) ||
(continueWith[list] && continueWith[list][prefix + 'continue']) ||
continueWith[prefix + 'continue'];
params[prefix + 'continue'] = nextFromKey;
params[prefix + 'from'] = nextFromKey;
return aggregate(apiOptions, params, list, key, prefix, nextResults);
}
return nextResults;
});
}
const headingPattern = /(==+)(?:(?!\n)\s?)((?:(?!==|\n)[^])+)(?:(?!\n)\s?)(==+)/g;
function getHeadings(text) {
let match;
const matches = [];
while ((match = headingPattern.exec(text)) !== null) {
matches.push({
level: match[1].trim().length,
text: match[2].trim(),
start: match.index,
end: match.index + match[0].length
});
}
return matches;
}
export function parseContent(source) {
const headings = getHeadings(source);
const minLevel = Math.min(...headings.map(({ level }) => level));
const sections = headings.map((heading, index) => {
const next = headings[index + 1];
const content = source
.substring(heading.end, next ? next.start : undefined)
.trim();
return {
title: heading.text,
level: heading.level - minLevel,
id: index,
content,
items: []
};
});
const lastParentLevel = (index, level) => {
if (level === 0)
return null;
for (let i = index - 1; i >= 0; i--) {
if (sections[i].level < level) {
return sections[i].id;
}
}
return null;
};
// Set parents
sections.forEach((section, index) => {
section.parent = lastParentLevel(index, section.level);
});
const root = {
items: []
};
const findSection = id => sections.find(s => id === s.id);
// Organize
sections.forEach(section => {
if (section.parent === null) {
root.items.push(section);
}
else {
findSection(section.parent).items.push(section);
}
});
// Clean up
sections.forEach(section => {
delete section.id;
delete section.parent;
delete section.level;
if (!section.items.length) {
delete section.items;
}
});
return root.items;
}

9
app/node_modules/wikijs/dist/mjs/wiki.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* wiki
* @example
* wiki({ apiUrl: 'http://fr.wikipedia.org/w/api.php' }).search(...);
* @namespace Wiki
* @param {Object} options
* @return {Object} - wiki (for chaining methods)
*/
export default function wiki(options?: Object): Object;

320
app/node_modules/wikijs/dist/mjs/wiki.js generated vendored Normal file
View File

@@ -0,0 +1,320 @@
'use strict';
import fetch from 'cross-fetch';
import querystring from 'querystring';
import { pagination, api, aggregate } from './util.js';
import wikiPage from './page.js';
import QueryChain from './chain.js';
/**
* @namespace
* @constant
* @property {string} apiUrl - URL of Wikipedia API
* @property {string} headers - Headers to pass through to the API request
* @property {string} origin - When accessing the API using a cross-domain AJAX
* request (CORS), set this to the originating domain. This must be included in
* any pre-flight request, and therefore must be part of the request URI (not
* the POST body). This must match one of the origins in the Origin header
* exactly, so it has to be set to something like https://en.wikipedia.org or
* https://meta.wikimedia.org. If this parameter does not match the Origin
* header, a 403 response will be returned. If this parameter matches the Origin
* header and the origin is whitelisted, an Access-Control-Allow-Origin header
* will be set.
*/
const defaultOptions = {
apiUrl: 'http://en.wikipedia.org/w/api.php',
origin: '*'
};
/**
* wiki
* @example
* wiki({ apiUrl: 'http://fr.wikipedia.org/w/api.php' }).search(...);
* @namespace Wiki
* @param {Object} options
* @return {Object} - wiki (for chaining methods)
*/
export default function wiki(options = {}) {
if (this instanceof wiki) {
// eslint-disable-next-line
console.log('Please do not use wikijs ^1.0.0 as a class. Please see the new README.');
}
const apiOptions = Object.assign({}, defaultOptions, options);
function handleRedirect(res) {
if (res.query.redirects && res.query.redirects.length === 1) {
return api(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
titles: res.query.redirects[0].to
});
}
return res;
}
/**
* Search articles
* @example
* wiki.search('star wars').then(data => console.log(data.results.length));
* @example
* wiki.search('star wars').then(data => {
* data.next().then(...);
* });
* @method Wiki#search
* @param {string} query - keyword query
* @param {Number} [limit] - limits the number of results
* @param {Boolean} [all] - returns entire article objects instead of just titles
* @return {Promise} - pagination promise with results and next page function
*/
function search(query, limit = 50, all = false) {
return pagination(apiOptions, {
list: 'search',
srsearch: query,
srlimit: limit
}, res => res.query.search.map(article => {
return all ? article : article.title;
})).catch(err => {
if (err.message === '"text" search is disabled.') {
// Try backup search method
return opensearch(query, limit);
}
throw err;
});
}
/**
* Search articles using "fuzzy" prefixsearch
* @example
* wiki.prefixSearch('star wars').then(data => console.log(data.results.length));
* @example
* wiki.prefixSearch('star wars').then(data => {
* data.next().then(...);
* });
* @method Wiki#prefixSearch
* @param {string} query - keyword query
* @param {Number} [limit] - limits the number of results
* @return {Promise} - pagination promise with results and next page function
*/
function prefixSearch(query, limit = 50) {
return pagination(apiOptions, {
list: 'prefixsearch',
pslimit: limit,
psprofile: 'fuzzy',
pssearch: query
}, res => res.query.prefixsearch.map(article => article.title));
}
/**
* Opensearch (mainly used as a backup to normal text search)
* @param {string} query - keyword query
* @param {Number} limit - limits the number of results
* @return {Array} List of page title results
*/
function opensearch(query, limit = 50) {
return api(apiOptions, {
search: query,
limit,
namespace: 0,
action: 'opensearch',
redirects: undefined
}).then(res => res[1]);
}
/**
* Random articles
* @example
* wiki.random(3).then(results => console.log(results[0]));
* @method Wiki#random
* @param {Number} [limit] - limits the number of random articles
* @return {Promise} - List of page titles
*/
function random(limit = 1) {
return api(apiOptions, {
list: 'random',
rnnamespace: 0,
rnlimit: limit
}).then(res => res.query.random.map(article => article.title));
}
/**
* Get Page
* @example
* wiki.page('Batman').then(page => console.log(page.pageid));
* @method Wiki#page
* @param {string} title - title of article
* @return {Promise}
*/
function page(title) {
return api(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
titles: title
})
.then(handleRedirect)
.then(res => {
const id = Object.keys(res.query.pages)[0];
if (!id || id === '-1') {
throw new Error('No article found');
}
return wikiPage(res.query.pages[id], apiOptions);
});
}
/**
* Get Page by PageId
* @example
* wiki.findById(4335).then(page => console.log(page.title));
* @method Wiki#findById
* @param {integer} pageid, id of the page
* @return {Promise}
*/
function findById(pageid) {
return api(apiOptions, {
prop: 'info|pageprops',
inprop: 'url',
ppprop: 'disambiguation',
pageids: pageid
})
.then(handleRedirect)
.then(res => {
const id = Object.keys(res.query.pages)[0];
if (!id || id === '-1') {
throw new Error('No article found');
}
return wikiPage(res.query.pages[id], apiOptions);
});
}
/**
* Find page by query and optional predicate
* @example
* wiki.find('luke skywalker').then(page => console.log(page.title));
* @method Wiki#find
* @param {string} search query
* @param {function} [predicate] - testing function for choosing which page result to fetch. Default is first result.
* @return {Promise}
*/
function find(query, predicate = results => results[0]) {
return search(query)
.then(res => predicate(res.results))
.then(name => page(name));
}
/**
* Geographical Search
* @example
* wiki.geoSearch(32.329, -96.136).then(titles => console.log(titles.length));
* @method Wiki#geoSearch
* @param {Number} lat - latitude
* @param {Number} lon - longitude
* @param {Number} [radius=1000] - search radius in meters (default: 1km)
* @param {Number} [limit=10] - number of results (default: 10 results)
* @return {Promise} - List of page titles
*/
function geoSearch(lat, lon, radius = 1000, limit = 10) {
return api(apiOptions, {
list: 'geosearch',
gsradius: radius,
gscoord: `${lat}|${lon}`,
gslimit: limit
}).then(res => res.query.geosearch.map(article => article.title));
}
/**
* @summary Find the most viewed pages with counts
* @example
* wiki.mostViewed().then(list => console.log(`${list[0].title}: ${list[0].count}`))
* @method Wiki#mostViewed
* @returns {Promise} - Array of {title,count}
*/
function mostViewed() {
return api(apiOptions, {
list: 'mostviewed'
}).then(res => {
return res.query.mostviewed.map(({ title, count }) => ({ title, count }));
});
}
/**
* Fetch all page titles in wiki
* @method Wiki#allPages
* @return {Array} Array of pages
*/
function allPages() {
return aggregate(apiOptions, {}, 'allpages', 'title', 'ap');
}
/**
* Fetch all categories in wiki
* @method Wiki#allCategories
* @return {Array} Array of categories
*/
function allCategories() {
return aggregate(apiOptions, {}, 'allcategories', '*', 'ac');
}
/**
* Fetch all pages in category
* @method Wiki#pagesInCategory
* @param {String} category Category to fetch from
* @return {Array} Array of pages
*/
function pagesInCategory(category) {
return aggregate(apiOptions, {
cmtitle: category
}, 'categorymembers', 'title', 'cm');
}
/**
* @summary Helper function to query API directly
* @method Wiki#api
* @param {Object} params [https://www.mediawiki.org/wiki/API:Query](https://www.mediawiki.org/wiki/API:Query)
* @returns {Promise} Query Response
* @example
* wiki().api({
* action: 'parse',
* page: 'Pet_door'
* }).then(res => res.parse.title.should.equal('Pet door'));
*/
function rawApi(params) {
return api(apiOptions, params);
}
/**
* @summary Returns a QueryChain to efficiently query specific data
* @method Wiki#chain
* @returns {QueryChain}
* @example
* // Find summaries and images of places near a specific location
* wiki()
* .chain()
* .geosearch(52.52437, 13.41053)
* .summary()
* .image()
* .coordinates()
* .request()
*/
function chain() {
return new QueryChain(apiOptions);
}
/**
* @summary Returns the Export XML for a page to be used for importing into another MediaWiki
* @method Wiki#exportXml
* @param {string} pageName
* @returns {Promise<string>} Export XML
*/
function exportXml(pageName) {
const qs = {
title: 'Special:Export',
pages: pageName
};
// The replace here is kinda hacky since
// the export action does not use
// the normal api endpoint.
const url = `${apiOptions.apiUrl.replace('api', 'index')}?${querystring.stringify(qs)}`;
const headers = Object.assign({ 'User-Agent': 'WikiJS Bot v1.0' }, apiOptions.headers);
return fetch(url, { headers }).then(res => res.text());
}
return {
search,
random,
page,
geoSearch,
options,
findById,
find,
allPages,
allCategories,
pagesInCategory,
opensearch,
prefixSearch,
mostViewed,
api: rawApi,
chain,
exportXml
};
}

11
app/node_modules/wikijs/fixup.sh generated vendored Normal file
View File

@@ -0,0 +1,11 @@
cat >dist/cjs/package.json <<!EOF
{
"type": "commonjs"
}
!EOF
cat >dist/mjs/package.json <<!EOF
{
"type": "module"
}
!EOF

373
app/node_modules/wikijs/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,373 @@
// Definitions by: Balazs Mocsai <https://github.com/mbale>
declare module 'wikijs' {
/**
* Default Options
*
* @interface Options
*/
interface Options {
/**
* URL of Wikipedia API
*
* @type {string}
* @memberof Options
*/
apiUrl?: string;
/**
* When accessing the API using a cross-domain AJAX request (CORS), set this to the originating domain.
* This must be included in any pre-flight request, and therefore must be part of the request URI (not the POST body).
* This must match one of the origins in the Origin header exactly, so it has to be set to something like https://en.wikipedia.org or https://meta.wikimedia.org.
* If this parameter does not match the Origin header, a 403 response will be returned.
* If this parameter matches the Origin header and the origin is whitelisted, an Access-Control-Allow-Origin header will be set.
*
* @type {string}
* @memberof Options
*/
origin?: string;
/**
* The Headers sent to be sent along with the request
*
* @type {HeadersInit}
* @memberof Options
*/
headers?: HeadersInit;
}
/**
* Coordinate object
*
* @interface Coordinates
*/
interface Coordinates {
lat: number;
lon: number;
primary: string;
globe: string;
}
/**
* Link object { lang, title }
*
* @interface Link
*/
interface Link {
lang: string;
title: string;
}
/**
* Image container
*
* @interface Image
*/
interface Image {
ns: number;
title: string;
missing: string;
known: string;
imagerepository: string;
imageinfo: object[];
}
interface Result {
results: string[];
query: string;
next(): Promise<Result>;
}
interface RawPage {
pageid: number;
ns: number;
title: string;
touched: string;
lastrevid: number;
counter: number;
length: number;
fullurl: string;
editurl: string;
}
/**
* WikiPage
*
* @interface Page
*/
interface Page {
raw: RawPage;
/**
* Paginated backlinks from page
*
* @param {boolean} aggregated
* @param {number} limit
* @returns {Promise<string[]>}
* @memberof Page
*/
backlinks(aggregated?: boolean, limit?: number): Promise<string[]>;
/**
* Paginated categories from page
*
* @param {boolean} aggregated
* @param {number} limit
* @returns {Promise<string[]>}
* @memberof Page
*/
categories(aggregated?: boolean, limit?: number): Promise<string[]>;
/**
* Text content from page
*
* @returns {Promise<string>}
* @memberof Page
*/
content(): Promise<string>;
/**
* Geographical coordinates from page
*
* @returns {Promise<Coordinates>}
* @memberof Page
*/
coordinates(): Promise<Coordinates>;
/**
* Get full information from page
*
* @returns {Promise<object>}
* @memberof Page
*/
fullInfo(): Promise<object>;
/**
* HTML from page
*
* @returns {Promise<string>}
* @memberof Page
*/
html(): Promise<string>;
/**
* Image URL's from page
*
* info Object contains key/value pairs of infobox data, or specific value if key given
* @returns {Promise<string[]>}
* @memberof Page
*/
images(): Promise<string[]>;
/**
* Get information from page
*
* @param {string} [key]
* Information key. Falsy keys are ignored
* @returns {Promise<object>}
* @memberof Page
*/
info(key?: string): Promise<object>;
/**
* Get list of links to different translations
*
* @returns {Promise<Link[]>}
* @memberof Page
*/
langlinks(): Promise<Link[]>;
/**
* Paginated links from page
*
* @param {boolean} [aggregated]
* return all links (default is true)
* @param {number} [limit]
* number of links per page
* @returns {Promise<string[]>}
* @memberof Page
*/
links(aggregated?: boolean, limit?: number): Promise<string[]>;
/**
* Main image URL from infobox on page
*
* @returns {Promise<string>}
* @memberof Page
*/
mainImage(): Promise<string>;
/**
* Raw content from page
*
* @returns {Promise<string>}
* @memberof Page
*/
rawContent(): Promise<string>;
/**
* Raw data from images from page
*
* @returns {Promise<Image[]>}
* @memberof Page
*/
rawImages(): Promise<Image[]>;
/**
* References from page
*
* @returns {Promise<string[]>}
* @memberof Page
*/
references(): Promise<string[]>;
/**
* Text summary from page
*
* @returns {Promise<string>}
* @memberof Page
*/
summary(): Promise<string>;
/**
* Tables from page
*
* @returns {Promise<any>}
* @memberof Page
*/
tables(): Promise<any>;
/**
* Get URL for wiki page
*
* @return {String}
* @memberof Page
*/
url(): string;
}
/**
* WikiJs is a node.js library which serves as an interface to Wikipedia (or any MediaWiki).
*
* @param {Options} [options]
*/
export default function WikiJS(
options?: Options
): {
/**
* Get Page by PageId
*
* @param {string} pageID
* id of the page
* @returns {Promise<Page>}
*/
findById(pageID: string): Promise<Page>;
/**
* Find page by query and optional predicate
* @example
* wiki.find('luke skywalker').then(page => console.log(page.title));
* @method Wiki#find
* @param {string} search query
* @param {function} [predicate] - testing function for choosing which page result to fetch. Default is first result.
* @return {Promise}
*/
find(query: string, predicate?: (pages: Page[]) => Page): Promise<Page>;
/**
* Geographical Search
*
* @param {number} lat
* latitude
* @param {number} lon
* longitude
* @param {number} [radius]
* search radius in kilometers (default: 1km)
* @returns {Promise<string[]>}
*/
geoSearch(lat: number, lon: number, radius?: number): Promise<string[]>;
/**
* Get Page
*
* @param {string} title
* title of article
* @returns {Promise<Page>}
*/
page(title: string): Promise<Page>;
/**
* Fetch all page titles in wiki
* @method Wiki#allPages
* @return {Array} Array of pages
*/
allPages(): Promise<string[]>;
/**
* Random articles
*
* @param {number} [limit]
* limits the number of random articles
* @returns {Promise<string[]>}
*/
random(limit?: number): Promise<string[]>;
/**
* Search articles
*
* @param {string} query
* keyword query
* @param {number} [limit]
* limits the number of results
* @returns {Promise<Result>}
*/
search(query: string, limit?: number): Promise<Result>;
/**
* Opensearch (mainly used as a backup to normal text search)
* @param {string} query - keyword query
* @param {Number} limit - limits the number of results
* @return {Promise<string[]>} List of page title results
*/
opensearch(query: string, limit?: number): Promise<string[]>;
/**
* Search articles using "fuzzy" prefixsearch
*
* @param {string} query
* keyword query
* @param {number} [limit]
* limits the number of results
* @returns {Promise<Result>}
*/
prefixSearch(query: string, limit?: number): Promise<Result>;
/**
* @summary Find the most viewed pages with counts
* @example
* wiki.mostViewed().then(list => console.log(`${list[0].title}: ${list[0].count}`))
* @method Wiki#mostViewed
* @returns {Promise} - Array of {title,count}
*/
mostViewed(): Promise<{ title: string; count: number }[]>;
/**
* Fetch all page titles in wiki
* @method Wiki#allPages
* @return {Promise<string[]>} Array of pages
*/
allPages(): Promise<string[]>;
/**
* Fetch all categories in wiki
* @method Wiki#allCategories
* @return {Promise<string[]>} Array of categories
*/
allCategories(): Promise<string[]>;
/**
* Fetch all pages in category
* @method Wiki#pagesInCategory
* @param {String} category Category to fetch from
* @return {Promise<string[]>} Array of pages
*/
pagesInCategory(category: string): Promise<string[]>;
};
}

104
app/node_modules/wikijs/package.json generated vendored Normal file
View File

@@ -0,0 +1,104 @@
{
"_from": "wikijs@6.4.1",
"_id": "wikijs@6.4.1",
"_inBundle": false,
"_integrity": "sha512-fnYyT9ISD9hFgAxFJu7Kzsomz48w7FpvvAfTuArvkMQY1bG9JPXoyURqUzYGcQA8FCq6MuZfjqT/6hP8Mh4hQA==",
"_location": "/wikijs",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "wikijs@6.4.1",
"name": "wikijs",
"escapedName": "wikijs",
"rawSpec": "6.4.1",
"saveSpec": null,
"fetchSpec": "6.4.1"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/wikijs/-/wikijs-6.4.1.tgz",
"_shasum": "2e2880b9d4ad2603ecca6b2120c502db57ceeabf",
"_spec": "wikijs@6.4.1",
"_where": "/mnt/c/Users/docto/Downloads/Rappaurio",
"author": {
"name": "Richard van der Dys"
},
"bugs": {
"url": "https://github.com/dijs/wiki/issues"
},
"bundleDependencies": false,
"dependencies": {
"cross-fetch": "^3.0.2",
"hyntax": "^1.1.9",
"infobox-parser": "3.6.2"
},
"deprecated": false,
"description": "Mediawiki interface for Node and Web",
"devDependencies": {
"@pollyjs/adapter-node-http": "^2.5.0",
"@pollyjs/core": "^2.5.0",
"@pollyjs/persister-fs": "^2.1.0",
"coveralls": "^2.11.9",
"eslint": "^4.19.1",
"gh-pages": "^1.0.0",
"istanbul": "^1.0.0-alpha.2",
"jsdoc": "^3.3.0-beta3",
"minami": "^1.1.0",
"mocha": "^10.2.0",
"nock": "^10.0.2",
"prettier": "1.15.3",
"should": "^9.0.0",
"typescript": "^4.9.5"
},
"engines": {
"node": ">=0.10.4"
},
"exports": {
".": {
"import": "./dist/mjs/wiki.js",
"require": "./dist/cjs/wiki.js"
}
},
"funding": {
"type": "individual",
"url": "https://www.buymeacoffee.com/2tmRKi9"
},
"homepage": "https://github.com/dijs/wiki",
"keywords": [
"wiki",
"wikipedia",
"interface",
"search",
"page",
"article",
"node",
"api",
"mediawiki"
],
"license": "MIT",
"main": "dist/cjs/wiki.js",
"module": "dist/mjs/wiki.js",
"name": "wikijs",
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git://github.com/dijs/wiki.git"
},
"scripts": {
"build": "rm -fr dist/* && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && bash fixup.sh",
"cover": "babel-node ./node_modules/istanbul/lib/cli cover node_modules/.bin/_mocha",
"coveralls": "cat ./coverage/lcov.info | coveralls",
"docs": "jsdoc --configure .jsdoc.json --verbose",
"lint": "eslint src",
"publish-docs": "PACKAGE_VERSION=$(cat package.json | grep version | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && gh-pages -d docs/wikijs/$PACKAGE_VERSION ",
"test": "mocha"
},
"type": "module",
"typings": "./index.d.ts",
"version": "6.4.1"
}

24
app/node_modules/wikijs/tsconfig-base.json generated vendored Normal file
View File

@@ -0,0 +1,24 @@
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"baseUrl": "src",
"declaration": true,
"esModuleInterop": true,
"inlineSourceMap": false,
"lib": ["esnext"],
"listEmittedFiles": false,
"listFiles": false,
"moduleResolution": "node",
"noFallthroughCasesInSwitch": true,
"pretty": true,
"resolveJsonModule": true,
"rootDir": "src",
"skipLibCheck": true,
"strict": true,
"traceResolution": false,
},
"compileOnSave": false,
"exclude": ["node_modules", "dist"],
"include": ["src"]
}

8
app/node_modules/wikijs/tsconfig-cjs.json generated vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"extends": "./tsconfig-base.json",
"compilerOptions": {
"module": "commonjs",
"outDir": "dist/cjs",
"target": "es2015"
}
}

8
app/node_modules/wikijs/tsconfig.json generated vendored Normal file
View File

@@ -0,0 +1,8 @@
{
"extends": "./tsconfig-base.json",
"compilerOptions": {
"module": "esnext",
"outDir": "dist/mjs",
"target": "esnext"
}
}