55 lines
1.6 KiB
JavaScript
55 lines
1.6 KiB
JavaScript
const { send, json } = require('micro')
|
|
const urlite = require('urlite/extra')
|
|
const Database = require('better-sqlite3')
|
|
const pagination = require('pagination-utility').PaginationUtility
|
|
|
|
const page = require('../page')
|
|
const ds = require('../index')
|
|
const db = ds.db()
|
|
|
|
const PER_PAGE = 100
|
|
|
|
/**
|
|
* Wrap search queries that might crash FTS5 with double quotes.
|
|
* @param {String} q - search query
|
|
* @returns {String} a search query that probably won't crash SQLite's FTS5
|
|
*/
|
|
function safeQuery(q) {
|
|
let q2 = q.trim()
|
|
if (q2.match(/[-./']/)) {
|
|
q2 = `"${q2}"`
|
|
}
|
|
if (q2.match(/\+/)) {
|
|
q2 = q2.replace(/\+/g, ' ')
|
|
}
|
|
return q2
|
|
}
|
|
|
|
module.exports.GET = async (req, res) => {
|
|
const url = urlite.parse(req.url)
|
|
const q = unescape(url.search.q)
|
|
const p = url.search.p ? parseInt(url.search.p) : 1
|
|
if (q) {
|
|
if (typeof q == 'boolean') {
|
|
res.setHeader('Location', '/')
|
|
return send(res, 302)
|
|
}
|
|
|
|
// Search, if we have a query.
|
|
const path = `/search?q=${encodeURIComponent(url.search.q)}&`
|
|
const {limit, offset} = pagination.getValuesToPaginate({ currentPage: p, perPage: PER_PAGE })
|
|
const q2 = safeQuery(q)
|
|
const results = await ds.search(db, q2, limit, offset)
|
|
const count = await ds.searchCount(db, q2)
|
|
const totalPages = pagination.getTotalPages({ totalItems: count, perPage: PER_PAGE })
|
|
const out = await page.render('search', { path, q, p, results, count, totalPages })
|
|
return send(res, 200, out)
|
|
//return send(res, 200, { results, count })
|
|
|
|
} else {
|
|
res.setHeader('Location', '/')
|
|
return send(res, 302)
|
|
}
|
|
}
|
|
|