Add badge for dependents and dependent repos using Libraries.io (#1895)
See #1845
This commit is contained in:
@@ -15,7 +15,7 @@ class BaseJsonService extends BaseService {
|
||||
})
|
||||
if (error) {
|
||||
this.logTrace(
|
||||
'error',
|
||||
'validate',
|
||||
emojic.womanShrugging,
|
||||
'Response did not match schema',
|
||||
error.message
|
||||
|
||||
49
services/librariesio/librariesio-base.js
Normal file
49
services/librariesio/librariesio-base.js
Normal file
@@ -0,0 +1,49 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const BaseJsonService = require('../base-json')
|
||||
const { InvalidResponse } = require('../errors')
|
||||
const { nonNegativeInteger } = require('../validators')
|
||||
|
||||
// API doc: https://libraries.io/api#project
|
||||
// We distinguishb between packages and repos based on the presence of the
|
||||
// `platform` key.
|
||||
const packageSchema = Joi.object({
|
||||
platform: Joi.string().required(),
|
||||
dependents_count: nonNegativeInteger,
|
||||
dependent_repos_count: nonNegativeInteger,
|
||||
}).required()
|
||||
|
||||
const repoSchema = Joi.object({
|
||||
platform: Joi.any().forbidden(),
|
||||
}).required()
|
||||
|
||||
const packageOrRepoSchema = Joi.alternatives(repoSchema, packageSchema)
|
||||
|
||||
class LibrariesIoBase extends BaseJsonService {
|
||||
static buildUrl(base) {
|
||||
return {
|
||||
base,
|
||||
format: '(\\w+)/(.+)',
|
||||
capture: ['platform', 'packageName'],
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ platform, packageName }, { allowPackages, allowRepos } = {}) {
|
||||
const json = await this._requestJson({
|
||||
schema: packageOrRepoSchema,
|
||||
url: `https://libraries.io/api/${platform}/${packageName}`,
|
||||
notFoundMessage: 'package not found',
|
||||
})
|
||||
const isPackage = Boolean(json.platform)
|
||||
if (isPackage && !allowPackages) {
|
||||
throw new InvalidResponse({ prettyMessage: 'not supported for packages' })
|
||||
}
|
||||
if (!isPackage && !allowRepos) {
|
||||
throw new InvalidResponse({ prettyMessage: 'not supported for repos' })
|
||||
}
|
||||
return json
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LibrariesIoBase
|
||||
50
services/librariesio/librariesio-dependent-repos.service.js
Normal file
50
services/librariesio/librariesio-dependent-repos.service.js
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict'
|
||||
|
||||
const { metric } = require('../../lib/text-formatters')
|
||||
const LibrariesIoBase = require('./librariesio-base')
|
||||
|
||||
// https://libraries.io/api#project-dependent-repositories
|
||||
class LibrariesIoDependentRepos extends LibrariesIoBase {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'dependent repos',
|
||||
}
|
||||
}
|
||||
|
||||
static get url() {
|
||||
return this.buildUrl('librariesio/dependent-repos')
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Dependent repos (via libraries.io)',
|
||||
previewUrl: 'npm/got',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static render({ dependentReposCount }) {
|
||||
return {
|
||||
message: metric(dependentReposCount),
|
||||
color: dependentReposCount === 0 ? 'orange' : 'brightgreen',
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ platform, packageName }) {
|
||||
const { dependent_repos_count: dependentReposCount } = await this.fetch(
|
||||
{
|
||||
platform,
|
||||
packageName,
|
||||
},
|
||||
{ allowPackages: true }
|
||||
)
|
||||
return this.constructor.render({ dependentReposCount })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LibrariesIoDependentRepos
|
||||
29
services/librariesio/librariesio-dependent-repos.tester.js
Normal file
29
services/librariesio/librariesio-dependent-repos.tester.js
Normal file
@@ -0,0 +1,29 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const ServiceTester = require('../service-tester')
|
||||
const { isMetric } = require('../test-validators')
|
||||
|
||||
const t = new ServiceTester({
|
||||
id: 'librariesio-dependent-repos',
|
||||
title: 'Libraries.io dependent repos',
|
||||
pathPrefix: '/librariesio/dependent-repos',
|
||||
})
|
||||
module.exports = t
|
||||
|
||||
t.create('dependent repo count')
|
||||
.get('/npm/got.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'dependent repos',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('dependent repo count (not a package)')
|
||||
.get('/npm/foobar-is-not-package.json')
|
||||
.timeout(10000)
|
||||
.expectJSON({
|
||||
name: 'dependent repos',
|
||||
value: 'package not found',
|
||||
})
|
||||
50
services/librariesio/librariesio-dependents.service.js
Normal file
50
services/librariesio/librariesio-dependents.service.js
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict'
|
||||
|
||||
const { metric } = require('../../lib/text-formatters')
|
||||
const LibrariesIoBase = require('./librariesio-base')
|
||||
|
||||
// https://libraries.io/api#project-dependents
|
||||
class LibrariesIoDependents extends LibrariesIoBase {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'dependents',
|
||||
}
|
||||
}
|
||||
|
||||
static get url() {
|
||||
return this.buildUrl('librariesio/dependents')
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Dependents (via libraries.io)',
|
||||
previewUrl: 'npm/got',
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static render({ dependentCount }) {
|
||||
return {
|
||||
message: metric(dependentCount),
|
||||
color: dependentCount === 0 ? 'orange' : 'brightgreen',
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ platform, packageName }) {
|
||||
const { dependents_count: dependentCount } = await this.fetch(
|
||||
{
|
||||
platform,
|
||||
packageName,
|
||||
},
|
||||
{ allowPackages: true }
|
||||
)
|
||||
return this.constructor.render({ dependentCount })
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = LibrariesIoDependents
|
||||
36
services/librariesio/librariesio-dependents.tester.js
Normal file
36
services/librariesio/librariesio-dependents.tester.js
Normal file
@@ -0,0 +1,36 @@
|
||||
'use strict'
|
||||
|
||||
const Joi = require('joi')
|
||||
const ServiceTester = require('../service-tester')
|
||||
const { isMetric } = require('../test-validators')
|
||||
|
||||
const t = new ServiceTester({
|
||||
id: 'librariesio-dependents',
|
||||
title: 'Libraries.io dependents',
|
||||
pathPrefix: '/librariesio/dependents',
|
||||
})
|
||||
module.exports = t
|
||||
|
||||
t.create('dependent count')
|
||||
.get('/npm/got.json')
|
||||
.expectJSONTypes(
|
||||
Joi.object().keys({
|
||||
name: 'dependents',
|
||||
value: isMetric,
|
||||
})
|
||||
)
|
||||
|
||||
t.create('dependent count (nonexistent package)')
|
||||
.get('/npm/foobar-is-not-package.json')
|
||||
.timeout(10000)
|
||||
.expectJSON({
|
||||
name: 'dependents',
|
||||
value: 'package not found',
|
||||
})
|
||||
|
||||
t.create('dependent count (repo)')
|
||||
.get('/github/sindresorhus/got.json')
|
||||
.expectJSON({
|
||||
name: 'dependents',
|
||||
value: 'not supported for repos',
|
||||
})
|
||||
@@ -22,7 +22,7 @@ const schema = Joi.object({
|
||||
// Abstract class for NPM badges which display data about the latest version
|
||||
// of a package.
|
||||
module.exports = class NpmBase extends BaseJsonService {
|
||||
static buildUrl(base, { withTag }) {
|
||||
static buildUrl(base, { withTag } = {}) {
|
||||
if (withTag) {
|
||||
return {
|
||||
base,
|
||||
|
||||
Reference in New Issue
Block a user