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
|
const waitings = {} // Cache ongoing fetching, prevent redundant request
|
||||||
|
|
||||||
module.exports = Object.entries(liveFns).map(([name, fn]) => {
|
module.exports = async function fetchLiveParams (scope, fn, paramsPath) {
|
||||||
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) {
|
|
||||||
const fetchKey = `#${scope} ${paramsPath}`
|
const fetchKey = `#${scope} ${paramsPath}`
|
||||||
if (waitings[fetchKey]) return waitings[fetchKey]
|
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": [
|
"alias": [
|
||||||
"badgen",
|
"badgen",
|
||||||
"badgen.net",
|
"badgen.net",
|
||||||
"flat.badgen.net"
|
"flat.badgen.net",
|
||||||
|
"api.badgen.net"
|
||||||
],
|
],
|
||||||
"public": true,
|
|
||||||
"files": [
|
"files": [
|
||||||
"package-lock.json",
|
"package-lock.json",
|
||||||
"service.js",
|
"service.js",
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@
|
||||||
"dev": "micro-dev service.js -s",
|
"dev": "micro-dev service.js -s",
|
||||||
"pretest": "npm run lint",
|
"pretest": "npm run lint",
|
||||||
"test": "tap test/*.js --reporter spec -j12",
|
"test": "tap test/*.js --reporter spec -j12",
|
||||||
"start": "micro service.js",
|
"start": "node service.js",
|
||||||
"precanary": "now alias rm badgen-canary -y -T amio",
|
"precanary": "now alias rm badgen-canary -y -T amio",
|
||||||
"canary": "now -T amio && now alias badgen-canary -T amio",
|
"canary": "now -T amio && now alias badgen-canary -T amio",
|
||||||
"predeploy": "now rm badgen-service --safe -y -T amio || true",
|
"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": {
|
"dependencies": {
|
||||||
"axios": "^0.18.0",
|
"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 serve404 = require('./libs/serve-404.js')
|
||||||
const serveDocs = require('./libs/serve-docs.js')
|
const serveDocs = require('./libs/serve-docs.js')
|
||||||
const serveBadge = require('./libs/serve-badge.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('/*', serve404),
|
||||||
get('/', serveIndex),
|
get('/', serveIndex),
|
||||||
get('/docs/:topic', serveDocs),
|
get('/docs/:topic', serveDocs),
|
||||||
|
|
@ -15,9 +16,19 @@ module.exports = router()(
|
||||||
get('/favicon.svg', serveFavicon),
|
get('/favicon.svg', serveFavicon),
|
||||||
get('/badge/:subject/:status', (req, res) => serveBadge(req, res)),
|
get('/badge/:subject/:status', (req, res) => serveBadge(req, res)),
|
||||||
get('/badge/:subject/:status/:color', (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) {
|
if (require.main === module) {
|
||||||
micro(module.exports).listen(3000)
|
micro(module.exports).listen(3000)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Ładowanie…
Reference in New Issue