-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
173 changed files
with
155,686 additions
and
253,195 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
/** | ||
* This class wraps request params to ease interpretting the query | ||
**/ | ||
|
||
// Build regex pattern for matching a phrase fully enclosed in quotes (or smart quotes): | ||
const QUOTE_CHARS = '"\u201C\u201D\u201E\u201F\u2033\u2036' | ||
const IN_QUOTES_PATTERN = new RegExp(`^[${QUOTE_CHARS}][^${QUOTE_CHARS}]+[${QUOTE_CHARS}]$`) | ||
|
||
class ApiRequest { | ||
static ADVANCED_SEARCH_PARAMS = ['title', 'subject', 'contributor'] | ||
static IDENTIFIER_NUMBER_PARAMS = ['isbn', 'issn', 'lccn', 'oclc'] | ||
|
||
constructor (params) { | ||
this.params = params | ||
|
||
// Make some substitutions for folks querying with "date:1997", etc | ||
if (this.params.q) { | ||
this.params.q = this.params.q | ||
.replace(/date:/g, 'dateStartYear:') | ||
.replace(/location:/g, 'locations:') | ||
.replace(/subject:/g, 'subjectLiteral:') | ||
} | ||
} | ||
|
||
/** | ||
* Get array of params in the query that are also valid search-scopes: | ||
*/ | ||
advancedSearchParamsThatAreAlsoScopes () { | ||
// Return search params that are also valid search_scope values | ||
return ApiRequest.ADVANCED_SEARCH_PARAMS | ||
.filter((key) => this.params[key]) | ||
} | ||
|
||
hasKeyword () { | ||
return !!this.params.q | ||
} | ||
|
||
hasSearch () { | ||
return this.hasKeyword() || this.advancedSearchParamsThatAreAlsoScopes().length > 0 | ||
} | ||
|
||
/** | ||
* Returns true if search_scope matches one of the named scopes | ||
**/ | ||
hasScope (scopes) { | ||
return scopes.includes(this.params.search_scope) | ||
} | ||
|
||
/** | ||
* Returns true if query is fully wrapped in quotes (or smart quotes) | ||
**/ | ||
queryIsFullyQuoted () { | ||
return IN_QUOTES_PATTERN.test(this.params.q) | ||
} | ||
|
||
/** | ||
* Get keyword query without surrounding quotes (if fully quoted) | ||
**/ | ||
querySansQuotes () { | ||
return this.queryIsFullyQuoted() | ||
? this.params.q.substring(1, this.params.q.length - 1) | ||
: this.params.q | ||
} | ||
|
||
hasIdentifierNumberParam () { | ||
return Object.keys(this.params) | ||
.some((userParam) => ApiRequest.IDENTIFIER_NUMBER_PARAMS.includes(userParam)) | ||
} | ||
|
||
static fromParams (params) { | ||
return new ApiRequest(params) | ||
} | ||
} | ||
|
||
module.exports = ApiRequest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
// Configure search scopes: | ||
const SEARCH_SCOPES = { | ||
all: { | ||
fields: [ | ||
'title^5', | ||
'title.folded^2', | ||
'description.folded', | ||
'subjectLiteral^2', | ||
'subjectLiteral.folded', | ||
'creatorLiteral^2', | ||
'creatorLiteral.folded', | ||
'contributorLiteral.folded', | ||
'note.label.folded', | ||
'publisherLiteral.folded', | ||
'seriesStatement.folded', | ||
'titleAlt.folded', | ||
'titleDisplay.folded', | ||
'contentsTitle.folded', | ||
'donor.folded', | ||
'parallelTitle.folded^5', | ||
'parallelTitleDisplay.folded', | ||
'parallelTitleAlt.folded', | ||
'parallelSeriesStatement.folded', | ||
'parallelCreatorLiteral.folded', | ||
'parallelPublisher', | ||
'uniformTitle.folded', | ||
'parallelUniformTitle', | ||
'formerTitle', | ||
'addedAuthorTitle', | ||
'placeOfPublication', | ||
{ field: 'items.idBarcode', on: (q) => /\d{6,}/.test(q) }, | ||
// Try to detect shelfmark searches (e.g. JFD 16-5143) | ||
{ field: 'items.shelfMark', on: (q) => /^[A-Z]{1,3} \d{2,}/.test(q) } | ||
] | ||
}, | ||
title: { | ||
fields: [ | ||
'title^5', | ||
'title.folded^2', | ||
'titleAlt.folded', | ||
'uniformTitle.folded', | ||
'titleDisplay.folded', | ||
'seriesStatement.folded', | ||
'contentsTitle.folded', | ||
'donor.folded', | ||
'parallelTitle.folded^5', | ||
'parallelTitleDisplay.folded', | ||
'parallelSeriesStatement.folded', | ||
'parallelTitleAlt.folded', | ||
'parallelCreatorLiteral.folded', | ||
'parallelUniformTitle', | ||
'formerTitle', | ||
'addedAuthorTitle' | ||
] | ||
}, | ||
contributor: { | ||
fields: ['creatorLiteral^4', 'creatorLiteral.folded^2', 'contributorLiteral.folded', 'parallelCreatorLiteral.folded', 'parallelContributorLiteral.folded'] | ||
}, | ||
subject: { | ||
fields: ['subjectLiteral^2', 'subjectLiteral.folded', 'parallelSubjectLiteral.folded'] | ||
}, | ||
series: { | ||
fields: ['seriesStatement.folded'] | ||
}, | ||
journal_title: { | ||
fields: null | ||
}, | ||
callnumber: { | ||
// We do custom field matching for this search-scope | ||
}, | ||
standard_number: { | ||
// We do custom field matching for this search-scope | ||
} | ||
} | ||
|
||
const FILTER_CONFIG = { | ||
owner: { operator: 'match', field: 'items.owner_packed', repeatable: true, path: 'items' }, | ||
subjectLiteral: { operator: 'match', field: 'subjectLiteral_exploded', repeatable: true }, | ||
holdingLocation: { operator: 'match', field: 'items.holdingLocation_packed', repeatable: true, path: 'items' }, | ||
buildingLocation: { operator: 'match', field: 'buildingLocationIds', repeatable: true }, | ||
language: { operator: 'match', field: 'language_packed', repeatable: true }, | ||
materialType: { operator: 'match', field: 'materialType_packed', repeatable: true }, | ||
mediaType: { operator: 'match', field: 'mediaType_packed', repeatable: true }, | ||
carrierType: { operator: 'match', field: 'carrierType_packed', repeatable: true }, | ||
publisher: { operator: 'match', field: 'publisherLiteral.raw', repeatable: true }, | ||
contributorLiteral: { operator: 'match', field: 'contributorLiteral.raw', repeatable: true }, | ||
creatorLiteral: { operator: 'match', field: 'creatorLiteral.raw', repeatable: true }, | ||
issuance: { operator: 'match', field: 'issuance_packed', repeatable: true }, | ||
createdYear: { operator: 'match', field: 'createdYear', repeatable: true }, | ||
dateAfter: { | ||
operator: 'custom', | ||
type: 'int' | ||
}, | ||
dateBefore: { | ||
operator: 'custom', | ||
type: 'int' | ||
} | ||
} | ||
|
||
module.exports = { | ||
SEARCH_SCOPES, | ||
FILTER_CONFIG | ||
} |
Oops, something went wrong.