From 4dd5bd2f0b4ac76f1aa3a97c1ddae3298c4b28c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=99=8B=E6=99=93=E7=82=9C=20Amio=20/?= Date: Sun, 14 Jun 2020 17:40:19 +0800 Subject: [PATCH] badge(memo): add memo badge (#399) * chore: bump deps * badge: add /memo badge (resolve #398) * chore: add help for memo badge * chore: clean code * fix: support html entities in url --- api/memo.ts | 49 +++++++++++++++++++++++++++++++++++ libs/create-badgen-handler.ts | 44 +++++++++++++++++++------------ nodemon.json | 4 +-- package-lock.json | 32 ++++++++++++----------- 4 files changed, 96 insertions(+), 33 deletions(-) create mode 100644 api/memo.ts diff --git a/api/memo.ts b/api/memo.ts new file mode 100644 index 0000000..d4c45a4 --- /dev/null +++ b/api/memo.ts @@ -0,0 +1,49 @@ +import got from '../libs/got' +import { createBadgenHandler, PathArgs } from '../libs/create-badgen-handler' + +const help = ` +A badge with memories + +## Usage + +Update a badge with a \`PUT\` request: + + curl -X PUT https://badgen.net/memo/a-public-writable-badge/coverage/75%25/orange + +Then you have it: + + https://badgen.net/memo/a-public-writable-badge + +![](https://badgen.net/badge/coverage/75%25/orange) + +## Limits + +Up to 1 write per second per badge. + +## Caveat + +Since everyone can write to any badge, it's recommended to add a uuid suffix to badge name: + + https://badgen.net/memo/my-coverage-badge-df3ff1af-4703-435a-b4ea-20a38e711c7d + +For uuid, you may grab one at https://uuid.now.sh +` + +export default createBadgenHandler({ + title: 'Memo', + help, + examples: { + '/memo/deployed': 'memoized badge for deploy status', + }, + handlers: { + '/memo/:name': handler + } +}) + +async function handler ({ name }: PathArgs) { + const endpoint = `https://badgen-store.amio.workers.dev/${name}` + const data = await got(endpoint).json() + data.subject = data.subject || data.label + + return data +} diff --git a/libs/create-badgen-handler.ts b/libs/create-badgen-handler.ts index 17b8ac9..f6c36a8 100644 --- a/libs/create-badgen-handler.ts +++ b/libs/create-badgen-handler.ts @@ -3,6 +3,7 @@ import matchRoute from 'my-way' import urlParse from 'url-parse' import { measure } from 'measurement-protocol' +import got from './got' import fetchIcon from './fetch-icon' import serveBadge from './serve-badge' import serveDoc from './serve-doc' @@ -51,30 +52,41 @@ export function createBadgenHandler (conf: BadgenServeConfig): BadgenHandler { return res.end() } - // Match handler - let matchedArgs: ReturnType = null - const matchedScheme = Object.keys(conf.handlers).find(scheme => { - return matchedArgs = matchRoute(scheme, decodeURI(pathname)) - }) - - // Serve docs - if (!matchedScheme) { - if (matchRoute('/:name', url)) { - return serveDoc(conf)(req, res) - } else { - return serve404(req, res) - } - } - const defaultLabel = pathname.split('/')[1] + const defaultParams = { subject: defaultLabel, status: 'unknown', color: 'grey' } - // Serve badge try { + // Match handler + let matchedArgs: ReturnType = null + const matchedScheme = Object.keys(conf.handlers).find(scheme => { + return matchedArgs = matchRoute(scheme, decodeURI(pathname)) + }) + + if (!matchedScheme) { + // Serve docs + if (matchRoute('/:name', url)) { + return serveDoc(conf)(req, res) + } + + // handle PUT requests + if (req.method === 'PUT') { + const memoArgs = matchRoute('/memo/:name/:label/:status/:color?', url) + if (memoArgs) { + const memoApi = `https://badgen-store.amio.workers.dev/${url.substr(6)}` + const putResult = await got.put(memoApi).text() + return res.end(putResult) + } + } + + return serve404(req, res) + } + + // Invoke badge handler const badgeParamsPromise = conf.handlers[matchedScheme](matchedArgs || {}) let iconPromise: Promise = Promise.resolve(undefined) diff --git a/nodemon.json b/nodemon.json index 8df7053..7607cb6 100644 --- a/nodemon.json +++ b/nodemon.json @@ -11,8 +11,8 @@ }, "watch": [ "index.ts", - "endpoints", - "libs" + "libs", + "api" ], "env": { "PUB_DIR": "dist" diff --git a/package-lock.json b/package-lock.json index 4201622..680975c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1569,20 +1569,20 @@ } }, "@babel/plugin-transform-react-jsx-development": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.10.1.tgz", - "integrity": "sha512-XwDy/FFoCfw9wGFtdn5Z+dHh6HXKHkC6DwKNWpN74VWinUagZfDcEJc3Y8Dn5B3WMVnAllX8Kviaw7MtC5Epwg==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.9.0.tgz", + "integrity": "sha512-tK8hWKrQncVvrhvtOiPpKrQjfNX3DtkNLSX4ObuGcpS9p0QrGetKmlySIGR07y48Zft8WVgPakqd/bk46JrMSw==", "dev": true, "requires": { - "@babel/helper-builder-react-jsx-experimental": "^7.10.1", - "@babel/helper-plugin-utils": "^7.10.1", - "@babel/plugin-syntax-jsx": "^7.10.1" + "@babel/helper-builder-react-jsx-experimental": "^7.9.0", + "@babel/helper-plugin-utils": "^7.8.3", + "@babel/plugin-syntax-jsx": "^7.8.3" }, "dependencies": { "@babel/helper-plugin-utils": { - "version": "7.10.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", - "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", + "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true } } @@ -6828,6 +6828,14 @@ "dev": true, "requires": { "yallist": "^3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } } }, "lru_map": { @@ -11614,12 +11622,6 @@ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, "yaml": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",