New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@rehearsal/reporter

Package Overview
Dependencies
Maintainers
3
Versions
92
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@rehearsal/reporter - npm Package Compare versions

Comparing version 0.0.14 to 0.0.15

dist/src/formatters/json.d.ts

6

dist/src/index.d.ts

@@ -1,3 +0,5 @@

export { default as Reporter } from './reporter';
export type { ReporterOptions, Report, TSCLog, ReporterSummary, TSCLogError } from './interfaces';
export { default } from './reporter';
export { json } from './formatters/json';
export { pullRequestMd } from './formatters/pull-request-md';
export type { Report, ReportItem, ReportSummary } from './types';
//# sourceMappingURL=index.d.ts.map

@@ -6,5 +6,9 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.Reporter = void 0;
exports.pullRequestMd = exports.json = exports.default = void 0;
var reporter_1 = require("./reporter");
Object.defineProperty(exports, "Reporter", { enumerable: true, get: function () { return __importDefault(reporter_1).default; } });
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(reporter_1).default; } });
var json_1 = require("./formatters/json");
Object.defineProperty(exports, "json", { enumerable: true, get: function () { return json_1.json; } });
var pull_request_md_1 = require("./formatters/pull-request-md");
Object.defineProperty(exports, "pullRequestMd", { enumerable: true, get: function () { return pull_request_md_1.pullRequestMd; } });
//# sourceMappingURL=index.js.map

@@ -1,30 +0,37 @@

import type { Logger } from 'winston';
import type { ReporterOptions, Report } from './interfaces';
import ts from 'typescript';
import winston from 'winston';
import { Report, ReportItem } from './types';
/**
* Reporter class which handles the stdout/file report for Rehearsal
*
*
* @param options - ReporterOptions
* Representation of diagnostic and migration report.
*/
export default class Reporter {
cwd: ReporterOptions['cwd'];
streamFile: string;
private filepath;
filename: string;
report: Report;
terminalLogger: Logger;
fileLogger: Logger;
constructor(options?: ReporterOptions);
private parseLog;
private getCumulativeErrors;
private getAutofixedUniqueErrorList;
private get autofixedErrors();
private getUniqueErrorsList;
private get uniqueErrors();
set tscVersion(version: string);
set projectName(name: string);
setCWD(cwd: string): void;
logSummary(): void;
end(_cb?: () => void): Promise<void>;
readonly basePath: string;
private report;
private logger?;
constructor(projectName?: string, basePath?: string, logger?: winston.Logger);
getFileNames(): string[];
getItemsByFile(fileName: string): ReportItem[];
/**
* Appends an element to the summary
*/
addSummary(key: string, value: unknown): void;
/**
* Appends am information about provided diagnostic and related node to the report
*/
addItem(diagnostic: ts.DiagnosticWithLocation, node?: ts.Node, hint?: string, fixed?: boolean): void;
/**
* Prints the current report using provided formatter (ex. json, pull-request etc.)
*/
print(file: string, formatter: (report: Report) => string): string;
/**
* Saves the current report information to the file in simple JSON format
* to be able to load it later with 'load' function
*/
save(file: string): void;
/**
* Loads the report exported by function 'save' from the file
*/
load(file: string): Reporter;
private static isReport;
}
//# sourceMappingURL=reporter.d.ts.map

@@ -6,150 +6,93 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const tmp_1 = require("tmp");
const path_1 = require("path");
const winston_1 = require("winston");
const fs_extra_1 = require("fs-extra");
const utils_1 = require("./utils");
const debug_1 = __importDefault(require("debug"));
const DEBUG_CALLBACK = debug_1.default('rehearsal:reporter');
const fs_1 = __importDefault(require("fs"));
const typescript_1 = __importDefault(require("typescript"));
/**
* Reporter class which handles the stdout/file report for Rehearsal
*
*
* @param options - ReporterOptions
* Representation of diagnostic and migration report.
*/
class Reporter {
constructor(options = {}) {
const tmpDir = tmp_1.dirSync().name;
// this is the private file that will be malformed json from the stream
this.streamFile = path_1.join(tmpDir, '.rehearsal');
this.cwd = options.cwd || tmpDir;
// this is the public file that the user will see
this.filename = options.filename || '.rehearsal.json';
this.filepath = path_1.join(this.cwd, this.filename);
this.terminalLogger = winston_1.createLogger({
defaultMeta: {
service: 'rehearsal',
constructor(projectName = '', basePath = '', logger) {
this.basePath = basePath;
this.logger = logger === null || logger === void 0 ? void 0 : logger.child({ service: 'rehearsal-reporter' });
this.report = {
summary: {
projectName: projectName,
tsVersion: typescript_1.default.version,
timestamp: Date.now().toString(),
basePath: basePath,
},
transports: [new winston_1.transports.Console({})],
});
this.fileLogger = winston_1.createLogger({
defaultMeta: {
service: 'rehearsal',
},
transports: [new winston_1.transports.File({ filename: this.streamFile })],
format: winston_1.format.combine(winston_1.format.json()),
});
this.report = {
projectName: options.projectName || '',
timestamp: new Date().toISOString(),
tscVersion: options.tscVersion || '',
tscLog: [],
// the number of files that were parsed
fileCount: 0,
// the total number of tsc errors found before fixing
cumulativeErrors: 0,
// the total number of unique tsc errors found before fixing
uniqueErrors: 0,
// the unique tsc diagnostic lookup id's found
uniqueErrorList: [],
// the fixed total number of tsc errors fixed
autofixedErrors: 0,
// the fixed and unique tsc diagnostic lookup id's found
autofixedUniqueErrorList: [],
items: [],
};
}
// happends after the stream has finished
async parseLog() {
// build a JSON representation of the log
this.report.tscLog = utils_1.readJSONString(this.streamFile);
DEBUG_CALLBACK('parseLog()', 'log parsed');
// set all cumulative properties
this.report.fileCount = this.report.tscLog.length;
this.report.cumulativeErrors = this.getCumulativeErrors(this.report.tscLog);
this.report.uniqueErrors = this.uniqueErrors;
this.report.uniqueErrorList = Array.from(this.getUniqueErrorsList(this.report.tscLog));
const { uniqueErrors } = this.getAutofixedUniqueErrorList(this.report.tscLog);
this.report.autofixedUniqueErrorList = Array.from(uniqueErrors);
this.report.autofixedErrors = this.autofixedErrors;
await fs_extra_1.writeJSON(this.filepath, this.report);
DEBUG_CALLBACK('parseLog()', 'report written to file');
getFileNames() {
return [...new Set(this.report.items.map((item) => item.file))];
}
// get the total number of tsc errors found before fixing
getCumulativeErrors(tscLog) {
return tscLog.reduce((acc, curr) => {
return acc + curr.errors.length;
}, 0);
getItemsByFile(fileName) {
return this.report.items.filter((item) => item.file === fileName);
}
getAutofixedUniqueErrorList(tscLog) {
const uniqueErrors = new Set();
let errorCount = 0;
tscLog.forEach((log) => {
log.errors.forEach((error) => {
// if the tsc error was autofixed by rehearsal then add it to the unique errors
if (error.isAutofixed) {
uniqueErrors.add(error.errorCode);
errorCount++;
}
});
});
return { uniqueErrors, errorCount };
/**
* Appends an element to the summary
*/
addSummary(key, value) {
this.report.summary[key] = value;
}
get autofixedErrors() {
const { errorCount } = this.getAutofixedUniqueErrorList(this.report.tscLog);
return errorCount;
}
getUniqueErrorsList(tscLog) {
const uniqueErrors = new Set();
tscLog.forEach((log) => {
log.errors.forEach((error) => {
uniqueErrors.add(error.errorCode);
});
/**
* Appends am information about provided diagnostic and related node to the report
*/
addItem(diagnostic, node, hint = '', fixed = false) {
this.report.items.push({
file: diagnostic.file.fileName,
code: diagnostic.code,
category: typescript_1.default.DiagnosticCategory[diagnostic.category],
message: typescript_1.default.flattenDiagnosticMessageText(diagnostic.messageText, '. '),
hint: hint,
fixed: fixed,
nodeKind: node ? typescript_1.default.SyntaxKind[node.kind] : undefined,
nodeText: node === null || node === void 0 ? void 0 : node.getText(),
location: Object.assign({ start: diagnostic.start, length: diagnostic.length }, diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start)),
});
return uniqueErrors;
}
get uniqueErrors() {
return this.getUniqueErrorsList(this.report.tscLog).size;
/**
* Prints the current report using provided formatter (ex. json, pull-request etc.)
*/
print(file, formatter) {
const report = formatter(this.report);
if (file) {
fs_1.default.writeFileSync(file, report);
}
return report;
}
set tscVersion(version) {
this.report.tscVersion = version;
/**
* Saves the current report information to the file in simple JSON format
* to be able to load it later with 'load' function
*/
save(file) {
var _a;
const formatter = (report) => JSON.stringify(report, null, 2);
this.print(file, formatter);
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.info(`Report saved to: ${file}.`);
}
set projectName(name) {
this.report.projectName = name;
/**
* Loads the report exported by function 'save' from the file
*/
load(file) {
var _a, _b, _c, _d;
if (!fs_1.default.existsSync(file)) {
(_a = this.logger) === null || _a === void 0 ? void 0 : _a.error(`Report file not found: ${file}.`);
}
(_b = this.logger) === null || _b === void 0 ? void 0 : _b.info(`Report file found: ${file}.`);
const content = fs_1.default.readFileSync(file, 'utf-8');
const report = JSON.parse(content);
if (!Reporter.isReport(report)) {
(_c = this.logger) === null || _c === void 0 ? void 0 : _c.error(`Report not loaded: wrong file format`);
return this;
}
this.report = report;
(_d = this.logger) === null || _d === void 0 ? void 0 : _d.info(`Report loaded from file.`);
return this;
}
setCWD(cwd) {
this.cwd = cwd;
this.filepath = path_1.join(this.cwd, this.filename);
static isReport(report) {
return report && report.summary !== undefined && report.items !== undefined;
}
logSummary() {
console.log(`\n`);
console.log(`Files Parsed: ${this.report.fileCount} total`);
console.log(`TSC Errors: ${this.report.cumulativeErrors} total`);
console.log(`TSC Errors Autofixed: ${this.report.autofixedErrors} total`);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
async end(_cb = () => { }) {
await utils_1.sleep(1000);
DEBUG_CALLBACK('end()', 'end called');
this.fileLogger.on('finish', async () => {
DEBUG_CALLBACK('end()', 'fileLogger on finish event subscribed');
await this.parseLog();
tmp_1.setGracefulCleanup();
DEBUG_CALLBACK('setGracefulCleanup()', 'cleanup finsished');
});
this.fileLogger.on('error', (err) => {
throw new Error(`${err}`);
});
this.terminalLogger.end();
DEBUG_CALLBACK('end()', 'terminalLogger ended');
this.fileLogger.end();
DEBUG_CALLBACK('end()', 'fileLogger ended');
// winston is racing a promise to finish, so we need to wait for it to finish
// 2 seconds is more than enough
await utils_1.sleep(1000);
this.logSummary();
// optional callback to be called after the reporter has finished
_cb();
}
}
exports.default = Reporter;
//# sourceMappingURL=reporter.js.map
{
"name": "@rehearsal/reporter",
"version": "0.0.14",
"version": "0.0.15",
"description": "Rehearsal Reporter",

@@ -27,51 +27,19 @@ "keywords": [

"prepare": "yarn build",
"test": "yarn lint && yarn nyc mocha"
"test": "yarn nyc mocha"
},
"nyc": {
"extension": [
".ts"
]
},
"dependencies": {
"debug": "^4.3.2",
"fs-extra": "^10.0.0",
"json5": "^2.2.0",
"tmp": "^0.2.1",
"winston": "^3.3.3"
"winston": "^3.6.0"
},
"devDependencies": {
"@commitlint/cli": "^16.1.0",
"@commitlint/config-conventional": "^16.0.0",
"@microsoft/api-documenter": "^7.13.68",
"@microsoft/api-extractor": "^7.18.19",
"@types/chai": "^4.2.22",
"@types/chai-as-promised": "^7.1.4",
"@types/chai-fs": "^2.0.2",
"@types/chai": "^4.3.0",
"@types/debug": "^4.1.7",
"@types/fs-extra": "^9.0.13",
"@types/json5": "*",
"@types/mocha": "^9.0.0",
"@types/node": "^17.0.16",
"@types/tmp": "^0.2.2",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"chai": "^4.3.4",
"chai-as-promised": "^7.1.1",
"chai-fs": "^2.0.0",
"eslint": "^8.2.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-filenames": "^1.3.2",
"eslint-plugin-import": "^2.25.3",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"husky": "^7.0.4",
"mocha": "^9.1.3",
"npm-run-all": "^4.1.5",
"nyc": "^15.1.0",
"pre-commit": "^1.2.2",
"prettier": "^2.4.1",
"ts-node": "^10.4.0",
"typescript": "~4.5.2"
"@types/eslint": "^8.4.1",
"@types/mocha": "^9.1.0",
"chai": "^4.3.6",
"mocha": "^9.2.2",
"nyc": "^15.1.0"
},
"peerDependencies": {
"typescript": ">4.0"
},
"engines": {

@@ -84,3 +52,3 @@ "node": ">=10.0.0"

},
"gitHead": "2979d15209b7efc821b26b60caa72a1c453201a2"
"gitHead": "37ef0d49fe9e214e70e1276a89dc9089cd25c6d4"
}

@@ -1,3 +0,6 @@

export { default as Reporter } from './reporter';
export { default } from './reporter';
export type { ReporterOptions, Report, TSCLog, ReporterSummary, TSCLogError } from './interfaces';
export { json } from './formatters/json';
export { pullRequestMd } from './formatters/pull-request-md';
export type { Report, ReportItem, ReportSummary } from './types';

@@ -1,194 +0,114 @@

import { dirSync, setGracefulCleanup } from 'tmp';
import { join } from 'path';
import { createLogger, transports, format } from 'winston';
import { writeJSON } from 'fs-extra';
import { readJSONString, sleep } from './utils';
import debug from 'debug';
import fs from 'fs';
import ts from 'typescript';
import winston from 'winston';
import { Report, ReportItem } from './types';
import type { Logger } from 'winston';
import type { TSCLog, ReporterOptions, Report } from './interfaces';
const DEBUG_CALLBACK = debug('rehearsal:reporter');
/**
* Reporter class which handles the stdout/file report for Rehearsal
*
*
* @param options - ReporterOptions
* Representation of diagnostic and migration report.
*/
export default class Reporter {
public cwd: ReporterOptions['cwd'];
public streamFile: string;
private filepath: string;
public filename: string;
public report: Report;
public terminalLogger: Logger;
public fileLogger: Logger;
readonly basePath: string;
constructor(options: ReporterOptions = {}) {
const tmpDir = dirSync().name;
// this is the private file that will be malformed json from the stream
this.streamFile = join(tmpDir, '.rehearsal');
this.cwd = options.cwd || tmpDir;
// this is the public file that the user will see
this.filename = options.filename || '.rehearsal.json';
this.filepath = join(this.cwd, this.filename);
private report: Report;
private logger?: winston.Logger;
this.terminalLogger = createLogger({
defaultMeta: {
service: 'rehearsal',
constructor(projectName = '', basePath = '', logger?: winston.Logger) {
this.basePath = basePath;
this.logger = logger?.child({ service: 'rehearsal-reporter' });
this.report = {
summary: {
projectName: projectName,
tsVersion: ts.version,
timestamp: Date.now().toString(),
basePath: basePath,
},
transports: [new transports.Console({})],
});
this.fileLogger = createLogger({
defaultMeta: {
service: 'rehearsal',
},
transports: [new transports.File({ filename: this.streamFile })],
format: format.combine(format.json()),
});
this.report = {
projectName: options.projectName || '',
timestamp: new Date().toISOString(),
tscVersion: options.tscVersion || '',
tscLog: [],
// the number of files that were parsed
fileCount: 0,
// the total number of tsc errors found before fixing
cumulativeErrors: 0,
// the total number of unique tsc errors found before fixing
uniqueErrors: 0,
// the unique tsc diagnostic lookup id's found
uniqueErrorList: [],
// the fixed total number of tsc errors fixed
autofixedErrors: 0,
// the fixed and unique tsc diagnostic lookup id's found
autofixedUniqueErrorList: [],
items: [],
};
}
// happends after the stream has finished
private async parseLog(): Promise<void> {
// build a JSON representation of the log
this.report.tscLog = readJSONString<TSCLog>(this.streamFile);
DEBUG_CALLBACK('parseLog()', 'log parsed');
// set all cumulative properties
this.report.fileCount = this.report.tscLog.length;
this.report.cumulativeErrors = this.getCumulativeErrors(this.report.tscLog);
this.report.uniqueErrors = this.uniqueErrors;
this.report.uniqueErrorList = Array.from(this.getUniqueErrorsList(this.report.tscLog));
const { uniqueErrors } = this.getAutofixedUniqueErrorList(this.report.tscLog);
this.report.autofixedUniqueErrorList = Array.from(uniqueErrors);
this.report.autofixedErrors = this.autofixedErrors;
await writeJSON(this.filepath, this.report);
DEBUG_CALLBACK('parseLog()', 'report written to file');
getFileNames(): string[] {
return [...new Set(this.report.items.map((item) => item.file))];
}
// get the total number of tsc errors found before fixing
private getCumulativeErrors(tscLog: TSCLog[]): number {
return tscLog.reduce((acc, curr) => {
return acc + curr.errors.length;
}, 0);
getItemsByFile(fileName: string): ReportItem[] {
return this.report.items.filter((item) => item.file === fileName);
}
private getAutofixedUniqueErrorList(tscLog: TSCLog[]): {
uniqueErrors: Set<string>;
errorCount: number;
} {
const uniqueErrors = new Set<string>();
let errorCount = 0;
tscLog.forEach((log) => {
log.errors.forEach((error) => {
// if the tsc error was autofixed by rehearsal then add it to the unique errors
if (error.isAutofixed) {
uniqueErrors.add(error.errorCode);
errorCount++;
}
});
});
return { uniqueErrors, errorCount };
/**
* Appends an element to the summary
*/
addSummary(key: string, value: unknown): void {
this.report.summary[key] = value;
}
private get autofixedErrors(): number {
const { errorCount } = this.getAutofixedUniqueErrorList(this.report.tscLog);
return errorCount;
}
private getUniqueErrorsList(tscLog: TSCLog[]): Set<string> {
const uniqueErrors = new Set<string>();
tscLog.forEach((log) => {
log.errors.forEach((error) => {
uniqueErrors.add(error.errorCode);
});
/**
* Appends am information about provided diagnostic and related node to the report
*/
addItem(diagnostic: ts.DiagnosticWithLocation, node?: ts.Node, hint = '', fixed = false): void {
this.report.items.push({
file: diagnostic.file.fileName,
code: diagnostic.code,
category: ts.DiagnosticCategory[diagnostic.category],
message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '. '),
hint: hint,
fixed: fixed,
nodeKind: node ? ts.SyntaxKind[node.kind] : undefined,
nodeText: node?.getText(),
location: {
start: diagnostic.start,
length: diagnostic.length,
...diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start),
},
});
return uniqueErrors;
}
private get uniqueErrors(): number {
return this.getUniqueErrorsList(this.report.tscLog).size;
}
/**
* Prints the current report using provided formatter (ex. json, pull-request etc.)
*/
print(file: string, formatter: (report: Report) => string): string {
const report = formatter(this.report);
public set tscVersion(version: string) {
this.report.tscVersion = version;
}
if (file) {
fs.writeFileSync(file, report);
}
public set projectName(name: string) {
this.report.projectName = name;
return report;
}
public setCWD(cwd: string): void {
this.cwd = cwd;
this.filepath = join(this.cwd, this.filename);
/**
* Saves the current report information to the file in simple JSON format
* to be able to load it later with 'load' function
*/
save(file: string): void {
const formatter = (report: Report): string => JSON.stringify(report, null, 2);
this.print(file, formatter);
this.logger?.info(`Report saved to: ${file}.`);
}
public logSummary(): void {
console.log(`\n`);
console.log(`Files Parsed: ${this.report.fileCount} total`);
console.log(`TSC Errors: ${this.report.cumulativeErrors} total`);
console.log(`TSC Errors Autofixed: ${this.report.autofixedErrors} total`);
}
/**
* Loads the report exported by function 'save' from the file
*/
load(file: string): Reporter {
if (!fs.existsSync(file)) {
this.logger?.error(`Report file not found: ${file}.`);
}
// eslint-disable-next-line @typescript-eslint/no-empty-function
public async end(_cb = () => {}): Promise<void> {
await sleep(1000);
this.logger?.info(`Report file found: ${file}.`);
const content = fs.readFileSync(file, 'utf-8');
const report = JSON.parse(content);
DEBUG_CALLBACK('end()', 'end called');
if (!Reporter.isReport(report)) {
this.logger?.error(`Report not loaded: wrong file format`);
return this;
}
this.fileLogger.on('finish', async () => {
DEBUG_CALLBACK('end()', 'fileLogger on finish event subscribed');
this.report = report as Report;
this.logger?.info(`Report loaded from file.`);
await this.parseLog();
setGracefulCleanup();
return this;
}
DEBUG_CALLBACK('setGracefulCleanup()', 'cleanup finsished');
});
this.fileLogger.on('error', (err) => {
throw new Error(`${err}`);
});
this.terminalLogger.end();
DEBUG_CALLBACK('end()', 'terminalLogger ended');
this.fileLogger.end();
DEBUG_CALLBACK('end()', 'fileLogger ended');
// winston is racing a promise to finish, so we need to wait for it to finish
// 2 seconds is more than enough
await sleep(1000);
this.logSummary();
// optional callback to be called after the reporter has finished
_cb();
private static isReport(report: any): report is Report {
return report && report.summary !== undefined && report.items !== undefined;
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc