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

forgejo-ts

v0.2.0

Published

Zero-dependency TypeScript client for the Forgejo REST API

Downloads

555

Readme

forgejo-ts

Zero-dependency TypeScript client for the Forgejo REST API. Works with Forgejo, Gitea, and Codeberg instances.

Features

  • Zero external dependencies (uses Node.js built-in fetch)
  • Dual ESM + CommonJS builds
  • Full TypeScript types for all API responses
  • Injectable logger interface
  • Typed error classes (ForgejoApiError, ForgejoNetworkError)
  • Covers pull requests, issues, CI/actions, tags, releases, file contents, reviews, and more
  • Raw API escape hatch for any endpoint not covered by typed methods

Installation

# From git (recommended for now)
npm install git+https://git.araj.me/maxking/forgejo-ts.git

Quick Start

import { ForgejoClient, ForgejoApiError } from 'forgejo-ts';

const client = new ForgejoClient({
  instanceUrl: 'https://codeberg.org',
  token: 'your-api-token',        // optional for public repos
  timeout: 30000,                  // optional, default 30s
});

// List open pull requests
const prs = await client.listPullRequests('owner', 'repo', 'open');

// Get issue details
const issue = await client.getIssue('owner', 'repo', 42);

// Create a pull request
const pr = await client.createPullRequest('owner', 'repo', 'My PR', 'feature-branch', 'main', 'Description');

// Error handling
try {
  await client.getPullRequest('owner', 'repo', 999);
} catch (err) {
  if (err instanceof ForgejoApiError) {
    console.error(err.statusCode, err.responseBody);
  }
}

API

Constructor

new ForgejoClient(options: {
  instanceUrl: string;   // e.g. "https://codeberg.org"
  token?: string;        // personal access token
  logger?: ForgejoLogger; // custom logger (default: silent)
  timeout?: number;      // request timeout in ms (default: 30000)
})

Methods

| Category | Method | Description | |----------|--------|-------------| | Connection | testConnection() | Test connectivity, returns boolean | | Pull Requests | | | | | listPullRequests(owner, repo, state?) | List PRs (paginates automatically) | | | getPullRequest(owner, repo, number) | Get PR details | | | createPullRequest(owner, repo, title, head, base, body?) | Create a PR | | | updatePullRequest(owner, repo, number, updates) | Update PR title/body/state | | | mergePullRequest(owner, repo, number, method?, deleteBranch?) | Merge a PR | | | closePullRequest(owner, repo, number) | Close a PR | | | getPullRequestFiles(owner, repo, number) | List changed files | | | getPullRequestRefs(owner, repo, number) | Get head/base branch refs | | | getPullRequestReviews(owner, repo, number) | List reviews | | | getPullRequestCommits(owner, repo, number) | List commits | | Reviews | | | | | getReviewComments(owner, repo, prNumber, reviewId) | Get review comments | | | createReview(owner, repo, number, state, body) | Create a review | | | createReviewWithComments(owner, repo, prNumber, options) | Create review with inline comments | | Issues | | | | | listIssues(owner, repo, state?) | List issues (PRs filtered out) | | | getIssue(owner, repo, number) | Get issue details | | | createIssue(owner, repo, title, body?) | Create an issue | | | updateIssue(owner, repo, number, updates) | Update issue title/body/state | | | getIssueComments(owner, repo, number) | List comments | | | createComment(owner, repo, number, body) | Add a comment | | | getIssueTimeline(owner, repo, number) | Get timeline events | | Files | | | | | getFileContents(owner, repo, filepath, ref) | Get decoded file contents | | CI / Actions | | | | | listWorkflowRuns(owner, repo, options?) | List workflow runs (paginates) | | | getWorkflowRun(owner, repo, runId) | Get run details | | | getWorkflowJobs(owner, repo, runId) | Get jobs for a run | | | getWorkflowLogs(owner, repo, runNumber, jobIndex?) | Fetch job logs | | | getJobSteps(owner, repo, runNumber, jobIndex?) | Parse step summaries | | | rerunWorkflow(owner, repo, runId) | Re-run a workflow | | | getCommitStatuses(owner, repo, sha) | Get commit statuses | | Tags | | | | | listTags(owner, repo) | List tags | | | createTag(owner, repo, options) | Create a tag | | | deleteTag(owner, repo, tagName) | Delete a tag | | Releases | | | | | listReleases(owner, repo) | List releases | | | createRelease(owner, repo, options) | Create a release | | | getRelease(owner, repo, id) | Get release by ID | | | getReleaseByTag(owner, repo, tag) | Get release by tag name | | | deleteRelease(owner, repo, id) | Delete a release | | Raw | | | | | rawRequest(method, endpoint, body?) | Escape hatch for any endpoint |

Custom Logger

Inject your own logger to capture client activity:

import { ForgejoClient, ForgejoLogger } from 'forgejo-ts';

const logger: ForgejoLogger = {
  debug: (msg, ...args) => console.debug('[forgejo]', msg, ...args),
  info:  (msg, ...args) => console.info('[forgejo]', msg, ...args),
  warn:  (msg, ...args) => console.warn('[forgejo]', msg, ...args),
  error: (msg, ...args) => console.error('[forgejo]', msg, ...args),
};

const client = new ForgejoClient({
  instanceUrl: 'https://codeberg.org',
  token: 'your-token',
  logger,
});

Error Types

  • ForgejoApiError -- HTTP error from the API. Has statusCode, statusText, responseBody.
  • ForgejoNetworkError -- Network/timeout error. Has url, cause.
  • Both extend ForgejoError which extends Error.

Development

npm install
npm run build       # dual ESM + CJS build
npm test            # unit tests (68 tests)
npm run test:coverage  # with coverage report
npm run test:live   # live tests (requires FORGEJO_TEST_URL and FORGEJO_TEST_TOKEN)
npm run lint        # type check

License

Apache-2.0