Files
shields/services/github/github-downloads.service.js
dependabot-preview[bot] ee83590942 Build(deps-dev): bump @typescript-eslint/eslint-plugin from 2.34.0 to 4.19.0, run [GitHub GitlabCoverage F-Droid Wordpress VisualStudioAppCenter Ore Packagist] (#6319)
* Build(deps-dev): bump @typescript-eslint/eslint-plugin

Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 2.34.0 to 4.19.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v4.19.0/packages/eslint-plugin)

Signed-off-by: dependabot-preview[bot] <support@dependabot.com>

* chore: update eslint camelcase rule

* chore: eslint camelcase updates for wordpress

* chore: fix eslint camelcase for misc other services

* chore: fix eslint camelcase issue in github and gitlab

* chore: run prettier

* chore: account for JSX globals

* deps: bump typescript-eslint-parser to v4

* chore: frontend lint changes

* chore: update eslint config to only run @typescript-eslint/explicit-module-boundary-types on ts files

Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>
Co-authored-by: Caleb Cartwright <caleb.cartwright@outlook.com>
2021-03-28 08:26:01 -05:00

269 lines
7.1 KiB
JavaScript

'use strict'
const Joi = require('joi')
const { metric } = require('../text-formatters')
const { nonNegativeInteger } = require('../validators')
const { downloadCount: downloadCountColor } = require('../color-formatters')
const { NotFound } = require('..')
const { GithubAuthV3Service } = require('./github-auth-service')
const { fetchLatestRelease } = require('./github-common-release')
const { documentation, errorMessagesFor } = require('./github-helpers')
const queryParamSchema = Joi.object({
sort: Joi.string().valid('date', 'semver').default('date'),
}).required()
const releaseSchema = Joi.object({
assets: Joi.array()
.items({
name: Joi.string().required(),
download_count: nonNegativeInteger,
})
.required(),
}).required()
const releaseArraySchema = Joi.alternatives().try(
Joi.array().items(releaseSchema),
Joi.array().length(0)
)
module.exports = class GithubDownloads extends GithubAuthV3Service {
static category = 'downloads'
static route = {
base: 'github',
pattern: ':kind(downloads|downloads-pre)/:user/:repo/:tag*/:assetName',
queryParamSchema,
}
static examples = [
{
title: 'GitHub all releases',
pattern: 'downloads/:user/:repo/total',
namedParams: {
user: 'atom',
repo: 'atom',
},
staticPreview: this.render({
assetName: 'total',
downloadCount: 857000,
}),
documentation,
},
{
title: 'GitHub release (latest by date)',
pattern: 'downloads/:user/:repo/:tag/total',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
},
staticPreview: this.render({
tag: 'latest',
assetName: 'total',
downloadCount: 27000,
}),
documentation,
},
{
title: 'GitHub release (latest by SemVer)',
pattern: 'downloads/:user/:repo/:tag/total',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
},
queryParams: { sort: 'semver' },
staticPreview: this.render({
tag: 'latest',
assetName: 'total',
downloadCount: 27000,
}),
documentation,
},
{
title: 'GitHub release (latest by date including pre-releases)',
pattern: 'downloads-pre/:user/:repo/:tag/total',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
},
staticPreview: this.render({
tag: 'latest',
assetName: 'total',
downloadCount: 2000,
}),
documentation,
},
{
title: 'GitHub release (latest by SemVer including pre-releases)',
pattern: 'downloads-pre/:user/:repo/:tag/total',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
},
queryParams: { sort: 'semver' },
staticPreview: this.render({
tag: 'latest',
assetName: 'total',
downloadCount: 2000,
}),
documentation,
},
{
title: 'GitHub release (by tag)',
pattern: 'downloads/:user/:repo/:tag/total',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'v0.190.0',
},
staticPreview: this.render({
tag: 'v0.190.0',
assetName: 'total',
downloadCount: 490000,
}),
documentation,
},
{
title: 'GitHub release (latest by date and asset)',
pattern: 'downloads/:user/:repo/:tag/:assetName',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
assetName: 'atom-amd64.deb',
},
staticPreview: this.render({
tag: 'latest',
assetName: 'atom-amd64.deb',
downloadCount: 3000,
}),
documentation,
},
{
title: 'GitHub release (latest by SemVer and asset)',
pattern: 'downloads/:user/:repo/:tag/:assetName',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
assetName: 'atom-amd64.deb',
},
queryParams: { sort: 'semver' },
staticPreview: this.render({
tag: 'latest',
assetName: 'atom-amd64.deb',
downloadCount: 3000,
}),
documentation,
},
{
title: 'GitHub release (latest by date and asset including pre-releases)',
pattern: 'downloads-pre/:user/:repo/:tag/:assetName',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
assetName: 'atom-amd64.deb',
},
staticPreview: this.render({
tag: 'latest',
assetName: 'atom-amd64.deb',
downloadCount: 237,
}),
documentation,
},
{
title:
'GitHub release (latest by SemVer and asset including pre-releases)',
pattern: 'downloads-pre/:user/:repo/:tag/:assetName',
namedParams: {
user: 'atom',
repo: 'atom',
tag: 'latest',
assetName: 'atom-amd64.deb',
},
queryParams: { sort: 'semver' },
staticPreview: this.render({
tag: 'latest',
assetName: 'atom-amd64.deb',
downloadCount: 237,
}),
documentation,
},
]
static defaultBadgeData = { label: 'downloads', namedLogo: 'github' }
static render({ tag, assetName, downloadCount }) {
return {
label: tag ? `downloads@${tag}` : 'downloads',
message:
assetName === 'total'
? metric(downloadCount)
: `${metric(downloadCount)} [${assetName}]`,
color: downloadCountColor(downloadCount),
}
}
static transform({ releases, assetName }) {
const downloadCount = releases.reduce((accum1, { assets }) => {
const filteredAssets =
assetName === 'total'
? assets
: assets.filter(
({ name }) => name.toLowerCase() === assetName.toLowerCase()
)
return (
accum1 +
filteredAssets.reduce(
(accum2, { download_count: downloadCount }) => accum2 + downloadCount,
0
)
)
}, 0)
return { downloadCount }
}
async handle({ kind, user, repo, tag, assetName }, { sort }) {
let releases
if (tag === 'latest') {
const includePre = kind === 'downloads-pre' || undefined
const latestRelease = await fetchLatestRelease(
this,
{ user, repo },
{ sort, include_prereleases: includePre }
)
releases = [latestRelease]
} else if (tag) {
const wantedRelease = await this._requestJson({
schema: releaseSchema,
url: `/repos/${user}/${repo}/releases/tags/${tag}`,
errorMessages: errorMessagesFor('repo or release not found'),
})
releases = [wantedRelease]
} else {
const allReleases = await this._requestJson({
schema: releaseArraySchema,
url: `/repos/${user}/${repo}/releases`,
options: { qs: { per_page: 500 } },
errorMessages: errorMessagesFor('repo not found'),
})
releases = allReleases
}
if (releases.length === 0) {
throw new NotFound({ prettyMessage: 'no releases' })
}
const { downloadCount } = this.constructor.transform({
releases,
assetName,
})
return this.constructor.render({ tag, assetName, downloadCount })
}
}