diff --git a/README.md b/README.md index 8ece54d..172eddd 100644 --- a/README.md +++ b/README.md @@ -62,9 +62,17 @@ const wiki = require('wikipedia'); } })(); ``` + +You can also pass a valid wikipedia url instead of a string by using the url parameters in [pageOptions][10] like this. If you use an url without the url option it will fail. +```js + const page = await wiki.page('https://en.wikipedia.org/wiki/Batman',{url:true}); + console.log(page); + //Response will be the same as passing a string +``` + 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. -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. +All the page methods can take a title parameter, url or a pageId. Read up on the [Page documentation][2] here to see a detailed overview of the methods available in page. 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. @@ -246,3 +254,4 @@ The project would not be the way it is without these rockstars. [7]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#eventOptions [8]: https://github.com/dopecodez/wikipedia/blob/master/docs/wiki.md#onThisDay [9]: https://github.com/dopecodez/wikipedia/blob/master/docs/PAGE.md#summary +[10]: https://github.com/dopecodez/wikipedia/blob/master/docs/optionTypes.md#pageOptions diff --git a/docs/optionTypes.md b/docs/optionTypes.md index 47acc98..6c5c4b3 100644 --- a/docs/optionTypes.md +++ b/docs/optionTypes.md @@ -19,12 +19,14 @@ interface pageOptions { redirect?: boolean preload?: boolean fields?: Array + url?: boolean } ``` The options for page methods on `Page` or `wiki`. Generally, can be used for all page methods which do not return a array. - `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**. - `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. +- `url : boolean`(default = false) - allows you to pass a valid wikipedia url in the title to get the information of that page. The other two fields are only applicable if added on the `wiki.page('title')` method, otherwise its ignored. @@ -38,6 +40,7 @@ interface listOptions { autoSuggest?: boolean redirect?: boolean limit?: number + url?: boolean } ``` The options for page methods on `Page` or `wiki`. Generally, can be used for all page methods which return an array @@ -45,6 +48,7 @@ The options for page methods on `Page` or `wiki`. Generally, can be used for all - `autoSuggest : boolean`(default = false) - suggest a page title which is reccomened by wikipedia for given search string* - `redirect : boolean`(default = true) - redirect in case wikipedia returns a 304 - `limit : number`(default = 10) - Use this to increase/decrease number of results in the returned array +- `url : boolean`(default = false) - allows you to pass a valid wikipedia url in the title to get the information of that page. ### searchOptions diff --git a/source/index.ts b/source/index.ts index 642fb8c..c9ea93c 100644 --- a/source/index.ts +++ b/source/index.ts @@ -66,13 +66,13 @@ wiki.search = async (query: string, searchOptions?: searchOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } let pageParams: any = { prop: 'info|pageprops', @@ -114,8 +114,8 @@ wiki.page = async (title: string, pageOptions?: pageOptions): Promise => { */ wiki.intro = async (title: string, pageOptions?: pageOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const result = await intro(title, pageOptions?.redirect); return result; @@ -136,8 +136,8 @@ wiki.intro = async (title: string, pageOptions?: pageOptions): Promise = */ wiki.images = async (title: string, listOptions?: listOptions): Promise> => { try { - if (listOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (listOptions?.url || listOptions?.autoSuggest) { + title = await setTitleForPage(title, listOptions); } const result = await images(title, listOptions); return result; @@ -158,8 +158,8 @@ wiki.images = async (title: string, listOptions?: listOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const result = await summary(title, pageOptions?.redirect); return result; @@ -182,8 +182,8 @@ wiki.summary = async (title: string, pageOptions?: pageOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const result = await html(title, pageOptions?.redirect); return result; @@ -204,8 +204,8 @@ wiki.html = async (title: string, pageOptions?: pageOptions): Promise => */ wiki.content = async (title: string, pageOptions?: pageOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await content(title, pageOptions?.redirect); return response.result; @@ -226,8 +226,8 @@ wiki.content = async (title: string, pageOptions?: pageOptions): Promise */ wiki.categories = async (title: string, listOptions?: listOptions): Promise> => { try { - if (listOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (listOptions?.url || listOptions?.autoSuggest) { + title = await setTitleForPage(title, listOptions); } const response = await categories(title, listOptions); return response; @@ -251,8 +251,8 @@ wiki.categories = async (title: string, listOptions?: listOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await related(title, pageOptions?.redirect); return response; @@ -276,8 +276,8 @@ wiki.related = async (title: string, pageOptions?: pageOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await media(title, pageOptions?.redirect); return response; @@ -298,8 +298,8 @@ wiki.media = async (title: string, pageOptions?: pageOptions): Promise> => { try { - if (listOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (listOptions?.url || listOptions?.autoSuggest) { + title = await setTitleForPage(title, listOptions); } const response = await links(title, listOptions); return response; @@ -320,8 +320,8 @@ wiki.links = async (title: string, listOptions?: listOptions): Promise> => { try { - if (listOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (listOptions?.url || listOptions?.autoSuggest) { + title = await setTitleForPage(title, listOptions); } const response = await references(title, listOptions); return response; @@ -342,8 +342,8 @@ wiki.references = async (title: string, listOptions?: listOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await coordinates(title, pageOptions?.redirect); return response; @@ -364,8 +364,8 @@ wiki.coordinates = async (title: string, pageOptions?: pageOptions): Promise> => { try { - if (listOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (listOptions?.url || listOptions?.autoSuggest) { + title = await setTitleForPage(title, listOptions); } const response = await langLinks(title, listOptions); return response; @@ -386,8 +386,8 @@ wiki.langLinks = async (title: string, listOptions?: listOptions): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await infobox(title, pageOptions?.redirect); return response; @@ -408,8 +408,8 @@ wiki.infobox = async (title: string, pageOptions?: pageOptions): Promise => */ wiki.tables = async (title: string, pageOptions?: pageOptions): Promise> => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const response = await tables(title, pageOptions?.redirect); return response; @@ -580,8 +580,8 @@ wiki.random = async (format?: randomFormats): Promise => { try { - if (pageOptions?.autoSuggest) { - title = await setTitleForPage(title); + if (pageOptions?.url || pageOptions?.autoSuggest) { + title = await setTitleForPage(title, pageOptions); } const result = await mobileHtml(title, pageOptions?.redirect); return result; diff --git a/source/messages.ts b/source/messages.ts index 6382701..5cdc2d6 100644 --- a/source/messages.ts +++ b/source/messages.ts @@ -1,5 +1,6 @@ export const MSGS = { PAGE_NOT_SUGGEST: 'No page with given title suggested : ', PAGE_NOT_EXIST: 'No page with given title exists : ', - INFOBOX_NOT_EXIST: 'Info cannot be parsed for given page' + INFOBOX_NOT_EXIST: 'Info cannot be parsed for given page', + INVALID_WIKIPEDIA_URL: 'The provided URL is invalid or does not belong to Wikipedia - ', } \ No newline at end of file diff --git a/source/optionTypes.ts b/source/optionTypes.ts index 2b235cf..a9964ab 100644 --- a/source/optionTypes.ts +++ b/source/optionTypes.ts @@ -12,12 +12,14 @@ export interface pageOptions { redirect?: boolean preload?: boolean fields?: Array + url?: boolean } export interface listOptions { autoSuggest?: boolean redirect?: boolean limit?: number + url?: boolean } export interface geoOptions { diff --git a/source/page.ts b/source/page.ts index cb8f463..4845d8a 100644 --- a/source/page.ts +++ b/source/page.ts @@ -31,7 +31,7 @@ export class Page { _categories!: Array; _references!: Array; _links!: Array; - _coordinates!: coordinatesResult; + _coordinates!: coordinatesResult | null; _langLinks!: Array; _infobox!: any; _tables!: Array; @@ -245,7 +245,7 @@ export class Page { * @param redirect - Whether to redirect in case of 302 * @returns The coordinates as {@link coordinatesResult | coordinatesResult} */ - public coordinates = async (pageOptions?: pageOptions): Promise => { + public coordinates = async (pageOptions?: pageOptions): Promise => { try { if (!this._coordinates) { const result = await coordinates(this.pageid.toString(), pageOptions?.redirect); @@ -628,7 +628,7 @@ export const references = async (title: string, listOptions?: listOptions): Prom * @param redirect - Whether to redirect in case of 302 * @returns The coordinates as {@link coordinatesResult | coordinatesResult} */ -export const coordinates = async (title: string, redirect = true): Promise => { +export const coordinates = async (title: string, redirect = true): Promise => { try { let coordinatesOptions: any = { prop: 'coordinates', diff --git a/source/utils.ts b/source/utils.ts index 33966b3..f188d4a 100644 --- a/source/utils.ts +++ b/source/utils.ts @@ -1,4 +1,4 @@ -import wiki from "."; +import wiki, { pageOptions } from "."; import { pageError } from "./errors"; import { MSGS } from "./messages"; @@ -7,9 +7,15 @@ export function isString(title: any){ return isNaN(title); } -//set title for page in case autoSuggest is true -export async function setTitleForPage(title: string) { +//set title for page in case url or autoSuggest is true +export async function setTitleForPage(title: string, pageOptions?: pageOptions): Promise { { + if (pageOptions?.url) { + const match = title.match(/(?<=\/wiki\/)[^/?#]+/); + if (!match) throw new pageError(`${MSGS.INVALID_WIKIPEDIA_URL}${title}`); + title = match[0]; + return title; + } const searchResult = await wiki.search(title, { limit: 1, suggestion: true }) if (!searchResult.suggestion && searchResult.results.length == 0) { throw new pageError(`${MSGS.PAGE_NOT_SUGGEST}${title}`) diff --git a/test/index.test.ts b/test/index.test.ts index f86b76b..1317749 100644 --- a/test/index.test.ts +++ b/test/index.test.ts @@ -217,4 +217,11 @@ test('Suggest returns string', async () => { test('sets the user agent', async () => { let result = wiki.setUserAgent("testUser"); expect(result).toStrictEqual(undefined); +}); + +test('Page returns results as Page Class if url given instead of title', async () => { + requestMock.mockImplementation(async () => { return { query: { pages: { 500: pageJson } } } }); + setTitleMock.mockImplementation(async () => { return "test" }); + const result = await wiki.page("https://en.wikipedia.org/wiki/Test", { url: true }); + expect(result.toString()).toStrictEqual(pageObject.toString()); }); \ No newline at end of file diff --git a/test/utils.test.ts b/test/utils.test.ts index d70ee00..3955f3c 100644 --- a/test/utils.test.ts +++ b/test/utils.test.ts @@ -16,7 +16,7 @@ test('Is String returns true for strings', () => { }); test('Returns error if no suggestion or search results are present', async () => { - searchMock.mockImplementation(async () => { return { suggestion: null, results: [] } }); + searchMock.mockImplementation(async () => { return { suggestion: "", results: [] } }); const t = async () => { await setTitleForPage("Test") }; @@ -30,7 +30,7 @@ test('Returns suggestion if suggestion is present', async () => { }); test('Returns title if no suggestion but search results are present', async () => { - searchMock.mockImplementation(async () => { return { suggestion: null, results: ['result'] } }); + searchMock.mockImplementation(async () => { return { suggestion: "", results: ['result'] } }); const result = await setTitleForPage("Test"); expect(result).toBe("Test"); }); @@ -58,3 +58,21 @@ test('Sets pageid from result if not present in params', () => { const result = setPageId({}, output); expect(result).toBe("500"); }); + +test('Returns the correct title if given url', async () => { + const result = await setTitleForPage("https://en.wikipedia.org/wiki/Batman", { url: true }); + expect(result).toBe("Batman"); +}); + +test('Returns the correct title if url has special chars in title', async () => { + const result = await setTitleForPage("https://en.wikipedia.org/wiki/666_(number)", { url: true }); + expect(result).toBe("666_(number)"); +}); + +test('Throws error if url not wikipedia', async () => { + const t = async () => { + await setTitleForPage("https://example.com/666_(number)", { url: true }); + }; + expect(t).rejects.toThrowError(pageError); +}); +