Unify order of properties and methods in services (#3353)
I find having these in a consistent order makes the services much faster to read. This is the order I’ve generally been using: 1. Category 2. Route 3. Examples 4. Rendering 5. Other helpers (`fetch()`, `transform()`) 6. `handle()`
This commit is contained in:
@@ -12,15 +12,40 @@ parserOptions:
|
||||
sourceType: 'script'
|
||||
|
||||
overrides:
|
||||
files:
|
||||
- gatsby-browser.js
|
||||
parserOptions:
|
||||
sourceType: 'module'
|
||||
- files:
|
||||
- gatsby-browser.js
|
||||
parserOptions:
|
||||
sourceType: 'module'
|
||||
- files:
|
||||
- 'core/base-service/**/*.js'
|
||||
- 'services/**/*.js'
|
||||
rules:
|
||||
sort-class-members/sort-class-members:
|
||||
[
|
||||
'warn',
|
||||
{
|
||||
order:
|
||||
[
|
||||
'name',
|
||||
'category',
|
||||
'isDeprecated',
|
||||
'route',
|
||||
'examples',
|
||||
'defaultBadgeData',
|
||||
'render',
|
||||
'constructor',
|
||||
'fetch',
|
||||
'transform',
|
||||
'handle',
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
plugins:
|
||||
- mocha
|
||||
- no-extension-in-require
|
||||
- 'chai-friendly'
|
||||
- chai-friendly
|
||||
- sort-class-members
|
||||
|
||||
rules:
|
||||
# Disable some rules from eslint:recommended.
|
||||
|
||||
@@ -70,26 +70,6 @@ const serviceDataSchema = Joi.object({
|
||||
.required()
|
||||
|
||||
module.exports = class BaseService {
|
||||
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
|
||||
this._requestFetcher = sendAndCacheRequest
|
||||
this._handleInternalErrors = handleInternalErrors
|
||||
}
|
||||
|
||||
static render(props) {
|
||||
throw new Error(`render() function not implemented for ${this.name}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous function to handle requests for this service. Take the route
|
||||
* parameters (as defined in the `route` property), perform a request using
|
||||
* `this._sendAndCacheRequest`, and return the badge data.
|
||||
*/
|
||||
async handle(namedParams, queryParams) {
|
||||
throw new Error(`Handler not implemented for ${this.constructor.name}`)
|
||||
}
|
||||
|
||||
// Metadata
|
||||
|
||||
/**
|
||||
* Name of the category to sort this badge into (eg. "build"). Used to sort
|
||||
* the badges on the main shields.io website.
|
||||
@@ -98,6 +78,10 @@ module.exports = class BaseService {
|
||||
throw new Error(`Category not set for ${this.name}`)
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object:
|
||||
* - base: (Optional) The base path of the routes for this service. This is
|
||||
@@ -127,17 +111,14 @@ module.exports = class BaseService {
|
||||
throw new Error(`Route not defined for ${this.name}`)
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Default data for the badge. Can include label, logo, and color. These
|
||||
* defaults are used if the value is neither included in the service data
|
||||
* from the handler nor overridden by the user via query parameters.
|
||||
*/
|
||||
static get defaultBadgeData() {
|
||||
return {}
|
||||
static get _cacheLength() {
|
||||
const cacheLengths = {
|
||||
build: 30,
|
||||
license: 3600,
|
||||
version: 300,
|
||||
debug: 60,
|
||||
}
|
||||
return cacheLengths[this.category]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,6 +153,15 @@ module.exports = class BaseService {
|
||||
return []
|
||||
}
|
||||
|
||||
/**
|
||||
* Default data for the badge. Can include label, logo, and color. These
|
||||
* defaults are used if the value is neither included in the service data
|
||||
* from the handler nor overridden by the user via query parameters.
|
||||
*/
|
||||
static get defaultBadgeData() {
|
||||
return {}
|
||||
}
|
||||
|
||||
static validateDefinition() {
|
||||
assertValidCategory(this.category, `Category for ${this.name}`)
|
||||
|
||||
@@ -219,14 +209,53 @@ module.exports = class BaseService {
|
||||
return result
|
||||
}
|
||||
|
||||
static get _cacheLength() {
|
||||
const cacheLengths = {
|
||||
build: 30,
|
||||
license: 3600,
|
||||
version: 300,
|
||||
debug: 60,
|
||||
}
|
||||
return cacheLengths[this.category]
|
||||
static render(props) {
|
||||
throw new Error(`render() function not implemented for ${this.name}`)
|
||||
}
|
||||
|
||||
constructor({ sendAndCacheRequest }, { handleInternalErrors }) {
|
||||
this._requestFetcher = sendAndCacheRequest
|
||||
this._handleInternalErrors = handleInternalErrors
|
||||
}
|
||||
|
||||
async _request({ url, options = {}, errorMessages = {} }) {
|
||||
const logTrace = (...args) => trace.logTrace('fetch', ...args)
|
||||
logTrace(emojic.bowAndArrow, 'Request', url, '\n', options)
|
||||
const { res, buffer } = await this._requestFetcher(url, options)
|
||||
logTrace(emojic.dart, 'Response status code', res.statusCode)
|
||||
return checkErrorResponse.asPromise(errorMessages)({ buffer, res })
|
||||
}
|
||||
|
||||
static _validate(
|
||||
data,
|
||||
schema,
|
||||
{
|
||||
prettyErrorMessage = 'invalid response data',
|
||||
includeKeys = false,
|
||||
allowAndStripUnknownKeys = true,
|
||||
} = {}
|
||||
) {
|
||||
return validate(
|
||||
{
|
||||
ErrorClass: InvalidResponse,
|
||||
prettyErrorMessage,
|
||||
includeKeys,
|
||||
traceErrorMessage: 'Response did not match schema',
|
||||
traceSuccessMessage: 'Response after validation',
|
||||
allowAndStripUnknownKeys,
|
||||
},
|
||||
data,
|
||||
schema
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronous function to handle requests for this service. Take the route
|
||||
* parameters (as defined in the `route` property), perform a request using
|
||||
* `this._sendAndCacheRequest`, and return the badge data.
|
||||
*/
|
||||
async handle(namedParams, queryParams) {
|
||||
throw new Error(`Handler not implemented for ${this.constructor.name}`)
|
||||
}
|
||||
|
||||
_handleError(error) {
|
||||
@@ -398,35 +427,4 @@ module.exports = class BaseService {
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
static _validate(
|
||||
data,
|
||||
schema,
|
||||
{
|
||||
prettyErrorMessage = 'invalid response data',
|
||||
includeKeys = false,
|
||||
allowAndStripUnknownKeys = true,
|
||||
} = {}
|
||||
) {
|
||||
return validate(
|
||||
{
|
||||
ErrorClass: InvalidResponse,
|
||||
prettyErrorMessage,
|
||||
includeKeys,
|
||||
traceErrorMessage: 'Response did not match schema',
|
||||
traceSuccessMessage: 'Response after validation',
|
||||
allowAndStripUnknownKeys,
|
||||
},
|
||||
data,
|
||||
schema
|
||||
)
|
||||
}
|
||||
|
||||
async _request({ url, options = {}, errorMessages = {} }) {
|
||||
const logTrace = (...args) => trace.logTrace('fetch', ...args)
|
||||
logTrace(emojic.bowAndArrow, 'Request', url, '\n', options)
|
||||
const { res, buffer } = await this._requestFetcher(url, options)
|
||||
logTrace(emojic.dart, 'Response status code', res.statusCode)
|
||||
return checkErrorResponse.asPromise(errorMessages)({ buffer, res })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,22 +25,16 @@ const queryParamSchema = Joi.object({
|
||||
.required()
|
||||
|
||||
class DummyService extends BaseService {
|
||||
static render({ namedParamA, queryParamA }) {
|
||||
return {
|
||||
message: `Hello namedParamA: ${namedParamA} with queryParamA: ${queryParamA}`,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ namedParamA }, { queryParamA }) {
|
||||
return this.constructor.render({ namedParamA, queryParamA })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'cat', namedLogo: 'appveyor' }
|
||||
static get route() {
|
||||
return {
|
||||
base: 'foo',
|
||||
pattern: ':namedParamA',
|
||||
queryParamSchema,
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
@@ -54,13 +48,19 @@ class DummyService extends BaseService {
|
||||
]
|
||||
}
|
||||
|
||||
static get route() {
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'cat', namedLogo: 'appveyor' }
|
||||
}
|
||||
|
||||
static render({ namedParamA, queryParamA }) {
|
||||
return {
|
||||
base: 'foo',
|
||||
pattern: ':namedParamA',
|
||||
queryParamSchema,
|
||||
message: `Hello namedParamA: ${namedParamA} with queryParamA: ${queryParamA}`,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ namedParamA }, { queryParamA }) {
|
||||
return this.constructor.render({ namedParamA, queryParamA })
|
||||
}
|
||||
}
|
||||
|
||||
describe('BaseService', function() {
|
||||
|
||||
@@ -38,22 +38,22 @@ function deprecatedService(attrs) {
|
||||
return category
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return route
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
return true
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label }
|
||||
static get route() {
|
||||
return route
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return examples
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label }
|
||||
}
|
||||
|
||||
async handle() {
|
||||
throw new Deprecated({ prettyMessage: message })
|
||||
}
|
||||
|
||||
@@ -40,18 +40,6 @@ module.exports = function redirector(attrs) {
|
||||
} = Joi.attempt(attrs, attrSchema, `Redirector for ${attrs.route.base}`)
|
||||
|
||||
return class Redirector extends BaseService {
|
||||
static get category() {
|
||||
return category
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return route
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
return true
|
||||
}
|
||||
|
||||
static get name() {
|
||||
if (name) {
|
||||
return name
|
||||
@@ -62,6 +50,18 @@ module.exports = function redirector(attrs) {
|
||||
}
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return category
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
return true
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return route
|
||||
}
|
||||
|
||||
static register({ camp, requestCounter }) {
|
||||
const { regex, captureNames } = prepareRoute(this.route)
|
||||
|
||||
|
||||
6
package-lock.json
generated
6
package-lock.json
generated
@@ -8977,6 +8977,12 @@
|
||||
"integrity": "sha512-lHBVRIaz5ibnIgNG07JNiAuBUeKhEf8l4etNx5vfAEwqQ5tcuK3jV9yjmopPgQDagQb7HwIuQVsE3IVcGrRnag==",
|
||||
"dev": true
|
||||
},
|
||||
"eslint-plugin-sort-class-members": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-sort-class-members/-/eslint-plugin-sort-class-members-1.4.0.tgz",
|
||||
"integrity": "sha512-FQG6d4Cy2vYmG9gr6J138E91WaltqwOk/b/7GCssPqnUmizrcgOeN91bV5eOTuoS4RSH1Jdn4ukWEtyWLwV8ig==",
|
||||
"dev": true
|
||||
},
|
||||
"eslint-plugin-standard": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz",
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
"eslint-plugin-promise": "^4.1.1",
|
||||
"eslint-plugin-react": "^7.12.4",
|
||||
"eslint-plugin-react-hooks": "^1.6.0",
|
||||
"eslint-plugin-sort-class-members": "^1.4.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"fetch-ponyfill": "^6.0.0",
|
||||
"fs-readfile-promise": "^3.0.1",
|
||||
|
||||
@@ -18,16 +18,16 @@ const schema = Joi.object({
|
||||
}).required()
|
||||
|
||||
class BaseAmoService extends BaseJsonService {
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'mozilla add-on' }
|
||||
}
|
||||
|
||||
async fetch({ addonId }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `https://addons.mozilla.org/api/v3/addons/addon/${addonId}`,
|
||||
})
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'mozilla add-on' }
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { BaseAmoService, keywords }
|
||||
|
||||
@@ -19,14 +19,14 @@ const condaSchema = Joi.object({
|
||||
}).required()
|
||||
|
||||
module.exports = class BaseCondaService extends BaseJsonService {
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'conda' }
|
||||
}
|
||||
|
||||
async fetch({ channel, pkg }) {
|
||||
return this._requestJson({
|
||||
schema: condaSchema,
|
||||
url: `https://api.anaconda.org/package/${channel}/${pkg}`,
|
||||
})
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'conda' }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,12 +33,6 @@ class PowershellGalleryPlatformSupport extends BaseXmlService {
|
||||
return 'platform-support'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'platform',
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'powershellgallery/p',
|
||||
@@ -58,6 +52,12 @@ class PowershellGalleryPlatformSupport extends BaseXmlService {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'platform',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ platforms }) {
|
||||
return {
|
||||
message: platforms.join(' | '),
|
||||
|
||||
@@ -22,10 +22,6 @@ module.exports = class PubVersion extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'pub' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -45,6 +41,10 @@ module.exports = class PubVersion extends BaseJsonService {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'pub' }
|
||||
}
|
||||
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
|
||||
@@ -15,10 +15,6 @@ module.exports = class PuppetforgeModuleVersion extends BasePuppetForgeModulesSe
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'puppetforge' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -32,6 +28,10 @@ module.exports = class PuppetforgeModuleVersion extends BasePuppetForgeModulesSe
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'puppetforge' }
|
||||
}
|
||||
|
||||
async handle({ user, moduleName }) {
|
||||
const data = await this.fetch({ user, moduleName })
|
||||
return renderVersionBadge({ version: data.current_release.version })
|
||||
|
||||
@@ -9,10 +9,6 @@ module.exports = class PuppetForgeModuleCountService extends BasePuppetForgeUser
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'modules' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'puppetforge/mc',
|
||||
@@ -32,9 +28,8 @@ module.exports = class PuppetForgeModuleCountService extends BasePuppetForgeUser
|
||||
]
|
||||
}
|
||||
|
||||
async handle({ user }) {
|
||||
const data = await this.fetch({ user })
|
||||
return this.constructor.render({ modules: data.module_count })
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'modules' }
|
||||
}
|
||||
|
||||
static render({ modules }) {
|
||||
@@ -43,4 +38,9 @@ module.exports = class PuppetForgeModuleCountService extends BasePuppetForgeUser
|
||||
color: floorCountColor(modules, 5, 10, 50),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user }) {
|
||||
const data = await this.fetch({ user })
|
||||
return this.constructor.render({ modules: data.module_count })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,10 +9,6 @@ module.exports = class PuppetForgeReleaseCountService extends BasePuppetForgeUse
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'releases' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'puppetforge/rc',
|
||||
@@ -32,9 +28,8 @@ module.exports = class PuppetForgeReleaseCountService extends BasePuppetForgeUse
|
||||
]
|
||||
}
|
||||
|
||||
async handle({ user }) {
|
||||
const data = await this.fetch({ user })
|
||||
return this.constructor.render({ releases: data.release_count })
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'releases' }
|
||||
}
|
||||
|
||||
static render({ releases }) {
|
||||
@@ -43,4 +38,9 @@ module.exports = class PuppetForgeReleaseCountService extends BasePuppetForgeUse
|
||||
color: floorCountColor(releases, 10, 50, 100),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ user }) {
|
||||
const data = await this.fetch({ user })
|
||||
return this.constructor.render({ releases: data.release_count })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiDjangoVersions extends PypiBase {
|
||||
return this.buildRoute('pypi/djversions')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'django versions' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiDjangoVersions extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'django versions' }
|
||||
}
|
||||
|
||||
static render({ versions }) {
|
||||
if (versions.length > 0) {
|
||||
return {
|
||||
|
||||
@@ -34,33 +34,6 @@ const periodMap = {
|
||||
// this badge uses PyPI Stats instead of the PyPI API
|
||||
// so it doesn't extend PypiBase
|
||||
module.exports = class PypiDownloads extends BaseJsonService {
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
url: `https://pypistats.org/api/packages/${packageName.toLowerCase()}/recent`,
|
||||
schema,
|
||||
errorMessages: { 404: 'package not found' },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ period, downloads }) {
|
||||
return {
|
||||
message: `${metric(downloads)}${periodMap[period].suffix}`,
|
||||
color: downloadCount(downloads),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ period, packageName }) {
|
||||
const json = await this.fetch({ packageName })
|
||||
return this.constructor.render({
|
||||
period,
|
||||
downloads: json.data[periodMap[period].api_field],
|
||||
})
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'downloads'
|
||||
}
|
||||
@@ -85,4 +58,31 @@ module.exports = class PypiDownloads extends BaseJsonService {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static render({ period, downloads }) {
|
||||
return {
|
||||
message: `${metric(downloads)}${periodMap[period].suffix}`,
|
||||
color: downloadCount(downloads),
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ packageName }) {
|
||||
return this._requestJson({
|
||||
url: `https://pypistats.org/api/packages/${packageName.toLowerCase()}/recent`,
|
||||
schema,
|
||||
errorMessages: { 404: 'package not found' },
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ period, packageName }) {
|
||||
const json = await this.fetch({ packageName })
|
||||
return this.constructor.render({
|
||||
period,
|
||||
downloads: json.data[periodMap[period].api_field],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiFormat extends PypiBase {
|
||||
return this.buildRoute('pypi/format')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'format' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiFormat extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'format' }
|
||||
}
|
||||
|
||||
static render({ hasWheel, hasEgg }) {
|
||||
if (hasWheel) {
|
||||
return {
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiImplementation extends PypiBase {
|
||||
return this.buildRoute('pypi/implementation')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'implementation' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiImplementation extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'implementation' }
|
||||
}
|
||||
|
||||
static render({ implementations }) {
|
||||
return {
|
||||
message: implementations.sort().join(' | '),
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiPythonVersions extends PypiBase {
|
||||
return this.buildRoute('pypi/pyversions')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'python' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -27,6 +23,10 @@ module.exports = class PypiPythonVersions extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'python' }
|
||||
}
|
||||
|
||||
static render({ versions }) {
|
||||
const versionSet = new Set(versions)
|
||||
// We only show v2 if eg. v2.4 does not appear.
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiStatus extends PypiBase {
|
||||
return this.buildRoute('pypi/status')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'status' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiStatus extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'status' }
|
||||
}
|
||||
|
||||
static render({ status = '' }) {
|
||||
status = status.toLowerCase()
|
||||
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiVersion extends PypiBase {
|
||||
return this.buildRoute('pypi/v')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'pypi' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiVersion extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'pypi' }
|
||||
}
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
@@ -12,10 +12,6 @@ module.exports = class PypiWheel extends PypiBase {
|
||||
return this.buildRoute('pypi/wheel')
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'wheel' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -28,6 +24,10 @@ module.exports = class PypiWheel extends PypiBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'wheel' }
|
||||
}
|
||||
|
||||
static render({ hasWheel }) {
|
||||
if (hasWheel) {
|
||||
return {
|
||||
|
||||
@@ -14,11 +14,6 @@ const schema = Joi.object({
|
||||
})
|
||||
|
||||
class BaseRedminePluginRating extends BaseXmlService {
|
||||
async fetch({ plugin }) {
|
||||
const url = `https://www.redmine.org/plugins/${plugin}.xml`
|
||||
return this._requestXml({ schema, url })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
@@ -27,6 +22,11 @@ class BaseRedminePluginRating extends BaseXmlService {
|
||||
throw new Error(`render() function not implemented for ${this.name}`)
|
||||
}
|
||||
|
||||
async fetch({ plugin }) {
|
||||
const url = `https://www.redmine.org/plugins/${plugin}.xml`
|
||||
return this._requestXml({ schema, url })
|
||||
}
|
||||
|
||||
async handle({ plugin }) {
|
||||
const data = await this.fetch({ plugin })
|
||||
const rating = data['redmine-plugin']['ratings-average']
|
||||
@@ -42,10 +42,6 @@ class RedminePluginRating extends BaseRedminePluginRating {
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'redmine' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -56,6 +52,10 @@ class RedminePluginRating extends BaseRedminePluginRating {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'redmine' }
|
||||
}
|
||||
|
||||
static render({ rating }) {
|
||||
return {
|
||||
label: 'rating',
|
||||
|
||||
@@ -8,6 +8,10 @@ const statusSchema = Joi.object({
|
||||
}).required()
|
||||
|
||||
module.exports = class RequiresIo extends BaseJsonService {
|
||||
static get category() {
|
||||
return 'dependencies'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'requires',
|
||||
@@ -15,42 +19,6 @@ module.exports = class RequiresIo extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'requirements' }
|
||||
}
|
||||
|
||||
async handle({ service, user, repo, branch }) {
|
||||
const { status } = await this.fetch({ service, user, repo, branch })
|
||||
return this.constructor.render({ status })
|
||||
}
|
||||
|
||||
async fetch({ service, user, repo, branch }) {
|
||||
const url = `https://requires.io/api/v1/status/${service}/${user}/${repo}`
|
||||
return this._requestJson({
|
||||
url,
|
||||
schema: statusSchema,
|
||||
options: { qs: { branch } },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ status }) {
|
||||
let message = status
|
||||
let color = 'lightgrey'
|
||||
if (status === 'up-to-date') {
|
||||
message = 'up to date'
|
||||
color = 'brightgreen'
|
||||
} else if (status === 'outdated') {
|
||||
color = 'yellow'
|
||||
} else if (status === 'insecure') {
|
||||
color = 'red'
|
||||
}
|
||||
return { message, color }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'dependencies'
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -72,4 +40,36 @@ module.exports = class RequiresIo extends BaseJsonService {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'requirements' }
|
||||
}
|
||||
|
||||
static render({ status }) {
|
||||
let message = status
|
||||
let color = 'lightgrey'
|
||||
if (status === 'up-to-date') {
|
||||
message = 'up to date'
|
||||
color = 'brightgreen'
|
||||
} else if (status === 'outdated') {
|
||||
color = 'yellow'
|
||||
} else if (status === 'insecure') {
|
||||
color = 'red'
|
||||
}
|
||||
return { message, color }
|
||||
}
|
||||
|
||||
async fetch({ service, user, repo, branch }) {
|
||||
const url = `https://requires.io/api/v1/status/${service}/${user}/${repo}`
|
||||
return this._requestJson({
|
||||
url,
|
||||
schema: statusSchema,
|
||||
options: { qs: { branch } },
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ service, user, repo, branch }) {
|
||||
const { status } = await this.fetch({ service, user, repo, branch })
|
||||
return this.constructor.render({ status })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,17 +40,6 @@ const legacyApiSchema = Joi.array()
|
||||
.required()
|
||||
|
||||
module.exports = class SonarBase extends BaseJsonService {
|
||||
transform({ json, sonarVersion }) {
|
||||
const useLegacyApi = isLegacyVersion({ sonarVersion })
|
||||
const rawValue = useLegacyApi
|
||||
? json[0].msr[0].val
|
||||
: json.component.measures[0].value
|
||||
const value = parseInt(rawValue)
|
||||
|
||||
// Most values are numeric, but not all of them.
|
||||
return { metricValue: value || rawValue }
|
||||
}
|
||||
|
||||
async fetch({ sonarVersion, protocol, host, component, metricName }) {
|
||||
let qs, url
|
||||
const useLegacyApi = isLegacyVersion({ sonarVersion })
|
||||
@@ -88,4 +77,15 @@ module.exports = class SonarBase extends BaseJsonService {
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
transform({ json, sonarVersion }) {
|
||||
const useLegacyApi = isLegacyVersion({ sonarVersion })
|
||||
const rawValue = useLegacyApi
|
||||
? json[0].msr[0].val
|
||||
: json.component.measures[0].value
|
||||
const value = parseInt(rawValue)
|
||||
|
||||
// Most values are numeric, but not all of them.
|
||||
return { metricValue: value || rawValue }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,11 @@ module.exports = class StackExchangeMonthlyQuestions extends BaseJsonService {
|
||||
return 'chat'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
static get route() {
|
||||
return {
|
||||
base: 'stackexchange',
|
||||
pattern: ':stackexchangesite/qm/:query',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
@@ -35,11 +38,8 @@ module.exports = class StackExchangeMonthlyQuestions extends BaseJsonService {
|
||||
]
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'stackexchange',
|
||||
pattern: ':stackexchangesite/qm/:query',
|
||||
}
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
}
|
||||
|
||||
static render(props) {
|
||||
|
||||
@@ -30,10 +30,6 @@ module.exports = class StackExchangeReputation extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -48,6 +44,10 @@ module.exports = class StackExchangeReputation extends BaseJsonService {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
}
|
||||
|
||||
static render({ stackexchangesite, numValue }) {
|
||||
const label = `${stackexchangesite} reputation`
|
||||
|
||||
|
||||
@@ -22,8 +22,11 @@ module.exports = class StackExchangeQuestions extends BaseJsonService {
|
||||
return 'chat'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
static get route() {
|
||||
return {
|
||||
base: 'stackexchange',
|
||||
pattern: ':stackexchangesite/t/:query',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
@@ -41,11 +44,8 @@ module.exports = class StackExchangeQuestions extends BaseJsonService {
|
||||
]
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'stackexchange',
|
||||
pattern: ':stackexchangesite/t/:query',
|
||||
}
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'stackoverflow' }
|
||||
}
|
||||
|
||||
static render(props) {
|
||||
|
||||
@@ -121,6 +121,36 @@ const fileFoundOrNotSchema = Joi.alternatives(
|
||||
)
|
||||
|
||||
class SteamCollectionSize extends BaseSteamAPI {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'steam/collection-files',
|
||||
pattern: ':collectionId',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Steam Collection Files',
|
||||
namedParams: { collectionId: '180077636' },
|
||||
staticPreview: this.render({ size: 32 }),
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'files' }
|
||||
}
|
||||
|
||||
static render({ size }) {
|
||||
return { message: metric(size), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
static get interf() {
|
||||
return 'ISteamRemoteStorage'
|
||||
}
|
||||
@@ -133,10 +163,6 @@ class SteamCollectionSize extends BaseSteamAPI {
|
||||
return '1'
|
||||
}
|
||||
|
||||
static render({ size }) {
|
||||
return { message: metric(size), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async handle({ collectionId }) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
@@ -159,32 +185,6 @@ class SteamCollectionSize extends BaseSteamAPI {
|
||||
size: json.response.collectiondetails[0].children.length,
|
||||
})
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'files' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'steam/collection-files',
|
||||
pattern: ':collectionId',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Steam Collection Files',
|
||||
namedParams: { collectionId: '180077636' },
|
||||
staticPreview: this.render({ size: 32 }),
|
||||
documentation,
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileService extends BaseSteamAPI {
|
||||
@@ -200,6 +200,10 @@ class SteamFileService extends BaseSteamAPI {
|
||||
return '1'
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
throw new Error(`onRequest() wasn't implemented for ${this.name}`)
|
||||
}
|
||||
|
||||
async handle({ fileId }) {
|
||||
const options = {
|
||||
method: 'POST',
|
||||
@@ -217,29 +221,13 @@ class SteamFileService extends BaseSteamAPI {
|
||||
|
||||
return this.onRequest({ response: json.response.publishedfiledetails[0] })
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
throw new Error(`onRequest() wasn't implemented for ${this.name}`)
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileSize extends SteamFileService {
|
||||
static render({ fileSize }) {
|
||||
return { message: prettyBytes(fileSize), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({ fileSize: response.file_size })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'size'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'size' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'steam/size',
|
||||
@@ -257,20 +245,23 @@ class SteamFileSize extends SteamFileService {
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileReleaseDate extends SteamFileService {
|
||||
static render({ releaseDate }) {
|
||||
return { message: formatDate(releaseDate), color: ageColor(releaseDate) }
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'size' }
|
||||
}
|
||||
|
||||
static render({ fileSize }) {
|
||||
return { message: prettyBytes(fileSize), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
const releaseDate = new Date(0).setUTCSeconds(response.time_created)
|
||||
return this.constructor.render({ releaseDate })
|
||||
return this.constructor.render({ fileSize: response.file_size })
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'release date' }
|
||||
class SteamFileReleaseDate extends SteamFileService {
|
||||
static get category() {
|
||||
return 'activity'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
@@ -293,24 +284,21 @@ class SteamFileReleaseDate extends SteamFileService {
|
||||
]
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'activity'
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'release date' }
|
||||
}
|
||||
|
||||
static render({ releaseDate }) {
|
||||
return { message: formatDate(releaseDate), color: ageColor(releaseDate) }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
const releaseDate = new Date(0).setUTCSeconds(response.time_created)
|
||||
return this.constructor.render({ releaseDate })
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileSubscriptions extends SteamFileService {
|
||||
static render({ subscriptions }) {
|
||||
return { message: metric(subscriptions), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({ subscriptions: response.subscriptions })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'subscriptions' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
@@ -332,21 +320,21 @@ class SteamFileSubscriptions extends SteamFileService {
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileFavorites extends SteamFileService {
|
||||
static render({ favorites }) {
|
||||
return { message: metric(favorites), color: 'brightgreen' }
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'subscriptions' }
|
||||
}
|
||||
|
||||
static render({ subscriptions }) {
|
||||
return { message: metric(subscriptions), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({ favorites: response.favorited })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'favorites' }
|
||||
return this.constructor.render({ subscriptions: response.subscriptions })
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileFavorites extends SteamFileService {
|
||||
static get category() {
|
||||
return 'rating'
|
||||
}
|
||||
@@ -368,27 +356,25 @@ class SteamFileFavorites extends SteamFileService {
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileDownloads extends SteamFileService {
|
||||
static render({ downloads }) {
|
||||
return { message: metric(downloads), color: downloadCount(downloads) }
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'favorites' }
|
||||
}
|
||||
|
||||
static render({ favorites }) {
|
||||
return { message: metric(favorites), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({
|
||||
downloads: response.lifetime_subscriptions,
|
||||
})
|
||||
return this.constructor.render({ favorites: response.favorited })
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileDownloads extends SteamFileService {
|
||||
static get category() {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'steam/downloads',
|
||||
@@ -406,19 +392,25 @@ class SteamFileDownloads extends SteamFileService {
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class SteamFileViews extends SteamFileService {
|
||||
static render({ views }) {
|
||||
return { message: metric(views), color: 'brightgreen' }
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static render({ downloads }) {
|
||||
return { message: metric(downloads), color: downloadCount(downloads) }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({ views: response.views })
|
||||
return this.constructor.render({
|
||||
downloads: response.lifetime_subscriptions,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'views' }
|
||||
class SteamFileViews extends SteamFileService {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
@@ -439,8 +431,16 @@ class SteamFileViews extends SteamFileService {
|
||||
]
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'other'
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'views' }
|
||||
}
|
||||
|
||||
static render({ views }) {
|
||||
return { message: metric(views), color: 'brightgreen' }
|
||||
}
|
||||
|
||||
async onRequest({ response }) {
|
||||
return this.constructor.render({ views: response.views })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ const validatorSchema = Joi.object()
|
||||
.required()
|
||||
|
||||
module.exports = class SwaggerValidatorService extends BaseJsonService {
|
||||
static render({ message, clr }) {
|
||||
return { message, color: clr }
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
@@ -26,38 +26,6 @@ module.exports = class SwaggerValidatorService extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'swagger' }
|
||||
}
|
||||
|
||||
async handle({ scheme, url }) {
|
||||
const json = await this.fetch({ scheme, urlF: url })
|
||||
const valMessages = json.schemaValidationMessages
|
||||
|
||||
if (!valMessages || valMessages.length === 0) {
|
||||
return this.constructor.render({ message: 'valid', clr: 'brightgreen' })
|
||||
} else {
|
||||
return this.constructor.render({ message: 'invalid', clr: 'red' })
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ scheme, urlF }) {
|
||||
const url = 'http://online.swagger.io/validator/debug'
|
||||
return this._requestJson({
|
||||
url,
|
||||
schema: validatorSchema,
|
||||
options: {
|
||||
qs: {
|
||||
url: `${scheme}://${urlF}`,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -72,4 +40,36 @@ module.exports = class SwaggerValidatorService extends BaseJsonService {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'swagger' }
|
||||
}
|
||||
|
||||
static render({ message, clr }) {
|
||||
return { message, color: clr }
|
||||
}
|
||||
|
||||
async fetch({ scheme, urlF }) {
|
||||
const url = 'http://online.swagger.io/validator/debug'
|
||||
return this._requestJson({
|
||||
url,
|
||||
schema: validatorSchema,
|
||||
options: {
|
||||
qs: {
|
||||
url: `${scheme}://${urlF}`,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ scheme, url }) {
|
||||
const json = await this.fetch({ scheme, urlF: url })
|
||||
const valMessages = json.schemaValidationMessages
|
||||
|
||||
if (!valMessages || valMessages.length === 0) {
|
||||
return this.constructor.render({ message: 'valid', clr: 'brightgreen' })
|
||||
} else {
|
||||
return this.constructor.render({ message: 'invalid', clr: 'red' })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,16 +47,16 @@ const gradeColors = {
|
||||
}
|
||||
|
||||
class SymfonyInsightBase extends BaseXmlService {
|
||||
static get category() {
|
||||
return 'analysis'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'symfony insight',
|
||||
}
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'analysis'
|
||||
}
|
||||
|
||||
async fetch({ projectUuid }) {
|
||||
const url = `https://insight.symfony.com/api/projects/${projectUuid}`
|
||||
const options = {
|
||||
|
||||
@@ -7,24 +7,6 @@ const {
|
||||
} = require('./symfony-insight-base')
|
||||
|
||||
module.exports = class SymfonyInsightGrade extends SymfonyInsightBase {
|
||||
static render({ status, grade }) {
|
||||
const label = 'grade'
|
||||
if (status !== 'finished' && status !== '') {
|
||||
return {
|
||||
label,
|
||||
message: 'pending',
|
||||
color: 'lightgrey',
|
||||
}
|
||||
}
|
||||
|
||||
const message = grade === 'none' ? 'no medal' : grade
|
||||
return {
|
||||
label,
|
||||
message,
|
||||
color: gradeColors[grade],
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'symfony/i/grade',
|
||||
@@ -48,6 +30,24 @@ module.exports = class SymfonyInsightGrade extends SymfonyInsightBase {
|
||||
]
|
||||
}
|
||||
|
||||
static render({ status, grade }) {
|
||||
const label = 'grade'
|
||||
if (status !== 'finished' && status !== '') {
|
||||
return {
|
||||
label,
|
||||
message: 'pending',
|
||||
color: 'lightgrey',
|
||||
}
|
||||
}
|
||||
|
||||
const message = grade === 'none' ? 'no medal' : grade
|
||||
return {
|
||||
label,
|
||||
message,
|
||||
color: gradeColors[grade],
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ projectUuid }) {
|
||||
const data = await this.fetch({ projectUuid })
|
||||
const { grade, status } = this.transform({ data })
|
||||
|
||||
@@ -16,23 +16,6 @@ const gradeStars = {
|
||||
}
|
||||
|
||||
module.exports = class SymfonyInsightStars extends SymfonyInsightBase {
|
||||
static render({ status, grade }) {
|
||||
const label = 'stars'
|
||||
if (status !== 'finished' && status !== '') {
|
||||
return {
|
||||
label,
|
||||
message: 'pending',
|
||||
color: 'lightgrey',
|
||||
}
|
||||
}
|
||||
const numStars = gradeStars[grade]
|
||||
return {
|
||||
label,
|
||||
message: starRating(numStars, 4),
|
||||
color: gradeColors[grade],
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'symfony/i/stars',
|
||||
@@ -56,6 +39,23 @@ module.exports = class SymfonyInsightStars extends SymfonyInsightBase {
|
||||
]
|
||||
}
|
||||
|
||||
static render({ status, grade }) {
|
||||
const label = 'stars'
|
||||
if (status !== 'finished' && status !== '') {
|
||||
return {
|
||||
label,
|
||||
message: 'pending',
|
||||
color: 'lightgrey',
|
||||
}
|
||||
}
|
||||
const numStars = gradeStars[grade]
|
||||
return {
|
||||
label,
|
||||
message: starRating(numStars, 4),
|
||||
color: gradeColors[grade],
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ projectUuid }) {
|
||||
const data = await this.fetch({ projectUuid })
|
||||
const { grade, status } = this.transform({ data })
|
||||
|
||||
@@ -3,6 +3,29 @@
|
||||
const { SymfonyInsightBase, keywords } = require('./symfony-insight-base')
|
||||
|
||||
module.exports = class SymfonyInsightViolations extends SymfonyInsightBase {
|
||||
static get route() {
|
||||
return {
|
||||
base: 'symfony/i/violations',
|
||||
pattern: ':projectUuid',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'SymfonyInsight Violations',
|
||||
namedParams: {
|
||||
projectUuid: '45afb680-d4e6-4e66-93ea-bcfa79eb8a87',
|
||||
},
|
||||
staticPreview: this.render({
|
||||
numViolations: 0,
|
||||
status: 'finished',
|
||||
}),
|
||||
keywords,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static render({
|
||||
status,
|
||||
numViolations,
|
||||
@@ -54,29 +77,6 @@ module.exports = class SymfonyInsightViolations extends SymfonyInsightBase {
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'symfony/i/violations',
|
||||
pattern: ':projectUuid',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'SymfonyInsight Violations',
|
||||
namedParams: {
|
||||
projectUuid: '45afb680-d4e6-4e66-93ea-bcfa79eb8a87',
|
||||
},
|
||||
staticPreview: this.render({
|
||||
numViolations: 0,
|
||||
status: 'finished',
|
||||
}),
|
||||
keywords,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
async handle({ projectUuid }) {
|
||||
const data = await this.fetch({ projectUuid })
|
||||
const lastAnalysis = this.transform({ data })
|
||||
|
||||
@@ -15,31 +15,6 @@ const buildStatusSchema = Joi.object({
|
||||
}).required()
|
||||
|
||||
module.exports = class TeamCityBuild extends TeamCityBase {
|
||||
static render({ status, statusText, useVerbose }) {
|
||||
if (status === 'SUCCESS') {
|
||||
return {
|
||||
message: 'passing',
|
||||
color: 'brightgreen',
|
||||
}
|
||||
} else if (statusText && useVerbose) {
|
||||
return {
|
||||
message: statusText.toLowerCase(),
|
||||
color: 'red',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
message: status.toLowerCase(),
|
||||
color: 'red',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'build',
|
||||
}
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
@@ -94,6 +69,31 @@ module.exports = class TeamCityBuild extends TeamCityBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'build',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ status, statusText, useVerbose }) {
|
||||
if (status === 'SUCCESS') {
|
||||
return {
|
||||
message: 'passing',
|
||||
color: 'brightgreen',
|
||||
}
|
||||
} else if (statusText && useVerbose) {
|
||||
return {
|
||||
message: statusText.toLowerCase(),
|
||||
color: 'red',
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
message: status.toLowerCase(),
|
||||
color: 'red',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ protocol, hostAndPath, verbosity, buildId }) {
|
||||
// JetBrains Docs: https://confluence.jetbrains.com/display/TCD18/REST+API#RESTAPI-BuildStatusIcon
|
||||
const buildLocator = `buildType:(id:${buildId})`
|
||||
|
||||
@@ -17,19 +17,6 @@ const buildStatisticsSchema = Joi.object({
|
||||
}).required()
|
||||
|
||||
module.exports = class TeamCityCoverage extends TeamCityBase {
|
||||
static render({ coverage }) {
|
||||
return {
|
||||
message: `${coverage.toFixed(0)}%`,
|
||||
color: coveragePercentage(coverage),
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'coverage',
|
||||
}
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'coverage'
|
||||
}
|
||||
@@ -69,21 +56,17 @@ module.exports = class TeamCityCoverage extends TeamCityBase {
|
||||
]
|
||||
}
|
||||
|
||||
async handle({ protocol, hostAndPath, buildId }) {
|
||||
// JetBrains Docs: https://confluence.jetbrains.com/display/TCD18/REST+API#RESTAPI-Statistics
|
||||
const buildLocator = `buildType:(id:${buildId})`
|
||||
const apiPath = `app/rest/builds/${encodeURIComponent(
|
||||
buildLocator
|
||||
)}/statistics`
|
||||
const data = await this.fetch({
|
||||
protocol,
|
||||
hostAndPath,
|
||||
apiPath,
|
||||
schema: buildStatisticsSchema,
|
||||
})
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'coverage',
|
||||
}
|
||||
}
|
||||
|
||||
const { coverage } = this.transform({ data })
|
||||
return this.constructor.render({ coverage })
|
||||
static render({ coverage }) {
|
||||
return {
|
||||
message: `${coverage.toFixed(0)}%`,
|
||||
color: coveragePercentage(coverage),
|
||||
}
|
||||
}
|
||||
|
||||
transform({ data }) {
|
||||
@@ -104,4 +87,21 @@ module.exports = class TeamCityCoverage extends TeamCityBase {
|
||||
|
||||
throw new InvalidResponse({ prettyMessage: 'no coverage data available' })
|
||||
}
|
||||
|
||||
async handle({ protocol, hostAndPath, buildId }) {
|
||||
// JetBrains Docs: https://confluence.jetbrains.com/display/TCD18/REST+API#RESTAPI-Statistics
|
||||
const buildLocator = `buildType:(id:${buildId})`
|
||||
const apiPath = `app/rest/builds/${encodeURIComponent(
|
||||
buildLocator
|
||||
)}/statistics`
|
||||
const data = await this.fetch({
|
||||
protocol,
|
||||
hostAndPath,
|
||||
apiPath,
|
||||
schema: buildStatisticsSchema,
|
||||
})
|
||||
|
||||
const { coverage } = this.transform({ data })
|
||||
return this.constructor.render({ coverage })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,14 +94,6 @@ class TwitterFollow extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ user }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `http://cdn.syndication.twimg.com/widgets/followbutton/info.json`,
|
||||
options: { qs: { screen_names: user } },
|
||||
})
|
||||
}
|
||||
|
||||
static render({ user, followers }) {
|
||||
return {
|
||||
label: `follow @${user}`,
|
||||
@@ -114,6 +106,14 @@ class TwitterFollow extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ user }) {
|
||||
return this._requestJson({
|
||||
schema,
|
||||
url: `http://cdn.syndication.twimg.com/widgets/followbutton/info.json`,
|
||||
options: { qs: { screen_names: user } },
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ user }) {
|
||||
const data = await this.fetch({ user })
|
||||
if (data.length === 0) {
|
||||
|
||||
@@ -6,12 +6,6 @@ const UptimeRobotBase = require('./uptimerobot-base')
|
||||
const ratioColor = colorScale([10, 30, 50, 70])
|
||||
|
||||
module.exports = class UptimeRobotRatio extends UptimeRobotBase {
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'uptime',
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'uptimerobot/ratio',
|
||||
@@ -40,6 +34,12 @@ module.exports = class UptimeRobotRatio extends UptimeRobotBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'uptime',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ ratio }) {
|
||||
return {
|
||||
message: `${ratio}%`,
|
||||
|
||||
@@ -3,12 +3,6 @@
|
||||
const UptimeRobotBase = require('./uptimerobot-base')
|
||||
|
||||
module.exports = class UptimeRobotStatus extends UptimeRobotBase {
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'status',
|
||||
}
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'uptimerobot/status',
|
||||
@@ -28,6 +22,12 @@ module.exports = class UptimeRobotStatus extends UptimeRobotBase {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'status',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ status }) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
|
||||
@@ -26,19 +26,6 @@ module.exports = class VisualStudioMarketplaceAzureDevOpsInstalls extends Visual
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'installs',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ count }) {
|
||||
return {
|
||||
message: metric(count),
|
||||
color: downloadCount(count),
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -54,6 +41,19 @@ module.exports = class VisualStudioMarketplaceAzureDevOpsInstalls extends Visual
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'installs',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ count }) {
|
||||
return {
|
||||
message: metric(count),
|
||||
color: downloadCount(count),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ measure, extensionId }) {
|
||||
const json = await this.fetch({ extensionId })
|
||||
const { statistics } = this.transformStatistics({ json })
|
||||
|
||||
@@ -26,16 +26,6 @@ module.exports = class VisualStudioMarketplaceDownloads extends VisualStudioMark
|
||||
}
|
||||
}
|
||||
|
||||
static render({ measure, count }) {
|
||||
const label = measure === 'd' ? 'downloads' : 'installs'
|
||||
|
||||
return {
|
||||
label,
|
||||
message: metric(count),
|
||||
color: downloadCount(count),
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -57,6 +47,16 @@ module.exports = class VisualStudioMarketplaceDownloads extends VisualStudioMark
|
||||
]
|
||||
}
|
||||
|
||||
static render({ measure, count }) {
|
||||
const label = measure === 'd' ? 'downloads' : 'installs'
|
||||
|
||||
return {
|
||||
label,
|
||||
message: metric(count),
|
||||
color: downloadCount(count),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ measure, extensionId }) {
|
||||
const json = await this.fetch({ extensionId })
|
||||
const { statistics } = this.transformStatistics({ json })
|
||||
|
||||
@@ -17,23 +17,6 @@ module.exports = class VisualStudioMarketplaceRating extends VisualStudioMarketp
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'rating',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ format, averageRating, ratingCount }) {
|
||||
const message =
|
||||
format === 'r'
|
||||
? `${averageRating.toFixed(1)}/5 (${ratingCount})`
|
||||
: starRating(averageRating)
|
||||
return {
|
||||
message,
|
||||
color: floorCount(averageRating, 2, 3, 4),
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -60,6 +43,23 @@ module.exports = class VisualStudioMarketplaceRating extends VisualStudioMarketp
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'rating',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ format, averageRating, ratingCount }) {
|
||||
const message =
|
||||
format === 'r'
|
||||
? `${averageRating.toFixed(1)}/5 (${ratingCount})`
|
||||
: starRating(averageRating)
|
||||
return {
|
||||
message,
|
||||
color: floorCount(averageRating, 2, 3, 4),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ format, extensionId }) {
|
||||
const json = await this.fetch({ extensionId })
|
||||
const { statistics } = this.transformStatistics({ json })
|
||||
|
||||
@@ -15,16 +15,6 @@ module.exports = class VisualStudioMarketplaceVersion extends VisualStudioMarket
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'version',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
@@ -37,6 +27,16 @@ module.exports = class VisualStudioMarketplaceVersion extends VisualStudioMarket
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return {
|
||||
label: 'version',
|
||||
}
|
||||
}
|
||||
|
||||
static render({ version }) {
|
||||
return renderVersionBadge({ version })
|
||||
}
|
||||
|
||||
transform({ json }) {
|
||||
const { extension } = this.transformExtension({ json })
|
||||
const version = extension.versions[0].version
|
||||
|
||||
@@ -23,33 +23,15 @@ module.exports = class WaffleLabel extends BaseJsonService {
|
||||
return 'issue-tracking'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'waffle/label',
|
||||
pattern: ':user/:repo/:label',
|
||||
}
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'waffle' }
|
||||
}
|
||||
|
||||
static get isDeprecated() {
|
||||
const now = new Date()
|
||||
return now.getTime() >= new Date('2019-05-16')
|
||||
}
|
||||
|
||||
static render({ label, color, count }) {
|
||||
if (count === 'absent') {
|
||||
return { message: count }
|
||||
}
|
||||
if (count === 0 || !color) {
|
||||
color = '78bdf2'
|
||||
}
|
||||
static get route() {
|
||||
return {
|
||||
label,
|
||||
message: metric(count),
|
||||
color,
|
||||
base: 'waffle/label',
|
||||
pattern: ':user/:repo/:label',
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,6 +53,24 @@ module.exports = class WaffleLabel extends BaseJsonService {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'waffle' }
|
||||
}
|
||||
|
||||
static render({ label, color, count }) {
|
||||
if (count === 'absent') {
|
||||
return { message: count }
|
||||
}
|
||||
if (count === 0 || !color) {
|
||||
color = '78bdf2'
|
||||
}
|
||||
return {
|
||||
label,
|
||||
message: metric(count),
|
||||
color,
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ user, repo }) {
|
||||
const url = `https://api.waffle.io/${user}/${repo}/columns`
|
||||
return this._requestJson({
|
||||
|
||||
@@ -15,53 +15,6 @@ const werckerSchema = Joi.array()
|
||||
.required()
|
||||
|
||||
module.exports = class Wercker extends BaseJsonService {
|
||||
static getBaseUrl({ projectId, applicationName }) {
|
||||
if (applicationName) {
|
||||
return `https://app.wercker.com/api/v3/applications/${applicationName}/builds`
|
||||
} else {
|
||||
return `https://app.wercker.com/api/v3/runs?applicationId=${projectId}`
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ baseUrl, branch }) {
|
||||
return this._requestJson({
|
||||
schema: werckerSchema,
|
||||
url: baseUrl,
|
||||
options: {
|
||||
qs: {
|
||||
branch,
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
errorMessages: {
|
||||
401: 'private application not supported',
|
||||
404: 'application not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
static render({ result }) {
|
||||
return renderBuildStatusBadge({ status: result })
|
||||
}
|
||||
|
||||
async handle({ projectId, applicationName, branch }) {
|
||||
const json = await this.fetch({
|
||||
baseUrl: this.constructor.getBaseUrl({
|
||||
projectId,
|
||||
applicationName,
|
||||
}),
|
||||
branch,
|
||||
})
|
||||
if (json.length === 0) {
|
||||
return this.constructor.render({
|
||||
result: 'not built',
|
||||
})
|
||||
}
|
||||
const { result } = json[0]
|
||||
return this.constructor.render({ result })
|
||||
}
|
||||
|
||||
// Metadata
|
||||
static get category() {
|
||||
return 'build'
|
||||
}
|
||||
@@ -113,4 +66,50 @@ module.exports = class Wercker extends BaseJsonService {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static render({ result }) {
|
||||
return renderBuildStatusBadge({ status: result })
|
||||
}
|
||||
|
||||
static getBaseUrl({ projectId, applicationName }) {
|
||||
if (applicationName) {
|
||||
return `https://app.wercker.com/api/v3/applications/${applicationName}/builds`
|
||||
} else {
|
||||
return `https://app.wercker.com/api/v3/runs?applicationId=${projectId}`
|
||||
}
|
||||
}
|
||||
|
||||
async fetch({ baseUrl, branch }) {
|
||||
return this._requestJson({
|
||||
schema: werckerSchema,
|
||||
url: baseUrl,
|
||||
options: {
|
||||
qs: {
|
||||
branch,
|
||||
limit: 1,
|
||||
},
|
||||
},
|
||||
errorMessages: {
|
||||
401: 'private application not supported',
|
||||
404: 'application not found',
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
async handle({ projectId, applicationName, branch }) {
|
||||
const json = await this.fetch({
|
||||
baseUrl: this.constructor.getBaseUrl({
|
||||
projectId,
|
||||
applicationName,
|
||||
}),
|
||||
branch,
|
||||
})
|
||||
if (json.length === 0) {
|
||||
return this.constructor.render({
|
||||
result: 'not built',
|
||||
})
|
||||
}
|
||||
const { result } = json[0]
|
||||
return this.constructor.render({ result })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,43 @@ const wheelmapSchema = Joi.object({
|
||||
}).required()
|
||||
|
||||
module.exports = class Wheelmap extends BaseJsonService {
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'wheelmap/a',
|
||||
pattern: ':nodeId(-?[0-9]+)',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Wheelmap',
|
||||
namedParams: { nodeId: '26699541' },
|
||||
staticPreview: this.render({ accessibility: 'yes' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'accessibility' }
|
||||
}
|
||||
|
||||
static render({ accessibility }) {
|
||||
let color
|
||||
if (accessibility === 'yes') {
|
||||
color = 'brightgreen'
|
||||
} else if (accessibility === 'limited') {
|
||||
color = 'yellow'
|
||||
} else if (accessibility === 'no') {
|
||||
color = 'red'
|
||||
}
|
||||
return { message: accessibility, color }
|
||||
}
|
||||
|
||||
async fetch({ nodeId }) {
|
||||
let options
|
||||
if (serverSecrets.wheelmap_token) {
|
||||
@@ -32,46 +69,9 @@ module.exports = class Wheelmap extends BaseJsonService {
|
||||
})
|
||||
}
|
||||
|
||||
static render({ accessibility }) {
|
||||
let color
|
||||
if (accessibility === 'yes') {
|
||||
color = 'brightgreen'
|
||||
} else if (accessibility === 'limited') {
|
||||
color = 'yellow'
|
||||
} else if (accessibility === 'no') {
|
||||
color = 'red'
|
||||
}
|
||||
return { message: accessibility, color }
|
||||
}
|
||||
|
||||
async handle({ nodeId }) {
|
||||
const json = await this.fetch({ nodeId })
|
||||
const accessibility = json.node.wheelchair
|
||||
return this.constructor.render({ accessibility })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'accessibility' }
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'other'
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: 'wheelmap/a',
|
||||
pattern: ':nodeId(-?[0-9]+)',
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
title: 'Wheelmap',
|
||||
namedParams: { nodeId: '26699541' },
|
||||
staticPreview: this.render({ accessibility: 'yes' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,29 +29,10 @@ function DownloadsForExtensionType(extensionType) {
|
||||
return `Wordpress${capt}Downloads`
|
||||
}
|
||||
|
||||
static render({ downloads }) {
|
||||
return {
|
||||
message: metric(downloads),
|
||||
color: downloadCount(downloads),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ slug }) {
|
||||
const { downloaded: downloads } = await this.fetch({
|
||||
extensionType,
|
||||
slug,
|
||||
})
|
||||
return this.constructor.render({ downloads })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: `wordpress/${extensionType}/dt`,
|
||||
@@ -68,6 +49,25 @@ function DownloadsForExtensionType(extensionType) {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static render({ downloads }) {
|
||||
return {
|
||||
message: metric(downloads),
|
||||
color: downloadCount(downloads),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ slug }) {
|
||||
const { downloaded: downloads } = await this.fetch({
|
||||
extensionType,
|
||||
slug,
|
||||
})
|
||||
return this.constructor.render({ downloads })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,25 +83,6 @@ function InstallsForExtensionType(extensionType) {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static render({ installCount }) {
|
||||
return {
|
||||
message: metric(installCount),
|
||||
color: downloadCount(installCount),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ slug }) {
|
||||
const { active_installs: installCount } = await this.fetch({
|
||||
extensionType,
|
||||
slug,
|
||||
})
|
||||
return this.constructor.render({ installCount })
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'active installs' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: `wordpress/${extensionType}/installs`,
|
||||
@@ -118,6 +99,25 @@ function InstallsForExtensionType(extensionType) {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'active installs' }
|
||||
}
|
||||
|
||||
static render({ installCount }) {
|
||||
return {
|
||||
message: metric(installCount),
|
||||
color: downloadCount(installCount),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ slug }) {
|
||||
const { active_installs: installCount } = await this.fetch({
|
||||
extensionType,
|
||||
slug,
|
||||
})
|
||||
return this.constructor.render({ installCount })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,10 +158,6 @@ function DownloadsForInterval(interval) {
|
||||
return 'downloads'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base,
|
||||
@@ -179,6 +175,10 @@ function DownloadsForInterval(interval) {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'downloads' }
|
||||
}
|
||||
|
||||
static render({ downloads }) {
|
||||
return {
|
||||
message: `${metric(downloads)}${messageSuffix}`,
|
||||
|
||||
@@ -52,10 +52,6 @@ class WordpressPluginTestedVersion extends BaseWordpress {
|
||||
return 'platform-support'
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'wordpress' }
|
||||
}
|
||||
|
||||
static get route() {
|
||||
return {
|
||||
base: `wordpress/plugin/tested`,
|
||||
@@ -75,6 +71,10 @@ class WordpressPluginTestedVersion extends BaseWordpress {
|
||||
]
|
||||
}
|
||||
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'wordpress' }
|
||||
}
|
||||
|
||||
static renderStaticPreview({ testedVersion }) {
|
||||
// Since this badge has an async `render()` function, but `get examples()` has to
|
||||
// be synchronous, this method exists. It should return the same value as the
|
||||
|
||||
Reference in New Issue
Block a user