Files
shields/services/hexpm/hexpm.service.js
Paul Melnikow 226fa67a02 Create shortcut for BaseService-related imports (#2809)
Continue to implement #2698:

- Add `core/base-service/index.js` (but hold off on moving the things it imports)
- Add shortcuts in `services/index.js` for Base*Service, errors, and deprecatedService. This file will be streamlined later to avoid cluttering it with rarely used bits.
- Apply consistent ordering of imports and use of `module.exports` in testers.
- Remove some renaming of imports.
- Remove obsolete tests here and there.
2019-01-21 15:41:24 -05:00

183 lines
3.8 KiB
JavaScript

'use strict'
const Joi = require('joi')
const { metric, addv, maybePluralize } = require('../../lib/text-formatters')
const {
downloadCount,
version: versionColor,
} = require('../../lib/color-formatters')
const { BaseJsonService } = require('..')
const hexSchema = Joi.object({
downloads: Joi.object({
// these keys may or may not exist
all: Joi.number()
.integer()
.default(0),
week: Joi.number()
.integer()
.default(0),
day: Joi.number()
.integer()
.default(0),
}).required(),
meta: Joi.object({
licenses: Joi.array().required(),
}).required(),
releases: Joi.array()
.items(Joi.object({ version: Joi.string().required() }).required())
.required(),
}).required()
class BaseHexPmService extends BaseJsonService {
async fetch({ packageName }) {
return this._requestJson({
schema: hexSchema,
url: `https://hex.pm/api/packages/${packageName}`,
})
}
static get defaultBadgeData() {
return { label: 'hex' }
}
}
class HexPmLicense extends BaseHexPmService {
static render({ licenses }) {
if (licenses.length === 0) {
return {
label: 'license',
message: 'Unknown',
color: 'lightgrey',
}
}
return {
label: maybePluralize('license', licenses),
message: licenses.join(', '),
color: 'blue',
}
}
async handle({ packageName }) {
const json = await this.fetch({ packageName })
return this.constructor.render({ licenses: json.meta.licenses })
}
static get defaultBadgeData() {
return { label: 'license' }
}
static get category() {
return 'license'
}
static get route() {
return {
base: 'hexpm/l',
pattern: ':packageName',
}
}
static get examples() {
return [
{
title: 'Hex.pm',
namedParams: { packageName: 'plug' },
staticPreview: this.render({ licenses: ['Apache 2'] }),
},
]
}
}
class HexPmVersion extends BaseHexPmService {
static render({ version }) {
return { message: addv(version), color: versionColor(version) }
}
async handle({ packageName }) {
const json = await this.fetch({ packageName })
return this.constructor.render({ version: json.releases[0].version })
}
static get category() {
return 'version'
}
static get route() {
return {
base: 'hexpm/v',
pattern: ':packageName',
}
}
static get examples() {
return [
{
title: 'Hex.pm',
namedParams: { packageName: 'plug' },
staticPreview: this.render({ version: '1.6.4' }),
},
]
}
}
function DownloadsForInterval(interval) {
const { base, messageSuffix } = {
day: {
base: 'hexpm/dd',
messageSuffix: '/day',
},
week: {
base: 'hexpm/dw',
messageSuffix: '/week',
},
all: {
base: 'hexpm/dt',
messageSuffix: '',
},
}[interval]
return class HexPmDownloads extends BaseHexPmService {
static render({ downloads }) {
return {
message: `${metric(downloads)}${messageSuffix}`,
color: downloadCount(downloads),
}
}
async handle({ packageName }) {
const json = await this.fetch({ packageName })
return this.constructor.render({ downloads: json.downloads[interval] })
}
static get defaultBadgeData() {
return { label: 'downloads' }
}
static get category() {
return 'downloads'
}
static get route() {
return {
base,
pattern: ':packageName',
}
}
static get examples() {
return [
{
title: 'Hex.pm',
namedParams: { packageName: 'plug' },
staticPreview: this.render({ downloads: 85000 }),
},
]
}
}
}
const downloadsServices = ['day', 'week', 'all'].map(DownloadsForInterval)
module.exports = [...downloadsServices, HexPmLicense, HexPmVersion]