npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@askalf/git-providers

v0.0.2

Published

Unified GitHub + GitLab + Bitbucket Cloud REST clients behind one GitProvider interface (user info, list repos, list branches, OAuth config). Plus a 40+ entry api-key-provider taxonomy for cloud / CI / PM / monitoring vendors. Zero runtime deps.

Readme

@askalf/git-providers

One interface for GitHub + GitLab + Bitbucket Cloud. User info, repos, branches, OAuth config — same shape across all three. Plus a 40+ entry taxonomy for non-OAuth API-key providers (cloud / CI/CD / PM / monitoring / e-commerce / marketing / ...).

npm install @askalf/git-providers

CI npm License

Why

Building a tool that integrates with "your git provider"? You don't actually want three implementations. You want one GitProvider interface and a registry that hands you the right adapter at runtime. That's all this package is.

Zero runtime dependencies. Native fetch. ~600 lines of TypeScript total.

Use it

import { getProvider, getOAuthConfig, isValidProvider } from '@askalf/git-providers';

const provider = getProvider('github');
const user = await provider.getUserInfo(accessToken);
const repos = await provider.listRepos(accessToken);
const branches = await provider.getBranches(accessToken, 'askalf/git-providers');

// OAuth config (reads $GITHUB_CLIENT_ID + $GITHUB_CLIENT_SECRET by default)
const oauth = getOAuthConfig('github');
//  → { clientId, clientSecret, authorizeUrl, tokenUrl, scopes }

if (isValidProvider(req.body.provider)) {
  const adapter = getProvider(req.body.provider);
  // ...
}

The GitProvider interface

interface GitProvider {
  getUserInfo(accessToken: string): Promise<GitProviderUserInfo>;
  listRepos(accessToken: string): Promise<GitRepo[]>;
  getBranches(accessToken: string, repoFullName: string): Promise<GitBranch[]>;
}

interface GitRepo {
  fullName: string;        // 'owner/name'
  url: string;             // web URL
  cloneUrl: string;        // https clone URL
  defaultBranch: string;   // 'main' / 'master' / etc
  isPrivate: boolean;
  description: string | null;
  language: string | null;  // null on GitLab list-projects
}

interface GitBranch {
  name: string;
  isDefault: boolean;
}

repoFullName uses the owner/name shape across all three providers; the GitLab adapter URL-encodes it to the v4 API's namespace%2Fproject form internally.

Self-hosted (GHE / self-hosted GitLab)

The default singletons (githubProvider, gitlabProvider, bitbucketProvider) talk to the public clouds. For GitHub Enterprise Server or self-hosted GitLab, build a custom one:

import { createGitHubProvider, createGitLabProvider } from '@askalf/git-providers';

const ghe = createGitHubProvider({
  baseUrl: 'https://github.example.com/api/v3',
});
const gl = createGitLabProvider({
  baseUrl: 'https://gitlab.example.com/api/v4',
});

await ghe.listRepos(token);
await gl.listRepos(token);

Bitbucket Cloud has only one API origin. Bitbucket Server (the self-hosted product, formerly Stash) uses a totally different API and isn't covered here — open an issue if you need it.

OAuth config

Each provider exports a getXxxOAuthConfig({ clientId?, clientSecret? }) helper. With no args, it reads <PROVIDER>_CLIENT_ID / <PROVIDER>_CLIENT_SECRET from process.env and returns null if either is missing. Pass options to bypass env entirely:

import { getGitHubOAuthConfig, getGitLabOAuthConfig } from '@askalf/git-providers';

const cfg = getGitHubOAuthConfig({
  clientId: process.env.MY_GH_CLIENT_ID,
  clientSecret: process.env.MY_GH_CLIENT_SECRET,
});

// Self-hosted GitLab — also override the OAuth host:
const gl = getGitLabOAuthConfig({
  clientId: '...',
  clientSecret: '...',
  oauthHost: 'https://gitlab.example.com',
});

API key provider taxonomy

A separate sub-export ships a 40+ entry catalog of API-key (non-OAuth) providers — useful for any app that lets users bring their own credentials for cloud / CI / project-management / monitoring / commerce / marketing / etc. tools.

import {
  API_KEY_PROVIDERS,
  PROVIDER_CONFIGS,
  testApiKeyIntegration,
} from '@askalf/git-providers/api-key-providers';

// What providers do we know about?
console.log(API_KEY_PROVIDERS);
// ['aws', 'gcp', 'azure', 'digitalocean', 'vercel', 'netlify', 'railway', 'flyio',
//  'jira', 'linear', 'notion', 'asana', 'datadog', 'sentry', 'pagerduty', ...]

// What does each one need?
PROVIDER_CONFIGS['stripe']
// → {
//     name: 'Stripe',
//     category: 'ecommerce',
//     requiredFields: [{ key: 'secret_key', label: 'Secret Key', sensitive: true }],
//     testEndpoint: 'https://api.stripe.com/v1/balance',
//     testHeaders: (c) => ({ Authorization: `Bearer ${c.secret_key}` }),
//   }

// Test a connection (10s timeout, SSRF-safe):
const result = await testApiKeyIntegration('stripe', { secret_key: 'sk_test_...' });
// → { success: true,  message: 'Connected to Stripe' }
// or { success: false, message: 'Stripe returned 401: Unauthorized' }

testApiKeyIntegration has SSRF-safe URL construction for the two providers (Jira, Grafana) where part of the URL is built from user input — Jira domains are constrained to *.atlassian.net, Grafana URLs are forced through a URL-parser + protocol allowlist.

What's NOT covered

  • Bitbucket Server (self-hosted, formerly Stash) — different API, different shape.
  • Pull-request / issue / commit / file-content endpoints — only user info + repos + branches + OAuth config. Open an issue if you need more; most are mechanical to add.
  • Webhook signing / payload parsing — different concern, not bundled here.
  • Token refresh — we accept access tokens, we don't manage them.

License

MIT — see LICENSE.

Also by askalf

| Project | What it does | |---------|-------------| | arnie | Portable IT troubleshooting companion. Networking, AD, Windows Update, package managers, log triage, hardware checks. | | brio | Capability layer for AI workloads — semantic cache, cost tiering, policy. Sits in front of any Anthropic-compat endpoint. | | browser-bridge | Stealth headless Chromium in a container. CDP on 9222 — Playwright/Puppeteer/MCP-compatible. | | claude-bridge | Bridge Claude Code sessions to Discord. | | dario | Local LLM router. Use your Claude Max/Pro subscription as an API. | | deepdive | Local research agent. Plan → search → fetch → extract → synthesize. Cited answers. | | hands | Cross-platform computer-use agent. Mouse, keyboard, screen. | | install-kit | curl-pipe-bash template for self-hosted Docker apps. | | pgflex | One Postgres API. Two modes (real PG ↔ PGlite WASM). | | redisflex | One Redis API. Two modes (ioredis ↔ in-process). |