feat(scripts): Add fuzzy search and type filtering for community scripts; improve scripts CLI output and cache handling
This commit is contained in:
@@ -88,6 +88,11 @@ export class ScriptIndex {
|
||||
*/
|
||||
public async loadCache(): Promise<void> {
|
||||
try {
|
||||
// Don't reload if already cached
|
||||
if (this.cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!Deno) {
|
||||
throw new Error('Deno runtime not available');
|
||||
}
|
||||
@@ -251,23 +256,45 @@ export class ScriptIndex {
|
||||
}
|
||||
|
||||
/**
|
||||
* Search scripts by query string
|
||||
* Search scripts by query string with optional type filter
|
||||
* @param query - Search query
|
||||
* @param typeFilter - Optional type filter (e.g., 'vm', 'ct', 'pve')
|
||||
*/
|
||||
public search(query: string): IScriptMetadata[] {
|
||||
public search(query: string, typeFilter?: string): IScriptMetadata[] {
|
||||
if (!this.cache) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const lowerQuery = query.toLowerCase();
|
||||
let scripts = this.cache.scripts;
|
||||
|
||||
return this.cache.scripts.filter((script) => {
|
||||
// Search in name, description, and slug
|
||||
return (
|
||||
(script.name && script.name.toLowerCase().includes(lowerQuery)) ||
|
||||
(script.slug && script.slug.toLowerCase().includes(lowerQuery)) ||
|
||||
(script.description && script.description.toLowerCase().includes(lowerQuery))
|
||||
);
|
||||
// Apply type filter if provided
|
||||
if (typeFilter) {
|
||||
scripts = scripts.filter((script) => script.type === typeFilter);
|
||||
}
|
||||
|
||||
// Use smartfuzzy for ranking
|
||||
const fuzzyMatcher = new plugins.smartfuzzy.FuzzyMatcher();
|
||||
|
||||
const scoredResults = scripts.map((script) => {
|
||||
// Calculate match scores for each field
|
||||
const nameScore = script.name ? fuzzyMatcher.match(query, script.name) : 0;
|
||||
const slugScore = script.slug ? fuzzyMatcher.match(query, script.slug) : 0;
|
||||
const descScore = script.description ? fuzzyMatcher.match(query, script.description) : 0;
|
||||
|
||||
// Prioritize: slug > name > description
|
||||
const totalScore = slugScore * 3 + nameScore * 2 + descScore;
|
||||
|
||||
return {
|
||||
script,
|
||||
score: totalScore,
|
||||
};
|
||||
});
|
||||
|
||||
// Filter out non-matches and sort by score
|
||||
return scoredResults
|
||||
.filter((result) => result.score > 0)
|
||||
.sort((a, b) => b.score - a.score)
|
||||
.map((result) => result.script);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user