lint: consolidate ajv-related code, visitor trait interfaces
This commit is contained in:
parent
9183ef3307
commit
de5dd2833a
|
@ -244,7 +244,7 @@ An example rule module [is available here](https://github.com/ssube/salty-dog-oo
|
|||
## From Path
|
||||
|
||||
Rules may be loaded from a directory. Files with `.json` and `.yaml`/`.yml` extensions will be loaded,
|
||||
with filenames lowercased before checking.
|
||||
with file names converted to lowercase before being checked.
|
||||
|
||||
To load a directory: `--rule-path rules/`
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
import { ValidateFunction } from 'ajv';
|
||||
import { ErrorObject, ValidateFunction } from 'ajv';
|
||||
import { cloneDeep, defaultTo, isNil } from 'lodash';
|
||||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { Rule, RuleData } from '.';
|
||||
import { hasItems } from '../utils';
|
||||
import { friendlyError } from '../utils/ajv';
|
||||
import { Visitor } from '../visitor';
|
||||
import { Visitor, VisitorError, VisitorResult } from '../visitor';
|
||||
import { VisitorContext } from '../visitor/VisitorContext';
|
||||
import { VisitorError } from '../visitor/VisitorError';
|
||||
import { VisitorResult } from '../visitor/VisitorResult';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/strict-boolean-expressions */
|
||||
|
||||
|
@ -76,3 +73,22 @@ export class SchemaRule implements Rule, RuleData, Visitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function friendlyError(ctx: VisitorContext, err: ErrorObject, rule: SchemaRule): VisitorError {
|
||||
return {
|
||||
data: {
|
||||
err,
|
||||
rule,
|
||||
},
|
||||
level: 'error',
|
||||
msg: friendlyErrorMessage(err, rule),
|
||||
};
|
||||
}
|
||||
|
||||
export function friendlyErrorMessage(err: ErrorObject, rule: SchemaRule): string {
|
||||
if (isNil(err.message)) {
|
||||
return `${err.dataPath} ${err.keyword} at ${rule.select} for ${rule.name}`;
|
||||
} else {
|
||||
return `${err.dataPath} ${err.message} at ${rule.select} for ${rule.name}`;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,8 +7,8 @@ import { join } from 'path';
|
|||
import { YamlParser } from '../parser/YamlParser';
|
||||
import { readDir, readFile } from '../source';
|
||||
import { ensureArray, hasItems } from '../utils';
|
||||
import { VisitorResult } from '../visitor';
|
||||
import { VisitorContext } from '../visitor/VisitorContext';
|
||||
import { VisitorResult } from '../visitor/VisitorResult';
|
||||
import { SchemaRule } from './SchemaRule';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
import { ErrorObject } from 'ajv';
|
||||
import { isNil } from 'lodash';
|
||||
|
||||
import { SchemaRule } from '../../rule/SchemaRule';
|
||||
import { VisitorContext } from '../../visitor/VisitorContext';
|
||||
import { VisitorError } from '../../visitor/VisitorError';
|
||||
|
||||
export function friendlyError(ctx: VisitorContext, err: ErrorObject, rule: SchemaRule): VisitorError {
|
||||
return {
|
||||
data: {
|
||||
err,
|
||||
rule,
|
||||
},
|
||||
level: 'error',
|
||||
msg: friendlyErrorMessage(err, rule),
|
||||
};
|
||||
}
|
||||
|
||||
export function friendlyErrorMessage(err: ErrorObject, rule: SchemaRule): string {
|
||||
if (isNil(err.message)) {
|
||||
return `${err.dataPath} ${err.keyword} at ${rule.select} for ${rule.name}`;
|
||||
} else {
|
||||
return `${err.dataPath} ${err.message} at ${rule.select} for ${rule.name}`;
|
||||
}
|
||||
}
|
|
@ -2,9 +2,8 @@ import Ajv from 'ajv';
|
|||
import { JSONPath } from 'jsonpath-plus';
|
||||
import { Logger } from 'noicejs';
|
||||
|
||||
import { VisitorError, VisitorResult } from '.';
|
||||
import { doesExist, hasItems } from '../utils';
|
||||
import { VisitorError } from './VisitorError';
|
||||
import { VisitorResult } from './VisitorResult';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import { LogLevel } from 'noicejs';
|
||||
|
||||
/**
|
||||
* This is an runtime error, not an exception.
|
||||
*/
|
||||
export interface VisitorError {
|
||||
data: any;
|
||||
level: LogLevel;
|
||||
msg: string;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
export interface VisitorResult {
|
||||
changes: ReadonlyArray<any>;
|
||||
errors: ReadonlyArray<any>;
|
||||
}
|
|
@ -1,5 +1,20 @@
|
|||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { VisitorContext } from './VisitorContext';
|
||||
import { VisitorResult } from './VisitorResult';
|
||||
|
||||
/**
|
||||
* This is a runtime error, not an exception.
|
||||
*/
|
||||
export interface VisitorError {
|
||||
data: any;
|
||||
level: LogLevel;
|
||||
msg: string;
|
||||
}
|
||||
|
||||
export interface VisitorResult {
|
||||
changes: ReadonlyArray<any>;
|
||||
errors: ReadonlyArray<any>;
|
||||
}
|
||||
|
||||
export interface Visitor<TResult extends VisitorResult = VisitorResult> {
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,7 @@ import { expect } from 'chai';
|
|||
import { NullLogger } from 'noicejs';
|
||||
import { stub } from 'sinon';
|
||||
|
||||
import { SchemaRule } from '../../src/rule/SchemaRule';
|
||||
import { friendlyError, SchemaRule } from '../../src/rule/SchemaRule';
|
||||
import { VisitorContext } from '../../src/visitor/VisitorContext';
|
||||
import { describeLeaks, itLeaks } from '../helpers/async';
|
||||
|
||||
|
@ -157,3 +157,29 @@ describeLeaks('schema rule', async () => {
|
|||
expect(checkSpy, 'check spy should not have been called').to.have.callCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('friendly errors', () => {
|
||||
it('should have a message', () => {
|
||||
const err = friendlyError(new VisitorContext({
|
||||
innerOptions: {
|
||||
coerce: false,
|
||||
defaults: false,
|
||||
mutate: false,
|
||||
},
|
||||
logger: NullLogger.global,
|
||||
}), {
|
||||
dataPath: 'test-path',
|
||||
keyword: TEST_NAME,
|
||||
params: { /* ? */ },
|
||||
schemaPath: 'test-path',
|
||||
}, new SchemaRule({
|
||||
check: {},
|
||||
desc: TEST_NAME,
|
||||
level: 'info',
|
||||
name: TEST_NAME,
|
||||
select: '',
|
||||
tags: [TEST_NAME],
|
||||
}));
|
||||
expect(err.msg).to.not.equal('');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,34 +0,0 @@
|
|||
import { expect } from 'chai';
|
||||
import { NullLogger } from 'noicejs';
|
||||
|
||||
import { SchemaRule } from '../../../src/rule/SchemaRule';
|
||||
import { friendlyError } from '../../../src/utils/ajv';
|
||||
import { VisitorContext } from '../../../src/visitor/VisitorContext';
|
||||
|
||||
const TEST_NAME = 'test';
|
||||
|
||||
describe('friendly errors', () => {
|
||||
it('should have a message', () => {
|
||||
const err = friendlyError(new VisitorContext({
|
||||
innerOptions: {
|
||||
coerce: false,
|
||||
defaults: false,
|
||||
mutate: false,
|
||||
},
|
||||
logger: NullLogger.global,
|
||||
}), {
|
||||
dataPath: 'test-path',
|
||||
keyword: TEST_NAME,
|
||||
params: { /* ? */ },
|
||||
schemaPath: 'test-path',
|
||||
}, new SchemaRule({
|
||||
check: {},
|
||||
desc: TEST_NAME,
|
||||
level: 'info',
|
||||
name: TEST_NAME,
|
||||
select: '',
|
||||
tags: [TEST_NAME],
|
||||
}));
|
||||
expect(err.msg).to.not.equal('');
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue