fix: usage of __dirname, lint rules and corresponding fixes
This commit is contained in:
parent
052ca736d2
commit
3b7e48a494
|
@ -15,8 +15,7 @@
|
|||
"eslint-plugin-mocha",
|
||||
"eslint-plugin-no-null",
|
||||
"eslint-plugin-sonarjs",
|
||||
"@typescript-eslint",
|
||||
"@typescript-eslint/tslint"
|
||||
"@typescript-eslint"
|
||||
],
|
||||
"rules": {
|
||||
"@typescript-eslint/adjacent-overload-signatures": "error",
|
||||
|
@ -291,72 +290,6 @@
|
|||
"sonarjs/no-redundant-jump": "error",
|
||||
"sonarjs/no-same-line-conditional": "error",
|
||||
"sonarjs/no-useless-catch": "error",
|
||||
"sonarjs/prefer-immediate-return": "error",
|
||||
"@typescript-eslint/tslint/config": [
|
||||
"error",
|
||||
{
|
||||
"rules": {
|
||||
"ban": [
|
||||
true,
|
||||
{
|
||||
"message": "use lodash isString",
|
||||
"name": [
|
||||
"util",
|
||||
"isString"
|
||||
]
|
||||
},
|
||||
{
|
||||
"message": "use lodash isNil",
|
||||
"name": [
|
||||
"util",
|
||||
"isNullOrUndefined"
|
||||
]
|
||||
}
|
||||
],
|
||||
"import-spacing": true,
|
||||
"jsdoc-format": [
|
||||
true,
|
||||
"check-multiline-start"
|
||||
],
|
||||
"no-dynamic-delete": true,
|
||||
"no-inferred-empty-object-type": true,
|
||||
"no-reference-import": true,
|
||||
"object-literal-sort-keys": true,
|
||||
"one-line": [
|
||||
true,
|
||||
"check-catch",
|
||||
"check-else",
|
||||
"check-finally",
|
||||
"check-open-brace",
|
||||
"check-whitespace"
|
||||
],
|
||||
"prefer-switch": true,
|
||||
"strict-type-predicates": true,
|
||||
"trailing-comma": [
|
||||
true,
|
||||
{
|
||||
"esSpecCompliant": true,
|
||||
"multiline": {
|
||||
"arrays": "always",
|
||||
"functions": "never",
|
||||
"object": "always"
|
||||
},
|
||||
"singleline": "never"
|
||||
}
|
||||
],
|
||||
"whitespace": [
|
||||
true,
|
||||
"check-branch",
|
||||
"check-decl",
|
||||
"check-operator",
|
||||
"check-separator",
|
||||
"check-type",
|
||||
"check-typecast",
|
||||
"check-type-operator",
|
||||
"check-rest-spread"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
"sonarjs/prefer-immediate-return": "error"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"es2017",
|
||||
"esnext.asynciterable"
|
||||
],
|
||||
"module": "es6",
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { createLogger } from 'bunyan';
|
||||
import yargs from 'yargs';
|
||||
const { showCompletionScript } = yargs;
|
||||
|
||||
import { loadConfig } from './config/index.js';
|
||||
import { CONFIG_ARGS_NAME, CONFIG_ARGS_PATH, MODE, parseArgs } from './config/args.js';
|
||||
|
@ -19,7 +18,7 @@ export const STATUS_MAX = 255;
|
|||
export async function main(argv: Array<string>): Promise<number> {
|
||||
const { args, mode } = await parseArgs(argv.slice(ARGS_START));
|
||||
if (mode === MODE.complete) {
|
||||
showCompletionScript();
|
||||
yargs(argv).showCompletionScript();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import yargs, { Options } from 'yargs';
|
||||
const { usage } = yargs;
|
||||
|
||||
import { RuleSelector, RuleSources } from '../rule/index.js';
|
||||
import { VERSION_INFO } from '../version.js';
|
||||
|
@ -11,8 +10,6 @@ export enum MODE {
|
|||
list = 'list',
|
||||
}
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
export const CONFIG_ARGS_NAME = 'config-name';
|
||||
export const CONFIG_ARGS_PATH = 'config-path';
|
||||
|
||||
|
@ -23,6 +20,7 @@ const RULE_OPTION: Options = {
|
|||
};
|
||||
|
||||
export interface Args {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
args: any;
|
||||
mode: string;
|
||||
}
|
||||
|
@ -50,15 +48,16 @@ export interface ParseResults {
|
|||
export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
||||
let mode: MODE = MODE.check;
|
||||
|
||||
const parser = usage('Usage: salty-dog <mode> [options]')
|
||||
const parser = yargs(argv).usage('Usage: salty-dog <mode> [options]')
|
||||
.command({
|
||||
command: ['check', '*'],
|
||||
describe: 'validate the source documents',
|
||||
handler: (argi: any) => {
|
||||
handler: (argi: unknown) => {
|
||||
mode = MODE.check;
|
||||
},
|
||||
})
|
||||
.command({
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
builder: (cmd: any) => cmd.options({
|
||||
coerce: {
|
||||
default: false,
|
||||
|
@ -75,21 +74,21 @@ export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
|||
}),
|
||||
command: ['fix'],
|
||||
describe: 'validate the source document and insert defaults',
|
||||
handler: (argi: any) => {
|
||||
handler: (argi: unknown) => {
|
||||
mode = MODE.fix;
|
||||
},
|
||||
})
|
||||
.command({
|
||||
command: ['list'],
|
||||
describe: 'list active rules',
|
||||
handler: (argi: any) => {
|
||||
handler: (argi: unknown) => {
|
||||
mode = MODE.list;
|
||||
},
|
||||
})
|
||||
.command({
|
||||
command: ['complete'],
|
||||
describe: 'generate tab completion script for bash or zsh',
|
||||
handler: (argi: any) => {
|
||||
handler: (argi: unknown) => {
|
||||
mode = MODE.complete;
|
||||
},
|
||||
})
|
||||
|
@ -165,6 +164,7 @@ export async function parseArgs(argv: Array<string>): Promise<ParseResults> {
|
|||
.alias('version', 'v');
|
||||
|
||||
// @TODO: this should not need a cast but the parser's type omits command options and doesn't expose camelCase
|
||||
/* eslint-disable-next-line @typescript-eslint/no-explicit-any */
|
||||
const args = parser.parse(argv) as any;
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { doesExist, NotFoundError } from '@apextoaster/js-utils';
|
||||
import { Stream } from 'bunyan';
|
||||
import { LogLevel } from 'noicejs';
|
||||
import { join } from 'path';
|
||||
import { dirname, join } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
import { YamlParser } from '../parser/YamlParser.js';
|
||||
import { readSource } from '../source.js';
|
||||
|
@ -18,6 +19,10 @@ export interface ConfigData {
|
|||
};
|
||||
}
|
||||
|
||||
export function dirName(): string {
|
||||
return dirname(fileURLToPath(import.meta.url));
|
||||
}
|
||||
|
||||
/**
|
||||
* With the given name, generate all potential config paths in their complete, absolute form.
|
||||
*
|
||||
|
@ -37,8 +42,9 @@ export function completePaths(name: string, extras: Array<string>): Array<string
|
|||
paths.push(join(home, name));
|
||||
}
|
||||
|
||||
if (__dirname !== '') {
|
||||
paths.push(join(__dirname, name));
|
||||
const cwd = dirName();
|
||||
if (cwd !== '') {
|
||||
paths.push(join(cwd, name));
|
||||
}
|
||||
|
||||
for (const e of extras) {
|
||||
|
@ -56,7 +62,9 @@ export async function loadConfig(name: string, ...extras: Array<string>): Promis
|
|||
if (doesExist(data)) {
|
||||
const parser = new YamlParser();
|
||||
const [head] = parser.parse(data);
|
||||
return head;
|
||||
|
||||
/* eslint-disable-next-line sonarjs/prefer-immediate-return */
|
||||
return head as any; // TODO: validate config
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { VERSION_INFO } from './version.js';
|
||||
|
||||
export default {
|
||||
export {
|
||||
VERSION_INFO,
|
||||
};
|
||||
|
|
|
@ -26,8 +26,8 @@ export class YamlParser implements Parser {
|
|||
include.setSchema(this.schema);
|
||||
}
|
||||
|
||||
public dump(...data: Array<any>): string {
|
||||
const docs: Array<any> = [];
|
||||
public dump(...data: Array<unknown>): string {
|
||||
const docs: Array<unknown> = [];
|
||||
for (const doc of data) {
|
||||
const part = dump(doc, {
|
||||
schema: this.schema,
|
||||
|
@ -37,9 +37,9 @@ export class YamlParser implements Parser {
|
|||
return docs.join('\n---\n\n');
|
||||
}
|
||||
|
||||
public parse(body: string): Array<any> {
|
||||
const docs: Array<any> = [];
|
||||
loadAll(body, (doc: any) => docs.push(doc), {
|
||||
public parse(body: string): Array<unknown> {
|
||||
const docs: Array<unknown> = [];
|
||||
loadAll(body, (doc: unknown) => docs.push(doc), {
|
||||
schema: this.schema,
|
||||
});
|
||||
return docs;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export interface Parser {
|
||||
dump(...data: Array<any>): string;
|
||||
parse(body: string): Array<any>;
|
||||
dump(...data: Array<unknown>): string;
|
||||
parse(body: string): Array<unknown>;
|
||||
}
|
|
@ -1,12 +1,12 @@
|
|||
import { doesExist, hasItems } from '@apextoaster/js-utils';
|
||||
import { ErrorObject, ValidateFunction } from 'ajv';
|
||||
import lodash from 'lodash';
|
||||
import { LogLevel } from 'noicejs';
|
||||
|
||||
import { Rule, RuleData } from './index.js';
|
||||
import { Visitor, VisitorError, VisitorResult } from '../visitor/index.js';
|
||||
import { VisitorContext } from '../visitor/VisitorContext.js';
|
||||
import { Rule, RuleData } from './index.js';
|
||||
|
||||
import lodash from 'lodash';
|
||||
const { cloneDeep, defaultTo } = lodash;
|
||||
|
||||
|
||||
|
|
|
@ -162,13 +162,23 @@ export async function loadRulePaths(paths: Array<string>, ctx: VisitorContext):
|
|||
return rules;
|
||||
}
|
||||
|
||||
export async function loadRuleModules(modules: Array<string>, ctx: VisitorContext, r = require): Promise<Array<Rule>> {
|
||||
type LoadBack = (path: string) => Promise<unknown>;
|
||||
|
||||
export async function loadRuleModules(modules: Array<string>, ctx: VisitorContext, load?: LoadBack): Promise<Array<Rule>> {
|
||||
const rules = [];
|
||||
|
||||
function loadModule(path: string) {
|
||||
if (doesExist(load)) {
|
||||
return load(path);
|
||||
} else {
|
||||
return import(path);
|
||||
}
|
||||
}
|
||||
|
||||
for (const name of modules) {
|
||||
try {
|
||||
/* eslint-disable-next-line @typescript-eslint/no-var-requires */
|
||||
const data: RuleSourceModule = r(name);
|
||||
const data: RuleSourceModule = await loadModule(name);
|
||||
if (!validateRules(ctx, data)) {
|
||||
ctx.logger.error({
|
||||
module: name,
|
||||
|
@ -218,7 +228,7 @@ export async function resolveRules(rules: Array<Rule>, selector: RuleSelector):
|
|||
}
|
||||
|
||||
export function validateRules(ctx: VisitorContext, root: any): boolean {
|
||||
const { definitions, name } = {} as any; // ruleSchemaData as any; // TODO: fix this
|
||||
const { definitions, name } = { definitions: { config: {} } } as any; // ruleSchemaData as any;
|
||||
|
||||
const validCtx = new VisitorContext(ctx);
|
||||
validCtx.addSchema(name, definitions);
|
||||
|
@ -233,7 +243,7 @@ export function validateRules(ctx: VisitorContext, root: any): boolean {
|
|||
}
|
||||
|
||||
export function validateConfig(ctx: VisitorContext, root: any): boolean {
|
||||
const { definitions, name } = {} as any; // ruleSchemaData as any;
|
||||
const { definitions, name } = { definitions: { config: {} } } as any; // ruleSchemaData as any;
|
||||
|
||||
const validCtx = new VisitorContext(ctx);
|
||||
validCtx.addSchema(name, definitions);
|
||||
|
|
|
@ -3,6 +3,8 @@ import { LogLevel } from 'noicejs';
|
|||
|
||||
import { VisitorContext } from './VisitorContext.js';
|
||||
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
|
||||
/**
|
||||
* This is a runtime error, not an exception.
|
||||
*/
|
||||
|
@ -20,7 +22,7 @@ export interface VisitorResult {
|
|||
export interface Visitor<TResult extends VisitorResult = VisitorResult> {
|
||||
/**
|
||||
* Select nodes eligible to be visited.
|
||||
**/
|
||||
*/
|
||||
pick(ctx: VisitorContext, root: any): Promise<Array<any>>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,7 +2,9 @@ import { NotFoundError } from '@apextoaster/js-utils';
|
|||
import { expect } from 'chai';
|
||||
import { join } from 'path';
|
||||
|
||||
import { loadConfig, readConfig } from '../../src/config/index.js';
|
||||
import { dirName, loadConfig, readConfig } from '../../src/config/index.js';
|
||||
|
||||
const __dirname = dirName();
|
||||
|
||||
describe('load config helper', async () => {
|
||||
it('should load an existing config', async () =>
|
||||
|
|
|
@ -3,11 +3,14 @@ import { vol } from 'memfs';
|
|||
import { LogLevel, NullLogger } from 'noicejs';
|
||||
import { spy, stub } from 'sinon';
|
||||
|
||||
import { dirName } from '../../src/config/index.js';
|
||||
import { loadRuleFiles, loadRuleModules, loadRulePaths, loadRuleSource } from '../../src/rule/index.js';
|
||||
import { SchemaRule } from '../../src/rule/SchemaRule.js';
|
||||
import { Filesystem, setFs } from '../../src/source.js';
|
||||
import { VisitorContext } from '../../src/visitor/VisitorContext.js';
|
||||
|
||||
const __dirname = dirName();
|
||||
|
||||
const EXAMPLE_EMPTY = '{name: foo, definitions: {}, rules: []}';
|
||||
const EXAMPLE_RULES = `{
|
||||
name: foo,
|
||||
|
|
|
@ -467,9 +467,9 @@
|
|||
source-map "^0.6.0"
|
||||
|
||||
"@types/yargs-parser@*":
|
||||
version "13.1.0"
|
||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228"
|
||||
integrity sha512-gCubfBUZ6KxzoibJ+SCUc/57Ms1jz5NjHe4+dI2krNmU5zCPAphyLJYyTOg06ueIyfj+SaCUqmzun7ImlxDcKg==
|
||||
version "20.2.1"
|
||||
resolved "https://artifacts.apextoaster.com/repository/group-npm/@types/yargs-parser/-/yargs-parser-20.2.1.tgz#3b9ce2489919d9e4fea439b76916abc34b2df129"
|
||||
integrity sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw==
|
||||
|
||||
"@types/yargs@17.0.8":
|
||||
version "17.0.8"
|
||||
|
|
Loading…
Reference in New Issue