diff --git a/src/lib/DocsSearchBar.js b/src/lib/DocsSearchBar.js index 9d22c853..bfa6caec 100644 --- a/src/lib/DocsSearchBar.js +++ b/src/lib/DocsSearchBar.js @@ -3,6 +3,7 @@ import templates from './templates' import utils from './utils' import $ from './zepto' import { MeiliSearch } from 'meilisearch' +import { constructClientAgents } from './agents' /** * Adds an autocomplete dropdown to an input field @@ -56,6 +57,7 @@ class DocsSearchBar { enhancedSearchInput = false, layout = 'columns', enableDarkMode = false, + clientAgents = [], }) { DocsSearchBar.checkArguments({ hostUrl, @@ -72,6 +74,7 @@ class DocsSearchBar { enhancedSearchInput, layout, enableDarkMode, + clientAgents, }) this.apiKey = apiKey @@ -115,6 +118,7 @@ class DocsSearchBar { this.client = new MeiliSearch({ host: hostUrl, apiKey: this.apiKey, + clientAgents: constructClientAgents(clientAgents), }) DocsSearchBar.addThemeWrapper(inputSelector, this.enableDarkMode) @@ -255,6 +259,8 @@ class DocsSearchBar { false, ) + DocsSearchBar.typeCheck(args, ['clientAgents'], 'array', true) + DocsSearchBar.typeCheck( args, ['queryDataCallback', 'transformData', 'queryHook', 'handleSelected'], @@ -268,6 +274,20 @@ class DocsSearchBar { ) } } + /** + * Throw a type error. + * + * @param {string} argument - Name of the parameter + * @param {string} type - Type the parameter should have + * @param {string} value - Value the parameter has + * + * @returns {void} + */ + static throwTypeError(argument, type, value) { + throw new Error( + `Error: "${argument}" must be of type: ${type}. Found type: ${typeof value}`, + ) + } /** * Checks if the arguments defined in the check variable are of the supplied @@ -283,10 +303,12 @@ class DocsSearchBar { .filter((argument) => !optional || args[argument]) .forEach((argument) => { const value = args[argument] - if (typeof args[argument] !== type) { - throw new Error( - `Error: "${argument}" must be of type: ${type}. Found type: ${typeof value}`, - ) + if (type === 'array') { + if (!Array.isArray(args[argument])) { + DocsSearchBar.throwTypeError(argument, type, value) + } + } else if (typeof args[argument] !== type) { + DocsSearchBar.throwTypeError(argument, type, value) } }) } diff --git a/src/lib/__tests__/DocsSearchBar-test.js b/src/lib/__tests__/DocsSearchBar-test.js index 8e153c09..95ffc831 100644 --- a/src/lib/__tests__/DocsSearchBar-test.js +++ b/src/lib/__tests__/DocsSearchBar-test.js @@ -3,6 +3,7 @@ import sinon from 'sinon' import $ from '../zepto' import DocsSearchBar from '../DocsSearchBar' +import PACKAGE_VERSION from '../version' /** * Pitfalls: * Whenever you call new DocsSearchBar(), it will add the a new dropdown markup to @@ -183,6 +184,7 @@ describe('DocsSearchBar', () => { MeiliSearch.calledWith({ host: 'https://test.getmeili.com', apiKey: 'apiKey', + clientAgents: [`Meilisearch docs-searchbar.js (v${PACKAGE_VERSION})`], }), ).toBe(true) }) @@ -226,6 +228,27 @@ describe('DocsSearchBar', () => { expect(autocomplete.on.calledTwice).toBe(true) expect(autocomplete.on.calledWith('autocomplete:selected')).toBe(true) }) + + it('should have spread the user agents', () => { + // Given + const options = { ...defaultOptions, clientAgents: ['test'] } + + // When + new DocsSearchBar(options) + + // Then + expect(MeiliSearch.calledOnce).toBe(true) + expect( + MeiliSearch.calledWith({ + host: 'https://test.getmeili.com', + apiKey: 'apiKey', + clientAgents: [ + 'test', + `Meilisearch docs-searchbar.js (v${PACKAGE_VERSION})`, + ], + }), + ).toBe(true) + }) }) describe('checkArguments', () => { @@ -377,6 +400,15 @@ describe('DocsSearchBar', () => { // Given const options = { ...defaultOptions, handleSelected: 'not-a-function' } + // When + expect(() => { + checkArguments(options) + }).toThrow(/^Error:/) + }) + it('should throw an error if clientAgents is not an array', () => { + // Given + const options = { ...defaultOptions, clientAgents: 'test' } + // When expect(() => { checkArguments(options) diff --git a/src/lib/agents.js b/src/lib/agents.js new file mode 100644 index 00000000..659d0c50 --- /dev/null +++ b/src/lib/agents.js @@ -0,0 +1,7 @@ +import version from './version' + +export const constructClientAgents = (clientAgents = []) => { + const instantMeilisearchAgent = `Meilisearch docs-searchbar.js (v${version})` + + return clientAgents.concat(instantMeilisearchAgent) +}