license import * as Lint from "tslint" ; import { isJsxOpeningElement , isJsxSelfClosingElement } from "tsutils/typeguard/3.0" ; import * as ts from "typescript" ; interface IOption { pattern : RegExp ; message ? : string ; } export class Rule extends Lint . Rules . AbstractRule { public static metadata : Lint . IRuleMetadata = { ruleName : "jsx-ban-elements" , description : Lint . Utils . dedent `
            Bans specific JSX elements from being used.` , options : { type : "list" , listType : { type : "array" , items : { type : "string" } , minLength : 1 , maxLength : 2 , } , } , optionsDescription : Lint . Utils . dedent `
            A list of \`["regex", "optional explanation here"]\`, which bans
            types that match \`regex\`` , optionExamples : [ [ true , [ "Object" , "Use {} instead." ] , [ "String" ] ] ] , type : "typescript" , typescriptOnly : false , } ; public static FAILURE_STRING_FACTORY ( elementName , messageAddition ? ) { return `JSX element '${ elementName }' is banned.${ messageAddition !== undefined ? ` ${ messageAddition }` : "" }` ; } public apply ( sourceFile ) { return this . applyWithFunction ( sourceFile , walk , this . ruleArguments . map ( parseOption ) ) ; } } function parseOption ( [ pattern , message ] ) { return { message , pattern : new RegExp ( `${ pattern }` ) } ; } function walk ( ctx ) { return ts . forEachChild ( ctx . sourceFile , function cb ( node ) : void { if ( isJsxOpeningElement ( node ) || isJsxSelfClosingElement ( node ) ) { const typeName = node . tagName . getText ( ) ; for ( const ban of ctx . options ) { if ( ban . pattern . test ( typeName ) ) { ctx . addFailureAtNode ( node . tagName , Rule . FAILURE_STRING_FACTORY ( typeName , ban . message ) ) ; break ; } } } return ts . forEachChild ( node , cb ) ; } ) ; }