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
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ exports[`searchPatternFlyDocsTool, callback should parse parameters, with lower

exports[`searchPatternFlyDocsTool, callback should parse parameters, with made up componentName: search 1`] = `"No PatternFly documentation found matching "lorem ipsum dolor sit amet""`;

exports[`searchPatternFlyDocsTool, callback should parse parameters, with multiple words: search 1`] = `"No PatternFly documentation found matching "Button Card Table""`;
exports[`searchPatternFlyDocsTool, callback should parse parameters, with multiple words: search 1`] = `"# Search results for "Button Card Table", 3 matches found:"`;

exports[`searchPatternFlyDocsTool, callback should parse parameters, with partial componentName: search 1`] = `"# Search results for "ton", 2 matches found:"`;

Expand Down
13 changes: 11 additions & 2 deletions src/server.search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ interface ClosestSearchOptions {
interface FuzzySearchResult {
item: string;
distance: number;
matchType: 'exact' | 'prefix' | 'suffix' | 'contains' | 'fuzzy' | 'all';
matchType: 'exact' | 'prefix' | 'suffix' | 'contains' | 'partial' | 'fuzzy' | 'all';
}

/**
Expand All @@ -33,6 +33,7 @@ interface FuzzySearchResult {
* - prefix = 1
* - suffix = 1
* - contains = 2
* - partial = 2
* - fuzzy = Levenshtein edit distance
* - `maxResults` - Maximum number of results to return
* - `normalizeFn` - Function to normalize strings (default: `normalizeString`)
Expand All @@ -47,6 +48,7 @@ interface FuzzySearchOptions {
isPrefixMatch?: boolean;
isSuffixMatch?: boolean;
isContainsMatch?: boolean;
isPartialMatch?: boolean;
isFuzzyMatch?: boolean;
deduplicateByNormalized?: boolean;
}
Expand All @@ -59,6 +61,7 @@ interface FuzzySearchOptions {
* - Function has a `memo` property to allow use as a memoized function.
*
* @param str
* @returns Normalized or empty string
*/
const normalizeString: NormalizeString = (str: string) => String(str || '')
.trim()
Expand Down Expand Up @@ -126,11 +129,12 @@ const findClosest = (
* @param {FuzzySearchOptions} options - Search configuration options
* @param {number} options.maxDistance - Maximum edit distance for a match. Distance is defined as
* @param {number} options.maxResults - Maximum number of results to return
* @param {NormalizeString} options.normalizeFn - Function to normalize strings (default: `normalizeString`)
* @param {NormalizeString} options.normalizeFn - Function to normalize strings. Should always return a string or empty string (default: `normalizeString`)
* @param {boolean} options.isExactMatch - Include exact matches in results (default: `true`)
* @param {boolean} options.isPrefixMatch - Include prefix matches in results (default: `true`)
* @param {boolean} options.isSuffixMatch - Include suffix matches in results (default: `true`)
* @param {boolean} options.isContainsMatch - Include contains matches in results (default: `true`)
* @param {boolean} options.isPartialMatch - Include partial matches in results (default: `true`)
* @param {boolean} options.isFuzzyMatch - Allow fuzzy matches even when `maxDistance` is negative or zero.
* @param {boolean} options.deduplicateByNormalized - If `true`, deduplicate results by normalized value instead of original string.
* @returns {FuzzySearchResult[]} Array of matching strings with distance and match type
Expand All @@ -155,6 +159,7 @@ const fuzzySearch = (
isPrefixMatch = true,
isSuffixMatch = true,
isContainsMatch = true,
isPartialMatch = true,
isFuzzyMatch = false,
deduplicateByNormalized = false
}: FuzzySearchOptions = {}
Expand Down Expand Up @@ -186,6 +191,9 @@ const fuzzySearch = (
} else if (normalizedQuery !== '' && normalizedItem.includes(normalizedQuery)) {
matchType = 'contains';
editDistance = 2;
} else if (normalizedQuery !== '' && normalizedItem !== '' && normalizedQuery.includes(normalizedItem)) {
matchType = 'partial';
editDistance = 2;
} else if (isFuzzyMatch && Math.abs(normalizedItem.length - normalizedQuery.length) <= maxDistance) {
matchType = 'fuzzy';
editDistance = distance(normalizedQuery, normalizedItem);
Expand All @@ -199,6 +207,7 @@ const fuzzySearch = (
(matchType === 'prefix' && isPrefixMatch) ||
(matchType === 'suffix' && isSuffixMatch) ||
(matchType === 'contains' && isContainsMatch) ||
(matchType === 'partial' && isPartialMatch) ||
(matchType === 'fuzzy' && isFuzzyMatch);

if (editDistance <= maxDistance && isIncluded) {
Expand Down
Loading