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

sf-cat

v2.1.2

Published

Convert Salesforce Code Analyzer reports to CI/CD-compatible formats

Readme

sf-cat

NPM Downloads/week GitHub Marketplace License Maintainability codecov Mutation testing badge

Converts Salesforce Code Analyzer output into formats consumable by external code quality platforms — SonarQube, GitHub Code Scanning, Azure DevOps, GitLab, Jenkins, and other SARIF-, CodeClimate-, or JUnit-compatible tools.

Use sf-cat as either a native GitHub Action or a Salesforce CLI plugin.

How It Works

Salesforce Code Analyzer scans Apex, Visualforce, Flows, Lightning components, and other Salesforce source using engines such as PMD, ESLint, RetireJS, and Salesforce Graph Engine. Its JSON output isn't directly compatible with many external code quality platforms.

sf-cat provides a single conversion step between Code Analyzer and your platform of choice:

Salesforce Code Analyzer → JSON → sf-cat → SonarQube / SARIF / CodeClimate / JUnit / GitHub

Supported output formats:

| Format | Use with | | --- | --- | | sonar | SonarQube / SonarCloud generic issue data | | sarif | GitHub Code Scanning, Azure DevOps, GitLab, Qodana, and other SARIF consumers | | codeclimate | GitLab Code Quality, CodeClimate engines | | junit | Jenkins, GitHub Actions, GitLab, Azure DevOps, CircleCI, Bitbucket Pipelines | | github | GitHub Actions inline annotations without GitHub Advanced Security |

GitHub Action

sf-cat is available as a native GitHub Action. Running sf-cat this way does not require the Salesforce CLI or an sf-cat plugin installation. The Action includes everything needed to transform an existing Salesforce Code Analyzer JSON report.

This differs from the Salesforce Code Analyzer GitHub Action, which requires the Salesforce CLI and the code-analyzer CLI plugin to be installed on the runner before Code Analyzer runs.

A typical workflow is:

  1. Install the Salesforce CLI and Salesforce Code Analyzer.
  2. Run Salesforce Code Analyzer to produce a JSON report.
  3. Pass that report to the sf-cat Action — no additional Salesforce CLI or sf-cat plugin installation is required for the transform step.
- name: Install Salesforce CLI
  run: npm install -g @salesforce/cli@latest

- name: Install Salesforce Code Analyzer
  run: sf plugins install code-analyzer@latest

- name: Run Salesforce Code Analyzer
  uses: forcedotcom/run-code-analyzer@v2
  with:
    run-arguments: --workspace ./force-app/main/default/ --rule-selector Recommended --output-file analyzer.json

- name: Transform Code Analyzer output
  id: transform
  uses: mcarvin8/sf-cat@v2
  with:
    input-file: analyzer.json
    format: sarif
    output-file: results.sarif

Inputs

| Input | Description | Required | Default | | --- | --- | --- | --- | | input-file | Path to the JSON file created by Salesforce Code Analyzer. | Yes | | | output-file | Path to the output file this Action creates. Defaults per format (see Command Reference). | No | | | format | Output format to produce: sonar, sarif, codeclimate, junit, or github. | No | sonar | | fail-on | Fail the Action when any violation has the given severity or higher. | No | never | | strip-prefix | Strip a leading prefix from every violation file path. Mutually exclusive with project-relative. | No | | | project-relative | Make every violation file path relative to the Salesforce DX project root. Mutually exclusive with strip-prefix. | No | false | | max-annotations | Maximum number of format: github annotations to emit. | No | 50 |

Outputs

| Output | Description | | --- | --- | | output-path | Path to the transformed report. Empty when format: github writes to stdout instead of a file. | | violations | Total number of violations in the input report. | | failures | Number of violations at or above the fail-on severity threshold. | | warnings | Newline-separated list of warnings emitted while transforming, if any. |

Fail the build on high-severity findings

Use fail-on to make the Action fail when findings meet or exceed a severity threshold. The transformed output is still written before the failing exit, so later steps can upload the report with if: always().

- name: Transform to SARIF and fail on high severity
  id: transform
  uses: mcarvin8/sf-cat@v2
  with:
    input-file: analyzer.json
    format: sarif
    output-file: results.sarif
    fail-on: high

- name: Upload SARIF
  if: always()
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

Salesforce CLI Plugin

Use the Salesforce CLI plugin when running sf-cat locally or from CI/CD platforms where the native GitHub Action isn't applicable.

Requirements

  • Salesforce CLI (sf)
  • Salesforce Code Analyzer v5 (sf code-analyzer)
  • Node.js 22.19 or later

Install

sf plugins install sf-cat@latest

Quick Start

Step 1 — Run Salesforce Code Analyzer and save its JSON output:

sf code-analyzer run --workspace "./force-app/main/default/" --rule-selector Recommended --output-file "analyzer.json"

sf code-analyzer run uses --output-file for its output path. sf-cat uses -f for the output format — these are different flags on different commands.

Step 2 — Transform the report with sf-cat:

sf cat transform -i "analyzer.json" -f <format> -o "results.<ext>"

For example:

sf cat transform -i "analyzer.json" -f sarif -o "results.sarif"

See the platform-specific examples below for each supported output format.

Output Formats

SonarQube

Convert Code Analyzer output into SonarQube generic issue data:

sf cat transform -i "analyzer.json" -o "sonar.json"

sonar is the default format, so -f sonar is optional.

Add the report to sonar-project.properties:

sonar.externalIssuesReportPaths=sonar.json

Or provide it directly to SonarScanner:

sonar-scanner -Dsonar.externalIssuesReportPaths=sonar.json

SARIF (GitHub Code Scanning, Azure DevOps, GitLab, ...)

Convert Code Analyzer output into SARIF v2.1.0:

sf cat transform -i "analyzer.json" -f sarif -o "results.sarif"

Each Code Analyzer engine (PMD, ESLint, RetireJS, SFGE, ...) is emitted as a separate SARIF run, allowing consumers to display them as distinct analysis tools.

Upload to GitHub Code Scanning:

- name: Upload SARIF
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: results.sarif

The same SARIF file can be consumed by Azure DevOps SARIF integrations, GitLab SAST artifacts, Qodana, and other SARIF v2.1.0-compatible tools.

CodeClimate / GitLab Code Quality

Convert Code Analyzer output into CodeClimate JSON:

sf cat transform -i "analyzer.json" -f codeclimate

The default output path is gl-code-quality-report.json, the conventional filename for GitLab Code Quality reports.

Each issue receives a stable fingerprint so GitLab can deduplicate findings across pipeline runs.

GitLab CI (gitlab-ci.yml):

sf-cat:
  script:
    - sf code-analyzer run --workspace ./force-app/main/default/ --rule-selector Recommended --output-file analyzer.json
    - sf cat transform -i analyzer.json -f codeclimate
  artifacts:
    reports:
      codequality: gl-code-quality-report.json

JUnit XML (Jenkins, GitHub Actions, GitLab, Azure DevOps, ...)

Use JUnit when your CI platform doesn't support SARIF, when GitHub Advanced Security isn't available, or when you want Code Analyzer violations to appear in the standard CI test results interface.

sf cat transform -i "analyzer.json" -f junit

Each Code Analyzer engine becomes a <testsuite> and each violation becomes a failing <testcase>.

The default output path is junit.xml.

Jenkins:

junit 'junit.xml'

GitHub Actions using dorny/test-reporter:

- uses: dorny/test-reporter@v2
  if: always()
  with:
    name: Salesforce Code Analyzer
    path: junit.xml
    reporter: java-junit

GitLab CI:

artifacts:
  reports:
    junit: junit.xml

Azure DevOps:

- task: PublishTestResults@2
  inputs:
    testResultsFormat: JUnit
    testResultsFiles: junit.xml

GitHub Actions workflow commands (inline PR annotations, no GHAS)

Use the github format when you want inline GitHub Actions annotations without uploading a SARIF report to GitHub Code Scanning.

sf-cat writes GitHub workflow commands such as:

::error file=force-app/main/default/classes/MyClass.cls,line=10::Violation message

The GitHub Actions runner converts these commands into workflow annotations automatically.

When using GitHub Actions, the native sf-cat Action is the recommended approach because it doesn't require installing the sf-cat Salesforce CLI plugin:

- name: Transform Code Analyzer output
  uses: mcarvin8/sf-cat@v2
  with:
    input-file: analyzer.json
    format: github

If you're using the Salesforce CLI plugin instead:

jobs:
  code-analysis:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Install Salesforce CLI
        run: npm install -g @salesforce/cli@latest

      - name: Install Salesforce Code Analyzer
        run: sf plugins install code-analyzer@latest

      - name: Install sf-cat
        run: sf plugins install sf-cat@latest

      - name: Run Salesforce Code Analyzer
        run: sf code-analyzer run --workspace ./force-app/main/default/ --rule-selector Recommended --output-file analyzer.json

      - name: Create GitHub annotations
        run: sf cat transform -i analyzer.json -f github

No upload-sarif step or GitHub Code Scanning configuration is required.

Severity is mapped to GitHub annotation levels as follows:

| Salesforce Code Analyzer severity | GitHub annotation | | --- | --- | | Critical | error | | High | error | | Moderate | warning | | Low | notice | | Info | notice |

Note: GitHub limits the number of annotations that can be displayed for a workflow step and may silently drop annotations beyond its limits. sf-cat applies a default --max-annotations value of 50 and emits a warning when the number of violations exceeds the configured limit. Use --max-annotations to adjust the value. For complete results, consider producing a SARIF, CodeClimate, or JUnit artifact in the same job.

Failing the Build on High-Severity Findings

--fail-on <severity> lets sf cat transform act as a CI quality gate.

The transformed output file is written first, then the process exits with code 1 if any violation meets or exceeds the configured threshold. This allows later CI steps to upload the report even when the quality gate fails.

sf cat transform \
  -i analyzer.json \
  -f sarif \
  -o results.sarif \
  --fail-on high

This example fails when at least one High or Critical violation exists while still writing results.sarif.

Severity ranking from highest to lowest:

critical → high → moderate → low → info

The default value is never, which disables failure based on violation severity.

Path Normalization

Salesforce Code Analyzer can produce absolute file paths on CI runners, for example:

/home/runner/work/myrepo/myrepo/force-app/main/default/classes/MyClass.cls

External tools commonly expect repository-relative paths. Absolute paths can prevent GitHub Code Scanning from anchoring findings to source files, produce inconsistent CodeClimate fingerprints across runners, or result in undesirable JUnit identifiers.

sf-cat provides two mutually exclusive path normalization options.

Strip a known prefix:

sf cat transform \
  -i analyzer.json \
  -f sarif \
  --strip-prefix "/home/runner/work/myrepo/myrepo/"

Automatically make paths relative to the Salesforce DX project root:

sf cat transform \
  -i analyzer.json \
  -f sarif \
  --project-relative

--project-relative walks upward from the current directory until it finds sfdx-project.json and uses that directory as the project root.

--strip-prefix and --project-relative are mutually exclusive. Use whichever option best matches your CI environment.

Column Data Handling

Salesforce Code Analyzer can report startColumn and endColumn values that exceed the actual length of the referenced source line. Some external tools reject these values and can fail to process the entire report.

sf-cat removes column values before generating output.

Line-level locations are preserved, while potentially invalid column data is omitted so downstream platforms can reliably consume the transformed report.

CLI Command Reference

sf cat transform

Transform Salesforce Code Analyzer results into a code quality format such as SonarQube, SARIF, CodeClimate / GitLab Code Quality, JUnit XML, or GitHub Actions workflow commands.

USAGE
  $ sf cat transform -i <value> [--json] [--flags-dir <value>] [-o <value>] [-f
    sonar|sarif|codeclimate|junit|github] [--fail-on critical|high|moderate|low|info|never] [--strip-prefix <value> |
    --project-relative] [--max-annotations <value>]

FLAGS
  -f, --format=<option>          [default: sonar] Output format to produce. One of: `sonar` (SonarQube generic issue
                                 data), `sarif` (SARIF v2.1.0), `codeclimate` (CodeClimate / GitLab Code Quality),
                                 `junit` (JUnit XML), or `github` (GitHub Actions workflow commands).
                                 <options: sonar|sarif|codeclimate|junit|github>
  -i, --input-file=<value>       (required) Path to the JSON file created by the Salesforce Code Analyzer plugin.
  -o, --output-file=<value>      Path to the output created by this plugin. Defaults to `output.json` for `sonar`,
                                 `output.sarif` for `sarif`, `gl-code-quality-report.json` for `codeclimate`,
                                 `junit.xml` for `junit`, and stdout for `github`.
      --fail-on=<option>         [default: never] Exit with code 1 when any violation has the given severity or higher.
                                 One of `critical`, `high`, `moderate`, `low`, `info`, or `never` (default). The output
                                 file is still written before the failing exit, so CI artifact uploads in later steps
                                 still see it.
                                 <options: critical|high|moderate|low|info|never>
      --max-annotations=<value>  [default: 50] Maximum number of GitHub Actions workflow command annotations to emit
                                 (only applies to `--format github`). GitHub silently drops annotations beyond its
                                 per-step cap; this flag lets you control how many are emitted and surfaces a warning
                                 when the total exceeds the limit. Defaults to 50.
      --project-relative         Make every violation file path relative to the Salesforce DX project root (resolved by
                                 walking upward from the current directory until an `sfdx-project.json` is found).
                                 Mutually exclusive with `--strip-prefix`.
      --strip-prefix=<value>     Strip a leading prefix from every violation file path before formatting (for example,
                                 `/home/runner/work/repo/repo/`). Useful when CI runners produce absolute paths that
                                 break GitHub Code Scanning anchors or CodeClimate fingerprints. Mutually exclusive with
                                 `--project-relative`.

GLOBAL FLAGS
  --flags-dir=<value>  Import flag values from a directory.
  --json               Format output as json.

DESCRIPTION
  Transform Salesforce Code Analyzer results into a code quality format such as SonarQube, SARIF, CodeClimate / GitLab
  Code Quality, JUnit XML, or GitHub Actions workflow commands.

  Transform Salesforce Code Analyzer results into a code quality format consumable by external tools. Supported formats:
  SonarQube generic issue data, SARIF v2.1.0 (GitHub Code Scanning, Azure DevOps, GitLab, etc.), CodeClimate JSON
  (GitLab Code Quality, CodeClimate engines), JUnit XML (Jenkins, GitHub Actions test reporters, GitLab, Azure DevOps,
  CircleCI, Bitbucket, etc.), and GitHub Actions workflow commands (inline PR annotations on GitHub without GHAS).

EXAMPLES
  `sf cat transform -i "sf-code-analyzer.json" -o "sonar.json"`

  `sf cat transform -i "sf-code-analyzer.json" -f sarif`

  `sf cat transform -i "sf-code-analyzer.json" -f codeclimate`

  `sf cat transform -i "sf-code-analyzer.json" -f junit`

  `sf cat transform -i "sf-code-analyzer.json" -f github`

  `sf cat transform -i "sf-code-analyzer.json" -f sarif -o "results.sarif"`

  `sf cat transform -i "sf-code-analyzer.json" --fail-on high`

  `sf cat transform -i "sf-code-analyzer.json" --project-relative`

See code: src/commands/cat/transform.ts

Issues

Found a bug or have an idea? Open an issue.

License

MIT