Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ module.exports = {
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/member-delimiter-style': [
'error',
{
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@
"test:watch": "yarn test --watch",
"test": "jest --runInBand --selectProjects dom --selectProjects node",
"test:build": "yarn build && jest --runInBand --selectProjects build",
"test:e2e": "concurrently --kill-others -s first \"NODE_ENV=test yarn playground:angular\" \"cypress run --env playground=angular\"",
"test:e2e": "concurrently --kill-others -s first \"yarn playground:vue\" \"cypress run --env playground=vue\"",
"test:e2e:all": "sh scripts/e2e.sh",
"test:e2e:watch": "concurrently --kill-others -s first \"NODE_ENV=test yarn playground:angular\" \"cypress open --env playground=angular\"",
"test:e2e:watch": "concurrently --kill-others -s first \"yarn playground:vue\" \"cypress open --env playground=vue\"",
"test:all": "yarn test:e2e:all && yarn test && test:build",
"cy:open": "cypress open",
"playground:vue": "yarn --cwd ./playgrounds/vue && yarn --cwd ./playgrounds/vue serve",
Expand Down Expand Up @@ -71,7 +71,7 @@
"babel-jest": "^27.2.2",
"concurrently": "^6.2.1",
"cssnano": "^4.1.10",
"cypress": "^7.3.0",
"cypress": "^8.5.0",
"eslint": "^7.21.0",
"eslint-config-prettier": "^8.1.0",
"eslint-config-standard": "^16.0.0",
Expand Down
13 changes: 0 additions & 13 deletions src/adapter/__tests__/utils.ts

This file was deleted.

35 changes: 0 additions & 35 deletions src/adapter/facets-distribution-adapter.ts

This file was deleted.

32 changes: 0 additions & 32 deletions src/adapter/hits-adapter.ts

This file was deleted.

4 changes: 0 additions & 4 deletions src/adapter/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
export * from './search-request-adapter'
export * from './search-response-adapter'
export * from './hits-adapter'
export * from './highlight-adapter'
export * from './pagination-adapter'
export * from './facets-distribution-adapter'
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import { facetsDistributionAdapter } from '../'
import { assignMissingFilters } from '../filters'

test('One field in cache present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{ genre: ['comedy'] },
{ genre: { comedy: 1 } }
)
expect(returnedDistribution).toMatchObject({ genre: { comedy: 1 } })
})

test('One field in cache not present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
{ genre: ['comedy'] },
{}
)
const returnedDistribution = assignMissingFilters({ genre: ['comedy'] }, {})
expect(returnedDistribution).toMatchObject({ genre: { comedy: 0 } })
})

test('two field in cache only one present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{ genre: ['comedy'], title: ['hamlet'] },
{ genre: { comedy: 12 } }
)
Expand All @@ -28,7 +25,7 @@ test('two field in cache only one present in distribution', () => {
})

test('two field in cache w/ different facet name none present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{ genre: ['comedy'], title: ['hamlet'] },
{}
)
Expand All @@ -39,7 +36,7 @@ test('two field in cache w/ different facet name none present in distribution',
})

test('two field in cache w/ different facet name both present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{ genre: ['comedy'], title: ['hamlet'] },
{ genre: { comedy: 12 }, title: { hamlet: 1 } }
)
Expand All @@ -50,7 +47,7 @@ test('two field in cache w/ different facet name both present in distribution',
})

test('Three field in cache w/ different facet name two present in distribution', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{ genre: ['comedy', 'horror'], title: ['hamlet'] },
{ genre: { comedy: 12 }, title: { hamlet: 1 } }
)
Expand All @@ -61,31 +58,31 @@ test('Three field in cache w/ different facet name two present in distribution',
})

test('Cache is undefined and facets distribution is not', () => {
const returnedDistribution = facetsDistributionAdapter(undefined, {
const returnedDistribution = assignMissingFilters(undefined, {
genre: { comedy: 12 },
})
expect(returnedDistribution).toMatchObject({ genre: { comedy: 12 } })
})

test('Cache is empty object and facets distribution is not', () => {
const returnedDistribution = facetsDistributionAdapter(
const returnedDistribution = assignMissingFilters(
{},
{ genre: { comedy: 12 } }
)
expect(returnedDistribution).toMatchObject({ genre: { comedy: 12 } })
})

test('Cache is empty object and facets distribution empty object', () => {
const returnedDistribution = facetsDistributionAdapter({}, {})
const returnedDistribution = assignMissingFilters({}, {})
expect(returnedDistribution).toMatchObject({})
})

test('Cache is undefined and facets distribution empty object', () => {
const returnedDistribution = facetsDistributionAdapter(undefined, {})
const returnedDistribution = assignMissingFilters(undefined, {})
expect(returnedDistribution).toMatchObject({})
})

test('Cache is undefined and facets distribution is undefined', () => {
const returnedDistribution = facetsDistributionAdapter(undefined, undefined)
const returnedDistribution = assignMissingFilters(undefined, undefined)
expect(returnedDistribution).toMatchObject({})
})
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { cacheFilters } from '..'
import { cacheFilters } from '../filters'

const facetCacheData = [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import type { Filter, AlgoliaSearchOptions } from '../types'
import { replaceColonByEqualSign } from '../utils'
import type { Filter, SearchContext } from '../../types'
import { replaceColonByEqualSign } from '../../utils'

/**
* Transform InstantSearch filter to MeiliSearch filter.
* Change sign from `:` to `=` in nested filter object.
* example: [`genres:comedy`] becomes [`genres=comedy`]
*
* @param {AlgoliaSearchOptions['facetFilters']} filters?
* @returns Filter
* @param {SearchContext['facetFilters']} filters?
* @returns {Filter}
*/
function transformFilter(
filters?: AlgoliaSearchOptions['facetFilters']
): Filter {
function transformFilter(filters?: SearchContext['facetFilters']): Filter {
if (typeof filters === 'string') {
return replaceColonByEqualSign(filters)
} else if (Array.isArray(filters))
Expand All @@ -34,7 +32,7 @@ function transformFilter(
* If filter is array, return without change.
*
* @param {Filter} filter
* @returns Array
* @returns {Array}
*/
function filterToArray(filter: Filter): Array<string | string[]> {
// Filter is a string
Expand All @@ -51,7 +49,7 @@ function filterToArray(filter: Filter): Array<string | string[]> {
* @param {Filter} facetFilters
* @param {Filter} numericFilters
* @param {string} filters
* @returns Filter
* @returns {Filter}
*/
function mergeFilters(
facetFilters: Filter,
Expand Down Expand Up @@ -82,14 +80,14 @@ function mergeFilters(
* combining and transforming all provided filters.
*
* @param {string|undefined} filters
* @param {AlgoliaSearchOptions['numericFilters']} numericFilters
* @param {AlgoliaSearchOptions['facetFilters']} facetFilters
* @returns Filter
* @param {SearchContext['numericFilters']} numericFilters
* @param {SearchContext['facetFilters']} facetFilters
* @returns {Filter}
*/
export function adaptFilters(
filters: string | undefined,
numericFilters: AlgoliaSearchOptions['numericFilters'],
facetFilters: AlgoliaSearchOptions['facetFilters']
numericFilters: SearchContext['numericFilters'],
facetFilters: SearchContext['facetFilters']
): Filter {
const transformedFilter = transformFilter(facetFilters || [])
const transformedNumericFilter = transformFilter(numericFilters || [])
Expand Down
94 changes: 94 additions & 0 deletions src/adapter/search-request-adapter/filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {
Filter,
ParsedFilter,
FacetsDistribution,
FilterCache,
} from '../../types'
import { removeUndefined } from '../../utils'

/**
* @param {string} filter
*/
const adaptFilterSyntax = (filter: string) => {
const matches = filter.match(/([^=]*)="?([^\\"]*)"?$/)
if (matches) {
const [_, filterName, value] = matches
return [{ filterName, value }]
}
return [undefined]
}

/**
* @param {Filter} filters?
* @returns {Array}
*/
function extractFilters(filters?: Filter): Array<ParsedFilter | undefined> {
if (typeof filters === 'string') {
return adaptFilterSyntax(filters)
} else if (Array.isArray(filters)) {
return filters
.map((nestedFilter) => {
if (Array.isArray(nestedFilter)) {
return nestedFilter.map((filter) => adaptFilterSyntax(filter))
}
return adaptFilterSyntax(nestedFilter)
})
.flat(2)
}
return [undefined]
}

/**
* @param {Filter} filters?
* @returns {FilterCache}
*/
export function cacheFilters(filters?: Filter): FilterCache {
const extractedFilters = extractFilters(filters)
const cleanFilters = removeUndefined(extractedFilters)
return cleanFilters.reduce<FilterCache>(
(cache, parsedFilter: ParsedFilter) => {
const { filterName, value } = parsedFilter
const prevFields = cache[filterName] || []
cache = {
...cache,
[filterName]: [...prevFields, value],
}
return cache
},
{} as FilterCache
)
}

/**
* Assign missing filters to facetsDistribution.
* All facet passed as filter should appear in the facetsDistribution.
* If not present, the facet is added with 0 as value.
*
*
* @param {FilterCache} cache?
* @param {FacetsDistribution} distribution?
* @returns {FacetsDistribution}
*/
export function assignMissingFilters(
cache?: FilterCache,
distribution?: FacetsDistribution
): FacetsDistribution {
distribution = distribution || {}
if (cache && Object.keys(cache).length > 0) {
for (const cachedFacet in cache) {
for (const cachedField of cache[cachedFacet]) {
// if cached field is not present in the returned distribution

if (
!distribution[cachedFacet] ||
!Object.keys(distribution[cachedFacet]).includes(cachedField)
) {
// add 0 value
distribution[cachedFacet] = distribution[cachedFacet] || {}
distribution[cachedFacet][cachedField] = 0
}
}
}
}
return distribution
}
2 changes: 2 additions & 0 deletions src/adapter/search-request-adapter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './search-resolver'
export * from './search-params-adapter'
Loading