Skip to content

Instantly share code, notes, and snippets.

@rokerkony
Last active January 22, 2018 13:42
Show Gist options
  • Save rokerkony/7aaf3cdadb77ea0bdde25dc1a127a609 to your computer and use it in GitHub Desktop.
Save rokerkony/7aaf3cdadb77ea0bdde25dc1a127a609 to your computer and use it in GitHub Desktop.
import {ImportDeclaration, SourceFile} from 'typescript';
import {IRuleMetadata, Replacement, RuleFailure, Rules, RuleWalker} from 'tslint';
const disallowedImports: string[] = [
// lettable import
'\'rxjs/operators\'',
'"rxjs/operators"',
// not-lettable import
'rxjs/add/operator',
];
export class Rule extends Rules.AbstractRule {
public apply (sourceFile: SourceFile): RuleFailure[] {
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
}
}
class Walker extends RuleWalker {
public visitImportDeclaration (importDeclaration: ImportDeclaration): void {
const importDeclarationText: string = importDeclaration.getText();
if (this.hasDisallowedImport(importDeclarationText)) {
this.addFailureAt(
importDeclaration.getStart(),
importDeclaration.getWidth(),
'RxJS operators should be imported from their own scope.',
this.getFix(importDeclaration),
);
}
}
private hasDisallowedImport (importDeclarationText: string): boolean {
return disallowedImports.some((i: string): boolean => importDeclarationText.indexOf(i) !== -1);
}
private getFix (importDeclaration: ImportDeclaration): Replacement {
const fix: string = this.getRxJsOperators(importDeclaration)
.reduce((prev: string[], curr: string): string[] => prev.concat([this.getRxJsOperatorImport(curr)]), [])
.join('\n');
return new Replacement(importDeclaration.getStart(), importDeclaration.getWidth(), fix);
}
private getRxJsOperators (importDeclaration: ImportDeclaration): string[] {
if (!importDeclaration.importClause) {
const operator: RegExpExecArray | null = /rxjs\/add\/operator\/(.*)['|"]+/.exec(importDeclaration.getText());
return operator && operator[1] ? [operator[1]] : [];
}
return importDeclaration
.importClause
.getText()
.replace(/[\s{}]*/g, '')
.split(',')
.filter((operator: string): boolean => operator.length > 0)
.sort();
}
private getRxJsOperatorImport (operator: string): string {
return `import {${operator}} from 'rxjs/operators/${operator}';`;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment