Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
96 changes: 96 additions & 0 deletions src/adapter/search-request-adapter/filters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
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 []
}

/**
* @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 []
}

/**
* @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(
cachedFilters?: FilterCache,
distribution?: FacetsDistribution
): FacetsDistribution {
distribution = distribution || {}

// If cachedFilters contains something
if (cachedFilters && Object.keys(cachedFilters).length > 0) {
// for all filters in cached filters
for (const cachedFacet in cachedFilters) {
// if facet does not exist on returned distribution, add an empty object
if (!distribution[cachedFacet]) distribution[cachedFacet] = {}
// for all fields in every filter
for (const cachedField of cachedFilters[cachedFacet]) {
// if the field is not present in the returned distribution
// set it at 0
if (!Object.keys(distribution[cachedFacet]).includes(cachedField)) {
// add 0 value
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