Skip to content

Commit

Permalink
refactor: update to esm (#191)
Browse files Browse the repository at this point in the history
* refactor: update to esm

* refacto: update dependencies

* refacto: fix lint

* refactor: dependencies update + lint

* refacto: fix bug
  • Loading branch information
Kawacrepe authored Aug 14, 2021
1 parent 7bd5282 commit a13b990
Show file tree
Hide file tree
Showing 14 changed files with 17,869 additions and 12,158 deletions.
13 changes: 9 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Editor configuration, see https://editorconfig.org
root = true

[*]
indent_size = 4
indent_style = space
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
end_of_line = lf

[*.md]
max_line_length = off
trim_trailing_whitespace = false
7 changes: 4 additions & 3 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"extends": "@slimio/eslint-config",
"rules": {
"jsdoc/require-jsdoc": "off"
"extends": "@nodesecure/eslint-config",
"parserOptions": {
"sourceType": "module",
"requireConfigFile": false
}
}
7 changes: 0 additions & 7 deletions .travis.yml

This file was deleted.

20 changes: 10 additions & 10 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
# Contributing to Slim.io
# Contributing to NodeSecure

Contributions to Slim.io include code, documentation, answering user questions,
running the project's infrastructure, and advocating for all types of Slim.io
Contributions to NodeSecure include code, documentation, answering user questions,
running the project's infrastructure, and advocating for all types of NodeSecure
users.

The Slim.io project welcomes all contributions from anyone willing to work in
The NodeSecure project welcomes all contributions from anyone willing to work in
good faith with other contributors and the community. No contribution is too
small and all contributions are valued.

This guide explains the process for contributing to the Slim.io project's.
This guide explains the process for contributing to the NodeSecure project's.

## [Code of Conduct](https://github.com/SlimIO/Governance/blob/master/CODE_OF_CONDUCT.md)
## [Code of Conduct](https://github.com/NodeSecure/Governance/blob/main/CONTRIBUTING.md)

The Slim.io project has a
[Code of Conduct](https://github.com/SlimIO/Governance/blob/master/CODE_OF_CONDUCT.md)
The NodeSecure project has a
[Code of Conduct](https://github.com/NodeSecure/Governance/blob/main/CONTRIBUTING.md)
that *all* contributors are expected to follow. This code describes the
*minimum* behavior expectations for all contributors.

See [details on our policy on Code of Conduct](https://github.com/SlimIO/Governance/blob/master/COC_POLICY.md).
See [details on our policy on Code of Conduct](https://github.com/NodeSecure/Governance/blob/main/COC_POLICY.md).

<a id="developers-certificate-of-origin"></a>
## Developer's Certificate of Origin 1.1
Expand All @@ -44,4 +44,4 @@ By making a contribution to this project, I certify that:
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
this project or the open source license(s) involved.
16 changes: 0 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,5 @@ The theme can be either `dark` or `light`. Themes are editable in *public/css/th

> All D3 scale-chromatic for charts can be found [here](https://github.com/d3/d3-scale-chromatic/blob/master/README.md).
## Dependencies

|Name|Refactoring|Security Risk|Usage|
|---|---|---|---|
|[@slimio/async-cli-spinner](https://github.com/SlimIO/Async-cli-spinner)|Minor|Low|Elegant Asynchronous Terminal (CLI) Spinner|
|[@slimio/lock](https://github.com/SlimIO/Lock)|Minor|Low|Semaphore for async/await|
|[@slimio/utils](https://github.com/SlimIO/Utils)|Minor|Low|Bunch of useful functions for SlimIO|
|[dotenv](https://github.com/motdotla/dotenv)|Minor|Low|Loads environment variables from .env|
|[filenamify](https://github.com/sindresorhus/filenamify#readme)|Minor|High|Convert a string to a valid safe filename|
|[isomorphic-git](https://isomorphic-git.org/)|Minor|High|A pure JavaScript implementation of git for node and browsers!|
|[kleur](https://github.com/lukeed/kleur)|Minor|Low|The fastest Node.js library for formatting terminal text with ANSI colors|
|[make-promises-safe](https://github.com/mcollina/make-promises-safe)|⚠️Major|Low|Force Node.js [DEP00018](https://nodejs.org/dist/latest-v8.x/docs/api/deprecations.html#deprecations_dep0018_unhandled_promise_rejections)|
|[nsecure](https://github.com/ES-Community/node-secure#readme)|Minor|High|Node.js security CLI / API that allow you to deeply analyze the dependency tree of a given package / directory|
|[puppeteer](https://github.com/puppeteer/puppeteer#readme)|Minor|High|Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium|
|[zup](https://github.com/mscdex/zup#readme)|Minor|Low|A simple and fast template engine for Node.js|

## License
MIT
5 changes: 0 additions & 5 deletions commitlint.config.js

This file was deleted.

244 changes: 124 additions & 120 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,152 +1,156 @@
/* eslint-disable max-depth */
"use strict";

require("dotenv").config();
require("make-promises-safe");

/* eslint-disable max-depth, max-len */
// Require Node.js Dependencies
const { join, basename } = require("path");
const { readdirSync, promises: { mkdir, rmdir, readFile, writeFile } } = require("fs");
import path from "path";
import fs, { promises } from "fs";
import { fileURLToPath } from "url";

// Require Third-party Dependencies
const { cyan, white } = require("kleur");
const { taggedString } = require("@slimio/utils");
const compile = require("zup");
const Spinner = require("@slimio/async-cli-spinner");
import dotenv from "dotenv";
dotenv.config();

import kleur from "kleur";
import { taggedString } from "@slimio/utils";
import compile from "zup";
import Spinner from "@slimio/async-cli-spinner";
Spinner.DEFAULT_SPINNER = "dots";

// Require Internal Dependencies
const { cloneGITRepository, fetchStatsFromNsecurePayloads, nsecure, cleanReportName } = require("./src/utils");
const { generatePDF } = require("./src/pdf");
const config = require("./data/config.json");
import { cloneGITRepository, fetchStatsFromNsecurePayloads, nsecure, cleanReportName } from "./src/utils.js";
import { generatePDF } from "./src/pdf.js";
const config = JSON.parse(
fs.readFileSync(new URL("./data/config.json", import.meta.url))
);

// CONSTANTS
const kCloneDir = join(__dirname, "clones");
const kJsonDir = join(__dirname, "json");
const kViewsDir = join(__dirname, "views");
const kReportsDir = join(__dirname, "reports");
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const kCloneDir = path.join(__dirname, "clones");
const kJsonDir = path.join(__dirname, "json");
const kViewsDir = path.join(__dirname, "views");
const kReportsDir = path.join(__dirname, "reports");
const kChartTemplate = taggedString`\tcreateChart("${0}", "${4}", { labels: [${1}], interpolate: ${3}, data: [${2}] });`;
const kAvailableThemes = new Set(readdirSync(join(__dirname, "public", "css", "themes")).map((file) => basename(file, ".css")));
const kAvailableThemes = new Set(fs.readdirSync(path.join(__dirname, "public", "css", "themes")).map((file) => path.basename(file, ".css")));

async function fetchPackagesStats() {
const spinner = new Spinner({
prefixText: white().bold("Fetching packages stats on nsecure")
}).start();

try {
const jsonFiles = await Promise.all(config.npm_packages.map(nsecure.onPackage));
const elapsed = `${spinner.elapsedTime.toFixed(2)}ms`;
spinner.succeed(`Successfully done in ${cyan().bold(elapsed)}`);

return fetchStatsFromNsecurePayloads(jsonFiles.filter((value) => value !== null));
}
catch (error) {
spinner.failed(error.message);
throw error;
}
const spinner = new Spinner({
prefixText: kleur.white().bold("Fetching packages stats on nsecure")
}).start();

try {
const jsonFiles = await Promise.all(config.npm_packages.map(nsecure.onPackage));
const elapsed = `${spinner.elapsedTime.toFixed(2)}ms`;
spinner.succeed(`Successfully done in ${kleur.cyan().bold(elapsed)}`);

return fetchStatsFromNsecurePayloads(jsonFiles.filter((value) => value !== null));
}
catch (error) {
spinner.failed(error.message);
throw error;
}
}

async function fetchRepositoriesStats() {
const spinner = new Spinner({
prefixText: white().bold("Clone and analyze built-in addons")
}).start("clone repositories...");

try {
const repos = await Promise.all(config.git_repositories.map(cloneGITRepository));
spinner.text = "Run node-secure analyze";

const jsonFiles = await Promise.all(repos.map(nsecure.onLocalDirectory));
const elapsed = `${spinner.elapsedTime.toFixed(2)}ms`;
spinner.succeed(`Successfully done in ${cyan().bold(elapsed)}`);

return fetchStatsFromNsecurePayloads(jsonFiles.filter((value) => value !== null));
}
catch (error) {
spinner.failed(error.message);
throw error;
}
const spinner = new Spinner({
prefixText: kleur.white().bold("Clone and analyze built-in addons")
}).start("clone repositories...");

try {
const repos = await Promise.all(config.git_repositories.map(cloneGITRepository));
spinner.text = "Run node-secure analyze";

const jsonFiles = await Promise.all(repos.map(nsecure.onLocalDirectory));
const elapsed = `${spinner.elapsedTime.toFixed(2)}ms`;
spinner.succeed(`Successfully done in ${kleur.cyan().bold(elapsed)}`);

return fetchStatsFromNsecurePayloads(jsonFiles.filter((value) => value !== null));
}
catch (error) {
spinner.failed(error.message);
throw error;
}
}

// eslint-disable-next-line max-params
function toChart(baliseName, data, interpolateName, type = "bar") {
const graphLabels = Object.keys(data).map((key) => `"${key}"`).join(",");
const graphLabels = Object.keys(data).map((key) => `"${key}"`).join(",");

return kChartTemplate(baliseName, graphLabels, Object.values(data).join(","), interpolateName, type);
return kChartTemplate(baliseName, graphLabels, Object.values(data).join(","), interpolateName, type);
}

function generateChartArray(pkgStats, repoStats) {
const charts = [];
const displayableCharts = config.charts.filter((chart) => chart.display);

if (pkgStats !== null) {
for (const chart of displayableCharts) {
const name = chart.name.toLowerCase();
charts.push(toChart(`npm_${name}_canvas`, pkgStats[name], chart.interpolation, chart.type));
}
const charts = [];
const displayableCharts = config.charts.filter((chart) => chart.display);

if (pkgStats !== null) {
for (const chart of displayableCharts) {
const name = chart.name.toLowerCase();
charts.push(toChart(`npm_${name}_canvas`, pkgStats[name], chart.interpolation, chart.type));
}
if (repoStats !== null) {
for (const chart of displayableCharts) {
const name = chart.name.toLowerCase();
charts.push(toChart(`git_${name}_canvas`, repoStats[name], chart.interpolation, chart.type));
}
}
if (repoStats !== null) {
for (const chart of displayableCharts) {
const name = chart.name.toLowerCase();
charts.push(toChart(`git_${name}_canvas`, repoStats[name], chart.interpolation, chart.type));
}
}

return charts;
return charts;
}

async function main() {
await Promise.all([
mkdir(kJsonDir, { recursive: true }),
mkdir(kCloneDir, { recursive: true }),
mkdir(kReportsDir, { recursive: true })
]);

try {
// eslint-disable-next-line new-cap
const generationDate = Intl.DateTimeFormat("en-GB", {
day: "2-digit", month: "short", year: "numeric", hour: "numeric", minute: "numeric", second: "numeric"
}).format(new Date());

const pkgStats = await (config.npm_packages.length === 0 ? Promise.resolve(null) : fetchPackagesStats());
const repoStats = await (config.git_repositories.length === 0 ? Promise.resolve(null) : fetchRepositoriesStats());
if (pkgStats === null && repoStats === null) {
console.log("No git repositories and no npm packages to fetch in the local configuration!");
process.exit(0);
}

console.log("Start generating template!");
const HTMLTemplateStr = await readFile(join(kViewsDir, "template.html"), "utf8");
const templateGenerator = compile(HTMLTemplateStr);

const templatePayload = {
report_theme: kAvailableThemes.has(config.theme) ? config.theme : "dark",
report_title: config.report_title,
report_logo: config.report_logo,
report_date: generationDate,
npm_stats: pkgStats,
git_stats: repoStats,
charts: config.charts.filter((chart) => chart.display).map(({ name, help = null }) => {
return { name, help };
})
};

const charts = generateChartArray(pkgStats, repoStats);
const HTMLReport = templateGenerator(templatePayload)
.concat(`\n<script>\ndocument.addEventListener("DOMContentLoaded", () => {\n${charts.join("\n")}\n});\n</script>`);

const reportHTMLPath = join(kReportsDir, cleanReportName(config.report_title, ".html"));
await writeFile(reportHTMLPath, HTMLReport);
await new Promise((resolve) => setTimeout(resolve, 100));
console.log("HTML Report writted on disk!");

await generatePDF(reportHTMLPath);
console.log("Report sucessfully generated!");
}
finally {
await new Promise((resolve) => setTimeout(resolve, 100));
await rmdir(kCloneDir, { recursive: true });
process.exit(0);
await Promise.all([
promises.mkdir(kJsonDir, { recursive: true }),
promises.mkdir(kCloneDir, { recursive: true }),
promises.mkdir(kReportsDir, { recursive: true })
]);

try {
// eslint-disable-next-line new-cap
const generationDate = Intl.DateTimeFormat("en-GB", {
day: "2-digit", month: "short", year: "numeric", hour: "numeric", minute: "numeric", second: "numeric"
}).format(new Date());

const pkgStats = await (config.npm_packages.length === 0 ? Promise.resolve(null) : fetchPackagesStats());
const repoStats = await (config.git_repositories.length === 0 ? Promise.resolve(null) : fetchRepositoriesStats());
if (pkgStats === null && repoStats === null) {
console.log("No git repositories and no npm packages to fetch in the local configuration!");
process.exit(0);
}

console.log("Start generating template!");
const HTMLTemplateStr = await promises.readFile(path.join(kViewsDir, "template.html"), "utf8");
const templateGenerator = compile(HTMLTemplateStr);


const templatePayload = {
report_theme: kAvailableThemes.has(config.theme) ? config.theme : "dark",
report_title: config.report_title,
report_logo: config.report_logo,
report_date: generationDate,
npm_stats: pkgStats,
git_stats: repoStats,
charts: config.charts.filter((chart) => chart.display).map(({ name, help = null }) => {
return { name, help };
})
};

const charts = generateChartArray(pkgStats, repoStats);

const HTMLReport = templateGenerator(templatePayload)
.concat(`\n<script>\ndocument.addEventListener("DOMContentLoaded", () => {\n${charts.join("\n")}\n});\n</script>`);

const reportHTMLPath = path.join(kReportsDir, cleanReportName(config.report_title, ".html"));
await promises.writeFile(reportHTMLPath, HTMLReport);
await new Promise((resolve) => setTimeout(resolve, 100));
console.log("HTML Report writted on disk!");

await generatePDF(reportHTMLPath);
console.log("Report sucessfully generated!");
}
finally {
await new Promise((resolve) => setTimeout(resolve, 100));
await promises.rm(kCloneDir, { recursive: true });
process.exit(0);
}
}
main().catch(console.error);

Loading

0 comments on commit a13b990

Please sign in to comment.