diff --git a/services/homebrew/homebrew-cask-downloads.service.js b/services/homebrew/homebrew-cask-downloads.service.js new file mode 100644 index 0000000000..7b11aea067 --- /dev/null +++ b/services/homebrew/homebrew-cask-downloads.service.js @@ -0,0 +1,82 @@ +import Joi from 'joi' +import { renderDownloadsBadge } from '../downloads.js' +import { BaseJsonService, pathParams } from '../index.js' +import { nonNegativeInteger } from '../validators.js' + +function getSchema({ cask }) { + return Joi.object({ + analytics: Joi.object({ + install: Joi.object({ + '30d': Joi.object({ [cask]: nonNegativeInteger }).required(), + '90d': Joi.object({ [cask]: nonNegativeInteger }).required(), + '365d': Joi.object({ [cask]: nonNegativeInteger }).required(), + }).required(), + }).required(), + }).required() +} + +const periodMap = { + dm: { + api_field: '30d', + interval: 'month', + }, + dq: { + api_field: '90d', + interval: 'quarter', + }, + dy: { + api_field: '365d', + interval: 'year', + }, +} + +export default class HomebrewCaskDownloads extends BaseJsonService { + static category = 'downloads' + + static route = { + base: 'homebrew/cask/installs', + pattern: ':interval(dm|dq|dy)/:cask', + } + + static openApi = { + '/homebrew/cask/installs/{interval}/{cask}': { + get: { + summary: 'Homebrew Cask Downloads', + parameters: pathParams( + { + name: 'interval', + example: 'dm', + schema: { type: 'string', enum: this.getEnum('interval') }, + description: 'Monthly, Quarterly or Yearly downloads', + }, + { + name: 'cask', + example: 'freetube', + }, + ), + }, + }, + } + + static defaultBadgeData = { label: 'downloads' } + + async fetch({ cask }) { + const schema = getSchema({ cask }) + return this._requestJson({ + schema, + url: `https://formulae.brew.sh/api/cask/${cask}.json`, + httpErrors: { 404: 'cask not found' }, + }) + } + + async handle({ interval, cask }) { + const { + analytics: { install }, + } = await this.fetch({ cask }) + + return renderDownloadsBadge({ + downloads: install[periodMap[interval].api_field][cask], + interval: periodMap[interval].interval, + }) + } +} diff --git a/services/homebrew/homebrew-cask-downloads.tester.js b/services/homebrew/homebrew-cask-downloads.tester.js new file mode 100644 index 0000000000..57d1ff9636 --- /dev/null +++ b/services/homebrew/homebrew-cask-downloads.tester.js @@ -0,0 +1,28 @@ +import { createServiceTester } from '../tester.js' +import { isMetricOverTimePeriod } from '../test-validators.js' + +export const t = await createServiceTester() + +t.create('daily downloads (valid)') + .get('/dm/freetube.json') + .expectBadge({ label: 'downloads', message: isMetricOverTimePeriod }) + +t.create('yearly downloads (valid)') + .get('/dq/freetube.json') + .expectBadge({ label: 'downloads', message: isMetricOverTimePeriod }) + +t.create('yearly downloads (valid)') + .get('/dy/freetube.json') + .expectBadge({ label: 'downloads', message: isMetricOverTimePeriod }) + +t.create('daily downloads (not found)') + .get('/dm/not-a-package.json') + .expectBadge({ label: 'downloads', message: 'cask not found' }) + +t.create('yearly downloads (not found)') + .get('/dq/not-a-package.json') + .expectBadge({ label: 'downloads', message: 'cask not found' }) + +t.create('yearly downloads (not found)') + .get('/dy/not-a-package.json') + .expectBadge({ label: 'downloads', message: 'cask not found' }) diff --git a/services/homebrew/homebrew-cask.service.js b/services/homebrew/homebrew-cask-version.service.js similarity index 95% rename from services/homebrew/homebrew-cask.service.js rename to services/homebrew/homebrew-cask-version.service.js index 555b6f76f9..8c2e127ae9 100644 --- a/services/homebrew/homebrew-cask.service.js +++ b/services/homebrew/homebrew-cask-version.service.js @@ -13,7 +13,7 @@ export default class HomebrewCask extends BaseJsonService { static openApi = { '/homebrew/cask/v/{cask}': { get: { - summary: 'homebrew cask', + summary: 'Homebrew Cask Version', parameters: pathParams({ name: 'cask', example: 'iterm2', diff --git a/services/homebrew/homebrew-cask.tester.js b/services/homebrew/homebrew-cask-version.tester.js similarity index 100% rename from services/homebrew/homebrew-cask.tester.js rename to services/homebrew/homebrew-cask-version.tester.js diff --git a/services/homebrew/homebrew-downloads.service.js b/services/homebrew/homebrew-formula-downloads.service.js similarity index 97% rename from services/homebrew/homebrew-downloads.service.js rename to services/homebrew/homebrew-formula-downloads.service.js index 1f3ca913e2..37a1e17890 100644 --- a/services/homebrew/homebrew-downloads.service.js +++ b/services/homebrew/homebrew-formula-downloads.service.js @@ -41,7 +41,7 @@ export default class HomebrewDownloads extends BaseJsonService { static openApi = { '/homebrew/installs/{interval}/{formula}': { get: { - summary: 'homebrew downloads', + summary: 'Homebrew Formula Downloads', parameters: pathParams( { name: 'interval', diff --git a/services/homebrew/homebrew-downloads.tester.js b/services/homebrew/homebrew-formula-downloads.tester.js similarity index 100% rename from services/homebrew/homebrew-downloads.tester.js rename to services/homebrew/homebrew-formula-downloads.tester.js diff --git a/services/homebrew/homebrew-version.service.js b/services/homebrew/homebrew-formula-version.service.js similarity index 95% rename from services/homebrew/homebrew-version.service.js rename to services/homebrew/homebrew-formula-version.service.js index ffb4e136a4..283b645de3 100644 --- a/services/homebrew/homebrew-version.service.js +++ b/services/homebrew/homebrew-formula-version.service.js @@ -16,7 +16,7 @@ export default class HomebrewVersion extends BaseJsonService { static openApi = { '/homebrew/v/{formula}': { get: { - summary: 'homebrew version', + summary: 'Homebrew Formula Version', parameters: pathParams({ name: 'formula', example: 'cake', diff --git a/services/homebrew/homebrew-version.tester.js b/services/homebrew/homebrew-formula-version.tester.js similarity index 100% rename from services/homebrew/homebrew-version.tester.js rename to services/homebrew/homebrew-formula-version.tester.js