Files
shields/services/freecodecamp/freecodecamp-points.service.js
T
chris48sGitHubrepo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
c73072deed Remove requestOptions2GotOptions compatibility layer (#7270)
* gzip --> decompress

* strictSSL --> https.rejectUnauthorized

* auth --> username/password

* qs --> searchParams

* fix base service auth docs

* completely remove requestOptions2GotOptions layer

* update the docs

Co-authored-by: repo-ranger[bot] <39074581+repo-ranger[bot]@users.noreply.github.com>
2021-11-15 19:56:08 +00:00

77 lines
1.9 KiB
JavaScript

import Joi from 'joi'
import { metric } from '../text-formatters.js'
import { BaseJsonService, InvalidResponse, NotFound } from '../index.js'
/**
* Validates that the schema response is what we're expecting.
* The username pattern should match the freeCodeCamp repository.
*
* @see https://github.com/freeCodeCamp/freeCodeCamp/blob/main/utils/validate.js#L14
*/
const schema = Joi.object({
entities: Joi.object({
user: Joi.object()
.required()
.pattern(/^[a-zA-Z0-9\-_+]*$/, {
points: Joi.number().allow(null).required(),
}),
}).optional(),
}).required()
/**
* This badge displays the total number of points a student has accumulated
* from completing challenges on freeCodeCamp.
*/
export default class FreeCodeCampPoints extends BaseJsonService {
static category = 'other'
static route = {
base: 'freecodecamp/points',
pattern: ':username',
}
static examples = [
{
title: 'freeCodeCamp points',
namedParams: { username: 'sethi' },
staticPreview: this.render({ points: 934 }),
},
]
static defaultBadgeData = { label: 'points', color: 'info' }
static render({ points }) {
return { message: metric(points) }
}
async fetch({ username }) {
return this._requestJson({
schema,
url: `https://api.freecodecamp.org/api/users/get-public-profile`,
options: {
searchParams: {
username,
},
},
})
}
static transform(response, username) {
const { entities } = response
if (entities === undefined)
throw new NotFound({ prettyMessage: 'profile not found' })
const { points } = entities.user[username]
if (points === null) throw new InvalidResponse({ prettyMessage: 'private' })
return points
}
async handle({ username }) {
const response = await this.fetch({ username })
const points = this.constructor.transform(response, username)
return this.constructor.render({ points })
}
}