Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ updates:
versioning-strategy: widen
schedule:
interval: "weekly"
cooldown:
default-days: 5
groups:
dependencies:
dependency-type: "production"
Expand All @@ -14,6 +16,8 @@ updates:
directory: "/"
schedule:
interval: "monthly"
cooldown:
default-days: 5
groups:
github-actions:
patterns:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
runs-on: ${{matrix.os}}
strategy:
matrix:
node-version: [20.x, 22.x]
node-version: [24.x]
os: [ubuntu-latest]
fail-fast: false
steps:
Expand All @@ -28,8 +28,10 @@ jobs:
uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5.0.0
with:
node-version: ${{ matrix.node-version }}
- name: Install chromium
run: npx puppeteer browsers install chrome
- name: Install dependencies
run: npm i
run: npm install --ignore-scripts
- name: Lint
run: npm run lint
- name: Run tests
Expand All @@ -47,4 +49,4 @@ jobs:
- name: Merge Dependabot PR
uses: fastify/github-action-merge-dependabot@e820d631adb1d8ab16c3b93e5afe713450884a4a # v3.11.1
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
github-token: ${{ secrets.GITHUB_TOKEN }}
2 changes: 2 additions & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
package-lock=false
save-exact=true
ignore-scripts=true
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ This project is designed to generate periodic security reports in both HTML and

## Requirements

- [Node.js](https://nodejs.org/en/) v20 or higher.
- [Node.js](https://nodejs.org/en/) v24 or higher.

## Getting Started

Expand Down
8 changes: 4 additions & 4 deletions bin/commands/execute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import * as rc from "@nodesecure/rc";
import kleur from "kleur";

// Import Internal Dependencies
import { store } from "../../src/localStorage.js";
import { store } from "../../src/localStorage.ts";

import { fetchPackagesAndRepositoriesData } from "../../src/analysis/fetch.js";
import * as CONSTANTS from "../../src/constants.js";
import * as reporting from "../../src/reporting/index.js";
import { fetchPackagesAndRepositoriesData } from "../../src/analysis/fetch.ts";
import * as CONSTANTS from "../../src/constants.ts";
import * as reporting from "../../src/reporting/index.ts";

// CONSTANTS
const kReadConfigOptions = {
Expand Down
4 changes: 2 additions & 2 deletions bin/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./execute.js";
export * from "./init.js";
export * from "./execute.ts";
export * from "./init.ts";
2 changes: 1 addition & 1 deletion bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import sade from "sade";
import kleur from "kleur";

// Import Internal Dependencies
import * as commands from "./commands/index.js";
import * as commands from "./commands/index.ts";

console.log(kleur.grey().bold(`\n > Executing nreport at: ${kleur.yellow().bold(process.cwd())}\n`));

Expand Down
14 changes: 6 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
"build:views": "rimraf dist/views && cp -r views dist/views",
"build:public": "rimraf dist/public && cp -r public dist/public",
"lint": "eslint src test bin scripts",
"test-only": "glob -c \"tsx --test-reporter=spec --test\" \"./test/**/*.spec.ts\"",
"test-only": "node --test-reporter=spec --test ./test/**/*.spec.ts",
"test": "c8 --all --src ./src -r html npm run test-only",
"test:e2e": "glob -c \"tsx -r dotenv/config --test-reporter=spec --test\" \"./test/**/*.e2e-spec.ts\"",
"preview:light": "tsx --no-warnings ./scripts/preview.js --theme light",
"preview:dark": "tsx --no-warnings ./scripts/preview.js --theme dark",
"test:e2e": "node -r dotenv/config --test-reporter=spec --test ./test/**/*.e2e-spec.ts",
"preview:light": "node --no-warnings ./scripts/preview.js --theme light",
"preview:dark": "node --no-warnings ./scripts/preview.js --theme dark",
"prepublishOnly": "npm run build"
},
"files": [
Expand Down Expand Up @@ -62,16 +62,14 @@
},
"devDependencies": {
"@openally/config.eslint": "^2.1.0",
"@openally/config.typescript": "^1.0.3",
"@openally/config.typescript": "1.2.1",
"@types/node": "^24.0.1",
"c8": "^10.1.2",
"glob": "^11.0.0",
"open": "^10.1.0",
"rimraf": "^6.0.1",
"tsx": "^4.19.2",
"typescript": "^5.7.2"
},
"engines": {
"node": ">=20"
"node": ">=24"
}
}
4 changes: 2 additions & 2 deletions scripts/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import { parseArgs } from "node:util";
import open from "open";

// Import Internal Dependencies
import { HTMLTemplateGenerator } from "../src/reporting/template.js";
import { buildFrontAssets } from "../src/reporting/html.js";
import { HTMLTemplateGenerator } from "../src/reporting/template.ts";
import { buildFrontAssets } from "../src/reporting/html.ts";

// CONSTANTS
const kPreviewDir = path.join(import.meta.dirname, "..", "preview");
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/extractScannerData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Extractors, type Payload, type Dependency, type DependencyVersion, type
import type { RC } from "@nodesecure/rc";

// Import Internal Dependencies
import * as localStorage from "../localStorage.js";
import * as localStorage from "../localStorage.ts";

// CONSTANTS
const kFlagsList = Object.values(getManifest());
Expand Down
10 changes: 5 additions & 5 deletions src/analysis/fetch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import path from "node:path";
import kleur from "kleur";

// Import Internal Dependencies
import { buildStatsFromScannerDependencies } from "./extractScannerData.js";
import * as scanner from "./scanner.js";
import * as localStorage from "../localStorage.js";
import * as utils from "../utils/index.js";
import * as CONSTANTS from "../constants.js";
import { buildStatsFromScannerDependencies } from "./extractScannerData.ts";
import * as scanner from "./scanner.ts";
import * as localStorage from "../localStorage.ts";
import * as utils from "../utils/index.ts";
import * as CONSTANTS from "../constants.ts";

export async function fetchPackagesAndRepositoriesData(
verbose = true
Expand Down
2 changes: 1 addition & 1 deletion src/analysis/scanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Mutex } from "@openally/mutex";
import * as scanner from "@nodesecure/scanner";

// Import Internal Dependencies
import * as CONSTANTS from "../constants.js";
import * as CONSTANTS from "../constants.ts";

// CONSTANTS
const kMaxAnalysisLock = new Mutex({ concurrency: 2 });
Expand Down
4 changes: 2 additions & 2 deletions src/api/report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import { type Payload } from "@nodesecure/scanner";
import { type RC } from "@nodesecure/rc";

// Import Internal Dependencies
import { buildStatsFromScannerDependencies } from "../analysis/extractScannerData.js";
import { HTML, PDF } from "../reporting/index.js";
import { buildStatsFromScannerDependencies } from "../analysis/extractScannerData.ts";
import { HTML, PDF } from "../reporting/index.ts";

export interface ReportLocationOptions {
includesPDF: boolean;
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./api/report.js";
export * from "./api/report.ts";
10 changes: 5 additions & 5 deletions src/reporting/html.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import esbuild from "esbuild";
import type { RC } from "@nodesecure/rc";

// Import Internal Dependencies
import * as utils from "../utils/index.js";
import * as CONSTANTS from "../constants.js";
import * as localStorage from "../localStorage.js";
import { HTMLTemplateGenerator } from "./template.js";
import type { ReportStat } from "../analysis/extractScannerData.js";
import * as utils from "../utils/index.ts";
import * as CONSTANTS from "../constants.ts";
import * as localStorage from "../localStorage.ts";
import { HTMLTemplateGenerator } from "./template.ts";
import type { ReportStat } from "../analysis/extractScannerData.ts";

// CONSTANTS
const kDateFormatter = Intl.DateTimeFormat("en-GB", {
Expand Down
8 changes: 4 additions & 4 deletions src/reporting/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
import kleur from "kleur";

// Import Internal Dependencies
import * as utils from "../utils/index.js";
import * as localStorage from "../localStorage.js";
import * as utils from "../utils/index.ts";
import * as localStorage from "../localStorage.ts";

// Import Reporters
import { HTML, type HTMLReportData } from "./html.js";
import { PDF } from "./pdf.js";
import { HTML, type HTMLReportData } from "./html.ts";
import { PDF } from "./pdf.ts";

export async function proceed(
data: HTMLReportData,
Expand Down
4 changes: 2 additions & 2 deletions src/reporting/pdf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { pathToFileURL } from "node:url";
import puppeteer from "puppeteer";

// Import Internal Dependencies
import * as CONSTANTS from "../constants.js";
import * as utils from "../utils/index.js";
import * as CONSTANTS from "../constants.ts";
import * as utils from "../utils/index.ts";

export interface PDFReportOptions {
title: string;
Expand Down
8 changes: 4 additions & 4 deletions src/reporting/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import compile from "zup";
import type { RC } from "@nodesecure/rc";

// Import Internal Dependencies
import * as utils from "../utils/index.js";
import * as CONSTANTS from "../constants.js";
import * as localStorage from "../localStorage.js";
import type { ReportStat } from "../analysis/extractScannerData.js";
import * as utils from "../utils/index.ts";
import * as CONSTANTS from "../constants.ts";
import * as localStorage from "../localStorage.ts";
import type { ReportStat } from "../analysis/extractScannerData.ts";

const kHTMLStaticTemplate = readFileSync(
path.join(CONSTANTS.DIRS.VIEWS, "template.html"),
Expand Down
2 changes: 1 addition & 1 deletion src/utils/charts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { taggedString } from "@nodesecure/utils";
import type { RC } from "@nodesecure/rc";

// Import Internal Dependencies
import type { ReportStat } from "../analysis/extractScannerData.js";
import type { ReportStat } from "../analysis/extractScannerData.ts";

// CONSTANTS
const kChartTemplate = taggedString`\tcreateChart("${0}", "${4}", { labels: [${1}], interpolate: ${3}, data: [${2}] });`;
Expand Down
10 changes: 5 additions & 5 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export * from "./cleanReportName.js";
export * from "./cloneGITRepository.js";
export * from "./runInSpinner.js";
export * from "./formatNpmPackages.js";
export * from "./charts.js";
export * from "./cleanReportName.ts";
export * from "./cloneGITRepository.ts";
export * from "./runInSpinner.ts";
export * from "./formatNpmPackages.ts";
export * from "./charts.ts";
2 changes: 1 addition & 1 deletion test/api/report.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import assert from "node:assert";
import { from } from "@nodesecure/scanner";

// Import Internal Dependencies
import { report } from "../../src/index.js";
import { report } from "../../src/index.ts";

// CONSTANTS
const kReportPayload = {
Expand Down
126 changes: 63 additions & 63 deletions test/commands/execute.e2e-spec.ts
Original file line number Diff line number Diff line change
@@ -1,63 +1,63 @@
// Import Node.js Dependencies
import { fileURLToPath } from "node:url";
import path from "node:path";
import fs from "node:fs/promises";
import { afterEach, describe, it } from "node:test";
import assert from "node:assert";
import { stripVTControlCharacters } from "node:util";
// Import Internal Dependencies
import { filterProcessStdout } from "../helpers/reportCommandRunner.js";
import * as CONSTANTS from "../../src/constants.js";
// CONSTANTS
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const kProcessDir = path.join(__dirname, "../..");
describe("Report execute command", () => {
afterEach(async() => await fs.rm(CONSTANTS.DIRS.CLONES, {
recursive: true, force: true
}));
it("should execute command on fixture '.nodesecurerc'", async() => {
const options = {
cmd: "node",
args: ["dist/bin/index.js", "execute"],
cwd: kProcessDir
};
function byMessage(buffer) {
const message = ".*";
const afterNonAlphaNum = String.raw`?<=[^a-zA-Z\d\s:]\s`;
const beforeTime = String.raw`?=\s\d{1,5}.\d{1,4}ms`;
const withoutDuplicates = String.raw`(?![\s\S]*\1)`;
const matchMessage = `(${afterNonAlphaNum})(${message})(${beforeTime})|(${afterNonAlphaNum})(${message})`;
const reg = new RegExp(`(${matchMessage})${withoutDuplicates}`, "g");
const matchedMessages = stripVTControlCharacters(buffer.toString()).match(reg);
return matchedMessages ?? [""];
}
const expectedLines = [
`Executing nreport at: ${kProcessDir}`,
"title: Default report title",
"reporters: html,pdf",
"[Fetcher: NPM] - Fetching NPM packages metadata on the NPM Registry",
"",
"[Fetcher: NPM] - successfully executed in",
"[Fetcher: GIT] - Cloning GIT repositories",
"[Fetcher: GIT] - Fetching repositories metadata on the NPM Registry",
"[Fetcher: GIT] - successfully executed in",
"[Reporter: HTML] - Building template and assets",
"[Reporter: HTML] - successfully executed in",
"[Reporter: PDF] - Using puppeteer to convert HTML content to PDF",
"[Reporter: PDF] - successfully executed in",
"Security report successfully generated! Enjoy 🚀."
];
const actualLines = await filterProcessStdout(options, byMessage);
assert.deepEqual(actualLines, expectedLines, "we are expecting these lines");
});
});
// Import Node.js Dependencies
import { fileURLToPath } from "node:url";
import path from "node:path";
import fs from "node:fs/promises";
import { afterEach, describe, it } from "node:test";
import assert from "node:assert";
import { stripVTControlCharacters } from "node:util";

// Import Internal Dependencies
import { filterProcessStdout } from "../helpers/reportCommandRunner.ts";
import * as CONSTANTS from "../../src/constants.ts";

// CONSTANTS
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const kProcessDir = path.join(__dirname, "../..");

describe("Report execute command", () => {
afterEach(async() => await fs.rm(CONSTANTS.DIRS.CLONES, {
recursive: true, force: true
}));

it("should execute command on fixture '.nodesecurerc'", async() => {
const options = {
cmd: "node",
args: ["dist/bin/index.ts", "execute"],
cwd: kProcessDir
};

function byMessage(buffer) {
const message = ".*";
const afterNonAlphaNum = String.raw`?<=[^a-zA-Z\d\s:]\s`;
const beforeTime = String.raw`?=\s\d{1,5}.\d{1,4}ms`;
const withoutDuplicates = String.raw`(?![\s\S]*\1)`;

const matchMessage = `(${afterNonAlphaNum})(${message})(${beforeTime})|(${afterNonAlphaNum})(${message})`;
const reg = new RegExp(`(${matchMessage})${withoutDuplicates}`, "g");

const matchedMessages = stripVTControlCharacters(buffer.toString()).match(reg);

return matchedMessages ?? [""];
}

const expectedLines = [
`Executing nreport at: ${kProcessDir}`,
"title: Default report title",
"reporters: html,pdf",
"[Fetcher: NPM] - Fetching NPM packages metadata on the NPM Registry",
"",
"[Fetcher: NPM] - successfully executed in",
"[Fetcher: GIT] - Cloning GIT repositories",
"[Fetcher: GIT] - Fetching repositories metadata on the NPM Registry",
"[Fetcher: GIT] - successfully executed in",
"[Reporter: HTML] - Building template and assets",
"[Reporter: HTML] - successfully executed in",
"[Reporter: PDF] - Using puppeteer to convert HTML content to PDF",
"[Reporter: PDF] - successfully executed in",
"Security report successfully generated! Enjoy 🚀."
];

const actualLines = await filterProcessStdout(options, byMessage);
assert.deepEqual(actualLines, expectedLines, "we are expecting these lines");
});
});
Loading