mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-02-17 23:45:29 -05:00
fix: fix the exact search phrase (#2225)
* fix: Fix the exact search phrase * fix: Add changeset to fix of exact search phrase Co-authored-by: Juan Picado <juanpicado19@gmail.com>
This commit is contained in:
parent
1cc00cf2ab
commit
5ddfa5264c
7 changed files with 50 additions and 9 deletions
12
.changeset/red-chefs-float.md
Normal file
12
.changeset/red-chefs-float.md
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
'@verdaccio/store': patch
|
||||
'@verdaccio/web': patch
|
||||
---
|
||||
|
||||
Fix the search by exact name of the package
|
||||
|
||||
Full package name queries was not finding anithing. It was happening
|
||||
becouse of stemmer of [lunr.js](https://lunrjs.com/).
|
||||
|
||||
To fix this, the stemmer of [lunr.js](https://lunrjs.com/) was removed from search pipeline.
|
||||
|
|
@ -123,6 +123,16 @@ describe('endpoint web unit test', () => {
|
|||
});
|
||||
|
||||
describe('Search', () => {
|
||||
test('should find @scope/pk1-test', (done) => {
|
||||
request(app)
|
||||
.get('/-/verdaccio/search/@scope%2fpk1-test')
|
||||
.expect(HTTP_STATUS.OK)
|
||||
.end(function (err, res) {
|
||||
expect(res.body).toHaveLength(1);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test('should not find forbidden-place', (done) => {
|
||||
request(app)
|
||||
.get('/-/verdaccio/search/forbidden-place')
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
"async": "3.1.1",
|
||||
"debug": "^4.1.1",
|
||||
"lodash": "4.17.15",
|
||||
"lunr": "2.3.9",
|
||||
"lunr-mutable-indexes": "^2.3.2",
|
||||
"semver": "7.1.2"
|
||||
},
|
||||
|
|
|
@ -1,14 +1,20 @@
|
|||
// eslint-disable no-invalid-this
|
||||
|
||||
import lunr from 'lunr';
|
||||
import lunrMutable from 'lunr-mutable-indexes';
|
||||
import { Version, IPluginStorage, Config } from '@verdaccio/types';
|
||||
import { IStorageHandler, IStorage } from './storage';
|
||||
|
||||
export interface ISearchResult {
|
||||
ref: string;
|
||||
score: number;
|
||||
}
|
||||
|
||||
export interface IWebSearch {
|
||||
index: lunrMutable.index;
|
||||
storage: IStorageHandler;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
query(query: string): any;
|
||||
query(query: string): ISearchResult[];
|
||||
add(pkg: Version): void;
|
||||
remove(name: string): void;
|
||||
reindex(): void;
|
||||
|
@ -42,6 +48,8 @@ class Search implements IWebSearch {
|
|||
// @ts-ignore
|
||||
this.field('readme');
|
||||
});
|
||||
|
||||
this.index.builder.pipeline.remove(lunr.stemmer);
|
||||
}
|
||||
|
||||
public init() {
|
||||
|
@ -55,7 +63,7 @@ class Search implements IWebSearch {
|
|||
* @param {*} q the keyword
|
||||
* @return {Array} list of results.
|
||||
*/
|
||||
public query(query: string): any[] {
|
||||
public query(query: string): ISearchResult[] {
|
||||
const localStorage = this.storage.localStorage as IStorage;
|
||||
|
||||
return query === '*'
|
||||
|
|
|
@ -28,6 +28,7 @@ function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth):
|
|||
debug('is allowed %o', allowed);
|
||||
if (err || !allowed) {
|
||||
debug('deny access');
|
||||
reject(err);
|
||||
return;
|
||||
}
|
||||
debug('access succeed');
|
||||
|
@ -52,17 +53,17 @@ function addSearchWebApi(route: Router, storage: IStorageHandler, auth: IAuth):
|
|||
res: $ResponseExtend,
|
||||
next: $NextFunctionVer
|
||||
): Promise<void> {
|
||||
const results: string[] = SearchInstance.query(req.params.anything);
|
||||
const results = SearchInstance.query(req.params.anything);
|
||||
debug('search results %o', results);
|
||||
if (results.length > 0) {
|
||||
let packages: Package[] = [];
|
||||
for (let pkgName of results) {
|
||||
for (let result of results) {
|
||||
try {
|
||||
const pkg = await getPackageInfo(pkgName, req.remote_user);
|
||||
debug('package found %o', pkgName);
|
||||
const pkg = await getPackageInfo(result.ref, req.remote_user);
|
||||
debug('package found %o', result.ref);
|
||||
packages.push(pkg);
|
||||
} catch (err) {
|
||||
debug('search for %o failed err %o', pkgName, err?.message);
|
||||
debug('search for %o failed err %o', result.ref, err?.message);
|
||||
}
|
||||
}
|
||||
next(packages);
|
||||
|
|
|
@ -9,7 +9,10 @@ import { initializeServer } from './helper';
|
|||
setup([]);
|
||||
|
||||
const mockManifest = jest.fn();
|
||||
const mockQuery = jest.fn(() => ['pkg1', 'pk2']);
|
||||
const mockQuery = jest.fn(() => [
|
||||
{ ref: 'pkg1', score: 1 },
|
||||
{ ref: 'pk2', score: 0.9 },
|
||||
]);
|
||||
jest.mock('@verdaccio/ui-theme', () => mockManifest());
|
||||
|
||||
jest.mock('@verdaccio/store', () => ({
|
||||
|
@ -74,7 +77,11 @@ describe('test web server', () => {
|
|||
|
||||
test('should fail search api', async () => {
|
||||
mockQuery.mockImplementation(() => {
|
||||
return ['aa', 'bb', 'cc'];
|
||||
return [
|
||||
{ ref: 'aa', score: 1 },
|
||||
{ ref: 'bb', score: 0.8 },
|
||||
{ ref: 'cc', score: 0.6 },
|
||||
];
|
||||
});
|
||||
const response = await supertest(await initializeServer('default-test.yaml'))
|
||||
.get('/-/verdaccio/search/notFound')
|
||||
|
|
2
pnpm-lock.yaml
generated
2
pnpm-lock.yaml
generated
|
@ -978,6 +978,7 @@ importers:
|
|||
async: 3.1.1
|
||||
debug: ^4.1.1
|
||||
lodash: 4.17.15
|
||||
lunr: 2.3.9
|
||||
lunr-mutable-indexes: ^2.3.2
|
||||
semver: 7.1.2
|
||||
dependencies:
|
||||
|
@ -992,6 +993,7 @@ importers:
|
|||
async: 3.1.1
|
||||
debug: 4.1.1
|
||||
lodash: 4.17.15
|
||||
lunr: 2.3.9
|
||||
lunr-mutable-indexes: 2.3.2
|
||||
semver: 7.1.2
|
||||
devDependencies:
|
||||
|
|
Loading…
Add table
Reference in a new issue