From d5303f407be830d9e3a27e128f5a626132b50504 Mon Sep 17 00:00:00 2001 From: "Juan Picado @jotadeveloper" Date: Thu, 5 Sep 2019 12:12:10 -0700 Subject: [PATCH] feat: browse web package version (#1457) * feat: allow endpoint to query by version * chore: update @verdaccio/ui-theme * test: add unit test for sidebar endpoint by version --- package.json | 2 +- src/api/web/endpoint/package.ts | 39 ++++++++++++++++++-------- src/lib/utils.ts | 11 +++++++- test/unit/modules/web/api.web.spec.ts | 29 ++++++++++++++++++- yarn.lock | Bin 365238 -> 365238 bytes 5 files changed, 66 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 6b68e075b..d1a5f7346 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "@verdaccio/local-storage": "2.2.1", "@verdaccio/readme": "8.0.0", "@verdaccio/streams": "8.0.0", - "@verdaccio/ui-theme": "0.2.3", + "@verdaccio/ui-theme": "0.3.0", "JSONStream": "1.3.5", "async": "3.1.0", "body-parser": "1.19.0", diff --git a/src/api/web/endpoint/package.ts b/src/api/web/endpoint/package.ts index e92260eb2..5695cce14 100644 --- a/src/api/web/endpoint/package.ts +++ b/src/api/web/endpoint/package.ts @@ -1,5 +1,14 @@ import _ from 'lodash'; -import { addScope, addGravatarSupport, deleteProperties, sortByName, parseReadme, formatAuthor, convertDistRemoteToLocalTarballUrls } from '../../../lib/utils'; +import { + addScope, + addGravatarSupport, + deleteProperties, + sortByName, + parseReadme, + formatAuthor, + convertDistRemoteToLocalTarballUrls, + isVersionValid +} from '../../../lib/utils'; import { allow } from '../../middleware'; import { DIST_TAGS, HEADER_TYPE, HEADERS, HTTP_STATUS } from '../../../lib/constants'; import { generateGravatarUrl } from '../../../utils/user'; @@ -104,22 +113,28 @@ function addPackageWebApi(route: Router, storage: IStorageHandler, auth: IAuth, req, callback: function(err: Error, info: $SidebarPackage): void { if (_.isNil(err)) { + const {v} = req.query; let sideBarInfo: any = _.clone(info); sideBarInfo.versions = convertDistRemoteToLocalTarballUrls(info, req, config.url_prefix).versions; - sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest]; - sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author); - sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo); - if (config.web) { - sideBarInfo = addGravatarSupport(sideBarInfo, config.web.gravatar); + if (isVersionValid(info, v)) { + sideBarInfo.latest = sideBarInfo.versions[v]; + sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author); + } else { + sideBarInfo.latest = sideBarInfo.versions[info[DIST_TAGS].latest]; + sideBarInfo.latest.author = formatAuthor(sideBarInfo.latest.author); + } + sideBarInfo = deleteProperties(['readme', '_attachments', '_rev', 'name'], sideBarInfo); + if (config.web) { + sideBarInfo = addGravatarSupport(sideBarInfo, config.web.gravatar); + } else { + sideBarInfo = addGravatarSupport(sideBarInfo); + } + next(sideBarInfo); } else { - sideBarInfo = addGravatarSupport(sideBarInfo); + res.status(HTTP_STATUS.NOT_FOUND); + res.end(); } - next(sideBarInfo); - } else { - res.status(HTTP_STATUS.NOT_FOUND); - res.end(); } - }, }); }); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index eddc1502e..d006c479d 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,7 +1,6 @@ /** * @prettier */ - import _ from 'lodash'; import fs from 'fs'; import assert from 'assert'; @@ -599,3 +598,13 @@ export function encodeScopedUri(packageName) { export function hasDiffOneKey(versions) { return Object.keys(versions).length !== 1; } + +export function isVersionValid(packageMeta, packageVersion): boolean { + const hasVersion = typeof packageVersion !== 'undefined'; + if (!hasVersion) { + return false; + } + + const hasMatchVersion = Object.keys(packageMeta.versions).includes(packageVersion); + return hasMatchVersion; +} diff --git a/test/unit/modules/web/api.web.spec.ts b/test/unit/modules/web/api.web.spec.ts index b902f860d..eb161922c 100644 --- a/test/unit/modules/web/api.web.spec.ts +++ b/test/unit/modules/web/api.web.spec.ts @@ -86,7 +86,7 @@ describe('endpoint web unit test', () => { }); }); - //FIXME: disable, we need to inspect why fails randomly + //FIXME: disabled, we need to inspect why fails randomly test.skip('should display scoped readme 404', (done) => { request(app) .get('/-/verdaccio/package/readme/@scope/404') @@ -115,6 +115,23 @@ describe('endpoint web unit test', () => { }); }); + test('should display sidebar info by version', (done) => { + request(app) + .get('/-/verdaccio/sidebar/@scope/pk1-test?v=1.0.6') + .expect(HTTP_STATUS.OK) + .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) + .end(function(err, res) { + const sideBarInfo = res.body; + const latestVersion = publishMetadata.versions[publishMetadata[DIST_TAGS].latest]; + + expect(sideBarInfo.latest.author).toBeDefined(); + expect(sideBarInfo.latest.author.avatar).toMatch(/www.gravatar.com/); + expect(sideBarInfo.latest.author.name).toBe(latestVersion.author.name); + expect(sideBarInfo.latest.author.email).toBe(latestVersion.author.email); + done(); + }); + }); + test('should display sidebar info 404', (done) => { request(app) .get('/-/verdaccio/sidebar/@scope/404') @@ -124,6 +141,16 @@ describe('endpoint web unit test', () => { done(); }); }); + + test('should display sidebar info 404 with version', (done) => { + request(app) + .get('/-/verdaccio/sidebar/@scope/pk1-test?v=0.0.0-not-found') + .expect(HTTP_STATUS.NOT_FOUND) + .expect(HEADER_TYPE.CONTENT_TYPE, HEADERS.JSON_CHARSET) + .end(function() { + done(); + }); + }); }); describe('Search', () => { diff --git a/yarn.lock b/yarn.lock index 85e319c14a38c6b5e5f69192fa52fb8b01d546a5..dd3fbd3a045a67191050070aff7ea5fb69a83513 100644 GIT binary patch delta 188 zcmWN=Ne;nK007W@!_K-Fu-DI@YFk6oFGvT3mCn?{H}t2h>>Qyda0B5m?t;GLy&lTz zq1>L}YZe~>`o&rYjbg%qqM{aTos(;mFyuju5eov!IuVNEh{ibdAt5niB-Cga!!9Yn zy{622!ryW?_X4S=>|&sH4z=#e9%Fy*9t=CT2FV0xmqR2L=VeBxiK#krMvubHhHX6^ i@AOPMQgdv5v=Q8sWIs4T>;B`QTq#$}wfB$L-^L$d?LXZB delta 193 zcmdnCRBYQ)v4$;-|2$cY^o*6J`}H#0PmgzEF%DA=i#61WbWmf;*y?Y5}0U|8|YaTl%Jz-?Cz785#gKW oAE9kl8WgEt8SIpj6O?ae>Dd0?ixG&KfS4JGS+@W8V%_cz05OC>O8@`>