@statoscope/stats-validator
v5.28.1
Published
Statoscope stats validator
Downloads
69,518
Readme
Statoscope Stats Validator
This package contains a toolkit to validate stats.
API
new Validator(config: Config, rootDir?: string)
Create the Validator instance with config (see below), relative rootDir
-directory (current working directory by default)
validate(input: string, reference?: string): Promise<Result>
Apply rules to input
and reference
(if specified) files.
input
-file is a current stats (e.g. stats of current branch).
reference
-file is a stats to compare with (e.g. stats of master branch).
Returns validation results (see below).
Config
type Config = {
plugins?: Array<string | [string, string]>;
rules: Record<string, RuleDesc<unknown>>;
reporters?: ReporterConfig[];
warnAsError?: boolean;
};
plugins
List of plugins (see more about plugins API below).
The main goal of a plugin is providing some rules for validation.
There is a plugin to validate webpack stats (need to be installed)
npm install --save-dev @statoscope/stats-validator-plugin-webpack
statoscope.config.js:
module.export = {
validate: {
plugins: ['@statoscope/webpack'],
rules: {
'@statoscope/webpack/no-modules-deopts': ["error"]
}
}
};
Plugin path resolution
There are a few ways to how you can specify a plugin name:
- full package name
- short package name (please see example below)
- relative or absolute path
Here are the examples with all possible ways:
statoscope.config.js:
module.export = {
validate: {
plugins: [
'statoscope-stats-validator-plugin-foo', // full package name
'@statoscope/webpack', // short package name, resolves to @statoscope/stats-validator-plugin-webpack
'@foo/my-validator', // short package name, resolves to @foo/statoscope-stats-validator-plugin-my-validator
'webpack', // short package name, resolves to statoscope-stats-validator-plugin-webpack
['./my/plugin.js', 'my-plugin'], // relative path (relative config path)
[require.resolve('./my/another/plugin.js'), 'my-another-plugin'] // absolute path
],
rules: {
'statoscope-stats-validator-plugin-foo/some-rule': ['error'],
'@statoscope/webpack/no-modules-deopts': ['error'],
'foo/some-rule': ['error'],
'my-plugin/some-rule': ['error'],
'my-another-plugin/some-rule': ['error'],
}
}
};
To use short package name, its name must have statoscope-stats-validator-plugin-
-prefix or @statoscope/stats-validator-plugin-
-prefix.
Note that relative or absolute path should be specified with an alias
rules
List of rules (see more about rules API below).
Rule validates some part of a bundle.
Every item of the list contains: rule name, execution mode and rule options (optional).
Execution modes:
error
- rules messages have treated as an errorwarn
- rules messages have treated as a warningoff
- rules messages have ignored
statoscope.config.js:
module.export = {
validate: {
plugins: [
'@statoscope/webpack',
],
rules: {
'@statoscope/webpack/restricted-packages': ['error', ['lodash']],
}
}
};
reporters
List of reporters (see more about reporters API below).
Reporter handles validation results.
There are two builtin reporters:
statoscope.config.js:
module.export = {
validate: {
plugins: [
'@statoscope/webpack',
],
reporters: [
'statoscope-stats-validator-reporter-foo', // full package name
'@statoscope/stats-report', // short package name, resolves to @statoscope/stats-validator-reporter-stats-report
'stats-report', // short package name, resolves to @statoscope/stats-validator-reporter-stats-report or statoscope-stats-validator-reporter-stats-report
['./my/plugin.js', 'my-report'], // relative path (relative config path)
[require.resolve('./my/another/report.js'), 'my-another-report'] // absolute path
],
rules: {
'@statoscope/webpack/restricted-packages': ['error', ['lodash']],
}
}
};
To use short package name, its name must have statoscope-stats-validator-reporter-
-prefix or @statoscope/stats-validator-reporter-
-prefix.
ConsoleReporter
has used by default.
warnAsError
Treat warn-messages from rules as errors.
Plugins API
Plugin is a function that must return a plugin descriptor:
const myPlugin = () => {
return {
prepare(files) {
return doSomethingWithFiles(files);
},
rules: {
foo: fooRule,
bar: barRule,
}
};
};
prepare
prepare
-function of every plugin will be called for input
and reference
files.
rules
List of rules that plugin provides.
Rules API
Rule is a function that validates some part of bundle:
const myRule = (params, data, api) => {
if (!isOK(data)) {
api.message('Something is wrong');
}
}
params
- options from config (e.g.'my-plugin/my-rule': ['error', { foo: 'bar'}]
)data
- input and reference files contentapi
- rule API instance
api.message(text: string, options?: APIFnOptions): void
Add validation message from the rule.
options.filename?: string
File name that the message has associated with
options.compilation?: string
Compilation id that the message has associated with
options.related?: RelatedItem[]
Entities that the message has associated with
api.message(
'Something is wrong with module ./foo.js',
{
related: [
{ type: 'module', id: './foo.js' }
]
}
);
There are several types of related items:
module
package
package-instance
resource
entry
compilation
options.details?: Details
Details for reporters
There are several types of details:
text
Used by text-reporters
api.message(
'Something is wrong with module ./foo.js',
{
details: [
{
type: 'text',
content: [
'Here are the module reasons:',
...module.resons.map(r => r.name)
]
}
]
}
);
❌ Something is wrong with module ./foo.js
Here are the module reasons:
./bar.js
./baz.js
content
might bestring | string[] | (() => string | string[])
tty
Used by TTY-reporters (e.g. ConsoleReporter)
import chalk from 'chalk';
api.message(
'Something is wrong with module ./foo.js',
{
details: [
{
type: 'tty',
content: [
chalk.cyan('Here are the module reasons:'),
...module.resons.map(r => chalk.yellow(r.name))
]
}
]
}
);
content
might bestring | string[] | (() => string | string[])
discovery
Used by discovery-reporters (e.g. StatsReportReporter)
The main idea around this type of details is passing some data to stats report viewer (based on DiscoveryJS).
It helps to discover validation message with flexible UI.
api.message(`Module ${module.name} should not be used`, {
details: [
{
type: 'discovery',
query: `
$input: resolveInputFile();
{ module: #.module.resolveModule(#.compilation) }
`,
payload: {
context: {
compilation: compilation.hash,
module: module.name,
},
},
view: {
view: 'module-item',
data: `{ module }`
}
},
],
});
See examples at Stats Validator Webpack Plugin
api.getStorage(): Storage
Get list of validation messages (results) that was emitted by the rule.
const items = api.getStorage();
for (const item of items) {
console.log(item.message);
}
Every storage item has the following format:
type Item = {
message: string; // item message
filename?: string; // file name that the message has associated with
compilation?: string; // compilation id that the message has associated with
details?: Details; // rule's details (see api.message method for more info)
related?: RelatedItem[]; // rule's related entities (see api.message method for more info)
};
api.setRuleDescriptor(descriptor: RuleDescriptor): void
Set rule meta-data.
api.setRuleDescriptor({
description: `My pretty cool rule`,
package: {
name: 'my-package-with-validator-plugin',
version: '7.7.7',
},
});
api.getRuleDescriptor(): RuleDescriptor | null
Get rule meta-data
Reporters API
Reporter is a class with run
method:
interface Reporter {
run(result: Result): Promise<void>;
}
Example:
class MyConsoleReporter {
run(result) {
for (const rule of result.rules) {
const ruleDescriptor = rule.api.getRuleDescriptor();
console.log(`Rule name: ${rule.name}`);
console.log(`Rule description: ${ruleDescriptor.description}`);
const items = rule.api.getStorage();
for (const item of items) {
console.log(item.message);
for (const detail of item.details) {
if (detail.type === 'tty') {
console.log(detail.content);
}
}
}
}
}
}
Custom Plugin Example
Create custom plugin script:
my-custom-stats-validator-plugin.js:
module.exports = () => {
return {
rules: {
'my-rule': (ruleParams, data, api) => {
const result = data.query('some jora query', data.files, {ruleParams});
if(result.notOk) {
api.message(':(')
}
}
}
}
}
Add this plugin to statoscope config:
statoscope.config.js:
module.exports = {
validate: {
plugins: ['@statoscope/webpack', ['./my-custom-stats-validator-plugin.js', 'my-plugin']],
rules: {
'@statoscope/webpack/restricted-packages': ['error', ['foo']],
'my-plugin/my-rule': ['error', 'rule params'],
},
}
}
For more rule examples, please see existing rule sources