diff --git a/CHANGELOG.md b/CHANGELOG.md index cc65f09ef..ddc865203 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +## [3.8.2](https://github.com/verdaccio/verdaccio/compare/v3.8.1...v3.8.2) (2018-09-27) + + +### Bug Fixes + +* normalize contributors field [#1022](https://github.com/verdaccio/verdaccio/issues/1022) ([#1024](https://github.com/verdaccio/verdaccio/issues/1024)) ([4deefe7](https://github.com/verdaccio/verdaccio/commit/4deefe7)) + + + ## [3.8.1](https://github.com/verdaccio/verdaccio/compare/v3.8.0...v3.8.1) (2018-09-10) diff --git a/package.json b/package.json index 1aacd1a32..2612feefe 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "verdaccio", - "version": "3.8.1", + "version": "3.8.2", "description": "Private npm repository server", "author": { "name": "Alex Kocharin", @@ -56,7 +56,7 @@ "@commitlint/config-conventional": "7.1.2", "@material-ui/core": "3.1.0", "@material-ui/icons": "3.0.1", - "@verdaccio/types": "3.7.1", + "@verdaccio/types": "3.7.2", "babel-cli": "6.26.0", "babel-core": "6.26.3", "babel-eslint": "10.0.0", diff --git a/src/lib/local-storage.js b/src/lib/local-storage.js index 49289a630..ac5bf45f9 100644 --- a/src/lib/local-storage.js +++ b/src/lib/local-storage.js @@ -8,7 +8,7 @@ import _ from 'lodash'; // $FlowFixMe import {ErrorCode, isObject, getLatestVersion, tagVersion, validateName, DIST_TAGS} from './utils'; import { - generatePackageTemplate, normalizePackage, generateRevision, getLatestReadme, cleanUpReadme, + generatePackageTemplate, normalizePackage, generateRevision, getLatestReadme, cleanUpReadme, normalizeContributors, fileExist, noSuchFile, DEFAULT_REVISION, pkgFileName, } from './storage-utils'; import {createTarballHash} from './crypto-utils'; @@ -138,6 +138,7 @@ class LocalStorage implements IStorage { // we don't keep readmes for package versions, // only one readme per package version = cleanUpReadme(version); + version.contributors = normalizeContributors(version.contributors); change = true; packageLocalJson.versions[versionId] = version; @@ -219,6 +220,7 @@ class LocalStorage implements IStorage { // TODO: lodash remove metadata = cleanUpReadme(metadata); + metadata.contributors = normalizeContributors(metadata.contributors); if (data.versions[version] != null) { return cb( ErrorCode.getConflict() ); diff --git a/src/lib/storage-utils.js b/src/lib/storage-utils.js index 4d20a3a65..715037fb2 100644 --- a/src/lib/storage-utils.js +++ b/src/lib/storage-utils.js @@ -5,7 +5,7 @@ import {ErrorCode, isObject, normalizeDistTags, DIST_TAGS, semverSort} from './u import Search from './search'; import {generateRandomHexString} from '../lib/crypto-utils'; -import type {Package, Version} from '@verdaccio/types'; +import type {Package, Version, Author} from '@verdaccio/types'; import type {IStorage} from '../../types'; import {API_ERROR, HTTP_STATUS} from './constants'; @@ -99,7 +99,15 @@ function cleanUpReadme(version: Version): Version { return version; } -export const WHITELIST = ['_rev', 'name', 'versions', DIST_TAGS, 'readme', 'time']; +export function normalizeContributors(contributors: Array): Array { + if (isObject(contributors) || _.isString(contributors)) { + return [((contributors): any)]; + } + + return contributors; +} + +export const WHITELIST = ['_rev', 'name', 'versions', 'dist-tags', 'readme', 'time']; export function cleanUpLinksRef(keepUpLinkData: boolean, result: Package): Package { const propertyToKeep = [...WHITELIST]; diff --git a/src/lib/utils.js b/src/lib/utils.js index 1bdab933f..909746fce 100644 --- a/src/lib/utils.js +++ b/src/lib/utils.js @@ -17,11 +17,12 @@ import { DEFAULT_PROTOCOL, CHARACTER_ENCODING, HEADERS } from './constants'; -import {generateGravatarUrl} from '../utils/user'; +import {generateGravatarUrl, GRAVATAR_DEFAULT} from '../utils/user'; import type {Package} from '@verdaccio/types'; import type {$Request} from 'express'; import type {StringValue} from '../../types'; +import {normalizeContributors} from './storage-utils'; const Logger = require('./logger'); const pkginfo = require('pkginfo')(module); // eslint-disable-line no-unused-vars @@ -482,7 +483,7 @@ export function deleteProperties(propertiesToDelete: Array, objectItem: export function addGravatarSupport(pkgInfo: Object): Object { const pkgInfoCopy = {...pkgInfo}; const author = _.get(pkgInfo, 'latest.author', null); - const contributors = _.get(pkgInfo, 'latest.contributors', []); + const contributors = normalizeContributors(_.get(pkgInfo, 'latest.contributors', [])); const maintainers = _.get(pkgInfo, 'latest.maintainers', []); // for author. @@ -501,7 +502,17 @@ export function addGravatarSupport(pkgInfo: Object): Object { // for contributors if (_.isEmpty(contributors) === false) { pkgInfoCopy.latest.contributors = contributors.map((contributor) => { - contributor.avatar = generateGravatarUrl(contributor.email); + if (isObject(contributor)) { + // $FlowFixMe + contributor.avatar = generateGravatarUrl(contributor.email); + } else if (_.isString(contributor)) { + contributor = { + avatar: GRAVATAR_DEFAULT, + email: contributor, + name: contributor, + }; + } + return contributor; }); } diff --git a/test/unit/api/utils.spec.js b/test/unit/api/utils.spec.js index 909494828..552966140 100644 --- a/test/unit/api/utils.spec.js +++ b/test/unit/api/utils.spec.js @@ -396,35 +396,82 @@ describe('Utilities', () => { expect(addGravatarSupport(packageInfo)).toEqual(packageInfo); }); - test('contributors field has contributors', () => { - const packageInfo = { - latest: { - contributors: [ - { name: 'user', email: 'user@verdccio.org' }, - { name: 'user1', email: 'user1@verdccio.org' } - ] - } - }; + describe("contributors", () => { + test('contributors field has contributors', () => { + const packageInfo = { + latest: { + contributors: [ + { name: 'user', email: 'user@verdccio.org' }, + { name: 'user1', email: 'user1@verdccio.org' } + ] + } + }; - const result = { - latest: { - contributors: [ - { - avatar: - 'https://www.gravatar.com/avatar/794d7f6ef93d0689437de3c3e48fadc7', - email: 'user@verdccio.org', - name: 'user' - }, - { - avatar: - 'https://www.gravatar.com/avatar/51105a49ce4a9c2bfabf0f6a2cba3762', - email: 'user1@verdccio.org', - name: 'user1' - } - ] - } - }; - expect(addGravatarSupport(packageInfo)).toEqual(result); + const result = { + latest: { + contributors: [ + { + avatar: + 'https://www.gravatar.com/avatar/794d7f6ef93d0689437de3c3e48fadc7', + email: 'user@verdccio.org', + name: 'user' + }, + { + avatar: + 'https://www.gravatar.com/avatar/51105a49ce4a9c2bfabf0f6a2cba3762', + email: 'user1@verdccio.org', + name: 'user1' + } + ] + } + }; + expect(addGravatarSupport(packageInfo)).toEqual(result); + }); + + test('contributors field is an object', () => { + const packageInfo = { + latest: { + contributors: { name: 'user', email: 'user@verdccio.org' } + } + }; + + const result = { + latest: { + contributors: [ + { + avatar: 'https://www.gravatar.com/avatar/794d7f6ef93d0689437de3c3e48fadc7', + email: 'user@verdccio.org', + name: 'user' + } + ] + } + }; + + expect(addGravatarSupport(packageInfo)).toEqual(result); + }); + + test('contributors field is a string', () => { + const contributor: string = 'Barney Rubble (http://barnyrubble.tumblr.com/)'; + const packageInfo = { + latest: { + contributors: contributor + } + }; + + const result = { + latest: { + contributors: [ + { + avatar: GRAVATAR_DEFAULT, + email: contributor, + name: contributor + } + ] + } + }; + + expect(addGravatarSupport(packageInfo)).toEqual(result); + }); }); test('maintainers field is a blank array', () => { diff --git a/website/siteConfig.js b/website/siteConfig.js index 72c24b823..83193ce75 100644 --- a/website/siteConfig.js +++ b/website/siteConfig.js @@ -56,7 +56,7 @@ const users = [ const siteConfig = { title: 'Verdaccio' /* title for your website */, - tagline: 'Verdaccio ยท A lightweight private npm proxy registry', + tagline: 'A lightweight private npm proxy registry', url: 'https://verdaccio.org' /* your website url */, organizationName: 'verdaccio', cname: 'verdaccio.org',