@andymenderunix/jisho-js
Version:
JavaScript wrapper around the jisho.org search Web API.
321 lines (260 loc) • 11.1 kB
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>JSDoc: Source: index.js</title>
<script src="scripts/prettify/prettify.js"> </script>
<script src="scripts/prettify/lang-css.js"> </script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>
<body>
<div id="main">
<h1 class="page-title">Source: index.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>/*
Main module entrypoint.
*/
// CONSTANTS
const JISHO_API_URL = "https://jisho.org/api/v1/search/words?keyword=";
const REQUEST_HEADERS = new Headers();
REQUEST_HEADERS.append('content-type', 'application/json');
REQUEST_HEADERS.append('accept', 'application/json');
REQUEST_HEADERS.append('user-agent', 'node.js');
const REQUEST_JSON = {
method: "GET",
headers: REQUEST_HEADERS,
mode: "cors",
cache: "default",
};
// OBJECTS
// NOTE: Using a proper 'class' definition is significantly slower
/**
* [JishoRecord Converts an entry from the Jisho Web API into a simplified form]
* @param {Object} entry [Entry from the Jisho Web API]
* @return {Object} [Array of jisho results objects]
*/
function JishoRecord(entry) {
return {
slug: entry.slug,
is_common: entry.is_common,
jlpt_level: extractJLPTLevel(entry),
wanikani_level: extractWaniKaniLevel(entry),
reading: extractReading(entry),
meanings: extractMeanings(entry),
word_type: extractWordTypes(entry)
};
}
// ENDPOINTS
/**
* [getEntries Gets records from the Jisho Web API]
* @param {string} query [Query word to send to the API]
* @param {boolean} is_commmon [Flag to query for common vocabulary]
* @return {Array} [Array of JishoRecord objects]
*/
async function getEntries(query, is_common = false) {
if (typeof query !== 'string') {
throw new Error(`Query value '${query}' is incompatible. It must be a string. Aborting!`);
}
const query_blocks = [query];
if (is_common) {
query_blocks.unshift('#common');
}
const response_json = await execute_query(query_blocks);
return extractJishoData(response_json);
}
/**
* [getCommonEntries Get only common entries for a given query]
* @param {string} query [Query word to send to the API]
* @return {Array} [Array of JishoRecord objects]
*/
async function getCommonEntries(query) {
return getEntries(query, true);
}
/**
* [getEntriesStartingWith Get results for a word starting with a given query]
* @param {string} query [Query word to send to the API]
* @param {boolean} is_commmon [Flag to query for common vocabulary]
* @return {Array} [Array of JishoRecord objects]
*/
async function getEntriesStartingWith(query, is_common = false) {
if (typeof query !== 'string') {
throw new Error(`Query value '${query}' is incompatible. It must be a string. Aborting!`);
}
return getEntries(`${query}*`, is_common);
}
/**
* [getEntriesEndingWith Get results for a word ending with a given query]
* @param {string} query [Query word to send to the API]
* @param {boolean} is_commmon [Flag to query for common vocabulary]
* @return {Array} [Array of JishoRecord objects]
*/
async function getEntriesEndingWith(query, is_common = false) {
if (typeof query !== 'string') {
throw new Error(`Query value '${query}' is incompatible. It must be a string. Aborting!`);
}
return getEntries(`*${query}`, is_common);
}
/**
* [getEntriesJLPTLevel Get results for a given JLPT level]
* @param {string} query [Query word to send to the API]
* @param {string} jlpt_level [JLPT level in the Nx or nx format]
* @return {Array} [Array of JishoRecord objects]
*/
async function getEntriesJLPTLevel(query, jlpt_level) {
if (typeof query !== 'string') {
throw new Error(`Query value '${query}' is incompatible. It must be a string. Aborting!`);
}
const jlpt_regex = /[Nn]?/;
if (typeof jlpt_level !== 'string' && !jlpt_level.match(jlpt_regex)) {
throw new Error(`JLPT level needs to be in the format 'N3' or 'n3'. Got '${jlpt_level}' instead. Aborting!`);
}
const jlpt_string = `#jlpt-${jlpt_level.toLowerCase()}`;
const response_json = await execute_query([jlpt_string, query]);
return extractJishoData(response_json);
}
/**
* [getEntriesWasei Get wasei eigo results for a given query]
* @param {string} query [Query word to send to the API]
* @param {boolean} is_commmon [Flag to query for common vocabulary]
* @return {Array} [Array of JishoRecord objects]
*/
async function getEntriesWasei(query, is_common = false) {
if (typeof query !== 'string') {
throw new Error(`Query value '${query}' is incompatible. It must be a string. Aborting!`);
}
const query_blocks = ['#wasei', query];
if (is_common) {
query_blocks.unshift('#common');
}
const response_json = await execute_query(query_blocks);
return extractJishoData(response_json);
}
/**
* [execute_query Core function to get results from the Jisho API]
* @param {Array} query_blocks [Query words to send to the API]
* @return {Array} [Array of jisho results objects]
*/
async function execute_query(query_blocks) {
const query_string = query_blocks.join(' ');
const encoded_query = query_blocks.map(entry => encodeURIComponent(entry)).join(' ');
const fullURL = `${JISHO_API_URL}${encoded_query}`;
console.debug(`Executing Jisho API call '${fullURL}'`);
const request = new Request(fullURL, REQUEST_JSON);
const response = await fetch(request);
// NOTE: The Jisho Web API almost always returns HTTP 200,
// because there is some result to return
if (response.status === 200) {
console.debug(`Response for query '${query_string}' received.`);
return await response.json();
}
throw new Error(
`HTTP ${response.status}: Couldn't get results for query '${query_string}'.`
+ ' Check if API server is available and the query correct.'
);
}
// UTILITY FUNCTIONS
/**
* [extractJLPTLevel Extract the JLPT level from a Jisho API response record]
* @param {Object} entry [record in a Jisho API response]
* @return {string} [JLPT level in the format 'Nx']
*/
function extractJLPTLevel(entry) {
const jlpt_block = entry.jlpt[0];
if (jlpt_block === undefined) return '';
return jlpt_block
.replace('jlpt-', '')
.toUpperCase();
}
/**
* [extractWaniKaniLevel Extract the WaniKani level from a Jisho API response record]
* @param {Object} entry [record in a Jisho API response]
* @return {string} [WaniKani level]
*/
function extractWaniKaniLevel(entry) {
const tags_block = entry.tags[0];
if (tags_block === undefined) return '';
return tags_block
.replace('wanikani', '');
}
/**
* [extractReading Extract the word reading from a Jisho API response record]
* @param {Object} entry [record in a Jisho API response]
* @return {string} [reading]
*/
function extractReading(entry) {
const reading = entry.japanese[0].reading;
return reading;
}
/**
* [extractMeanings Extract a word's meanings from a Jisho API response record]
* @param {Object} entry [record in a Jisho API response]
* @return {Array} [array of unique word meanings]
*/
function extractMeanings(entry) {
let meanings = [];
for (const meaning_block of entry.senses) {
meanings = meanings.concat(
meaning_block.english_definitions.
map(entry => entry.toLowerCase())
);
}
return [...new Set(meanings)];
}
/**
* [extractWordTypes Extract a word's grammatical types from a Jisho API response record]
* @param {Object} entry [record in a Jisho API response]
* @return {Array} [array of unique word grammatical types]
*/
function extractWordTypes(entry) {
let word_types = [];
for (const type_block of entry.senses) {
word_types = word_types.concat(
type_block.parts_of_speech
.map(entry => entry.toLowerCase())
.filter(entry => !entry.includes('wikipedia'))
);
}
return [...new Set(word_types)];
}
/**
* [extractJishoData Converts Jisho API response records into JishoRecord entries]
* @param {Array} response_json [array of records in a Jisho API response]
* @return {Array} [array of JishoRecord Objects]
*/
async function extractJishoData(response_json) {
// Extract and transform the data block
return response_json.data.map(entry => JishoRecord(entry));
}
// TESTING GROUNDS
getEntries('道具').then(results => console.log(results)).catch((error) => {
console.error(error);
});
// getCommonEntries('道具').then(results => console.log(results)).catch((error) => {
// console.error(error);
// });
// getEntriesJLPTLevel('地', 'N3').then(results => console.log(results)).catch((error) => {
// console.error(error);
// });
// getEntriesWasei('ボ', true).then(results => console.log(results)).catch((error) => {
// console.error(error);
// });
</code></pre>
</article>
</section>
</div>
<nav>
<h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#execute_query">execute_query</a></li><li><a href="global.html#extractJishoData">extractJishoData</a></li><li><a href="global.html#extractJLPTLevel">extractJLPTLevel</a></li><li><a href="global.html#extractMeanings">extractMeanings</a></li><li><a href="global.html#extractReading">extractReading</a></li><li><a href="global.html#extractWaniKaniLevel">extractWaniKaniLevel</a></li><li><a href="global.html#extractWordTypes">extractWordTypes</a></li><li><a href="global.html#getCommonEntries">getCommonEntries</a></li><li><a href="global.html#getEntries">getEntries</a></li><li><a href="global.html#getEntriesEndingWith">getEntriesEndingWith</a></li><li><a href="global.html#getEntriesJLPTLevel">getEntriesJLPTLevel</a></li><li><a href="global.html#getEntriesStartingWith">getEntriesStartingWith</a></li><li><a href="global.html#getEntriesWasei">getEntriesWasei</a></li><li><a href="global.html#JishoRecord">JishoRecord</a></li></ul>
</nav>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc/jsdoc">JSDoc 3.6.11</a> on Sun Jul 23 2023 12:57:23 GMT+0200 (Central European Summer Time)
</footer>
<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>