UNPKG

antler

Version:
105 lines (89 loc) 2.88 kB
import { Rule } from './rule'; import { Level, Node, RuleConfig } from './types'; const REGEX_FLAGS = ''; const VALID_KEYS = ['allow', 'disallow']; export abstract class RegexRule extends Rule { protected allow?: RegExp | ReadonlyArray<RegExp>; protected disallow?: RegExp | ReadonlyArray<RegExp>; public constructor(config: Level | RuleConfig) { super(config); if (this.options) { if (!('allow' in this.options || 'disallow' in this.options)) { this.error( `Invalid option keys - must include one of ${VALID_KEYS.join(', ')}` ); } for (const key in this.options) { if (VALID_KEYS.indexOf(key) < 0) { this.error(`Invalid key in options - ${key}`); } else if ( !( typeof this.options[key] === 'string' || Array.isArray(this.options[key]) ) ) { this.error(`Type of key ${key} must be a string or array of strings`); } } const { allow, disallow } = this.options; if (typeof allow === 'string') { this.allow = new RegExp(allow, REGEX_FLAGS); } else if (Array.isArray(allow)) { this.allow = allow.map((pattern) => new RegExp(pattern, REGEX_FLAGS)); } if (typeof disallow === 'string') { this.disallow = new RegExp(disallow, REGEX_FLAGS); } else if (Array.isArray(disallow)) { this.disallow = disallow.map( (pattern) => new RegExp(pattern, REGEX_FLAGS) ); } } else { this.error('Invalid options - must be an object'); } } public run(node: Node) { if (!this.shouldRun(node)) { return; } const part = this.getPart(node); if (this.allow instanceof RegExp) { if (!this.allow.test(part)) { return this.report( `${node.path} does not match allowed pattern - ${this.allow}` ); } } else if (Array.isArray(this.allow)) { let matchedAllowed = false; for (const allow of this.allow) { if (allow.test(part)) { matchedAllowed = true; } } if (!matchedAllowed) { return this.report( `${node.path} does not match any allowed patterns - ${this.allow.join( ', ' )}` ); } } if (this.disallow instanceof RegExp) { if (this.disallow.test(part)) { return this.report( `${node.path} matches disallowed pattern - ${this.disallow}` ); } } else if (Array.isArray(this.disallow)) { for (const disallow of this.disallow) { if (disallow.test(part)) { return this.report( `${node.path} matches disallowed pattern - ${disallow}` ); } } } } protected abstract getPart(node: Node): string; protected abstract shouldRun(node: Node): boolean; }