UNPKG

wordnik-api

Version:

Community API for https://wordnik.com with types

602 lines (528 loc) 24.5 kB
import fetch from "node-fetch"; import {PartOfSpeech} from "./struct/PartOfSpeech"; import Word from "./entity/Word"; import AudioMetadata from "./entity/AudioMetadata"; import Example from "./entity/Example"; import Frequency from "./entity/Frequency"; import Syllable from "./entity/Syllable"; import Phrase from "./entity/Phrase"; import Pronunciation from "./entity/Pronunciation"; import {RelationshipType} from "./struct/RelationshipType"; import RelatedWord from "./entity/RelatedWord"; import RandomWord from "./entity/RandomWord"; import WordOfTheDay from "./entity/WordOfTheDay"; /** * Defines the WordnikAPI class. */ export default class WordnikAPI { private static readonly BASE_URL = "https://api.wordnik.com/v4/word.json/"; private static readonly WORDS_URL = "https://api.wordnik.com/v4/words.json/"; private readonly API_KEY: string; /** * Constructs a new WordnikAPI instance. * @param API_KEY {string} The API key to use. */ public constructor(API_KEY: string) { this.API_KEY = API_KEY; if(!API_KEY || API_KEY.length === 0) { throw new Error("API_KEY must be defined. See https://developer.wordnik.com/gettingstarted to obtain one."); } } /** * Make an API call to the Wordnik API. * * @param endpoint {string} The endpoint to call. * @param params {object} The parameters to pass to the endpoint. * @param base_url {string} The base URL to use (optional). * * @private */ private async makeRequest(endpoint: string, params: any, base_url: string = WordnikAPI.BASE_URL): Promise<any> { //use node-fetch to make the request, all params are passed as query params //start with the api_key param and append "params" to the url let url = `${base_url}${endpoint}?api_key=${this.API_KEY}`; //loop through the params and append them to the url for (let key in params) { //the key may be "undefined" if (params[key] !== undefined) { url += "&" + key + "=" + params[key]; } } //make the request const res = await fetch(url, { headers: { "Accept": "application/json", "User-Agent": "WordnikAPI-EP/1.0.0", }, method: "GET", redirect: "error", }); if(res.status === 401) { console.error("[wordnik-api]: Invalid API key. If you do not have an API key, go to https://developer.wordnik.com/gettingstarted to get one."); throw new Error("Invalid API key."); } //return the response return await res.json(); } /** * Gets the API key. * * @returns {string} The API key. */ public getAPIKey(): string { return this.API_KEY; } /** * Get definitions for a word. * * https://developer.wordnik.com/docs#!/word/getDefinitions * * @param word {string} The word to get definitions for. * @param limit {number} The limit of definitions to get. * @param partOfSpeech {PartOfSpeech} The part of speech to get definitions for. * @param sourceDictionary {"all" | "ahd-5" | "century" | "wiktionary" | "webster" | "wordnet"} The source dictionary to get definitions for. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param includeTags {boolean} Whether to include tags in the response. * * @returns {Promise<Word[] | null>} The definitions for the word, or null if the word is not found. */ public async getDefinitions(word: string, limit: number = 1, partOfSpeech: PartOfSpeech[] | PartOfSpeech | undefined = undefined, sourceDictionary: "all" | "ahd-5" | "century" | "wiktionary" | "webster" | "wordnet" = "all", useCanonical: boolean = false, includeTags: boolean = false): Promise<Word[] | null> { try { const res = await this.makeRequest(word + "/definitions", { limit: limit, partOfSpeech: partOfSpeech?.toString(), sourceDictionaries: sourceDictionary, useCanonical: useCanonical, includeTags: includeTags, }); //the response body is a JSON array of Word objects let words: Word[] = []; //loop through the JSON array and create Word objects for (let w of res) { words.push(w); } return words; } catch (e) { return null; } } /** * Get the audio metadata for a word. * * https://developer.wordnik.com/docs#!/word/getAudio * * @param word {string} The word to get audio metadata for. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param limit {number} The limit of audio metadata to get. * * @returns {Promise<AudioMetadata[] | null>} The audio metadata for the word, or null if the word is not found. */ public async getAudio(word: string, useCanonical: boolean = false, limit: number = 1): Promise<AudioMetadata[] | null> { try { const res = await this.makeRequest(word + "/audio", { useCanonical: useCanonical, limit: limit, }); //the response body is a JSON array of AudioMetadata objects let audios: AudioMetadata[] = []; //loop through the JSON array and create AudioMetadata objects for (let a of res) { audios.push(a); } return audios; } catch (e) { return null; } } /** * Get the etymologies for a word. * * https://developer.wordnik.com/docs#!/word/getEtymologies * * @param word {string} The word to get etymologies for. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * * @returns {Promise<string[] | null>} The etymologies for the word, or null if the word is not found. */ public async getEtymologies(word: string, useCanonical: boolean = false): Promise<string[] | null> { try { const res = await this.makeRequest(word + "/etymologies", { useCanonical: useCanonical, }); //the response body is a JSON array of strings let etymologies: string[] = []; //loop through the JSON array and create strings for (let e of res) { etymologies.push(e); } return etymologies; } catch (e) { return null; } } /** * Get examples of a word's usage. * * https://developer.wordnik.com/docs#!/word/getExamples * * @param word {string} The word to get examples for. * @param includeDuplicates {boolean} Whether to include duplicate examples. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param skip {number} The number of examples to skip. * @param limit {number} The limit of examples to get (max 50). * * @returns {Promise<Example[] | null>} The examples for the word, or null if the word is not found. */ public async getExamples(word: string, includeDuplicates: boolean = false, useCanonical: boolean = false, skip: number = 0, limit: number = 1): Promise<Example[] | null> { try { if (limit > 50) { limit = 50; } const res = await this.makeRequest(word + "/examples", { includeDuplicates: includeDuplicates, useCanonical: useCanonical, skip: skip, limit: limit, }); //the response body is a JSON object with an "examples" key (a JSON array of Example objects) //create an array of Example objects let examples: Example[] = []; //loop through the JSON array and create Example objects for (let e of res.examples) { examples.push(e); } return examples; } catch (e) { return null; } } /** * Get the frequency of a word. * * https://developer.wordnik.com/docs#!/word/getWordFrequency * * @param word {string} The word to get the frequency of. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param startYear {number} The start year to get the frequency of. * @param endYear {number} The end year to get the frequency of. * * @returns {Promise<Frequency[] | null>} The frequency of the word, or null if the word is not found. */ public async getFrequency(word: string, useCanonical: boolean = false, startYear: number = 1800, endYear: number = 2012): Promise<Frequency[] | null> { try { const res = await this.makeRequest(word + "/frequency", { useCanonical: useCanonical, startYear: startYear, endYear: endYear, }); //the response body is a JSON object with a "frequency" key (a JSON array of Frequency objects) //create an array of Frequency objects let frequencies: Frequency[] = []; //loop through the JSON array and create Frequency objects for (let f of res.frequency) { frequencies.push(f); } return frequencies; } catch (e) { return null; } } /** * Get the word's hyphenation. * * https://developer.wordnik.com/docs#!/word/getHyphenation * * @param word {string} The word to get the hyphenation of. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param sourceDictionary {string} The source dictionary to get the hyphenation of. * @param limit {number} The limit of hyphenations to get. * * @returns {Promise<Syllable[] | null>} The word's hyphenation. */ public async getHyphenation(word: string, useCanonical: boolean = false, sourceDictionary: "all" | "ahd-5" | "century" | "wiktionary" | "webster" | "wordnet" = "all", limit: number = 1): Promise<Syllable[] | null> { try { const res = await this.makeRequest(word + "/hyphenation", { useCanonical: useCanonical, sourceDictionary: sourceDictionary, limit: limit, }); //the response body is a JSON array of Syllable objects //create an array of Syllable objects let syllables: Syllable[] = []; //loop through the JSON array and create Syllable objects for (let s of res) { syllables.push(s); } return syllables; } catch (e) { return null; } } /** * Get word phrases * * https://developer.wordnik.com/docs#!/word/getPhrases * * @param word {string} The word to get the phrases of. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param limit {number} The limit of phrases to get. * * @returns {Promise<Phrase[] | null>} The word's phrases. */ public async getPhrases(word: string, useCanonical: boolean = false, limit: number = 1): Promise<Phrase[] | null> { try { const res = await this.makeRequest(word + "/phrases", { useCanonical: useCanonical, limit: limit, }); //the response body is a JSON array of Phrase objects //create an array of Phrase objects let phrases: Phrase[] = []; //loop through the JSON array and create Phrase objects for (let p of res) { phrases.push(p); } return phrases; } catch (e) { return null; } } /** * Get the word's Pronunciation. * * https://developer.wordnik.com/docs#!/word/getTextPronunciations * * @param word {string} The word to get the pronunciation of. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param sourceDictionary {string} The source dictionary to get the pronunciation of. * @param typeFormat {string} The type of pronunciation to get. * @param limit {number} The limit of pronunciations to get. * * @returns {Promise<Pronunciation[] | null>} The word's Pronunciation. */ public async getPronunciation(word: string, useCanonical: boolean = false, sourceDictionary: "ahd-5" | "century" | "wiktionary" | "webster" | "wordnet" | undefined = undefined, typeFormat: "ahd-5" | "arpabet" | "gcide-diacritical" | "IPA" | undefined = undefined, limit: number = 1): Promise<Pronunciation[] | null> { try { const res = await this.makeRequest(word + "/pronunciation", { limit: limit, useCanonical: useCanonical, sourceDictionary: sourceDictionary, typeFormat: typeFormat, }); //the response body is a JSON array of Pronunciation objects //create an array of Pronunciation objects let pronunciations: Pronunciation[] = []; //loop through the JSON array and create Pronunciation objects for (let p of res) { pronunciations.push(p); } return pronunciations; } catch (e) { return null; } } /** * Get related words. * * https://developer.wordnik.com/docs#!/word/getRelatedWords * * @param word {string} The word to get related words for. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * @param relationshipTypes {RelationshipType | undefined} The relationship types to get. * @param limitPerRelationshipType {number} The limit of related words to get per relationship type. * @returns {Promise<RelatedWord[] | null>} The related words or null if an error occurred. */ public async getRelatedWords(word: string, useCanonical: boolean = false, relationshipTypes: RelationshipType | undefined = undefined, limitPerRelationshipType: number | undefined = undefined): Promise<RelatedWord[] | null> { try { const res = await this.makeRequest(word + "/relatedWords", { useCanonical: useCanonical, relationshipTypes: relationshipTypes, limitPerRelationshipType: limitPerRelationshipType, }); //the response body is a JSON array of RelatedWord objects //create an array of RelatedWord objects let relatedWords: RelatedWord[] = []; //loop through the JSON array and create RelatedWord objects for (let r of res) { relatedWords.push(r); } return relatedWords; } catch (e) { return null; } } /** * Get the scrabble score of a word. * You may want to lowercase the word before passing it in. * * https://developer.wordnik.com/docs#!/word/getScrabbleScore * * @param word {string} The word to get the scrabble score of. * * @returns {Promise<number | null>} The scrabble score of the word, or null if the word is not found. */ public async getScrabbleScore(word: string): Promise<number | null> { try { const res = await this.makeRequest(word + "/scrabbleScore", {}); return res.value; } catch (e) { return null; } } /** * Get the top example of a word. * * https://developer.wordnik.com/docs#!/word/getTopExample * * @param word {string} The word to get the top example of. * @param useCanonical {boolean} Whether to use the canonical form of the word (e.g. "cats" -> "cat"). * * @returns {Promise<Example | null>} The top example of the word, or null if the word is not found. */ public async getTopExample(word: string, useCanonical: boolean = false): Promise<Example | null> { try { return await this.makeRequest(word + "/topExample", { useCanonical: useCanonical, }); } catch (e) { return null; } } /** * Get a random word. * * https://developer.wordnik.com/docs#!/words/getRandomWord * * @param hasDictionaryDef {"true" | "false"} Only return words with dictionary definitions * @param includePartOfSpeech {PartOfSpeech | undefined} Only return words with the specified part of speech. * @param excludePartOfSpeech {PartOfSpeech | undefined} Only return words without the specified part of speech. * @param minCorpusCount {number | undefined} Minimum corpus frequency for terms * @param maxCorpusCount {number | undefined} Maximum corpus frequency for terms * @param minDictionaryCount {number | undefined} Minimum dictionary count * @param maxDictionaryCount {number | undefined} Maximum dictionary count * @param minLength {number | undefined} Minimum word length * @param maxLength {number | undefined} Maximum word length */ public async getRandomWord(hasDictionaryDef: "true" | "false" = "true", includePartOfSpeech: PartOfSpeech | undefined = undefined, excludePartOfSpeech: PartOfSpeech | undefined = undefined, minCorpusCount: number | undefined = undefined, maxCorpusCount: number | undefined = undefined, minDictionaryCount: number | undefined = undefined, maxDictionaryCount: number | undefined = undefined, minLength: number | undefined = undefined, maxLength: number | undefined = undefined): Promise<RandomWord | null> { try { return await this.makeRequest("randomWord", { hasDictionaryDef: hasDictionaryDef, includePartOfSpeech: includePartOfSpeech, excludePartOfSpeech: excludePartOfSpeech, minCorpusCount: minCorpusCount, maxCorpusCount: maxCorpusCount, minDictionaryCount: minDictionaryCount, maxDictionaryCount: maxDictionaryCount, minLength: minLength, maxLength: maxLength, }, WordnikAPI.WORDS_URL); } catch (e) { return null; } } /** * Get random words. * * https://developer.wordnik.com/docs#!/words/getRandomWords * * @param hasDictionaryDef {"true" | "false"} Only return words with dictionary definitions * @param includePartOfSpeech {PartOfSpeech[] | undefined} Only return words with the specified part of speech. * @param excludePartOfSpeech {PartOfSpeech[] | undefined} Only return words without the specified part of speech. * @param minCorpusCount {number | undefined} Minimum corpus frequency for terms * @param maxCorpusCount {number | undefined} Maximum corpus frequency for terms * @param minDictionaryCount {number | undefined} Minimum dictionary count * @param maxDictionaryCount {number | undefined} Maximum dictionary count * @param minLength {number | undefined} Minimum word length * @param maxLength {number | undefined} Maximum word length * @param sortBy {"alpha" | "count" | undefined} Sort by * @param sortOrder {"asc" | "desc" | undefined} Sort order * @param limit {number | undefined} Limit * * @returns {Promise<RandomWord[]>} Random words, or an empty array if no words were found. */ public async getRandomWords(hasDictionaryDef: "true" | "false" = "true", includePartOfSpeech: PartOfSpeech[] | undefined = undefined, excludePartOfSpeech: PartOfSpeech[] | undefined = undefined, minCorpusCount: number | undefined = undefined, maxCorpusCount: number | undefined = undefined, minDictionaryCount: number | undefined = undefined, maxDictionaryCount: number | undefined = undefined, minLength: number | undefined = undefined, maxLength: number | undefined = undefined, sortBy: "alpha" | "count" | undefined = undefined, sortOrder: "asc" | "desc" | undefined = undefined, limit: number = 10): Promise<RandomWord[]> { //this returns an array of random words try { return await this.makeRequest("randomWords", { hasDictionaryDef: hasDictionaryDef, includePartOfSpeech: includePartOfSpeech, excludePartOfSpeech: excludePartOfSpeech, minCorpusCount: minCorpusCount, maxCorpusCount: maxCorpusCount, minDictionaryCount: minDictionaryCount, maxDictionaryCount: maxDictionaryCount, minLength: minLength, maxLength: maxLength, sortBy: sortBy, sortOrder: sortOrder, limit: limit, }, WordnikAPI.WORDS_URL); } catch (e) { return []; } } /** * Get the word of the day. * * https://developer.wordnik.com/docs#!/words/getWordOfTheDay * * @param date {Date | string | undefined} the Date to get the word of the day for, a string in the format yyyy-MM-dd, or undefined to get the word of the day for today. * @returns {Promise<WordOfTheDay | null>} */ public async getWordOfTheDay(date: string | Date | undefined = undefined): Promise<WordOfTheDay | null> { //the date should be in the format yyyy-MM-dd, validate that it is if it is a string, otherwise use the date if(date && typeof date === "string") { if (!/^\d{4}-\d{2}-\d{2}$/.test(date)) { throw new Error("Invalid date format, should be yyyy-MM-dd"); } } else if(date && date instanceof Date) { date = date.toISOString().substring(0, 10); } try { return await this.makeRequest("wordOfTheDay", { date: date, }, WordnikAPI.WORDS_URL); } catch (e) { return null; } } }