Refactor [bundlephobia] (#3132)
This commit is contained in:
committed by
chris48s
parent
eb453401e3
commit
cc0f1fc6db
@@ -1,24 +1,41 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const Joi = require('joi')
|
||||||
const prettyBytes = require('pretty-bytes')
|
const prettyBytes = require('pretty-bytes')
|
||||||
const { makeBadgeData: getBadgeData } = require('../../lib/badge-data')
|
const { BaseJsonService } = require('..')
|
||||||
const LegacyService = require('../legacy-service')
|
const { nonNegativeInteger } = require('../validators')
|
||||||
|
|
||||||
// This legacy service should be rewritten to use e.g. BaseJsonService.
|
const schema = Joi.object({
|
||||||
//
|
size: nonNegativeInteger,
|
||||||
// Tips for rewriting:
|
gzip: nonNegativeInteger,
|
||||||
// https://github.com/badges/shields/blob/master/doc/rewriting-services.md
|
}).required()
|
||||||
//
|
|
||||||
// Do not base new services on this code.
|
const keywords = ['node', 'bundlephobia']
|
||||||
module.exports = class Bundlephobia extends LegacyService {
|
|
||||||
|
module.exports = class Bundlephobia extends BaseJsonService {
|
||||||
static get category() {
|
static get category() {
|
||||||
return 'size'
|
return 'size'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get defaultBadgeData() {
|
||||||
|
return {
|
||||||
|
label: 'bundlephobia',
|
||||||
|
color: 'informational',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static get route() {
|
static get route() {
|
||||||
return {
|
return {
|
||||||
base: 'bundlephobia',
|
base: 'bundlephobia',
|
||||||
pattern: '',
|
pattern: ':format(min|minzip)/:scope(@[^/]+)?/:packageName/:version?',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static render({ format, size }) {
|
||||||
|
const label = format === 'min' ? 'minified size' : 'minzipped size'
|
||||||
|
return {
|
||||||
|
label,
|
||||||
|
message: prettyBytes(size),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,78 +44,68 @@ module.exports = class Bundlephobia extends LegacyService {
|
|||||||
{
|
{
|
||||||
title: 'npm bundle size',
|
title: 'npm bundle size',
|
||||||
pattern: ':format(min|minzip)/:packageName',
|
pattern: ':format(min|minzip)/:packageName',
|
||||||
namedParams: { format: 'minzip', packageName: 'react' },
|
namedParams: {
|
||||||
staticPreview: {
|
format: 'min',
|
||||||
label: 'minified size',
|
packageName: 'react',
|
||||||
message: '2.57 kB',
|
|
||||||
color: 'blue',
|
|
||||||
},
|
},
|
||||||
keywords: ['node'],
|
staticPreview: this.render({ format: 'min', size: 6652 }),
|
||||||
|
keywords,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'npm bundle size (scoped)',
|
||||||
|
pattern: ':format(min|minzip)/:scope/:packageName',
|
||||||
|
namedParams: {
|
||||||
|
format: 'min',
|
||||||
|
scope: '@cycle',
|
||||||
|
packageName: 'core',
|
||||||
|
},
|
||||||
|
staticPreview: this.render({ format: 'min', size: 3562 }),
|
||||||
|
keywords,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'npm bundle size (version)',
|
||||||
|
pattern: ':format(min|minzip)/:packageName/:version',
|
||||||
|
namedParams: {
|
||||||
|
format: 'min',
|
||||||
|
packageName: 'react',
|
||||||
|
version: '15.0.0',
|
||||||
|
},
|
||||||
|
staticPreview: this.render({ format: 'min', size: 20535 }),
|
||||||
|
keywords,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'npm bundle size (scoped version)',
|
||||||
|
pattern: ':format(min|minzip)/:scope/:packageName/:version',
|
||||||
|
namedParams: {
|
||||||
|
format: 'min',
|
||||||
|
scope: '@cycle',
|
||||||
|
packageName: 'core',
|
||||||
|
version: '7.0.0',
|
||||||
|
},
|
||||||
|
staticPreview: this.render({ format: 'min', size: 3562 }),
|
||||||
|
keywords,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
static registerLegacyRouteHandler({ camp, cache }) {
|
async fetch({ scope, packageName, version }) {
|
||||||
camp.route(
|
const packageQuery = `${scope ? `${scope}/` : ''}${packageName}${
|
||||||
/^\/bundlephobia\/(min|minzip)\/(?:@([^/]+)?\/)?([^/]+)?(?:\/([^/]+)?)?\.(svg|png|gif|jpg|json)?$/,
|
version ? `@${version}` : ''
|
||||||
cache((data, match, sendBadge, request) => {
|
}`
|
||||||
// A: /bundlephobia/(min|minzip)/:package.:format
|
const options = { qs: { package: packageQuery } }
|
||||||
// B: /bundlephobia/(min|minzip)/:package/:version.:format
|
return this._requestJson({
|
||||||
// C: /bundlephobia/(min|minzip)/@:scope/:package.:format
|
schema,
|
||||||
// D: /bundlephobia/(min|minzip)/@:scope/:package/:version.:format
|
url: 'https://bundlephobia.com/api/size',
|
||||||
const resultType = match[1]
|
options,
|
||||||
const scope = match[2]
|
errorMessages: {
|
||||||
const packageName = match[3]
|
404: 'package or version not found',
|
||||||
const packageVersion = match[4]
|
},
|
||||||
const format = match[5]
|
})
|
||||||
const showMin = resultType === 'min'
|
}
|
||||||
|
|
||||||
const badgeData = getBadgeData(
|
async handle({ format, scope, packageName, version }) {
|
||||||
showMin ? 'minified size' : 'minzipped size',
|
const json = await this.fetch({ scope, packageName, version })
|
||||||
data
|
const size = format === 'min' ? json.size : json.gzip
|
||||||
)
|
return this.constructor.render({ format, size })
|
||||||
|
|
||||||
let packageString =
|
|
||||||
typeof scope === 'string' ? `@${scope}/${packageName}` : packageName
|
|
||||||
|
|
||||||
if (packageVersion) {
|
|
||||||
packageString += `@${packageVersion}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const requestOptions = {
|
|
||||||
url: 'https://bundlephobia.com/api/size',
|
|
||||||
qs: {
|
|
||||||
package: packageString,
|
|
||||||
},
|
|
||||||
json: true,
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* `ErrorCode` => `error code`
|
|
||||||
* @param {string} code
|
|
||||||
* @returns {string}
|
|
||||||
*/
|
|
||||||
const formatErrorCode = code =>
|
|
||||||
code
|
|
||||||
.replace(/([A-Z])/g, ' $1')
|
|
||||||
.trim()
|
|
||||||
.toLowerCase()
|
|
||||||
|
|
||||||
request(requestOptions, (error, response, body) => {
|
|
||||||
if (typeof body !== 'object' || body === null) {
|
|
||||||
badgeData.text[1] = 'error'
|
|
||||||
badgeData.colorscheme = 'red'
|
|
||||||
} else if (error !== null || body.error) {
|
|
||||||
badgeData.text[1] =
|
|
||||||
'code' in body.error ? formatErrorCode(body.error.code) : 'error'
|
|
||||||
badgeData.colorscheme = 'red'
|
|
||||||
} else {
|
|
||||||
badgeData.text[1] = prettyBytes(showMin ? body.size : body.gzip)
|
|
||||||
badgeData.colorscheme = 'blue'
|
|
||||||
}
|
|
||||||
sendBadge(format, badgeData)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { isFileSize } = require('../test-validators')
|
const { isFileSize } = require('../test-validators')
|
||||||
const { ServiceTester } = require('../tester')
|
const t = (module.exports = require('../tester').createServiceTester())
|
||||||
|
|
||||||
const t = (module.exports = new ServiceTester({
|
|
||||||
id: 'bundlephobia',
|
|
||||||
title: 'NPM package bundle size',
|
|
||||||
}))
|
|
||||||
|
|
||||||
const formats = {
|
const formats = {
|
||||||
A: '/bundlephobia/:type/:package.:format',
|
A: '/bundlephobia/:type/:package.:format',
|
||||||
@@ -59,12 +54,12 @@ const data = [
|
|||||||
{
|
{
|
||||||
format: formats.A,
|
format: formats.A,
|
||||||
get: '/min/some-no-exist.json',
|
get: '/min/some-no-exist.json',
|
||||||
expect: { label: 'minified size', message: 'package not found error' },
|
expect: { label: 'bundlephobia', message: 'package or version not found' },
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
format: formats.C,
|
format: formats.C,
|
||||||
get: '/min/@some-no-exist/some-no-exist.json',
|
get: '/min/@some-no-exist/some-no-exist.json',
|
||||||
expect: { label: 'minified size', message: 'package not found error' },
|
expect: { label: 'bundlephobia', message: 'package or version not found' },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user