diff --git a/README.md b/README.md index 06b92365..ccfe2917 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ This package only guarantees the compatibility with the [version v4 of InstantSe **Supported MeiliSearch versions**: -This package only guarantees the compatibility with the [version v0.23.0 of MeiliSearch](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.23.0). +This package only guarantees the compatibility with the [version v0.24.0 of MeiliSearch](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.24.0). **Node / NPM versions**: diff --git a/package.json b/package.json index 67d94918..dc4dc98a 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "url": "https://github.com/meilisearch/instant-meilisearch.git" }, "dependencies": { - "meilisearch": "^0.22.3" + "meilisearch": "^0.23.0" }, "devDependencies": { "@babel/cli": "^7.16.0", diff --git a/playgrounds/angular/src/app/app.component.html b/playgrounds/angular/src/app/app.component.html index 4f62caa7..0076725c 100644 --- a/playgrounds/angular/src/app/app.component.html +++ b/playgrounds/angular/src/app/app.component.html @@ -10,8 +10,7 @@

MeiliSearch + Angular InstantSearch

- MeiliSearch + Angular InstantSearch value: 'steam-video-games:recommendationCount:asc', label: 'Least Recommended' } - ]" - > - + ]"> + +

Genres

- +

Players

- +

Platforms

- +

Misc

- +
@@ -51,7 +51,8 @@

Misc

- + +
price: ${{hit.price}}
Release date: {{hit.releaseDate}}
diff --git a/src/adapter/search-response-adapter/format-adapter/format-adapter.ts b/src/adapter/search-response-adapter/format-adapter/format-adapter.ts new file mode 100644 index 00000000..70aefe88 --- /dev/null +++ b/src/adapter/search-response-adapter/format-adapter/format-adapter.ts @@ -0,0 +1,37 @@ +import { adaptHighlight } from './highlight-adapter' +import { adaptSnippet } from './snippet-adapter' +import { SearchContext } from '../../../types' + +/** + * Adapt MeiliSearch formating to formating compliant with instantsearch.js. + * + * @param {Record, + searchContext: SearchContext +): Record { + const attributesToSnippet = searchContext?.attributesToSnippet + const ellipsis = searchContext?.snippetEllipsisText + const preTag = searchContext?.highlightPreTag + const postTag = searchContext?.highlightPostTag + + if (!hit._formatted) return {} + const _highlightResult = adaptHighlight(hit, preTag, postTag) + + // what is ellipsis by default + const _snippetResult = adaptHighlight( + adaptSnippet(hit, attributesToSnippet, ellipsis), + preTag, + postTag + ) + + const highlightedHit = { + _highlightResult, + _snippetResult, + } + + return highlightedHit +} diff --git a/src/adapter/search-response-adapter/format-adapter/highlight-adapter.ts b/src/adapter/search-response-adapter/format-adapter/highlight-adapter.ts new file mode 100644 index 00000000..10b1b3f1 --- /dev/null +++ b/src/adapter/search-response-adapter/format-adapter/highlight-adapter.ts @@ -0,0 +1,76 @@ +import { isString } from '../../../utils' +/** + * Replace `em` tags in highlighted MeiliSearch hits to + * provided tags by instantsearch.js. + * + * @param {string} value + * @param {string} highlightPreTag? + * @param {string} highlightPostTag? + * @returns {string} + */ +function replaceDefaultEMTag( + value: any, + preTag = '__ais-highlight__', + postTag = '__/ais-highlight__' +): string { + // Highlight is applied by MeiliSearch ( tags) + // We replace the by the expected tag for InstantSearch + const stringifiedValue = isString(value) ? value : JSON.stringify(value) + + return stringifiedValue.replace(//g, preTag).replace(/<\/em>/g, postTag) +} + +function addHighlightTags( + value: any, + preTag?: string, + postTag?: string +): string { + if (typeof value === 'string') { + // String + return replaceDefaultEMTag(value, preTag, postTag) + } else if (value === undefined) { + // undefined + return JSON.stringify(null) + } else { + // Other + return JSON.stringify(value) + } +} + +export function resolveHighlightValue( + value: any, + preTag?: string, + postTag?: string +): { value: string } | Array<{ value: string }> { + if (Array.isArray(value)) { + // Array + return value.map((elem) => ({ + value: addHighlightTags(elem, preTag, postTag), + })) + } else { + return { value: addHighlightTags(value, preTag, postTag) } + } +} + +/** + * @param {Record, + preTag?: string, + postTag?: string +): Record { + // hit is the `_formatted` object returned by MeiliSearch. + // It contains all the highlighted and croped attributes + + if (!hit._formatted) return hit._formatted + return Object.keys(hit._formatted).reduce((result, key) => { + const value = hit._formatted[key] + + result[key] = resolveHighlightValue(value, preTag, postTag) + return result + }, {} as any) +} diff --git a/src/adapter/search-response-adapter/format-adapter/index.ts b/src/adapter/search-response-adapter/format-adapter/index.ts new file mode 100644 index 00000000..9b22120c --- /dev/null +++ b/src/adapter/search-response-adapter/format-adapter/index.ts @@ -0,0 +1 @@ +export * from './format-adapter' diff --git a/src/adapter/search-response-adapter/format-adapter/snippet-adapter.ts b/src/adapter/search-response-adapter/format-adapter/snippet-adapter.ts new file mode 100644 index 00000000..79c81ea3 --- /dev/null +++ b/src/adapter/search-response-adapter/format-adapter/snippet-adapter.ts @@ -0,0 +1,95 @@ +import { isString } from '../../../utils' + +function nakedOfTags(str: string) { + return str.replace(//g, '').replace(/<\/em>/g, '') +} + +function addEllipsis(value: any, formatValue: string, ellipsis: string): any { + // Manage ellpsis on cropped values until this feature is implemented https://roadmap.meilisearch.com/c/69-policy-for-cropped-values?utm_medium=social&utm_source=portal_share in MeiliSearch + + let ellipsedValue = formatValue + + if ( + isString(formatValue) && + value.toString().length > nakedOfTags(formatValue).length + ) { + if ( + formatValue[0] === formatValue[0].toLowerCase() && // beginning of a sentence + formatValue.startsWith('') === false // beginning of the document field, otherwise MeiliSearch would crop around the highlight + ) { + ellipsedValue = `${ellipsis}${formatValue.trim()}` + } + if (!!formatValue.match(/[.!?]$/) === false) { + // end of the sentence + ellipsedValue = `${formatValue.trim()}${ellipsis}` + } + } + return ellipsedValue +} + +/** + * @param {string} value + * @param {string} ellipsis? + * @returns {string} + */ +function resolveSnippet(value: any, formatValue: any, ellipsis?: string): any { + if (!ellipsis || !(typeof formatValue === 'string')) { + return formatValue + } else if (Array.isArray(value)) { + // Array + return value.map((elem) => addEllipsis(elem, formatValue, ellipsis)) + } + return addEllipsis(value, formatValue, ellipsis) +} + +/** + * @param {Record, + attributes: readonly string[] | undefined, + ellipsis: string | undefined +): Record { + // hit is the `_formatted` object returned by MeiliSearch. + // It contains all the highlighted and croped attributes + + const formattedHit = hit._formatted + const newHit = hit._formatted + + if (attributes === undefined) { + return hit + } + + // All attributes that should be snippeted and their snippet size + const snippets = attributes.map( + (attribute) => attribute.split(':')[0] + ) as any[] + + // Find presence of a wildcard * + const wildCard = snippets.includes('*') + + if (wildCard) { + // In case of * + for (const attribute in formattedHit) { + newHit[attribute] = resolveSnippet( + hit[attribute], + formattedHit[attribute], + ellipsis + ) + } + } else { + // Itterate on all attributes that needs snippeting + for (const attribute of snippets) { + newHit[attribute] = resolveSnippet( + hit[attribute], + formattedHit[attribute], + ellipsis + ) + } + } + hit._formatted = newHit + + return hit +} diff --git a/src/adapter/search-response-adapter/highlight-adapter.ts b/src/adapter/search-response-adapter/highlight-adapter.ts deleted file mode 100644 index 336995f5..00000000 --- a/src/adapter/search-response-adapter/highlight-adapter.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { isString } from '../../utils' -import { SearchContext } from '../../types' - -/** - * Replace `em` tags in highlighted MeiliSearch hits to - * provided tags by instantsearch.js. - * - * @param {string} value - * @param {string} highlightPreTag? - * @param {string} highlightPostTag? - * @returns {string} - */ -function replaceHighlightTags( - value: any, - preTag?: string, - postTag?: string -): string { - preTag = preTag || '__ais-highlight__' - postTag = postTag || '__/ais-highlight__' - // Highlight is applied by MeiliSearch ( tags) - // We replace the by the expected tag for InstantSearch - const stringifiedValue = isString(value) ? value : JSON.stringify(value) - - return stringifiedValue.replace(//g, preTag).replace(/<\/em>/g, postTag) -} - -function addHighlightTags(value: string, preTag?: string, postTag?: string) { - return { - value: replaceHighlightTags(value, preTag, postTag), - } -} - -function resolveHighlightValue( - value: string, - preTag?: string, - postTag?: string -) { - if (typeof value === 'string') { - // String - return addHighlightTags(value, preTag, postTag) - } else if (value === undefined) { - // undefined - return { value: JSON.stringify(null) } - } else { - // Other - return { value: JSON.stringify(value) } - } -} - -/** - * @param {Record, - preTag?: string, - postTag?: string -): Record { - // hit is the `_formatted` object returned by MeiliSearch. - // It contains all the highlighted and croped attributes - - return Object.keys(hit).reduce((result, key) => { - const value = hit[key] - - if (Array.isArray(value)) { - // Array - result[key] = value.map((elem) => - resolveHighlightValue(elem, preTag, postTag) - ) - } else { - result[key] = resolveHighlightValue(value, preTag, postTag) - } - return result - }, {} as any) -} - -/** - * @param {string} value - * @param {string} preTag? - * @param {string} postTag? - * @param {string} ellipsis? - * @returns {string} - */ -function resolveSnippetValue( - value: string, - preTag?: string, - postTag?: string, - ellipsis?: string -): { value: string } { - let newValue = value - - // Manage ellpsis on cropped values until this feature is implemented https://roadmap.meilisearch.com/c/69-policy-for-cropped-values?utm_medium=social&utm_source=portal_share in MeiliSearch - if (newValue && ellipsis !== undefined && isString(newValue)) { - if ( - newValue[0] === newValue[0].toLowerCase() && // beginning of a sentence - newValue.startsWith('') === false // beginning of the document field, otherwise MeiliSearch would crop around the highlight - ) { - newValue = `${ellipsis}${newValue}` - } - if (!!newValue.match(/[.!?]$/) === false) { - // end of the sentence - newValue = `${newValue}${ellipsis}` - } - } - return resolveHighlightValue(newValue, preTag, postTag) -} - -/** - * @param {Record, - attributes: readonly string[] | undefined, - ellipsis: string | undefined, - pretag: string | undefined, - postTag: string | undefined -) { - if (attributes === undefined) { - return null - } - attributes = attributes.map((attribute) => attribute.split(':')[0]) as any[] - const snippetAll = attributes.includes('*') - - // hit is the `_formatted` object returned by MeiliSearch. - // It contains all the highlighted and croped attributes - - return (Object.keys(hit) as any[]).reduce((result, key) => { - if (snippetAll || attributes?.includes(key)) { - const value = hit[key] - if (Array.isArray(value)) { - // Array - result[key] = value.map((elem) => - resolveSnippetValue(elem, pretag, postTag, ellipsis) - ) - } else { - result[key] = resolveSnippetValue(value, pretag, postTag, ellipsis) - } - } - return result - }, {} as any) -} - -/** - * Adapt MeiliSearch formating to formating compliant with instantsearch.js. - * - * @param {Record, - searchContext: SearchContext -): Record { - const attributesToSnippet = searchContext?.attributesToSnippet - const ellipsis = searchContext?.snippetEllipsisText - const preTag = searchContext?.highlightPreTag - const postTag = searchContext?.highlightPostTag - - if (!hit || hit.length) return {} - const highlightedHit = { - _highlightResult: adaptHighlight(hit, preTag, postTag), - _snippetResult: adaptSnippet( - hit, - attributesToSnippet, - ellipsis, - preTag, - postTag - ), - } - return highlightedHit -} diff --git a/src/adapter/search-response-adapter/hits-adapter.ts b/src/adapter/search-response-adapter/hits-adapter.ts index 20a3871c..2c0b88a1 100644 --- a/src/adapter/search-response-adapter/hits-adapter.ts +++ b/src/adapter/search-response-adapter/hits-adapter.ts @@ -1,6 +1,6 @@ import type { PaginationContext, SearchContext } from '../../types' import { adaptPagination } from './pagination-adapter' -import { adaptFormating } from './highlight-adapter' +import { adaptFormating } from './format-adapter' import { adaptGeoResponse } from './geo-reponse-adapter' /** @@ -22,9 +22,10 @@ export function adaptHits( // Creates Hit object compliant with InstantSearch if (Object.keys(hit).length > 0) { const { _formatted: formattedHit, _matchesInfo, ...restOfHit } = hit + return { ...restOfHit, - ...adaptFormating(formattedHit, searchContext), + ...adaptFormating(hit, searchContext), ...(primaryKey && { objectID: hit[primaryKey] }), } } diff --git a/tests/assets/utils.ts b/tests/assets/utils.ts index ffb8727c..a1247ea9 100644 --- a/tests/assets/utils.ts +++ b/tests/assets/utils.ts @@ -204,6 +204,7 @@ export type Movies = { id?: number title?: string overview?: string + poster?: string genres?: string[] release_date?: number // eslint-disable-line undefinedArray?: [undefined, undefined, undefined] diff --git a/tests/highlight.tests.ts b/tests/highlight.tests.ts index 76ab07d6..5c2aae86 100644 --- a/tests/highlight.tests.ts +++ b/tests/highlight.tests.ts @@ -272,7 +272,7 @@ describe('Highlight Browser test', () => { if (hit?.object) { // @ts-ignore - expect(hit?.object?.value).toEqual('{"id":1,"name":"Nader"}') + expect(hit?.object?.value).toEqual('{"id":"1","name":"Nader"}') } if (hit?.nullField) { diff --git a/tests/snippets.tests.ts b/tests/snippets.tests.ts index 26a8d802..9a3ef7df 100644 --- a/tests/snippets.tests.ts +++ b/tests/snippets.tests.ts @@ -25,11 +25,12 @@ describe('Snippet Browser test', () => { params: { query: '', attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', }, }, ]) - const snippeted = response.results[0]?.hits[0]?._highlightResult - expect(snippeted?.overview?.value).toEqual('Princess') + const snippeted = response.results[0]?.hits[0]?._snippetResult + expect(snippeted).toHaveProperty('overview', { value: 'Princess...' }) }) test('Test one attributesToSnippet on specific query', async () => { @@ -45,8 +46,13 @@ describe('Snippet Browser test', () => { ]) const highlighted = response.results[0]?.hits[0]?._highlightResult const snippeted = response.results[0].hits[0]._snippetResult - expect(highlighted?.overview?.value).toEqual('While') - expect(snippeted?.overview?.value).toEqual('While...') + + expect(highlighted).toHaveProperty('overview', { + value: 'While', + }) + expect(snippeted).toHaveProperty('overview', { + value: 'While...', + }) }) test('Test * attributesToSnippet on specific query', async () => { @@ -62,33 +68,48 @@ describe('Snippet Browser test', () => { ]) const highlighted = response.results[0]?.hits[0]?._highlightResult const snippeted = response.results[0].hits[0]._snippetResult - expect(highlighted?.id?.value).toEqual('6') - expect(highlighted?.title?.value).toEqual( - '__ais-highlight__Judg__/ais-highlight__ment Night' - ) - expect(highlighted?.overview?.value).toEqual('While') + + expect(highlighted).toHaveProperty('id', { + value: '6', + }) + expect(snippeted).toHaveProperty('id', { + value: '6', + }) + expect(highlighted).toHaveProperty('title', { + value: '__ais-highlight__Judg__/ais-highlight__ment Night', + }) + expect(snippeted).toHaveProperty('title', { + value: '__ais-highlight__Judg__/ais-highlight__ment Night', + }) + expect(highlighted).toHaveProperty('overview', { + value: 'While', + }) + expect(snippeted).toHaveProperty('overview', { + value: 'While...', + }) + expect(highlighted).toHaveProperty('release_date', { + value: '750643200', + }) + expect(snippeted).toHaveProperty('release_date', { + value: '750643200', + }) + expect(highlighted?.genres).toBeTruthy() if (highlighted?.genres) { expect(highlighted?.genres[0].value).toEqual('Action') expect(highlighted?.genres[1].value).toEqual('Thriller') expect(highlighted?.genres[2].value).toEqual('Crime') } - expect(highlighted?.release_date?.value).toEqual('750643200') - expect(snippeted?.id?.value).toEqual('6') - expect(snippeted?.title?.value).toEqual( - '__ais-highlight__Judg__/ais-highlight__ment Night...' - ) - expect(snippeted?.overview?.value).toEqual('While...') + expect(snippeted?.genres).toBeTruthy() if (snippeted?.genres) { - expect(snippeted?.genres[0].value).toEqual('Action...') - expect(snippeted?.genres[1].value).toEqual('Thriller...') - expect(snippeted?.genres[2].value).toEqual('Crime...') + expect(snippeted?.genres[0].value).toEqual('Action') + expect(snippeted?.genres[1].value).toEqual('Thriller') + expect(snippeted?.genres[2].value).toEqual('Crime') } - expect(snippeted?.release_date?.value).toEqual('750643200') }) - test('Test two attributesToSnippet on specific query with one hit empty string', async () => { + test('Test two snippets on specific query and compare snippet with highlight results', async () => { const response = await searchClient.search([ { indexName: 'movies', @@ -105,21 +126,31 @@ describe('Snippet Browser test', () => { const firstHitHighlight = response.results[0]?.hits[0]?._highlightResult const firstHitSnippet = response.results[0].hits[0]._snippetResult - expect(firstHitHighlight?.title?.value).toEqual('

S

tar Wars') - expect(firstHitHighlight?.overview?.value).toEqual( - 'Luke

S

kywalker and' - ) - expect(firstHitSnippet?.title?.value).toEqual('

S

tar Wars...') - expect(firstHitSnippet?.overview?.value).toEqual( - 'Luke

S

kywalker and...' - ) + expect(firstHitHighlight).toHaveProperty('title', { + value: '

S

tar Wars', + }) + expect(firstHitHighlight).toHaveProperty('overview', { + value: 'Luke

S

kywalker and', + }) + + expect(firstHitSnippet).toHaveProperty('title', { + value: '

S

tar Wars', + }) + expect(firstHitSnippet).toHaveProperty('overview', { + value: 'Luke

S

kywalker and...', + }) const secondHitHighlight = response.results[0]?.hits[1]?._highlightResult const secondHitSnippet = response.results[0]?.hits[1]?._snippetResult - expect(secondHitHighlight?.title?.value).toEqual('Four') + expect(secondHitHighlight).toHaveProperty('title', { value: 'Four' }) expect(secondHitHighlight?.overview?.value).toEqual("It'

s

Ted") - expect(secondHitSnippet?.title?.value).toEqual('Four...') - expect(secondHitSnippet?.overview?.value).toEqual("It'

s

Ted...") + + expect(secondHitSnippet).toHaveProperty('title', { + value: 'Four...', + }) + expect(secondHitSnippet).toHaveProperty('overview', { + value: "It'

s

Ted...", + }) }) test('Test attributesToSnippet on a null attribute', async () => { @@ -129,12 +160,13 @@ describe('Snippet Browser test', () => { params: { query: 'Kill', attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', }, }, ]) - const firstHit = response.results[0]?.hits[0]?._highlightResult - expect(firstHit?.overview?.value).toEqual('null') + const firstHit = response.results[0]?.hits[0]?._snippetResult + expect(firstHit).toHaveProperty('overview', { value: 'null' }) }) test('Test one attributesToSnippet on placeholder w/ snippetEllipsisText', async () => { @@ -144,11 +176,14 @@ describe('Snippet Browser test', () => { params: { query: '', attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', }, }, ]) - const snippeted = response.results[0]?.hits[0]?._highlightResult - expect(snippeted?.overview?.value).toEqual('Princess') + + const snippeted = response.results[0]?.hits[0]?._snippetResult + expect(snippeted).toHaveProperty('overview', { value: 'Princess...' }) + expect(snippeted).toHaveProperty('title', { value: 'Star Wars' }) }) test('Test one attributesToSnippet on specific query w/ snippetEllipsisText', async () => { @@ -158,11 +193,12 @@ describe('Snippet Browser test', () => { params: { query: 'judg', attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', }, }, ]) - const snippeted = response.results[0]?.hits[0]?._highlightResult?.overview - expect(snippeted?.value).toEqual('While') + const snippeted = response.results[0]?.hits[0]?._snippetResult + expect(snippeted).toHaveProperty('overview', { value: 'While...' }) }) test('Test two attributesToSnippet on specific query with one hit empty string w/ snippetEllipsisText', async () => { @@ -170,24 +206,26 @@ describe('Snippet Browser test', () => { { indexName: 'movies', params: { - query: 's', - attributesToSnippet: ['overview:2', 'title:2'], + query: 'm', + attributesToSnippet: ['overview:2', 'title:5'], + snippetEllipsisText: '...', }, }, ]) - const firstHit = response.results[0]?.hits[0]?._highlightResult + const firstHit = response.results[0]?.hits[0]?._snippetResult - expect(firstHit?.title?.value).toEqual( - '__ais-highlight__S__/ais-highlight__tar Wars' - ) - expect(firstHit?.overview?.value).toEqual( - 'Luke __ais-highlight__S__/ais-highlight__kywalker and' - ) - const secondHit = response.results[0].hits[1]._highlightResult - expect(secondHit?.title?.value).toEqual('Four') - expect(secondHit?.overview?.value).toEqual( - "It'__ais-highlight__s__/ais-highlight__ Ted" - ) + expect(firstHit).toHaveProperty('title', { + value: '__ais-highlight__M__/ais-highlight__agnetic Rose', + }) + expect(firstHit).toHaveProperty('overview', { value: '' }) + + const secondHit = response.results[0].hits[1]._snippetResult + expect(secondHit).toHaveProperty('title', { + value: 'Judgment...', + }) + expect(secondHit).toHaveProperty('overview', { + value: 'boxing __ais-highlight__m__/ais-highlight__atch,...', + }) }) test('Test attributesToSnippet on a null attribute w/ snippetEllipsisText', async () => { @@ -197,29 +235,19 @@ describe('Snippet Browser test', () => { params: { query: 'Kill', attributesToSnippet: ['overview:2'], + snippetEllipsisText: '...', }, }, ]) + const firstHit = response.results[0]?.hits[0]?._snippetResult - const firstHit = response.results[0]?.hits[0]?._highlightResult - expect(firstHit?.overview?.value).toEqual('null') - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty('id') - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty( - 'title' - ) - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty( - 'overview' - ) - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty( - 'genres' - ) - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty( - 'poster' - ) - expect(response.results[0]?.hits[0]?._highlightResult).toHaveProperty( - 'release_date' - ) - // expect(resKeys).toEqual(expect.arrayContaining(Object.keys(dataset[0]))) + expect(firstHit).toHaveProperty('overview', { value: 'null' }) + expect(firstHit).toHaveProperty('id', { + value: '24', + }) + expect(firstHit).toHaveProperty('title', { + value: '__ais-highlight__Kill__/ais-highlight__ Bill: Vol. 1', + }) }) test('Test attributes to snippet on non-string-types', async () => { @@ -229,13 +257,17 @@ describe('Snippet Browser test', () => { params: { query: 'Jud', attributesToSnippet: ['*:2'], + snippetEllipsisText: '...', }, }, ]) - const hit = response.results[0].hits[0]._highlightResult + const hit = response.results[0].hits[0]._snippetResult if (hit?.overview) { - expect(hit?.overview.value).toEqual('While') + expect(hit?.overview.value).toEqual('While...') + } + if (hit?.poster) { + expect(hit?.poster.value).toEqual('https...') } if (hit?.genres) { @@ -268,7 +300,7 @@ describe('Snippet Browser test', () => { if (hit?.object) { // @ts-ignore - expect(hit?.object?.value).toEqual('{"id":1,"name":"Nader"}') + expect(hit?.object?.value).toEqual('{"id":"1","name":"Nader"}') } if (hit?.nullField) { diff --git a/yarn.lock b/yarn.lock index 2dfd761c..9ad6f7da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5229,10 +5229,10 @@ mdn-data@2.0.4: resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA== -meilisearch@^0.22.3: - version "0.22.3" - resolved "https://registry.yarnpkg.com/meilisearch/-/meilisearch-0.22.3.tgz#6d8ff0881697f083e1c6179837712e359eb8f0ef" - integrity sha512-Syocfn586JhD0AoEhiu9x5S9xV0z9WPLEDeNaiGFlqR3JJMVQYj0WR5vZ7ZCj/mCkl1VD0GiOW+NsysPY6bWXg== +meilisearch@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/meilisearch/-/meilisearch-0.23.0.tgz#eed5098bd147c13658c3f92e658df9cbfb9e8953" + integrity sha512-bLNonPJK2pJz2akjwolcc/Eqnz/GKJ7y1I4Flg4zjL+v0yPFyIGFFdfe0dw93JWFJWj/RbLS2Q6dDTobZQ9Ehg== dependencies: cross-fetch "^3.1.4"