{"id":15679872,"url":"https://github.com/nvuillam/node-sarif-builder","last_synced_at":"2026-02-28T20:04:57.556Z","repository":{"id":44694437,"uuid":"446210118","full_name":"nvuillam/node-sarif-builder","owner":"nvuillam","description":"JS/TS library to easily build valid SARIF output from your javascript based SAST tools","archived":false,"fork":false,"pushed_at":"2026-02-26T02:12:27.000Z","size":1155,"stargazers_count":18,"open_issues_count":6,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-26T07:19:50.186Z","etag":null,"topics":["builder","code-quality","javascript","linters","nodejs","reports","sarif","sdk","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nvuillam.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["nvuillam"]}},"created_at":"2022-01-09T21:46:11.000Z","updated_at":"2026-02-22T03:38:40.000Z","dependencies_parsed_at":"2023-12-06T21:26:34.902Z","dependency_job_id":"fe9eadc2-0ff5-4edf-b8bd-13b7970a2651","html_url":"https://github.com/nvuillam/node-sarif-builder","commit_stats":{"total_commits":22,"total_committers":2,"mean_commits":11.0,"dds":"0.045454545454545414","last_synced_commit":"b2b4aafa0e2529b8a49768118277a8a59b073b5d"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/nvuillam/node-sarif-builder","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvuillam%2Fnode-sarif-builder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvuillam%2Fnode-sarif-builder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvuillam%2Fnode-sarif-builder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvuillam%2Fnode-sarif-builder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nvuillam","download_url":"https://codeload.github.com/nvuillam/node-sarif-builder/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nvuillam%2Fnode-sarif-builder/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29951108,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-28T18:42:55.706Z","status":"ssl_error","status_checked_at":"2026-02-28T18:42:48.811Z","response_time":90,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["builder","code-quality","javascript","linters","nodejs","reports","sarif","sdk","typescript"],"created_at":"2024-10-03T16:38:17.690Z","updated_at":"2026-02-28T20:04:57.547Z","avatar_url":"https://github.com/nvuillam.png","language":"TypeScript","funding_links":["https://github.com/sponsors/nvuillam"],"categories":[],"sub_categories":[],"readme":"# node-sarif-builder\n\n[![Version](https://img.shields.io/npm/v/node-sarif-builder.svg)](https://npmjs.org/package/node-sarif-builder)\n[![Downloads/week](https://img.shields.io/npm/dw/node-sarif-builder.svg)](https://npmjs.org/package/node-sarif-builder)\n[![Downloads/total](https://img.shields.io/npm/dt/node-sarif-builder.svg)](https://npmjs.org/package/node-sarif-builder)\u003c!-- gh-dependents-info-used-by-start --\u003e\n[![Generated by github-dependents-info](https://img.shields.io/static/v1?label=Used%20by\u0026message=5324\u0026color=informational\u0026logo=slickpic)](https://github.com/nvuillam/node-sarif-builder/blob/main/docs/github-dependents-info.md)\u003c!-- gh-dependents-info-used-by-end --\u003e\n[![Test](https://github.com/nvuillam/node-sarif-builder/workflows/Test/badge.svg?branch=main)](https://github.com/nvuillam/node-sarif-builder/actions?query=workflow%3ATest+branch%3Amain)\n[![Mega-Linter](https://github.com/nvuillam/node-sarif-builder/workflows/MegaLinter/badge.svg?branch=main)](https://megalinter.github.io/)\n[![GitHub contributors](https://img.shields.io/github/contributors/nvuillam/node-sarif-builder.svg)](https://github.com/nvuillam/node-sarif-builder/graphs/contributors/)\n[![GitHub stars](https://img.shields.io/github/stars/nvuillam/node-sarif-builder?label=stars\u0026maxAge=3600)](https://github.com/nvuillam/node-sarif-builder/stargazers/)\n[![License](https://img.shields.io/npm/l/node-sarif-builder.svg)](https://github.com/nvuillam/node-sarif-builder/blob/master/package.json)\n[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square)](http://makeapullrequest.com)\n\n## Introduction\n\nUntil today, every SAST tool (not exhaustive list available at \u003chttps://analysis-tools.dev/\u003e) is using its own custom output format.\n\nIn order to **unify SAST tools output format**, more and more tools and services are implementing [**SARIF format**](https://sarifweb.azurewebsites.net/) ([example](https://github.com/microsoft/sarif-tutorials/blob/main/samples/1-Introduction/simple-example.sarif))\n\nSARIF logs can be:\n- **Uploaded to DevOps tools**, like [Github](https://docs.github.com/en/code-security/code-scanning/integrating-with-code-scanning/sarif-support-for-code-scanning), [Azure DevOps](https://github.com/microsoft/sarif-azuredevops-extension) to show issues directly in their web UI \u003c!-- markdown-link-check-disable-line --\u003e\n- **Visualized in IDEs**, like [Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=MS-SarifVSCode.sarif-viewer), [Visual Studio](https://marketplace.visualstudio.com/items?itemName=WDGIS.MicrosoftSarifViewer), [Jetbrains editors](https://plugins.jetbrains.com/plugin/16938-qodana)\n- **Aggregated by multi-language linters**, like [MegaLinter](https://megalinter.io/latest/)\n\nExample of linters that can output logs in SARIF format:\n\n- bandit (python)\n- checkov (terraform)\n- checkstyle (java)\n- cfn-lint (AWS CloudFormation)\n- codeql (multi-language)\n- devskim (security)\n- eslint (javascript,typescript,json)\n- gitleaks (security)\n- ktlint (Kotlin)\n- hadolint (Dockerfile)\n- MegaLinter (linters orchestrator)\n- psalm (php)\n- semgrep (multi-language)\n- revive (Go)\n- tflint (terraform)\n- terrascan (terrasform)\n- trivy (security)\n- and many more...\n\nIf you are a **maintainer** of any **javascript/typescript based** SAST tool, but also IaC tool, or **any type of tool that can return a list of errors with a level of severity**, you can either:\n\n- read the whole [OASIS Specification](https://docs.oasis-open.org/sarif/sarif/v2.1.0/csprd01/sarif-v2.1.0-csprd01.html) and implement it\n- **simply use this library** to add SARIF as additional output format, so your tool will be natively compliant with any of SARIF-compliant tools !\n\n## Installation\n\n- with npm\n\n```shell\nnpm install node-sarif-builder\n```\n\n- with yarn\n\n```shell\nyarn add node-sarif-builder\n```\n\n## Use\n\nWith node-sarif-builder, you can generate complex SARIF format with simple methods\n\n___\n\n- Start by importing module\n\n```javascript\nconst { SarifBuilder, SarifRunBuilder, SarifResultBuilder, SarifRuleBuilder } = require(\"node-sarif-builder\");\n```\n\n___\n\n- Create and init **SarifBuilder** and **SarifRunBuilder** objects\n\n```javascript\n// SARIF builder\nconst sarifBuilder = new SarifBuilder();\n// SARIF Run builder\nconst sarifRunBuilder = new SarifRunBuilder().initSimple({\n    toolDriverName: \"npm-groovy-lint\",                           // Name of your analyzer tool\n    toolDriverVersion: \"9.0.5\",                                  // Version of your analyzer tool\n    url: \"https://nvuillam.github.io/npm-groovy-lint/\"           // Url of your analyzer tool\n});\n```\n\n___\n\n- Add all rules that can be found in your results (recommended but optional)\n\n```javascript\n// Add SARIF rules\nfor (const rule of rules) {                           // rules from your linter in any format\n    const sarifRuleBuiler = new SarifRuleBuilder().initSimple({\n        ruleId: rule.id,                              // ex: \"no-any\"\n        shortDescriptionText: rule.description,       // ex: \"Do not use any in your code !\"\n        helpUri: rule.docUrl                          // ex: \"http://my.linter.com/rules/no-any\"\n    });\n    sarifRunBuilder.addRule(sarifRuleBuiler);\n}\n```\n\n___\n\n- For each found issue, create a SarifResultBuilder and add it to the SarifRunBuilder object\n\n```javascript\nimport { pathToFileURL } from 'url'\n\n// Add results\nfor (const issue of issues) { // issues from your linter in any format\n    const sarifResultBuilder = new SarifResultBuilder();\n    const sarifResultInit = {\n         // Transcode to a SARIF level:  can be \"warning\" or \"error\" or \"note\"\n        level: issue.severity === \"info\" ? \"note\" : issue.severity,\n        messageText: err.msg,                                     // Ex: \"any is forbidden !\"\n        ruleId: err.rule,                                         // Ex: \"no-any\"\n        fileUri: process.env.SARIF_URI_ABSOLUTE                   // Ex: src/myfile.ts\n            ? pathToFileURL(fileNm)\n            : path.relative(process.cwd(), fileNm).replace(/\\\\/g, '/'),\n    };\n    // When possible, provide location of the issue in the source code\n    if (issue.range) {\n        sarifResultInit.startLine = issue.range.start.line;        // any integer \u003e= 1 (optional)\n        sarifResultInit.startColumn = issue.range.start.character; // any integer \u003e= 1 (optional)\n        sarifResultInit.endLine = issue.range.end.line;            // any integer \u003e= 1 (optional)\n        sarifResultInit.endColumn = issue.range.end.character;     // any integer \u003e= 1 (optional)\n    }\n    // Init sarifResultBuilder\n    sarifResultBuilder.initSimple(sarifResultInit); \n    // Add result to sarifRunBuilder\n    sarifRunBuilder.addResult(sarifResultBuilder);\n}\n```\n\n___\n\n- Add run to sarifBuilder then generate JSON SARIF output file\n\n```javascript\n    sarifBuilder.addRun(sarifRunBuilder);\n    const sarifJsonString = sarifBuilder.buildSarifJsonString({ indent: false }); // indent:true if you like\n    fs.writeFileSync(outputSarifFile,sarifJsonString);\n    // const sarifObj = sarifBuilder.buildSarifOutput();                          // You could also just get the Sarif log as an object and not a string\n```\n\n## Full example\n\n- Working in [npm-groovy-lint](https://github.com/nvuillam/npm-groovy-lint)\n\n```javascript\nimport { pathToFileURL } from 'url'\n\nfunction buildSarifResult(lintResult) {\n    // SARIF builder\n    const sarifBuilder = new SarifBuilder();\n    // SARIF Run builder\n    const sarifRunBuilder = new SarifRunBuilder().initSimple({\n        toolDriverName: \"npm-groovy-lint\",\n        toolDriverVersion: \"9.0.5\", \n        url: \"https://nvuillam.github.io/npm-groovy-lint/\"\n    });\n    // SARIF rules\n    for (const ruleId of Object.keys(lintResult.rules || {})) {\n        const rule = lintResult.rules[ruleId];\n        const sarifRuleBuiler = new SarifRuleBuilder().initSimple({\n            ruleId: ruleId,\n            shortDescriptionText: rule.description,\n            helpUri: rule.docUrl\n        });\n        sarifRunBuilder.addRule(sarifRuleBuiler);\n    }\n    // Add SARIF results (individual errors)\n    for (const fileNm of Object.keys(lintResult.files)) {\n        const fileErrors = lintResult.files[fileNm].errors;\n        for (const err of fileErrors) {\n            const sarifResultBuilder = new SarifResultBuilder();\n            const sarifResultInit = {\n                level: err.severity === \"info\" ? \"note\" : err.severity, // Other values can be \"warning\" or \"error\"\n                messageText: err.msg,\n                ruleId: err.rule,\n                fileUri: process.env.SARIF_URI_ABSOLUTE\n                    ? pathToFileURL(fileNm)\n                    : path.relative(process.cwd(), fileNm).replace(/\\\\/g, '/')\n            };\n            if (err.range) {\n                sarifResultInit.startLine = fixLine(err.range.start.line);\n                sarifResultInit.startColumn = fixCol(err.range.start.character);\n                sarifResultInit.endLine = fixLine(err.range.end.line);\n                sarifResultInit.endColumn = fixCol(err.range.end.character);\n            }\n            sarifResultBuilder.initSimple(sarifResultInit);\n            sarifRunBuilder.addResult(sarifResultBuilder);\n        }\n    }\n    sarifBuilder.addRun(sarifRunBuilder);\n    return sarifBuilder.buildSarifJsonString({ indent: false });\n}\n\nfunction fixLine(val) {\n    if (val === null) {\n        return undefined;\n    }\n    return val === 0 ? 1 : val;\n}\n\nfunction fixCol(val) {\n    if (val === null) {\n        return undefined;\n    }\n    return val === 0 ? 1 : val + 1;\n}\n```\n\n## Test\n\nYou can confirm that your generated SARIF logs are valid on \u003chttps://sarifweb.azurewebsites.net/Validation\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvuillam%2Fnode-sarif-builder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnvuillam%2Fnode-sarif-builder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnvuillam%2Fnode-sarif-builder/lists"}