Files
shields/services/docker/docker-size.service.js
chris48s 13d75e0607 upgrade to prettier 2 (#5051)
* arrowParens: avoid
* remove trailingComma setting
2020-05-05 21:07:43 +01:00

133 lines
3.4 KiB
JavaScript

'use strict'
const Joi = require('@hapi/joi')
const prettyBytes = require('pretty-bytes')
const { nonNegativeInteger } = require('../validators')
const { latest } = require('../version')
const { BaseJsonService, NotFound } = require('..')
const {
buildDockerUrl,
getDockerHubUser,
getMultiPageData,
} = require('./docker-helpers')
const buildSchema = Joi.object({
name: Joi.string().required(),
full_size: nonNegativeInteger.required(),
}).required()
const pagedSchema = Joi.object({
count: nonNegativeInteger.required(),
results: Joi.array().items(
Joi.object({
name: Joi.string().required(),
full_size: nonNegativeInteger.required(),
})
),
}).required()
const queryParamSchema = Joi.object({
sort: Joi.string().valid('date', 'semver').default('date'),
}).required()
module.exports = class DockerSize extends BaseJsonService {
static get category() {
return 'size'
}
static get route() {
return { ...buildDockerUrl('image-size', true), queryParamSchema }
}
static get examples() {
return [
{
title: 'Docker Image Size (latest by date)',
pattern: ':user/:repo',
namedParams: { user: 'fedora', repo: 'apache' },
queryParams: { sort: 'date' },
staticPreview: this.render({ size: 126000000 }),
},
{
title: 'Docker Image Size (latest semver)',
pattern: ':user/:repo',
namedParams: { user: 'fedora', repo: 'apache' },
queryParams: { sort: 'semver' },
staticPreview: this.render({ size: 136000000 }),
},
{
title: 'Docker Image Size (tag)',
pattern: ':user/:repo/:tag',
namedParams: { user: 'fedora', repo: 'apache', tag: 'latest' },
staticPreview: this.render({ size: 103000000 }),
},
]
}
static get defaultBadgeData() {
return {
label: 'image size',
color: 'blue',
}
}
static render({ size }) {
return { message: prettyBytes(size) }
}
async fetch({ user, repo, tag, page }) {
page = page ? `&page=${page}` : ''
return this._requestJson({
schema: tag ? buildSchema : pagedSchema,
url: `https://registry.hub.docker.com/v2/repositories/${getDockerHubUser(
user
)}/${repo}/tags${
tag ? `/${tag}` : '?page_size=100&ordering=last_updated'
}${page}`,
errorMessages: { 404: 'repository or tag not found' },
})
}
transform({ tag, sort, data }) {
if (!tag && sort === 'date') {
if (data.count === 0) {
throw new NotFound({ prettyMessage: 'repository not found' })
} else {
return { size: data.results[0].full_size }
}
} else if (!tag && sort === 'semver') {
const [matches, versions] = data.reduce(
([m, v], d) => {
m[d.name] = d.full_size
v.push(d.name)
return [m, v]
},
[{}, []]
)
const version = latest(versions)
return { size: matches[version] }
} else {
return { size: data.full_size }
}
}
async handle({ user, repo, tag }, { sort }) {
let data
if (!tag && sort === 'date') {
data = await this.fetch({ user, repo })
} else if (!tag && sort === 'semver') {
data = await getMultiPageData({
user,
repo,
fetch: this.fetch.bind(this),
})
} else {
data = await this.fetch({ user, repo, tag })
}
const { size } = await this.transform({ tag, sort, data })
return this.constructor.render({ size })
}
}