From 370a4a87b6c3278965923528b7156b0250446561 Mon Sep 17 00:00:00 2001 From: Kyle Brown Date: Wed, 15 Jul 2020 00:37:18 -0600 Subject: [PATCH] feat: allow customn npm and github endpoints (#412) * feat: allow customnpm and github endpoints Allow specifying of custom endpoints for NPM and Github. This is to allow usage in a self-hosted enterprise environment. These are configured by an override environment variable. `NPM_URL="https://registry.npm.compnay.com"` - NPM `GITHUB_URL="https://github.company.com/api/v3"` - Github v3 `GITHUB_URL_GRAPHQL="https://github.company.com/api/graphql" - Github Graphql * feat(npm): support all pkg data through npm reg - Add option to disable use of unpkg for npm "info" - Add ability to query scoped packages and tags through npm - Update env var names Note, this keeps existing logic unless DISABLE_UNPKG == true * fix(npm): fix if logic, remove elses * fix: address review comments - Address review comments - Query NPM with abbreviated metadata header support - Support GITHUB_TOKENS - Environment variable info in readme - Only skip unpkg use if a custom registry is used. --- README.md | 11 +++++++++++ api/npm.ts | 27 +++++++++++++++++++++++---- libs/github.ts | 13 ++++++++----- 3 files changed, 42 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 7ed7d28..4dcacc4 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,17 @@ Badgen use [Sentry](https://sentry.io) to collect errors for improving service, Badgen do not collect any identifying information. +## Environments + +Supported environment variables for managing a Badgen instance. + +- `GITHUB_TOKENS` - Comma delimited list of Github Tokens. Required for Github Badges +- `GITHUB_API` - Custom Github API endpoint. e.g., `https://github.mycompany.com/api/v3` +- `GITHUB_API_GRAPHQL` - Custom Github GraphQL API endpoint. e.g., `https://github.mycompany.com/api/graphql` +- `NPM_REGISTRY` - Custom NPM registry endpoint +- `SENTRY_DSN` - Sentry Error Monitoring Data Source Name +- `TRACKING_GA` - Google Analytics Tracking ID + ## Contributors Thanks to our [contributors][contributors-href] 🎉👏 diff --git a/api/npm.ts b/api/npm.ts index eee0804..ff32193 100644 --- a/api/npm.ts +++ b/api/npm.ts @@ -1,7 +1,7 @@ import cheerio from 'cheerio' import got from '../libs/got' import { millify, version, versionColor } from '../libs/utils' -import { createBadgenHandler, PathArgs } from '../libs/create-badgen-handler' +import { createBadgenHandler, PathArgs, BadgenError } from '../libs/create-badgen-handler' // https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md // https://github.com/npm/registry/blob/master/docs/download-counts.md @@ -68,9 +68,22 @@ async function handler ({ topic, scope, pkg, tag }: PathArgs) { } async function npmMetadata (pkg: string, ver = 'latest'): Promise { - // only works for ver === 'latest', none-scoped package - const endpoint = `https://registry.npmjs.org/${pkg}/${ver}` + const host = process.env.NPM_REGISTRY || 'https://registry.npmjs.org' + if (pkg.startsWith('@') || ver !== 'latest') { + const meta = await got(`${host}/${pkg}`, { + // support querying abbreviated metadata https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md + headers: { + accept: 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*' + } + }).json() + if (meta["dist-tags"][ver]) { + return meta.versions[meta["dist-tags"][ver]] + } + throw new BadgenError({ status: '404', color: 'grey', code: 404 }) + } + const endpoint = `${host}/${pkg}/${ver}` return got(endpoint).json() + } async function pkgJson (pkg: string, tag = 'latest'): Promise { @@ -80,7 +93,13 @@ async function pkgJson (pkg: string, tag = 'latest'): Promise { } async function info (topic: string, pkg: string, tag = 'latest') { - const meta = await (tag === 'latest' && pkg[0] !== '@' ? npmMetadata(pkg) : pkgJson(pkg, tag)) + // ver === 'latest', non-scoped package use npmMetadata (npm), all others use unpkg + // optionally disable unpkg to request all info from NPM + const meta = await( + process.env.NPM_REGISTRY || (tag === "latest" && pkg.startsWith('@')) + ? npmMetadata(pkg, tag) + : pkgJson(pkg, tag) + ) switch (topic) { case 'version': { diff --git a/libs/github.ts b/libs/github.ts index b34ed7a..f47d048 100644 --- a/libs/github.ts +++ b/libs/github.ts @@ -9,7 +9,7 @@ export function restGithub(path: string, preview = 'hellcat') { authorization: `token ${pickGithubToken()}`, accept: `application/vnd.github.${preview}-preview+json` } - const prefixUrl = 'https://api.github.com/' + const prefixUrl = process.env.GITHUB_API || 'https://api.github.com/' return got.get(path, { prefixUrl, headers }).json() } @@ -20,14 +20,17 @@ export function queryGithub(query) { accept: 'application/vnd.github.hawkgirl-preview+json' } const json = { query } - return got.post('https://api.github.com/graphql', { json, headers }).json() + const endpoint = + process.env.GITHUB_API_GRAPHQL || 'https://api.github.com/graphql' + return got.post(endpoint, { json, headers }).json() } function pickGithubToken() { - const { GH_TOKENS } = process.env - if (!GH_TOKENS) { + const { GH_TOKENS, GITHUB_TOKENS } = process.env + const githubTokens = GITHUB_TOKENS || GH_TOKENS + if (!githubTokens) { throw new BadgenError({ status: 'token required' }) } - const tokens = GH_TOKENS.split(',').map(segment => segment.trim()) + const tokens = githubTokens.split(',').map(segment => segment.trim()) return rand(tokens) }