diff --git a/services/spiget/spiget-base.js b/services/spiget/spiget-base.js new file mode 100644 index 0000000000000000000000000000000000000000..be2885939a12c43febaceb8b270317d0dedc951d --- /dev/null +++ b/services/spiget/spiget-base.js @@ -0,0 +1,46 @@ +'use strict' + +const Joi = require('joi') +const BaseJsonService = require('../base-json') + +const resourceSchema = Joi.object({ + downloads: Joi.number().required(), + file: Joi.object({ + size: Joi.number().required(), + sizeUnit: Joi.string().required(), + }).required(), + testedVersions: Joi.array(), + rating: Joi.object({ + count: Joi.number().required(), + average: Joi.number().required(), + }).required(), +}).required() + +const documentation = ` +<p>You can find your resource ID in the url for your resource page.</p> +<p>Example: <code>https://www.spigotmc.org/resources/essentialsx.9089/</code> - Here the Resource ID is 9089.</p>` + +const keywords = ['spigot', 'spigotmc'] + +class BaseSpigetService extends BaseJsonService { + async fetch({ + resourceid, + schema = resourceSchema, + url = `https://api.spiget.org/v2/resources/${resourceid}`, + }) { + return this._requestJson({ + schema, + url, + }) + } + + static get defaultBadgeData() { + return { label: 'spiget' } + } + + static get category() { + return 'other' + } +} + +module.exports = { keywords, documentation, BaseSpigetService } diff --git a/services/spiget/spiget-download-size.service.js b/services/spiget/spiget-download-size.service.js new file mode 100644 index 0000000000000000000000000000000000000000..91fb611e6befdfaf0144ef8bdc731a2bc9a67fb0 --- /dev/null +++ b/services/spiget/spiget-download-size.service.js @@ -0,0 +1,47 @@ +'use strict' + +const { BaseSpigetService, documentation, keywords } = require('./spiget-base') + +module.exports = class SpigetDownloadSize extends BaseSpigetService { + static get route() { + return { + base: 'spiget/download-size', + pattern: ':resourceid', + } + } + + static get defaultBadgeData() { + return { + label: 'size', + color: 'blue', + } + } + + async handle({ resourceid }) { + const { file } = await this.fetch({ resourceid }) + return this.constructor.render({ size: file.size, unit: file.sizeUnit }) + } + + static render({ size, unit }) { + return { + message: `${size} ${unit}`, + } + } + + static get category() { + return 'size' + } + static get examples() { + return [ + { + title: 'Spiget Download Size', + namedParams: { + resourceid: '9089', + }, + staticPreview: this.render({ size: 2.5, unit: 'MB' }), + documentation, + keywords, + }, + ] + } +} diff --git a/services/spiget/spiget-download-size.tester.js b/services/spiget/spiget-download-size.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..d40c256f7d91472b865240e888ca378268a2848e --- /dev/null +++ b/services/spiget/spiget-download-size.tester.js @@ -0,0 +1,17 @@ +'use strict' + +const Joi = require('joi') +const { isFileSize } = require('../test-validators') + +const t = (module.exports = require('../create-service-tester')()) + +t.create('EssentialsX (id 9089)') + .get('/9089.json') + .expectJSONTypes(Joi.object().keys({ name: 'size', value: isFileSize })) + +t.create('Invalid Resource (id 1)') + .get('/1.json') + .expectJSON({ + name: 'size', + value: 'not found', + }) diff --git a/services/spiget/spiget-downloads.service.js b/services/spiget/spiget-downloads.service.js new file mode 100644 index 0000000000000000000000000000000000000000..31580e6661f2c116503620d41a5f0562521373b7 --- /dev/null +++ b/services/spiget/spiget-downloads.service.js @@ -0,0 +1,50 @@ +'use strict' + +const { BaseSpigetService, documentation, keywords } = require('./spiget-base') +const { metric } = require('../../lib/text-formatters') +const { downloadCount } = require('../../lib/color-formatters') + +module.exports = class SpigetDownloads extends BaseSpigetService { + static get route() { + return { + base: 'spiget/downloads', + pattern: ':resourceid', + } + } + + static get defaultBadgeData() { + return { + label: 'downloads', + } + } + + async handle({ resourceid }) { + const { downloads } = await this.fetch({ resourceid }) + return this.constructor.render({ downloads }) + } + + static render({ downloads }) { + return { + message: metric(downloads), + color: downloadCount(downloads), + } + } + + static get category() { + return 'downloads' + } + + static get examples() { + return [ + { + title: 'Spiget Downloads', + namedParams: { + resourceid: '9089', + }, + staticPreview: this.render({ downloads: 560891 }), + documentation, + keywords, + }, + ] + } +} diff --git a/services/spiget/spiget-downloads.tester.js b/services/spiget/spiget-downloads.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..761da8c7e74b55e5234bce7a621c34d98b2a36c2 --- /dev/null +++ b/services/spiget/spiget-downloads.tester.js @@ -0,0 +1,22 @@ +'use strict' + +const Joi = require('joi') +const { isMetric } = require('../test-validators') + +const t = (module.exports = require('../create-service-tester')()) + +t.create('EssentialsX (id 9089)') + .get('/9089.json') + .expectJSONTypes( + Joi.object().keys({ + name: 'downloads', + value: isMetric, + }) + ) + +t.create('Invalid Resource (id 1)') + .get('/1.json') + .expectJSON({ + name: 'downloads', + value: 'not found', + }) diff --git a/services/spiget/spiget-latest-version.service.js b/services/spiget/spiget-latest-version.service.js new file mode 100644 index 0000000000000000000000000000000000000000..79a43b54263e9f103982bd0df352fc8cfab1fed6 --- /dev/null +++ b/services/spiget/spiget-latest-version.service.js @@ -0,0 +1,53 @@ +'use strict' + +const { BaseSpigetService, documentation, keywords } = require('./spiget-base') + +const { renderVersionBadge } = require('../../lib/version') + +const Joi = require('joi') +const versionSchema = Joi.object({ + downloads: Joi.number().required(), + name: Joi.string().required(), +}).required() + +module.exports = class SpigetLatestVersion extends BaseSpigetService { + static get route() { + return { + base: 'spiget/version', + pattern: ':resourceid', + } + } + + static get defaultBadgeData() { + return { + label: 'version', + color: 'blue', + } + } + + async handle({ resourceid }) { + const { name } = await this.fetch({ + resourceid, + schema: versionSchema, + url: `https://api.spiget.org/v2/resources/${resourceid}/versions/latest`, + }) + return renderVersionBadge({ version: name }) + } + + static get category() { + return 'version' + } + static get examples() { + return [ + { + title: 'Spiget Version', + namedParams: { + resourceid: '9089', + }, + staticPreview: renderVersionBadge({ version: 2.1 }), + documentation, + keywords, + }, + ] + } +} diff --git a/services/spiget/spiget-latest-version.tester.js b/services/spiget/spiget-latest-version.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..f484295632749eb5845f3abfe27ea73f1e2585a3 --- /dev/null +++ b/services/spiget/spiget-latest-version.tester.js @@ -0,0 +1,24 @@ +'use strict' + +const Joi = require('joi') +const { withRegex } = require('../test-validators') + +const t = (module.exports = require('../create-service-tester')()) + +// Note that Spigot versions can be anything (including just a string), so we'll make sure it's not returning 'not found' + +t.create('EssentialsX (id 9089)') + .get('/9089.json') + .expectJSONTypes( + Joi.object().keys({ + name: 'version', + value: withRegex(/^(?!not found$)/), + }) + ) + +t.create('Invalid Resource (id 1)') + .get('/1.json') + .expectJSON({ + name: 'version', + value: 'not found', + }) diff --git a/services/spiget/spiget-rating.service.js b/services/spiget/spiget-rating.service.js new file mode 100644 index 0000000000000000000000000000000000000000..625e5d010e4a2da87fc86dc592040a63bb166f2c --- /dev/null +++ b/services/spiget/spiget-rating.service.js @@ -0,0 +1,71 @@ +'use strict' + +const { BaseSpigetService, documentation, keywords } = require('./spiget-base') + +const { starRating, metric } = require('../../lib/text-formatters') +const { floorCount } = require('../../lib/color-formatters') + +module.exports = class SpigetRatings extends BaseSpigetService { + static get route() { + return { + base: 'spiget', + pattern: ':format(rating|stars)/:resourceid', + } + } + + async handle({ format, resourceid }) { + const { rating } = await this.fetch({ resourceid }) + return this.constructor.render({ + format, + total: rating.count, + average: rating.average, + }) + } + + static render({ format, total, average }) { + const message = + format === 'stars' + ? starRating(average) + : `${average}/5 (${metric(total)})` + return { + message, + color: floorCount(average, 2, 3, 4), + } + } + + static get category() { + return 'rating' + } + + static get defaultBadgeData() { + return { label: 'rating' } + } + + static get examples() { + return [ + { + title: 'Spiget Stars', + pattern: 'stars/:resourceid', + namedParams: { + resourceid: '9089', + }, + staticPreview: this.render({ + format: 'stars', + total: 325, + average: 4.5, + }), + documentation, + }, + { + title: 'Spiget Rating', + pattern: 'rating/:resourceid', + namedParams: { + resourceid: '9089', + }, + staticPreview: this.render({ total: 325, average: 4.5 }), + documentation, + keywords, + }, + ] + } +} diff --git a/services/spiget/spiget-rating.tester.js b/services/spiget/spiget-rating.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..46263caa588f6ca012cd1dd730b4240e84af7e5e --- /dev/null +++ b/services/spiget/spiget-rating.tester.js @@ -0,0 +1,39 @@ +'use strict' + +const Joi = require('joi') + +const { isStarRating, withRegex } = require('../test-validators') + +const t = (module.exports = require('../create-service-tester')()) + +t.create('Stars - EssentialsX (id 9089)') + .get('/stars/9089.json') + .expectJSONTypes( + Joi.object().keys({ + name: 'rating', + value: isStarRating, + }) + ) + +t.create('Stars - Invalid Resource (id 1)') + .get('/stars/1.json') + .expectJSON({ + name: 'rating', + value: 'not found', + }) + +t.create('Rating - EssentialsX (id 9089)') + .get('/rating/9089.json') + .expectJSONTypes( + Joi.object().keys({ + name: 'rating', + value: withRegex(/^(\d*\.\d+)(\/5 \()(\d+)(\))$/), + }) + ) + +t.create('Rating - Invalid Resource (id 1)') + .get('/rating/1.json') + .expectJSON({ + name: 'rating', + value: 'not found', + }) diff --git a/services/spiget/spiget-tested-versions.service.js b/services/spiget/spiget-tested-versions.service.js new file mode 100644 index 0000000000000000000000000000000000000000..c647d4bf87677bbe260e1beadf8b16e716532a00 --- /dev/null +++ b/services/spiget/spiget-tested-versions.service.js @@ -0,0 +1,57 @@ +'use strict' + +const { BaseSpigetService, documentation, keywords } = require('./spiget-base') + +module.exports = class SpigetTestedVersions extends BaseSpigetService { + static get route() { + return { + base: 'spiget/tested-versions', + pattern: ':resourceid', + } + } + + static get defaultBadgeData() { + return { + label: 'tested versions', + color: 'blue', + } + } + + async handle({ resourceid }) { + const { testedVersions } = await this.fetch({ resourceid }) + const { versions } = this.transform({ testedVersions }) + return this.constructor.render({ versions }) + } + + transform({ testedVersions }) { + const earliest = testedVersions[0] + const latest = testedVersions.slice(-1)[0] + let versions = '' + if (earliest === latest) { + versions = earliest + } else { + versions = `${earliest}-${latest}` + } + return { versions } + } + + static render({ versions }) { + return { + message: versions, + } + } + + static get examples() { + return [ + { + title: 'Spiget Tested Versions', + namedParams: { + resourceid: '9089', + }, + staticPreview: this.render({ versions: '1.7-1.13' }), + documentation, + keywords, + }, + ] + } +} diff --git a/services/spiget/spiget-tested-versions.tester.js b/services/spiget/spiget-tested-versions.tester.js new file mode 100644 index 0000000000000000000000000000000000000000..696bc2d53fc010963e82dde5265ea00d925140f6 --- /dev/null +++ b/services/spiget/spiget-tested-versions.tester.js @@ -0,0 +1,71 @@ +'use strict' + +const Joi = require('joi') + +const t = (module.exports = require('../create-service-tester')()) + +const { withRegex } = require('../test-validators') + +const multipleVersions = withRegex(/^([+]?\d*\.\d+)(-)([+]?\d*\.\d+)$/) + +t.create('EssentialsX - multiple versions supported - (id 9089)') + .get('/9089.json') + .expectJSONTypes( + Joi.object().keys({ + name: 'tested versions', + value: multipleVersions, + }) + ) + +t.create('Invalid Resource (id 1)') + .get('/1.json') + .expectJSON({ + name: 'tested versions', + value: 'not found', + }) + +t.create('Nock - single version supported') + .get('/1.json') + .intercept(nock => + nock('https://api.spiget.org/v2/resources/') + .get('/1') + .reply(200, { + downloads: 1, + file: { + size: 1, + sizeUnit: '1', + }, + testedVersions: ['1.13'], + rating: { + count: 1, + average: 1, + }, + }) + ) + .expectJSON({ + name: 'tested versions', + value: '1.13', + }) + +t.create('Nock - multiple versions supported') + .get('/1.json') + .intercept(nock => + nock('https://api.spiget.org/v2/resources/') + .get('/1') + .reply(200, { + downloads: 1, + file: { + size: 1, + sizeUnit: '1', + }, + testedVersions: ['1.10', '1.11', '1.12', '1.13'], + rating: { + count: 1, + average: 1, + }, + }) + ) + .expectJSON({ + name: 'tested versions', + value: '1.10-1.13', + })