diff --git a/services/gitlab/gitlab-stars.service.js b/services/gitlab/gitlab-stars.service.js new file mode 100644 index 0000000000000000000000000000000000000000..a440c814f34a12a5de34788f0eac517d86947228 --- /dev/null +++ b/services/gitlab/gitlab-stars.service.js @@ -0,0 +1,74 @@ +import Joi from 'joi' +import { optionalUrl, nonNegativeInteger } from '../validators.js' +import { metric } from '../text-formatters.js' +import GitLabBase from './gitlab-base.js' + +const schema = Joi.object({ + star_count: nonNegativeInteger, +}).required() + +const queryParamSchema = Joi.object({ + gitlab_url: optionalUrl, +}).required() + +const documentation = ` +<p> + You may use your GitLab Project Id (e.g. 278964) or your Project Path (e.g. gitlab-org/gitlab ). + Note that only internet-accessible GitLab instances are supported, for example https://jihulab.com, https://gitlab.gnome.org, or https://gitlab.com/. +</p> +` + +export default class GitlabStars extends GitLabBase { + static category = 'social' + + static route = { + base: 'gitlab/stars', + pattern: ':project+', + queryParamSchema, + } + + static examples = [ + { + title: 'GitLab stars', + namedParams: { + project: 'gitlab-org/gitlab', + }, + queryParams: { gitlab_url: 'https://gitlab.com' }, + staticPreview: { + label: 'stars', + message: '3.9k', + style: 'social', + }, + documentation, + }, + ] + + static defaultBadgeData = { label: 'stars', namedLogo: 'gitlab' } + + static render({ baseUrl, project, starCount }) { + return { + message: metric(starCount), + color: 'blue', + link: [`${baseUrl}/${project}`, `${baseUrl}/${project}/-/starrers`], + } + } + + async fetch({ project, baseUrl }) { + // https://docs.gitlab.com/ee/api/projects.html#get-single-project + return super.fetch({ + schema, + url: `${baseUrl}/api/v4/projects/${encodeURIComponent(project)}`, + errorMessages: { + 404: 'project not found', + }, + }) + } + + async handle({ project }, { gitlab_url: baseUrl = 'https://gitlab.com' }) { + const { star_count: starCount } = await this.fetch({ + project, + baseUrl, + }) + return this.constructor.render({ baseUrl, project, starCount }) + } +} diff --git a/services/gitlab/gitlab-stars.tester.js b/services/gitlab/gitlab-stars.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..11fc18aa6f49cb223d43e3750c959eaec2459db6 --- /dev/null +++ b/services/gitlab/gitlab-stars.tester.js @@ -0,0 +1,35 @@ +import { isMetric } from '../test-validators.js' +import { createServiceTester } from '../tester.js' + +export const t = await createServiceTester() + +t.create('Stars') + .get('/gitlab-org/gitlab.json') + .expectBadge({ + label: 'stars', + message: isMetric, + color: 'blue', + link: [ + 'https://gitlab.com/gitlab-org/gitlab', + 'https://gitlab.com/gitlab-org/gitlab/-/starrers', + ], + }) + +t.create('Stars (self-managed)') + .get('/gitlab-cn/gitlab.json?gitlab_url=https://jihulab.com') + .expectBadge({ + label: 'stars', + message: isMetric, + color: 'blue', + link: [ + 'https://jihulab.com/gitlab-cn/gitlab', + 'https://jihulab.com/gitlab-cn/gitlab/-/starrers', + ], + }) + +t.create('Stars (project not found)') + .get('/user1/gitlab-does-not-have-this-repo.json') + .expectBadge({ + label: 'stars', + message: 'project not found', + })