mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-12-30 22:34:10 -05:00
feat: add stars api
This commit is contained in:
parent
9bc9597413
commit
75c0e1e4ec
5 changed files with 77 additions and 2 deletions
|
@ -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
|
||||
|
||||
|
|
32
src/api/endpoint/api/stars.js
Normal file
32
src/api/endpoint/api/stars.js
Normal 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,
|
||||
})),
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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?');
|
||||
|
|
|
@ -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' };
|
||||
|
|
Loading…
Reference in a new issue