(query: string, options?: { userId?: string; maxResults?: number })
| 2486 | } |
| 2487 | |
| 2488 | searchHubSkills(query: string, options?: { userId?: string; maxResults?: number }): Array<{ hit: HubSkillSearchRow; rank: number }> { |
| 2489 | const limit = options?.maxResults ?? 10; |
| 2490 | const userId = options?.userId ?? ""; |
| 2491 | const sanitized = sanitizeFtsQuery(query); |
| 2492 | let rows: HubSkillSearchRow[]; |
| 2493 | if (sanitized) { |
| 2494 | rows = this.db.prepare(` |
| 2495 | SELECT hs.id, hs.name, hs.description, hs.version, hs.visibility, '' AS group_name, hu.username AS owner_name, hu.status AS owner_status, hs.quality_score, |
| 2496 | bm25(hub_skills_fts) as rank |
| 2497 | FROM hub_skills_fts f |
| 2498 | JOIN hub_skills hs ON hs.rowid = f.rowid |
| 2499 | LEFT JOIN hub_users hu ON hu.id = hs.source_user_id |
| 2500 | WHERE hub_skills_fts MATCH ? |
| 2501 | ORDER BY rank |
| 2502 | LIMIT ? |
| 2503 | `).all(sanitized, limit) as HubSkillSearchRow[]; |
| 2504 | } else { |
| 2505 | rows = this.db.prepare(` |
| 2506 | SELECT hs.id, hs.name, hs.description, hs.version, hs.visibility, '' AS group_name, hu.username AS owner_name, hu.status AS owner_status, hs.quality_score, |
| 2507 | 0 as rank |
| 2508 | FROM hub_skills hs |
| 2509 | LEFT JOIN hub_users hu ON hu.id = hs.source_user_id |
| 2510 | ORDER BY hs.updated_at DESC |
| 2511 | LIMIT ? |
| 2512 | `).all(limit) as HubSkillSearchRow[]; |
| 2513 | } |
| 2514 | return rows.map((row, idx) => ({ hit: row, rank: idx + 1 })); |
| 2515 | } |
| 2516 | |
| 2517 | deleteHubSkillBySource(sourceUserId: string, sourceSkillId: string): void { |
| 2518 | this.db.prepare('DELETE FROM hub_skills WHERE source_user_id = ? AND source_skill_id = ?').run(sourceUserId, sourceSkillId); |
no test coverage detected