generate static examples without api call [apm appveyor cdnjs clojars gem npm uptimerobot] (#1740)
* allow service classes to define a static example * define static example for some services (apm, appveyor, cdnjs, clojars, gem, librariesio, npm, uptimerobot) * add/update tests This allows us to show an example without making an API call to a live service for better performance. We can now specify 3 fields in the example definition: * urlPattern for the version with placeholders e.g: /npm/dw/:package.svg * ExampleUrl/Uri for the concrete example e.g: /npm/dw/localeval.svg * PreviewUrl/Uri for the static (or live) image we will actually show
This commit is contained in:
@@ -6,8 +6,9 @@ import resolveBadgeUrl from '../lib/badge-url'
|
||||
|
||||
const Badge = ({
|
||||
title,
|
||||
previewUri,
|
||||
exampleUri,
|
||||
previewUri,
|
||||
urlPattern,
|
||||
documentation,
|
||||
baseUri,
|
||||
longCache,
|
||||
@@ -15,7 +16,14 @@ const Badge = ({
|
||||
onClick,
|
||||
}) => {
|
||||
const handleClick = onClick
|
||||
? () => onClick({ title, previewUri, exampleUri, documentation })
|
||||
? () =>
|
||||
onClick({
|
||||
title,
|
||||
exampleUri,
|
||||
previewUri,
|
||||
urlPattern,
|
||||
documentation,
|
||||
})
|
||||
: undefined
|
||||
|
||||
const previewImage = previewUri ? (
|
||||
@@ -29,7 +37,7 @@ const Badge = ({
|
||||
'\u00a0'
|
||||
) // non-breaking space
|
||||
const resolvedExampleUri = resolveBadgeUrl(
|
||||
exampleUri || previewUri,
|
||||
urlPattern || previewUri,
|
||||
baseUri,
|
||||
{ longCache: false }
|
||||
)
|
||||
@@ -59,8 +67,9 @@ const Badge = ({
|
||||
}
|
||||
Badge.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
previewUri: PropTypes.string,
|
||||
exampleUri: PropTypes.string,
|
||||
previewUri: PropTypes.string,
|
||||
urlPattern: PropTypes.string,
|
||||
documentation: PropTypes.string,
|
||||
baseUri: PropTypes.string,
|
||||
longCache: PropTypes.bool.isRequired,
|
||||
@@ -101,8 +110,9 @@ Category.propTypes = {
|
||||
examples: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
title: PropTypes.string.isRequired,
|
||||
previewUri: PropTypes.string,
|
||||
exampleUri: PropTypes.string,
|
||||
previewUri: PropTypes.string,
|
||||
urlPattern: PropTypes.string,
|
||||
documentation: PropTypes.string,
|
||||
})
|
||||
).isRequired,
|
||||
|
||||
@@ -10,8 +10,9 @@ export default class MarkupModal extends React.Component {
|
||||
static propTypes = {
|
||||
example: PropTypes.shape({
|
||||
title: PropTypes.string.isRequired,
|
||||
previewUri: PropTypes.string,
|
||||
exampleUri: PropTypes.string,
|
||||
previewUri: PropTypes.string,
|
||||
urlPattern: PropTypes.string,
|
||||
documentation: PropTypes.string,
|
||||
link: PropTypes.string,
|
||||
}),
|
||||
@@ -20,6 +21,7 @@ export default class MarkupModal extends React.Component {
|
||||
}
|
||||
|
||||
state = {
|
||||
exampleUri: null,
|
||||
badgeUri: null,
|
||||
link: null,
|
||||
style: 'flat',
|
||||
@@ -38,10 +40,13 @@ export default class MarkupModal extends React.Component {
|
||||
|
||||
// Transfer `badgeUri` and `link` into state so they can be edited by the
|
||||
// user.
|
||||
const { exampleUri, previewUri, link } = example
|
||||
const { exampleUri, urlPattern, previewUri, link } = example
|
||||
this.setState({
|
||||
exampleUri: exampleUri
|
||||
? resolveBadgeUrl(exampleUri, baseUri || window.location.href)
|
||||
: null,
|
||||
badgeUri: resolveBadgeUrl(
|
||||
exampleUri || previewUri,
|
||||
urlPattern || previewUri,
|
||||
baseUri || window.location.href
|
||||
),
|
||||
link,
|
||||
@@ -126,6 +131,18 @@ export default class MarkupModal extends React.Component {
|
||||
/>
|
||||
</label>
|
||||
</p>
|
||||
{this.state.exampleUri && (
|
||||
<p>
|
||||
Example
|
||||
<ClickToSelect>
|
||||
<input
|
||||
className="code clickable"
|
||||
readOnly
|
||||
value={this.state.exampleUri}
|
||||
/>
|
||||
</ClickToSelect>
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
<label>
|
||||
Style
|
||||
|
||||
@@ -120,22 +120,26 @@ const allBadgeExamples = [
|
||||
{
|
||||
title: 'Travis (.org)',
|
||||
previewUri: '/travis/rust-lang/rust.svg',
|
||||
exampleUri: '/travis/USER/REPO.svg',
|
||||
urlPattern: '/travis/:user/:repo.svg',
|
||||
exampleUri: '/travis/rust-lang/rust.svg',
|
||||
},
|
||||
{
|
||||
title: 'Travis (.org) branch',
|
||||
previewUri: '/travis/rust-lang/rust/master.svg',
|
||||
exampleUri: '/travis/USER/REPO/BRANCH.svg',
|
||||
urlPattern: '/travis/:user/:repo/:branch.svg',
|
||||
exampleUri: '/travis/rust-lang/rust/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'Travis (.com)',
|
||||
previewUri: '/travis/com/ivandelabeldad/rackian-gateway.svg',
|
||||
exampleUri: '/travis/com/USER/REPO.svg',
|
||||
urlPattern: '/travis/com/:user/:repo.svg',
|
||||
exampleUri: '/travis/com/ivandelabeldad/rackian-gateway.svg',
|
||||
},
|
||||
{
|
||||
title: 'Travis (.com) branch',
|
||||
previewUri: '/travis/com/ivandelabeldad/rackian-gateway/master.svg',
|
||||
exampleUri: '/travis/com/USER/REPO/BRANCH.svg',
|
||||
urlPattern: '/travis/com/:user/:repo/:branch.svg',
|
||||
exampleUri: '/travis/com/ivandelabeldad/rackian-gateway/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'TeamCity CodeBetter',
|
||||
@@ -148,7 +152,7 @@ const allBadgeExamples = [
|
||||
{
|
||||
title: 'TeamCity (full build status)',
|
||||
keywords: ['teamcity'],
|
||||
exampleUri: '/teamcity/http/teamcity.jetbrains.com/e/bt345.svg',
|
||||
previewUri: '/teamcity/http/teamcity.jetbrains.com/e/bt345.svg',
|
||||
},
|
||||
{
|
||||
title: 'Buildkite',
|
||||
@@ -176,8 +180,10 @@ const allBadgeExamples = [
|
||||
title: 'CircleCI token',
|
||||
previewUri:
|
||||
'/circleci/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
urlPattern:
|
||||
'/circleci/token/:token/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
exampleUri:
|
||||
'/circleci/token/YOURTOKEN/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
'/circleci/token/b90b5c49e59a4c67ba3a92f7992587ac7a0408c2/project/github/RedSparr0w/node-csgo-parser/master.svg',
|
||||
},
|
||||
{
|
||||
title: 'Visual Studio Team services',
|
||||
@@ -281,8 +287,9 @@ const allBadgeExamples = [
|
||||
{
|
||||
title: 'Codecov private',
|
||||
previewUri: '/codecov/c/github/codecov/example-python.svg',
|
||||
urlPattern: '/codecov/c/token/:token/github/codecov/example-python.svg',
|
||||
exampleUri:
|
||||
'/codecov/c/token/YOURTOKEN/github/codecov/example-python.svg',
|
||||
'/codecov/c/token/My0A8VL917/github/codecov/example-python.svg',
|
||||
},
|
||||
{
|
||||
title: 'Coverity Scan',
|
||||
@@ -312,8 +319,9 @@ const allBadgeExamples = [
|
||||
title: 'Dockbit',
|
||||
previewUri:
|
||||
'/dockbit/DockbitStatus/health.svg?token=TvavttxFHJ4qhnKstDxrvBXM',
|
||||
urlPattern: '/dockbit/:organisation/:pipeline.svg?token=:token',
|
||||
exampleUri:
|
||||
'/dockbit/ORGANIZATION_NAME/PIPELINE_NAME.svg?token=PIPELINE_TOKEN',
|
||||
'/dockbit/DockbitStatus/health.svg?token=TvavttxFHJ4qhnKstDxrvBXM',
|
||||
},
|
||||
{
|
||||
title: 'continuousphp',
|
||||
@@ -333,7 +341,10 @@ const allBadgeExamples = [
|
||||
title: 'Bitrise',
|
||||
previewUri:
|
||||
'/bitrise/cde737473028420d/master.svg?token=GCIdEzacE4GW32jLVrZb7A',
|
||||
exampleUri: '/bitrise/APP-ID/BRANCH.svg?token=APP-STATUS-BADGE-TOKEN',
|
||||
urlPattern:
|
||||
'/bitrise/:app-id/:branch.svg?token=:app-status-badge-token',
|
||||
exampleUri:
|
||||
'/bitrise/cde737473028420d/master.svg?token=GCIdEzacE4GW32jLVrZb7A',
|
||||
},
|
||||
{
|
||||
title: 'Code Climate',
|
||||
@@ -1440,7 +1451,8 @@ const allBadgeExamples = [
|
||||
{
|
||||
title: 'iTunes App Store',
|
||||
previewUri: '/itunes/v/803453959.svg',
|
||||
exampleUri: '/itunes/v/BUNDLE_ID.svg',
|
||||
urlPattern: '/itunes/v/:bundle-id.svg',
|
||||
exampleUri: '/itunes/v/803453959.svg',
|
||||
},
|
||||
{
|
||||
title: 'JitPack',
|
||||
|
||||
@@ -15,14 +15,16 @@ describe('The badge examples', function() {
|
||||
expect(appVeyorBuildExamples).to.deep.equal([
|
||||
{
|
||||
title: 'AppVeyor',
|
||||
previewUri: '/appveyor/ci/gruntjs/grunt.svg',
|
||||
exampleUri: undefined,
|
||||
exampleUri: '/appveyor/ci/gruntjs/grunt.svg',
|
||||
previewUri: '/badge/build-passing-brightgreen.svg',
|
||||
urlPattern: '/appveyor/ci/:user/:repo.svg',
|
||||
documentation: undefined,
|
||||
},
|
||||
{
|
||||
title: 'AppVeyor branch',
|
||||
previewUri: '/appveyor/ci/gruntjs/grunt/master.svg',
|
||||
exampleUri: undefined,
|
||||
exampleUri: '/appveyor/ci/gruntjs/grunt/master.svg',
|
||||
previewUri: '/badge/build-passing-brightgreen.svg',
|
||||
urlPattern: '/appveyor/ci/:user/:repo/:branch.svg',
|
||||
documentation: undefined,
|
||||
},
|
||||
])
|
||||
|
||||
@@ -29,15 +29,6 @@ class BaseAPMService extends BaseJsonService {
|
||||
static get defaultBadgeData() {
|
||||
return { label: 'apm' }
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
previewUrl: 'vim-mode',
|
||||
keywords: ['atom'],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class APMDownloads extends BaseAPMService {
|
||||
@@ -65,6 +56,17 @@ class APMDownloads extends BaseAPMService {
|
||||
capture: ['repo'],
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
exampleUrl: 'vim-mode',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ downloads: '60043' }),
|
||||
keywords: ['atom'],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class APMVersion extends BaseAPMService {
|
||||
@@ -94,6 +96,17 @@ class APMVersion extends BaseAPMService {
|
||||
capture: ['repo'],
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
exampleUrl: 'vim-mode',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ version: '0.6.0' }),
|
||||
keywords: ['atom'],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
class APMLicense extends BaseAPMService {
|
||||
@@ -127,6 +140,17 @@ class APMLicense extends BaseAPMService {
|
||||
capture: ['repo'],
|
||||
}
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
exampleUrl: 'vim-mode',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ license: 'MIT' }),
|
||||
keywords: ['atom'],
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@@ -11,11 +11,15 @@ module.exports = class AppVeyorCi extends AppVeyorBase {
|
||||
return [
|
||||
{
|
||||
title: 'AppVeyor',
|
||||
previewUrl: 'gruntjs/grunt',
|
||||
exampleUrl: 'gruntjs/grunt',
|
||||
urlPattern: ':user/:repo',
|
||||
staticExample: this.render({ status: 'success' }),
|
||||
},
|
||||
{
|
||||
title: 'AppVeyor branch',
|
||||
previewUrl: 'gruntjs/grunt/master',
|
||||
exampleUrl: 'gruntjs/grunt/master',
|
||||
urlPattern: ':user/:repo/:branch',
|
||||
staticExample: this.render({ status: 'success' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -86,19 +86,35 @@ class BaseService {
|
||||
return '/' + [this.url.base, partialUrl].filter(Boolean).join('/')
|
||||
}
|
||||
|
||||
static _makeStaticExampleUrl(serviceData) {
|
||||
const badgeData = this._makeBadgeData({}, serviceData)
|
||||
const color = badgeData.colorscheme || badgeData.colorB
|
||||
return `/badge/${encodeURIComponent(
|
||||
badgeData.text[0]
|
||||
)}-${encodeURIComponent(badgeData.text[1])}-${color}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of examples. Each example is prepared according to the
|
||||
* schema in `lib/all-badge-examples.js`. Four keys are supported:
|
||||
* - title
|
||||
* - previewUrl
|
||||
* - exampleUrl
|
||||
* - documentation
|
||||
* schema in `lib/all-badge-examples.js`.
|
||||
*/
|
||||
static prepareExamples() {
|
||||
return this.examples.map(
|
||||
({ title, previewUrl, query, exampleUrl, documentation }) => {
|
||||
if (!previewUrl) {
|
||||
throw Error(`Example for ${this.name} is missing required previewUrl`)
|
||||
({
|
||||
title,
|
||||
query,
|
||||
exampleUrl,
|
||||
previewUrl,
|
||||
urlPattern,
|
||||
staticExample,
|
||||
documentation,
|
||||
}) => {
|
||||
if (!previewUrl && !staticExample) {
|
||||
throw Error(
|
||||
`Example for ${
|
||||
this.name
|
||||
} is missing required previewUrl or staticExample`
|
||||
)
|
||||
}
|
||||
|
||||
const stringified = queryString.stringify(query)
|
||||
@@ -106,10 +122,15 @@ class BaseService {
|
||||
|
||||
return {
|
||||
title: title ? `${title}` : this.name,
|
||||
previewUri: `${this._makeFullUrl(previewUrl, query)}.svg${suffix}`,
|
||||
exampleUri: exampleUrl
|
||||
? `${this._makeFullUrl(exampleUrl, query)}.svg${suffix}`
|
||||
: undefined,
|
||||
previewUri: staticExample
|
||||
? `${this._makeStaticExampleUrl(staticExample)}.svg`
|
||||
: `${this._makeFullUrl(previewUrl, query)}.svg${suffix}`,
|
||||
urlPattern: urlPattern
|
||||
? `${this._makeFullUrl(urlPattern, query)}.svg${suffix}`
|
||||
: undefined,
|
||||
documentation,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,17 +16,29 @@ const BaseService = require('./base')
|
||||
require('../lib/register-chai-plugins.spec')
|
||||
|
||||
class DummyService extends BaseService {
|
||||
static render({ namedParamA, queryParamA }) {
|
||||
return {
|
||||
message: `Hello namedParamA: ${namedParamA} with queryParamA: ${queryParamA}`,
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ namedParamA }, { queryParamA }) {
|
||||
return { message: `Hello ${namedParamA}${queryParamA}` }
|
||||
return this.constructor.render({ namedParamA, queryParamA })
|
||||
}
|
||||
|
||||
static get category() {
|
||||
return 'cat'
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [
|
||||
{ previewUrl: 'World' },
|
||||
{ previewUrl: 'World', query: { queryParamA: '!!!' } },
|
||||
{
|
||||
urlPattern: ':world',
|
||||
exampleUrl: 'World',
|
||||
staticExample: this.render({ namedParamA: 'foo', queryParamA: 'bar' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
static get url() {
|
||||
@@ -87,7 +99,9 @@ describe('BaseService', function() {
|
||||
{ namedParamA: 'bar.bar.bar' },
|
||||
{ queryParamA: '!' }
|
||||
)
|
||||
expect(serviceData).to.deep.equal({ message: 'Hello bar.bar.bar!' })
|
||||
expect(serviceData).to.deep.equal({
|
||||
message: 'Hello namedParamA: bar.bar.bar with queryParamA: !',
|
||||
})
|
||||
})
|
||||
|
||||
describe('Logging', function() {
|
||||
@@ -294,7 +308,7 @@ describe('BaseService', function() {
|
||||
const expectedFormat = 'svg'
|
||||
expect(mockSendBadge).to.have.been.calledOnce
|
||||
expect(mockSendBadge).to.have.been.calledWith(expectedFormat, {
|
||||
text: ['cat', 'Hello bar?'],
|
||||
text: ['cat', 'Hello namedParamA: bar with queryParamA: ?'],
|
||||
colorscheme: 'lightgrey',
|
||||
template: undefined,
|
||||
logo: undefined,
|
||||
@@ -307,17 +321,27 @@ describe('BaseService', function() {
|
||||
|
||||
describe('prepareExamples', function() {
|
||||
it('returns the expected result', function() {
|
||||
const [first, second] = DummyService.prepareExamples()
|
||||
const [first, second, third] = DummyService.prepareExamples()
|
||||
expect(first).to.deep.equal({
|
||||
title: 'DummyService',
|
||||
previewUri: '/foo/World.svg',
|
||||
exampleUri: undefined,
|
||||
previewUri: '/foo/World.svg',
|
||||
urlPattern: undefined,
|
||||
documentation: undefined,
|
||||
})
|
||||
expect(second).to.deep.equal({
|
||||
title: 'DummyService',
|
||||
previewUri: '/foo/World.svg?queryParamA=%21%21%21',
|
||||
exampleUri: undefined,
|
||||
previewUri: '/foo/World.svg?queryParamA=%21%21%21',
|
||||
urlPattern: undefined,
|
||||
documentation: undefined,
|
||||
})
|
||||
expect(third).to.deep.equal({
|
||||
title: 'DummyService',
|
||||
exampleUri: '/foo/World.svg',
|
||||
previewUri:
|
||||
'/badge/cat-Hello%20namedParamA%3A%20foo%20with%20queryParamA%3A%20bar-lightgrey.svg',
|
||||
urlPattern: '/foo/:world.svg',
|
||||
documentation: undefined,
|
||||
})
|
||||
})
|
||||
|
||||
@@ -59,7 +59,9 @@ module.exports = class Cdnjs extends BaseJsonService {
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
previewUrl: 'jquery',
|
||||
urlPattern: ':library',
|
||||
exampleUrl: 'jquery',
|
||||
staticExample: this.render({ version: '1.5.2' }),
|
||||
keywords: ['cdn', 'cdnjs'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -56,6 +56,12 @@ module.exports = class Clojars extends BaseJsonService {
|
||||
}
|
||||
|
||||
static get examples() {
|
||||
return [{ previewUrl: 'prismic' }]
|
||||
return [
|
||||
{
|
||||
exampleUrl: 'prismic',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ clojar: 'clojar', version: '1.2' }),
|
||||
},
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ module.exports = class GemDownloads extends BaseJsonService {
|
||||
}
|
||||
}
|
||||
|
||||
_getLabel(version, info) {
|
||||
static _getLabel(version, info) {
|
||||
if (version) {
|
||||
return 'downloads@' + version
|
||||
} else {
|
||||
@@ -65,7 +65,7 @@ module.exports = class GemDownloads extends BaseJsonService {
|
||||
let version =
|
||||
splitRubygem.length > 1 ? splitRubygem[splitRubygem.length - 1] : null
|
||||
version = version === 'stable' ? version : semver.valid(version)
|
||||
const label = this._getLabel(version, info)
|
||||
const label = this.constructor._getLabel(version, info)
|
||||
const json = await this.fetch({ repo, info })
|
||||
|
||||
let downloads
|
||||
@@ -122,22 +122,42 @@ module.exports = class GemDownloads extends BaseJsonService {
|
||||
return [
|
||||
{
|
||||
title: 'Gem',
|
||||
previewUrl: 'dv/rails/stable',
|
||||
exampleUrl: 'dv/rails/stable',
|
||||
urlPattern: 'dv/:package/stable',
|
||||
staticExample: this.render({
|
||||
label: this._getLabel('stable', 'dv'),
|
||||
downloads: 70000,
|
||||
}),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
{
|
||||
title: 'Gem',
|
||||
previewUrl: 'dv/rails/4.1.0',
|
||||
exampleUrl: 'dv/rails/4.1.0',
|
||||
urlPattern: 'dv/:package/:version',
|
||||
staticExample: this.render({
|
||||
label: this._getLabel('4.1.0', 'dv'),
|
||||
downloads: 50000,
|
||||
}),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
{
|
||||
title: 'Gem',
|
||||
previewUrl: 'dtv/rails',
|
||||
exampleUrl: 'dtv/rails',
|
||||
urlPattern: 'dtv/:package',
|
||||
staticExample: this.render({
|
||||
label: this._getLabel(undefined, 'dtv'),
|
||||
downloads: 70000,
|
||||
}),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
{
|
||||
title: 'Gem',
|
||||
previewUrl: 'dt/rails',
|
||||
exampleUrl: 'dt/rails',
|
||||
urlPattern: 'dt/:package',
|
||||
staticExample: this.render({
|
||||
label: this._getLabel(undefined, 'dt'),
|
||||
downloads: 900000,
|
||||
}),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -49,7 +49,9 @@ module.exports = class GemOwner extends BaseJsonService {
|
||||
return [
|
||||
{
|
||||
title: 'Gems',
|
||||
previewUrl: 'raphink',
|
||||
exampleUrl: 'raphink',
|
||||
urlPattern: ':user',
|
||||
staticExample: this.render({ count: 34 }),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -25,8 +25,8 @@ const dailySchema = Joi.array()
|
||||
.required()
|
||||
|
||||
module.exports = class GemRank extends BaseJsonService {
|
||||
async fetch({ info, repo }) {
|
||||
const totalRank = info === 'rt'
|
||||
async fetch({ period, repo }) {
|
||||
const totalRank = period === 'rt'
|
||||
const endpoint = totalRank ? '/total_ranking.json' : '/daily_ranking.json'
|
||||
const url = `http://bestgems.org/api/v1/gems/${repo}${endpoint}`
|
||||
const schema = totalRank ? totalSchema : dailySchema
|
||||
@@ -36,23 +36,20 @@ module.exports = class GemRank extends BaseJsonService {
|
||||
})
|
||||
}
|
||||
|
||||
static render({ message, count }) {
|
||||
static render({ period, rank }) {
|
||||
const count = Math.floor(100000 / rank)
|
||||
let message = ordinalNumber(rank)
|
||||
message += period === 'rt' ? '' : ' daily'
|
||||
return {
|
||||
message: message,
|
||||
color: floorCountColor(count, 10, 50, 100),
|
||||
}
|
||||
}
|
||||
|
||||
async handle({ info, repo }) {
|
||||
const json = await this.fetch({ info, repo })
|
||||
|
||||
const totalRank = info === 'rt'
|
||||
const rank = totalRank ? json[0].total_ranking : json[0].daily_ranking
|
||||
const count = Math.floor(100000 / rank)
|
||||
let message = ordinalNumber(rank)
|
||||
message += totalRank ? '' : ' daily'
|
||||
|
||||
return this.constructor.render({ message, count })
|
||||
async handle({ period, repo }) {
|
||||
const json = await this.fetch({ period, repo })
|
||||
const rank = period === 'rt' ? json[0].total_ranking : json[0].daily_ranking
|
||||
return this.constructor.render({ period, rank })
|
||||
}
|
||||
|
||||
// Metadata
|
||||
@@ -68,7 +65,7 @@ module.exports = class GemRank extends BaseJsonService {
|
||||
return {
|
||||
base: 'gem',
|
||||
format: '(rt|rd)/(.+)',
|
||||
capture: ['info', 'repo'],
|
||||
capture: ['period', 'repo'],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,12 +73,16 @@ module.exports = class GemRank extends BaseJsonService {
|
||||
return [
|
||||
{
|
||||
title: 'Gem download rank',
|
||||
previewUrl: 'rt/puppet',
|
||||
exampleUrl: 'rt/puppet',
|
||||
urlPattern: 'rt/:package',
|
||||
staticExample: this.render({ period: 'rt', rank: 332 }),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
{
|
||||
title: 'Gem download rank (daily)',
|
||||
previewUrl: 'rd/facter',
|
||||
exampleUrl: 'rd/facter',
|
||||
urlPattern: 'rd/:package',
|
||||
staticExample: this.render({ period: 'rd', rank: 656 }),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -55,7 +55,9 @@ module.exports = class GemVersion extends BaseJsonService {
|
||||
return [
|
||||
{
|
||||
title: 'Gem',
|
||||
previewUrl: 'formatador',
|
||||
exampleUrl: 'formatador',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ version: '2.1.0' }),
|
||||
keywords: ['ruby'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -23,7 +23,9 @@ class LibrariesIoDependentRepos extends LibrariesIoBase {
|
||||
return [
|
||||
{
|
||||
title: 'Dependent repos (via libraries.io)',
|
||||
previewUrl: 'npm/got',
|
||||
exampleUrl: 'npm/got',
|
||||
urlPattern: ':platform/:library',
|
||||
staticExample: this.render({ dependentReposCount: 84000 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -23,7 +23,9 @@ class LibrariesIoDependents extends LibrariesIoBase {
|
||||
return [
|
||||
{
|
||||
title: 'Dependents (via libraries.io)',
|
||||
previewUrl: 'npm/got',
|
||||
exampleUrl: 'npm/got',
|
||||
urlPattern: ':platform/:library',
|
||||
staticExample: this.render({ dependentCount: 2000 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -24,7 +24,9 @@ class LibrariesIoSourcerank extends LibrariesIoBase {
|
||||
return [
|
||||
{
|
||||
title: 'Libraries.io SourceRank',
|
||||
previewUrl: 'npm/got',
|
||||
exampleUrl: 'npm/got',
|
||||
urlPattern: ':platform/:library',
|
||||
staticExample: this.render({ rank: 25 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@@ -62,7 +62,9 @@ function DownloadsForInterval(interval) {
|
||||
return [
|
||||
{
|
||||
title: 'npm',
|
||||
previewUrl: 'localeval',
|
||||
exampleUrl: 'localeval',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ downloads: 30000 }),
|
||||
keywords: ['node'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -20,11 +20,15 @@ module.exports = class NpmLicense extends NpmBase {
|
||||
static get examples() {
|
||||
return [
|
||||
{
|
||||
previewUrl: 'express',
|
||||
exampleUrl: 'express',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ licenses: ['MIT'] }),
|
||||
keywords: ['node'],
|
||||
},
|
||||
{
|
||||
previewUrl: 'express',
|
||||
exampleUrl: 'express',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ licenses: ['MIT'] }),
|
||||
query: { registry_uri: 'https://registry.npmjs.com' },
|
||||
keywords: ['node'],
|
||||
},
|
||||
|
||||
@@ -28,28 +28,38 @@ module.exports = class NpmVersion extends NpmBase {
|
||||
return [
|
||||
{
|
||||
title: 'npm',
|
||||
previewUrl: 'npm',
|
||||
exampleUrl: 'npm',
|
||||
urlPattern: ':package',
|
||||
staticExample: this.render({ version: '6.3.0' }),
|
||||
keywords: ['node'],
|
||||
},
|
||||
{
|
||||
title: 'npm (scoped)',
|
||||
previewUrl: '@cycle/core',
|
||||
exampleUrl: '@cycle/core',
|
||||
urlPattern: ':scope/:package',
|
||||
staticExample: this.render({ version: '7.0.0' }),
|
||||
keywords: ['node'],
|
||||
},
|
||||
{
|
||||
title: 'npm (tag)',
|
||||
previewUrl: 'npm/next',
|
||||
exampleUrl: 'npm/next',
|
||||
urlPattern: ':package/:tag',
|
||||
staticExample: this.render({ tag: 'latest', version: '6.3.0' }),
|
||||
keywords: ['node'],
|
||||
},
|
||||
{
|
||||
title: 'npm (custom registry)',
|
||||
previewUrl: 'npm/next',
|
||||
exampleUrl: 'npm/next',
|
||||
urlPattern: ':package/:tag',
|
||||
staticExample: this.render({ tag: 'latest', version: '7.0.0' }),
|
||||
query: { registry_uri: 'https://registry.npmjs.com' },
|
||||
keywords: ['node'],
|
||||
},
|
||||
{
|
||||
title: 'npm (scoped with tag)',
|
||||
previewUrl: '@cycle/core/canary',
|
||||
exampleUrl: '@cycle/core/canary',
|
||||
staticExample: this.render({ tag: 'latest', version: '6.3.0' }),
|
||||
urlPattern: ':scope/:package/:tag',
|
||||
keywords: ['node'],
|
||||
},
|
||||
]
|
||||
|
||||
@@ -24,16 +24,20 @@ module.exports = class UptimeRobotRatio extends UptimeRobotBase {
|
||||
return [
|
||||
{
|
||||
title: 'Uptime Robot ratio (30 days)',
|
||||
previewUrl: 'm778918918-3e92c097147760ee39d02d36',
|
||||
exampleUrl: 'm778918918-3e92c097147760ee39d02d36',
|
||||
urlPattern: ':monitor-specific-key',
|
||||
staticExample: this.render({ ratio: 100 }),
|
||||
},
|
||||
{
|
||||
title: 'Uptime Robot ratio (7 days)',
|
||||
previewUrl: '7/m778918918-3e92c097147760ee39d02d36',
|
||||
exampleUrl: '7/m778918918-3e92c097147760ee39d02d36',
|
||||
urlPattern: '7/:monitor-specific-key',
|
||||
staticExample: this.render({ ratio: 100 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static async render({ ratio }) {
|
||||
static render({ ratio }) {
|
||||
return {
|
||||
message: `${ratio}%`,
|
||||
color: ratioColor(ratio),
|
||||
|
||||
@@ -21,12 +21,14 @@ module.exports = class UptimeRobotStatus extends UptimeRobotBase {
|
||||
return [
|
||||
{
|
||||
title: 'Uptime Robot status',
|
||||
previewUrl: 'm778918918-3e92c097147760ee39d02d36',
|
||||
exampleUrl: 'm778918918-3e92c097147760ee39d02d36',
|
||||
urlPattern: ':monitor-specific-key',
|
||||
staticExample: this.render({ status: 2 }),
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
static async render({ status }) {
|
||||
static render({ status }) {
|
||||
switch (status) {
|
||||
case 0:
|
||||
return { message: 'paused', color: 'yellow' }
|
||||
|
||||
Reference in New Issue
Block a user