From a583ca71057a31eb3e4dfa4c648449705d156343 Mon Sep 17 00:00:00 2001 From: "Eray Erdin (&mut self)" Date: Sun, 4 Aug 2024 23:25:25 +0300 Subject: [PATCH] [Crates] Implement Dependents Badge (#10438) * add dependents service * remove redundant timeout --- services/crates/crates-dependents.service.js | 49 ++++++++++++++++++++ services/crates/crates-dependents.tester.js | 15 ++++++ 2 files changed, 64 insertions(+) create mode 100644 services/crates/crates-dependents.service.js create mode 100644 services/crates/crates-dependents.tester.js diff --git a/services/crates/crates-dependents.service.js b/services/crates/crates-dependents.service.js new file mode 100644 index 0000000000000..dbbfc09392d90 --- /dev/null +++ b/services/crates/crates-dependents.service.js @@ -0,0 +1,49 @@ +import Joi from 'joi' +import { pathParams } from '../index.js' +import { metric } from '../text-formatters.js' +import { nonNegativeInteger } from '../validators.js' +import { BaseCratesService, description } from './crates-base.js' + +const dependentsResponseSchema = Joi.object({ + meta: Joi.object({ + total: nonNegativeInteger, + }).required(), +}).required() + +export default class CratesDependents extends BaseCratesService { + static category = 'other' + static route = { base: 'crates/dependents', pattern: ':crate' } + + static openApi = { + '/crates/dependents/{crate}': { + get: { + summary: 'Crates.io Dependents', + description, + parameters: pathParams({ + name: 'crate', + example: 'tokio', + }), + }, + }, + } + + static render({ dependentCount }) { + return { + label: 'dependents', + message: metric(dependentCount), + color: dependentCount === 0 ? 'orange' : 'brightgreen', + } + } + + async fetch({ crate }) { + const url = `https://crates.io/api/v1/crates/${crate}/reverse_dependencies` + const schema = dependentsResponseSchema + return this._requestJson({ schema, url }) + } + + async handle({ crate }) { + const json = await this.fetch({ crate }) + const { total: dependentCount } = json.meta + return this.constructor.render({ dependentCount }) + } +} diff --git a/services/crates/crates-dependents.tester.js b/services/crates/crates-dependents.tester.js new file mode 100644 index 0000000000000..32109d92dba11 --- /dev/null +++ b/services/crates/crates-dependents.tester.js @@ -0,0 +1,15 @@ +import { isMetric } from '../test-validators.js' +import { createServiceTester } from '../tester.js' +export const t = await createServiceTester() + +t.create('dependent count').get('/tokio.json').expectBadge({ + label: 'dependents', + message: isMetric, +}) + +t.create('dependent count (nonexistent package)') + .get('/foobar-is-not-crate.json') + .expectBadge({ + label: 'crates.io', + message: 'not found', + })