Skip to content

Commit

Permalink
Merge pull request #20 from sw-yx/improve-search
Browse files Browse the repository at this point in the history
  • Loading branch information
swyxio authored May 31, 2020
2 parents 6d179a7 + f44f17d commit c203438
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 17 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,11 +116,13 @@ You can use this plugin in two ways:
// app.js
document.getElementById('myForm').addEventListener('submit', async event => {
event.preventDefault()
const result = await fetch(`/.netlify/functions/searchIndex?search=${event.target.searchText.value}`).then(x => x.json())
const result = await fetch(`/.netlify/functions/searchIndex?search=${event.target.searchText.value}&limit=25`).then(x => x.json())
document.getElementById('result').innerText = JSON.stringify(result, null, 2)
})
```

You can use an optional `limit` parameter to limit the length of returned results.

Under the hood, the search function uses [fuse.js](https://fusejs.io/) and in future we may expose more configurations for this.


Expand Down
4 changes: 4 additions & 0 deletions fixtures/manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name: 'articles-generator'

inputs:
- name: folder
42 changes: 32 additions & 10 deletions fixtures/this.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@
* @jest-environment node
*/

const { indexKeys: expectedKeys } = require('../parser')

let index
let searchHandler
let referenceLen = 0
const netlifyPlugin = require('../index.js');
test('plugin fixture works', () => {
const initPlugin = netlifyPlugin;
console.log(`running ${initPlugin.name}`);
console.log(`running build plugin`);
return initPlugin
.onPostBuild({
// from netlify.yml
inputs: {
debugMode: false,
exclude: ['/search.html', /^\/devnull\/.*/],
generatedFunctionName: 'mySearchFunction',
publishDirJSONFileName: 'mySearchIndex'
generatedFunctionName: 'search',
publishDirJSONFileName: 'searchIndex'
},
constants: {
PUBLISH_DIR: 'fixtures/publishDir',
Expand All @@ -26,7 +26,7 @@ test('plugin fixture works', () => {
utils: { build: { failBuild() {} } },
})
.then(() => {
index = require('./publishDir/mySearchIndex.json')
index = require('./publishDir/searchIndex.json')
expect(Object.keys(index)).not.toBe(0)
});
});
Expand All @@ -36,8 +36,30 @@ test('files in ignored list are not searchable', () => {
expect(Object.keys(index).find(e => e.indexOf('/devnull/') === 0)).toBe(undefined)
})

test('search items have expected keys', () => {
expectedKeys.forEach((expectedKey) => {
expect(Object.entries(index).find(([_, e]) => !e[expectedKey])).toBe(undefined)
})
test('empty search index returns 400', async () => {
searchHandler = require('./functions/search/search').handler
const { statusCode } = await searchHandler({ queryStringParameters: { search: '' } })
expect(statusCode).toBe(400)
});

test('non-empty search index returns results', async () => {
const { statusCode, body } = await searchHandler({ queryStringParameters: { search: 'developers' } })
expect(statusCode).toBe(200)
const results = JSON.parse(body)
expect(results.length).toBeGreaterThanOrEqual(1)
referenceLen = results.length
});

test('limit qury param should limit results len', async () => {
const { statusCode, body } = await searchHandler({ queryStringParameters: { search: 'developers', limit: '2' } })
expect(statusCode).toBe(200)
const results = JSON.parse(body)
expect(results.length).toBe(2)
});

test('NaN should not break search', async () => {
const { statusCode, body } = await searchHandler({ queryStringParameters: { search: 'developers', limit: 'nan' } })
expect(statusCode).toBe(200)
const results = JSON.parse(body)
expect(results.length).toBeGreaterThanOrEqual(referenceLen)
});
26 changes: 20 additions & 6 deletions functionTemplate/{{searchIndex}}.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ searchIndex = Object.entries(searchIndex).map(([k, v]) => {
});
var options = {
shouldSort: true,
threshold: 0.6,
threshold: 0.5,
location: 0,
distance: 100,
maxPatternLength: 32,
Expand All @@ -28,18 +28,32 @@ var options = {
var fuse = new Fuse(searchIndex, options);

exports.handler = async (event) => {
const searchTerm =
event.queryStringParameters.search || event.queryStringParameters.s;
const {
s,
search,
limit
} = event.queryStringParameters

const searchTerm = search || s
if (typeof searchTerm === 'undefined') {
return {
statusCode: 400,
body:
'no search term specified, query this function with /?search=searchTerm or /?s=searchTerm'
};
}
}
var result = fuse.search(searchTerm);
let parsedInt
if (limit) {
maybeInt = parseInt(limit)
if (maybeInt !== NaN) {
parsedInt = maybeInt
}
}

const result = fuse.search(searchTerm);

return {
statusCode: 200,
body: JSON.stringify(result)
body: JSON.stringify(parsedInt ? result.slice(0, parsedInt) : result)
};
};
2 changes: 2 additions & 0 deletions netlify.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
publish = "fixtures/publishDir"
functions = "fixtures/functions"

[[plugins]]
package = "@netlify/plugin-local-install-core"
[[plugins]]
package = "./fixtures/generator"
[[plugins]]
Expand Down

0 comments on commit c203438

Please sign in to comment.