mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-15 06:35:20 -07:00
refactor(search): extract shared filter helper
Share filter parsing and provider mapping logic between Stork and upcoming search adapters. This keeps the existing Stork API stable while adding Pagefind-oriented filter serialization under test.
This commit is contained in:
parent
e5f28b16ee
commit
727f84e4c2
3 changed files with 135 additions and 120 deletions
119
helpers/search/filters.js
Normal file
119
helpers/search/filters.js
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
import { filterSeparator } from '~/helpers/constants.js'
|
||||
import { isString } from '~/helpers/check-types.js'
|
||||
|
||||
export class SearchFilters {
|
||||
constructor({
|
||||
initialFilters = {}
|
||||
} = {}) {
|
||||
this.initialFilters = initialFilters
|
||||
|
||||
this.filters = {
|
||||
...initialFilters
|
||||
}
|
||||
}
|
||||
|
||||
get list () {
|
||||
return Object.entries( this.filters ).map( ([ filterKey, filterValue ]) => {
|
||||
return `${ filterKey }${ filterSeparator }${ filterValue }`
|
||||
} )
|
||||
}
|
||||
|
||||
get asQuery () {
|
||||
return this.list.join(' ')
|
||||
}
|
||||
|
||||
get asPagefindFilters () {
|
||||
return Object.fromEntries( Object.entries( this.filters ).map( ([ filterKey, filterValue ]) => {
|
||||
return [ filterKey, [ filterValue ] ]
|
||||
}) )
|
||||
}
|
||||
|
||||
getByKey ( key ) {
|
||||
return `${ key }${ filterSeparator }${ this.filters[ key ] }`
|
||||
}
|
||||
|
||||
isQueryValue ( filterNameOrQueryValue ) {
|
||||
return filterNameOrQueryValue.includes( filterSeparator )
|
||||
}
|
||||
|
||||
getKeyAndValue ( filterQueryValue ) {
|
||||
const key = filterQueryValue.substring(0, filterQueryValue.indexOf( filterSeparator ))
|
||||
const value = filterQueryValue.substring(filterQueryValue.indexOf( filterSeparator )+1)
|
||||
|
||||
return { key, value }
|
||||
}
|
||||
|
||||
getFilterNameAndValueFromString ( filterNameOrQueryValue ) {
|
||||
if ( this.isQueryValue( filterNameOrQueryValue ) ) {
|
||||
return this.getKeyAndValue( filterNameOrQueryValue )
|
||||
}
|
||||
|
||||
return {
|
||||
key: filterNameOrQueryValue,
|
||||
value: null
|
||||
}
|
||||
}
|
||||
|
||||
remove ( filterName ) {
|
||||
if ( this.isQueryValue( filterName ) ) throw new Error(`${ filterName } is not a valid filter name`)
|
||||
|
||||
delete this.filters[ filterName ]
|
||||
}
|
||||
|
||||
setFromStringArray ( filterStringArray ) {
|
||||
filterStringArray.forEach( filterString => {
|
||||
const { key, value } = this.getFilterNameAndValueFromString( filterString )
|
||||
|
||||
this.filters[ key ] = value
|
||||
})
|
||||
}
|
||||
|
||||
setFromString ( filterNameOrQueryValue ) {
|
||||
const {
|
||||
key,
|
||||
value = ''
|
||||
} = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
if ( value.trim().length === 0 ) throw new Error(`${ filterNameOrQueryValue } is not a valid filter value`)
|
||||
|
||||
this.set( key, value )
|
||||
}
|
||||
|
||||
set ( filterName, filterValue ) {
|
||||
if ( this.isQueryValue( filterName ) ) throw new Error(`${ filterName } is not a valid filter name`)
|
||||
|
||||
this.filters[ filterName ] = filterValue
|
||||
}
|
||||
|
||||
toggleFilter ( filterNameOrQueryValue, filterValue = null ) {
|
||||
const fromString = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
const filterName = fromString.key
|
||||
filterValue = filterValue || fromString.value
|
||||
|
||||
if ( this.has( filterNameOrQueryValue ) ) {
|
||||
this.remove( filterName )
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if ( typeof filterValue !== 'string' ) {
|
||||
throw new Error(`Filter value must be a string. Got ${ typeof filterValue }`)
|
||||
}
|
||||
|
||||
this.set( filterName, filterValue )
|
||||
}
|
||||
|
||||
has ( filterNameOrQueryValue ) {
|
||||
const {
|
||||
key : filterName,
|
||||
value : filterValue = null
|
||||
} = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
if ( isString( filterValue ) ) {
|
||||
return !!this.filters[ filterName ] && this.filters[ filterName ] === filterValue
|
||||
}
|
||||
|
||||
return !!this.filters[ filterName ]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import { filterSeparator } from '~/helpers/constants.js'
|
||||
|
||||
import { isString } from '~/helpers/check-types.js'
|
||||
import { SearchFilters } from '~/helpers/search/filters.js'
|
||||
|
||||
import {
|
||||
storkIndexRelativeURL,
|
||||
|
|
@ -276,121 +275,4 @@ export class StorkClient {
|
|||
}
|
||||
}
|
||||
|
||||
export class StorkFilters {
|
||||
constructor({
|
||||
initialFilters = {}
|
||||
} = {}) {
|
||||
this.initialFilters = initialFilters
|
||||
|
||||
this.filters = {
|
||||
...initialFilters
|
||||
}
|
||||
}
|
||||
|
||||
get list () {
|
||||
return Object.entries( this.filters ).map( ([ filterKey, filterValue ]) => {
|
||||
return `${ filterKey }${ filterSeparator }${ filterValue }`
|
||||
} )
|
||||
}
|
||||
|
||||
get asQuery () {
|
||||
return this.list.join(' ')
|
||||
}
|
||||
|
||||
getByKey ( key ) {
|
||||
return `${ key }${ filterSeparator }${ this.filters[ key ] }`
|
||||
}
|
||||
|
||||
isQueryValue ( filterNameOrQueryValue ) {
|
||||
return filterNameOrQueryValue.includes( filterSeparator )
|
||||
}
|
||||
|
||||
getKeyAndValue ( filterQueryValue ) {
|
||||
const key = filterQueryValue.substring(0, filterQueryValue.indexOf( filterSeparator ))
|
||||
const value = filterQueryValue.substring(filterQueryValue.indexOf( filterSeparator )+1)
|
||||
|
||||
return { key, value }
|
||||
}
|
||||
|
||||
getFilterNameAndValueFromString ( filterNameOrQueryValue ) {
|
||||
if ( this.isQueryValue( filterNameOrQueryValue ) ) {
|
||||
return this.getKeyAndValue( filterNameOrQueryValue )
|
||||
}
|
||||
|
||||
return {
|
||||
key: filterNameOrQueryValue,
|
||||
value: null
|
||||
}
|
||||
}
|
||||
|
||||
remove ( filterName ) {
|
||||
// Throw error if it's not a valid filter name
|
||||
if ( this.isQueryValue( filterName ) ) throw new Error(`${ filterName } is not a valid filter name`)
|
||||
|
||||
delete this.filters[ filterName ]
|
||||
}
|
||||
|
||||
setFromStringArray ( filterStringArray ) {
|
||||
filterStringArray.forEach( filterString => {
|
||||
const { key, value } = this.getFilterNameAndValueFromString( filterString )
|
||||
|
||||
this.filters[ key ] = value
|
||||
})
|
||||
}
|
||||
|
||||
setFromString ( filterNameOrQueryValue ) {
|
||||
const {
|
||||
key,
|
||||
value = ''
|
||||
} = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
// Throw for empty values
|
||||
if ( value.trim().length === 0 ) throw new Error(`${ filterNameOrQueryValue } is not a valid filter value`)
|
||||
|
||||
this.set( key, value )
|
||||
}
|
||||
|
||||
set ( filterName, filterValue ) {
|
||||
// Throw error if it's not a valid filter name
|
||||
if ( this.isQueryValue( filterName ) ) throw new Error(`${ filterName } is not a valid filter name`)
|
||||
|
||||
this.filters[ filterName ] = filterValue
|
||||
}
|
||||
|
||||
toggleFilter ( filterNameOrQueryValue, filterValue = null ) {
|
||||
|
||||
const fromString = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
const filterName = fromString.key
|
||||
filterValue = filterValue || fromString.value
|
||||
|
||||
// If the filter is already set, remove it
|
||||
if ( this.has( filterNameOrQueryValue ) ) {
|
||||
this.remove( filterName )
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Throw error if filter value is not a string
|
||||
if ( typeof filterValue !== 'string' ) {
|
||||
throw new Error(`Filter value must be a string. Got ${ typeof filterValue }`)
|
||||
}
|
||||
|
||||
this.set( filterName, filterValue )
|
||||
}
|
||||
|
||||
has ( filterNameOrQueryValue ) {
|
||||
|
||||
const {
|
||||
key : filterName,
|
||||
value : filterValue = null
|
||||
} = this.getFilterNameAndValueFromString( filterNameOrQueryValue )
|
||||
|
||||
// If this filter is a name and value, check if it's set
|
||||
if ( isString( filterValue ) ) {
|
||||
return !!this.filters[ filterName ] && this.filters[ filterName ] === filterValue
|
||||
}
|
||||
|
||||
return !!this.filters[ filterName ]
|
||||
}
|
||||
}
|
||||
export class StorkFilters extends SearchFilters {}
|
||||
|
|
|
|||
|
|
@ -84,5 +84,19 @@ describe('StorkFilters', () => {
|
|||
filters.setFromString('test_works_yes')
|
||||
expect(filters.asQuery).toBe('test_works_yes')
|
||||
})
|
||||
|
||||
it('should map filters for Pagefind', () => {
|
||||
const filters = new StorkFilters()
|
||||
|
||||
filters.setFromStringArray([
|
||||
'status_native',
|
||||
'category_system_tools'
|
||||
])
|
||||
|
||||
expect(filters.asPagefindFilters).toEqual({
|
||||
status: [ 'native' ],
|
||||
category: [ 'system_tools' ]
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue