Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@betterer/reporter

Package Overview
Dependencies
Maintainers
0
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@betterer/reporter - npm Package Compare versions

Comparing version 5.4.0 to 6.0.0-alpha.1

dist/components/suite/Run.d.ts

8

dist/components/config/Config.d.ts

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

/// <reference types="react" />
import { BettererContext } from '@betterer/betterer';
import { FC } from '@betterer/render';
export declare type ConfigEditField = 'filters' | 'ignores' | null;
import type { BettererContext } from '@betterer/betterer';
import type { FC } from '@betterer/render';
export type ConfigEditField = 'filters' | 'ignores' | null;
/** @knipignore used by an exported function */
export interface ConfigProps {

@@ -6,0 +6,0 @@ context: BettererContext;

@@ -1,9 +0,6 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Config = void 0;
const render_1 = require("@betterer/render");
const EditConfig_1 = require("./EditConfig");
const Config = function Config({ context, editField }) {
const [filters, setFilters] = (0, render_1.useState)(serialiseFilters(context.config));
const [ignores, setIgnores] = (0, render_1.useState)(serialiseIgnores(context.config));
import { React, Box, Text, useState } from '@betterer/render';
import { EditConfig } from './EditConfig.js';
export const Config = function Config({ context, editField }) {
const [filters, setFilters] = useState(serialiseFilters(context.config));
const [ignores, setIgnores] = useState(serialiseIgnores(context.config));
function updateFilters(newFilters) {

@@ -35,18 +32,17 @@ setFilters(newFilters);

}
return (render_1.React.createElement(render_1.Box, { flexDirection: "column", marginBottom: 1 },
editField == null && (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(render_1.Box, null,
render_1.React.createElement(render_1.Text, { color: "yellowBright" }, "Filters"),
render_1.React.createElement(render_1.Text, null, " (press \"f\" to edit)"),
render_1.React.createElement(render_1.Text, { color: "yellowBright" }, ": "),
filters.length ? render_1.React.createElement(render_1.Text, null, filters) : render_1.React.createElement(render_1.Text, { color: "gray" }, "No current filter patterns")),
render_1.React.createElement(render_1.Box, null,
render_1.React.createElement(render_1.Text, { color: "yellowBright" }, "Ignores"),
render_1.React.createElement(render_1.Text, null, " (press \"i\" to edit)"),
render_1.React.createElement(render_1.Text, { color: "yellowBright" }, ": "),
ignores.length ? render_1.React.createElement(render_1.Text, null, ignores) : render_1.React.createElement(render_1.Text, { color: "gray" }, "No current ignore patterns")))),
editField == 'filters' && (render_1.React.createElement(EditConfig_1.EditConfig, { name: "Filters", value: filters, onChange: updateFilters, onSubmit: submitFilters }, "Use RegExp patterns e.g. /my test/. Use \",\" to separate multiple filters.")),
editField == 'ignores' && (render_1.React.createElement(EditConfig_1.EditConfig, { name: "Ignores", value: ignores, onChange: updateIgnores, onSubmit: submitIgnores }, "Use glob patterns starting from CWD e.g. **/*.ts. Use \",\" to separate multiple ignores."))));
return (React.createElement(Box, { flexDirection: "column", marginBottom: 1 },
editField == null && (React.createElement(React.Fragment, null,
React.createElement(Box, null,
React.createElement(Text, { color: "yellowBright" }, "Filters"),
React.createElement(Text, null, " (press \"f\" to edit)"),
React.createElement(Text, { color: "yellowBright" }, ": "),
filters.length ? React.createElement(Text, null, filters) : React.createElement(Text, { color: "gray" }, "No current filter patterns")),
React.createElement(Box, null,
React.createElement(Text, { color: "yellowBright" }, "Ignores"),
React.createElement(Text, null, " (press \"i\" to edit)"),
React.createElement(Text, { color: "yellowBright" }, ": "),
ignores.length ? React.createElement(Text, null, ignores) : React.createElement(Text, { color: "gray" }, "No current ignore patterns")))),
editField == 'filters' && (React.createElement(EditConfig, { name: "Filters", value: filters, onChange: updateFilters, onSubmit: submitFilters }, "Use RegExp patterns e.g. /my test/. Use \",\" to separate multiple filters.")),
editField == 'ignores' && (React.createElement(EditConfig, { name: "Ignores", value: ignores, onChange: updateIgnores, onSubmit: submitIgnores }, "Use glob patterns starting from CWD e.g. **/*.ts. Use \",\" to separate multiple ignores."))));
};
exports.Config = Config;
function serialiseFilters(config) {

@@ -53,0 +49,0 @@ return config.filters.map((filter) => `/${filter.source}/`).join(', ');

@@ -1,4 +0,4 @@

/// <reference types="react" />
import { PropsWithChildren } from '@betterer/render';
export interface EditConfigProps<ValidatedConfigType> {
import type { PropsWithChildren } from '@betterer/render';
/** @knipignore used by an exported function */
export type EditConfigProps<ValidatedConfigType> = PropsWithChildren<{
name: string;

@@ -8,4 +8,4 @@ onChange: (newValue: string) => [ValidatedConfigType | null, Error | null];

value: string;
}
export declare function EditConfig<ValidatedConfigType>(props: PropsWithChildren<EditConfigProps<ValidatedConfigType>>): JSX.Element;
}>;
export declare function EditConfig<ValidatedConfigType>(props: EditConfigProps<ValidatedConfigType>): React.JSX.Element;
//# sourceMappingURL=EditConfig.d.ts.map

@@ -1,31 +0,26 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.EditConfig = void 0;
const render_1 = require("@betterer/render");
function EditConfig(props) {
import { React, Box, Text, TextInput, useState, useCallback } from '@betterer/render';
export function EditConfig(props) {
const { children, name, onChange, onSubmit, value } = props;
const [error, setError] = (0, render_1.useState)(null);
const [valid, setValid] = (0, render_1.useState)(null);
function change(newValue) {
const [error, setError] = useState(null);
const [valid, setValid] = useState(null);
const change = useCallback((newValue) => {
const [valid, error] = onChange(newValue);
setValid(valid);
setError(error);
}
async function submit() {
}, [onChange]);
const submit = useCallback(async () => {
if (valid) {
await onSubmit(valid);
}
}
return (render_1.React.createElement(render_1.Box, { flexDirection: "column" },
render_1.React.createElement(render_1.Text, { color: "grey" },
children,
" Press \"enter\" to confirm."),
render_1.React.createElement(render_1.Box, null,
render_1.React.createElement(render_1.Text, { color: error ? 'redBright' : 'yellowBright' },
}, [valid, onSubmit]);
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, { color: "grey" }, "Press \"enter\" to confirm, or \"esc\" to cancel."),
React.createElement(Text, { color: "grey" }, children),
React.createElement(Box, null,
React.createElement(Text, { color: error ? 'redBright' : 'yellowBright' },
name,
": "),
render_1.React.createElement(render_1.TextInput, { value: value, onChange: change, onSubmit: submit })),
render_1.React.createElement(render_1.Box, null, error && render_1.React.createElement(render_1.Text, null, error.message))));
React.createElement(TextInput, { value: value, onChange: change, onSubmit: () => void submit() })),
React.createElement(Box, null, error && React.createElement(Text, null, error.message))));
}
exports.EditConfig = EditConfig;
//# sourceMappingURL=EditConfig.js.map

@@ -1,2 +0,2 @@

export { Config, ConfigEditField, ConfigProps } from './Config';
export { Config, ConfigEditField, ConfigProps } from './Config.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,6 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Config = void 0;
var Config_1 = require("./Config");
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return Config_1.Config; } });
export { Config } from './Config.js';
//# sourceMappingURL=index.js.map

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

/// <reference types="react" />
import { BettererSuite } from '@betterer/betterer';
import { FC } from '@betterer/render';
import type { BettererFilePaths } from '@betterer/betterer';
import type { FC } from '@betterer/render';
/** @knipignore used by an exported function */
export interface DefaultFilesProps {
suite: BettererSuite;
filePaths: BettererFilePaths;
running: boolean;

@@ -7,0 +7,0 @@ }

@@ -1,16 +0,15 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultFiles = void 0;
const render_1 = require("@betterer/render");
const messages_1 = require("../../messages");
exports.DefaultFiles = (0, render_1.memo)(function DefaultFiles(props) {
const { suite, running } = props;
const { filePaths } = suite;
return (render_1.React.createElement(render_1.React.Fragment, null, filePaths.length ? (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, running ? (0, messages_1.filesChecking)(filePaths.length) : (0, messages_1.filesChecked)(filePaths.length))),
render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 }, filePaths.map((filePath) => (render_1.React.createElement(render_1.Text, { key: filePath },
import { Box, React, Text, memo } from '@betterer/render';
import { filesChecked, filesChecking } from '../../messages.js';
export const DefaultFiles = memo(function DefaultFiles(props) {
const { filePaths, running } = props;
if (!filePaths.length) {
return null;
}
return (React.createElement(React.Fragment, null,
React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null, running ? filesChecking(filePaths.length) : filesChecked(filePaths.length))),
React.createElement(Box, { flexDirection: "column", paddingBottom: 1 }, filePaths.map((filePath) => (React.createElement(Text, { key: filePath },
"\u30FB ",
filePath)))))) : null));
filePath))))));
});
//# sourceMappingURL=DefaultFiles.js.map

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

/// <reference types="react" />
import { FC } from '@betterer/render';
import { BettererReporterState } from '../../state';
export declare const DefaultReporter: FC<BettererReporterState>;
import type { FC } from '@betterer/render';
export declare const DefaultReporter: FC;
//# sourceMappingURL=DefaultReporter.d.ts.map

@@ -1,17 +0,18 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultReporter = void 0;
const render_1 = require("@betterer/render");
const suite_1 = require("../suite");
const DefaultFiles_1 = require("./DefaultFiles");
exports.DefaultReporter = (0, render_1.memo)(function DefaultReporter(props) {
const { context, done, suiteSummary } = props;
const suite = props.suite || props.suiteSummary;
import { React, memo } from '@betterer/render';
import { useReporterState } from '../../state/index.js';
import { Suite, SuiteSummary } from '../suite/index.js';
import { DefaultFiles } from './DefaultFiles.js';
export const DefaultReporter = memo(function DefaultReporter() {
const [{ context, contextSummary, suite, suiteSummary }] = useReporterState();
if (!suite) {
return null;
}
return (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(DefaultFiles_1.DefaultFiles, { suite: suite, running: !suiteSummary }),
render_1.React.createElement(suite_1.Suite, { context: context, suite: suite, suiteSummary: suiteSummary, done: done })));
if (context.config.ci && !contextSummary) {
return null;
}
return (React.createElement(React.Fragment, null,
React.createElement(DefaultFiles, { filePaths: suite.filePaths, running: !suiteSummary }),
!suiteSummary && React.createElement(Suite, { suite: suite }),
suiteSummary && React.createElement(SuiteSummary, { context: context, suiteSummary: suiteSummary })));
});
//# sourceMappingURL=DefaultReporter.js.map

@@ -1,2 +0,2 @@

export { DefaultReporter } from './DefaultReporter';
export { DefaultReporter } from './DefaultReporter.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,6 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DefaultReporter = void 0;
var DefaultReporter_1 = require("./DefaultReporter");
Object.defineProperty(exports, "DefaultReporter", { enumerable: true, get: function () { return DefaultReporter_1.DefaultReporter; } });
export { DefaultReporter } from './DefaultReporter.js';
//# sourceMappingURL=index.js.map

@@ -1,8 +0,9 @@

/// <reference types="react" />
import { BettererError } from '@betterer/errors';
import { FC } from '@betterer/render';
import type { BettererError } from '@betterer/errors';
import type { FC } from '@betterer/render';
/** @knipignore used by an exported function */
export interface ErrorProps {
error: BettererError;
logo: boolean;
}
export declare const Error: FC<ErrorProps>;
//# sourceMappingURL=Error.d.ts.map

@@ -1,12 +0,9 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Error = void 0;
const render_1 = require("@betterer/render");
const tasks_1 = require("@betterer/tasks");
const Error = function Error({ error }) {
return (render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 },
render_1.React.createElement(tasks_1.BettererLogo, null),
render_1.React.createElement(tasks_1.BettererErrorLog, { error: error })));
import { React, Box } from '@betterer/render';
import { BettererErrorLog, BettererLogo } from '@betterer/tasks';
export const Error = function Error(props) {
const { error, logo } = props;
return (React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
logo && React.createElement(BettererLogo, null),
React.createElement(BettererErrorLog, { error: error })));
};
exports.Error = Error;
//# sourceMappingURL=Error.js.map

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

export { Error, ErrorProps } from './Error';
export { Reporter } from './Reporter';
export { Error, ErrorProps } from './Error.js';
export { Reporter } from './Reporter.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,8 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Reporter = exports.Error = void 0;
var Error_1 = require("./Error");
Object.defineProperty(exports, "Error", { enumerable: true, get: function () { return Error_1.Error; } });
var Reporter_1 = require("./Reporter");
Object.defineProperty(exports, "Reporter", { enumerable: true, get: function () { return Reporter_1.Reporter; } });
export { Error } from './Error.js';
export { Reporter } from './Reporter.js';
//# sourceMappingURL=index.js.map

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

/// <reference types="react" />
import { FC } from '@betterer/render';
import { BettererReporterState } from '../state';
export declare const Reporter: FC<BettererReporterState>;
import type { FC } from '@betterer/render';
export declare const Reporter: FC;
//# sourceMappingURL=Reporter.d.ts.map

@@ -1,13 +0,11 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Reporter = void 0;
const render_1 = require("@betterer/render");
const tasks_1 = require("@betterer/tasks");
const default_1 = require("./default");
const watch_1 = require("./watch");
const Reporter = function Reporter(props) {
const { context } = props;
const { isRawModeSupported } = (0, render_1.useStdin)();
isRawModeSupported &&
(0, render_1.useInput)((input, key) => {
import { React, Box, useInput, useStdin } from '@betterer/render';
import { BettererLogo } from '@betterer/tasks';
import { useReporterState } from '../state/index.js';
import { DefaultReporter } from './default/index.js';
import { WatchReporter } from './watch/index.js';
export const Reporter = function Reporter() {
const [{ context }] = useReporterState();
const { isRawModeSupported } = useStdin();
if (isRawModeSupported) {
useInput((input, key) => {
if (key.ctrl && input === 'c') {

@@ -18,8 +16,8 @@ void context.stop();

});
const ReporterComponent = context.config.watch ? watch_1.WatchReporter : default_1.DefaultReporter;
return (render_1.React.createElement(render_1.Box, { flexDirection: "column" },
render_1.React.createElement(tasks_1.BettererLogo, null),
render_1.React.createElement(ReporterComponent, Object.assign({}, props))));
}
const ReporterComponent = context.config.watch ? WatchReporter : DefaultReporter;
return (React.createElement(Box, { flexDirection: "column" },
context.config.logo && React.createElement(BettererLogo, null),
React.createElement(ReporterComponent, null)));
};
exports.Reporter = Reporter;
//# sourceMappingURL=Reporter.js.map

@@ -1,2 +0,4 @@

export { Suite, SuiteProps } from './Suite';
export type { SuiteSummaryProps } from './SuiteSummary.js';
export { Suite } from './Suite.js';
export { SuiteSummary } from './SuiteSummary.js';
//# sourceMappingURL=index.d.ts.map

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

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Suite = void 0;
var Suite_1 = require("./Suite");
Object.defineProperty(exports, "Suite", { enumerable: true, get: function () { return Suite_1.Suite; } });
export { Suite } from './Suite.js';
export { SuiteSummary } from './SuiteSummary.js';
//# sourceMappingURL=index.js.map

@@ -1,12 +0,8 @@

/// <reference types="react" />
import { BettererContext, BettererSuite, BettererSuiteSummary } from '@betterer/betterer';
import { FC } from '@betterer/render';
import { BettererTasksDone } from '@betterer/tasks';
import type { BettererSuite } from '@betterer/betterer';
import type { FC } from '@betterer/render';
/** @knipignore used by an exported function */
export interface SuiteProps {
context: BettererContext;
suite: BettererSuite | BettererSuiteSummary;
suiteSummary?: BettererSuiteSummary;
done?: BettererTasksDone;
suite: BettererSuite;
}
export declare const Suite: FC<SuiteProps>;
//# sourceMappingURL=Suite.d.ts.map

@@ -1,25 +0,13 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Suite = void 0;
const render_1 = require("@betterer/render");
const tasks_1 = require("@betterer/tasks");
const tasks_2 = require("./tasks");
const SuiteSummary_1 = require("./SuiteSummary");
exports.Suite = (0, render_1.memo)(function Runs({ context, suite, suiteSummary, done }) {
const { ci, precommit } = context.config;
return (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 },
render_1.React.createElement(tasks_1.BettererTasksLogger, { name: "Betterer", update: update, exit: false, done: done, timer: !precommit && !ci }, suite.runs.map((run) => (render_1.React.createElement(tasks_1.BettererTaskLogger, { key: run.name, name: run.name, task: (0, tasks_2.useTask)(run) }))))),
suiteSummary ? render_1.React.createElement(SuiteSummary_1.SuiteSummary, { context: context, suiteSummary: suiteSummary }) : null));
import { Box, memo, React } from '@betterer/render';
import { BettererTasksResult, useTimer } from '@betterer/tasks';
import { useReporterState } from '../../state/index.js';
import { Run } from './Run.js';
import { update } from './update.js';
export const Suite = memo(function Suite({ suite }) {
const [state] = useReporterState();
const time = useTimer();
return (React.createElement(React.Fragment, null,
React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
React.createElement(BettererTasksResult, Object.assign({}, state, { name: "Betterer", time: time, update: update }), suite.runs.map((run) => (React.createElement(Run, { key: run.name, run: run })))))));
});
function update(state) {
const { done, errors, running } = state;
const runningStatus = running ? `${tests(running)} running... ` : '';
const doneStatus = done ? `${tests(done)} done! ` : '';
const errorStatus = errors ? `${tests(errors)} errored! ` : '';
return `${runningStatus}${doneStatus}${errorStatus}`;
}
function tests(n) {
return n === 1 ? `${n} test` : `${n} tests`;
}
//# sourceMappingURL=Suite.js.map

@@ -1,4 +0,4 @@

/// <reference types="react" />
import { BettererContext, BettererSuiteSummary } from '@betterer/betterer';
import { FC } from '@betterer/render';
import type { BettererContext, BettererSuiteSummary } from '@betterer/betterer';
import type { FC } from '@betterer/render';
/** @knipignore used by an exported function */
export interface SuiteSummaryProps {

@@ -5,0 +5,0 @@ context: BettererContext;

@@ -1,10 +0,11 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SuiteSummary = void 0;
const render_1 = require("@betterer/render");
const messages_1 = require("../../messages");
import { Box, React, Text, memo } from '@betterer/render';
import { BettererTasksResult } from '@betterer/tasks';
import { testsBetter, testsChecked, testsComplete, testsExpired, testsFailed, testsNew, testsObsolete, testsRemoved, testsSame, testsSkipped, testsUpdated, testsWorse, unexpectedChanges, unexpectedChangesInstructions, stayedTheSameButChanged, stayedTheSameButChangedInstructions, updateInstructionsObsolete, updateInstructionsWorse } from '../../messages.js';
import { useReporterState } from '../../state/index.js';
import { RunSummary } from './RunSummary.js';
import { update } from './update.js';
import { WorkflowSuggestions } from './WorkflowSuggestions.js';
const TEXT_COLOURS = {
better: 'greenBright',
changed: 'red',
checked: 'gray',
completed: 'greenBright',

@@ -14,3 +15,5 @@ expired: 'brightRed',

new: 'gray',
obsolete: 'brightRed',
obsolete: 'magentaBright',
ran: 'gray',
removed: 'white',
same: 'brightYellow',

@@ -21,41 +24,57 @@ skipped: 'brightYellow',

};
exports.SuiteSummary = (0, render_1.memo)(function SuiteSummary({ context, suiteSummary }) {
const better = suiteSummary.better.length;
const completed = suiteSummary.completed.length;
const expired = suiteSummary.expired.length;
const failed = suiteSummary.failed.length;
const neww = suiteSummary.new.length;
const ran = suiteSummary.ran.length;
const same = suiteSummary.same.length;
const skipped = suiteSummary.skipped.length;
const updated = suiteSummary.updated.length;
const worse = suiteSummary.worse.length;
return (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 },
render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.checked }, (0, messages_1.testChecked)(tests(ran))),
neww ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.new }, (0, messages_1.testNew)(tests(neww))) : null,
better ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.better }, (0, messages_1.testBetter)(tests(better))) : null,
completed ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.completed }, (0, messages_1.testComplete)(tests(completed))) : null,
same ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.same }, (0, messages_1.testSame)(tests(same))) : null,
failed ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.failed }, (0, messages_1.testFailed)(tests(failed))) : null,
skipped ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.skipped }, (0, messages_1.testSkipped)(tests(skipped))) : null,
updated ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.updated }, (0, messages_1.testUpdated)(tests(updated))) : null,
worse ? (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.worse }, (0, messages_1.testWorse)(tests(worse)))),
!context.config.strict && render_1.React.createElement(render_1.Text, null, (0, messages_1.updateInstructions)()))) : null,
expired ? render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.expired },
(0, messages_1.testExpired)(tests(expired)),
")") : null),
context.config.ci && suiteSummary.changed.length ? (render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 },
render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.changed }, (0, messages_1.unexpectedChanges)()),
render_1.React.createElement(render_1.Box, { flexDirection: "column", padding: 1 }, suiteSummary.changed.map((name) => (render_1.React.createElement(render_1.Text, { key: name },
export const SuiteSummary = memo(function SuiteSummary({ context, suiteSummary }) {
const [state] = useReporterState();
function getColor(name) {
return TEXT_COLOURS[name];
}
function showIfHasCategory(name, getMessage) {
const count = suiteSummary[name].length;
return count ? React.createElement(Text, { color: getColor(name) }, getMessage(count)) : null;
}
const { endTime } = state;
if (endTime == null) {
return null;
}
const unexpectedChangesDetected = context.config.ci && suiteSummary.changed.length;
const fileContentChanges = unexpectedChangesDetected && onlyFileContentsChanges(suiteSummary);
return (React.createElement(React.Fragment, null,
React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
React.createElement(BettererTasksResult, Object.assign({}, state, { name: "Betterer", time: endTime, update: update }), suiteSummary.runSummaries.map((runSummary) => (React.createElement(RunSummary, { key: runSummary.name, runSummary: runSummary }))))),
React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
React.createElement(Text, { color: getColor('ran') }, testsChecked(suiteSummary.ran.length)),
showIfHasCategory('new', testsNew),
showIfHasCategory('better', testsBetter),
showIfHasCategory('completed', testsComplete),
showIfHasCategory('same', testsSame),
showIfHasCategory('failed', testsFailed),
showIfHasCategory('skipped', testsSkipped),
showIfHasCategory('updated', testsUpdated),
suiteSummary.worse.length ? (React.createElement(React.Fragment, null,
React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, { color: getColor('worse') }, testsWorse(suiteSummary.worse.length))),
!context.config.strict ? React.createElement(Text, null, updateInstructionsWorse()) : null)) : null,
showIfHasCategory('removed', testsRemoved),
suiteSummary.obsolete.length ? (React.createElement(React.Fragment, null,
React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, { color: getColor('obsolete') }, testsObsolete(suiteSummary.obsolete.length))),
React.createElement(Text, null, updateInstructionsObsolete()))) : null,
showIfHasCategory('expired', testsExpired)),
unexpectedChangesDetected && !fileContentChanges ? (React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
React.createElement(Text, { color: getColor('changed') }, unexpectedChanges()),
React.createElement(Box, { flexDirection: "column", padding: 1 }, suiteSummary.changed.map((name) => (React.createElement(Text, { key: name },
"\"",
name,
"\"")))),
render_1.React.createElement(render_1.Text, { color: TEXT_COLOURS.changed }, (0, messages_1.unexpectedChangesInstructions)()))) : null));
React.createElement(Text, { color: getColor('changed') }, unexpectedChangesInstructions()),
React.createElement(WorkflowSuggestions, null))) : null,
fileContentChanges ? (React.createElement(Box, { flexDirection: "column", paddingBottom: 1 },
React.createElement(Text, { color: TEXT_COLOURS.changed }, stayedTheSameButChanged()),
React.createElement(Text, { color: TEXT_COLOURS.changed }, stayedTheSameButChangedInstructions()),
React.createElement(WorkflowSuggestions, null))) : null));
});
function tests(n) {
return n === 1 ? `${n} test` : `${n} tests`;
function onlyFileContentsChanges(suiteSummary) {
// If every test name listed in `changed` is also the name of a test listed in `same`,
// the the actual contents of the files changed, but not the results:
return suiteSummary.changed.every((testName) => !!suiteSummary.same.find((runSummary) => runSummary.name === testName));
}
//# sourceMappingURL=SuiteSummary.js.map

@@ -1,2 +0,2 @@

export { WatchReporter } from './WatchReporter';
export { WatchReporter } from './WatchReporter.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,6 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchReporter = void 0;
var WatchReporter_1 = require("./WatchReporter");
Object.defineProperty(exports, "WatchReporter", { enumerable: true, get: function () { return WatchReporter_1.WatchReporter; } });
export { WatchReporter } from './WatchReporter.js';
//# sourceMappingURL=index.js.map

@@ -1,4 +0,4 @@

import { BettererContext } from '@betterer/betterer';
import { ConfigEditField } from '../config';
import type { BettererContext } from '@betterer/betterer';
import type { ConfigEditField } from '../config/index.js';
export declare function useControls(context: BettererContext): ConfigEditField;
//# sourceMappingURL=useControls.d.ts.map

@@ -1,37 +0,38 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useControls = void 0;
const render_1 = require("@betterer/render");
function useControls(context) {
const { isRawModeSupported } = (0, render_1.useStdin)();
const [editing, setEditing] = (0, render_1.useState)(null);
const canEdit = isRawModeSupported;
const useEdit = canEdit ? render_1.useInput : () => void 0;
isRawModeSupported &&
useEdit((input, key) => {
if (key.return) {
setEditing(null);
import { useEffect, useState, useStdin } from '@betterer/render';
// Stolen mostly from ink's `useInput` hook.
export function useControls(context) {
const { stdin } = useStdin();
const [editing, setEditing] = useState(null);
useEffect(() => {
function handleData(data) {
const input = String(data);
const isReturn = input === '\r';
const isEscape = input === '\u001B';
if (editing) {
if (isReturn || isEscape) {
setEditing(null);
return;
}
return;
}
if (key.escape) {
if (isEscape || input === 'q') {
void context.stop();
return;
}
if (editing != null) {
return;
}
// Don't exit on 'q' if the user is editing filters or ignores:
if (input === 'q') {
void context.stop();
}
if (input === 'f') {
setEditing('filters');
return;
}
if (input === 'i') {
setEditing('ignores');
return;
}
});
}
stdin === null || stdin === void 0 ? void 0 : stdin.on('data', handleData);
return () => {
stdin === null || stdin === void 0 ? void 0 : stdin.off('data', handleData);
};
}, [editing]);
return editing;
}
exports.useControls = useControls;
//# sourceMappingURL=useControls.js.map

@@ -1,4 +0,3 @@

/// <reference types="react" />
import { FC } from '@betterer/render';
import type { FC } from '@betterer/render';
export declare const WatchEnding: FC;
//# sourceMappingURL=WatchEnding.d.ts.map

@@ -1,10 +0,7 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchEnding = void 0;
const render_1 = require("@betterer/render");
const messages_1 = require("../../messages");
exports.WatchEnding = (0, render_1.memo)(function WatchEnding() {
return (render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, (0, messages_1.watchEnd)())));
import { React, Box, Text, memo } from '@betterer/render';
import { watchEnd } from '../../messages.js';
export const WatchEnding = memo(function WatchEnding() {
return (React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null, watchEnd())));
});
//# sourceMappingURL=WatchEnding.js.map

@@ -1,9 +0,9 @@

/// <reference types="react" />
import { BettererContext, BettererSuite } from '@betterer/betterer';
import { FC } from '@betterer/render';
import { ConfigEditField } from '../config';
import type { BettererContext, BettererFilePaths } from '@betterer/betterer';
import type { FC } from '@betterer/render';
import type { ConfigEditField } from '../config/index.js';
/** @knipignore used by an exported function */
export interface WatchFilesProps {
context: BettererContext;
editField: ConfigEditField;
suite: BettererSuite;
filePaths: BettererFilePaths;
running: boolean;

@@ -10,0 +10,0 @@ }

@@ -1,21 +0,19 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchFiles = void 0;
const render_1 = require("@betterer/render");
const messages_1 = require("../../messages");
const config_1 = require("../config");
exports.WatchFiles = (0, render_1.memo)(function WatchFiles(props) {
const { context, editField, suite, running } = props;
const { filePaths } = suite;
const isTestChange = context.config.configPaths.some((configPath) => filePaths.includes(configPath));
return (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(config_1.Config, { context: context, editField: editField }),
(filePaths === null || filePaths === void 0 ? void 0 : filePaths.length) ? (render_1.React.createElement(render_1.React.Fragment, null,
isTestChange ? (render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, (0, messages_1.testsChanged)()))) : (render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, running ? (0, messages_1.filesChecking)(filePaths.length) : (0, messages_1.filesChecked)(filePaths.length)))),
render_1.React.createElement(render_1.Box, { flexDirection: "column", paddingBottom: 1 }, filePaths.map((filePath) => (render_1.React.createElement(render_1.Text, { key: filePath },
"\u30FB ",
filePath)))))) : null));
import { React, Box, Text, memo } from '@betterer/render';
import { filesChecked, filesChecking, testsChanged } from '../../messages.js';
import { Config } from '../config/index.js';
export const WatchFiles = memo(function WatchFiles(props) {
const { context, editField, filePaths, running } = props;
const isTestChange = filePaths.length === 0;
if (isTestChange) {
return (React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null, testsChanged())));
}
return (React.createElement(React.Fragment, null,
React.createElement(Config, { context: context, editField: editField }),
React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null, running ? filesChecking(filePaths.length) : filesChecked(filePaths.length))),
React.createElement(Box, { flexDirection: "column", paddingBottom: 1 }, filePaths.map((filePath) => (React.createElement(Text, { key: filePath },
"\u30FB ",
filePath))))));
});
//# sourceMappingURL=WatchFiles.js.map

@@ -1,4 +0,8 @@

/// <reference types="react" />
import { FC } from '@betterer/render';
export declare const WatchInstructions: FC;
import type { FC } from '@betterer/render';
import type { ConfigEditField } from '../config/Config.js';
/** @knipignore used by an exported function */
export interface WatchFilesProps {
editField: ConfigEditField;
}
export declare const WatchInstructions: FC<WatchFilesProps>;
//# sourceMappingURL=WatchInstructions.d.ts.map

@@ -1,9 +0,10 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchInstructions = void 0;
const render_1 = require("@betterer/render");
exports.WatchInstructions = (0, render_1.memo)(function WatchInstructions() {
return (render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, "(press \"q\" to quit)")));
import { React, Box, Text, memo } from '@betterer/render';
export const WatchInstructions = memo(function WatchInstructions(props) {
const quitCommands = `"ctrl+c"${props.editField ? '' : ' or "q"'}`;
return (React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null,
"(press ",
quitCommands,
" to quit)")));
});
//# sourceMappingURL=WatchInstructions.js.map

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

/// <reference types="react" />
import { FC } from '@betterer/render';
import { BettererReporterState } from '../../state';
export declare const WatchReporter: FC<BettererReporterState>;
import type { FC } from '@betterer/render';
export declare const WatchReporter: FC;
//# sourceMappingURL=WatchReporter.d.ts.map

@@ -1,26 +0,24 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchReporter = void 0;
const render_1 = require("@betterer/render");
const suite_1 = require("../suite");
const WatchEnding_1 = require("./WatchEnding");
const WatchFiles_1 = require("./WatchFiles");
const WatchInstructions_1 = require("./WatchInstructions");
const WatchStarting_1 = require("./WatchStarting");
const useControls_1 = require("./useControls");
exports.WatchReporter = (0, render_1.memo)(function WatchReporter(props) {
const { context, contextSummary, done, suiteSummary } = props;
const suite = props.suiteSummary || props.suite;
const editing = (0, useControls_1.useControls)(context);
import { React, memo } from '@betterer/render';
import { useReporterState } from '../../state/index.js';
import { Suite, SuiteSummary } from '../suite/index.js';
import { WatchEnding } from './WatchEnding.js';
import { WatchFiles } from './WatchFiles.js';
import { WatchInstructions } from './WatchInstructions.js';
import { WatchStarting } from './WatchStarting.js';
import { useControls } from './useControls.js';
export const WatchReporter = memo(function WatchReporter() {
const [{ context, contextSummary, suite, suiteSummary }] = useReporterState();
const editField = useControls(context);
if (contextSummary) {
return render_1.React.createElement(WatchEnding_1.WatchEnding, null);
return React.createElement(WatchEnding, null);
}
if (suite) {
return (render_1.React.createElement(render_1.React.Fragment, null,
render_1.React.createElement(WatchFiles_1.WatchFiles, { context: context, editField: editing, suite: suite, running: !suiteSummary }),
render_1.React.createElement(suite_1.Suite, { context: context, suite: suite, suiteSummary: suiteSummary, done: done }),
render_1.React.createElement(WatchInstructions_1.WatchInstructions, null)));
if (!suite) {
return React.createElement(WatchStarting, { context: context, editField: editField });
}
return render_1.React.createElement(WatchStarting_1.WatchStarting, { context: context, editField: editing });
return (React.createElement(React.Fragment, null,
React.createElement(WatchFiles, { context: context, editField: editField, filePaths: suite.filePaths, running: !suiteSummary }),
!suiteSummary && React.createElement(Suite, { suite: suite }),
suiteSummary && React.createElement(SuiteSummary, { context: context, suiteSummary: suiteSummary }),
React.createElement(WatchInstructions, { editField: editField })));
});
//# sourceMappingURL=WatchReporter.js.map

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

/// <reference types="react" />
import { FC } from '@betterer/render';
import { BettererContext } from '@betterer/betterer';
import { ConfigEditField } from '../config';
import type { BettererContext } from '@betterer/betterer';
import type { FC } from '@betterer/render';
import type { ConfigEditField } from '../config/index.js';
/** @knipignore used by an exported function */
export interface WatchStartingProps {

@@ -6,0 +6,0 @@ context: BettererContext;

@@ -1,16 +0,13 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.WatchStarting = void 0;
const render_1 = require("@betterer/render");
const messages_1 = require("../../messages");
const config_1 = require("../config");
const WatchInstructions_1 = require("./WatchInstructions");
exports.WatchStarting = (0, render_1.memo)(function WatchStarting(props) {
import { React, Box, Text, memo } from '@betterer/render';
import { watchStart } from '../../messages.js';
import { Config } from '../config/index.js';
import { WatchInstructions } from './WatchInstructions.js';
export const WatchStarting = memo(function WatchStarting(props) {
const { context, editField } = props;
return (render_1.React.createElement(render_1.Box, { flexDirection: "column" },
render_1.React.createElement(config_1.Config, { context: context, editField: editField }),
render_1.React.createElement(render_1.Box, { paddingBottom: 1 },
render_1.React.createElement(render_1.Text, null, (0, messages_1.watchStart)())),
render_1.React.createElement(WatchInstructions_1.WatchInstructions, null)));
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Config, { context: context, editField: editField }),
React.createElement(Box, { paddingBottom: 1 },
React.createElement(Text, null, watchStart())),
React.createElement(WatchInstructions, { editField: editField })));
});
//# sourceMappingURL=WatchStarting.js.map

@@ -6,3 +6,3 @@ /**

*/
export { reporter } from './reporter';
export { reporter, createReporterΔ } from './reporter.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,2 +0,1 @@

"use strict";
/**

@@ -7,6 +6,3 @@ * The default reporter for {@link https://github.com/phenomnomnominal/betterer | **Betterer**}.

*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.reporter = void 0;
var reporter_1 = require("./reporter");
Object.defineProperty(exports, "reporter", { enumerable: true, get: function () { return reporter_1.reporter; } });
export { reporter, createReporterΔ } from './reporter.js';
//# sourceMappingURL=index.js.map

@@ -1,16 +0,33 @@

export declare function testBetter(context: string, delta?: string): string;
export declare function testChecked(context: string): string;
export declare function testComplete(context: string, isNew?: boolean): string;
export declare function testExpired(context: string): string;
export declare function testFailed(context: string): string;
export declare function testNew(context: string, delta?: string): string;
export declare function testRunning(context: string): string;
export declare function testSame(context: string, delta?: string): string;
export declare function testSkipped(context: string, delta?: string): string;
export declare function testUpdated(context: string, delta?: string): string;
export declare function testWorse(context: string, delta?: string): string;
export declare function testBetter(name: string, delta?: string): string;
export declare function testsBetter(count: number, delta?: string): string;
export declare function testsChecked(count: number): string;
export declare function testComplete(name: string, isSame?: boolean): string;
export declare function testsComplete(count: number): string;
export declare function testExpired(name: string): string;
export declare function testsExpired(count: number): string;
export declare function testsFailed(count: number): string;
export declare function testNew(name: string, delta?: string): string;
export declare function testsNew(count: number, delta?: string): string;
export declare function testObsolete(name: string): string;
export declare function testsObsolete(count: number): string;
export declare function testRemoved(name: string): string;
export declare function testsRemoved(count: number): string;
export declare function testRunning(name: string): string;
export declare function testSame(name: string, delta?: string): string;
export declare function testsSame(count: number, delta?: string): string;
export declare function testSkipped(name: string, delta?: string): string;
export declare function testsSkipped(count: number, delta?: string): string;
export declare function testUpdated(name: string, delta?: string): string;
export declare function testsUpdated(count: number, delta?: string): string;
export declare function testWorse(name: string, delta?: string): string;
export declare function testsWorse(count: number, delta?: string): string;
export declare function testsChanged(): string;
export declare function updateInstructions(): string;
export declare function updateInstructionsWorse(): string;
export declare function updateInstructionsObsolete(): string;
export declare function unexpectedChanges(): string;
export declare function unexpectedChangesInstructions(): string;
export declare function stayedTheSameButChanged(): string;
export declare function stayedTheSameButChangedInstructions(): string;
export declare function workflowSuggestions(): string;
export declare function workflowLink(): string;
export declare function filesChecking(files: number): string;

@@ -17,0 +34,0 @@ export declare function filesChecked(files: number): string;

@@ -1,83 +0,130 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.watchEnd = exports.watchStart = exports.filesChecked = exports.filesChecking = exports.unexpectedChangesInstructions = exports.unexpectedChanges = exports.updateInstructions = exports.testsChanged = exports.testWorse = exports.testUpdated = exports.testSkipped = exports.testSame = exports.testRunning = exports.testNew = exports.testFailed = exports.testExpired = exports.testComplete = exports.testChecked = exports.testBetter = void 0;
function testBetter(context, delta = '') {
return `${context} got better!${delta} 😍`;
export function testBetter(name, delta = '') {
return `${name} got better!${delta} 😍`;
}
exports.testBetter = testBetter;
function testChecked(context) {
return `${context} got checked. 🤔`;
export function testsBetter(count, delta = '') {
return testBetter(getTests(count), delta);
}
exports.testChecked = testChecked;
function testComplete(context, isNew = false) {
return `${context}${isNew ? ' has already' : ''} met its goal! ${isNew ? '✨' : '🎉'}`;
function testChecked(name) {
return `${name} got checked. 🤔`;
}
exports.testComplete = testComplete;
function testExpired(context) {
return `${context} has passed its deadline. 👻`;
export function testsChecked(count) {
return testChecked(getTests(count));
}
exports.testExpired = testExpired;
function testFailed(context) {
return `${context} failed to run. 🔥`;
export function testComplete(name, isSame = false) {
return `${name}${isSame ? ` ${getHas(1)} already` : ''} met ${getIts(1)} goal! ${isSame ? '✨' : '🎉'}`;
}
exports.testFailed = testFailed;
function testNew(context, delta = '') {
return `${context} got checked for the first time!${delta} 🎉`;
export function testsComplete(count) {
return `${getTests(count)} met ${getIts(count)} goal! 🎉`;
}
exports.testNew = testNew;
function testRunning(context) {
return `running ${context}!`;
export function testExpired(name) {
return `${name} ${getHas(1)} passed ${getIts(1)} deadline. 👻`;
}
exports.testRunning = testRunning;
function testSame(context, delta = '') {
return `${context} stayed the same.${delta} 😐`;
export function testsExpired(count) {
return `${getTests(count)} ${getHas(count)} passed ${getIts(count)} deadline. 👻`;
}
exports.testSame = testSame;
function testSkipped(context, delta = '') {
return `${context} got skipped.${delta} 🚫`;
function testFailed(name) {
return `${name} failed to run. 🔥`;
}
exports.testSkipped = testSkipped;
function testUpdated(context, delta = '') {
return `${context} got force updated.${delta} 🆙`;
export function testsFailed(count) {
return testFailed(getTests(count));
}
exports.testUpdated = testUpdated;
function testWorse(context, delta = '') {
return `${context} got worse.${delta} 😔`;
export function testNew(name, delta = '') {
return `${name} got checked for the first time!${delta} 🎉`;
}
exports.testWorse = testWorse;
function testsChanged() {
export function testsNew(count, delta = '') {
return testNew(getTests(count), delta);
}
export function testObsolete(name) {
return `${name} ${getIs(1)} obsolete! 🗑️`;
}
export function testsObsolete(count) {
return `${getTests(count)} ${getIs(count)} obsolete! 🗑️`;
}
export function testRemoved(name) {
return `${name} got removed! 👋🏻`;
}
export function testsRemoved(count) {
return testRemoved(getTests(count));
}
export function testRunning(name) {
return `running ${name}!`;
}
export function testSame(name, delta = '') {
return `${name} stayed the same.${delta} 😐`;
}
export function testsSame(count, delta = '') {
return testSame(getTests(count), delta);
}
export function testSkipped(name, delta = '') {
return `${name} got skipped.${delta} 🚫`;
}
export function testsSkipped(count, delta = '') {
return testSkipped(getTests(count), delta);
}
export function testUpdated(name, delta = '') {
return `${name} got force updated.${delta} 🆙`;
}
export function testsUpdated(count, delta = '') {
return testUpdated(getTests(count), delta);
}
export function testWorse(name, delta = '') {
return `${name} got worse.${delta} 😔`;
}
export function testsWorse(count, delta = '') {
return testWorse(getTests(count), delta);
}
export function testsChanged() {
return 'Your tests have changed, re-checking everything...\nThis could take a sec. ⏰';
}
exports.testsChanged = testsChanged;
function updateInstructions() {
export function updateInstructionsWorse() {
return 'You should try to fix the new issues! As a last resort, you can run `betterer --update` to force an update of the results file. 🆙';
}
exports.updateInstructions = updateInstructions;
function unexpectedChanges() {
export function updateInstructionsObsolete() {
return 'You have saved tests results that no longer have tests! If they are no longer needed, you can run `betterer --update` to remove the obsolete results from the results file. 🆙';
}
export function unexpectedChanges() {
return 'Unexpected changes detected in these tests while running in CI mode:';
}
exports.unexpectedChanges = unexpectedChanges;
function unexpectedChangesInstructions() {
return 'You should make sure the results file is up-to-date before committing! You might want to run `betterer precommit` in a commit hook. 💍';
export function unexpectedChangesInstructions() {
return 'You should make sure the results file is up-to-date before committing!';
}
exports.unexpectedChangesInstructions = unexpectedChangesInstructions;
function filesChecking(files) {
return `Checking ${files} ${getFiles(files)}... 🤔`;
export function stayedTheSameButChanged() {
return 'All test results stayed the same, but your code has changed in other ways!';
}
exports.filesChecking = filesChecking;
function filesChecked(files) {
return `Checked ${files} ${getFiles(files)}! 🔍`;
export function stayedTheSameButChangedInstructions() {
return 'You should make sure the results file is up-to-date before committing, and also after a rebase! 🔃';
}
exports.filesChecked = filesChecked;
function watchStart() {
export function workflowSuggestions() {
return 'Check out some suggestions to improve your workflow in the docs:';
}
export function workflowLink() {
return 'https://phenomnomnominal.github.io/betterer/docs/workflow';
}
export function filesChecking(files) {
return `Checking ${getFiles(files)}... 🤔`;
}
export function filesChecked(files) {
return `Checked ${getFiles(files)}! 🔍`;
}
export function watchStart() {
return 'Starting Betterer in watch mode! 🎉';
}
exports.watchStart = watchStart;
function watchEnd() {
export function watchEnd() {
return 'Stopping watch mode... 👋';
}
exports.watchEnd = watchEnd;
function getFiles(count) {
return count === 1 ? 'file' : 'files';
return count === 1 ? '1 file' : `${String(count)} files`;
}
function getTests(count) {
return count === 1 ? '1 test' : `${String(count)} tests`;
}
function getIs(count) {
return count === 1 ? 'is' : 'are';
}
function getHas(count) {
return count === 1 ? 'has' : 'have';
}
function getIts(count) {
return count === 1 ? 'its' : 'their';
}
//# sourceMappingURL=messages.js.map

@@ -1,2 +0,2 @@

import { BettererReporter } from '@betterer/betterer';
import type { BettererReporter } from '@betterer/betterer';
/**

@@ -11,2 +11,9 @@ * @public The default {@link @betterer/betterer#BettererReporter | `BettererReporter`}.

export declare const reporter: BettererReporter;
/**
* @internal This could change at any point! Please don't use!
*
* Used in {@link @betterer/betterer#BettererReporter | `BettererReporter`} to make
* sure there is always a fresh default Reporter.
*/
export declare function createReporterΔ(): BettererReporter;
//# sourceMappingURL=reporter.d.ts.map

@@ -1,7 +0,12 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.reporter = void 0;
const render_1 = require("@betterer/render");
const components_1 = require("./components");
const state_1 = require("./state");
import { diffΔ } from '@betterer/logger';
import { React, getRenderOptionsΔ, render } from '@betterer/render';
import { Error, Reporter } from './components/index.js';
import { getDelta } from './deltas/index.js';
import { testBetter, testComplete, testExpired, testNew, testObsolete, testRemoved, testRunning, testSame, testSkipped, testUpdated, testWorse } from './messages.js';
import { BettererReporterContext, contextEnd, runEnd, runError, runStart, suiteEnd, suiteError, suiteStart, useStore } from './state/index.js';
import { getPreciseTimeΔ } from '@betterer/time';
const DIFF_OPTIONS = {
aAnnotation: 'Expected',
bAnnotation: 'Result'
};
/**

@@ -15,10 +20,60 @@ * @public The default {@link @betterer/betterer#BettererReporter | `BettererReporter`}.

*/
exports.reporter = createReporter();
function createReporter() {
const RENDER_OPTIONS = {
debug: process.env.NODE_ENV === 'test',
export const reporter = createReporterΔ();
/**
* @internal This could change at any point! Please don't use!
*
* Used in {@link @betterer/betterer#BettererReporter | `BettererReporter`} to make
* sure there is always a fresh default Reporter.
*/
export function createReporterΔ() {
const renderOptions = getRenderOptionsΔ(process.env.NODE_ENV, {
exitOnCtrlC: false
});
let app;
let dispatch;
let logs = {};
let status = {};
const logger = createLogger((run, message) => {
var _a;
const runLogs = (_a = logs[run.name]) !== null && _a !== void 0 ? _a : [];
runLogs.push(message);
logs[run.name] = runLogs;
});
const statusLogger = createLogger((run, message) => {
status[run.name] = message;
});
const ReporterRoot = (props) => {
const store = useStore(props);
const [state] = store;
[, dispatch] = store;
return (React.createElement(BettererReporterContext.Provider, { value: [state, logs, status] },
React.createElement(Reporter, null)));
};
let renderer;
function createLogger(handler) {
return {
code(run, code) {
handler(run, { code });
},
debug(run, debug) {
handler(run, { debug });
},
error(run, error) {
handler(run, { error });
},
info(run, info) {
handler(run, { info });
},
progress(run, progress) {
handler(run, { progress });
},
success(run, success) {
handler(run, { success });
},
warn(run, warn) {
handler(run, { warn });
}
};
}
return {
runLogger: logger,
configError(_, error) {

@@ -28,46 +83,104 @@ renderError(error);

contextStart(context) {
renderer = createRenderer(context);
renderer.render();
const initialState = {
context,
done: 0,
running: 0,
errors: 0,
startTime: getPreciseTimeΔ(),
endTime: null
};
app = render(React.createElement(ReporterRoot, Object.assign({}, initialState)), renderOptions);
},
contextEnd(contextSummary) {
renderer.render((0, state_1.contextEnd)(contextSummary));
renderer.stop();
dispatch(contextEnd(contextSummary));
app.unmount();
},
contextError(_, error) {
renderError(error);
contextError(context, error) {
app.unmount();
renderError(error, context.config.logo);
},
suiteStart(suite) {
return new Promise((resolve) => {
renderer.render((0, state_1.suiteStart)(suite), resolve);
});
logs = {};
status = {};
dispatch(suiteStart(suite));
},
suiteEnd(suiteSummary) {
renderer.render((0, state_1.suiteEnd)(suiteSummary));
dispatch(suiteEnd(suiteSummary));
},
suiteError(suite, error) {
dispatch(suiteError(suite, error));
},
async runStart(run) {
await statusLogger.progress(run, testRunning(quote(run.name)));
dispatch(runStart(run));
},
async runEnd(runSummary) {
await logRunSummary(runSummary);
dispatch(runEnd(runSummary));
},
async runError(runSummary, error) {
await statusLogger.error(runSummary, error.message);
dispatch(runError(runSummary, error));
}
};
function renderError(error) {
(0, render_1.render)(render_1.React.createElement(components_1.Error, { error: error }), RENDER_OPTIONS);
function renderError(error, logo = false) {
const app = render(React.createElement(Error, { error: error, logo: logo }), renderOptions);
app.unmount();
}
function createRenderer(context) {
let app;
const dispatch = (0, state_1.createStore)(context);
return {
render(action, done) {
const state = dispatch(action);
// eslint-disable-next-line no-console
console.clear();
const component = render_1.React.createElement(components_1.Reporter, Object.assign({}, state, { done: done }));
if (!app) {
app = (0, render_1.render)(component, RENDER_OPTIONS);
}
else {
app.rerender(component);
}
},
stop() {
app.unmount();
async function logRunSummary(runSummary) {
const name = quote(runSummary.name);
if (runSummary.isExpired) {
await logger.warn(runSummary, testExpired(name));
}
if (runSummary.isComplete) {
await statusLogger.success(runSummary, testComplete(name, runSummary.isSame));
return;
}
const delta = getDelta(runSummary);
if (runSummary.isBetter) {
await statusLogger.success(runSummary, testBetter(name, delta));
return;
}
if (runSummary.isNew) {
await statusLogger.success(runSummary, testNew(name, delta));
return;
}
if (runSummary.isObsolete && !runSummary.isRemoved) {
await statusLogger.success(runSummary, testObsolete(name));
return;
}
if (runSummary.isRemoved) {
await statusLogger.success(runSummary, testRemoved(name));
return;
}
if (runSummary.isSkipped) {
await statusLogger.success(runSummary, testSkipped(name, delta));
return;
}
if (runSummary.isSame) {
await statusLogger.success(runSummary, testSame(name, delta));
return;
}
const { diff, expected, result } = runSummary;
if ((diff === null || diff === void 0 ? void 0 : diff.diff) === null && expected && result) {
const diffStr = diffΔ(expected.value, result.value, DIFF_OPTIONS);
if (diffStr) {
await logger.error(runSummary, diffStr);
}
};
}
if (runSummary.isWorse && !runSummary.isUpdated) {
await statusLogger.error(runSummary, testWorse(name, delta));
return;
}
if (runSummary.isUpdated) {
await statusLogger.success(runSummary, testUpdated(name, delta));
return;
}
// Should never get here. Note that `isFailed` isn't covered here because
// that will trigger the `runError()` hook.
}
}
function quote(str) {
return `"${str.replace(/^"/, '').replace(/"$/, '')}"`;
}
//# sourceMappingURL=reporter.js.map

@@ -1,6 +0,11 @@

import { BettererSuiteSummary, BettererContextSummary } from '@betterer/betterer';
import { BettererSuite } from '@betterer/betterer';
import type { BettererContextSummary, BettererRun, BettererRunSummary, BettererSuite, BettererSuiteSummary } from '@betterer/betterer';
import type { BettererError } from '@betterer/errors';
export declare const CONTEXT_END = "contextEnd";
export declare const RUN_END = "runEnd";
export declare const RUN_ERROR = "runError";
export declare const RUN_START = "runStart";
export declare const SUITE_END = "suiteEnd";
export declare const SUITE_ERROR = "suiteError";
export declare const SUITE_START = "suiteStart";
export declare const SUITE_END = "suiteEnd";
/** @knipignore used by an exported function */
export interface BettererContextEndAction {

@@ -10,6 +15,19 @@ name: typeof CONTEXT_END;

}
export interface BettererSuiteStartAction {
name: typeof SUITE_START;
suite: BettererSuite;
/** @knipignore used by an exported function */
export interface BettererRunEndAction {
name: typeof RUN_END;
runSummary: BettererRunSummary;
}
/** @knipignore used by an exported function */
export interface BettererRunErrorAction {
name: typeof RUN_ERROR;
runSummary: BettererRunSummary;
error: BettererError;
}
/** @knipignore used by an exported function */
export interface BettererRunStartAction {
name: typeof RUN_START;
run: BettererRun;
}
/** @knipignore used by an exported function */
export interface BettererSuiteEndAction {

@@ -19,6 +37,21 @@ name: typeof SUITE_END;

}
export declare type BettererReporterAction = BettererContextEndAction | BettererSuiteStartAction | BettererSuiteEndAction;
/** @knipignore used by an exported function */
export interface BettererSuiteErrorAction {
name: typeof SUITE_ERROR;
suiteSummary: BettererSuiteSummary;
error: BettererError;
}
/** @knipignore used by an exported function */
export interface BettererSuiteStartAction {
name: typeof SUITE_START;
suite: BettererSuite;
}
export type BettererReporterAction = BettererContextEndAction | BettererRunEndAction | BettererRunErrorAction | BettererRunStartAction | BettererSuiteEndAction | BettererSuiteErrorAction | BettererSuiteStartAction;
export declare function contextEnd(contextSummary: BettererContextSummary): BettererContextEndAction;
export declare function runEnd(runSummary: BettererRunSummary): BettererRunEndAction;
export declare function runError(runSummary: BettererRunSummary, error: BettererError): BettererRunErrorAction;
export declare function runStart(run: BettererRun): BettererRunStartAction;
export declare function suiteStart(suite: BettererSuite): BettererSuiteStartAction;
export declare function suiteEnd(suiteSummary: BettererSuiteSummary): BettererSuiteEndAction;
export declare function suiteError(suiteSummary: BettererSuiteSummary, error: BettererError): BettererSuiteErrorAction;
//# sourceMappingURL=actions.d.ts.map

@@ -1,28 +0,29 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.suiteEnd = exports.suiteStart = exports.contextEnd = exports.SUITE_END = exports.SUITE_START = exports.CONTEXT_END = void 0;
exports.CONTEXT_END = 'contextEnd';
exports.SUITE_START = 'suiteStart';
exports.SUITE_END = 'suiteEnd';
function contextEnd(contextSummary) {
return {
name: exports.CONTEXT_END,
contextSummary
};
export const CONTEXT_END = 'contextEnd';
export const RUN_END = 'runEnd';
export const RUN_ERROR = 'runError';
export const RUN_START = 'runStart';
export const SUITE_END = 'suiteEnd';
export const SUITE_ERROR = 'suiteError';
export const SUITE_START = 'suiteStart';
export function contextEnd(contextSummary) {
return { name: CONTEXT_END, contextSummary };
}
exports.contextEnd = contextEnd;
function suiteStart(suite) {
return {
name: exports.SUITE_START,
suite
};
export function runEnd(runSummary) {
return { name: RUN_END, runSummary };
}
exports.suiteStart = suiteStart;
function suiteEnd(suiteSummary) {
return {
name: exports.SUITE_END,
suiteSummary
};
export function runError(runSummary, error) {
return { name: RUN_ERROR, runSummary, error };
}
exports.suiteEnd = suiteEnd;
export function runStart(run) {
return { name: RUN_START, run };
}
export function suiteStart(suite) {
return { name: SUITE_START, suite };
}
export function suiteEnd(suiteSummary) {
return { name: SUITE_END, suiteSummary };
}
export function suiteError(suiteSummary, error) {
return { name: SUITE_ERROR, suiteSummary, error };
}
//# sourceMappingURL=actions.js.map

@@ -1,4 +0,4 @@

export { CONTEXT_END, SUITE_END, SUITE_START, BettererContextEndAction, BettererReporterAction, BettererSuiteStartAction, BettererSuiteEndAction, contextEnd, suiteStart, suiteEnd } from './actions';
export { createStore } from './store';
export { BettererReporterState } from './types';
export { BettererContextEndAction, BettererReporterAction, BettererRunEndAction, BettererRunErrorAction, BettererRunStartAction, BettererSuiteEndAction, BettererSuiteErrorAction, BettererSuiteStartAction, CONTEXT_END, RUN_END, RUN_ERROR, RUN_START, SUITE_END, SUITE_ERROR, SUITE_START, contextEnd, runEnd, runError, runStart, suiteEnd, suiteError, suiteStart } from './actions.js';
export { BettererReporterContext, useStore, useReporterState } from './store.js';
export { BettererReporterState } from './types.js';
//# sourceMappingURL=index.d.ts.map

@@ -1,13 +0,3 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStore = exports.suiteEnd = exports.suiteStart = exports.contextEnd = exports.SUITE_START = exports.SUITE_END = exports.CONTEXT_END = void 0;
var actions_1 = require("./actions");
Object.defineProperty(exports, "CONTEXT_END", { enumerable: true, get: function () { return actions_1.CONTEXT_END; } });
Object.defineProperty(exports, "SUITE_END", { enumerable: true, get: function () { return actions_1.SUITE_END; } });
Object.defineProperty(exports, "SUITE_START", { enumerable: true, get: function () { return actions_1.SUITE_START; } });
Object.defineProperty(exports, "contextEnd", { enumerable: true, get: function () { return actions_1.contextEnd; } });
Object.defineProperty(exports, "suiteStart", { enumerable: true, get: function () { return actions_1.suiteStart; } });
Object.defineProperty(exports, "suiteEnd", { enumerable: true, get: function () { return actions_1.suiteEnd; } });
var store_1 = require("./store");
Object.defineProperty(exports, "createStore", { enumerable: true, get: function () { return store_1.createStore; } });
export { CONTEXT_END, RUN_END, RUN_ERROR, RUN_START, SUITE_END, SUITE_ERROR, SUITE_START, contextEnd, runEnd, runError, runStart, suiteEnd, suiteError, suiteStart } from './actions.js';
export { BettererReporterContext, useStore, useReporterState } from './store.js';
//# sourceMappingURL=index.js.map

@@ -1,4 +0,10 @@

import { BettererContext } from '@betterer/betterer';
import { BettererReporterDispatch } from './types';
export declare function createStore(context: BettererContext): BettererReporterDispatch;
import type { BettererLog, BettererLogs } from '@betterer/logger';
import type { BettererReporterAction } from './actions.js';
import type { BettererReporterState } from './types.js';
type BettererReporterLogs = Record<string, BettererLogs>;
type BettererReporterStatus = Record<string, BettererLog>;
export declare const BettererReporterContext: import("react").Context<[BettererReporterState, BettererReporterLogs, BettererReporterStatus] | null>;
export declare function useReporterState(): [BettererReporterState, BettererReporterLogs, BettererReporterStatus];
export declare function useStore(initialState: BettererReporterState): [BettererReporterState, React.Dispatch<BettererReporterAction>];
export {};
//# sourceMappingURL=store.d.ts.map

@@ -1,35 +0,51 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStore = void 0;
const actions_1 = require("./actions");
function createStore(context) {
const reducer = (state, action) => {
import { invariantΔ } from '@betterer/errors';
import { createContext, useContext, useReducer } from '@betterer/render';
import { getPreciseTimeΔ } from '@betterer/time';
import { CONTEXT_END, RUN_END, RUN_ERROR, RUN_START, SUITE_END, SUITE_ERROR, SUITE_START } from './actions.js';
export const BettererReporterContext = createContext(null);
export function useReporterState() {
const context = useContext(BettererReporterContext);
invariantΔ(context, 'Trying to use `BettererReporterContext` before it was created!');
return context;
}
export function useStore(initialState) {
return useReducer((state, action) => {
switch (action.name) {
case actions_1.CONTEXT_END: {
case CONTEXT_END: {
return Object.assign(Object.assign({}, state), { contextSummary: action.contextSummary });
}
case actions_1.SUITE_START: {
return {
context: state.context,
suite: action.suite
};
case RUN_END: {
const { runSummary } = action;
// `isFailed` will be handled by `RUN_ERROR`:
const error = runSummary.isWorse && !runSummary.isUpdated;
const running = state.running - 1;
const allDone = running === 0;
return Object.assign(Object.assign({}, state), { running, done: state.done + 1, errors: state.errors + (error ? 1 : 0), endTime: allDone ? getPreciseTimeΔ() : null });
}
case actions_1.SUITE_END: {
return {
context: state.context,
suiteSummary: action.suiteSummary
};
case RUN_ERROR: {
const running = state.running - 1;
const allDone = running === 0;
return Object.assign(Object.assign({}, state), { running, done: state.done + 1, errors: state.errors + 1, endTime: allDone ? getPreciseTimeΔ() : null });
}
case RUN_START: {
return Object.assign(Object.assign({}, state), { running: state.running + 1 });
}
case SUITE_END: {
return Object.assign(Object.assign({}, state), { suiteSummary: action.suiteSummary });
}
case SUITE_ERROR: {
return Object.assign(Object.assign({}, state), { suiteSummary: action.suiteSummary });
}
case SUITE_START: {
const runsLogs = {};
const runsStatus = {};
action.suite.runs.forEach((run) => {
runsLogs[run.name] = [];
runsStatus[run.name] = {};
});
return Object.assign(Object.assign({}, state), { suite: action.suite, suiteSummary: void 0, done: 0, running: 0, errors: 0, startTime: getPreciseTimeΔ(), endTime: null });
}
}
};
let state = { context };
return function dispatch(action) {
if (!action) {
return state;
}
state = reducer(state, action);
return state;
};
}, initialState);
}
exports.createStore = createStore;
//# sourceMappingURL=store.js.map

@@ -1,12 +0,9 @@

import { BettererContext, BettererSuite, BettererSuiteSummary, BettererContextSummary } from '@betterer/betterer';
import { BettererTasksDone } from '@betterer/tasks';
import { BettererReporterAction } from './actions';
export interface BettererReporterState {
import type { BettererContext, BettererContextSummary, BettererSuite, BettererSuiteSummary } from '@betterer/betterer';
import type { BettererTasksState } from '@betterer/tasks';
export interface BettererReporterState extends BettererTasksState {
context: BettererContext;
contextSummary?: BettererContextSummary;
done?: BettererTasksDone;
suite?: BettererSuite;
suiteSummary?: BettererSuiteSummary;
}
export declare type BettererReporterDispatch = (action?: BettererReporterAction) => BettererReporterState;
//# sourceMappingURL=types.d.ts.map

@@ -1,3 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
export {};
//# sourceMappingURL=types.js.map

@@ -8,5 +8,5 @@ // This file is read by tools that parse documentation comments conforming to the TSDoc standard.

"packageName": "@microsoft/api-extractor",
"packageVersion": "7.18.20"
"packageVersion": "7.47.7"
}
]
}

@@ -1,11 +0,5 @@

import { BettererRun, BettererRunSummary } from '@betterer/betterer';
import { BettererTasksDone } from '@betterer/tasks';
import { BettererReporterAction } from './state';
export interface BettererReporterRenderer {
render: (action?: BettererReporterAction, done?: BettererTasksDone) => void;
stop: () => void;
}
export declare type BettererReporterRun = BettererRun & {
lifecycle: Promise<BettererRunSummary>;
import type { BettererRun, BettererRunSummary } from '@betterer/betterer';
export type BettererReporterRun = BettererRun & {
lifecycle: ReturnType<typeof Promise.withResolvers<BettererRunSummary>>;
};
//# sourceMappingURL=types.d.ts.map

@@ -1,3 +0,2 @@

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
export {};
//# sourceMappingURL=types.js.map
{
"name": "@betterer/reporter",
"description": "Default reporter @betterer/betterer",
"version": "5.4.0",
"version": "6.0.0-alpha.1",
"license": "MIT",

@@ -11,2 +11,3 @@ "publishConfig": {

"types": "dist/index.d.ts",
"type": "module",
"files": [

@@ -29,13 +30,13 @@ "dist"

"engines": {
"node": ">=12"
"node": ">=16"
},
"dependencies": {
"@betterer/betterer": "^5.4.0",
"@betterer/errors": "^5.3.0",
"@betterer/logger": "^5.3.4",
"@betterer/render": "^5.3.4",
"@betterer/tasks": "^5.3.6",
"tslib": "^2.3.1"
"@betterer/betterer": "^6.0.0-alpha.1",
"@betterer/errors": "^6.0.0-alpha.1",
"@betterer/logger": "^6.0.0-alpha.1",
"@betterer/render": "^6.0.0-alpha.1",
"@betterer/tasks": "^6.0.0-alpha.1",
"@betterer/time": "^6.0.0-alpha.1"
},
"gitHead": "c791fe43fb94344ee33d3573a6c42f274891d266"
"gitHead": "821992635c8b6a4891169dad3334203f866e5521"
}

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

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

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

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

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

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

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

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

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

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

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