├── .eslintrc.js
├── .github
└── workflows
│ ├── contributors.yml
│ └── main.yml
├── .gitignore
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── docs
├── PAGE.md
├── USAGE.md
├── optionTypes.md
├── resultTypes.md
└── wiki.md
├── jest.config.js
├── package.json
├── source
├── errors.ts
├── index.ts
├── messages.ts
├── optionTypes.ts
├── page.ts
├── request.ts
├── resultTypes.ts
└── utils.ts
├── test
├── categories.test.ts
├── citation.test.ts
├── content.test.ts
├── coordinates.test.ts
├── featuredContent.test.ts
├── html.test.ts
├── images.test.ts
├── index.test.ts
├── infobox.test.ts
├── intro.test.ts
├── langlinks.test.ts
├── links.test.ts
├── media.test.ts
├── mobileHtml.test.ts
├── onThisDay.test.ts
├── pdf.test.ts
├── random.test.ts
├── references.test.ts
├── related.test.ts
├── request.test.ts
├── samples.ts
├── summary.test.ts
├── tables.test.ts
└── utils.test.ts
├── tsconfig.json
└── yarn.lock
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parser: "@typescript-eslint/parser", // Specifies the ESLint parser
3 | plugins: [
4 | "@typescript-eslint/eslint-plugin",
5 | "eslint-plugin-tsdoc"
6 | ],
7 | parserOptions: {
8 | ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features
9 | sourceType: "module" // Allows for the use of imports
10 | },
11 | extends: [
12 | "plugin:@typescript-eslint/recommended" // Uses the recommended rules from the @typescript-eslint/eslint-plugin
13 | ],
14 | rules: {
15 | // Place to specify ESLint rules. Can be used to overwrite rules specified from the extended configs
16 | // e.g. "@typescript-eslint/explicit-function-return-type": "off",
17 | "@typescript-eslint/explicit-module-boundary-types": "off",
18 | "@typescript-eslint/no-explicit-any": "off",
19 | "tsdoc/syntax": "warn"
20 | }
21 | };
--------------------------------------------------------------------------------
/.github/workflows/contributors.yml:
--------------------------------------------------------------------------------
1 | name: contributors
2 | on:
3 | push:
4 | branches:
5 | - master
6 | jobs:
7 | contrib-readme-job:
8 | runs-on: ubuntu-latest
9 | name: A job to automate contrib in readme
10 | steps:
11 | - name: Contribute List
12 | uses: akhilmhdh/contributors-readme-action@v2.3.6
13 | env:
14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: build
2 | on:
3 | push:
4 | branches:
5 | - master
6 | tags:
7 | - '!*' # Do not execute on tags
8 | paths:
9 | - source/*
10 | - test/*
11 | - '*.json'
12 | - package.lock
13 | - .github/workflows/*
14 | pull_request:
15 |
16 | jobs:
17 | build:
18 | name: Node.js ${{ matrix.node-version }}
19 | runs-on: ubuntu-latest
20 | strategy:
21 | fail-fast: false
22 | matrix:
23 | node-version:
24 | - 14
25 | - 16
26 | - 18
27 | steps:
28 | - uses: actions/checkout@v2
29 | - uses: actions/setup-node@v1
30 | with:
31 | node-version: ${{ matrix.node-version }}
32 | - run: yarn
33 | - run: yarn build
34 | coverage:
35 | name: coverage
36 | runs-on: ubuntu-latest
37 | steps:
38 | - uses: actions/checkout@master
39 | - uses: actions/setup-node@master
40 | with:
41 | node-version: '16'
42 | - run: npm install
43 | - run: npm run test
44 | - uses: paambaati/codeclimate-action@v3.2.0
45 | env:
46 | CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
47 | if: env.CC_TEST_REPORTER_ID != null
48 | with:
49 | coverageCommand: yarn test
50 | debug: true
51 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | coverage
4 | test.js
5 | .DS_Store
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at gvind4@gmail.com. All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | We welcome patches and features. There are however a few things that are
4 | required before your pull request can be merged. Make sure you cut a branch
5 | from develop and all PRs pointed towards master.
6 |
7 | # Tests
8 |
9 | ## How to write a new test case
10 |
11 | For any new feature added, we expect a new test case. Since the repo has a 100% code coverage, we expect a success case test and a failure case test for each case. Read up more about why unit testing [here](https://dzone.com/articles/top-8-benefits-of-unit-testing).
12 |
13 | ## Running test cases
14 |
15 | Make sure your PR passes all the tests by running `npm run test` before
16 | raising a PR.
17 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Govind S
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WIKIPEDIA [](https://github.com/dopecodez/Wikipedia/actions) [](https://codeclimate.com/github/dopecodez/Wikipedia/test_coverage) [](https://github.com/dopecodez/Wikipedia/issues) [](https://badge.fury.io/js/wikipedia)
2 |
3 | Wikipedia for node. Works in the browser as well.
4 |
5 | Implements [legacy](https://www.mediawiki.org/wiki/API:Main_page) wiki endpoints and also the newer
6 | [REST API](https://en.wikipedia.org/api/rest_v1/#/).
7 |
8 | Try out the new [`summary()`][9] REST endpoint for a introduction to your page and the main images optimized for browsers and mobile!
9 |
10 | You can also now get the events which happened on a particular day using the [`onThisDay()`][8] api, which supports filtering by [event types][7] as well.
11 |
12 | Built with latest ES6 and native support for async/await and promises.
13 |
14 | Built with TypeScript - exports all the types used.
15 |
16 | # INSTALLATION
17 |
18 | ```
19 | $ npm install wikipedia
20 | ```
21 |
22 | ## Highlights
23 |
24 | - [What can it do](#what-can-it-do)
25 | - [Usage](#Usage)
26 | - [Options](#Options)
27 | - [Result Types](#result-types)
28 | - [Contributing](#contributing)
29 |
30 | For detailed documentation of methods available on `wiki` and `page`,
31 | - [wiki][4]
32 | - [Page][2]
33 |
34 | ## What can it do?
35 |
36 | - Get a summary for a page which contains the intro and main image optimized for web and mobile with the new wikipedia [REST APIs](https://en.wikipedia.org/api/rest_v1/#/)
37 | - Fetch article content
38 | - Find all links/images/categories in a page
39 | - Gets all the relevant events that happened on a particular day. You can further filter this by [event type][7]
40 | - Find related articles from the given article
41 | - Find articles by geographical location
42 | - Get a wikipedia page as a pdf document
43 | - Supports switching languages
44 | - Parses infoboxes using [infobox-parser](https://github.com/dijs/infobox-parser)
45 |
46 | ## Usage
47 |
48 | ```js
49 | const wiki = require('wikipedia');
50 |
51 | (async () => {
52 | try {
53 | const page = await wiki.page('Batman');
54 | console.log(page);
55 | //Response of type @Page object
56 | const summary = await page.summary();
57 | console.log(summary);
58 | //Response of type @wikiSummary - contains the intro and the main image
59 | } catch (error) {
60 | console.log(error);
61 | //=> Typeof wikiError
62 | }
63 | })();
64 | ```
65 | The page method returns a [Page][2] class object which has fields like `pageid`, `title`, `parentid`, `revisionid` and methods like `summary()`, `intro()`, `images()`, `html()` and more.
66 |
67 | All the page methods can take a title parameter or a pageId. Read up on the [Page documentation][2] here to see a detailed overview of the methods available in page.
68 |
69 | You can also call methods like `summary()` on the `wiki` object directly. [Read up here][3] to see when you should use the `page` object and when you should call `summary()` directly. There's a performance difference! Long story short, use the method directly if you are using only the `summary` of the page and are not expecting to use any of the other `page` attributes.
70 |
71 | ```js
72 | const wiki = require('wikipedia');
73 |
74 | (async () => {
75 | try {
76 | const summary = await wiki.summary('Batman');
77 | console.log(summary);
78 | //Response of type @wikiSummary - contains the intro and the main image
79 | } catch (error) {
80 | console.log(error);
81 | //=> Typeof wikiError
82 | }
83 | })();
84 | ```
85 | You can now get the events which happened on a particular day using the new `onThisDay()` api on the wiki object.
86 |
87 | ```js
88 | const wiki = require('wikipedia');
89 |
90 | (async () => {
91 | try {
92 | const events = await wiki.onThisDay();
93 | const deaths = await wiki.onThisDay({type:'deaths', month:'2', day:'28'});
94 | console.log(events); // returns all the events which happened today
95 | console.log(deaths); // returns all deaths which happened on Feb 28
96 | } catch (error) {
97 | console.log(error);
98 | //=> Typeof wikiError
99 | }
100 | })();
101 | ```
102 |
103 | There are other methods like `search()`, `geoSearch()`, `suggest()`, `setLang()`, `setUserAgent()` which should be called on the wiki object directly. Read up on the [wiki documentation][4] to see a complete list of methods available on the wiki default object.
104 |
105 | ```js
106 | const wiki = require('wikipedia');
107 |
108 | (async () => {
109 | try {
110 | const searchResults = await wiki.search('Batma');
111 | console.log(searchResults);
112 | //Response of type @wikiSearchResult - contains results and optionally a suggestion
113 | const newUrl = await wiki.setLang('fr');
114 | console.log(newUrl);
115 | //Returns the api url with language changed - use `languages()` method to see a list of available langs
116 | } catch (error) {
117 | console.log(error);
118 | //=> Typeof wikiError
119 | }
120 | })();
121 | ```
122 |
123 | You can export types or even specific methods if you are using modern ES6 js or TypeScript.
124 | ```js
125 | import wiki from 'wikipedia';
126 | import { wikiSummary, summaryError } from 'wikipedia';
127 | import { summary } from 'wikipedia';
128 |
129 | (async () => {
130 | try {
131 | let summary: wikiSummary; //sets the object as type wikiSummary
132 | summary = await wiki.summary('Batman');
133 | console.log(summary);
134 | let summary2 = await summary('Batman');//using summary directly
135 | } catch (error) {
136 | console.log(error);
137 | //=> Typeof summaryError, helpful in case you want to handle this error separately
138 | }
139 | })();
140 | ```
141 |
142 | ## Options
143 |
144 | All methods have options you can pass them. You can find them in [optionTypes documentation][5].
145 |
146 | ## Result Types
147 |
148 | All the returned result types are documented as well. You can find them [here][6].
149 |
150 | ## Contributing
151 |
152 | Before opening a pull request please make sure your changes follow the [contribution guidelines][1].
153 |
154 |
155 | ## Contributors
156 |
157 | The project would not be the way it is without these rockstars.
158 |
159 |
160 |
234 |
235 |
236 | [1]: https://github.com/dopecodez/wikipedia/blob/master/CONTRIBUTING.md
237 | [2]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md
238 | [3]: https://github.com/dopecodez/wikipedia/blob/master/docs/USAGE.md#when-to-use-page
239 | [4]: https://github.com/dopecodez/wikipedia/blob/master/docs/wiki.md
240 | [5]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md
241 | [6]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md
242 | [7]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#eventOptions
243 | [8]: https://github.com/dopecodez/wikipedia/blob/master/docs/wiki.md#onThisDay
244 | [9]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#summary
245 |
--------------------------------------------------------------------------------
/docs/PAGE.md:
--------------------------------------------------------------------------------
1 | # Page
2 |
3 | ## Highlights
4 |
5 | - [Class Members](#class-members)
6 | - [Functions](#functions)
7 | - [summary()](#summary)
8 | - [intro()](#intro)
9 | - [images()](#images)
10 | - [html()](#html)
11 | - [related()](#related)
12 | - [media()](#media)
13 | - [content()](#content)
14 | - [categories()](#categories)
15 | - [links()](#links)
16 | - [coordinates()](#coordinates)
17 | - [references()](#references)
18 | - [langLinks()](#langLinks)
19 | - [mobileHtml()](#mobileHtml)
20 | - [pdf()](#pdf)
21 |
22 | ## Class Members
23 |
24 | The `Page` class has the following properties:
25 |
26 | ```js
27 | pageid!: number; // id of page
28 | ns!: number;
29 | title!: string; // Title of page
30 | contentmodel!: string;
31 | pagelanguage!: string; // The language of the page
32 | pagelanguagehtmlcode!: string;
33 | pagelanguagedir!: string;
34 | touched!: string;
35 | lastrevid!: number; //The last rev id of the page
36 | length!: number;
37 | fullurl!: string; // The full url of the page
38 | editurl!: string;
39 | canonicalurl!: string;
40 | revid!: number; // The revision id of the page
41 | parentid!: number; // The parent id of the page
42 | _summary!: wikiSummary; // Stores the summary in case it is preloaded or called on the page object earlier
43 | _images!: Array; // Stores the images in case it is preloaded or called on the page object earlier
44 | _content!: string; // Stores the content in case it is preloaded or called on the page object earlier
45 | _html!: string; // Stores the html in case it is preloaded or called on the page object earlier
46 | _categories!: Array; // Stores the categories in case it is preloaded or called on the page object earlier
47 | _references!: Array; // Stores the references in case it is preloaded or called on the page object earlier
48 | _links!: Array; // Stores the links in case it is preloaded or called on the page object earlier
49 | _coordinates!: coordinatesResult; // Stores the coordinates in case it is preloaded or called on the page object earlier
50 | _langLinks!: Array; // Stores the langLinks in case it is preloaded or called on the page object earlier
51 | _infobox!: any; // Stores the infobox in case it is preloaded or called on the page object earlier
52 | _tables!: Array; // Stores the tables in case it is preloaded or called on the page object earlier
53 | _intro!: string; // Stores the intro in case it is preloaded or called on the page object earlier
54 | _related!: Array; // Stores the related info in case it is preloaded or called on the page object earlier
55 | ```
56 |
57 | ## Functions
58 |
59 | The page object has the following methods available on it :
60 |
61 | #### summary()
62 |
63 | Returns the summary for the page as [wikiSummary][2] object. Summary contains the title, page Id, introduction, main image and content urls for the page.
64 |
65 | ```js
66 | summary(pageOptions: pageOptions | undefined): Promise
67 | ```
68 | - @param [pageOptions][1] - the options for the page
69 | - @result[wikiSummary][2] - the summary object for the wiki page
70 |
71 | ```js
72 | //example
73 | const page = await wiki.page('Batman');
74 | const summary = await page.summary({redirect: false});
75 | ```
76 |
77 | #### intro()
78 |
79 | Returns the introduction of the page as string
80 |
81 | ```js
82 | intro(pageOptions: pageOptions | undefined): Promise
83 | ```
84 | - @param [pageOptions][1] - the options for the page
85 |
86 | ```js
87 | //example
88 | const page = await wiki.page('Batman');
89 | const intro = await page.intro({redirect: false});
90 | ```
91 |
92 | #### images()
93 |
94 | Returns the images present in the page.
95 |
96 | **For a main image, use the summary endpoint**
97 |
98 | ```js
99 | images(listOptions: listOptions | undefined): Promise>
100 | ```
101 | - @param [listOptions][3] - the options for the page
102 | - @result [imageResult][4] - the image results for the page
103 |
104 | ```js
105 | //example
106 | const page = await wiki.page('Batman');
107 | const images = await page.images({redirect: true, limit: 5});
108 | ```
109 |
110 | #### html()
111 |
112 | Returns the html content of the page as a string
113 |
114 | ```js
115 | html = async (pageOptions?: pageOptions): Promise
116 | ```
117 | - @param [pageOptions][1] - the options for the page
118 |
119 | ```js
120 | //example
121 | const page = await wiki.page('Batman');
122 | const html = await page.html({redirect: false});
123 | ```
124 |
125 | #### related()
126 |
127 | Returns the related pages given for a a page.
128 |
129 | ```js
130 | related = async (pageOptions?: pageOptions): Promise
131 | ```
132 | - @param [pageOptions][1] - the options for the page
133 | - @result[wikiSummary][2] - the summary object for the wiki page
134 |
135 | ```js
136 | //example
137 | const page = await wiki.page('Batman');
138 | const related = await page.related({redirect: false});
139 | ```
140 |
141 | #### media()
142 |
143 | Gets the list of media items present in the page
144 |
145 | ```js
146 | media = async (pageOptions?: pageOptions): Promise
147 | ```
148 | - @param [pageOptions][1] - the options for the page
149 | - @result[wikiMediaResult][6] - the media result object for the wiki page
150 |
151 | ```js
152 | //example
153 | const page = await wiki.page('Batman');
154 | const media = await page.media({redirect: false});
155 | ```
156 |
157 | #### content()
158 |
159 | Returns the plain text content of a page.
160 |
161 | ```js
162 | content = async (pageOptions?: pageOptions): Promise
163 | ```
164 | - @param [pageOptions][1] - the options for the page
165 |
166 | ```js
167 | //example
168 | const page = await wiki.page('Batman');
169 | const content = await page.content({redirect: false});
170 | ```
171 |
172 | #### categories()
173 |
174 | Returns the categories as an array of string
175 |
176 | ```js
177 | categories = async (listOptions?: listOptions): Promise>
178 | ```
179 | - @param [listOptions][3] - the options for the page
180 |
181 | ```js
182 | //example
183 | const page = await wiki.page('Batman');
184 | const categories = await page.categories({redirect: false, , limit: 5});
185 | ```
186 |
187 | #### links()
188 |
189 | Returns the links present in the page
190 |
191 | ```js
192 | links = async (listOptions?: listOptions): Promise>
193 | ```
194 | - @param [listOptions][3] - the options for the page
195 |
196 | ```js
197 | //example
198 | const page = await wiki.page('Batman');
199 | const links = await page.links({redirect: false, , limit: 5});
200 | ```
201 |
202 | #### references()
203 |
204 | Returns the references and external links in a page.
205 |
206 | ```js
207 | references = async (listOptions?: listOptions): Promise>
208 | ```
209 | - @param [listOptions][3] - the options for the page
210 |
211 | ```js
212 | //example
213 | const page = await wiki.page('Batman');
214 | const references = await page.references({redirect: false, , limit: 5});
215 | ```
216 |
217 | #### coordinates()
218 |
219 | Returns the coordinates of a page
220 |
221 | ```js
222 | coordinates = async (pageOptions?: pageOptions): Promise
223 | ```
224 | - @param [pageOptions][1] - the options for the page
225 | - @result[coordinatesResult][5] - the coordinates result object for the wiki page
226 |
227 | ```js
228 | //example
229 | const page = await wiki.page('Batman');
230 | const coordinates = await page.coordinates({redirect: false});
231 | ```
232 |
233 | #### langLinks()
234 |
235 | Returns the language links present in the page
236 |
237 | ```js
238 | langLinks = async (listOptions?: listOptions): Promise>
239 | ```
240 | - @param [listOptions][3] - the options for the page
241 | - @result[langLinksResult][6] - the langLinks result object
242 |
243 | ```js
244 | //example
245 | const page = await wiki.page('Batman');
246 | const langLinks = await page.langLinks({redirect: false, , limit: 5});
247 | ```
248 |
249 | #### infobox()
250 |
251 | The infobox data(if present), as a JSON object.
252 |
253 | ```js
254 | infobox = async (pageOptions?: pageOptions): Promise
255 | ```
256 | - @param [pageOptions][1] - the options for the page
257 |
258 | ```js
259 | //example
260 | const page = await wiki.page('Batman');
261 | const info = await page.infobox({redirect: false});
262 | ```
263 |
264 | #### tables()
265 |
266 | The tables data in the page, if present as an array of json objects.
267 | ```js
268 | tables = async (pageOptions?: pageOptions): Promise>
269 | ```
270 | - @param [pageOptions][1] - the options for the page
271 |
272 | ```js
273 | //example
274 | const page = await wiki.page('Batman');
275 | const tables = await page.tables({redirect: false});
276 | ```
277 |
278 | ### mobileHtml()
279 |
280 | Returns mobile-optimised HTML for a wiki page, given a title. Follows redirects by default.
281 |
282 | ```js
283 | mobileHtml = async (redirect?: boolean): Promise
284 | ```
285 | - @param redirect - whether to redirect in case of 302
286 |
287 | ```js
288 | const page = await wiki.page('John_Locke');
289 | const htmlJohnLocke = page.mobileHtml();
290 | console.log(htmlJohnLocke); // displays HTML for John Locke's wiki page
291 | const page = await wiki.page('Disco_Stu');
292 | const htmlDiscoStu = page.mobileHtml("Disco_Stu");
293 | console.log(htmlDiscoStu); // redirects to List of recurring The Simpsons characters
294 | const page = await wiki.page('Disco_Stu', {redirect: false});
295 | console.log(page); // no result, as redirect is false
296 | ```
297 |
298 | ### pdf()
299 |
300 | Returns the wikipedia link to pdf. Valid `format` are `a4`. `letter`, `legal`. Valid `type` are `desktop`, `mobile`.(by default fetches `a4` for `desktop`).
301 |
302 | ```js
303 | pdf = async (pdfOptions?: pdfOptions): Promise
304 | ```
305 | - @param [pdfOptions][7] - the options for the pdf
306 |
307 | ```js
308 | //example
309 | const page = await wiki.page('Batman');
310 | const pdf = await page.pdf({type:'mobile', format: 'legal'});
311 | ```
312 |
313 | [1]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#pageOptions
314 | [2]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiSummary
315 | [3]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#listOptions
316 | [4]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#imageResult
317 | [5]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#coordinatesResult
318 | [5]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#langLinksResult
319 | [6]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiMediaResult
320 | [7]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#pdfOptions
321 |
--------------------------------------------------------------------------------
/docs/USAGE.md:
--------------------------------------------------------------------------------
1 | # Usage Recommendations
2 |
3 | ## Highlights
4 |
5 | - [When to use page](#when-to-use-page)
6 |
7 | ## When to use page
8 |
9 | All the page functions like `summary()`, `images()`, `html()`(and the rest!) can be called directly from the `wiki` object. Note here that both the functions will output the same result!
10 |
11 | ```js
12 | const wiki = require('wikipedia');
13 |
14 | (async () => {
15 | try {
16 | const page = await wiki.page('Batman');
17 | console.log(response);
18 | //Response of type @Page object
19 | const summaryThroughPage = await page.summary();
20 | console.log(summary);
21 | const summaryWithoutPage = await wiki.summary('Batman');
22 | console.log(summary);
23 | // summaryThroughPage = summaryWithoutPage
24 | //Response of type @wikiSummary - contains the intro and the main image
25 | } catch (error) {
26 | console.log(error);
27 | //=> Typeof wikiError
28 | }
29 | })();
30 | ```
31 | Internally, if you call the function directly on the `wiki` object, theres only one API being called while if you call the `page()` and then `summary()`, it'll be two APIs called.
32 |
33 | **When to use the `page()` method?** Only use the `page()` method if you are going to use multiple attributes in the same page. Once you have a `Page` object, the loading of fields in this will be faster, so make sure you're using `page()` if you want to use multiple attributes within a page. Page objects are also helpful in case you want to `preload` some fields, and get the attributes you want to use along with the page object itself.
34 |
35 |
--------------------------------------------------------------------------------
/docs/optionTypes.md:
--------------------------------------------------------------------------------
1 | # Input Options
2 |
3 | ## Highlights
4 |
5 | - [pageOptions](#pageOptions)
6 | - [listOptions](#listOptions)
7 | - [searchOptions](#searchOptions)
8 | - [geoOptions](#geoOptions)
9 | - [eventOptions](#eventOptions)
10 | - [fcOptions](#fcOptions)
11 | - [pdfOptions](#pdfOptions)
12 | - [autocompletionOptions](#autocompletionoptions)
13 |
14 | ### pageOptions
15 |
16 | ```js
17 | interface pageOptions {
18 | autoSuggest?: boolean
19 | redirect?: boolean
20 | preload?: boolean
21 | fields?: Array
22 | }
23 | ```
24 | The options for page methods on `Page` or `wiki`. Generally, can be used for all page methods which do not return a array.
25 |
26 | - `redirect : boolean`(default = true) - redirect in case wikipedia returns a 304. **This is the only field that is applicable to any method called on a [Page][1] object**.
27 | - `autoSuggest : boolean`(default = false) - suggest a page title which is reccomened by wikipedia for given string. Useful in case you are using user input to get details for a page.
28 |
29 | The other two fields are only applicable if added on the `wiki.page('title')` method, otherwise its ignored.
30 |
31 | - `preload : boolean`(default = false) - When used with fields, it can preload any fields for the page(Loads summary by default if used without `fields` argument). This is helpful in case you want the whole loading to take place in one single step instead of calling each field when required.
32 | - `fields : string[]` - Accepts a array of string which should a combination the functions available on page(Accepted values are combinations of: 'summary','images','intro','html,'content','categories','links','references','coordinates','langLinks','infobox','tables','related').
33 |
34 | ### listOptions
35 |
36 | ```js
37 | interface listOptions {
38 | autoSuggest?: boolean
39 | redirect?: boolean
40 | limit?: number
41 | }
42 | ```
43 | The options for page methods on `Page` or `wiki`. Generally, can be used for all page methods which return an array
44 |
45 | - `autoSuggest : boolean`(default = false) - suggest a page title which is reccomened by wikipedia for given search string*
46 | - `redirect : boolean`(default = true) - redirect in case wikipedia returns a 304
47 | - `limit : number`(default = 10) - Use this to increase/decrease number of results in the returned array
48 |
49 | ### searchOptions
50 |
51 | ```js
52 | interface searchOptions {
53 | limit?: number // the number of results
54 | suggestion?: boolean // Loads the autosuggested value along with search results
55 | }
56 | ```
57 | - `limit : number`(default = 10) - Use this to increase/decrease number of results in the returned search result array
58 | - `suggestion: boolean`(default=false) - If set to true, returns the auto suggested page along with search results
59 |
60 | ### geoOptions
61 | ```js
62 | interface geoOptions {
63 | limit?: number
64 | radius?: number
65 | }
66 | ```
67 | - `limit : number`(default = 10) - Use this to increase/decrease number of results in the returned geo result array
68 | - `radius: number`(default = 1000) - Search radius in meters
69 |
70 | ### eventOptions
71 | ```js
72 | interface eventOptions {
73 | type?: eventTypes,
74 | month?: string,
75 | day?: string
76 | }
77 | ```
78 | The options for the onThisDay function on wiki object.
79 |
80 | - `type : eventTypes`(default = all) - Accepts types of valid events on the wikipedia Rest API. Events can be one of `all`, `selected`, `births`, `deaths`, `events`, `holidays`.
81 | - `month : string`(default = date.getMonth()) - Use this to pass the month you want as a string. By default, it will take current month.
82 | - `day : string`(default = date.getDay()) - Use this to pass the day you want as a string. By default, it will take current day.
83 |
84 | ### fcOptions
85 | ```js
86 | interface fcOptions {
87 | year?: string,
88 | month?: string,
89 | day?: string
90 | }
91 | ```
92 | The options for the featured content function on wiki object.
93 |
94 | - `year : string`(default = date.getYear()) - Use this to pass the year you want as a string. By default, it will take current year.
95 | - `month : string`(default = date.getMonth()) - Use this to pass the month you want as a string. By default, it will take current month.
96 | - `day : string`(default = date.getDay()) - Use this to pass the day you want as a string. By default, it will take current day.
97 |
98 | ### pdfOptions
99 | ```js
100 | interface pdfOptions {
101 | autoSuggest?: boolean
102 | format?: format
103 | type?: pdfType
104 | }
105 | ```
106 | The options for the onThisDay function on wiki object.
107 |
108 | - `type : pdfType`(default = a4) - type can be one of `a4`, `letter`, `legal`.
109 | - `format : format`(default = desktop) - format can be `desktop` or `mobile`.
110 | - `autoSuggest : boolean`(default = false) - suggest a page title which is reccomened by wikipedia for given search string*
111 |
112 | ### autocompletionOptions
113 | ```js
114 | interface autocompletionOptions {
115 | limit?: number
116 | }
117 | ```
118 | The options for the autocompletions function on wiki object.
119 |
120 | - `limit : number`(default = 10) - Use this to increase/decrease number of results in the returned array
121 |
122 | [1]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#functions
--------------------------------------------------------------------------------
/docs/resultTypes.md:
--------------------------------------------------------------------------------
1 | # Result Types
2 |
3 | ## Highlights
4 |
5 | - [wikiSummary](#wikiSummary)
6 | - [imageResult](#imageResult)
7 | - [coordinatesResult](#coordinatesResult)
8 | - [langLinksResult](#langLinksResult)
9 | - [wikiSearchResult](#wikiSearchResult)
10 | - [geoSearchResult](#geoSearchResult)
11 | - [languageResult](#languageResult)
12 | - [wikiMediaResult](#wikiMediaResult)
13 | - [eventResult](#eventResult)
14 | - [fcResult](#fcResult)
15 | - [relatedResult](#relatedResult)
16 | - [titleItem](#titleItem)
17 | - [mobileSections](#mobileSections)
18 |
19 | ### wikiSummary
20 |
21 | The wiki summary for the page.
22 |
23 | ```js
24 | interface wikiSummary {
25 | type: string,
26 | title: string, // title of the page
27 | displaytitle: string, // title of the page
28 | namespace: { id: number, text: string },
29 | wikibase_item: string,
30 | titles: { canonical: string, normalized: string, display: string },
31 | pageid: number, // page Id
32 | thumbnail: { // Thumbnail for the page
33 | source: string,
34 | width: number,
35 | height: number
36 | },
37 | originalimage: {
38 | source: string,
39 | width: number,
40 | height: number
41 | },
42 | lang: string,
43 | dir: string,
44 | revision: string,
45 | tid: string,
46 | timestamp: string,
47 | description: string,
48 | description_source: string,
49 | content_urls: { // The urls will be here
50 | desktop: {
51 | page: string,
52 | revisions: string,
53 | edit: string,
54 | talk: string
55 | },
56 | mobile: {
57 | page: string,
58 | revisions: string,
59 | edit: string,
60 | talk: string
61 | }
62 | },
63 | extract: string,
64 | extract_html: string,
65 | normalizedtitle?: string,
66 | coordinates?: {
67 | lat: number,
68 | lon: number
69 | }
70 | }
71 | ```
72 |
73 | ### imageResult
74 |
75 | The image result for the page.
76 |
77 | ```js
78 | interface imageResult {
79 | pageid: number,
80 | ns: number,
81 | title: string,
82 | imagerepository: string,
83 | imageinfo: any,
84 | url: string // This will contain the image url
85 | }
86 | ```
87 |
88 | ### coordinatesResult
89 |
90 | The coordinates result.
91 | ```js
92 | interface coordinatesResult {
93 | lat: number //latitude
94 | lon: number, //longitude
95 | primary: string,
96 | globe: string // The globe ie Earth!
97 | }
98 | ```
99 |
100 | ### langLinksResult
101 |
102 | The lang links result
103 |
104 | ```js
105 | interface langLinksResult {
106 | lang: string, //language code
107 | title: string, // The title of the page
108 | url: string // url of the page
109 | }
110 | ```
111 |
112 | ### wikiSearchResult
113 |
114 | The search result. The autosuggest will be populated or null based on input params.
115 |
116 | ```js
117 | interface wikiSearchResult {
118 | results: any[], // the search results as an array
119 | suggestion: string // the suggestion string if suggestion option is set to true
120 | }
121 | ```
122 | ### geoSearchResult
123 |
124 | The geosearch result.
125 |
126 | ```js
127 | interface geoSearchResult {
128 | pageid: number, // the page id. use this or title for further requests
129 | ns: number,
130 | title: string, // the title. use this or pageid for further requests
131 | lat: number, // the page latitude
132 | lon: number, // the page longitude
133 | dist: number,
134 | primary: string,
135 | type: string // the type of the page eg: city, museum
136 | }
137 | ```
138 | ### languageResult
139 |
140 | ```js
141 | interface languageResult {
142 | [key: string]: string // key will be the language code to be used in setLang(key), and the value will be the full url
143 | }
144 | ```
145 |
146 | ### wikiMediaResult
147 |
148 | ```js
149 | interface wikiMediaResult {
150 | revision: string, // the revision id of the page
151 | tid: string,
152 | items: Array // contains an array of media results
153 | }
154 |
155 | interface mediaResult {
156 | title: string, // title of image
157 | section_id: number, // section where image is present
158 | type: string, // type of media - can be image, video, or audio
159 | caption?: { // will be undefined for the infobox images
160 | html: string, // the html of the caption
161 | text: string // the text you probably want to use
162 | },
163 | showInGallery: boolean,
164 | srcset: Array // this contains the url for the media
165 | }
166 |
167 | interface srcResult {
168 | src: string, // the url for the media
169 | scale: string
170 | }
171 | ```
172 |
173 | ### eventResult
174 |
175 | The result for the `onThisDay` function call.
176 | ```js
177 | interface eventResult {
178 | births?: [
179 | {
180 | text: string,
181 | pages: Array,
182 | year?: number
183 | }
184 | ],
185 | deaths?: [
186 | {
187 | text: string,
188 | pages: Array,
189 | year?: number
190 | }
191 | ],
192 | events?: [
193 | {
194 | text: string,
195 | pages: Array,
196 | year?: number
197 | }
198 | ],
199 | holidays?: [
200 | {
201 | text: string,
202 | pages: Array
203 | }
204 | ],
205 | selected?: [
206 | {
207 | text: string,
208 | pages: Array,
209 | year?: number
210 | }
211 | ]
212 | }
213 | ```
214 |
215 | ### fcResult
216 |
217 | The result for the `featuredContent` function call.
218 | ```js
219 | interface fcResult {
220 | tfa: wikiSummary;
221 | mostread: {
222 | date: string;
223 | articles: Array
224 | };
225 | image: {
226 | title: string;
227 | thumbnail: {
228 | source: string;
229 | width: number;
230 | height: number;
231 | };
232 | image: {
233 | source: string;
234 | width: number;
235 | height: number;
236 | };
237 | file_page: string;
238 | artist: Artist;
239 | credit: htmlText;
240 | license: {
241 | type: string;
242 | code: string;
243 | };
244 | description: Description;
245 | wb_entity_id: string;
246 | structured: {
247 | captions: {
248 | [key: string]: string;
249 | }
250 | };
251 | };
252 | news: [
253 | {
254 | links: Array;
255 | story: string;
256 | }
257 | ];
258 | onthisday: [
259 | {
260 | text: string;
261 | pages: Array;
262 | year: number;
263 | }
264 | ]
265 | }
266 | ```
267 |
268 | ### relatedResult
269 |
270 | The related result.
271 | ```js
272 | interface relatedResult {
273 | pages: Array
274 | }
275 | ```
276 |
277 | ### titleItem
278 |
279 | The title item object for the page
280 | ```js
281 | interface titleItem {
282 | title: string,
283 | page_id: number,
284 | rev: number,
285 | tid: number,
286 | namespace: number,
287 | user_id: number,
288 | user_text: string,
289 | timestamp: string,
290 | comment: string,
291 | tags: Array,
292 | restrictions: Array,
293 | page_language: string,
294 | redirect: boolean
295 | }
296 |
297 | // The result for the random titles query
298 | interface title {
299 | items: Array
300 | }
301 | ```
302 |
303 | ### mobileSections
304 |
305 | The mobile sections for the page
306 |
307 | ```js
308 | interface mobileSections {
309 | lead: {
310 | ns: number,
311 | id: number,
312 | revision: string,
313 | lastmodified: string,
314 | lastmodifier: {
315 | user: string,
316 | gender: string
317 | },
318 | displaytitle: string,
319 | normalizedtitle: string,
320 | wikibase_item: string,
321 | description: string,
322 | description_source: string,
323 | protection: Record,
324 | editable: boolean,
325 | languagecount: number,
326 | image: {
327 | file: string,
328 | urls: {
329 | 320: string,
330 | 640: string,
331 | 800: string,
332 | 1024: string
333 | }
334 | },
335 | issues: Array,
336 | geo?: {
337 | latitude: string,
338 | longitude: string
339 | }
340 | sections: Array
341 | },
342 | remaining: {
343 | sections: Array
344 | }
345 | }
346 |
347 | interface section {
348 | id: number,
349 | text: string,
350 | toclevel: number,
351 | line: string,
352 | anchor: string
353 | }
354 | ```
--------------------------------------------------------------------------------
/docs/wiki.md:
--------------------------------------------------------------------------------
1 | # Wiki
2 |
3 | ## Highlights
4 |
5 | - [Functions](#functions)
6 | - [search()](#search)
7 | - [page()](#page)
8 | - [geoSearch()](#geoSearch)
9 | - [onThisDay()](#onThisDay)
10 | - [featuredContent()](#featuredContent)
11 | - [languages()](#languages)
12 | - [setLang()](#setLang)
13 | - [setUserAgent()](#setUserAgent)
14 | - [suggest()](#suggest)
15 | - [random()](#random)
16 | - [citation()](#citation)
17 | - [Page Methods](#page-methods)
18 |
19 | ## Functions
20 |
21 | ### search()
22 |
23 | Returns the search result for the input string as [wikiSearchResult][2] object. Accepts two inputs, the first the query string and the second a [searchOptions][1] object.
24 |
25 | ```js
26 | search = async (query: string, searchOptions?: searchOptions): Promise
27 | ```
28 | - @param query - The string you want to search for. This is required.
29 | - @param [searchOptions][1] - the options for the page
30 | - @result[wikiSearchResult][2] - the summary object for the wiki page
31 |
32 | ```js
33 | //example
34 | const searchResults = await wiki.search('Batma', {suggestion: true, limit: 10});
35 | console.log(searchResults.results) // The search results
36 | console.log(searchResults.suggestion) // Suggestion string if suggestion set to true, null otherwise.
37 | ```
38 |
39 | ### page()
40 |
41 | The main page method for the wiki. The title param can be either a string or a pageId. Returns a [Page][4] object which can be used to call any of the page methods. Use the `preload` and `fields` object present in [pageOptions][3] if you want to load multiple attributes of a page together.
42 |
43 | ```js
44 | page = async (title: string, pageOptions?: pageOptions): Promise
45 | ```
46 | - @param title - The title or pageId of the page. This is required.
47 | - @param [pageOptions][3] - the options for the page
48 | - @result[Page][4] - the summary object for the wiki page
49 |
50 | ```js
51 | //example
52 | const page = await wiki.page('Batman', {autoSuggest: true, preload:true, fields:["summary", "html"]});
53 | const summary = await page.summary(); // Does not call API, returns summary immediately as it is preloaded
54 | ```
55 | ### onThisDay()
56 |
57 | Returns the events that happened on a day depending on input `type`, `month`, `day` arguments. Type can be any one of the ones defined in [eventOptions][23]. By default, it will return all events that happened on the current day. All options are documented in the [eventOptions][23] object. Returns a array of [eventResult][24] object which internally has arrays of [wikiSummary][22].
58 |
59 | ```js
60 | onThisDay = async ({type: string, month: string, day: string}): Promise
61 | ```
62 | - @param type - Any one of the valid event types. By default, `all`.
63 | - @param month - The month to search for. Takes current month by default.
64 | - @param day - The day to search for. Takes current day by default.
65 | - @result[eventResult][24] - a eventResult object.
66 |
67 | ```js
68 | //example
69 | const events = await wiki.onThisDay();
70 | const deaths = await wiki.onThisDay({type:'deaths', month:'2', day:'28'});
71 | console.log(events); // returns all the events which happened today
72 | console.log(deaths); // returns all deaths which happened on Feb 28
73 | ```
74 |
75 | ### featuredContent()
76 |
77 | Returns featured content of a given day, depending on input `year`, `month`, `day` arguments. By default, it will return featured content of the current day. Returns a array of [fcResult][27] object.
78 |
79 | ```js
80 | featuredContent = async ({year: string, month: string, day: string}): Promise
81 | ```
82 | - @param year - The year to search for. Takes current year by default.
83 | - @param month - The month to search for. Takes current month by default.
84 | - @param day - The day to search for. Takes current day by default.
85 | - @result [fcResult][27] - a fcResult object.
86 |
87 | ```js
88 | //example
89 | const content = await wiki.featuredContent();
90 | const contentNewYear2020 = await wiki.featuredContent({year:'2020', month:'01', day:'01'});
91 | const contentNewYear = await wiki.featuredContent({month:'01', day:'01'});
92 | console.log(content); // returns featured content from today
93 | console.log(contentNewYear2020); // returns featured content from 2020-01-01
94 | console.log(contentNewYear); // returns featured content from 01-01 of this year
95 | ```
96 |
97 | ### geoSearch()
98 |
99 | Searches for a page based on input `latitude`, `longitude` coordinates. Optionally takes a `limit` and `radius`(the search radius in meters) parameter in the [geoOptions][5] object. Returns an array of [geoSearchResult][6] object.
100 |
101 | ```js
102 | geoSearch = async (latitude: number, longitude: number, geoOptions?: geoOptions): Promise>
103 | ```
104 | - @param latitude - The latitude to search for. This is required.
105 | - @param longitude - The longitude to search for. This is required.
106 | - @param [geoOptions][5] - the options for the geo search.
107 | - @result[geoSearchResult][6] - an array of geoSearchResult object.
108 |
109 | ```js
110 | //example
111 | const geoResult = await wiki.geoSearch(2.088, 4.023, { radius: 5000, limit: 20 });
112 | console.log(geoResult[0]); // the closest page to given coordinates
113 | ```
114 |
115 | ### languages()
116 |
117 | The array of languages available in wikipedia. Mainly meant for use before [setLang](#setLang) to check if the language is available before actually setting it. Returns an array of [languageResult][7] object.
118 |
119 | ```js
120 | languages = async (): Promise>
121 | ```
122 | - @result[languageResult][6] - an array of languageResult object.
123 |
124 | ```js
125 | //example
126 | const languages = await wiki.languages();
127 | ```
128 |
129 | ### setLang()
130 |
131 | Uses the input language code to set language for the wikimedia and the REST APIs. This is useful in case you want to switch languages while using wikipedia.
132 |
133 | ```js
134 | setLang = (language: string): string
135 | ```
136 | - @param language - The language code for the wiki.
137 | - @result Returns the new wikimedia url as string.
138 |
139 | ```js
140 | //example
141 | const changedLang = await wiki.setLang('fr'); // sets language to french
142 | ```
143 |
144 | ### setUserAgent()
145 |
146 | Changes the user agent used in the request to wikipedia from 'wikipedia (https://github.com/dopecodez/Wikipedia/)' to the string passed.
147 | As per the wikipedia docs - Set a unique userAgent header that allows us to contact you quickly. Email addresses or URLs of contact pages work well. Check https://meta.wikimedia.org/wiki/User-Agent_policy for more info.
148 |
149 | ```js
150 | setUserAgent = (userAgent: string)
151 | ```
152 | - @param language - The language code for the wiki.
153 | - @result null
154 |
155 | ```js
156 | //example
157 | await wiki.setUserAgent('Govind (gvind4@gmail.com)'); // sets userAgent to this value
158 | ```
159 |
160 | ### suggest()
161 |
162 | Returns the wiki suggestion for a given query string. This method returns null if no suggestion was returned.
163 |
164 | ```js
165 | suggest = async (query: string): Promise
166 | ```
167 | - @param query - The query string.
168 | - @result the suggestion or null if no suggestion present.
169 |
170 | ```js
171 | //example
172 | const suggestion = await wiki.suggest('Batma');
173 | console.log(suggestion); //Returns 'Batman'
174 | ```
175 |
176 | ### random()
177 |
178 | Returns a random wiki page in any of the available formats. Formats can be `summary`, `title`, `related`, `mobile-sections` or `mobile-sections-lead`. Defaults to summary.
179 |
180 | ```js
181 | random = async (format?: randomFormats): Promise
182 | ```
183 | - @param format - the format for the random page
184 | - @result the random page in requested format
185 |
186 | ```js
187 | //example
188 | const randomSummary = await wiki.random();
189 | console.log(random); //Returns wikiSummary of a random pageOption
190 | const randomMobileSections = await wiki.random("mobile-sections");
191 | console.log(randomMobileSections); // Returns random mobile sections for a page
192 | ```
193 | ### citation
194 |
195 | Generates citation data given a URL, DOI, PMID, ISBN, or PMCID. Defaults to mediawiki format. Format can be 'mediawiki', 'mediawiki-basefields', 'zotero', 'bibtex', 'wikibase'.
196 |
197 | ```js
198 | citation = async (query: string, format?: citationFormat, language?: string): Promise
199 | ```
200 | - @param query - url or query string
201 | - @param format - the format of the citation result
202 | - @param language - if you want lanuage enabled results
203 | - @returns Returns citation data
204 |
205 | ```js
206 | //example
207 | const citation = await wiki.citation("batman");
208 | console.log(random); //Returns citations in an array
209 | const citationsWiki = await wiki.citation("test", "mediawiki", "fr") ;
210 | console.log(citationsWiki); // Returns citations in mediawiki format
211 | ```
212 |
213 | #### autocompletions()
214 |
215 | Returns the autocompletions of a given title
216 |
217 | ```js
218 | autocompletions = async (autocompletionOptions?: autocompletionOptions): Promise>
219 | ```
220 | - @param [autocompletionOptions][28] - the options for the autocompletions
221 |
222 | ```js
223 | //example
224 | const autocompletions = await wiki.autocompletions({limit: 20});
225 | ```
226 |
227 | ### Page Methods
228 |
229 | All the methods defined in the [Page][4] documentation can be called directly from the wiki object as well. This includes [summary()][8], [images()][9], [intro()][10], [html()][11], [related()][12], [content()][13], [categories()][14], [links()][15], [references()][16], [coordinates()][17], [langLinks()][18], [infobox()][19], [mobileHtml()][25], [pdf()][26] and [tables()][20].
230 |
231 | **Read up [here][21] to understand when you should use these methods directly and when you should use the page methods**.
232 | Also, note that if called directly from the wiki object, you can use the `autoSuggest` option present in the [pageOptions][3] object which will be ignored if called through page.
233 | ```js
234 | //example
235 | const summary = await wiki.summary('Batma', {autoSuggest:true});
236 | console.log(summary); //Returns summary for 'Batman'
237 | const html = await wiki.summary('David Attenborough');
238 | console.log(html); //Returns html for the environmentalist
239 | ```
240 |
241 | [1]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#searchOptions
242 | [2]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiSearchResult
243 | [3]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#pageOptions
244 | [4]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md
245 | [5]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#geoOptions
246 | [6]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#geoSearchResult
247 | [7]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#languageResult
248 | [8]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#summary
249 | [9]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#images
250 | [10]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#intro
251 | [11]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#html
252 | [12]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#related
253 | [13]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#content
254 | [14]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#categories
255 | [15]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#links
256 | [16]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#references
257 | [17]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#coordinates
258 | [18]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#langLinks
259 | [19]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#infobox
260 | [20]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#tables
261 | [21]: https://github.com/dopecodez/wikipedia/blob/master/docs/USAGE.md#when-to-use-page
262 | [22]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#wikiSummary
263 | [23]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#eventOptions
264 | [24]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#eventResult
265 | [25]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#mobileHtml
266 | [26]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#pdf
267 | [27]: https://github.com/dopecodez/wikipedia/blob/master/docs/resultTypes.md#fcResult
268 | [28]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#autocompletionOptions
269 |
270 |
271 |
272 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | testEnvironment: 'node',
5 | transform: {
6 | '^.+\\.tsx?$': ['ts-jest', {
7 | isolatedModules: true,
8 | }]
9 | },
10 | testRegex: './test/.+\\.test\\.ts$',
11 | collectCoverage: false,
12 | collectCoverageFrom: ['source/*.{js,jsx,ts,tsx}'],
13 | moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
14 | coverageReporters: ['text-summary', 'lcov'],
15 | };
16 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "wikipedia",
3 | "version": "2.1.2",
4 | "description": "A JavaScript wrapper for the wikipedia apis",
5 | "main": "dist",
6 | "engines": {
7 | "node": ">=10"
8 | },
9 | "scripts": {
10 | "prepublishOnly": "tsc --build --clean && tsc",
11 | "test": "jest --coverage",
12 | "build": "yarn lint && tsc --build --clean && tsc",
13 | "prepare": "yarn build",
14 | "lint": "eslint source/*.ts",
15 | "release": "np"
16 | },
17 | "author": "Govind S",
18 | "license": "MIT",
19 | "homepage": "https://github.com/dopecodez/wikipedia#README",
20 | "repository": {
21 | "type": "git",
22 | "url": "git://github.com/dopecodez/wikipedia.git"
23 | },
24 | "devDependencies": {
25 | "@types/infobox-parser": "^3.3.1",
26 | "@types/jest": "^29.2.4",
27 | "@types/node": "^18.11.17",
28 | "@typescript-eslint/eslint-plugin": "^5.47.0",
29 | "@typescript-eslint/parser": "^5.47.0",
30 | "eslint": "^8.30.0",
31 | "eslint-plugin-tsdoc": "^0.2.17",
32 | "jest": "^29.3.1",
33 | "ts-jest": "^29.0.3",
34 | "typescript": "^4.9.4"
35 | },
36 | "files": [
37 | "dist"
38 | ],
39 | "types": "dist/",
40 | "dependencies": {
41 | "axios": "^1.4.0",
42 | "infobox-parser": "^3.6.2"
43 | },
44 | "keywords": [
45 | "wiki",
46 | "wikipedia",
47 | "wikimedia",
48 | "encyclopedia",
49 | "jest",
50 | "node-wiki",
51 | "wiki-node"
52 | ]
53 | }
54 |
--------------------------------------------------------------------------------
/source/errors.ts:
--------------------------------------------------------------------------------
1 | export class wikiError extends Error {
2 | code?: string;
3 | constructor(message: string, code?: string) {
4 | super(message);
5 | this.name = 'wikiError';
6 | this.code = code;
7 | }
8 | }
9 |
10 | export class searchError extends wikiError {
11 | constructor(message: string) {
12 | super(message);
13 | this.name = 'searchError';
14 | }
15 | }
16 |
17 | export class autocompletionsError extends wikiError {
18 | constructor(message: string) {
19 | super(message);
20 | this.name = 'autocompletionsError';
21 | }
22 | }
23 |
24 |
25 | export class pageError extends wikiError {
26 | constructor(message: string) {
27 | super(message);
28 | this.name = 'pageError';
29 | }
30 | }
31 |
32 | export class summaryError extends wikiError {
33 | constructor(message: string) {
34 | super(message);
35 | this.name = 'summaryError';
36 | }
37 | }
38 |
39 | export class imageError extends wikiError {
40 | constructor(message: string) {
41 | super(message);
42 | this.name = 'imageError';
43 | }
44 | }
45 |
46 | export class htmlError extends wikiError {
47 | constructor(message: string) {
48 | super(message);
49 | this.name = 'htmlError';
50 | }
51 | }
52 |
53 | export class contentError extends wikiError {
54 | constructor(message: string) {
55 | super(message);
56 | this.name = 'contentError';
57 | }
58 | }
59 |
60 | export class categoriesError extends wikiError {
61 | constructor(message: string) {
62 | super(message);
63 | this.name = 'categoriesError';
64 | }
65 | }
66 |
67 | export class linksError extends wikiError {
68 | constructor(message: string) {
69 | super(message);
70 | this.name = 'linksError';
71 | }
72 | }
73 |
74 | export class geoSearchError extends wikiError {
75 | constructor(message: string) {
76 | super(message);
77 | this.name = 'geoSearchError';
78 | }
79 | }
80 |
81 | export class coordinatesError extends wikiError {
82 | constructor(message: string) {
83 | super(message);
84 | this.name = 'coordinatesError';
85 | }
86 | }
87 |
88 | export class infoboxError extends wikiError {
89 | constructor(message: string) {
90 | super(message);
91 | this.name = 'infoboxError';
92 | }
93 | }
94 |
95 | export class preloadError extends wikiError {
96 | constructor(message: string) {
97 | super(message);
98 | this.name = 'preloadError';
99 | }
100 | }
101 |
102 | export class introError extends wikiError {
103 | constructor(message: string) {
104 | super(message);
105 | this.name = 'introError';
106 | }
107 | }
108 |
109 | export class relatedError extends wikiError {
110 | constructor(message: string) {
111 | super(message);
112 | this.name = 'relatedError';
113 | }
114 | }
115 |
116 | export class mediaError extends wikiError {
117 | constructor(message: string) {
118 | super(message);
119 | this.name = 'mediaError';
120 | }
121 | }
122 |
123 | export class eventsError extends wikiError {
124 | constructor(message: string) {
125 | super(message);
126 | this.name = 'eventsError';
127 | }
128 | }
129 |
130 | export class fcError extends wikiError {
131 | constructor(message: string) {
132 | super(message);
133 | this.name = 'featuredContentError';
134 | }
135 | }
136 |
137 | export class pdfError extends wikiError {
138 | constructor(message: string) {
139 | super(message);
140 | this.name = 'pdfError';
141 | }
142 | }
143 |
144 | export class citationError extends wikiError {
145 | constructor(message: string) {
146 | super(message);
147 | this.name = 'citationError';
148 | }
149 | }
--------------------------------------------------------------------------------
/source/index.ts:
--------------------------------------------------------------------------------
1 | import request, { makeRestRequest, setAPIUrl, setUserAgent } from './request'
2 | import { pageOptions, searchOptions, geoOptions, listOptions, eventOptions, fcOptions, randomFormats, pdfOptions, citationFormat, autocompletionOptions } from './optionTypes';
3 | import Page, {
4 | intro, images, html, content, categories, links, coordinates, langLinks,
5 | references, infobox, tables, summary, related, media, mobileHtml, pdf, citation
6 | } from './page';
7 | import { coordinatesResult, eventResult, featuredContentResult, geoSearchResult, imageResult, langLinksResult, languageResult,
8 | mobileSections, relatedResult,
9 | title, wikiMediaResult, wikiSearchResult, wikiSummary, notFound } from './resultTypes';
10 | import {
11 | categoriesError,
12 | contentError, coordinatesError, eventsError, fcError, geoSearchError, htmlError, imageError, infoboxError,
13 | introError, linksError, mediaError, pageError, relatedError, searchError, summaryError, wikiError,
14 | pdfError,
15 | citationError,
16 | autocompletionsError
17 | } from './errors';
18 | import { MSGS } from './messages';
19 | import { getCurrentDay, getCurrentMonth, getCurrentYear, setPageId, setPageIdOrTitleParam, setTitleForPage } from './utils';
20 |
21 | /**
22 | * The default wiki export
23 | *
24 | * @remarks
25 | * Internally calls wiki.page
26 | *
27 | */
28 | const wiki = async (title: string, pageOptions?: pageOptions): Promise => {
29 | return wiki.page(title, pageOptions);
30 | }
31 |
32 | /**
33 | * Returns the search results for a given query
34 | *
35 | * @remarks
36 | * Limits results by default to 10
37 | *
38 | * @param query - The string to search for
39 | * @param searchOptions - The number of results and if suggestion needed {@link searchOptions | searchOptions }
40 | * @returns an array of {@link wikiSearchResult | wikiSearchResult }
41 | */
42 | wiki.search = async (query: string, searchOptions?: searchOptions): Promise => {
43 | try {
44 | const searchParams: any = {
45 | 'list': 'search',
46 | 'srprop': '',
47 | 'srlimit': searchOptions?.limit || 10,
48 | 'srsearch': query
49 | }
50 | searchOptions?.suggestion ? searchParams['srinfo'] = 'suggestion' : null;
51 | const response = await request(searchParams);
52 | const result: wikiSearchResult = {
53 | results: response.query.search,
54 | suggestion: response.query.searchinfo ? response.query.searchinfo.suggestion : null
55 | }
56 | return result;
57 | } catch (error) {
58 | throw new searchError(error);
59 | }
60 | }
61 |
62 | /**
63 | * Returns the page for a given title or string
64 | *
65 | * @remarks
66 | * Call this method to get the basic info for page and also to preload any params you might use in future
67 | *
68 | * @param title - The title or page Id of the page
69 | * @param pageOptions - Whether to redirect, autoSuggest or preload any fields {@link pageOptions | pageOptions }
70 | * @returns The intro string
71 | */
72 | wiki.page = async (title: string, pageOptions?: pageOptions): Promise => {
73 | try {
74 | if (pageOptions?.autoSuggest) {
75 | title = await setTitleForPage(title);
76 | }
77 | let pageParams: any = {
78 | prop: 'info|pageprops',
79 | inprop: 'url',
80 | ppprop: 'disambiguation',
81 | }
82 | pageParams = setPageIdOrTitleParam(pageParams, title);
83 | const response = await request(pageParams);
84 | let pageInfo = response.query.pages;
85 | const pageId = setPageId(pageParams, response);
86 | pageInfo = pageInfo[pageId];
87 | if (pageInfo.missing == '') {
88 | throw new pageError(`${MSGS.PAGE_NOT_EXIST}${title}`)
89 | }
90 | const page = new Page(pageInfo);
91 | if (pageOptions?.preload) {
92 | if (!pageOptions?.fields) {
93 | pageOptions.fields = ['summary', 'images'];
94 | }
95 | for (const field of pageOptions.fields) {
96 | await page.runMethod(field);
97 | }
98 | }
99 | return page;
100 | } catch (error) {
101 | throw new pageError(error);
102 | }
103 | }
104 |
105 | /**
106 | * Returns the intro present in a wiki page
107 | *
108 | * @remarks
109 | * Called in page object and also through wiki default object
110 | *
111 | * @param title - The title or page Id of the page
112 | * @param pageOptions - Whether to redirect in case of 302
113 | * @returns The intro string
114 | */
115 | wiki.intro = async (title: string, pageOptions?: pageOptions): Promise => {
116 | try {
117 | if (pageOptions?.autoSuggest) {
118 | title = await setTitleForPage(title);
119 | }
120 | const result = await intro(title, pageOptions?.redirect);
121 | return result;
122 | } catch (error) {
123 | throw new introError(error);
124 | }
125 | }
126 |
127 | /**
128 | * Returns the images present in a wiki page
129 | *
130 | * @remarks
131 | * Called in page object and also through wiki default object
132 | *
133 | * @param title - The title or page Id of the page
134 | * @param listOptions - {@link listOptions | listOptions }
135 | * @returns an array of imageResult {@link imageResult | imageResult }
136 | */
137 | wiki.images = async (title: string, listOptions?: listOptions): Promise> => {
138 | try {
139 | if (listOptions?.autoSuggest) {
140 | title = await setTitleForPage(title);
141 | }
142 | const result = await images(title, listOptions);
143 | return result;
144 | } catch (error) {
145 | throw new imageError(error);
146 | }
147 | }
148 |
149 | /**
150 | * Returns the summary of the page
151 | *
152 | * @remarks
153 | * Called in page object and also through wiki default object
154 | *
155 | * @param title - The title or page Id of the page
156 | * @param pageOptions - Whether to redirect in case of 302
157 | * @returns The summary of the page as {@link wikiSummary | wikiSummary}
158 | */
159 | wiki.summary = async (title: string, pageOptions?: pageOptions): Promise => {
160 | try {
161 | if (pageOptions?.autoSuggest) {
162 | title = await setTitleForPage(title);
163 | }
164 | const result = await summary(title, pageOptions?.redirect);
165 | return result;
166 | } catch (error) {
167 | throw new summaryError(error);
168 | }
169 | }
170 |
171 | /**
172 | * Returns the html content of a page
173 | *
174 | * @remarks
175 | * Called in page object and also through wiki default object
176 | *
177 | * @param title - The title or page Id of the page
178 | * @param pageOptions - Whether to redirect in case of 302
179 | * @returns The html content as string
180 | *
181 | * @beta
182 | */
183 | wiki.html = async (title: string, pageOptions?: pageOptions): Promise => {
184 | try {
185 | if (pageOptions?.autoSuggest) {
186 | title = await setTitleForPage(title);
187 | }
188 | const result = await html(title, pageOptions?.redirect);
189 | return result;
190 | } catch (error) {
191 | throw new htmlError(error);
192 | }
193 | }
194 |
195 | /**
196 | * Returns the plain text content of a page
197 | *
198 | * @remarks
199 | * Called in page object and also through wiki default object
200 | *
201 | * @param title - The title or page Id of the page
202 | * @param pageOptions - Whether to redirect in case of 302
203 | * @returns The plain text as string and the parent and revision ids
204 | */
205 | wiki.content = async (title: string, pageOptions?: pageOptions): Promise => {
206 | try {
207 | if (pageOptions?.autoSuggest) {
208 | title = await setTitleForPage(title);
209 | }
210 | const response = await content(title, pageOptions?.redirect);
211 | return response.result;
212 | } catch (error) {
213 | throw new contentError(error);
214 | }
215 | }
216 |
217 | /**
218 | * Returns the cetegories present in page
219 | *
220 | * @remarks
221 | * Called in page object and also through wiki default object
222 | *
223 | * @param title - The title or page Id of the page
224 | * @param listOptions - {@link listOptions | listOptions }
225 | * @returns The categories as an array of string
226 | */
227 | wiki.categories = async (title: string, listOptions?: listOptions): Promise> => {
228 | try {
229 | if (listOptions?.autoSuggest) {
230 | title = await setTitleForPage(title);
231 | }
232 | const response = await categories(title, listOptions);
233 | return response;
234 | } catch (error) {
235 | throw new categoriesError(error);
236 | }
237 | }
238 |
239 | /**
240 | * Returns summaries for 20 pages related to the given page. Summaries include page title, namespace
241 | * and id along with short text description of the page and a thumbnail.
242 | *
243 | * @remarks
244 | * Called in page object and also through index
245 | *
246 | * @param title - The title or page Id of the page
247 | * @param pageOptions - Whether to redirect in case of 302
248 | * @returns The related pages and summary as an array of {@link wikiSummary | wikiSummary}
249 | *
250 | * @experimental
251 | */
252 | wiki.related = async (title: string, pageOptions?: pageOptions): Promise => {
253 | try {
254 | if (pageOptions?.autoSuggest) {
255 | title = await setTitleForPage(title);
256 | }
257 | const response = await related(title, pageOptions?.redirect);
258 | return response;
259 | } catch (error) {
260 | throw new relatedError(error);
261 | }
262 | }
263 |
264 | /**
265 | * Gets the list of media items (images, audio, and video) in the
266 | * order in which they appear on a given wiki page.
267 | *
268 | * @remarks
269 | * Called in page object and also through index
270 | *
271 | * @param title - The title or page Id of the page
272 | * @param redirect - Whether to redirect in case of 302
273 | * @returns The related pages and summary as an array of {@link wikiMediaResult | wikiMediaResult}
274 | *
275 | * @experimental
276 | */
277 | wiki.media = async (title: string, pageOptions?: pageOptions): Promise => {
278 | try {
279 | if (pageOptions?.autoSuggest) {
280 | title = await setTitleForPage(title);
281 | }
282 | const response = await media(title, pageOptions?.redirect);
283 | return response;
284 | } catch (error) {
285 | throw new mediaError(error);
286 | }
287 | }
288 |
289 | /**
290 | * Returns the links present in page
291 | *
292 | * @remarks
293 | * Called in page object and also through wiki default object
294 | *
295 | * @param title - The title or page Id of the page
296 | * @param listOptions - {@link listOptions | listOptions }
297 | * @returns The links as an array of string
298 | */
299 | wiki.links = async (title: string, listOptions?: listOptions): Promise> => {
300 | try {
301 | if (listOptions?.autoSuggest) {
302 | title = await setTitleForPage(title);
303 | }
304 | const response = await links(title, listOptions);
305 | return response;
306 | } catch (error) {
307 | throw new linksError(error);
308 | }
309 | }
310 |
311 | /**
312 | * Returns the references of external links present in page
313 | *
314 | * @remarks
315 | * Called in page object and also through wiki default object
316 | *
317 | * @param title - The title or page Id of the page
318 | * @param listOptions - {@link listOptions | listOptions }
319 | * @returns The references as an array of string
320 | */
321 | wiki.references = async (title: string, listOptions?: listOptions): Promise> => {
322 | try {
323 | if (listOptions?.autoSuggest) {
324 | title = await setTitleForPage(title);
325 | }
326 | const response = await references(title, listOptions);
327 | return response;
328 | } catch (error) {
329 | throw new linksError(error);
330 | }
331 | }
332 |
333 | /**
334 | * Returns the coordinates of a page
335 | *
336 | * @remarks
337 | * Called in page object and also through wiki default object
338 | *
339 | * @param title - The title or page Id of the page
340 | * @param pageOptions - Whether to redirect in case of 302
341 | * @returns The coordinates as {@link coordinatesResult | coordinatesResult}
342 | */
343 | wiki.coordinates = async (title: string, pageOptions?: pageOptions): Promise => {
344 | try {
345 | if (pageOptions?.autoSuggest) {
346 | title = await setTitleForPage(title);
347 | }
348 | const response = await coordinates(title, pageOptions?.redirect);
349 | return response;
350 | } catch (error) {
351 | throw new coordinatesError(error);
352 | }
353 | }
354 |
355 | /**
356 | * Returns the language links present in the page
357 | *
358 | * @remarks
359 | * Called in page object and also through wiki default object
360 | *
361 | * @param title - The title or page Id of the page
362 | * @param listOptions - {@link listOptions | listOptions }
363 | * @returns The links as an array of {@link langLinksResult | langLinksResult }
364 | */
365 | wiki.langLinks = async (title: string, listOptions?: listOptions): Promise> => {
366 | try {
367 | if (listOptions?.autoSuggest) {
368 | title = await setTitleForPage(title);
369 | }
370 | const response = await langLinks(title, listOptions);
371 | return response;
372 | } catch (error) {
373 | throw new linksError(error);
374 | }
375 | }
376 |
377 | /**
378 | * Returns the infobox content of page if present
379 | *
380 | * @remarks
381 | * Called in page object and also through wiki default object
382 | *
383 | * @param title - The title or page Id of the page
384 | * @param pageOptions - Whether to redirect in case of 302
385 | * @returns The info as JSON object
386 | */
387 | wiki.infobox = async (title: string, pageOptions?: pageOptions): Promise => {
388 | try {
389 | if (pageOptions?.autoSuggest) {
390 | title = await setTitleForPage(title);
391 | }
392 | const response = await infobox(title, pageOptions?.redirect);
393 | return response;
394 | } catch (error) {
395 | throw new infoboxError(error);
396 | }
397 | }
398 |
399 | /**
400 | * Returns the table content of page if present
401 | *
402 | * @remarks
403 | * Called in page object and also through wiki default object
404 | *
405 | * @param title - The title or page Id of the page
406 | * @param pageOptions - Whether to redirect in case of 302
407 | * @returns The tables as arrays of JSON objects
408 | */
409 | wiki.tables = async (title: string, pageOptions?: pageOptions): Promise> => {
410 | try {
411 | if (pageOptions?.autoSuggest) {
412 | title = await setTitleForPage(title);
413 | }
414 | const response = await tables(title, pageOptions?.redirect);
415 | return response;
416 | } catch (error) {
417 | throw new infoboxError(error);
418 | }
419 | }
420 |
421 | /**
422 | * Returns the languages available in wiki
423 | *
424 | * @remarks
425 | * Use this if you want to check if a lanuage exists before actually setting it
426 | *
427 | * @returns The languages an array of {@link languageResult | languageResult}
428 | */
429 | wiki.languages = async (): Promise> => {
430 | try {
431 | const langParams = {
432 | 'meta': 'siteinfo',
433 | 'siprop': 'languages'
434 | }
435 | const response = await request(langParams);
436 | const languages = [];
437 | for (const lang of response.query.languages) {
438 | languages.push({ [lang.code]: lang['*'] })
439 | }
440 | return languages;
441 | } catch (error) {
442 | throw new wikiError(error);
443 | }
444 | }
445 |
446 | /**
447 | * sets the languages to given string - verify your input using languages method
448 | *
449 | * @remarks
450 | * Use this to set your language for future api calls
451 | *
452 | * @returns The new api endpoint as string
453 | */
454 | wiki.setLang = (language: string): string => {
455 | const apiUrl = setAPIUrl(language);
456 | return apiUrl;
457 | }
458 |
459 | /**
460 | * Returns the pages with coordinates near the geo search coordinates
461 | *
462 | * @remarks
463 | * Latitude and longitude should be valid values
464 | *
465 | * @param latitude - The latitude to search
466 | * @param longitude - The longitude to search
467 | * @param geoOptions - The number of results and the search radius {@link geoOptions | geoOptions}
468 | * @returns The results as an array of {@link geoSearchResult | geoSearchResult}
469 | */
470 | wiki.geoSearch = async (latitude: number, longitude: number, geoOptions?: geoOptions): Promise> => {
471 | try {
472 | const geoSearchParams: any = {
473 | 'list': 'geosearch',
474 | 'gsradius': geoOptions?.radius || 1000,
475 | 'gscoord': `${latitude}|${longitude}`,
476 | 'gslimit': geoOptions?.limit || 10,
477 | 'gsprop': 'type'
478 | }
479 | const results = await request(geoSearchParams);
480 | const searchPages = results.query.geosearch;
481 | return searchPages;
482 | } catch (error) {
483 | throw new geoSearchError(error);
484 | }
485 | }
486 |
487 | /**
488 | * Returns the suggestion for a given query
489 | *
490 | * @remarks
491 | * Use this if you want your user to approve the suggestion before using it
492 | *
493 | * @param query - The string to query
494 | * @returns Returns a string or null based on if suggestion is present or not
495 | */
496 | wiki.suggest = async (query: string): Promise => {
497 | try {
498 | const suggestParams = {
499 | 'list': 'search',
500 | 'srinfo': 'suggestion',
501 | 'srprop': '',
502 | 'srsearch': query
503 | }
504 | const result = await request(suggestParams);
505 | return result.query?.searchinfo?.suggestion ? result.query?.searchinfo?.suggestion : null;
506 | } catch (error) {
507 | throw new searchError(error);
508 | }
509 | }
510 |
511 | /**
512 | * Returns the events for a given day
513 | *
514 | * @remarks
515 | * The api returns the events that happened on a particular month and day
516 | *
517 | * @param eventOptions - the event types, and the month and day {@link eventOptions | eventOptions}
518 | * @returns Returns the results as array of {@link eventResult | eventResult}
519 | */
520 | wiki.onThisDay = async (eventOptions: eventOptions = {}): Promise => {
521 | try {
522 | const type = eventOptions.type || 'all';
523 | const mm = (eventOptions.month || getCurrentMonth()).toString().padStart(2, "0")
524 | const dd = (eventOptions.day || getCurrentDay()).toString().padStart(2, "0")
525 | const path = `feed/onthisday/${type}/${mm}/${dd}`;
526 | const result = await makeRestRequest(path, true);
527 | return result;
528 | } catch (error) {
529 | throw new eventsError(error);
530 | }
531 | }
532 |
533 | /**
534 | * Returns featured content for a given day
535 | *
536 | * @remarks
537 | * The api returns content featured at a particular date
538 | *
539 | * @param fcOptions - the year/month/day of featured content by {@link fcOptions | eventOptions}
540 | * @returns Returns the results as array of {@link fcResult | fcResult}
541 | */
542 | wiki.featuredContent = async (fcOptions: fcOptions = {}): Promise => {
543 | try {
544 | const yyyy = (fcOptions.year || getCurrentYear()).toString()
545 | const mm = (fcOptions.month || getCurrentMonth()).toString().padStart(2, "0")
546 | const dd = (fcOptions.day || getCurrentDay()).toString().padStart(2, "0")
547 | const path = `feed/featured/${yyyy}/${mm}/${dd}`;
548 | const result = await makeRestRequest(path, true);
549 | return result;
550 | } catch (error) {
551 | throw new fcError(error);
552 | }
553 | }
554 |
555 | /**
556 | * Returns a random page
557 | *
558 | * @param format - The desired return format
559 | * @returns Returns content from a random page
560 | */
561 | wiki.random = async (format?: randomFormats): Promise => {
562 | try {
563 | if(!format){
564 | format = 'summary';
565 | }
566 | const path = `page/random/${format}`;
567 | const result = await makeRestRequest(path);
568 | return result;
569 | } catch (error) {
570 | throw new wikiError(error);
571 | }
572 | }
573 |
574 | /**
575 | * Returns mobile-optimised HTML of a page
576 | *
577 | * @param title - The title of the page to query
578 | * @param pageOptions - Whether to redirect in case of 302
579 | * @returns Returns HTML string
580 | */
581 | wiki.mobileHtml = async (title: string, pageOptions?: pageOptions): Promise => {
582 | try {
583 | if (pageOptions?.autoSuggest) {
584 | title = await setTitleForPage(title);
585 | }
586 | const result = await mobileHtml(title, pageOptions?.redirect);
587 | return result;
588 | } catch (error) {
589 | throw new htmlError(error);
590 | }
591 | }
592 |
593 | /**
594 | * Returns pdf of a given page
595 | *
596 | * @param title - The title of the page to query
597 | * @param pdfOptions - {@link pdfOptions | pdfOptions }
598 | * @returns Returns pdf format
599 | */
600 | wiki.pdf = async (title: string, pdfOptions?: pdfOptions): Promise => {
601 | try {
602 | if (pdfOptions?.autoSuggest) {
603 | title = await setTitleForPage(title);
604 | }
605 | const result = await pdf(title, pdfOptions);
606 | return result;
607 | } catch (error) {
608 | throw new pdfError(error);
609 | }
610 | }
611 |
612 | /**
613 | * Returns citation of a given page, or query string
614 | *
615 | * @param format - the format of the citation result
616 | * @param query - url or query string
617 | * @param language - if you want lanuage enabled results
618 | * @returns Returns citation data
619 | */
620 | wiki.citation = async (query: string, format?: citationFormat, language?: string): Promise => {
621 | try {
622 | const result = await citation(query, format, language);
623 | return result;
624 | } catch (error) {
625 | throw new citationError(error);
626 | }
627 | }
628 |
629 | /**
630 | * Returns the autocompletion results for a given query
631 | *
632 | * @remarks
633 | * Limits results by default to 10
634 | *
635 | * @param query - The string to search for
636 | * @param autocompletionOptions - The number of results {@link autocompletionOptions | autocompletionOptions }
637 | * @returns an array of string
638 | */
639 | wiki.autocompletions = async (query: string, autocompletionOptions?: autocompletionOptions): Promise> => {
640 | try {
641 | const autocompletionsParams: any = {
642 | list: "search",
643 | limit: autocompletionOptions?.limit || 10,
644 | search: query,
645 | action: "opensearch",
646 | redirect: "return"
647 | };
648 |
649 | const [, autocompletions] = await request(autocompletionsParams, false);
650 |
651 | return autocompletions;
652 | } catch (error) {
653 | throw new autocompletionsError(error);
654 | }
655 | }
656 |
657 | /**
658 | * Change the default user agent for wikipedia
659 | *
660 | * @param userAgent - The new custom userAgent
661 | */
662 | wiki.setUserAgent = (userAgent: string) => {
663 | setUserAgent(userAgent);
664 | }
665 |
666 | export default wiki;
667 | // For CommonJS default export support
668 | module.exports = wiki;
669 | module.exports.default = wiki;
670 |
671 | export * from './errors';
672 | export * from './resultTypes';
673 | export * from './optionTypes';
674 | export * from './page';
--------------------------------------------------------------------------------
/source/messages.ts:
--------------------------------------------------------------------------------
1 | export const MSGS = {
2 | PAGE_NOT_SUGGEST: 'No page with given title suggested : ',
3 | PAGE_NOT_EXIST: 'No page with given title exists : ',
4 | INFOBOX_NOT_EXIST: 'Info cannot be parsed for given page'
5 | }
--------------------------------------------------------------------------------
/source/optionTypes.ts:
--------------------------------------------------------------------------------
1 | export interface searchOptions {
2 | limit?: number
3 | suggestion?: boolean
4 | }
5 |
6 | export interface autocompletionOptions {
7 | limit?: number
8 | }
9 |
10 | export interface pageOptions {
11 | autoSuggest?: boolean
12 | redirect?: boolean
13 | preload?: boolean
14 | fields?: Array
15 | }
16 |
17 | export interface listOptions {
18 | autoSuggest?: boolean
19 | redirect?: boolean
20 | limit?: number
21 | }
22 |
23 | export interface geoOptions {
24 | limit?: number
25 | radius?: number
26 | }
27 |
28 | export type pageFunctions =
29 | 'summary' | 'images' | 'intro' | 'html' | 'content' | 'categories' | 'links' | 'references' | 'coordinates'
30 | | 'langLinks' | 'infobox' | 'tables' | 'related'
31 |
32 | export interface eventOptions {
33 | type?: eventTypes,
34 | month?: string,
35 | day?: string
36 | }
37 |
38 | export interface fcOptions {
39 | year?: string,
40 | month?: string,
41 | day?: string
42 | }
43 |
44 | export type eventTypes =
45 | 'all' | 'selected' | 'births' | 'deaths' | 'events' | 'holidays'
46 |
47 | export type randomFormats =
48 | 'title' | 'summary' | 'related' | 'mobile-sections' | 'mobile-sections-lead'
49 |
50 | export type format =
51 | 'a4' | 'letter' | 'legal'
52 |
53 | export type pdfType =
54 | 'desktop' | 'mobile'
55 |
56 | export interface pdfOptions {
57 | autoSuggest?: boolean
58 | format?: format
59 | type?: pdfType
60 | }
61 |
62 | export type citationFormat =
63 | 'mediawiki' | 'mediawiki-basefields' | 'zotero' | 'bibtex' | 'wikibase'
--------------------------------------------------------------------------------
/source/page.ts:
--------------------------------------------------------------------------------
1 | import { categoriesError, contentError, coordinatesError, htmlError, imageError, wikiError, pdfError,
2 | infoboxError, introError, linksError, mediaError, preloadError, relatedError, summaryError, citationError } from './errors';
3 | import request, { makeRestRequest, returnRestUrl } from './request';
4 | import { coordinatesResult, imageResult, langLinksResult, notFound, pageResult, relatedResult, wikiMediaResult, wikiSummary } from './resultTypes';
5 | import { setPageId, setPageIdOrTitleParam } from './utils';
6 | import { citationFormat, listOptions, pageOptions, pdfOptions } from './optionTypes';
7 | import { MSGS } from './messages';
8 |
9 | // eslint-disable-next-line @typescript-eslint/no-var-requires
10 | const infoboxParser = require('infobox-parser');
11 |
12 |
13 | export class Page {
14 | pageid!: number;
15 | ns!: number;
16 | title!: string;
17 | contentmodel!: string;
18 | pagelanguage!: string;
19 | pagelanguagehtmlcode!: string;
20 | pagelanguagedir!: string;
21 | touched!: string;
22 | lastrevid!: number;
23 | length!: number;
24 | fullurl!: string;
25 | editurl!: string;
26 | canonicalurl!: string;
27 | revid!: number;
28 | parentid!: number;
29 | _summary!: wikiSummary;
30 | _images!: Array;
31 | _content!: string;
32 | _html!: string;
33 | _categories!: Array;
34 | _references!: Array;
35 | _links!: Array;
36 | _coordinates!: coordinatesResult;
37 | _langLinks!: Array;
38 | _infobox!: any;
39 | _tables!: Array;
40 | _intro!: string;
41 | _related!: relatedResult;
42 | _media!: wikiMediaResult;
43 | _mobileHtml!: string | notFound;
44 | constructor(response: pageResult) {
45 | this.pageid = response.pageid;
46 | this.ns = response.ns;
47 | this.title = response.title;
48 | this.contentmodel = response.contentmodel;
49 | this.pagelanguage = response.pagelanguage;
50 | this.pagelanguagedir = response.pagelanguagedir;
51 | this.touched = response.touched;
52 | this.lastrevid = response.lastrevid;
53 | this.length = response.length;
54 | this.fullurl = response.fullurl;
55 | this.editurl = response.editurl;
56 | this.canonicalurl = response.canonicalurl;
57 | }
58 |
59 | /**
60 | * Returns the intro present in a wiki page
61 | *
62 | * @remarks
63 | * This method is part of the {@link Page | Page }.
64 | *
65 | * @param title - The title or page Id of the page
66 | * @param redirect - Whether to redirect in case of 302
67 | * @returns The intro string
68 | */
69 | public intro = async (pageOptions?: pageOptions): Promise => {
70 | try {
71 | if (!this._intro) {
72 | const response = await intro(this.pageid.toString(), pageOptions?.redirect);
73 | this._intro = response;
74 | }
75 | return this._intro;
76 | } catch (error) {
77 | throw new introError(error);
78 | }
79 | }
80 |
81 | /**
82 | * Returns the images present in a wiki page
83 | *
84 | * @remarks
85 | * This method is part of the {@link Page | Page }.
86 | *
87 | * @param title - The title or page Id of the page
88 | * @param listOptions - {@link listOptions | listOptions }
89 | * @returns an array of imageResult {@link imageResult | imageResult }
90 | */
91 | public images = async (listOptions?: listOptions): Promise> => {
92 | try {
93 | if (!this._images) {
94 | const result = await images(this.pageid.toString(), listOptions);
95 | this._images = result;
96 | }
97 | return this._images;
98 | } catch (error) {
99 | throw new imageError(error);
100 | }
101 | }
102 |
103 | /**
104 | * Returns the summary of the page
105 | *
106 | * @remarks
107 | * This method is part of the {@link Page | Page }.
108 | *
109 | * @param title - The title or page Id of the page
110 | * @param redirect - Whether to redirect in case of 302
111 | * @returns The summary of the page as {@link wikiSummary | wikiSummary}
112 | *
113 | */
114 | public summary = async (pageOptions?: pageOptions): Promise => {
115 | try {
116 | if (!this._summary) {
117 | const result = await summary(this.title, pageOptions?.redirect);
118 | this._summary = result;
119 | }
120 | return this._summary;
121 | } catch (error) {
122 | throw new summaryError(error);
123 | }
124 | }
125 |
126 | /**
127 | * Returns the html content of a page
128 | *
129 | * @remarks
130 | * This method is part of the {@link Page | Page }.
131 | *
132 | * @param title - The title or page Id of the page
133 | * @param redirect - Whether to redirect in case of 302
134 | * @returns The html content as string
135 | *
136 | * @beta
137 | */
138 | public html = async (pageOptions?: pageOptions): Promise => {
139 | try {
140 | if (!this._html) {
141 | const result = await html(this.pageid.toString(), pageOptions?.redirect);
142 | this._html = result;
143 | }
144 | return this._html;
145 | } catch (error) {
146 | throw new htmlError(error);
147 | }
148 | }
149 |
150 | /**
151 | * Returns the plain text content of a page and sets parent Id and rev Id
152 | *
153 | * @remarks
154 | * This method is part of the {@link Page | Page }.
155 | *
156 | * @param title - The title or page Id of the page
157 | * @param redirect - Whether to redirect in case of 302
158 | * @returns The plain text as string and the parent and revision ids
159 | */
160 | public content = async (pageOptions?: pageOptions): Promise => {
161 | try {
162 | if (!this._content) {
163 | const result = await content(this.pageid.toString(), pageOptions?.redirect);
164 | this.parentid = result.ids.parentId;
165 | this.revid = result.ids.revId;
166 | this._content = result.result;
167 | }
168 | return this._content;
169 | } catch (error) {
170 | throw new contentError(error);
171 | }
172 | }
173 |
174 | /**
175 | * Returns the cetegories present in page
176 | *
177 | * @remarks
178 | * This method is part of the {@link Page | Page }.
179 | *
180 | * @param title - The title or page Id of the page
181 | * @param listOptions - {@link listOptions | listOptions }
182 | * @returns The categories as an array of string
183 | */
184 | public categories = async (listOptions?: listOptions): Promise> => {
185 | try {
186 | if (!this._categories) {
187 | const result = await categories(this.pageid.toString(), listOptions);
188 | this._categories = result;
189 | }
190 | return this._categories;
191 | } catch (error) {
192 | throw new categoriesError(error);
193 | }
194 | }
195 |
196 | /**
197 | * Returns the links present in page
198 | *
199 | * @remarks
200 | * This method is part of the {@link Page | Page }.
201 | *
202 | * @param title - The title or page Id of the page
203 | * @param listOptions - {@link listOptions | listOptions }
204 | * @returns The links as an array of string
205 | */
206 | public links = async (listOptions?: listOptions): Promise> => {
207 | try {
208 | if (!this._links) {
209 | const result = await links(this.pageid.toString(), listOptions);
210 | this._links = result;
211 | }
212 | return this._links;
213 | } catch (error) {
214 | throw new linksError(error);
215 | }
216 | }
217 |
218 | /**
219 | * Returns the references of external links present in page
220 | *
221 | * @remarks
222 | * This method is part of the {@link Page | Page }.
223 | *
224 | * @param title - The title or page Id of the page
225 | * @param listOptions - {@link listOptions | listOptions }
226 | * @returns The references as an array of string
227 | */
228 | public references = async (listOptions?: listOptions): Promise> => {
229 | try {
230 | if (!this._references) {
231 | const result = await references(this.pageid.toString(), listOptions);
232 | this._references = result;
233 | }
234 | return this._references;
235 | } catch (error) {
236 | throw new linksError(error);
237 | }
238 | }
239 |
240 | /**
241 | * Returns the coordinates of a page
242 | *
243 | * @remarks
244 | * This method is part of the {@link Page | Page }.
245 | *
246 | * @param title - The title or page Id of the page
247 | * @param redirect - Whether to redirect in case of 302
248 | * @returns The coordinates as {@link coordinatesResult | coordinatesResult}
249 | */
250 | public coordinates = async (pageOptions?: pageOptions): Promise => {
251 | try {
252 | if (!this._coordinates) {
253 | const result = await coordinates(this.pageid.toString(), pageOptions?.redirect);
254 | this._coordinates = result;
255 | }
256 | return this._coordinates;
257 | } catch (error) {
258 | throw new coordinatesError(error);
259 | }
260 | }
261 |
262 | /**
263 | * Returns the language links present in the page
264 | *
265 | * @remarks
266 | * This method is part of the {@link Page | Page }.
267 | *
268 | * @param title - The title or page Id of the page
269 | * @param listOptions - {@link listOptions | listOptions }
270 | * @returns The links as an array of {@link langLinksResult | langLinksResult }
271 | */
272 | public langLinks = async (listOptions?: listOptions): Promise> => {
273 | try {
274 | if (!this._langLinks) {
275 | const result = await langLinks(this.pageid.toString(), listOptions);
276 | this._langLinks = result;
277 | }
278 | return this._langLinks;
279 | } catch (error) {
280 | throw new linksError(error);
281 | }
282 | }
283 |
284 | /**
285 | * Returns the infobox content of page if present
286 | *
287 | * @remarks
288 | * This method is part of the {@link Page | Page }.
289 | *
290 | * @param title - The title or page Id of the page
291 | * @param redirect - Whether to redirect in case of 302
292 | * @returns The info as JSON object
293 | */
294 | public infobox = async (pageOptions?: pageOptions): Promise => {
295 | try {
296 | if (!this._infobox) {
297 | const result = await infobox(this.pageid.toString(), pageOptions?.redirect);
298 | this._infobox = result;
299 | }
300 | return this._infobox;
301 | } catch (error) {
302 | throw new infoboxError(error);
303 | }
304 | }
305 |
306 | /**
307 | * Returns the table content of page if present
308 | *
309 | * @remarks
310 | * This method is part of the {@link Page | Page }.
311 | *
312 | * @param title - The title or page Id of the page
313 | * @param redirect - Whether to redirect in case of 302
314 | * @returns The tables as arrays of JSON objects
315 | */
316 | public tables = async (pageOptions?: pageOptions): Promise> => {
317 | try {
318 | if (!this._tables) {
319 | const result = await tables(this.pageid.toString(), pageOptions?.redirect);
320 | this._tables = result;
321 | }
322 | return this._tables;
323 | } catch (error) {
324 | throw new infoboxError(error);
325 | }
326 | }
327 |
328 | /**
329 | * Returns summaries for 20 pages related to the given page. Summaries include page title, namespace
330 | * and id along with short text description of the page and a thumbnail.
331 | *
332 | * @remarks
333 | * This method is part of the {@link Page | Page }.
334 | *
335 | * @param title - The title or page Id of the page
336 | * @param redirect - Whether to redirect in case of 302
337 | * @returns The related pages and summary as an array of {@link wikiSummary | wikiSummary}
338 | *
339 | * @experimental
340 | */
341 | public related = async (pageOptions?: pageOptions): Promise => {
342 | try {
343 | if (!this._related) {
344 | const result = await related(this.title, pageOptions?.redirect);
345 | this._related = result;
346 | }
347 | return this._related;
348 | } catch (error) {
349 | throw new relatedError(error);
350 | }
351 | }
352 |
353 | /**
354 | * Gets the list of media items (images, audio, and video) in the
355 | * order in which they appear on a given wiki page.
356 | *
357 | * @remarks
358 | * Called in page object and also through index
359 | *
360 | * @param title - The title or page Id of the page
361 | * @param redirect - Whether to redirect in case of 302
362 | * @returns The related pages and summary as an array of {@link wikiMediaResult | wikiMediaResult}
363 | *
364 | * @experimental
365 | */
366 | public media = async (pageOptions?: pageOptions): Promise => {
367 | try {
368 | if (!this._media) {
369 | const result = await media(this.title, pageOptions?.redirect);
370 | this._media = result;
371 | }
372 | return this._media;
373 | } catch (error) {
374 | throw new mediaError(error);
375 | }
376 | }
377 |
378 | /**
379 | * Returns mobile-optimised HTML of a page
380 | *
381 | * @param title - The title of the page to query
382 | * @param redirect - Whether to redirect in case of 302
383 | * @returns Returns HTML string
384 | */
385 | public mobileHtml = async (pageOptions?: pageOptions): Promise => {
386 | try {
387 | if (!this._mobileHtml) {
388 | const result = await mobileHtml(this.title, pageOptions?.redirect);
389 | this._mobileHtml = result;
390 | }
391 | return this._mobileHtml;
392 | } catch (error) {
393 | throw new htmlError(error);
394 | }
395 | }
396 |
397 | /**
398 | * Returns pdf of a given page
399 | *
400 | * @param pdfOptions - {@link pdfOptions | pdfOptions }
401 | * @returns Returns path string
402 | */
403 | public pdf = async (pdfOptions?: pdfOptions): Promise => {
404 | try {
405 | const result = await pdf(this.title, pdfOptions)
406 |
407 | return result;
408 | } catch (error) {
409 | throw new pdfError(error);
410 | }
411 | }
412 |
413 | public async runMethod(functionName: string): Promise {
414 | try {
415 | const result = await eval(`this.${functionName}()`);
416 | return result;
417 | } catch (error) {
418 | throw new preloadError(error);
419 | }
420 | }
421 | }
422 |
423 | /**
424 | * Returns the images present in a wiki page
425 | *
426 | * @remarks
427 | * Called in page object and also through wiki default object
428 | *
429 | * @param title - The title or page Id of the page
430 | * @param listOptions - {@link listOptions | listOptions }
431 | * @returns an array of imageResult {@link imageResult | imageResult }
432 | */
433 | export const images = async (title: string, listOptions?: listOptions): Promise> => {
434 | try {
435 | let imageOptions: any = {
436 | generator: 'images',
437 | gimlimit: listOptions?.limit || 5,
438 | prop: 'imageinfo',
439 | iiprop: 'url'
440 | }
441 | imageOptions = setPageIdOrTitleParam(imageOptions, title);
442 | const response = await request(imageOptions, listOptions?.redirect);
443 | const images = [];
444 | const imageKeys = Object.keys(response.query.pages);
445 | for (const image of imageKeys) {
446 | const imageInfo = response.query.pages[image];
447 | imageInfo.url = imageInfo.imageinfo[0].url;
448 | images.push(imageInfo);
449 | }
450 | return images;
451 | } catch (error) {
452 | throw new imageError(error);
453 | }
454 | }
455 |
456 | /**
457 | * Returns the intro present in a wiki page
458 | *
459 | * @remarks
460 | * Called in page object and also through wiki default object
461 | *
462 | * @param title - The title or page Id of the page
463 | * @param redirect - Whether to redirect in case of 302
464 | * @returns The intro string
465 | */
466 | export const intro = async (title: string, redirect = true): Promise => {
467 | try {
468 | let introOptions: any = {
469 | prop: 'extracts',
470 | explaintext: '',
471 | exintro: '',
472 | }
473 | introOptions = setPageIdOrTitleParam(introOptions, title);
474 | const response = await request(introOptions, redirect);
475 | const pageId = setPageId(introOptions, response);
476 | return response?.query?.pages[pageId].extract;
477 | } catch (error) {
478 | throw new introError(error);
479 | }
480 | }
481 |
482 | /**
483 | * Returns the html content of a page
484 | *
485 | * @remarks
486 | * Called in page object and also through wiki default object
487 | *
488 | * @param title - The title or page Id of the page
489 | * @param redirect - Whether to redirect in case of 302
490 | * @returns The html content as string
491 | *
492 | * @beta
493 | */
494 | export const html = async (title: string, redirect = true): Promise => {
495 | try {
496 | let htmlOptions: any = {
497 | 'prop': 'revisions',
498 | 'rvprop': 'content',
499 | 'rvlimit': 1,
500 | 'rvparse': ''
501 | }
502 | htmlOptions = setPageIdOrTitleParam(htmlOptions, title);
503 | const response = await request(htmlOptions, redirect);
504 | const pageId = setPageId(htmlOptions, response);
505 | return response.query.pages[pageId].revisions[0]['*'];
506 | } catch (error) {
507 | throw new htmlError(error);
508 | }
509 | }
510 |
511 | /**
512 | * Returns the plain text content of a page as well as parent id and revision id
513 | *
514 | * @remarks
515 | * Called in page object and also through wiki default object
516 | *
517 | * @param title - The title or page Id of the page
518 | * @param redirect - Whether to redirect in case of 302
519 | * @returns The plain text as string and the parent and revision ids
520 | */
521 | export const content = async (title: string, redirect = true): Promise => {
522 | try {
523 | let contentOptions: any = {
524 | 'prop': 'extracts|revisions',
525 | 'explaintext': '',
526 | 'rvprop': 'ids'
527 | }
528 | contentOptions = setPageIdOrTitleParam(contentOptions, title);
529 | const response = await request(contentOptions, redirect);
530 | const pageId = setPageId(contentOptions, response);
531 | const result = response['query']['pages'][pageId]['extract'];
532 | const ids = {
533 | revisionId: response['query']['pages'][pageId]['revisions'][0]['revid'],
534 | parentId: response['query']['pages'][pageId]['revisions'][0]['parentid']
535 | }
536 | return {
537 | result,
538 | ids
539 | }
540 | } catch (error) {
541 | throw new contentError(error);
542 | }
543 | }
544 |
545 | /**
546 | * Returns the cetegories present in page
547 | *
548 | * @remarks
549 | * Called in page object and also through wiki default object
550 | *
551 | * @param title - The title or page Id of the page
552 | * @param listOptions - {@link listOptions | listOptions }
553 | * @returns The categories as an array of string
554 | */
555 | export const categories = async (title: string, listOptions?: listOptions): Promise> => {
556 | try {
557 | let categoryOptions: any = {
558 | prop: 'categories',
559 | pllimit: listOptions?.limit,
560 | }
561 | categoryOptions = setPageIdOrTitleParam(categoryOptions, title);
562 | const response = await request(categoryOptions, listOptions?.redirect);
563 | const pageId = setPageId(categoryOptions, response);
564 | return response.query.pages[pageId].categories.map((category: any) => category.title)
565 | } catch (error) {
566 | throw new categoriesError(error);
567 | }
568 | }
569 |
570 | /**
571 | * Returns the links present in page
572 | *
573 | * @remarks
574 | * Called in page object and also through wiki default object
575 | *
576 | * @param title - The title or page Id of the page
577 | * @param listOptions - {@link listOptions | listOptions }
578 | * @returns The links as an array of string
579 | */
580 | export const links = async (title: string, listOptions?: listOptions): Promise> => {
581 | try {
582 | let linksOptions: any = {
583 | prop: 'links',
584 | plnamespace: 0,
585 | pllimit: listOptions?.limit || 'max',
586 | }
587 | linksOptions = setPageIdOrTitleParam(linksOptions, title);
588 | const response = await request(linksOptions, listOptions?.redirect);
589 | const pageId = setPageId(linksOptions, response);
590 | const result = response.query.pages[pageId].links.map((link: any) => link.title)
591 | return result;
592 | } catch (error) {
593 | throw new linksError(error);
594 | }
595 | }
596 |
597 | /**
598 | * Returns the references of external links present in page
599 | *
600 | * @remarks
601 | * Called in page object and also through wiki default object
602 | *
603 | * @param title - The title or page Id of the page
604 | * @param listOptions - {@link listOptions | listOptions }
605 | * @returns The references as an array of string
606 | */
607 | export const references = async (title: string, listOptions?: listOptions): Promise> => {
608 | try {
609 | let extLinksOptions: any = {
610 | prop: 'extlinks',
611 | ellimit: listOptions?.limit || 'max',
612 | }
613 | extLinksOptions = setPageIdOrTitleParam(extLinksOptions, title);
614 | const response = await request(extLinksOptions, listOptions?.redirect);
615 | const pageId = setPageId(extLinksOptions, response);
616 | const result = response.query.pages[pageId].extlinks.map((link: any) => link['*'])
617 | return result;
618 | } catch (error) {
619 | throw new linksError(error);
620 | }
621 | }
622 |
623 | /**
624 | * Returns the coordinates of a page
625 | *
626 | * @remarks
627 | * Called in page object and also through wiki default object
628 | *
629 | * @param title - The title or page Id of the page
630 | * @param redirect - Whether to redirect in case of 302
631 | * @returns The coordinates as {@link coordinatesResult | coordinatesResult}
632 | */
633 | export const coordinates = async (title: string, redirect = true): Promise => {
634 | try {
635 | let coordinatesOptions: any = {
636 | prop: 'coordinates',
637 | }
638 | coordinatesOptions = setPageIdOrTitleParam(coordinatesOptions, title);
639 | const response = await request(coordinatesOptions, redirect);
640 | const pageId = setPageId(coordinatesOptions, response);
641 | const coordinates = response.query.pages[pageId].coordinates;
642 | return coordinates ? coordinates[0] : null;
643 | } catch (error) {
644 | throw new coordinatesError(error);
645 | }
646 | }
647 |
648 | /**
649 | * Returns the language links present in the page
650 | *
651 | * @remarks
652 | * Called in page object and also through wiki default object
653 | *
654 | * @param title - The title or page Id of the page
655 | * @param listOptions - {@link listOptions | listOptions }
656 | * @returns The links as an array of {@link langLinksResult | langLinksResult }
657 | */
658 | export const langLinks = async (title: string, listOptions?: listOptions): Promise> => {
659 | try {
660 | let languageOptions: any = {
661 | prop: 'langlinks',
662 | lllimit: listOptions?.limit || 'max',
663 | llprop: 'url'
664 | }
665 | languageOptions = setPageIdOrTitleParam(languageOptions, title);
666 | const response = await request(languageOptions, listOptions?.redirect);
667 | const pageId = setPageId(languageOptions, response);
668 | const result = (response.query.pages[pageId].langlinks ?? []).map((link: any) => {
669 | return {
670 | lang: link.lang,
671 | title: link['*'],
672 | url: link.url
673 | };
674 | })
675 | return result;
676 | } catch (error) {
677 | throw new linksError(error);
678 | }
679 | }
680 |
681 | /**
682 | * Returns the infobox content of page if present
683 | *
684 | * @remarks
685 | * Called in page object and also through wiki default object
686 | *
687 | * @param title - The title or page Id of the page
688 | * @param redirect - Whether to redirect in case of 302
689 | * @returns The info as JSON object
690 | */
691 | export const infobox = async (title: string, redirect = true): Promise => {
692 | try {
693 | const infoboxOptions: any = {
694 | prop: 'revisions',
695 | rvprop: 'content',
696 | rvsection: 0
697 | }
698 | const fullInfo = await rawInfo(title, infoboxOptions, redirect);
699 | const info = infoboxParser(fullInfo).general;
700 | return info;
701 | } catch (error) {
702 | throw new infoboxError(error);
703 | }
704 | }
705 |
706 | /**
707 | * Returns the table content of page if present
708 | *
709 | * @remarks
710 | * Called in page object and also through wiki default object
711 | *
712 | * @param title - The title or page Id of the page
713 | * @param redirect - Whether to redirect in case of 302
714 | * @returns The tables as arrays of JSON objects
715 | */
716 | export const tables = async (title: string, redirect = true): Promise> => {
717 | try {
718 | const tableOptions: any = {
719 | prop: 'revisions',
720 | rvprop: 'content',
721 | }
722 | const fullInfo = await rawInfo(title, tableOptions, redirect);
723 | const info = infoboxParser(fullInfo).tables;
724 | return info;
725 | } catch (error) {
726 | throw new infoboxError(error);
727 | }
728 | }
729 |
730 | /**
731 | * Returns the raw info of the page
732 | *
733 | * @remarks
734 | * This is not exported and used internally
735 | *
736 | * @param title - The title or page Id of the page
737 | * @param redirect - Whether to redirect in case of 302
738 | * @returns The rawInfo of the page
739 | *
740 | */
741 | export const rawInfo = async (title: string, options: any, redirect = true): Promise => {
742 | try {
743 | options = setPageIdOrTitleParam(options, title);
744 | const response = await request(options, redirect);
745 | if (!(response.query?.pages)) {
746 | throw new wikiError(MSGS.INFOBOX_NOT_EXIST);
747 | }
748 | const pageId = setPageId(options, response);
749 | const data = response.query.pages[pageId]['revisions'][0];
750 | return data ? data['*'] : '';
751 | } catch (error) {
752 | throw new infoboxError(error);
753 | }
754 | }
755 |
756 | //REST-API Requests based on https://en.wikipedia.org/api/rest_v1/#/
757 | //APIs seems to support only title parameters which is a drawback
758 |
759 | /**
760 | * Returns the summary of the page
761 | *
762 | * @remarks
763 | * Called in page object and also through wiki default object
764 | *
765 | * @param title - The title or page Id of the page
766 | * @param redirect - Whether to redirect in case of 302
767 | * @returns The summary of the page as {@link wikiSummary | wikiSummary}
768 | */
769 | export const summary = async (title: string, redirect = true): Promise => {
770 | try {
771 | const path = 'page/summary/' + title.replace(" ", "_");
772 | const response = await makeRestRequest(path, redirect);
773 | return response;
774 | } catch (error) {
775 | throw new summaryError(error);
776 | }
777 | }
778 |
779 | /**
780 | * Returns summaries for 20 pages related to the given page. Summaries include page title, namespace
781 | * and id along with short text description of the page and a thumbnail.
782 | *
783 | * @remarks
784 | * Called in page object and also through index
785 | *
786 | * @param title - The title or page Id of the page
787 | * @param redirect - Whether to redirect in case of 302
788 | * @returns The related pages and summary as an array of {@link wikiSummary | wikiSummary}
789 | *
790 | * @experimental
791 | */
792 | export const related = async (title: string, redirect = true): Promise => {
793 | try {
794 | const path = 'page/related/' + title.replace(" ", "_");
795 | const response = await makeRestRequest(path, redirect);
796 | return response;
797 | } catch (error) {
798 | throw new relatedError(error);
799 | }
800 | }
801 |
802 | /**
803 | * Gets the list of media items (images, audio, and video) in the
804 | * order in which they appear on a given wiki page.
805 | *
806 | * @remarks
807 | * Called in page object and also through index
808 | *
809 | * @param title - The title or page Id of the page
810 | * @param redirect - Whether to redirect in case of 302
811 | * @returns The related pages and summary as an array of {@link wikiMediaResult | wikiMediaResult}
812 | *
813 | * @experimental
814 | */
815 | export const media = async (title: string, redirect = true): Promise => {
816 | try {
817 | const path = 'page/media-list/' + title.replace(" ", "_");
818 | const response = await makeRestRequest(path, redirect);
819 | return response;
820 | } catch (error) {
821 | throw new mediaError(error);
822 | }
823 | }
824 |
825 | /**
826 | * Returns mobile-optimised HTML of a page
827 | *
828 | * @param title - The title of the page to query
829 | * @param redirect - Whether to redirect in case of 302
830 | * @returns Returns HTML string
831 | */
832 | export const mobileHtml = async (title: string, redirect = true): Promise => {
833 | try {
834 | const path = `page/mobile-html/${title}`;
835 | const result = await makeRestRequest(path, redirect);
836 | return result;
837 | } catch (error) {
838 | throw new htmlError(error);
839 | }
840 | }
841 |
842 | /**
843 | * Returns pdf of a given page
844 | *
845 | * @param title - The title of the page to query
846 | * @param pdfOptions - {@link pdfOptions | pdfOptions }
847 | * @returns Returns pdf format
848 | */
849 | export const pdf = async (title: string, pdfOptions?: pdfOptions): Promise => {
850 | try {
851 | let path = `page/pdf/${title}`;
852 | pdfOptions?.format ? path += `/${pdfOptions.format}` : null;
853 | pdfOptions?.type ? path += `/${pdfOptions.type}` : null;
854 |
855 | const result = returnRestUrl(path);
856 | return result;
857 | } catch (error) {
858 | throw new pdfError(error);
859 | }
860 | }
861 |
862 | /**
863 | * Returns citation of a given page, or query string
864 | *
865 | * @param format - the format of the citation result
866 | * @param query - url or query string
867 | * @param language - if you want lanuage enabled results
868 | * @returns Returns ciation data
869 | */
870 | export const citation = async (query: string, format?: citationFormat, language?: string): Promise => {
871 | try {
872 | let path = `data/citation`;
873 | path += format ? `/${format}` : `/mediawiki`;
874 | path += `/${query}`;
875 | language ? path += `/${language}` : null;
876 |
877 | const result = await makeRestRequest(path);
878 | return result;
879 | } catch (error) {
880 | throw new citationError(error);
881 | }
882 | }
883 |
884 | export default Page;
885 |
--------------------------------------------------------------------------------
/source/request.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosRequestConfig } from 'axios';
2 | import { wikiError } from './errors';
3 |
4 | let API_URL = 'https://en.wikipedia.org/w/api.php?',
5 | REST_API_URL = 'https://en.wikipedia.org/api/rest_v1/',
6 | // RATE_LIMIT = false,
7 | // RATE_LIMIT_MIN_WAIT = undefined,
8 | // RATE_LIMIT_LAST_CALL = undefined,
9 | USER_AGENT = 'wikipedia (https://github.com/dopecodez/Wikipedia/)';
10 |
11 | async function callAPI(url: string) {
12 | const options: AxiosRequestConfig = {
13 | headers: {
14 | "Api-User-Agent": USER_AGENT,
15 | },
16 | };
17 | try {
18 | const { data } = await axios.get(url, options);
19 | return data;
20 | } catch (error) {
21 | throw new wikiError(error);
22 | }
23 | }
24 |
25 | // Makes a request to legacy php endpoint
26 | async function makeRequest(params: any, redirect = true): Promise {
27 | const search = { ...params };
28 | search['format'] = 'json';
29 | if (redirect) {
30 | search['redirects'] = '';
31 | }
32 | if (!params.action) {
33 | search['action'] = "query";
34 | }
35 | search['origin'] = '*';
36 | let searchParam = '';
37 | Object.keys(search).forEach(key => {
38 | searchParam += `${key}=${search[key]}&`;
39 | });
40 |
41 | return await callAPI(encodeURI(API_URL + searchParam));
42 | }
43 |
44 | // Makes a request to rest api endpoint
45 | export async function makeRestRequest(path: string, redirect = true): Promise {
46 | if (!redirect) {
47 | path += '?redirect=false';
48 | }
49 |
50 | return await callAPI(encodeURI(REST_API_URL + path));
51 | }
52 |
53 | //return rest uri
54 | export function returnRestUrl(path: string): string {
55 | return encodeURI(REST_API_URL + path);
56 | }
57 |
58 | //change language of both urls
59 | export function setAPIUrl(prefix: string) : string {
60 | API_URL = 'https://' + prefix.toLowerCase() + '.wikipedia.org/w/api.php?';
61 | REST_API_URL = 'https://' + prefix.toLowerCase() + '.wikipedia.org/api/rest_v1/';
62 | return API_URL;
63 | }
64 |
65 | //change user agent
66 | export function setUserAgent(userAgent: string) {
67 | USER_AGENT = userAgent;
68 | }
69 |
70 | export default makeRequest;
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/source/resultTypes.ts:
--------------------------------------------------------------------------------
1 | export interface wikiSearchResult {
2 | results: any[],
3 | suggestion: string
4 | }
5 |
6 | export interface pageResult {
7 | pageid: number,
8 | ns: number,
9 | title: string,
10 | contentmodel: string,
11 | pagelanguage: string,
12 | pagelanguagehtmlcode: string,
13 | pagelanguagedir: string,
14 | touched: string,
15 | lastrevid: number,
16 | length: number,
17 | fullurl: string,
18 | editurl: string,
19 | canonicalurl: string
20 | }
21 |
22 | export interface imageResult {
23 | pageid: number,
24 | ns: number,
25 | title: string,
26 | imagerepository: string,
27 | imageinfo: any,
28 | url: string
29 | }
30 |
31 | export interface languageResult {
32 | [key: string]: string
33 | }
34 |
35 | export interface geoSearchResult {
36 | pageid: number,
37 | ns: number,
38 | title: string,
39 | lat: number,
40 | lon: number,
41 | dist: number,
42 | primary: string,
43 | type: string
44 | }
45 |
46 | export interface coordinatesResult {
47 | lat: number
48 | lon: number,
49 | primary: string,
50 | globe: string
51 | }
52 |
53 | export interface langLinksResult {
54 | lang: string,
55 | title: string,
56 | url: string
57 | }
58 |
59 | export interface wikiSummary {
60 | ns?: number,
61 | index?: number,
62 | type: string,
63 | title: string,
64 | displaytitle: string,
65 | namespace: { id: number, text: string },
66 | wikibase_item: string,
67 | titles: { canonical: string, normalized: string, display: string },
68 | pageid: number,
69 | thumbnail: {
70 | source: string,
71 | width: number,
72 | height: number
73 | },
74 | originalimage: {
75 | source: string,
76 | width: number,
77 | height: number
78 | },
79 | lang: string,
80 | dir: string,
81 | revision: string,
82 | tid: string,
83 | timestamp: string,
84 | description: string,
85 | description_source: string,
86 | content_urls: {
87 | desktop: {
88 | page: string,
89 | revisions: string,
90 | edit: string,
91 | talk: string
92 | },
93 | mobile: {
94 | page: string,
95 | revisions: string,
96 | edit: string,
97 | talk: string
98 | }
99 | },
100 | extract: string
101 | extract_html: string
102 | normalizedtitle?: string,
103 | coordinates?: {
104 | lat: number,
105 | lon: number
106 | }
107 | }
108 |
109 | export interface MostRead extends wikiSummary {
110 | views: number;
111 | rank: number;
112 | view_history: [
113 | {
114 | date: string;
115 | views: number;
116 | }
117 | ]
118 | }
119 |
120 | export interface wikiMediaResult {
121 | revision: string,
122 | tid: string,
123 | items: Array
124 | }
125 |
126 | export interface mediaResult {
127 | title: string,
128 | section_id: number,
129 | type: string,
130 | caption?: htmlText,
131 | showInGallery: boolean,
132 | srcset: Array
133 | }
134 |
135 | export interface srcResult {
136 | src: string,
137 | scale: string
138 | }
139 |
140 | export interface eventResult {
141 | births?: [
142 | {
143 | text: string,
144 | pages: Array
145 | year?: number
146 | }
147 | ],
148 | deaths?: [
149 | {
150 | text: string,
151 | pages: Array,
152 | year?: number
153 | }
154 | ],
155 | events?: [
156 | {
157 | text: string,
158 | pages: Array,
159 | year?: number
160 | }
161 | ],
162 | holidays?: [
163 | {
164 | text: string,
165 | pages: Array
166 | }
167 | ],
168 | selected?: [
169 | {
170 | text: string,
171 | pages: Array,
172 | year?: number
173 | }
174 | ]
175 | }
176 |
177 | export interface titleItem {
178 | title: string,
179 | page_id: number,
180 | rev: number,
181 | tid: number,
182 | namespace: number,
183 | user_id: number,
184 | user_text: string,
185 | timestamp: string,
186 | comment: string,
187 | tags: Array,
188 | restrictions: Array,
189 | page_language: string,
190 | redirect: boolean
191 | }
192 |
193 | export interface title {
194 | items: Array
195 | }
196 |
197 | export interface relatedResult {
198 | pages: Array
199 | }
200 |
201 | export interface mobileSections {
202 | lead: {
203 | ns: number,
204 | id: number,
205 | revision: string,
206 | lastmodified: string,
207 | lastmodifier: {
208 | user: string,
209 | gender: string
210 | },
211 | displaytitle: string,
212 | normalizedtitle: string,
213 | wikibase_item: string,
214 | description: string,
215 | description_source: string,
216 | protection: Record,
217 | editable: boolean,
218 | languagecount: number,
219 | image: {
220 | file: string,
221 | urls: {
222 | 320: string,
223 | 640: string,
224 | 800: string,
225 | 1024: string
226 | }
227 | },
228 | issues: Array,
229 | geo?: {
230 | latitude: string,
231 | longitude: string
232 | }
233 | sections: Array
234 | },
235 | remaining: {
236 | sections: Array
237 | }
238 | }
239 |
240 | export interface section {
241 | id: number,
242 | text: string,
243 | toclevel: number,
244 | line: string,
245 | anchor: string
246 | }
247 |
248 | export interface htmlText {
249 | html: string,
250 | text: string
251 | }
252 |
253 | export interface Artist extends htmlText {
254 | name: string;
255 | user_page?: string;
256 | }
257 |
258 | export interface Description extends htmlText {
259 | lang: string;
260 | }
261 |
262 | export interface notFound {
263 | type: string,
264 | title: string,
265 | method: string,
266 | detail: string,
267 | uri: string
268 | }
269 |
270 | export interface featuredContentResult {
271 | tfa: wikiSummary;
272 | mostread: {
273 | date: string;
274 | articles: Array
275 | };
276 | image: {
277 | title: string;
278 | thumbnail: {
279 | source: string;
280 | width: number;
281 | height: number;
282 | };
283 | image: {
284 | source: string;
285 | width: number;
286 | height: number;
287 | };
288 | file_page: string;
289 | artist: Artist;
290 | credit: htmlText;
291 | license: {
292 | type: string;
293 | code: string;
294 | };
295 | description: Description;
296 | wb_entity_id: string;
297 | structured: {
298 | captions: {
299 | [key: string]: string;
300 | }
301 | };
302 | };
303 | news: [
304 | {
305 | links: Array;
306 | story: string;
307 | }
308 | ];
309 | onthisday: [
310 | {
311 | text: string;
312 | pages: Array;
313 | year: number;
314 | }
315 | ]
316 | }
--------------------------------------------------------------------------------
/source/utils.ts:
--------------------------------------------------------------------------------
1 | import wiki from ".";
2 | import { pageError } from "./errors";
3 | import { MSGS } from "./messages";
4 |
5 | //check if input is string
6 | export function isString(title: any){
7 | return isNaN(title);
8 | }
9 |
10 | //set title for page in case autoSuggest is true
11 | export async function setTitleForPage(title: string) {
12 | {
13 | const searchResult = await wiki.search(title, { limit: 1, suggestion: true })
14 | if (!searchResult.suggestion && searchResult.results.length == 0) {
15 | throw new pageError(`${MSGS.PAGE_NOT_SUGGEST}${title}`)
16 | }
17 | title = searchResult.suggestion || title;
18 | return title;
19 | }
20 | }
21 |
22 | //Set page id or title param for legacy api queries
23 | export function setPageIdOrTitleParam(params: any, title: string) {
24 | if (isString(title)) {
25 | params.titles = title
26 | } else {
27 | params.pageids = title
28 | }
29 | return params;
30 | }
31 |
32 | //Get page id from params or from results
33 | export function setPageId(params: any, results: any): number {
34 | let pageId;
35 | if (params.pageIds) {
36 | pageId = params.pageIds;
37 | } else {
38 | pageId = Object.keys(results.query.pages)[0];
39 | }
40 | return pageId;
41 | }
42 |
43 | //Get current year
44 | export function getCurrentYear(): number {
45 | const date = new Date();
46 | const year = date.getFullYear();
47 | return (year);
48 | }
49 |
50 | //Get current month
51 | export function getCurrentMonth(): number {
52 | const date = new Date();
53 | const month = date.getMonth();
54 | return (month + 1); //javascript months are indexed at zero for some reason
55 | }
56 |
57 | //Get current day
58 | export function getCurrentDay(): number {
59 | const date = new Date();
60 | const day = date.getDate();
61 | return day;
62 | }
--------------------------------------------------------------------------------
/test/categories.test.ts:
--------------------------------------------------------------------------------
1 | import { categoriesError } from '../source/errors';
2 | import Page, { categories } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const categoryMock = {
11 | 500: { categories: [{title:"Category1"}, {title: "Category2"}] }
12 | }
13 |
14 | const categoryResult = ["Category1", "Category2"]
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('Category method on page object returns without calling request if _categories field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: categoryMock } } });
23 | const page = new Page(pageJson);
24 | page._categories = []
25 | const result = await page.categories();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._categories);
28 | });
29 |
30 | test('category method on page object returns array of strings', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: categoryMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.categories();
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(categoryResult);
36 | });
37 |
38 | test('category method on page throws category error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.categories()
43 | };
44 | expect(t).rejects.toThrowError(categoriesError);
45 | });
46 |
47 | test('Throws category error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await categories("Test")
51 | };
52 | expect(t).rejects.toThrowError(categoriesError);
53 | });
54 |
55 | test('Returns empty if no categories are available', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: {500: {categories:[]}} } } });
57 | const result = await categories("Test");
58 | expect(result).toStrictEqual([]);
59 | });
60 |
61 | test('Returns with results an array of string', async () => {
62 | requestMock.mockImplementation(async () => { return { query: { pages: categoryMock } } });
63 | const result = await categories("Test");
64 | expect(result).toStrictEqual(categoryResult);
65 | });
66 |
67 | test('category method on index throws category error if response is empty', async () => {
68 | requestMock.mockImplementation(async () => { return [] });
69 | const t = async () => {
70 | await wiki.categories("Test");
71 | };
72 | expect(t).rejects.toThrowError(categoriesError);
73 | });
74 |
75 | test('categories method on index returns array of strings', async () => {
76 | requestMock.mockImplementation(async () => { return { query: { pages: categoryMock } } });
77 | const result = await wiki.categories("Test");
78 | expect(setTitleMock).toHaveBeenCalledTimes(0);
79 | expect(result).toStrictEqual(categoryResult);
80 | });
81 |
82 | test('category method on index returns array of strings even when autosuggest is true', async () => {
83 | requestMock.mockImplementation(async () => { return { query: { pages: categoryMock } } });
84 | setTitleMock.mockImplementation(async () => { return "test" });
85 | const result = await wiki.categories("Test", { autoSuggest: true });
86 | expect(setTitleMock).toHaveBeenCalledTimes(1);
87 | expect(result).toStrictEqual(categoryResult);
88 | });
--------------------------------------------------------------------------------
/test/citation.test.ts:
--------------------------------------------------------------------------------
1 | import * as request from '../source/request';
2 | import wiki, { citationError } from "../source/index";
3 | import { mobileSections, citationData, title } from './samples';
4 | import Page, { citation } from '../source/page';
5 | import { pageJson } from './samples';
6 | const requestMock = jest.spyOn(request, "makeRestRequest");
7 |
8 | afterAll(() => {
9 | requestMock.mockRestore();
10 | })
11 |
12 | test('Throws error if response is error', async () => {
13 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
14 | const err = async () => { await wiki.citation("test", "mediawiki", "fr") };
15 | expect(err).rejects.toThrowError(citationError);
16 | });
17 |
18 | test('Returns citation data', async () => {
19 | requestMock.mockImplementation(async () => { return citationData });
20 | const result = await wiki.citation("test", "mediawiki");
21 | expect(result).toStrictEqual(citationData);
22 | });
23 |
24 | test('Returns summary and format as wikimedia by default', async () => {
25 | requestMock.mockImplementation(async () => { return citationData });
26 | const result = await wiki.citation("test");
27 | expect(result).toStrictEqual(citationData);
28 | });
29 |
30 | test('Throws category error if response is empty', async () => {
31 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
32 | const t = async () => {
33 | await citation("Test")
34 | };
35 | expect(t).rejects.toThrowError(citationError);
36 | });
37 |
38 | test('Returns citation data', async () => {
39 | requestMock.mockImplementation(async () => { return citationData });
40 | const result = await citation("Test");
41 | expect(result).toStrictEqual(citationData);
42 | });
--------------------------------------------------------------------------------
/test/content.test.ts:
--------------------------------------------------------------------------------
1 | import { contentError } from '../source/errors';
2 | import Page, { content } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const contentMock = {
11 | 500: { revisions: [{ revid: "100", parentid: "200" }],
12 | extract: "This is the content" }
13 | }
14 |
15 | const contentResult = "This is the content"
16 |
17 | const contentWithIds = {
18 | result: contentResult,
19 | ids: {
20 | revisionId: "100",
21 | parentId: "200"
22 | }
23 | }
24 |
25 | afterAll(() => {
26 | requestMock.mockRestore();
27 | setTitleMock.mockRestore();
28 | })
29 |
30 | test('content method on page object returns without calling request if _content field set', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: contentMock } } });
32 | const page = new Page(pageJson);
33 | page._content = "Test content"
34 | const result = await page.content();
35 | expect(requestMock).toHaveBeenCalledTimes(0);
36 | expect(result).toStrictEqual(page._content);
37 | });
38 |
39 | test('content method on page object returns content', async () => {
40 | requestMock.mockImplementation(async () => { return { query: { pages: contentMock } } });
41 | const page = new Page(pageJson);
42 | const result = await page.content({redirect: true});
43 | expect(requestMock).toHaveBeenCalledTimes(1);
44 | expect(result).toStrictEqual(contentResult);
45 | });
46 |
47 | test('content method on page throws content error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const page = new Page(pageJson);
50 | const t = async () => {
51 | await page.content();
52 | };
53 | expect(t).rejects.toThrowError(contentError);
54 | });
55 |
56 | test('Throws content error if response is empty', async () => {
57 | requestMock.mockImplementation(async () => { return [] });
58 | const t = async () => {
59 | await content("Test")
60 | };
61 | expect(t).rejects.toThrowError(contentError);
62 | });
63 |
64 | test('Returns with results as string', async () => {
65 | requestMock.mockImplementation(async () => { return { query: { pages: contentMock } } });
66 | const result = await content("Test");
67 | expect(result).toStrictEqual(contentWithIds);
68 | });
69 |
70 | test('content method on index throws content error if response is empty', async () => {
71 | requestMock.mockImplementation(async () => { return [] });
72 | const t = async () => {
73 | await wiki.content("Test")
74 | };
75 | expect(t).rejects.toThrowError(contentError);
76 | });
77 |
78 | test('content method on index returns a string', async () => {
79 | requestMock.mockImplementation(async () => { return { query: { pages: contentMock } } });
80 | const result = await wiki.content("Test");
81 | expect(setTitleMock).toHaveBeenCalledTimes(0);
82 | expect(result).toStrictEqual(contentResult);
83 | });
84 |
85 | test('content method on index returns a string even when autosuggest is true', async () => {
86 | requestMock.mockImplementation(async () => { return { query: { pages: contentMock } } });
87 | setTitleMock.mockImplementation(async () => { return "test" });
88 | const result = await wiki.content("Test", { autoSuggest: true });
89 | expect(setTitleMock).toHaveBeenCalledTimes(1);
90 | expect(result).toStrictEqual(contentResult);
91 | });
--------------------------------------------------------------------------------
/test/coordinates.test.ts:
--------------------------------------------------------------------------------
1 | import { coordinatesError } from '../source/errors';
2 | import Page, { coordinates } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const coordinatesMock = {
11 | 500: { coordinates: [{lat: 51.17, lon: 30.15, primary: "", globe: "earth"}] }
12 | }
13 |
14 | const coordinatesResult = {lat: 51.17, lon: 30.15, primary: "", globe: "earth"}
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('Coordinates method on page object returns without calling request if _coordinates field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: coordinatesMock } } });
23 | const page = new Page(pageJson);
24 | page._coordinates = coordinatesResult;
25 | const result = await page.coordinates();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._coordinates);
28 | });
29 |
30 | test('Coordinates method on page object returns coordinates', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: coordinatesMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.coordinates({redirect: true});
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(coordinatesResult);
36 | });
37 |
38 | test('coordinates method on page throws coordinates error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.coordinates()
43 | };
44 | expect(t).rejects.toThrowError(coordinatesError);
45 | });
46 |
47 | test('Throws coordinates error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await coordinates("Test")
51 | };
52 | expect(t).rejects.toThrowError(coordinatesError);
53 | });
54 |
55 | test('Returns with results as coordinatesResult', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: coordinatesMock } } });
57 | const result = await coordinates("Test", true);
58 | expect(result).toStrictEqual(coordinatesResult);
59 | });
60 |
61 | test('Returns with results as null if coordinates not present', async () => {
62 | requestMock.mockImplementation(async () => { return { query: { pages: {500:{}} } } });
63 | const result = await coordinates("Test", true);
64 | expect(result).toStrictEqual(null);
65 | });
66 |
67 |
68 | test('coordinate method on index throws coordinates error if response is empty', async () => {
69 | requestMock.mockImplementation(async () => { return [] });
70 | const t = async () => {
71 | await wiki.coordinates("Test")
72 | };
73 | expect(t).rejects.toThrowError(coordinatesError);
74 | });
75 |
76 | test('coordinates method on index returns a coordinatesResult', async () => {
77 | requestMock.mockImplementation(async () => { return { query: { pages: coordinatesMock } } });
78 | const result = await wiki.coordinates("Test");
79 | expect(setTitleMock).toHaveBeenCalledTimes(0);
80 | expect(result).toStrictEqual(coordinatesResult);
81 | });
82 |
83 | test('coordinates method on index returns a coordinatesResult even when autosuggest is true', async () => {
84 | requestMock.mockImplementation(async () => { return { query: { pages: coordinatesMock } } });
85 | setTitleMock.mockImplementation(async () => { return "test" });
86 | const result = await wiki.coordinates("Test", { autoSuggest: true });
87 | expect(setTitleMock).toHaveBeenCalledTimes(1);
88 | expect(result).toStrictEqual(coordinatesResult);
89 | });
--------------------------------------------------------------------------------
/test/featuredContent.test.ts:
--------------------------------------------------------------------------------
1 | import { fcError } from '../source/errors';
2 | import * as request from '../source/request';
3 | import wiki from "../source/index";
4 | import { fcData } from './samples';
5 | const requestMock = jest.spyOn(request, "makeRestRequest");
6 |
7 | const fcMock = fcData;
8 |
9 | afterAll(() => {
10 | requestMock.mockRestore();
11 | })
12 |
13 | test('Throws featured content error if response is error', async () => {
14 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
15 | const result = async () => {
16 | await wiki.featuredContent({})
17 | };
18 | expect(result).rejects.toThrowError(fcError);
19 | });
20 |
21 | test('Returns with results as fcResult', async () => {
22 | requestMock.mockImplementation(async () => { return fcMock });
23 | const result = await wiki.featuredContent();
24 | expect(result).toStrictEqual(fcMock);
25 | });
26 |
27 | test('Featured content method call with params passed and no padding', async () => {
28 | requestMock.mockImplementation(async () => { return fcMock });
29 | const result = await wiki.featuredContent({ year: '2020', month: '1', day: '1' });
30 | expect(result).toStrictEqual(fcMock);
31 | expect(requestMock).toBeCalledWith(`feed/featured/2020/01/01`, true);
32 | });
33 |
34 | test('Featured content method call with params passed', async () => {
35 | requestMock.mockImplementation(async () => { return fcMock });
36 | const result = await wiki.featuredContent({ year: '2020', month: '01', day: '01' });
37 | expect(result).toStrictEqual(fcMock);
38 | expect(requestMock).toBeCalledWith(`feed/featured/2020/01/01`, true);
39 | });
--------------------------------------------------------------------------------
/test/html.test.ts:
--------------------------------------------------------------------------------
1 | import { htmlError } from '../source/errors';
2 | import Page, { html } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const htmlMock = {
11 | 500: { revisions: [{ "*": "" }] }
12 | }
13 |
14 | const htmlResult = ""
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('html method on page object returns without calling request if _html field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: htmlMock } } });
23 | const page = new Page(pageJson);
24 | page._html = ""
25 | const result = await page.html();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._html);
28 | });
29 |
30 | test('html method on page object returns html', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: htmlMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.html({redirect: true});
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(htmlResult);
36 | });
37 |
38 | test('html method on page throws html error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.html();
43 | };
44 | expect(t).rejects.toThrowError(htmlError);
45 | });
46 |
47 | test('Throws html error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await html("Test")
51 | };
52 | expect(t).rejects.toThrowError(htmlError);
53 | });
54 |
55 | test('Returns with results as string', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: htmlMock } } });
57 | const result = await html("Test");
58 | expect(result).toStrictEqual(htmlResult);
59 | });
60 |
61 | test('html method on index throws html error if response is empty', async () => {
62 | requestMock.mockImplementation(async () => { return [] });
63 | const t = async () => {
64 | await wiki.html("Test");
65 | };
66 | expect(t).rejects.toThrowError(htmlError);
67 | });
68 |
69 | test('html method on index returns a string', async () => {
70 | requestMock.mockImplementation(async () => { return { query: { pages: htmlMock } } });
71 | const result = await wiki.html("Test");
72 | expect(setTitleMock).toHaveBeenCalledTimes(0);
73 | expect(result).toStrictEqual(htmlResult);
74 | });
75 |
76 | test('html method on index returns a string even when autosuggest is true', async () => {
77 | requestMock.mockImplementation(async () => { return { query: { pages: htmlMock } } });
78 | setTitleMock.mockImplementation(async () => { return "test" });
79 | const result = await wiki.html("Test", { autoSuggest: true });
80 | expect(setTitleMock).toHaveBeenCalledTimes(1);
81 | expect(result).toStrictEqual(htmlResult);
82 | });
--------------------------------------------------------------------------------
/test/images.test.ts:
--------------------------------------------------------------------------------
1 | import { imageError } from '../source/errors';
2 | import Page, { images } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const imageMock = {
11 | 500: { pageid: 500, ns: 0, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }] },
12 | 501: { pageid: 501, ns: 1, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: "testUrl" }] }
13 | }
14 |
15 | const imageResult = [{ pageid: 500, ns: 0, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }], url: 'testUrl' },
16 | { pageid: 501, ns: 1, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }], url: 'testUrl' }]
17 |
18 | afterAll(() => {
19 | requestMock.mockRestore();
20 | setTitleMock.mockRestore();
21 | })
22 |
23 | test('Image method on page object returns without calling request if _images field set', async () => {
24 | requestMock.mockImplementation(async () => { return { query: { pages: imageMock } } });
25 | const page = new Page(pageJson);
26 | page._images = []
27 | const result = await page.images();
28 | expect(requestMock).toHaveBeenCalledTimes(0);
29 | expect(result).toStrictEqual([]);
30 | });
31 |
32 | test('Image method on page object returns array of images', async () => {
33 | requestMock.mockImplementation(async () => { return { query: { pages: imageMock } } });
34 | const page = new Page(pageJson);
35 | const result = await page.images();
36 | expect(requestMock).toHaveBeenCalledTimes(1);
37 | expect(result).toStrictEqual(imageResult);
38 | });
39 |
40 | test('images method on page throws image error if response is empty', async () => {
41 | requestMock.mockImplementation(async () => { return [] });
42 | const page = new Page(pageJson);
43 | const t = async () => {
44 | await page.images();
45 | };
46 | expect(t).rejects.toThrowError(imageError);
47 | });
48 |
49 | test('Throws image error if response is empty', async () => {
50 | requestMock.mockImplementation(async () => { return [] });
51 | const t = async () => {
52 | await images("Test")
53 | };
54 | expect(t).rejects.toThrowError(imageError);
55 | });
56 |
57 | test('Returns empty if no images are available', async () => {
58 | requestMock.mockImplementation(async () => { return { query: { pages: {} } } });
59 | const result = await images("Test");
60 | expect(result).toStrictEqual([]);
61 | });
62 |
63 | test('Returns with results an array of imageResult object', async () => {
64 | requestMock.mockImplementation(async () => { return { query: { pages: imageMock } } });
65 | const result = await images("Test");
66 | expect(result).toStrictEqual(imageResult);
67 | });
68 |
69 | test('image method on index throws image error if response is empty', async () => {
70 | requestMock.mockImplementation(async () => { return [] });
71 | const t = async () => {
72 | await wiki.images("Test")
73 | };
74 | expect(t).rejects.toThrowError(imageError);
75 | });
76 |
77 |
78 | test('Image method on index returns array of images', async () => {
79 | requestMock.mockImplementation(async () => { return { query: { pages: imageMock } } });
80 | const result = await wiki.images("Test");
81 | expect(setTitleMock).toHaveBeenCalledTimes(0);
82 | expect(result).toStrictEqual(imageResult);
83 | });
84 |
85 | test('Image method on index returns array of images even when autosuggest is true', async () => {
86 | requestMock.mockImplementation(async () => { return { query: { pages: imageMock } } });
87 | setTitleMock.mockImplementation(async () => { return "test" });
88 | const result = await wiki.images("Test", { autoSuggest: true });
89 | expect(setTitleMock).toHaveBeenCalledTimes(1);
90 | expect(result).toStrictEqual(imageResult);
91 | });
--------------------------------------------------------------------------------
/test/index.test.ts:
--------------------------------------------------------------------------------
1 | import { searchError, pageError, geoSearchError, wikiError, autocompletionsError } from '../source/errors';
2 | import * as request from '../source/request';
3 | import wiki from "../source/index";
4 | import Page from '../source/page';
5 | import * as utils from '../source/utils';
6 | const requestMock = jest.spyOn(request, "default");
7 | const restRequestMock = jest.spyOn(request, "makeRestRequest");
8 | import { pageJson, summaryJson } from './samples';
9 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
10 |
11 | const searchMock = {
12 | search: ["search1", "search2"],
13 | searchinfo: { suggestion: "suggest" }
14 | }
15 |
16 | const searchResult = {
17 | results: ["search1", "search2"],
18 | suggestion: "suggest"
19 | }
20 |
21 | const imageMock = {
22 | 500: { pageid: 500, ns: 0, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }] },
23 | 501: { pageid: 501, ns: 1, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: "testUrl" }] }
24 | }
25 |
26 | const imageResult = [{ pageid: 500, ns: 0, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }], url: 'testUrl' },
27 | { pageid: 501, ns: 1, title: 'test', imagerepository: 'testRepo', imageinfo: [{ url: 'testUrl' }], url: 'testUrl' }]
28 |
29 | const autocompletionsMock = ["Test", ["Test", "Testosterone", "Testicle", "Test cricket", "Test-driven development"]]
30 |
31 | const pageObject = new Page(pageJson);
32 |
33 | afterAll(() => {
34 | requestMock.mockRestore();
35 | setTitleMock.mockRestore();
36 | restRequestMock.mockRestore();
37 | })
38 |
39 | test('Default wiki returns results as Page Class', async () => {
40 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } });
41 | const result = await wiki("Test");
42 | expect(result.toString()).toStrictEqual(pageObject.toString());
43 | });
44 |
45 | test('Throws search error if some error occurs', async () => {
46 | requestMock.mockImplementation(async () => { return { searchMock } });
47 | const t = async () => {
48 | await wiki.search("Test")
49 | };
50 | expect(t).rejects.toThrowError(searchError);
51 | });
52 |
53 | test('Search returns results as wikiSearchResult', async () => {
54 | requestMock.mockImplementation(async () => { return { query: searchMock } });
55 | const result = await wiki.search("Test", {suggestion: true});
56 | expect(result).toStrictEqual(searchResult);
57 | });
58 |
59 | test('Search returns results as wikiSearchResult with suggestions as null', async () => {
60 | requestMock.mockImplementation(async () => {
61 | return {
62 | query: {
63 | search: ["search1", "search2"]
64 | }
65 | }
66 | });
67 | const result = await wiki.search("Test", {suggestion: false});
68 | expect(result).toStrictEqual({
69 | results: ["search1", "search2"],
70 | suggestion: null
71 | });
72 | });
73 |
74 | test('Autocompletions returns results as array of strings', async () => {
75 | requestMock.mockImplementation(async () => { return autocompletionsMock });
76 | const result = await wiki.autocompletions("Test");
77 | expect(result).toStrictEqual(
78 | ["Test", "Testosterone", "Testicle", "Test cricket", "Test-driven development"]
79 | );
80 | });
81 |
82 | test('Throws autocompletions error if some error occurs', async () => {
83 | requestMock.mockImplementation(async () => { return { autocompletionsMock } });
84 | const t = async () => {
85 | await wiki.autocompletions("Test")
86 | };
87 | expect(t).rejects.toThrowError(autocompletionsError);
88 | });
89 |
90 | test('Throws page error if result doesnt have page', async () => {
91 | requestMock.mockImplementation(async () => { return { } });
92 | const t = async () => {
93 | await wiki.page("Test")
94 | };
95 | expect(t).rejects.toThrowError(pageError);
96 | });
97 |
98 | test('Page throws error if missing attribute present in page', async () => {
99 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: { missing: '' } } } } });
100 | const t = async () => {
101 | await wiki.page("Test")
102 | };
103 | expect(t).rejects.toThrowError(pageError);
104 | });
105 |
106 | test('Page returns results as Page Class', async () => {
107 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } });
108 | const result = await wiki.page("Test");
109 | expect(result.toString()).toStrictEqual(pageObject.toString());
110 | });
111 |
112 | test('Page returns results as Page Class with auto suggest set to true', async () => {
113 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } });
114 | setTitleMock.mockImplementation(async () => { return "test" });
115 | const result = await wiki.page("Test", {autoSuggest: true});
116 | expect(result.toString()).toStrictEqual(pageObject.toString());
117 | });
118 |
119 | test('Page returns results as Page Class and loads default fields when preload set to true', async () => {
120 | requestMock.mockImplementationOnce(async () => { return { query: { pages: { 500: pageJson } } } })
121 | .mockImplementationOnce(async () => { return { query: { pages: imageMock } } });
122 | restRequestMock.mockImplementation(async () => { return summaryJson })
123 | const result = await wiki.page("Test", { preload: true, autoSuggest: false });
124 | expect(result.toString()).toStrictEqual(pageObject.toString());
125 | expect(result._summary).toStrictEqual(summaryJson);
126 | expect(result._images).toStrictEqual(imageResult);
127 | });
128 |
129 | test('Page returns results as Page Class and loads fields present in fields when preload set to true', async () => {
130 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } });
131 | restRequestMock.mockImplementation(async () => { return summaryJson });
132 | const result = await wiki.page("Test", { preload: true, fields: ["summary"] });
133 | expect(result.toString()).toStrictEqual(pageObject.toString());
134 | expect(result._summary).toStrictEqual(summaryJson);
135 | expect(result._images).toBeFalsy();
136 | });
137 |
138 | test('Page returns results as Page Class and loads fields present in fields when preload set to true', async () => {
139 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } });
140 | restRequestMock.mockImplementation(async () => { return summaryJson });
141 | const t = async () => {
142 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment
143 | // @ts-ignore: Type error
144 | await wiki.page("Test", { preload: true, fields: ["errorMethod"] })
145 | };
146 | expect(t).rejects.toThrowError(pageError);
147 | });
148 |
149 | test('Languages method throws wikiError if error', async () => {
150 | requestMock.mockImplementation(async () => { throw new Error("error")});
151 | const t = async () => {
152 | await wiki.languages();
153 | };
154 | expect(t).rejects.toThrowError(wikiError);
155 | });
156 |
157 | test('Languages method returns array of languageResult', async () => {
158 | requestMock.mockImplementation(async () => { return { query: { languages: [{ code: "test1", "*": "" }, { code: "test2", "*": "" }] } } });
159 | const result = await wiki.languages();
160 | expect(result).toStrictEqual([{ "test1": "" }, { "test2": "" }]);
161 | });
162 |
163 | test('Set language returns api url with language set', () => {
164 | const result = wiki.setLang("mal");
165 | expect(result).toStrictEqual("https://mal.wikipedia.org/w/api.php?");
166 | });
167 |
168 | test('Geo search error is thrown in case of error', async () => {
169 | requestMock.mockImplementation(async () => { return {} });
170 | const t = async () => {
171 | await wiki.geoSearch(2.088, 4.023)
172 | };
173 | expect(t).rejects.toThrowError(geoSearchError);
174 | });
175 |
176 | test('geoSearch returns results as geoSearchResult', async () => {
177 | requestMock.mockImplementation(async () => { return { query: { geosearch: [] } } });
178 | const result = await wiki.geoSearch(2.088, 4.023);
179 | expect(result).toStrictEqual([]);
180 | });
181 |
182 | test('geoSearch returns results as geoSearchResult with options', async () => {
183 | requestMock.mockImplementation(async () => { return { query: { geosearch: [] } } });
184 | const result = await wiki.geoSearch(2.088, 4.023, { radius: 5000, limit: 20 });
185 | expect(requestMock).toHaveBeenCalledWith(
186 | {
187 | 'list': 'geosearch',
188 | 'gsradius': 5000,
189 | 'gscoord': `${2.088}|${4.023}`,
190 | 'gslimit': 20,
191 | 'gsprop': 'type'
192 | }
193 | );
194 | expect(result).toStrictEqual([]);
195 | });
196 |
197 | test('Search error is thrown in case of error in suggest', async () => {
198 | requestMock.mockImplementation(async () => { throw new Error("Error") });
199 | const t = async () => {
200 | await wiki.suggest("Test")
201 | };
202 | expect(t).rejects.toThrowError(searchError);
203 | });
204 |
205 | test('Suggest returns null if suggestion not present', async () => {
206 | requestMock.mockImplementation(async () => { return { query: { searchinfo: {} } } });
207 | const result = await wiki.suggest("test");
208 | expect(result).toStrictEqual(null);
209 | });
210 |
211 | test('Suggest returns string', async () => {
212 | requestMock.mockImplementation(async () => { return { query: { searchinfo: {suggestion: "suggest"} } } });
213 | const result = await wiki.suggest("test");
214 | expect(result).toStrictEqual("suggest");
215 | });
216 |
217 | test('sets the user agent', async () => {
218 | let result = wiki.setUserAgent("testUser");
219 | expect(result).toStrictEqual(undefined);
220 | });
--------------------------------------------------------------------------------
/test/infobox.test.ts:
--------------------------------------------------------------------------------
1 | import { infoboxError } from '../source/errors';
2 | import Page, { infobox, rawInfo } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson, rawJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const rawResult= rawJson['*'];
11 | const rawMock = { 500: { revisions: [rawJson] } };
12 |
13 | const infoboxResult = {
14 | name: 'Linus Torvalds',
15 | image: 'LinuxCon Europe Linus Torvalds 03 (cropped).jpg',
16 | caption: 'Torvalds at LinuxCon Europe 2014'
17 | }
18 |
19 | afterAll(() => {
20 | requestMock.mockRestore();
21 | setTitleMock.mockRestore();
22 | })
23 |
24 | test('infobox method on page object returns without calling request if _infobox field set', async () => {
25 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
26 | const page = new Page(pageJson);
27 | page._infobox = infoboxResult;
28 | const result = await page.infobox();
29 | expect(requestMock).toHaveBeenCalledTimes(0);
30 | expect(result).toStrictEqual(page._infobox);
31 | });
32 |
33 | test('Infobox method on page object returns infobox', async () => {
34 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
35 | const page = new Page(pageJson);
36 | const result = await page.infobox({redirect: true});
37 | expect(requestMock).toHaveBeenCalledTimes(1);
38 | expect(result).toStrictEqual(infoboxResult);
39 | });
40 |
41 | test('infobox method on page throws infobox error if response is error', async () => {
42 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
43 | const page = new Page(pageJson);
44 | const t = async () => {
45 | await page.infobox();
46 | };
47 | expect(t).rejects.toThrowError(infoboxError);
48 | });
49 |
50 | test('Throws infobox error if response is error', async () => {
51 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
52 | const t = async () => {
53 | await infobox("Test")
54 | };
55 | expect(t).rejects.toThrowError(infoboxError);
56 | });
57 |
58 | test('Returns with results as any', async () => {
59 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
60 | const result = await infobox("Test", true);
61 | expect(result).toStrictEqual(infoboxResult);
62 | });
63 |
64 | test('infobox method on index throws infobox error if response is error', async () => {
65 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
66 | const t = async () => {
67 | await wiki.infobox("Test")
68 | };
69 | expect(t).rejects.toThrowError(infoboxError);
70 | });
71 |
72 | test('infobox method on index returns infobox', async () => {
73 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
74 | const result = await wiki.infobox("Test");
75 | expect(setTitleMock).toHaveBeenCalledTimes(0);
76 | expect(result).toStrictEqual(infoboxResult);
77 | });
78 |
79 | test('infobox method on index returns a infobox even when autosuggest is true', async () => {
80 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
81 | setTitleMock.mockImplementation(async () => { return "test" });
82 | const result = await wiki.infobox("Test", { autoSuggest: true });
83 | expect(setTitleMock).toHaveBeenCalledTimes(1);
84 | expect(result).toStrictEqual(infoboxResult);
85 | });
86 |
87 | test('rawinfo method returns a string', async () => {
88 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
89 | const result = await rawInfo("Test", {});
90 | expect(result).toStrictEqual(rawResult);
91 | });
92 |
93 | test('rawinfo method returns empty if * field is not present', async () => {
94 | requestMock.mockImplementation(async () => { return { query: { pages: { 500: { revisions: {} } } } } });
95 | const result = await rawInfo("Test", {});
96 | expect(result).toStrictEqual('');
97 | });
98 |
99 | test('rawinfo method throws an error', async () => {
100 | requestMock.mockImplementation(async () => { return {} });
101 | const t = async () => {
102 | await rawInfo("Test", {})
103 | };
104 | expect(t).rejects.toThrowError(infoboxError);
105 | });
--------------------------------------------------------------------------------
/test/intro.test.ts:
--------------------------------------------------------------------------------
1 | import { introError } from '../source/errors';
2 | import Page, { intro } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const introMock = {
11 | 500: { extract: "This is a test intro" }
12 | }
13 |
14 | const introResult = "This is a test intro"
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('Intro method on page object returns without calling request if _intro field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: introMock } } });
23 | const page = new Page(pageJson);
24 | page._intro = "test intro"
25 | const result = await page.intro();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._intro);
28 | });
29 |
30 | test('Intro method on page object returns intro', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: introMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.intro({redirect: true});
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(introResult);
36 | });
37 |
38 | test('intro method on page throws intro error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.intro();
43 | };
44 | expect(t).rejects.toThrowError(introError);
45 | });
46 |
47 | test('Throws intro error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await intro("Test")
51 | };
52 | expect(t).rejects.toThrowError(introError);
53 | });
54 |
55 | test('Returns with results as string', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: introMock } } });
57 | const result = await intro("Test");
58 | expect(result).toStrictEqual(introResult);
59 | });
60 |
61 | test('intro method on index throws intro error if response is empty', async () => {
62 | requestMock.mockImplementation(async () => { return [] });
63 | const t = async () => {
64 | await wiki.intro("Test")
65 | };
66 | expect(t).rejects.toThrowError(introError);
67 | });
68 |
69 | test('Intro method on index returns a string', async () => {
70 | requestMock.mockImplementation(async () => { return { query: { pages: introMock } } });
71 | const result = await wiki.intro("Test");
72 | expect(setTitleMock).toHaveBeenCalledTimes(0);
73 | expect(result).toStrictEqual(introResult);
74 | });
75 |
76 | test('Intro method on index returns a string even when autosuggest is true', async () => {
77 | requestMock.mockImplementation(async () => { return { query: { pages: introMock } } });
78 | setTitleMock.mockImplementation(async () => { return "test" });
79 | const result = await wiki.intro("Test", { autoSuggest: true });
80 | expect(setTitleMock).toHaveBeenCalledTimes(1);
81 | expect(result).toStrictEqual(introResult);
82 | });
--------------------------------------------------------------------------------
/test/langlinks.test.ts:
--------------------------------------------------------------------------------
1 | import { linksError } from '../source/errors';
2 | import Page, { langLinks } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const langLinkskMock = {
11 | 500: { langlinks: [{"*":"Link1", lang: "en", url: "url1"}, {"*": "Link2", lang: "fr", url: "url2"}] }
12 | }
13 |
14 | const langLinksResult = [{title:"Link1", lang: "en", url: "url1"}, {title: "Link2", lang: "fr", url: "url2"}]
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('Lang links method on page object returns without calling request if _langlinks field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: langLinkskMock } } });
23 | const page = new Page(pageJson);
24 | page._langLinks = []
25 | const result = await page.langLinks();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._langLinks);
28 | });
29 |
30 | test('lang links method on page object returns array of langLinksResult', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: langLinkskMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.langLinks();
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(langLinksResult);
36 | });
37 |
38 | test('lang links method on page throws links error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.langLinks()
43 | };
44 | expect(t).rejects.toThrowError(linksError);
45 | });
46 |
47 | test('Throws links error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await langLinks("Test")
51 | };
52 | expect(t).rejects.toThrowError(linksError);
53 | });
54 |
55 | test('Returns empty if no lang links are available', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: {500: {langlinks:[]}} } } });
57 | const result = await langLinks("Test");
58 | expect(result).toStrictEqual([]);
59 | });
60 |
61 | test('Returns empty if lang links object itself is not available', async () => {
62 | requestMock.mockImplementation(async () => { return { query: { pages: {404: {}} } } });
63 | const result = await langLinks("Test");
64 | expect(result).toStrictEqual([]);
65 | });
66 |
67 | test('Returns with results an array of langLinksResult object', async () => {
68 | requestMock.mockImplementation(async () => { return { query: { pages: langLinkskMock } } });
69 | const result = await langLinks("Test");
70 | expect(result).toStrictEqual(langLinksResult);
71 | });
72 |
73 | test('lang links method on index throws links error if response is empty', async () => {
74 | requestMock.mockImplementation(async () => { return [] });
75 | const t = async () => {
76 | await wiki.langLinks("Test")
77 | };
78 | expect(t).rejects.toThrowError(linksError);
79 | });
80 |
81 | test('lang links method on index returns array of langLinksResult object', async () => {
82 | requestMock.mockImplementation(async () => { return { query: { pages: langLinkskMock } } });
83 | const result = await wiki.langLinks("Test");
84 | expect(setTitleMock).toHaveBeenCalledTimes(0);
85 | expect(result).toStrictEqual(langLinksResult);
86 | });
87 |
88 | test('lang links method on index returns array of langLinksResult even when autosuggest is true', async () => {
89 | requestMock.mockImplementation(async () => { return { query: { pages: langLinkskMock } } });
90 | setTitleMock.mockImplementation(async () => { return "test" });
91 | const result = await wiki.langLinks("Test", { autoSuggest: true });
92 | expect(setTitleMock).toHaveBeenCalledTimes(1);
93 | expect(result).toStrictEqual(langLinksResult);
94 | });
--------------------------------------------------------------------------------
/test/links.test.ts:
--------------------------------------------------------------------------------
1 | import { linksError } from '../source/errors';
2 | import Page, { links } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const linkMock = {
11 | 500: { links: [{title:"Link1"}, {title: "Link2"}] }
12 | }
13 |
14 | const linkResult = ["Link1", "Link2"]
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('Links method on page object returns without calling request if _links field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: linkMock } } });
23 | const page = new Page(pageJson);
24 | page._links = []
25 | const result = await page.links();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._links);
28 | });
29 |
30 | test('link method on page object returns array of strings', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: linkMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.links();
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(linkResult);
36 | });
37 |
38 | test('links method on page throws links error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.links()
43 | };
44 | expect(t).rejects.toThrowError(linksError);
45 | });
46 |
47 | test('Throws links error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await links("Test")
51 | };
52 | expect(t).rejects.toThrowError(linksError);
53 | });
54 |
55 | test('Returns empty if no links are available', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: {500: {links:[]}} } } });
57 | const result = await links("Test");
58 | expect(result).toStrictEqual([]);
59 | });
60 |
61 | test('Returns with results an array of string', async () => {
62 | requestMock.mockImplementation(async () => { return { query: { pages: linkMock } } });
63 | const result = await links("Test");
64 | expect(result).toStrictEqual(linkResult);
65 | });
66 |
67 | test('links method on page throws links error if response is empty', async () => {
68 | requestMock.mockImplementation(async () => { return [] });
69 | const t = async () => {
70 | await wiki.links("Test")
71 | };
72 | expect(t).rejects.toThrowError(linksError);
73 | });
74 |
75 | test('links method on index returns array of strings', async () => {
76 | requestMock.mockImplementation(async () => { return { query: { pages: linkMock } } });
77 | const result = await wiki.links("Test");
78 | expect(setTitleMock).toHaveBeenCalledTimes(0);
79 | expect(result).toStrictEqual(linkResult);
80 | });
81 |
82 | test('links method on index returns array of strings even when autosuggest is true', async () => {
83 | requestMock.mockImplementation(async () => { return { query: { pages: linkMock } } });
84 | setTitleMock.mockImplementation(async () => { return "test" });
85 | const result = await wiki.links("Test", { autoSuggest: true });
86 | expect(setTitleMock).toHaveBeenCalledTimes(1);
87 | expect(result).toStrictEqual(linkResult);
88 | });
--------------------------------------------------------------------------------
/test/media.test.ts:
--------------------------------------------------------------------------------
1 | import { mediaError } from '../source/errors';
2 | import Page, { media } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson, mediaJson } from './samples';
7 | const requestMock = jest.spyOn(request, "makeRestRequest");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | afterAll(() => {
11 | requestMock.mockRestore();
12 | setTitleMock.mockRestore();
13 | })
14 |
15 | test('media method on page object returns without calling request if _media field set', async () => {
16 | requestMock.mockImplementation(async () => { return mediaJson });
17 | const page = new Page(pageJson);
18 | page._media = mediaJson;
19 | const result = await page.media();
20 | expect(requestMock).toHaveBeenCalledTimes(0);
21 | expect(result).toStrictEqual(page._media);
22 | });
23 |
24 | test('media method on page object returns wikiMediaResult with array of mediaResults', async () => {
25 | requestMock.mockImplementation(async () => { return mediaJson });
26 | const page = new Page(pageJson);
27 | const result = await page.media({redirect: true});
28 | expect(requestMock).toHaveBeenCalledTimes(1);
29 | expect(result).toStrictEqual(mediaJson);
30 | });
31 |
32 | test('media method on page throws media error if response is error', async () => {
33 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
34 | const page = new Page(pageJson);
35 | const t = async () => {
36 | await page.media()
37 | };
38 | expect(t).rejects.toThrowError(mediaError);
39 | });
40 |
41 | test('Throws media error if response is error', async () => {
42 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
43 | const t = async () => {
44 | await media("Test")
45 | };
46 | expect(t).rejects.toThrowError(mediaError);
47 | });
48 |
49 | test('Returns with results as wikiMediaResult', async () => {
50 | requestMock.mockImplementation(async () => { return mediaJson });
51 | const result = await media("Test");
52 | expect(result).toStrictEqual(mediaJson);
53 | });
54 |
55 | test('media method on index throws media error if response is error', async () => {
56 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
57 | const t = async () => {
58 | await wiki.media("Test")
59 | };
60 | expect(t).rejects.toThrowError(mediaError);
61 | });
62 |
63 | test('related method on index returns wikiMediaResult', async () => {
64 | requestMock.mockImplementation(async () => { return mediaJson });
65 | const result = await wiki.media("Test");
66 | expect(setTitleMock).toHaveBeenCalledTimes(0);
67 | expect(result).toStrictEqual(mediaJson);
68 | });
69 |
70 | test('media method on index returns wikiMediaResult even when autosuggest is true', async () => {
71 | requestMock.mockImplementation(async () => { return mediaJson });
72 | setTitleMock.mockImplementation(async () => { return "test" });
73 | const result = await wiki.media("Test", { autoSuggest: true });
74 | expect(setTitleMock).toHaveBeenCalledTimes(1);
75 | expect(result).toStrictEqual(mediaJson);
76 | });
--------------------------------------------------------------------------------
/test/mobileHtml.test.ts:
--------------------------------------------------------------------------------
1 | import * as request from '../source/request';
2 | import wiki from "../source/index";
3 | import { htmlString, notFoundJson } from './samples';
4 | import { htmlError } from '../source/errors';
5 | import Page, { mobileHtml } from '../source/page';
6 | import { pageJson } from './samples';
7 | import * as utils from '../source/utils'
8 | const requestMock = jest.spyOn(request, "makeRestRequest");
9 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
10 |
11 | const htmlResult = ""
12 |
13 | afterAll(() => {
14 | requestMock.mockRestore();
15 | setTitleMock.mockRestore();
16 | });
17 |
18 | test('mobilehtml method on page object returns without calling request if _mobileHtml field set', async () => {
19 | requestMock.mockImplementation(async () => { return htmlResult });
20 | const page = new Page(pageJson);
21 | page._mobileHtml = htmlResult;
22 | const result = await page.mobileHtml();
23 | expect(requestMock).toHaveBeenCalledTimes(0);
24 | expect(result).toStrictEqual(page._mobileHtml);
25 | });
26 |
27 | test('mobilehtml method on page object returns html', async () => {
28 | requestMock.mockImplementation(async () => { return htmlResult });
29 | const page = new Page(pageJson);
30 | const result = await page.mobileHtml({redirect: true});
31 | expect(requestMock).toHaveBeenCalledTimes(1);
32 | expect(result).toStrictEqual(htmlResult);
33 | });
34 |
35 | test('mobilehtml method on page throws html error if response is empty', async () => {
36 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
37 | const page = new Page(pageJson);
38 | const t = async () => {
39 | await page.mobileHtml();
40 | };
41 | expect(t).rejects.toThrowError(htmlError);
42 | });
43 |
44 | test('Throws mobilehtml error if response is empty', async () => {
45 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
46 | const t = async () => {
47 | await mobileHtml("Test")
48 | };
49 | expect(t).rejects.toThrowError(htmlError);
50 | });
51 |
52 | test('Returns with results as string', async () => {
53 | requestMock.mockImplementation(async () => { return htmlResult });
54 | const result = await mobileHtml("Test");
55 | expect(result).toStrictEqual(htmlResult);
56 | });
57 |
58 | test('Returns mobilehtml when page successfully queried', async () => {
59 | requestMock.mockImplementation(async () => { return htmlString });
60 | const result = await wiki.mobileHtml("ACID");
61 | expect(result).toStrictEqual(htmlString);
62 | });
63 |
64 | test('throws htmlError if error response', async () => {
65 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
66 | const t = async () => {
67 | await wiki.mobileHtml("ACID");
68 | };
69 | expect(t).rejects.toThrowError(htmlError);
70 | });
71 |
72 | test('Returns notFound if page not found', async () => {
73 | requestMock.mockImplementation(async () => { return notFoundJson });
74 | const result = await wiki.mobileHtml("does-not-exist-on-wikipedia");
75 | expect(result).toEqual(notFoundJson);
76 | });
77 |
78 | test('Returns empty body on redirect page with redirect set to false', async () => {
79 | requestMock.mockImplementation(async () => { return null });
80 | setTitleMock.mockImplementation(async () => { return "homestar" });
81 | const result = await wiki.mobileHtml("homestar", { autoSuggest: true, redirect: false });
82 | expect(setTitleMock).toHaveBeenCalledTimes(1);
83 | expect(result).toBeNull();
84 | });
85 |
--------------------------------------------------------------------------------
/test/onThisDay.test.ts:
--------------------------------------------------------------------------------
1 | import { eventsError } from '../source/errors';
2 | import * as request from '../source/request';
3 | import wiki from "../source/index";
4 | import { eventsJson } from './samples';
5 | const requestMock = jest.spyOn(request, "makeRestRequest");
6 |
7 | const eventsMock = eventsJson;
8 |
9 | afterAll(() => {
10 | requestMock.mockRestore();
11 | })
12 |
13 | test('Throws events error if response is error', async () => {
14 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
15 | const t = async () => {
16 | await wiki.onThisDay({})
17 | };
18 | expect(t).rejects.toThrowError(eventsError);
19 | });
20 |
21 | test('Returns with results as eventResult', async () => {
22 | requestMock.mockImplementation(async () => { return eventsMock });
23 | const result = await wiki.onThisDay();
24 | expect(result).toStrictEqual(eventsMock);
25 | });
26 |
27 | test('events method call with params passed and no padding', async () => {
28 | requestMock.mockImplementation(async () => { return eventsMock });
29 | const result = await wiki.onThisDay({ type: 'deaths', month: '6', day: '9' });
30 | expect(result).toStrictEqual(eventsMock);
31 | expect(requestMock).toBeCalledWith(`feed/onthisday/deaths/06/09`, true);
32 | });
33 |
34 | test('events method call with params passed', async () => {
35 | requestMock.mockImplementation(async () => { return eventsMock });
36 | const result = await wiki.onThisDay({ type: 'deaths', month: '11', day: '25' });
37 | expect(result).toStrictEqual(eventsMock);
38 | expect(requestMock).toBeCalledWith(`feed/onthisday/deaths/11/25`, true);
39 | });
--------------------------------------------------------------------------------
/test/pdf.test.ts:
--------------------------------------------------------------------------------
1 | import * as request from '../source/request';
2 | import wiki from "../source/index";
3 | import { htmlString, notFoundJson } from './samples';
4 | import { pdfError } from '../source/errors';
5 | import Page, { pdf } from '../source/page';
6 | import { pageJson } from './samples';
7 | import * as utils from '../source/utils'
8 | const requestMock = jest.spyOn(request, "returnRestUrl");
9 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
10 |
11 | const pdfResult = "link/pdf"
12 |
13 | afterAll(() => {
14 | requestMock.mockRestore();
15 | setTitleMock.mockRestore();
16 | });
17 |
18 | test('returns link of pdf on page', async () => {
19 | requestMock.mockImplementation(() => { return pdfResult });
20 | const page = new Page(pageJson);
21 | const result = await page.pdf();
22 | expect(requestMock).toHaveBeenCalledTimes(1);
23 | expect(result).toStrictEqual(pdfResult);
24 | });
25 |
26 | test('throws pdf error on page', async () => {
27 | requestMock.mockImplementation(() => { throw Error("this is an error") });
28 | const page = new Page(pageJson);
29 | const t = async () => {
30 | await page.pdf();
31 | };
32 | expect(t).rejects.toThrowError(pdfError);
33 | });
34 |
35 | test('Throws pdf error', async () => {
36 | requestMock.mockImplementation(() => { throw new Error("This is an error") });
37 | const t = async () => {
38 | await pdf("Test")
39 | };
40 | expect(t).rejects.toThrowError(pdfError);
41 | });
42 |
43 | test('Returns link of pdf', async () => {
44 | requestMock.mockImplementation(() => { return pdfResult });
45 | const result = await pdf("Test");
46 | expect(result).toStrictEqual(pdfResult);
47 | });
48 |
49 | test('Returns link of pdf directly', async () => {
50 | requestMock.mockImplementation(() => { return pdfResult });
51 | const result = await wiki.pdf("ACID");
52 | expect(result).toStrictEqual(pdfResult);
53 | });
54 |
55 | test('throws pdf error directly', async () => {
56 | requestMock.mockImplementation(() => { throw new Error("This is an error") });
57 | const t = async () => {
58 | await wiki.pdf("ACID");
59 | };
60 | expect(t).rejects.toThrowError(pdfError);
61 | });
62 |
63 | test('Returns link of pdf directly', async () => {
64 | let pdfResultWithAllFormats = pdfResult + '/legal/mobile';
65 | requestMock.mockImplementation(() => { return pdfResultWithAllFormats });
66 | const result = await wiki.pdf("ACID", { autoSuggest: true, type: 'mobile', format: 'legal' });
67 | expect(result).toStrictEqual(pdfResultWithAllFormats);
68 | });
69 |
--------------------------------------------------------------------------------
/test/random.test.ts:
--------------------------------------------------------------------------------
1 | import * as request from '../source/request';
2 | import wiki from "../source/index";
3 | import { mobileSections, summaryJson, title } from './samples';
4 | const requestMock = jest.spyOn(request, "makeRestRequest");
5 |
6 | afterAll(() => {
7 | requestMock.mockRestore();
8 | })
9 |
10 | test('Throws error if response is error', async () => {
11 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
12 | const err = async () => { await wiki.random("some_arg") };
13 | expect(err).rejects.toThrowError(Error);
14 | });
15 |
16 | test('Returns summary of random article summary', async () => {
17 | requestMock.mockImplementation(async () => { return summaryJson });
18 | const result = await wiki.random("summary");
19 | expect(result).toStrictEqual(summaryJson);
20 | });
21 |
22 | test('Returns summary of random article mobile sections', async () => {
23 | requestMock.mockImplementation(async () => { return mobileSections });
24 | const result = await wiki.random("mobile-sections");
25 | expect(result).toStrictEqual(mobileSections);
26 | });
27 |
28 | test('Returns summary of random article title', async () => {
29 | requestMock.mockImplementation(async () => { return title });
30 | const result = await wiki.random("title");
31 | expect(result).toStrictEqual(title);
32 | });
33 |
34 | test('Request includes arg provided to method', async () => {
35 | requestMock.mockImplementation(async () => { return summaryJson });
36 | const result = await wiki.random("summary");
37 | expect(result).toStrictEqual(summaryJson);
38 | expect(requestMock).toBeCalledWith(`page/random/summary`);
39 | });
40 |
41 | test('Calling random with no arguments', async () => {
42 | requestMock.mockImplementation(async () => { return summaryJson });
43 | const result = await wiki.random();
44 | expect(result).toStrictEqual(summaryJson);
45 | expect(requestMock).toBeCalledWith(`page/random/summary`);
46 | });
47 |
--------------------------------------------------------------------------------
/test/references.test.ts:
--------------------------------------------------------------------------------
1 | import { linksError } from '../source/errors';
2 | import Page, { references } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const referenceMock = {
11 | 500: { extlinks: [{"*":"Link1"}, {"*": "Link2"}] }
12 | }
13 |
14 | const referenceResult = ["Link1", "Link2"]
15 |
16 | afterAll(() => {
17 | requestMock.mockRestore();
18 | setTitleMock.mockRestore();
19 | })
20 |
21 | test('References method on page object returns without calling request if _references field set', async () => {
22 | requestMock.mockImplementation(async () => { return { query: { pages: referenceMock } } });
23 | const page = new Page(pageJson);
24 | page._references = []
25 | const result = await page.references();
26 | expect(requestMock).toHaveBeenCalledTimes(0);
27 | expect(result).toStrictEqual(page._references);
28 | });
29 |
30 | test('References method on page object returns array of strings', async () => {
31 | requestMock.mockImplementation(async () => { return { query: { pages: referenceMock } } });
32 | const page = new Page(pageJson);
33 | const result = await page.references();
34 | expect(requestMock).toHaveBeenCalledTimes(1);
35 | expect(result).toStrictEqual(referenceResult);
36 | });
37 |
38 | test('References method on page throws links error if response is empty', async () => {
39 | requestMock.mockImplementation(async () => { return [] });
40 | const page = new Page(pageJson);
41 | const t = async () => {
42 | await page.references()
43 | };
44 | expect(t).rejects.toThrowError(linksError);
45 | });
46 |
47 | test('Throws links error if response is empty', async () => {
48 | requestMock.mockImplementation(async () => { return [] });
49 | const t = async () => {
50 | await references("Test")
51 | };
52 | expect(t).rejects.toThrowError(linksError);
53 | });
54 |
55 | test('Returns empty if no external links are available', async () => {
56 | requestMock.mockImplementation(async () => { return { query: { pages: {500: {extlinks:[]}} } } });
57 | const result = await references("Test");
58 | expect(result).toStrictEqual([]);
59 | });
60 |
61 | test('Returns with results an array of string', async () => {
62 | requestMock.mockImplementation(async () => { return { query: { pages: referenceMock } } });
63 | const result = await references("Test");
64 | expect(result).toStrictEqual(referenceResult);
65 | });
66 |
67 | test('references method on page throws links error if response is empty', async () => {
68 | requestMock.mockImplementation(async () => { return [] });
69 | const t = async () => {
70 | await wiki.references("Test")
71 | };
72 | expect(t).rejects.toThrowError(linksError);
73 | });
74 |
75 |
76 | test('references method on index returns array of strings', async () => {
77 | requestMock.mockImplementation(async () => { return { query: { pages: referenceMock } } });
78 | const result = await wiki.references("Test");
79 | expect(setTitleMock).toHaveBeenCalledTimes(0);
80 | expect(result).toStrictEqual(referenceResult);
81 | });
82 |
83 | test('references method on index returns array of strings even when autosuggest is true', async () => {
84 | requestMock.mockImplementation(async () => { return { query: { pages: referenceMock } } });
85 | setTitleMock.mockImplementation(async () => { return "test" });
86 | const result = await wiki.references("Test", { autoSuggest: true });
87 | expect(setTitleMock).toHaveBeenCalledTimes(1);
88 | expect(result).toStrictEqual(referenceResult);
89 | });
--------------------------------------------------------------------------------
/test/related.test.ts:
--------------------------------------------------------------------------------
1 | import { relatedError } from '../source/errors';
2 | import Page, { related } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson, summaryJson } from './samples';
7 | const requestMock = jest.spyOn(request, "makeRestRequest");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const relatedMock = {pages: [summaryJson, summaryJson]};
11 |
12 | afterAll(() => {
13 | requestMock.mockRestore();
14 | setTitleMock.mockRestore();
15 | })
16 |
17 | test('Related method on page object returns without calling request if _related field set', async () => {
18 | requestMock.mockImplementation(async () => { return relatedMock });
19 | const page = new Page(pageJson);
20 | page._related = relatedMock;
21 | const result = await page.related();
22 | expect(requestMock).toHaveBeenCalledTimes(0);
23 | expect(result).toStrictEqual(page._related);
24 | });
25 |
26 | test('Related method on page object returns array of wikiSummary', async () => {
27 | requestMock.mockImplementation(async () => { return relatedMock });
28 | const page = new Page(pageJson);
29 | const result = await page.related({redirect: true});
30 | expect(requestMock).toHaveBeenCalledTimes(1);
31 | expect(result).toStrictEqual(relatedMock);
32 | });
33 |
34 | test('Related method on page throws related error if response is error', async () => {
35 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
36 | const page = new Page(pageJson);
37 | const t = async () => {
38 | await page.related()
39 | };
40 | expect(t).rejects.toThrowError(relatedError);
41 | });
42 |
43 | test('Throws related error if response is error', async () => {
44 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
45 | const t = async () => {
46 | await related("Test")
47 | };
48 | expect(t).rejects.toThrowError(relatedError);
49 | });
50 |
51 | test('Returns with results as array of wikiSummary', async () => {
52 | requestMock.mockImplementation(async () => { return relatedMock });
53 | const result = await related("Test");
54 | expect(result).toStrictEqual(relatedMock);
55 | });
56 |
57 | test('related method on index throws related error if response is error', async () => {
58 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
59 | const t = async () => {
60 | await wiki.related("Test")
61 | };
62 | expect(t).rejects.toThrowError(relatedError);
63 | });
64 |
65 | test('related method on index returns array of wikiSummary', async () => {
66 | requestMock.mockImplementation(async () => { return relatedMock });
67 | const result = await wiki.related("Test");
68 | expect(setTitleMock).toHaveBeenCalledTimes(0);
69 | expect(result).toStrictEqual(relatedMock);
70 | });
71 |
72 | test('related method on index returns a array of wikiSummary even when autosuggest is true', async () => {
73 | requestMock.mockImplementation(async () => { return relatedMock });
74 | setTitleMock.mockImplementation(async () => { return "test" });
75 | const result = await wiki.related("Test", { autoSuggest: true });
76 | expect(setTitleMock).toHaveBeenCalledTimes(1);
77 | expect(result).toStrictEqual(relatedMock);
78 | });
--------------------------------------------------------------------------------
/test/request.test.ts:
--------------------------------------------------------------------------------
1 | import axios, {AxiosHeaders} from 'axios';
2 | import {AxiosRequestConfig, AxiosResponse} from 'axios';
3 | import request, {makeRestRequest, setAPIUrl, returnRestUrl, setUserAgent} from '../source/request';
4 | import { wikiError } from '../source';
5 | const fetchMock = jest.spyOn(axios, "get");
6 |
7 | const options: AxiosRequestConfig = {
8 | headers: {
9 | 'Api-User-Agent': 'wikipedia (https://github.com/dopecodez/Wikipedia/)'
10 | }
11 | }
12 | const baseConfig : AxiosResponse['config'] = { headers: new AxiosHeaders()};
13 | const baseResponse : Omit = { status: 200, statusText: 'Ok', request: {}, headers: {}, config: baseConfig};
14 | const response1 : AxiosResponse = {...baseResponse, data:{"test1": "test1"}};
15 | const response2 : AxiosResponse = {...baseResponse, data:{"test2": "test2"}};
16 | const response3 : AxiosResponse = {...baseResponse, data:{"test3": "test3"}};
17 | //const response4 : AxiosResponse = {...baseResponse, data:{"test4": "test4"}};
18 | const apiUrl = "https://en.wikipedia.org/w/api.php?";
19 | const restApiUrl = 'https://en.wikipedia.org/api/rest_v1/';
20 |
21 | afterAll(() => {
22 | fetchMock.mockRestore();
23 | })
24 |
25 | test('makeRequest method calls and returns with expected params', async () => {
26 | fetchMock.mockImplementation(async () => { return response1 } );
27 | await request({}, true);
28 | expect(fetchMock).toHaveBeenCalledWith(
29 | apiUrl + 'format=json&redirects=&action=query&origin=*&',
30 | options
31 | );
32 | });
33 |
34 | test('makeRequest method calls and returns with expected params when no value passed for redirect', async () => {
35 | fetchMock.mockImplementation(async () => { return response3 } );
36 | await request({});
37 | expect(fetchMock).toHaveBeenCalledWith(
38 | apiUrl + 'format=json&redirects=&action=query&origin=*&',
39 | options
40 | );
41 | });
42 |
43 | test('makeRequest throws wiki error if error is raised', async () => {
44 | fetchMock.mockImplementation(async () => { throw new Error("Error") });
45 | const t = async () => {
46 | await request({}, true)
47 | };
48 | expect(t).rejects.toThrowError(wikiError);
49 | });
50 |
51 | test('makeRestRequest method calls and returns with expected params', async () => {
52 | fetchMock.mockImplementation(async () => { return response2 } );
53 | await makeRestRequest("path", false);
54 | expect(fetchMock).toHaveBeenCalledWith(
55 | restApiUrl + 'path?redirect=false',
56 | options
57 | );
58 | });
59 |
60 | test('makeRestRequest throws wiki error if error is raised', async () => {
61 | fetchMock.mockImplementation(async () => { throw new Error("Error") });
62 | const t = async () => {
63 | await makeRestRequest("")
64 | };
65 | expect(t).rejects.toThrowError(wikiError);
66 | });
67 |
68 | // test('makeRestRequest method calls and returns with expected params when no value for redirect', async () => {
69 | // fetchMock.mockImplementation(async () => { return response4 } );
70 | // await makeRestRequest("path");
71 | // expect(fetchMock).toHaveBeenCalledWith(
72 | // restApiUrl + 'path?redirect=true',
73 | // options
74 | // );
75 | // });
76 |
77 | test('Return rest url', () => {
78 | const result = returnRestUrl("path/pdf");
79 | expect(result).toStrictEqual("https://en.wikipedia.org/api/rest_v1/path/pdf");
80 | });
81 |
82 | test('Set language returns api url with language set', () => {
83 | const result = setAPIUrl("mal");
84 | expect(result).toStrictEqual("https://mal.wikipedia.org/w/api.php?");
85 | });
86 |
87 | test('Set user agent and use it to call the api', async () => {
88 | setUserAgent("testUser");
89 | fetchMock.mockImplementation(async () => { return response1 } );
90 | await request({}, true);
91 | const modifiedOptions : AxiosRequestConfig = {
92 | headers: {
93 | 'Api-User-Agent': 'testUser'
94 | }
95 | }
96 | expect(fetchMock).toHaveBeenCalledWith(
97 | expect.anything(),
98 | modifiedOptions
99 | );
100 | });
--------------------------------------------------------------------------------
/test/samples.ts:
--------------------------------------------------------------------------------
1 | export const pageJson = {
2 | "pageid": 100,
3 | "ns": 1,
4 | "title": "Test",
5 | "contentmodel": "",
6 | "pagelanguage": "",
7 | "pagelanguagehtmlcode": "",
8 | "pagelanguagedir": "",
9 | "touched": "",
10 | "lastrevid": 0,
11 | "length": 0,
12 | "fullurl": "",
13 | "editurl": "",
14 | "canonicalurl": ""
15 | }
16 |
17 | export const summaryJson = {
18 | type: "",
19 | title: "Test Summary",
20 | displaytitle: "Test",
21 | namespace: { id: 0, text: "" },
22 | wikibase_item: "",
23 | titles: { canonical: "", normalized: "", display: "" },
24 | pageid: 100,
25 | thumbnail: {
26 | source: "",
27 | width: 0,
28 | height: 0
29 | },
30 | originalimage: {
31 | source: "",
32 | width: 0,
33 | height: 0
34 | },
35 | lang: "",
36 | dir: "",
37 | revision: "",
38 | tid: "",
39 | timestamp: "",
40 | description: "",
41 | description_source: "",
42 | content_urls: {
43 | desktop: {
44 | page: "",
45 | revisions: "",
46 | edit: "",
47 | talk: ""
48 | },
49 | mobile: {
50 | page: "",
51 | revisions: "",
52 | edit: "",
53 | talk: ""
54 | }
55 | },
56 | extract: "",
57 | extract_html: ""
58 | }
59 |
60 | export const eventsJson = {
61 | births: [
62 | {
63 | text: "test",
64 | pages: [summaryJson]
65 | }
66 | ],
67 | deaths: [
68 | {
69 | text: "test",
70 | pages: [summaryJson]
71 | }
72 | ],
73 | events: [
74 | {
75 | text: "test",
76 | pages: [summaryJson]
77 | }
78 | ],
79 | holidays: [
80 | {
81 | text: "test",
82 | pages: [summaryJson]
83 | }
84 | ],
85 | selected: [
86 | {
87 | text: "test",
88 | pages: [summaryJson]
89 | }
90 | ]
91 | }
92 |
93 | export const rawJson = {
94 | contentformat: 'text/x-wiki',
95 | contentmodel: 'wikitext',
96 | '*': '{{pp-move-indef}}\n' +
97 | '{{short description|Creator and lead developer of Linux kernel}}\n' +
98 | '{{Use dmy dates|date=July 2020}}\n' +
99 | '{{Infobox person\n' +
100 | '| name = Linus Torvalds\n' +
101 | '| image = LinuxCon Europe Linus Torvalds 03 (cropped).jpg\n' +
102 | '| caption = Torvalds at LinuxCon Europe 2014\n'
103 | }
104 |
105 | export const tableJson = {
106 | contentformat: 'text/x-wiki',
107 | contentmodel: 'wikitext',
108 | '*': '{{pp-move-indef}}\n' +
109 | '== Awards and achievements ==\n' +
110 | '{| class="wikitable"\n' +
111 | '|-\n' +
112 | '! colspan="3" style="background: LightSteelBlue;" | Awards and achievements\n' +
113 | '|- style="background:#ccc;"\n' +
114 | '! Year !! Award !! Notes\n' +
115 | '|-\n' +
116 | '|2018\n' +
117 | '|IEEE Masaru Ibuka Consumer Electronics Award\n' +
118 | '|[[IEEE Masaru Ibuka Consumer Electronics Award]] is conferred by the [[Institute of Electrical and Electronics Engineers]] for outstanding contributions to consumer electronics technology has been named in honor the co-founder and honorary chairman of Sony Corporation, Masaru Ibuka. 2018 Ibuka award was conferred to Linus Torvalds "For his leadership of the development and proliferation of Linux."\n' +
119 | '|-\n' +
120 | '|2014\n' +
121 | '|IEEE Computer Pioneer Award\n' +
122 | "|On 23 April 2014, the [[Institute of Electrical and Electronics Engineers]] named Torvalds as the 2014 recipient of the IEEE Computer Society's Computer Pioneer Award. The Computer Pioneer Award was established in 1981 by the IEEE Computer Society Board of Governors to recognize and honor the vision of those whose efforts resulted in the creation and continued vitality of the computer industry. The award is presented to outstanding individuals whose main contribution to the concepts and development of the computer field was made at least 15 years earlier.[{{cite web|url=http://www.computer.org/portal/web/pressroom/Linus-Torvalds-Named-Recipient-of-the-2014-IEEE-Computer-Society-Computer-Pioneer-Award|title=Linus Torvalds Named Recipient of the 2014 IEEE Computer Society Computer Pioneer Award|publisher=[[Institute of Electrical and Electronics Engineers]]|date=23 April 2014|accessdate=5 May 2014|archive-url=https://web.archive.org/web/20140504034244/http://www.computer.org/portal/web/pressroom/Linus-Torvalds-Named-Recipient-of-the-2014-IEEE-Computer-Society-Computer-Pioneer-Award|archive-date=4 May 2014|url-status=dead}}]\n" +
123 | '|-\n' +
124 | '|}\n' +
125 | '\n' +
126 | '== Media recognition ==\n' +
127 | "[[Time (magazine)|''Time'' magazine]] has recognized Torvalds multiple times:\n"
128 | }
129 |
130 | export const mediaJson = {
131 | revision: "111",
132 | tid: "222",
133 | items: [{
134 | title: "sample",
135 | section_id: 1,
136 | type: "image",
137 | caption: {
138 | html: "test",
139 | text: "test"
140 | },
141 | showInGallery: true,
142 | srcset: [{
143 | src: "/something.jpg",
144 | scale: "1"
145 | }]
146 | }]
147 | }
148 |
149 | export const mobileSections = {
150 | lead: {
151 | ns: 0,
152 | id: 3449027,
153 | revision: "1000443218",
154 | lastmodified: "2021-01-15T03:44:53Z",
155 | lastmodifier: {
156 | user: "Ser Amantio di Nicolao",
157 | gender: "unknown"
158 | },
159 | displaytitle: "Girls Like Me",
160 | normalizedtitle: "Girls Like Me",
161 | wikibase_item: "Q5564650",
162 | description: "1986 studio album by Tanya Tucker",
163 | description_source: "local",
164 | protection: {},
165 | editable: true,
166 | languagecount: 1,
167 | image: {
168 | file: "TanyaTuckerGirlsLikeMeOriginal.jpg",
169 | urls: {
170 | 320: "https://upload.wikimedia.org/wikipedia/en/4/48/TanyaTuckerGirlsLikeMeOriginal.jpg",
171 | 640: "https://upload.wikimedia.org/wikipedia/en/4/48/TanyaTuckerGirlsLikeMeOriginal.jpg",
172 | 800: "https://upload.wikimedia.org/wikipedia/en/4/48/TanyaTuckerGirlsLikeMeOriginal.jpg",
173 | 1024: "https://upload.wikimedia.org/wikipedia/en/4/48/TanyaTuckerGirlsLikeMeOriginal.jpg"
174 | }
175 | },
176 | issues: [
177 | {
178 | html: "This is article",
179 | text: "This is article"
180 | }
181 | ],
182 | sections: [
183 | {
184 | id: 0,
185 | text: "This is article
"
186 | },
187 | {
188 | id: 1,
189 | toclevel: 1,
190 | anchor: "Track_listing",
191 | line: "Track listing"
192 | },
193 | {
194 | id: 2,
195 | toclevel: 1,
196 | anchor: "Chart_performance",
197 | line: "Chart performance"
198 | }
199 | ]
200 | },
201 | remaining: {
202 | sections: [
203 | {
204 | id: 1,
205 | text: "\n- \"One Love at a Time\"
",
206 | toclevel: 1,
207 | line: "Track listing",
208 | anchor: "Track_listing"
209 | },
210 | {
211 | id: 2,
212 | text: "\n",
213 | toclevel: 1,
214 | line: "Chart performance",
215 | anchor: "Chart_performance"
216 | }
217 | ]
218 | }
219 | }
220 |
221 | export const title = {
222 | items: [
223 | {
224 | title: "White-naped_seedeater",
225 | page_id: 12450272,
226 | rev: 1012232317,
227 | tid: "fce161c0-8ea1-11eb-8f0f-a75f37ec29b6",
228 | namespace: 0,
229 | user_id: 40600116,
230 | user_text: "ShortDescBot",
231 | timestamp: "2021-03-15T09:14:24Z",
232 | comment: "[[User:ShortDescBot|ShortDescBot]] adding [[Wikipedia:Short description|short description]] \"Species of bird\"",
233 | tags: [],
234 | restrictions: [],
235 | page_language: "en",
236 | redirect: false
237 | }
238 | ]
239 | }
240 |
241 | export const notFoundJson = {
242 | type: "https://mediawiki.org/wiki/HyperSwitch/errors/not_found",
243 | title: "Not found.",
244 | method: "get",
245 | detail: "Page or revision not found.",
246 | uri: "/en.wikipedia.org/v1/page/mobile-html/does-not-exist-on-wikipedia"
247 | }
248 |
249 | export const htmlString = "abcde";
250 |
251 | export const citationData = {
252 | data: [
253 | {
254 | "itemType": "journalArticle",
255 | "issue": "2",
256 | "DOI": "10.23884/ijesg.2017.2.2.04",
257 | "pages": "47–63",
258 | "title": "A MODEL APPLICATION OF MICRO GRID: BATMAN UNIVERSITY MICRO GRID",
259 | "volume": "2",
260 | "publicationTitle": "International Journal of Energy and Smart Grid",
261 | "date": "2017-12-30",
262 | "url": "http://dx.doi.org/10.23884/ijesg.2017.2.2.04",
263 | "ISSN": [
264 | "2548-0332"
265 | ],
266 | "accessDate": "2021-09-23",
267 | "author": [
268 | [
269 | "Mehmet Esref",
270 | "Demir"
271 | ],
272 | [
273 | "Musa",
274 | "Yilmaz"
275 | ],
276 | [
277 | "Ahmet",
278 | "Gündogdu"
279 | ]
280 | ],
281 | "source": [
282 | "Crossref"
283 | ]
284 | },
285 | {
286 | "itemType": "book",
287 | "title": "Batman.",
288 | "url": "http://worldcat.org/oclc/983466999",
289 | "abstractNote": "\"Batman: Arkham Asylum exposes players to a dark and atmospheric adventure that takes them into the depths of Arkham Asylum. Batman Arkham City introduces a brand-new story that draws together an all-star cast of classic characters and murderous villains from the Batman universe\"--Amazon.com.",
290 | "oclc": "983466999",
291 | "author": [
292 | [
293 | "WB Games (Firm), contributor. Warner Bros. Interactive Entertainment,",
294 | "publisher."
295 | ]
296 | ],
297 | "accessDate": "2021-09-23",
298 | "source": [
299 | "WorldCat"
300 | ]
301 | }
302 | ]
303 | }
304 |
305 | const sampleSummary = {
306 | "type": "standard",
307 | "title": "Jared_Lee_Loughner",
308 | "displaytitle": "Jared Lee Loughner",
309 | "namespace": {
310 | "id": 0,
311 | "text": ""
312 | },
313 | "wikibase_item": "Q4267485",
314 | "titles": {
315 | "canonical": "Jared_Lee_Loughner",
316 | "normalized": "Jared Lee Loughner",
317 | "display": "Jared Lee Loughner"
318 | },
319 | "pageid": 30372228,
320 | "thumbnail": {
321 | "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Jared_Loughner_USMS.jpg/256px-Jared_Loughner_USMS.jpg",
322 | "width": 256,
323 | "height": 320
324 | },
325 | "originalimage": {
326 | "source": "https://upload.wikimedia.org/wikipedia/commons/8/82/Jared_Loughner_USMS.jpg",
327 | "width": 480,
328 | "height": 600
329 | },
330 | "lang": "en",
331 | "dir": "ltr",
332 | "revision": "1063449101",
333 | "tid": "fa00d540-6d07-11ec-b627-0543a4912f8c",
334 | "timestamp": "2022-01-03T04:11:55Z",
335 | "description": "American mass murderer",
336 | "description_source": "local",
337 | "content_urls": {
338 | "desktop": {
339 | "page": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner",
340 | "revisions": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner?action=history",
341 | "edit": "https://en.wikipedia.org/wiki/Jared_Lee_Loughner?action=edit",
342 | "talk": "https://en.wikipedia.org/wiki/Talk:Jared_Lee_Loughner"
343 | },
344 | "mobile": {
345 | "page": "https://en.m.wikipedia.org/wiki/Jared_Lee_Loughner",
346 | "revisions": "https://en.m.wikipedia.org/wiki/Special:History/Jared_Lee_Loughner",
347 | "edit": "https://en.m.wikipedia.org/wiki/Jared_Lee_Loughner?action=edit",
348 | "talk": "https://en.m.wikipedia.org/wiki/Talk:Jared_Lee_Loughner"
349 | }
350 | },
351 | "rxtract": "abc",
352 | "extract_html": "abc
",
353 | "normalizedtitle": "abc"
354 | }
355 |
356 | export const fcData = {
357 | "tfa": sampleSummary,
358 | "mostread": {
359 | "date": "2022-01-07Z",
360 | "articles": [
361 | {
362 | "views": 1064940,
363 | "rank": 3,
364 | "view_history": [
365 | {
366 | "date": "2022-01-07Z",
367 | "views": 1064940
368 | }
369 | ],
370 | ...sampleSummary
371 | },
372 | ]
373 | },
374 | "image": {
375 | "title": "File:1930s Japan Travel Poster - 01.jpg",
376 | "thumbnail": {
377 | "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/1930s_Japan_Travel_Poster_-_01.jpg/640px-1930s_Japan_Travel_Poster_-_01.jpg",
378 | "width": 640,
379 | "height": 934
380 | },
381 | "image": {
382 | "source": "https://upload.wikimedia.org/wikipedia/commons/5/54/1930s_Japan_Travel_Poster_-_01.jpg",
383 | "width": 2056,
384 | "height": 3000
385 | },
386 | "file_page": "https://commons.wikimedia.org/wiki/File:1930s_Japan_Travel_Poster_-_01.jpg",
387 | "artist": {
388 | "html": "Japanese Government Railways",
389 | "text": "Japanese Government Railways",
390 | "name": "Japanese Government Railways"
391 | },
392 | "credit": {
393 | "html": "Heritage Auctions",
394 | "text": "Heritage Auctions"
395 | },
396 | "license": {
397 | "type": "Public domain",
398 | "code": "pd"
399 | },
400 | "description": {
401 | "html": "Sea bathing in Obama",
402 | "text": "Sea bathing in Obama",
403 | "lang": "en"
404 | },
405 | "wb_entity_id": "M31526367",
406 | "structured": {
407 | "captions": {}
408 | }
409 | },
410 | "news": [
411 | {
412 | "links": [ sampleSummary ],
413 | "story": "Bahamian-American actor."
414 | },
415 | ],
416 | "onthisday": [
417 | {
418 | "text": "abc",
419 | "pages": [ sampleSummary ]
420 | }
421 | ],
422 | }
--------------------------------------------------------------------------------
/test/summary.test.ts:
--------------------------------------------------------------------------------
1 | import { summaryError } from '../source/errors';
2 | import Page, { summary } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson, summaryJson } from './samples';
7 | const requestMock = jest.spyOn(request, "makeRestRequest");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const summaryMock = summaryJson;
11 |
12 | afterAll(() => {
13 | requestMock.mockRestore();
14 | setTitleMock.mockRestore();
15 | })
16 |
17 | test('Summary method on page object returns without calling request if _summary field set', async () => {
18 | requestMock.mockImplementation(async () => { return summaryMock });
19 | const page = new Page(pageJson);
20 | page._summary = summaryMock;
21 | const result = await page.summary();
22 | expect(requestMock).toHaveBeenCalledTimes(0);
23 | expect(result).toStrictEqual(page._summary);
24 | });
25 |
26 | test('Summary method on page object returns wikiSummary', async () => {
27 | requestMock.mockImplementation(async () => { return summaryMock });
28 | const page = new Page(pageJson);
29 | const result = await page.summary({redirect: true});
30 | expect(requestMock).toHaveBeenCalledTimes(1);
31 | expect(result).toStrictEqual(summaryMock);
32 | });
33 |
34 | test('summary method on page throws summary error if response is error', async () => {
35 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
36 | const page = new Page(pageJson);
37 | const t = async () => {
38 | await page.summary()
39 | };
40 | expect(t).rejects.toThrowError(summaryError);
41 | });
42 |
43 | test('Throws summary error if response is error', async () => {
44 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
45 | const t = async () => {
46 | await summary("Test")
47 | };
48 | expect(t).rejects.toThrowError(summaryError);
49 | });
50 |
51 | test('Returns with results as wikiSummary', async () => {
52 | requestMock.mockImplementation(async () => { return summaryMock });
53 | const result = await summary("Test");
54 | expect(result).toStrictEqual(summaryMock);
55 | });
56 |
57 | test('summary method on index throws summary error if response is error', async () => {
58 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
59 | const t = async () => {
60 | await wiki.summary("Test")
61 | };
62 | expect(t).rejects.toThrowError(summaryError);
63 | });
64 |
65 | test('summary method on index returns wikiSummary', async () => {
66 | requestMock.mockImplementation(async () => { return summaryMock });
67 | const result = await wiki.summary("Test");
68 | expect(setTitleMock).toHaveBeenCalledTimes(0);
69 | expect(result).toStrictEqual(summaryMock);
70 | });
71 |
72 | test('summary method on index returns a wikiSummary even when autosuggest is true', async () => {
73 | requestMock.mockImplementation(async () => { return summaryMock });
74 | setTitleMock.mockImplementation(async () => { return "test" });
75 | const result = await wiki.summary("Test", { autoSuggest: true });
76 | expect(setTitleMock).toHaveBeenCalledTimes(1);
77 | expect(result).toStrictEqual(summaryMock);
78 | });
--------------------------------------------------------------------------------
/test/tables.test.ts:
--------------------------------------------------------------------------------
1 | import { infoboxError } from '../source/errors';
2 | import Page, { tables } from '../source/page';
3 | import * as request from '../source/request';
4 | import wiki from "../source/index";
5 | import * as utils from '../source/utils'
6 | import { pageJson, tableJson } from './samples';
7 | const requestMock = jest.spyOn(request, "default");
8 | const setTitleMock = jest.spyOn(utils, "setTitleForPage");
9 |
10 | const rawMock = { 500: { revisions: [tableJson] } };
11 |
12 | const tablesResult = [[
13 | {
14 | awardsAndAchievements: 'style="background:#ccc;"\n! Year !! Award !! Notes'
15 | },
16 | { awardsAndAchievements: '2018' },
17 | { awardsAndAchievements: '2014' }
18 | ]]
19 |
20 |
21 | afterAll(() => {
22 | requestMock.mockRestore();
23 | setTitleMock.mockRestore();
24 | })
25 |
26 | test('tables method on page object returns without calling request if _tables field set', async () => {
27 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
28 | const page = new Page(pageJson);
29 | page._tables = tablesResult;
30 | const result = await page.tables();
31 | expect(requestMock).toHaveBeenCalledTimes(0);
32 | expect(result).toStrictEqual(page._tables);
33 | });
34 |
35 | test('Tables method on page object returns tables as array', async () => {
36 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
37 | const page = new Page(pageJson);
38 | const result = await page.tables({redirect: true});
39 | expect(requestMock).toHaveBeenCalledTimes(1);
40 | expect(result).toStrictEqual(tablesResult);
41 | });
42 |
43 | test('Tables method on index throws infobox error if response is error', async () => {
44 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
45 | const page = new Page(pageJson);
46 | const t = async () => {
47 | await page.tables()
48 | };
49 | expect(t).rejects.toThrowError(infoboxError);
50 | });
51 |
52 | test('Throws infobox error if response is error', async () => {
53 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
54 | const t = async () => {
55 | await tables("Test")
56 | };
57 | expect(t).rejects.toThrowError(infoboxError);
58 | });
59 |
60 | test('Returns with results as array of any', async () => {
61 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
62 | const result = await tables("Test", true);
63 | expect(result).toStrictEqual(tablesResult);
64 | });
65 |
66 | test('table method on index throws infobox error if response is error', async () => {
67 | requestMock.mockImplementation(async () => { throw new Error("This is an error") });
68 | const t = async () => {
69 | await wiki.tables("Test")
70 | };
71 | expect(t).rejects.toThrowError(infoboxError);
72 | });
73 |
74 | test('tables method on index returns tables as array', async () => {
75 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
76 | const result = await wiki.tables("Test");
77 | expect(setTitleMock).toHaveBeenCalledTimes(0);
78 | expect(result).toStrictEqual(tablesResult);
79 | });
80 |
81 | test('tables method on index returns array of tables even when autosuggest is true', async () => {
82 | requestMock.mockImplementation(async () => { return { query: { pages: rawMock } } });
83 | setTitleMock.mockImplementation(async () => { return "test" });
84 | const result = await wiki.tables("Test", { autoSuggest: true });
85 | expect(setTitleMock).toHaveBeenCalledTimes(1);
86 | expect(result).toStrictEqual(tablesResult);
87 | });
--------------------------------------------------------------------------------
/test/utils.test.ts:
--------------------------------------------------------------------------------
1 | import { isString, setTitleForPage, setPageIdOrTitleParam, setPageId } from '../source/utils';
2 | import wiki from "../source/index";
3 | import { pageError } from '../source/errors';
4 | const searchMock = jest.spyOn(wiki, "search");
5 |
6 | afterAll(() => {
7 | searchMock.mockRestore();
8 | })
9 |
10 | test('Is String returns false for numbers', () => {
11 | expect(isString(1)).toBe(false);
12 | });
13 |
14 | test('Is String returns true for strings', () => {
15 | expect(isString("test")).toBe(true);
16 | });
17 |
18 | test('Returns error if no suggestion or search results are present', async () => {
19 | searchMock.mockImplementation(async () => { return { suggestion: null, results: [] } });
20 | const t = async () => {
21 | await setTitleForPage("Test")
22 | };
23 | expect(t).rejects.toThrowError(pageError);
24 | });
25 |
26 | test('Returns suggestion if suggestion is present', async () => {
27 | searchMock.mockImplementation(async () => { return { suggestion: "Suggest", results: ['result'] } });
28 | const result = await setTitleForPage("Test");
29 | expect(result).toBe("Suggest");
30 | });
31 |
32 | test('Returns title if no suggestion but search results are present', async () => {
33 | searchMock.mockImplementation(async () => { return { suggestion: null, results: ['result'] } });
34 | const result = await setTitleForPage("Test");
35 | expect(result).toBe("Test");
36 | });
37 |
38 | test('Sets title param for string titles', () => {
39 | const params = {}
40 | const result = setPageIdOrTitleParam(params, "Test")
41 | expect(result.titles).toBe("Test");
42 | });
43 |
44 | test('Sets page ids params for number titles', () => {
45 | const params = {}
46 | const result = setPageIdOrTitleParam(params, "112")
47 | expect(result.pageids).toBe("112");
48 | });
49 |
50 | test('Sets pageId from params if present', () => {
51 | const params = { pageIds: 500 }
52 | const result = setPageId(params, "");
53 | expect(result).toBe(500);
54 | });
55 |
56 | test('Sets pageid from result if not present in params', () => {
57 | const output = { query: { pages: { 500: {} } } }
58 | const result = setPageId({}, output);
59 | expect(result).toBe("500");
60 | });
61 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "outDir": "dist",
4 | "target": "es2018", // Node.js 10
5 | "lib": [
6 | "es2018"
7 | ],
8 | "types" : [ "node", "jest" ],
9 | "strict": true,
10 | "noImplicitReturns": true,
11 | "noUnusedLocals": true,
12 | "noUnusedParameters": true,
13 | "allowSyntheticDefaultImports": true,
14 | "module": "commonjs",
15 | "moduleResolution": "node",
16 | "declaration": true,
17 | "useUnknownInCatchVariables": false
18 | },
19 | "include": [
20 | "source"
21 | ],
22 | "typedocOptions": {
23 | "exclude": ["**/node_modules/**"],
24 | "mode": "modules",
25 | "out": "docs"
26 | }
27 | }
--------------------------------------------------------------------------------