feat: add stars api

This commit is contained in:
vip30 2019-03-11 23:37:17 +08:00
parent 9bc9597413
commit 75c0e1e4ec
5 changed files with 77 additions and 2 deletions

View File

@ -157,7 +157,7 @@ Verdaccio aims to support all features of a standard npm client that make sense
- Searching (npm search) - **supported** (cli / browser)
- Ping (npm ping) - **supported**
- Starring (npm star, npm unstar) - not supported, *PR-welcome*
- Starring (npm star, npm unstar, npm stars) - **supported**
### Security

View File

@ -0,0 +1,32 @@
/**
* @prettier
* @flow
*/
import { USERS, HTTP_STATUS } from '../../../lib/constants';
import type { $Response, Router } from 'express';
import type { $RequestExtend, $NextFunctionVer, IStorageHandler } from '../../../../types';
import type { Package } from '@verdaccio/types';
export default function(route: Router, storage: IStorageHandler) {
route.get(
'/-/_view/starredByUser',
(req: $RequestExtend, res: $Response, next: $NextFunctionVer): void => {
const remoteUsername = req.remote_user.name;
storage.getLocalDatabase((err, localPackages: Package[]) => {
if (err) {
return next(err);
}
const filteredPackages = localPackages.filter(
localPackage => (localPackage[USERS] ? Object.keys(localPackage[USERS]).indexOf(remoteUsername) >= 0 : false)
);
res.status(HTTP_STATUS.OK);
next({
rows: filteredPackages.map(filteredPackage => ({
value: filteredPackage.name,
})),
});
});
}
);
}

View File

@ -15,6 +15,7 @@ import distTags from './api/dist-tags';
import publish from './api/publish';
import search from './api/search';
import pkg from './api/package';
import stars from './api/stars';
import profile from './api/v1/profile';
const { match, validateName, validatePackage, encodeScopePackage, antiLoop } = require('../middleware');
@ -55,6 +56,7 @@ export default function(config: Config, auth: IAuth, storage: IStorageHandler) {
distTags(app, auth, storage);
publish(app, auth, storage, config);
ping(app);
stars(app, storage);
return app;
}

View File

@ -375,12 +375,14 @@ class Storage implements IStorageHandler {
self.localStorage.getPackageMetadata(locals[itemPkg], function(err, info) {
if (_.isNil(err)) {
const latest = info[DIST_TAGS].latest;
if (latest && info.versions[latest]) {
const version = info.versions[latest];
const time = info.time[latest];
version.time = time;
// Add for stars api
version.users = info.users;
packages.push(version);
} else {
self.logger.warn({ package: locals[itemPkg] }, 'package @{package} does not have a "latest" tag?');

View File

@ -602,6 +602,45 @@ describe('endpoint unit test', () => {
});
});
});
test('should retrieve stars list with credentials', async (done) => {
const credentials = { name: 'star_user', password: 'secretPass' };
const token = await getNewToken(request(app), credentials);
request(app)
.put('/@scope%2fpk1-test')
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify({
...starMetadata,
users: {
[credentials.name]: true
}
}))
.expect(HTTP_STATUS.OK).end(function(err, res) {
if (err) {
expect(err).toBeNull();
return done(err);
}
request(app)
.get('/-/_view/starredByUser')
.set('authorization', buildToken(TOKEN_BEARER, token))
.set(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON)
.send(JSON.stringify({
key: [credentials.name]
}))
.expect(HTTP_STATUS.OK)
.end(function(err, res) {
if (err) {
expect(err).toBeNull();
return done(err);
}
expect(res.body.rows).toBeDefined();
expect(res.body.rows.length).toBeGreaterThan(0);
done();
});
});
});
test('should unpublish a new package with credentials', async (done) => {
const credentials = { name: 'jota_unpublish', password: 'secretPass' };