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

@xyne/connector-sdk

v0.1.3

Published

Connectors for @xyne/workflow-sdk: steps, triggers and credential types for external services.

Readme

@xyne/connector-sdk

Connectors for @xyne/workflow-sdk. A connector packages an external service's credential types, steps and triggers, so a host adds the whole service with one registration:

import { ConnectorRegistry } from '@xyne/workflow-sdk';
import { GitHubConnector } from '@xyne/connector-sdk/github';

const connectors = new ConnectorRegistry();
connectors.register(new GitHubConnector());

Each connector has its own entry point (@xyne/connector-sdk/github), so a host only loads the connectors it registers.

GitHub

| Kind | Type | Starts or does | |---|---|---| | Step | github.create_issue | Opens an issue | | Step | github.create_comment | Comments on an issue or pull request | | Step | github.get_pull_request | Fetches a pull request | | Trigger | github.pull_request | A pull request is opened, updated, closed or changed | | Trigger | github.pull_request_review | A pull request review is submitted, edited or dismissed | | Trigger | github.pull_request_review_comment | Someone comments on a line or file in a pull request's diff | | Trigger | github.issues | An issue is opened, edited, closed or changed | | Trigger | github.issue_comment | Someone comments on an issue or on a pull request's conversation |

Credential types:

  • GITHUB_TOKEN (bearer) — used by the steps. A personal access token with access to the repositories the workflow uses. GitHub App installation tokens expire after an hour, so they do not work as a stored token.
  • GITHUB_WEBHOOK_SECRET (secret) — used by the triggers to verify each delivery.

Every step and trigger produces the same camelCase summaries (GitHubPullRequestSummary, GitHubIssueSummary, …), so a pull request from a trigger has the same shape as one a step fetched. Every trigger also outputs payload: the delivery exactly as GitHub sent it, for any field the summaries leave out.

Webhook setup

  1. Save the workflow and copy its ID.
  2. In GitHub, add a webhook to the repository or organization:
    • Payload URL: the workflow router's public URL followed by /webhooks/<workflow id>
    • Content type: application/json
    • Secret: a long random string
    • Events: the one the trigger handles
  3. Store the same secret as a GitHub webhook secret credential and select it on the trigger.
  4. Activate the workflow. Deliveries to an inactive workflow are rejected.

A delivery with a missing or wrong X-Hub-Signature-256 is rejected. GitHub's ping, other events, and actions the author did not select are acknowledged without starting a run.

Starting a workflow when a comment is added

GitHub sends comments as three different events. Use the trigger for the comments you want, and subscribe the webhook to the matching event:

| Comment | Trigger | Webhook event in GitHub | |---|---|---| | On an issue, or on a pull request's conversation | github.issue_comment | Issue comments | | On a line or file in a pull request's diff | github.pull_request_review_comment | Pull request review comments | | A review's summary, when approving, requesting changes or commenting | github.pull_request_review | Pull request reviews |

Submitting a review with inline comments sends one pull request review event, and one review comment event per inline comment.

  • Set actions to created (submitted for reviews) so edits and deletions do not start runs.
  • On github.issue_comment, filter on {{trigger.isPullRequest}} equals true to react to pull requests only.
  • On github.pull_request_review, {{trigger.review.body}} is null when the reviewer left no comment.
  • A workflow that replies with a comment triggers itself again. Filter out its own comments, for example {{trigger.sender.login}} not equal to the account the token belongs to.
  • {{trigger.comment.authorAssociation}} says how the author relates to the repository (OWNER, MEMBER, COLLABORATOR, CONTRIBUTOR, NONE, …), for commands only maintainers may run.

Options

new GitHubConnector({ apiBaseUrl: 'https://github.example.com/api/v3' }); // GitHub Enterprise Server

Bitbucket

Works with self-hosted Bitbucket (Data Center, formerly Server): its REST API and webhook events.

import { BitbucketConnector } from '@xyne/connector-sdk/bitbucket';

connectors.register(
  new BitbucketConnector({ apiBaseUrl: 'https://bitbucket.example.com/rest/api/latest' }),
);

apiBaseUrl is the instance's REST API root. A bare instance URL also works: /rest/api/latest is appended. Only the steps call it. Rate-limited calls (a 429, or the 403 "rate limit" a WAF in front of the instance may send) are retried up to three times, honouring Retry-After.

| Kind | Type | Starts or does | |---|---|---| | Trigger | bitbucket.pull_request | A pull request is opened, gets new commits, has its target branch changed, is modified, merged, declined or deleted | | Trigger | bitbucket.pull_request_review | A reviewer approves, unapproves or requests changes, or reviewers are added or removed | | Trigger | bitbucket.pull_request_comment | A comment on a pull request is added, edited or deleted | | Trigger | bitbucket.push | Branches or tags are pushed, created or deleted | | Step | bitbucket.create_pull_request_comment | Comments on a pull request, or replies to a comment | | Step | bitbucket.get_pull_request | Fetches a pull request |

Bitbucket names what happened only in the X-Event-Key header, so each trigger maps the event keys it handles to the actions an author selects:

| Trigger | Action | Event key | |---|---|---| | pull_request | opened | pr:opened | | | source_branch_updated | pr:from_ref_updated | | | target_branch_updated | pr:to_ref_updated | | | modified | pr:modified | | | merged, declined, deleted | pr:merged, pr:declined, pr:deleted | | pull_request_review | approved, unapproved | pr:reviewer:approved, pr:reviewer:unapproved | | | changes_requested | pr:reviewer:changes_requested, or pr:reviewer:needs_work on older versions | | | reviewers_updated | pr:reviewer:updated | | pull_request_comment | added, edited, deleted | pr:comment:added, pr:comment:edited, pr:comment:deleted | | push | — | repo:refs_changed |

Credential types:

  • BITBUCKET_TOKEN (bearer) — used by the steps. A personal HTTP access token (BBDC-…) for a user with access to the repositories the workflow uses. Project and repository tokens have no user behind them, so actions that need one can fail.
  • BITBUCKET_WEBHOOK_SECRET (secret) — used by the triggers to verify each request.

Every trigger outputs action, eventKey, requestId, occurredAt, actor, repository and payload (the event exactly as Bitbucket sent it), beside its event's own summaries. Summary timestamps are ISO strings.

Webhook setup

  1. Save the workflow and copy its ID.
  2. In Bitbucket, open the repository's Repository settings → Webhooks and create a webhook:
    • URL: the workflow router's public URL followed by /webhooks/<workflow id>
    • Secret: a long random string
    • Events: the ones the trigger handles, from the table above
  3. Store the same secret as a Bitbucket webhook secret credential and select it on the trigger.
  4. Activate the workflow. Requests to an inactive workflow are rejected.

Test connection is answered with a 200 without starting a run. A request with a missing or wrong X-Hub-Signature is rejected. Other events, and actions the author did not select, are acknowledged without starting a run.

  • A workflow that replies with a comment triggers itself again. Filter out its own comments, for example {{trigger.actor.name}} not equal to the token's user.
  • To reply in the same thread, pass {{trigger.comment.id}} as the comment step's parentCommentId. {{trigger.comment.parentId}} is set when the comment is itself a reply.

Adding a connector

Give it its own folder with the same layout:

src/<connector>/
  connector.ts     the BaseConnector subclass
  credentials.ts   a defineCredential(...) per credential type
  constants.ts     connector id, step and trigger type ids, API constants
  steps/           one file per step, plus a shared base class
  triggers/        one file per trigger, plus a shared base class
  types/           schemas and types for API resources, webhook payloads and outputs
  utils/           API client, signature checks, mappers
  index.ts         the connector's public entry point

Then re-export it from src/index.ts and add ./<connector> to exports in package.json. Type ids are namespaced by connector (<connector-id>.<name>), and credential types are prefixed with it (GITHUB_TOKEN), so no two connectors can collide.