kopia lustrzana https://github.com/badgen/badgen.net
feat: add api server (#74)
Mainly two purposes: 1. Provide https://api.badgen.net 2. Serve this api behind Now CDN as a cache layerpull/75/head
rodzic
dfd20495ab
commit
fdb7ab493b
|
|
@ -0,0 +1,6 @@
|
|||
# api.badgen.net
|
||||
|
||||
## Examples
|
||||
|
||||
- https://api.badgen.net/npm/v/micro
|
||||
- https://api.badgen.net/npm/dependents/got
|
||||
|
|
@ -1,26 +1,6 @@
|
|||
const { get } = require('micro-fork')
|
||||
const liveFns = require('./live-fns/_index.js')
|
||||
const serveBadge = require('./serve-badge.js')
|
||||
const waitings = {} // Cache ongoing fetching, prevent redundant request
|
||||
|
||||
module.exports = Object.entries(liveFns).map(([name, fn]) => {
|
||||
return get(`/${name}/*`, async (req, res) => {
|
||||
const style = req.headers.host === 'flat.badgen.net' ? 'flat' : undefined
|
||||
const {
|
||||
subject = name,
|
||||
status = 'unknown',
|
||||
color = 'grey',
|
||||
failed = false
|
||||
} = await fetchLiveParams(name, fn, req.params['*'])
|
||||
|
||||
req.params = { subject, status, color, style }
|
||||
serveBadge(req, res, {
|
||||
maxAge: failed ? '0' : (Math.random() * 60 + 60).toFixed()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
async function fetchLiveParams (scope, fn, paramsPath) {
|
||||
module.exports = async function fetchLiveParams (scope, fn, paramsPath) {
|
||||
const fetchKey = `#${scope} ${paramsPath}`
|
||||
if (waitings[fetchKey]) return waitings[fetchKey]
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
const axios = require('./axios.js')
|
||||
const { get } = require('micro-fork')
|
||||
const liveFns = require('./live-fns/_index.js')
|
||||
const serveBadge = require('./serve-badge.js')
|
||||
const liveFetcher = require('./live-fetcher.js')
|
||||
|
||||
const { API_HOST } = process.env
|
||||
|
||||
module.exports = Object.entries(liveFns).map(([name, fn]) => {
|
||||
return get(`/${name}/*`, async (req, res) => {
|
||||
const {
|
||||
subject = name,
|
||||
status = 'unknown',
|
||||
color = 'grey',
|
||||
failed = false
|
||||
} = await (API_HOST
|
||||
? axios(API_HOST + req.url).then(res => res.data)
|
||||
: liveFetcher(name, fn, req.params['*'])
|
||||
)
|
||||
|
||||
const style = req.headers.host === 'flat.badgen.net' ? 'flat' : undefined
|
||||
req.params = { subject, status, color, style }
|
||||
serveBadge(req, res, {
|
||||
maxAge: failed ? '0' : (Math.random() * 60 + 60).toFixed()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const { send } = require('micro')
|
||||
const { router, get } = require('micro-fork')
|
||||
const liveFunctions = require('./live-fns/_index.js')
|
||||
const liveFetcher = require('./live-fetcher.js')
|
||||
|
||||
const CACHE_CONTROL = `public, max-age=60, stale-while-revalidate=86400, stale-if-error=86400`
|
||||
const sMaxAges = {
|
||||
'github': '240'
|
||||
}
|
||||
|
||||
const apiHandlers = Object.entries(liveFunctions).map(([name, fn]) => {
|
||||
return get(`/${name}/*`, async (req, res) => {
|
||||
res.setHeader('Cache-Control', `${CACHE_CONTROL}, s-maxage=${sMaxAges[name] || '120'}`)
|
||||
send(res, 200, await liveFetcher(name, fn, req.params['*']))
|
||||
})
|
||||
})
|
||||
|
||||
const indexContent = fs.readFileSync(path.join(__dirname, 'index-api.md'), 'utf8')
|
||||
const serveIndex = (req, res) => send(res, 200, indexContent)
|
||||
|
||||
module.exports = router()(
|
||||
get('/', serveIndex),
|
||||
...apiHandlers
|
||||
)
|
||||
4
now.json
4
now.json
|
|
@ -2,9 +2,9 @@
|
|||
"alias": [
|
||||
"badgen",
|
||||
"badgen.net",
|
||||
"flat.badgen.net"
|
||||
"flat.badgen.net",
|
||||
"api.badgen.net"
|
||||
],
|
||||
"public": true,
|
||||
"files": [
|
||||
"package-lock.json",
|
||||
"service.js",
|
||||
|
|
|
|||
|
|
@ -9,11 +9,11 @@
|
|||
"dev": "micro-dev service.js -s",
|
||||
"pretest": "npm run lint",
|
||||
"test": "tap test/*.js --reporter spec -j12",
|
||||
"start": "micro service.js",
|
||||
"start": "node service.js",
|
||||
"precanary": "now alias rm badgen-canary -y -T amio",
|
||||
"canary": "now -T amio && now alias badgen-canary -T amio",
|
||||
"predeploy": "now rm badgen-service --safe -y -T amio || true",
|
||||
"deploy": "now -T amio && now alias -T amio"
|
||||
"deploy": "now -T amio -e API_HOST='https://api.badgen.net'"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.18.0",
|
||||
|
|
|
|||
17
service.js
17
service.js
|
|
@ -5,9 +5,10 @@ const serveIndex = require('./libs/serve-index.js')
|
|||
const serve404 = require('./libs/serve-404.js')
|
||||
const serveDocs = require('./libs/serve-docs.js')
|
||||
const serveBadge = require('./libs/serve-badge.js')
|
||||
const liveBadgeHandlers = require('./libs/live-badge-handlers.js')
|
||||
const liveHandlers = require('./libs/live-handlers.js')
|
||||
const serveApi = require('./libs/serve-api.js')
|
||||
|
||||
module.exports = router()(
|
||||
const main = router()(
|
||||
get('/*', serve404),
|
||||
get('/', serveIndex),
|
||||
get('/docs/:topic', serveDocs),
|
||||
|
|
@ -15,9 +16,19 @@ module.exports = router()(
|
|||
get('/favicon.svg', serveFavicon),
|
||||
get('/badge/:subject/:status', (req, res) => serveBadge(req, res)),
|
||||
get('/badge/:subject/:status/:color', (req, res) => serveBadge(req, res)),
|
||||
...liveBadgeHandlers
|
||||
...liveHandlers
|
||||
)
|
||||
|
||||
module.exports = function (req, res) {
|
||||
switch (req.headers.host) {
|
||||
case 'api.badgen.net':
|
||||
case '127.0.0.1:3000':
|
||||
return serveApi(req, res)
|
||||
default:
|
||||
return main(req, res)
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
micro(module.exports).listen(3000)
|
||||
}
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue