From 635b41fcfa258111b1f3e98527f9e9188c92d823 Mon Sep 17 00:00:00 2001 From: Favo Yang Date: Sun, 23 Oct 2022 14:18:41 +0800 Subject: [PATCH] feat: searchV1 api with redis-search backend --- src/plugin.ts | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/plugin.ts b/src/plugin.ts index 5d40d70..5622589 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -34,6 +34,16 @@ export default class RedisStorage implements IPluginStorage { else this.redisClient = redisCreateClient(this.config, this.logger); this.db = new Database(this.redisClient, this.logger); + this.createIndex(); + } + + public async createIndex() { + try { + await this.redisClient.call("FT.CREATE", "ve-pkg-stat-idx", "ON", "HASH", "PREFIX", "1", "ve:pkg:", "SCHEMA", "stat", "TEXT"); + const result: any = await this.redisClient.call('FT.INFO', 've-pkg-stat-idx'); + this.logger.debug({ indexName: result[1] }, "index @{indexName} is ready"); + } catch (error) { + } } public async getSecret(): Promise { @@ -74,6 +84,45 @@ export default class RedisStorage implements IPluginStorage { }); } + /** + * Search api implementation for verdaccio-redis-search-patch and verdaccio@6 + * @param query + */ + public async searchV1(query): Promise { + this.logger.debug({ query }, "searchV1 query: @{query}"); + // Redis-search treats hyphen as separator, refs https://forum.redis.com/t/query-with-dash-is-treated-as-negation/119 + const text = query.text.replace(/-/g, ' ').trim(); + if (!text) return []; + const offset = query.from || 0; + const num = query.size || 250; + try { + const result: any = await this.redisClient.call("FT.SEARCH", "ve-pkg-stat-idx", text, "return", "1", "stat", "LIMIT", String(offset), String(num)); + const searchResult: any = []; + for (let i = 2; i < result.length; i += 2) { + const stat = JSON.parse(result[i][1]); + searchResult.push({ + package: { + name: stat.name, + path: stat.path, + time: Number(stat.time) + }, + score: { + final: 0, + detail: { + quality: 0, + popularity: 0, + maintenance: 0, + } + }, + }); + } + this.logger.debug({ searchResult }, "searchResult: @{searchResult}"); + return searchResult; + } catch (error) { + this.logger.error(error, "searchV1 error: @{error}"); + } + } + /** * Get the stat object to feed onSearchPackage callback. A stat object is an index-like object with less memory and bandwidth cost. * @param name