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

@pagopa/dx-tasks

v0.2.5

Published

Readme

@pagopa/dx-tasks

Reusable task implementations and a small dispatcher for DX orchestration tools.

Available tasks

| Task | Description | | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- | | terraformPlan | Runs terraform plan for a module path, handles common flags, and masks sensitive output before printing it. | | renderReport | Reads the persisted reports under .dx-tasks and renders them in a target format (currently markdown) to stdout, using per-namespace renderers. | | prComment | Adds a comment to a GitHub pull request, optionally replacing existing comments that match a search pattern. | | reportPrComment | Renders persisted reports and posts the rendered Markdown as a GitHub pull request comment. |

Dispatcher

Tasks are meant to run through a dispatcher. The dispatcher is responsible for decoding payloads, wiring the shared reporter context, and selecting the right task definition.

Public API

  • createTaskDispatcher() creates an empty dispatcher.
  • registerTask(task) registers a task definition.
  • dispatchTask(name, payload) decodes the payload and runs the matching task, returning Promise<unknown> because dispatch selects tasks dynamically by name.
  • @pagopa/dx-tasks/tasks exports the built-in task definitions, such as terraformPlanTask.
  • createDefaultTaskDispatcher() creates a dispatcher with the built-in tasks already registered.

Default dispatcher example

Here we create one shared report store, inject it when creating the default dispatcher, and dispatch terraformPlan with reporting enabled.

import {
  createDefaultTaskDispatcher,
  ReportStore,
  terraformPlanReportNamespace,
} from "@pagopa/dx-tasks";

const reports = new ReportStore(process.cwd()).register(
  terraformPlanReportNamespace,
);
const dispatcher = createDefaultTaskDispatcher({ reports });

await dispatcher.dispatchTask("terraformPlan", {
  modulePath: "./infra/modules/example",
  out: "plan.tfplan",
  refresh: true,
  report: true,
  verbose: false,
});

This prints the masked Terraform output to stdout and writes the JSON report under:

.dx-tasks/terraform-plan/Li9pbmZyYS9tb2R1bGVzL2V4YW1wbGU.json

The terraform-plan namespace is registered once on the shared report store, so other tasks can safely reuse the same ReportStore instance without overwriting each other's reports.

Custom dispatcher example

If you want to control which built-in tasks are available, register them explicitly from @pagopa/dx-tasks/tasks.

import {
  createTaskDispatcher,
  ReportStore,
  terraformPlanReportNamespace,
} from "@pagopa/dx-tasks";
import { terraformPlanTask } from "@pagopa/dx-tasks/tasks";

const reports = new ReportStore(process.cwd()).register(
  terraformPlanReportNamespace,
);
const dispatcher = createTaskDispatcher({
  context: { reports },
});

dispatcher.registerTask(terraformPlanTask);

await dispatcher.dispatchTask(terraformPlanTask.name, {
  modulePath: "./infra/modules/example",
  report: true,
});

For payload details and task-specific behavior, see the task definitions and implementations in src/.

Commenting on pull requests

The prComment task creates a GitHub pull request comment. Pass explicit repository and PR coordinates, direct Markdown content, and optionally a title rendered as an H2 before the body, a Markdown footer rendered after a --- separator, or a search pattern to delete matching older comments before creating the new one.

import { createDefaultTaskDispatcher } from "@pagopa/dx-tasks";

const dispatcher = createDefaultTaskDispatcher();

await dispatcher.dispatchTask("prComment", {
  commentBody: "### Build Results\n\nBuild completed successfully.",
  footer: "_Generated by dx-tasks_",
  githubToken: process.env.GITHUB_TOKEN,
  issueNumber: 123,
  owner: "pagopa",
  repo: "dx",
  searchPattern: "Build Results",
  title: "Build Results",
});

If githubToken is omitted, the task reads GITHUB_TOKEN from the environment.

Posting rendered reports on pull requests

The reportPrComment task combines report rendering with pull request commenting. Use it as the final orchestration step after all report-producing tasks have completed.

import { createDefaultTaskDispatcher } from "@pagopa/dx-tasks";

const dispatcher = createDefaultTaskDispatcher();

await dispatcher.dispatchTask("reportPrComment", {
  footer: "_Generated by dx-tasks_",
  githubToken: process.env.GITHUB_TOKEN,
  issueNumber: 123,
  owner: "pagopa",
  repo: "dx",
  searchPattern: "<!-- dx-report -->",
  sourceUrl: "https://github.com/pagopa/dx/actions/runs/123456",
  title: "Terraform Plan",
});

If title is provided, the rendered report is posted after a ## heading with that title. If footer is provided, it is posted after the rendered report with a --- separator. If the rendered report is empty, the task skips comment creation and returns undefined. If sourceUrl is provided, report renderers can use it to link back to the source workflow run or artifact. If githubToken is omitted, the task reads GITHUB_TOKEN from the environment through the underlying prComment implementation.

Rendering reports

The renderReport task is the inverse of the ReportStore: it reads the JSON artifacts written under .dx-tasks and renders them in a target format (currently markdown) to stdout.

Rendering is modular and format-aware: each report namespace registers a renderer for a specific (namespace, format) pair through the ReportStore. Namespaces found on disk with no renderer registered for the requested format are skipped, so an empty registry produces empty output.

import { createDefaultTaskDispatcher } from "@pagopa/dx-tasks";

const dispatcher = createDefaultTaskDispatcher();

// Prints the merged Markdown of every report under .dx-tasks that has a
// registered "markdown" renderer (e.g. terraform-plan).
await dispatcher.dispatchTask("renderReport", { format: "markdown" });

The default dispatcher pre-registers the built-in terraform-plan Markdown renderer, which receives all Terraform plan reports and produces one status title per module. Terraform warnings and errors are rendered as GitHub Markdown notices before the summary line. Full plan outputs are never included in the Markdown comment, keeping comments compact even across many plans and linking back to sourceUrl, when provided, and report artifacts for the complete output.

### Terraform Plans

#### Module: `./infra/modules/example` - ✅ Success

> [!WARNING]
> Warning: Deprecated attribute
>
> The attribute "foo" is deprecated.

Plan: 0 to add, 1 to change, 0 to destroy.

> [!NOTE]
> Full plan output is not included in this comment.
> See the workflow run logs or downloaded Terraform plan report artifacts for the complete output.

To control which namespaces/formats are renderable, build your own ReportStore and register namespaces with renderers explicitly:

import {
  createTaskDispatcher,
  ReportStore,
  terraformPlanReportNamespace,
} from "@pagopa/dx-tasks";
import { renderReportTask } from "@pagopa/dx-tasks/tasks";

const reports = new ReportStore(process.cwd()).register(
  terraformPlanReportNamespace,
);

const dispatcher = createTaskDispatcher({ context: { reports } });
dispatcher.registerTask(renderReportTask);

await dispatcher.dispatchTask(renderReportTask.name, { format: "markdown" });