lunr-elastic-search
Version:
Uses Lunr.js to index and search the knowledge base.
221 lines (177 loc) • 10 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>Source: plugin/freshdesk.js | lunr-elastic-search</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/bootstrap.min.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-jsdoc.css">
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
<link type="text/css" rel="stylesheet" href="styles/tui-doc.css">
</head>
<body>
<nav class="lnb" id="lnb">
<div class="logo" style="">
<img src="img/toast-ui.png" width="100%" height="100%">
</div>
<div class="title">
<h1><a href="index.html" class="link">lunr-elastic-search</a></h1>
</div>
<div class="search-container" id="search-container">
<input type="text" placeholder="Search">
<ul></ul>
</div>
<div class="lnb-api hidden"><h3>Classes</h3><ul><li><a href="LunrSearch.html">LunrSearch</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="LunrSearch_sub"><div class="member-type">Members</div><ul class="inner"><li><a href="LunrSearch.html#.VERSION">VERSION</a></li><li><a href="LunrSearch.html#builder">builder</a></li><li><a href="LunrSearch.html#docs">docs</a></li><li><a href="LunrSearch.html#domain">domain</a></li><li><a href="LunrSearch.html#editDistance">editDistance</a></li><li><a href="LunrSearch.html#index">index</a></li><li><a href="LunrSearch.html#pass">pass</a></li><li><a href="LunrSearch.html#plugins">plugins</a></li><li><a href="LunrSearch.html#user">user</a></li></ul><div class="member-type">Methods</div><ul class="inner"><li><a href="LunrSearch.html#.buildIndex">buildIndex</a></li><li><a href="LunrSearch.html#.exportIndex">exportIndex</a></li><li><a href="LunrSearch.html#.fetch">fetch</a></li><li><a href="LunrSearch.html#.getIndex">getIndex</a></li><li><a href="LunrSearch.html#.importIndex">importIndex</a></li><li><a href="LunrSearch.html#.isSupported">isSupported</a></li><li><a href="LunrSearch.html#.postIndex">postIndex</a></li><li><a href="LunrSearch.html#.search">search</a></li><li><a href="LunrSearch.html#buildIndex">buildIndex</a></li><li><a href="LunrSearch.html#exportIndex">exportIndex</a></li><li><a href="LunrSearch.html#fetch">fetch</a></li><li><a href="LunrSearch.html#getIndex">getIndex</a></li><li><a href="LunrSearch.html#importIndex">importIndex</a></li><li><a href="LunrSearch.html#postIndex">postIndex</a></li><li><a href="LunrSearch.html#search">search</a></li></ul><div class="member-type">Typedef</div><ul class="inner"><li><a href="LunrSearch.html#.Plugin">Plugin</a></li><li><a href="LunrSearch.html#.Result">Result</a></li></ul></div></li></ul></div><div class="lnb-api hidden"><h3>Namespaces</h3><ul><li><a href="plugin.html">plugin</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="plugin_sub"></div></li><li><a href="plugin.freshdesk.html">plugin.freshdesk</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="plugin.freshdesk_sub"><div class="member-type">Methods</div><ul class="inner"><li><a href="plugin.freshdesk.html#.fetch">fetch</a></li><li><a href="plugin.freshdesk.html#.isSupported">isSupported</a></li><li><a href="plugin.freshdesk.html#.plugin">plugin</a></li><li><a href="plugin.freshdesk.html#.process">process</a></li></ul></div></li><li><a href="util.html">util</a><button type="button" class="hidden toggle-subnav btn btn-link"> <span class="glyphicon glyphicon-plus"></span></button><div class="hidden" id="util_sub"><div class="member-type">Methods</div><ul class="inner"><li><a href="util.html#.definedFunction">definedFunction</a></li></ul></div></li></ul></div>
</nav>
<div id="resizer"></div>
<div class="main" id="main">
<section>
<article>
<pre class="prettyprint source linenums"><code>import * as util from '../util'
import _axios from 'axios'
import flatten from 'array-flatten'
const fields = ['title', 'description_text', 'body_text', 'tags', 'meta_title', 'meta_description', 'meta_keywords'] // the fields that will be indexed
/**
* The lunr.js builder plugin.
* Meant to be used like `builder.use(plugin)`
*
* @memberof plugin.freshdesk
* @return {void}
*/
function plugin () {
this.ref('id')
fields.forEach(f => this.field(f))
}
/**
* Fetches all the solution articles and forum posts from the designated source.
*
* @memberof plugin.freshdesk
* @param {string} domain the domain of the API to make the request to
* @param {string} user the username for the API
* @param {string} pass the password for the API
* @return {object[]} a list of processed solution articles, forum topics, and forum comments
*/
async function fetch (
domain,
user,
pass
) {
const solutions = _axios.create({
baseURL: `https://${domain}.freshdesk.com/api/v2/solutions/`,
auth: {
username: user,
password: pass
}
})
// gets a list of all the articles
const categories = await get(solutions, 'categories')
const folders = await getAllItemsIn(categories, solutions, id => `categories/${id}/folders`)
const articles = await getAllItemsIn(folders, solutions, id => `folders/${id}/articles`)
const processedArticles = await getAllItemsIn(articles, solutions, id => `articles/${id}`).then(arts => arts.map(a => process(a, 'solution'))) // process each article after fetching it
const posts = _axios.create({
baseURL: `https://${domain}.freshdesk.com/api/v2/discussions/`,
auth: {
username: user,
password: pass
}
})
// gets a list of all the articles
const discussionCategories = await get(posts, 'categories')
const forums = await getAllItemsIn(discussionCategories, posts, id => `categories/${id}/forums`).then(ary => ary.filter(t => hasComments(t)))
const topics = await getAllItemsIn(forums, posts, id => `forums/${id}/topics`).then(ary => ary.filter(t => hasComments(t)))
const comments = await getAllItemsIn(topics, posts, id => `topics/${id}/comments`).then(cmts => cmts.map(comment => process(comment, 'forum')))
return [...comments, ...processedArticles, ...topics.map(e => process(e, 'forum'))]
}
function hasComments (topic) {
return topic.comments_count > 0
}
/**
* Helper function to get all the items from a list of parent resources.
*
* @private
* @param {object[]} ary list of parent resources
* @param {axios.Instance} axios the preconfigured axios instance
* @param {Function} buildURL function to build the endpoint URL relative to the baseURL in the axios instance
* @return {object[]} a list of child resources
*/
async function getAllItemsIn (ary, axios, buildURL) {
return flatten.depth(await Promise.all(ary.map(({id}) => get(axios, buildURL(id)))), 1)
}
/**
* Helper function to make axios get request.
*
* @private
* @param {axios.Instance} axios the preconfigured axios instance
* @param {string} url the url to access relative to the baseURL in the axios instance
* @return {object} data of axios response
*/
async function get (axios, url) {
return axios.get(url).then(({data}) => {
let ret
const baseURL = axios.defaults.baseURL
if (data.constructor.name === 'Array') {
ret = data.map(doc => { return {...doc, documentSource: {url: baseURL + url}} })
} else if (data.constructor.name === 'Object') {
ret = {...data, documentSource: {url: baseURL + url}}
}
return ret
})
}
/**
* Modify the documents so that they can be indexed correctly.
*
* @memberof plugin.freshdesk
* @param {object} doc the document to be processed
* @param {?string} source the source of the document
* @return {object} the processed document
*/
function process (doc, source = '') {
const obj = {...doc} // dup the document
obj.tags = obj.tags ? obj.tags.join(' ') : '' // lunr can't index an array of strings so join the tags into 1 string
if (obj.seo_data) Object.keys(obj.seo_data).forEach(k => { obj[k] = obj.seo_data[k] }) // map seo_data to root field so that it can indexed (lunr can't index nested fields)
if (obj.documentSource) obj.documentSource = {...obj.documentSource, type: source}
fields.forEach(f => { obj[f] = obj[f] || '' }) // if any fields are null then it will impact lunr search results
return obj
}
/**
* Checks to see if certain functions are defined.
*
* @return {Boolean}
* @memberOf plugin.freshdesk
*/
function isSupported () {
return util.definedFunction(Object.keys) && util.definedFunction([].forEach)
}
/**
* Contains functions for interacting with the freshdesk API and processing those responses.
*
* @namespace freshdesk
* @memberOf plugin
*/
export {fields, plugin, process, fetch, isSupported}
</code></pre>
</article>
</section>
</div>
<footer>
<img class="logo" src="img/toast-ui.png" style="">
<div class="footer-text">made this awesome JSDoc theme!</div>
</footer>
<script>prettyPrint();</script>
<script src="scripts/jquery.min.js"></script>
<script src="scripts/tui-doc.js"></script>
<script src="scripts/linenumber.js"></script>
<script>
var id = '_sub'.replace(/"/g, '_');
var selectedApi = document.getElementById(id); // do not use jquery selector
var $selectedApi = $(selectedApi);
$selectedApi.removeClass('hidden');
$selectedApi.parent().find('.glyphicon').removeClass('glyphicon-plus').addClass('glyphicon-minus');
showLnbApi();
</script>
</body>
</html>