diff --git a/services/pypi/pypi-types.service.js b/services/pypi/pypi-types.service.js new file mode 100644 index 0000000000..b0e38ab328 --- /dev/null +++ b/services/pypi/pypi-types.service.js @@ -0,0 +1,40 @@ +import PypiBase, { pypiGeneralParams } from './pypi-base.js' + +export default class PypiTypes extends PypiBase { + static category = 'platform-support' + + static route = this.buildRoute('pypi/types') + + static openApi = { + '/pypi/types/{packageName}': { + get: { + summary: 'PyPI - Types', + description: + 'Whether the package provides type information, as indicated by the presence of the Typing :: Typed classifier in the package metadata', + parameters: pypiGeneralParams, + }, + }, + } + + static defaultBadgeData = { label: 'types' } + + static render({ isTyped }) { + if (isTyped) { + return { + message: 'typed', + color: 'brightgreen', + } + } else { + return { + message: 'untyped', + color: 'red', + } + } + } + + async handle({ egg }, { pypiBaseUrl }) { + const packageData = await this.fetch({ egg, pypiBaseUrl }) + const isTyped = packageData.info.classifiers.includes('Typing :: Typed') + return this.constructor.render({ isTyped }) + } +} diff --git a/services/pypi/pypi-types.tester.js b/services/pypi/pypi-types.tester.js new file mode 100644 index 0000000000..369596d2d6 --- /dev/null +++ b/services/pypi/pypi-types.tester.js @@ -0,0 +1,14 @@ +import { createServiceTester } from '../tester.js' +export const t = await createServiceTester() + +t.create('types (yes)') + .get('/pyre-check.json') + .expectBadge({ label: 'types', message: 'typed' }) + +t.create('types (no)') + .get('/z3-solver.json') + .expectBadge({ label: 'types', message: 'untyped' }) + +t.create('types (invalid)') + .get('/not-a-package.json') + .expectBadge({ label: 'types', message: 'package or version not found' })