unpkg/server/createSearchServer.js

88 lines
2.1 KiB
JavaScript

const express = require('express')
const getAssetPaths = require('./npm/getAssetPaths')
const npmSearchIndex = require('./npm/searchIndex')
function enhanceHit(hit) {
return new Promise(function (resolve, reject) {
const assetPaths = getAssetPaths(hit.name, hit.version)
if (assetPaths) {
// TODO: Double check the package metadata to ensure the files
// haven't moved from the paths in the index?
hit.assets = assetPaths.map(function (path) {
return `https://unpkg.com/${hit.name}@${hit.version}${path}`
})
resolve(hit)
} else {
resolve(hit)
}
})
}
function byRelevanceDescending(a, b) {
// Hits that have assets are more relevant.
return a.assets ? (b.assets ? 0 : -1) : (b.assets ? 1 : 0)
}
function createSearchServer() {
const app = express()
app.get('/', function (req, res) {
const { query, page = 0 } = req.query
const hitsPerPage = 20
if (!query)
return res.status(403).send({ error: 'Missing ?query parameter' })
const params = {
typoTolerance: 'min',
attributesToRetrieve: [
'name',
'version',
'description',
'owner'
],
attributesToHighlight: null,
restrictSearchableAttributes: [
'name',
'description'
],
hitsPerPage,
page
}
npmSearchIndex.search(query, params, function (error, value) {
if (error) {
console.error(error)
res.status(500).send({ error: 'There was an error executing the search' })
} else {
Promise.all(
value.hits.map(enhanceHit)
).then(function (hits) {
hits.sort(byRelevanceDescending)
const totalHits = value.nbHits
const totalPages = value.nbPages
res.send({
query,
page,
hitsPerPage,
totalHits,
totalPages,
hits
})
}, function (error) {
console.error(error)
res.status(500).send({ error: 'There was an error executing the search' })
})
}
})
})
return app
}
module.exports = createSearchServer