Socket
Socket
Sign inDemoInstall

tslint

Package Overview
Dependencies
Maintainers
1
Versions
182
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tslint - npm Package Compare versions

Comparing version 5.12.1 to 5.13.0

lib/rules/noRestrictedGlobalsRule.d.ts

166

lib/configs/all.d.ts

@@ -23,11 +23,17 @@ /**

"ban-ts-ignore": boolean;
"member-access": (string | boolean)[];
"member-ordering": (boolean | {
order: string;
alphabetize: boolean;
})[];
"member-access": {
options: string[];
};
"member-ordering": {
options: {
order: string;
alphabetize: boolean;
};
};
"no-any": boolean;
"no-empty-interface": boolean;
"no-import-side-effect": boolean;
"no-inferrable-types": (string | boolean)[];
"no-inferrable-types": {
options: string[];
};
"no-internal-module": boolean;

@@ -38,2 +44,3 @@ "no-magic-numbers": boolean;

"no-reference": boolean;
"no-restricted-globals": boolean;
"no-this-assignment": boolean;

@@ -45,10 +52,14 @@ "no-var-requires": boolean;

"promise-function-async": boolean;
typedef: (string | boolean)[];
"typedef-whitespace": (boolean | {
"call-signature": string;
"index-signature": string;
parameter: string;
"property-declaration": string;
"variable-declaration": string;
})[];
typedef: {
options: string[];
};
"typedef-whitespace": {
options: {
"call-signature": string;
"index-signature": string;
parameter: string;
"property-declaration": string;
"variable-declaration": string;
}[];
};
"unified-signatures": boolean;

@@ -69,3 +80,5 @@ "await-promise": boolean;

"no-duplicate-switch-case": boolean;
"no-duplicate-variable": (string | boolean)[];
"no-duplicate-variable": {
options: string[];
};
"no-dynamic-delete": boolean;

@@ -89,3 +102,5 @@ "no-empty": boolean;

"no-unbound-method": boolean;
"no-unnecessary-class": (string | boolean)[];
"no-unnecessary-class": {
options: string[];
};
"no-unsafe-any": boolean;

@@ -109,7 +124,19 @@ "no-unsafe-finally": boolean;

eofline: boolean;
indent: (string | boolean)[];
"linebreak-style": (string | boolean)[];
"max-classes-per-file": (number | boolean)[];
"max-file-line-count": (number | boolean)[];
"max-line-length": (number | boolean)[];
indent: {
options: string[];
};
"linebreak-style": {
options: string;
};
"max-classes-per-file": {
options: number;
};
"max-file-line-count": {
options: number;
};
"max-line-length": {
options: {
limit: number;
};
};
"no-default-export": boolean;

@@ -125,20 +152,34 @@ "no-default-import": boolean;

"prefer-const": boolean;
"trailing-comma": (boolean | {
esSpecCompliant: boolean;
multiline: string;
singleline: string;
})[];
align: (string | boolean)[];
"array-type": (string | boolean)[];
"trailing-comma": {
options: {
esSpecCompliant: boolean;
multiline: string;
singleline: string;
};
};
align: {
options: string[];
};
"array-type": {
options: string;
};
"arrow-parens": boolean;
"arrow-return-shorthand": (string | boolean)[];
"arrow-return-shorthand": {
options: string;
};
"binary-expression-operand-order": boolean;
"callable-types": boolean;
"class-name": boolean;
"comment-format": (string | boolean)[];
"comment-type": (string | boolean)[];
"comment-format": {
options: string[];
};
"comment-type": {
options: string[];
};
"completed-docs": boolean;
deprecation: boolean;
encoding: boolean;
"file-name-casing": (string | boolean)[];
"file-name-casing": {
options: string;
};
"import-spacing": boolean;

@@ -148,3 +189,5 @@ "increment-decrement": boolean;

"interface-over-type-literal": boolean;
"jsdoc-format": (string | boolean)[];
"jsdoc-format": {
options: string;
};
"match-default-export-name": boolean;

@@ -165,11 +208,18 @@ "new-parens": boolean;

"number-literal-format": boolean;
"object-literal-key-quotes": (string | boolean)[];
"object-literal-key-quotes": {
options: string;
};
"object-literal-shorthand": boolean;
"one-line": (string | boolean)[];
"one-line": {
options: string[];
};
"one-variable-per-declaration": boolean;
"ordered-imports": (boolean | {
"import-sources-order": string;
"named-imports-order": string;
"module-source-path": string;
})[];
"ordered-imports": {
options: {
"grouped-imports": boolean;
"import-sources-order": string;
"named-imports-order": string;
"module-source-path": string;
};
};
"prefer-function-over-method": boolean;

@@ -181,18 +231,30 @@ "prefer-method-signature": boolean;

"prefer-while": boolean;
quotemark: (string | boolean)[];
quotemark: {
options: string[];
};
"return-undefined": boolean;
semicolon: (string | boolean)[];
"space-before-function-paren": (boolean | {
anonymous: string;
asyncArrow: string;
constructor: string;
method: string;
named: string;
})[];
"space-within-parens": (number | boolean)[];
semicolon: {
options: string[];
};
"space-before-function-paren": {
options: {
anonymous: string;
asyncArrow: string;
constructor: string;
method: string;
named: string;
};
};
"space-within-parens": {
options: number;
};
"switch-final-break": boolean;
"type-literal-delimiter": boolean;
"unnecessary-bind": boolean;
"variable-name": (string | boolean)[];
whitespace: (string | boolean)[];
"variable-name": {
options: string[];
};
whitespace: {
options: string[];
};
};

@@ -199,0 +261,0 @@ export declare const RULES_EXCLUDED_FROM_ALL_CONFIG: string[];

@@ -41,10 +41,11 @@ "use strict";

"ban-ts-ignore": true,
"member-access": [true, "check-accessor", "check-constructor", "check-parameter-property"],
"member-ordering": [
true,
{
"member-access": {
options: ["check-accessor", "check-constructor", "check-parameter-property"],
},
"member-ordering": {
options: {
order: "statics-first",
alphabetize: true,
},
],
},
"no-any": true,

@@ -54,3 +55,3 @@ "no-empty-interface": true,

// Technically this is not the strictest setting, but don't want to conflict with "typedef"
"no-inferrable-types": [true, "ignore-params"],
"no-inferrable-types": { options: ["ignore-params"] },
"no-internal-module": true,

@@ -61,2 +62,3 @@ "no-magic-numbers": true,

"no-reference": true,
"no-restricted-globals": true,
"no-this-assignment": true,

@@ -68,29 +70,31 @@ "no-var-requires": true,

"promise-function-async": true,
typedef: [
true,
"call-signature",
"arrow-call-signature",
"parameter",
"arrow-parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration",
],
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
parameter: "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace",
},
{
"call-signature": "onespace",
"index-signature": "onespace",
parameter: "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace",
},
],
typedef: {
options: [
"call-signature",
"arrow-call-signature",
"parameter",
"arrow-parameter",
"property-declaration",
"variable-declaration",
"member-variable-declaration",
],
},
"typedef-whitespace": {
options: [
{
"call-signature": "nospace",
"index-signature": "nospace",
parameter: "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace",
},
{
"call-signature": "onespace",
"index-signature": "onespace",
parameter: "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace",
},
],
},
"unified-signatures": true,

@@ -114,3 +118,3 @@ // Functionality

"no-duplicate-switch-case": true,
"no-duplicate-variable": [true, "check-parameters"],
"no-duplicate-variable": { options: ["check-parameters"] },
"no-dynamic-delete": true,

@@ -135,3 +139,3 @@ "no-empty": true,

"no-unbound-method": true,
"no-unnecessary-class": [true, "allow-empty-class"],
"no-unnecessary-class": { options: ["allow-empty-class"] },
"no-unsafe-any": true,

@@ -157,7 +161,9 @@ "no-unsafe-finally": true,

eofline: true,
indent: [true, "spaces"],
"linebreak-style": [true, "LF"],
"max-classes-per-file": [true, 1],
"max-file-line-count": [true, 1000],
"max-line-length": [true, 120],
indent: { options: ["spaces"] },
"linebreak-style": { options: "LF" },
"max-classes-per-file": { options: 1 },
"max-file-line-count": { options: 1000 },
"max-line-length": {
options: { limit: 120 },
},
"no-default-export": true,

@@ -173,5 +179,4 @@ "no-default-import": true,

"prefer-const": true,
"trailing-comma": [
true,
{
"trailing-comma": {
options: {
esSpecCompliant: true,

@@ -181,18 +186,19 @@ multiline: "always",

},
],
},
// Style
align: [true, "parameters", "arguments", "statements", "elements", "members"],
"array-type": [true, "array-simple"],
align: {
options: ["parameters", "arguments", "statements", "elements", "members"],
},
"array-type": { options: "array-simple" },
"arrow-parens": true,
"arrow-return-shorthand": [true, "multiline"],
"arrow-return-shorthand": { options: "multiline" },
"binary-expression-operand-order": true,
"callable-types": true,
"class-name": true,
"comment-format": [true, "check-space", "check-uppercase"],
"comment-type": [true, "singleline", "multiline", "doc", "directive"],
"comment-format": { options: ["check-space", "check-uppercase"] },
"comment-type": { options: ["singleline", "multiline", "doc", "directive"] },
"completed-docs": true,
// "file-header": No sensible default
deprecation: true,
encoding: true,
"file-name-casing": [true, "camel-case"],
"file-name-casing": { options: "camel-case" },
"import-spacing": true,

@@ -202,3 +208,3 @@ "increment-decrement": true,

"interface-over-type-literal": true,
"jsdoc-format": [true, "check-multiline-start"],
"jsdoc-format": { options: "check-multiline-start" },
"match-default-export-name": true,

@@ -219,16 +225,17 @@ "new-parens": true,

"number-literal-format": true,
"object-literal-key-quotes": [true, "consistent-as-needed"],
"object-literal-key-quotes": { options: "consistent-as-needed" },
"object-literal-shorthand": true,
"one-line": [
true,
"check-catch",
"check-else",
"check-finally",
"check-open-brace",
"check-whitespace",
],
"one-line": {
options: [
"check-catch",
"check-else",
"check-finally",
"check-open-brace",
"check-whitespace",
],
},
"one-variable-per-declaration": true,
"ordered-imports": [
true,
{
"ordered-imports": {
options: {
"grouped-imports": true,
"import-sources-order": "case-insensitive",

@@ -238,3 +245,3 @@ "named-imports-order": "case-insensitive",

},
],
},
"prefer-function-over-method": true,

@@ -246,8 +253,9 @@ "prefer-method-signature": true,

"prefer-while": true,
quotemark: [true, "double", "avoid-escape", "avoid-template"],
quotemark: {
options: ["double", "avoid-escape", "avoid-template"],
},
"return-undefined": true,
semicolon: [true, "always"],
"space-before-function-paren": [
true,
{
semicolon: { options: ["always"] },
"space-before-function-paren": {
options: {
anonymous: "never",

@@ -259,21 +267,22 @@ asyncArrow: "always",

},
],
"space-within-parens": [true, 0],
},
"space-within-parens": { options: 0 },
"switch-final-break": true,
"type-literal-delimiter": true,
"unnecessary-bind": true,
"variable-name": [true, "ban-keywords", "check-format"],
whitespace: [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type",
"check-typecast",
"check-preblock",
"check-type-operator",
"check-rest-spread",
],
"variable-name": { options: ["ban-keywords", "check-format"] },
whitespace: {
options: [
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type",
"check-typecast",
"check-preblock",
"check-type-operator",
"check-rest-spread",
],
},
};

@@ -280,0 +289,0 @@ exports.RULES_EXCLUDED_FROM_ALL_CONFIG = [

@@ -26,6 +26,10 @@ /**

"prefer-object-spread": boolean;
"no-duplicate-variable": (string | boolean)[];
"no-duplicate-variable": {
options: string;
};
"no-this-assignment": boolean;
"no-duplicate-imports": boolean;
"space-within-parens": (number | boolean)[];
"space-within-parens": {
options: number;
};
"no-submodule-imports": boolean;

@@ -32,0 +36,0 @@ whitespace: {

@@ -34,3 +34,3 @@ "use strict";

// added in v5.4
"no-duplicate-variable": [true, "check-parameters"],
"no-duplicate-variable": { options: "check-parameters" },
// added in v5.5

@@ -40,3 +40,3 @@ "no-this-assignment": true,

"no-duplicate-imports": true,
"space-within-parens": [true, 0],
"space-within-parens": { options: 0 },
"no-submodule-imports": true,

@@ -58,5 +58,3 @@ // added in v5.7

"ban-comma-operator": true,
"jsdoc-format": {
options: "check-multiline-start",
},
"jsdoc-format": { options: "check-multiline-start" },
"no-duplicate-switch-case": true,

@@ -63,0 +61,0 @@ "no-implicit-dependencies": true,

@@ -50,6 +50,6 @@ /**

"max-classes-per-file": {
options: number[];
options: number;
};
"max-line-length": {
options: number[];
options: number;
};

@@ -95,3 +95,3 @@ "member-access": boolean;

"object-literal-key-quotes": {
options: string[];
options: string;
};

@@ -98,0 +98,0 @@ "object-literal-shorthand": boolean;

@@ -61,8 +61,4 @@ "use strict";

"label-position": true,
"max-classes-per-file": {
options: [1],
},
"max-line-length": {
options: [120],
},
"max-classes-per-file": { options: 1 },
"max-line-length": { options: 120 },
"member-access": true,

@@ -103,9 +99,6 @@ "member-ordering": {

"no-unused-expression": true,
// disable this rule as it is very heavy performance-wise and not that useful
"no-use-before-declare": false,
"no-var-keyword": true,
"no-var-requires": true,
"object-literal-key-quotes": {
options: ["consistent-as-needed"],
},
"object-literal-key-quotes": { options: "consistent-as-needed" },
"object-literal-shorthand": true,

@@ -122,5 +115,3 @@ "object-literal-sort-keys": true,

},
"one-variable-per-declaration": {
options: ["ignore-for-loop"],
},
"one-variable-per-declaration": { options: ["ignore-for-loop"] },
"only-arrow-functions": {

@@ -142,5 +133,3 @@ options: ["allow-declarations", "allow-named-functions"],

radix: true,
semicolon: {
options: ["always"],
},
semicolon: { options: ["always"] },
"space-before-function-paren": {

@@ -162,5 +151,3 @@ options: {

},
"triple-equals": {
options: ["allow-null-check"],
},
"triple-equals": { options: ["allow-null-check"] },
typedef: false,

@@ -250,5 +237,3 @@ "typedef-whitespace": {

},
"one-variable-per-declaration": {
options: ["ignore-for-loop"],
},
"one-variable-per-declaration": { options: ["ignore-for-loop"] },
quotemark: {

@@ -258,5 +243,3 @@ options: ["double", "avoid-escape"],

radix: true,
semicolon: {
options: ["always"],
},
semicolon: { options: ["always"] },
"space-before-function-paren": {

@@ -277,5 +260,3 @@ options: {

},
"triple-equals": {
options: ["allow-null-check"],
},
"triple-equals": { options: ["allow-null-check"] },
"use-isnan": true,

@@ -282,0 +263,0 @@ "variable-name": {

@@ -446,8 +446,6 @@ "use strict";

rules.forEach(function (ruleOptions, ruleName) {
if (ruleOptions.ruleSeverity !== "off") {
var Rule = ruleLoader_1.findRule(ruleName, rulesDirectory);
if (Rule !== undefined &&
(Rule.metadata === undefined || !Rule.metadata.typescriptOnly)) {
validJsRules.set(ruleName, ruleOptions);
}
var Rule = ruleLoader_1.findRule(ruleName, rulesDirectory);
if (Rule !== undefined &&
(Rule.metadata === undefined || !Rule.metadata.typescriptOnly)) {
validJsRules.set(ruleName, ruleOptions);
}

@@ -454,0 +452,0 @@ });

@@ -22,4 +22,5 @@ /**

static metadata: IFormatterMetadata;
format(failures: RuleFailure[]): string;
format(failures: RuleFailure[], _fixes: RuleFailure[], fileNames: string[]): string;
private formatFailure;
private escapeXml;
}

@@ -28,35 +28,34 @@ "use strict";

/* tslint:enable:object-literal-sort-keys */
Formatter.prototype.format = function (failures) {
var output = '<?xml version="1.0" encoding="utf-8"?><checkstyle version="4.3">';
if (failures.length !== 0) {
var failuresSorted = failures.sort(function (a, b) {
return a.getFileName().localeCompare(b.getFileName());
});
var previousFilename = null;
for (var _i = 0, failuresSorted_1 = failuresSorted; _i < failuresSorted_1.length; _i++) {
var failure = failuresSorted_1[_i];
var severity = failure.getRuleSeverity();
if (failure.getFileName() !== previousFilename) {
if (previousFilename !== null) {
output += "</file>";
}
previousFilename = failure.getFileName();
output += "<file name=\"" + this.escapeXml(failure.getFileName()) + "\">";
}
output += "<error line=\"" + (failure.getStartPosition().getLineAndCharacter().line +
1) + "\" ";
output += "column=\"" + (failure.getStartPosition().getLineAndCharacter().character +
1) + "\" ";
output += "severity=\"" + severity + "\" ";
output += "message=\"" + this.escapeXml(failure.getFailure()) + "\" ";
// checkstyle parser wants "source" to have structure like <anything>dot<category>dot<type>
output += "source=\"failure.tslint." + this.escapeXml(failure.getRuleName()) + "\" />";
Formatter.prototype.format = function (failures, _fixes, fileNames) {
var _this = this;
var groupedFailures = {};
for (var _i = 0, failures_1 = failures; _i < failures_1.length; _i++) {
var failure = failures_1[_i];
var fileName = failure.getFileName();
if (groupedFailures[fileName] !== undefined) {
groupedFailures[fileName].push(failure);
}
if (previousFilename !== null) {
output += "</file>";
else {
groupedFailures[fileName] = [failure];
}
}
output += "</checkstyle>";
return output;
var formattedFiles = fileNames.map(function (fileName) {
var formattedFailures = groupedFailures[fileName] !== undefined
? groupedFailures[fileName].map(function (f) { return _this.formatFailure(f); })
: [];
var joinedFailures = formattedFailures.join(""); // may be empty
return "<file name=\"" + _this.escapeXml(fileName) + "\">" + joinedFailures + "</file>";
});
var joinedFiles = formattedFiles.join("");
return "<?xml version=\"1.0\" encoding=\"utf-8\"?><checkstyle version=\"4.3\">" + joinedFiles + "</checkstyle>";
};
Formatter.prototype.formatFailure = function (failure) {
var line = failure.getStartPosition().getLineAndCharacter().line + 1;
var column = failure.getStartPosition().getLineAndCharacter().character + 1;
var severity = failure.getRuleSeverity();
var message = this.escapeXml(failure.getFailure());
// checkstyle parser wants "source" to have structure like <anything>dot<category>dot<type>
var source = "failure.tslint." + this.escapeXml(failure.getRuleName());
return "<error line=\"" + line + "\" column=\"" + column + "\" severity=\"" + severity + "\" message=\"" + message + "\" source=\"" + source + "\" />";
};
Formatter.prototype.escapeXml = function (str) {

@@ -74,3 +73,3 @@ return str

description: "Formats errors as though they were Checkstyle output.",
descriptionDetails: Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Imitates the XMLLogger from Checkstyle 4.3. All failures have the 'warning' severity."], ["\n Imitates the XMLLogger from Checkstyle 4.3. All failures have the 'warning' severity."]))),
descriptionDetails: Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Imitates the XMLLogger from Checkstyle 4.3. All failures have the 'warning' severity. Files without errors are still included."], ["\n Imitates the XMLLogger from Checkstyle 4.3. All failures have the 'warning' severity. Files without errors are still included."]))),
sample: Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <checkstyle version=\"4.3\">\n <file name=\"myFile.ts\">\n <error line=\"1\" column=\"14\" severity=\"warning\" message=\"Missing semicolon\" source=\"failure.tslint.semicolon\" />\n </file>\n </checkstyle>"], ["\n <?xml version=\"1.0\" encoding=\"utf-8\"?>\n <checkstyle version=\"4.3\">\n <file name=\"myFile.ts\">\n <error line=\"1\" column=\"14\" severity=\"warning\" message=\"Missing semicolon\" source=\"failure.tslint.semicolon\" />\n </file>\n </checkstyle>"]))),

@@ -77,0 +76,0 @@ consumer: "machine",

@@ -20,5 +20,5 @@ "use strict";

var tslib_1 = require("tslib");
var abstractFormatter_1 = require("../language/formatter/abstractFormatter");
var codeFrame = require("babel-code-frame");
var chalk_1 = require("chalk");
var abstractFormatter_1 = require("../language/formatter/abstractFormatter");
var Utils = require("../utils");

@@ -25,0 +25,0 @@ var Formatter = /** @class */ (function (_super) {

@@ -20,4 +20,4 @@ "use strict";

var tslib_1 = require("tslib");
var chalk_1 = require("chalk");
var abstractFormatter_1 = require("../language/formatter/abstractFormatter");
var chalk_1 = require("chalk");
var Utils = require("../utils");

@@ -24,0 +24,0 @@ var Formatter = /** @class */ (function (_super) {

@@ -21,4 +21,4 @@ /**

static metadata: IFormatterMetadata;
abstract format(failures: RuleFailure[]): string;
abstract format(failures: RuleFailure[], fixes: RuleFailure[], fileNames: string[]): string;
protected sortFailures(failures: RuleFailure[]): RuleFailure[];
}

@@ -49,4 +49,5 @@ /**

* @param fixes Fixed linter failures. Available when the `--fix` argument is used on the command line
* @param fileNames All of the file paths that were linted
*/
format(failures: RuleFailure[], fixes?: RuleFailure[]): string;
format(failures: RuleFailure[], fixes?: RuleFailure[], fileNames?: string[]): string;
}

@@ -26,5 +26,5 @@ /**

static metadata: IRuleMetadata;
ruleName: string;
protected readonly ruleArguments: any[];
protected readonly ruleSeverity: RuleSeverity;
ruleName: string;
constructor(options: IOptions);

@@ -31,0 +31,0 @@ getOptions(): IOptions;

@@ -81,3 +81,3 @@ /**

}
export declare type RuleType = "functionality" | "maintainability" | "style" | "typescript";
export declare type RuleType = "functionality" | "maintainability" | "style" | "typescript" | "formatting";
export declare type RuleSeverity = "warning" | "error" | "off";

@@ -170,2 +170,3 @@ export interface ICodeExample {

private readonly fix?;
static compare(a: RuleFailure, b: RuleFailure): number;
private readonly fileName;

@@ -176,3 +177,2 @@ private readonly startPosition;

private ruleSeverity;
static compare(a: RuleFailure, b: RuleFailure): number;
constructor(sourceFile: ts.SourceFile, start: number, end: number, failure: string, ruleName: string, fix?: Replacement | Replacement[] | undefined);

@@ -179,0 +179,0 @@ getFileName(): string;

@@ -20,2 +20,8 @@ /**

import { RuleWalker } from "./ruleWalker";
/**
* @deprecated
* RuleWalker-based rules are slow,
* so it's generally preferable to use applyWithFunction instead of applyWithWalker.
* @see https://github.com/palantir/tslint/issues/2522
*/
export declare class ProgramAwareRuleWalker extends RuleWalker {

@@ -22,0 +28,0 @@ private readonly program;

@@ -21,2 +21,9 @@ "use strict";

var ruleWalker_1 = require("./ruleWalker");
/**
* @deprecated
* RuleWalker-based rules are slow,
* so it's generally preferable to use applyWithFunction instead of applyWithWalker.
* @see https://github.com/palantir/tslint/issues/2522
*/
// tslint:disable-next-line deprecation
var ProgramAwareRuleWalker = /** @class */ (function (_super) {

@@ -23,0 +30,0 @@ tslib_1.__extends(ProgramAwareRuleWalker, _super);

@@ -21,2 +21,8 @@ /**

import { IWalker } from "./walker";
/**
* @deprecated
* RuleWalker-based rules are slow,
* so it's generally preferable to use applyWithFunction instead of applyWithWalker.
* @see https://github.com/palantir/tslint/issues/2522
*/
export declare class RuleWalker extends SyntaxWalker implements IWalker {

@@ -23,0 +29,0 @@ private readonly sourceFile;

@@ -22,2 +22,8 @@ "use strict";

var syntaxWalker_1 = require("./syntaxWalker");
/**
* @deprecated
* RuleWalker-based rules are slow,
* so it's generally preferable to use applyWithFunction instead of applyWithWalker.
* @see https://github.com/palantir/tslint/issues/2522
*/
var RuleWalker = /** @class */ (function (_super) {

@@ -24,0 +30,0 @@ tslib_1.__extends(RuleWalker, _super);

@@ -57,2 +57,3 @@ "use strict";

*/
// tslint:disable-next-line deprecation
var ScopeAwareRuleWalker = /** @class */ (function (_super) {

@@ -59,0 +60,0 @@ tslib_1.__extends(ScopeAwareRuleWalker, _super);

@@ -32,4 +32,2 @@ /**

static loadConfigurationFromPath: typeof loadConfigurationFromPath;
private failures;
private fixes;
/**

@@ -45,2 +43,5 @@ * Creates a TypeScript program object from a tsconfig.json file path and optional project directory.

static getFileNames(program: ts.Program): string[];
private failures;
private fixes;
private readonly fileNames;
constructor(options: ILinterOptions, program?: ts.Program | undefined);

@@ -47,0 +48,0 @@ lint(fileName: string, source: string, configuration?: IConfigurationFile): void;

@@ -40,2 +40,3 @@ "use strict";

this.fixes = [];
this.fileNames = [];
if (typeof options !== "object") {

@@ -103,5 +104,9 @@ throw new Error("Unknown Linter options type: " + typeof options);

}
this.fileNames.push(fileName);
var sourceFile = this.getSourceFile(fileName, source);
var isJs = /\.jsx?$/i.test(fileName);
var enabledRules = this.getEnabledRules(configuration, isJs);
if (enabledRules.length === 0) {
error_1.showWarningOnce("Tried to lint " + fileName + " but found no valid, enabled rules for this file type and file path in the resolved configuration.");
}
var fileFailures = this.getAllFailures(sourceFile, enabledRules);

@@ -139,3 +144,3 @@ if (fileFailures.length === 0) {

var formatter = new Formatter();
var output = formatter.format(failures, this.fixes);
var output = formatter.format(failures, this.fixes, this.fileNames);
var errorCount = errors.length;

@@ -244,3 +249,3 @@ return {

};
Linter.VERSION = "5.12.1";
Linter.VERSION = "5.13.0";
Linter.findConfiguration = configuration_1.findConfiguration;

@@ -247,0 +252,0 @@ Linter.findConfigurationPath = configuration_1.findConfigurationPath;

@@ -63,6 +63,2 @@ "use strict";

}
if (rules.length === 0) {
var fileType = isJs ? "JavaScript" : "TypeScript";
error_1.showWarningOnce("No valid rules have been specified for " + fileType + " files");
}
return rules;

@@ -69,0 +65,0 @@ }

@@ -65,3 +65,3 @@ "use strict";

optionExamples: [[true, "parameters", "statements"]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -68,0 +68,0 @@ };

@@ -138,2 +138,3 @@ "use strict";

case ts.SyntaxKind.ThisType:
case ts.SyntaxKind.UnknownKeyword:
return true;

@@ -140,0 +141,0 @@ case ts.SyntaxKind.TypeReference:

@@ -46,3 +46,3 @@ "use strict";

optionExamples: [true, [true, BAN_SINGLE_ARG_PARENS]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -49,0 +49,0 @@ };

@@ -78,2 +78,3 @@ "use strict";

{ name: ["*", "forEach"], message: "Use a regular for loop instead." },
{ name: ["*", "_id", "toString"], message: "Use 'toHexString' instead." },
],

@@ -148,3 +149,3 @@ ],

BanFunctionWalker.prototype.checkForObjectMethodBan = function (expression) {
for (var _i = 0, _a = this.options.methods; _i < _a.length; _i++) {
outer: for (var _i = 0, _a = this.options.methods; _i < _a.length; _i++) {
var ban = _a[_i];

@@ -157,3 +158,3 @@ if (expression.name.text !== ban.name) {

if (!tsutils_1.isPropertyAccessExpression(current) || current.name.text !== ban.object[i]) {
continue;
continue outer;
}

@@ -160,0 +161,0 @@ current = current.expression;

@@ -49,3 +49,3 @@ /**

export declare type Visibility = All | typeof VISIBILITY_EXPORTED | typeof VISIBILITY_INTERNAL;
export declare class Rule extends Lint.Rules.TypedRule {
export declare class Rule extends Lint.Rules.AbstractRule {
static FAILURE_STRING_EXIST: string;

@@ -109,4 +109,4 @@ static defaultArguments: IInputExclusionDescriptors;

private readonly exclusionFactory;
applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[];
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
private getExclusionsMap;
}

@@ -21,2 +21,3 @@ "use strict";

var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
var tsutils = require("tsutils");
var ts = require("typescript");

@@ -57,6 +58,6 @@ var Lint = require("../index");

}
Rule.prototype.applyWithProgram = function (sourceFile, program) {
Rule.prototype.apply = function (sourceFile) {
var options = this.getOptions();
var exclusionsMap = this.getExclusionsMap(options.ruleArguments);
return this.applyWithFunction(sourceFile, walk, exclusionsMap, program.getTypeChecker());
return this.applyWithFunction(sourceFile, walk, exclusionsMap);
};

@@ -213,6 +214,5 @@ Rule.prototype.getExclusionsMap = function (ruleArguments) {

typescriptOnly: false,
requiresTypeInfo: true,
};
return Rule;
}(Lint.Rules.TypedRule));
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;

@@ -222,3 +222,3 @@ var modifierAliases = {

};
function walk(context, typeChecker) {
function walk(context) {
return ts.forEachChild(context.sourceFile, cb);

@@ -281,3 +281,3 @@ function cb(node) {

if (node.parent.kind !== ts.SyntaxKind.ObjectLiteralExpression) {
checkNode(node, exports.ARGUMENT_PROPERTIES);
checkAccessorNode(node);
}

@@ -289,9 +289,23 @@ }

if (requirementNode === void 0) { requirementNode = node; }
if (!nodeIsExcluded(node, nodeType, requirementNode) && !nodeHasDocs(node)) {
addDocumentationFailure(node, describeNode(nodeType), requirementNode);
}
}
function checkAccessorNode(node) {
if (nodeIsExcluded(node, exports.ARGUMENT_PROPERTIES, node) || nodeHasDocs(node)) {
return;
}
var correspondingAccessor = getCorrespondingAccessor(node);
if (correspondingAccessor === undefined || !nodeHasDocs(correspondingAccessor)) {
addDocumentationFailure(node, exports.ARGUMENT_PROPERTIES, node);
}
}
function nodeIsExcluded(node, nodeType, requirementNode) {
var name = node.name;
if (name === undefined) {
return;
return true;
}
var exclusions = context.options.get(nodeType);
if (exclusions === undefined) {
return;
return true;
}

@@ -301,19 +315,16 @@ for (var _i = 0, exclusions_1 = exclusions; _i < exclusions_1.length; _i++) {

if (exclusion.excludes(requirementNode)) {
return;
return true;
}
}
var symbol = typeChecker.getSymbolAtLocation(name);
if (symbol === undefined) {
return;
}
var comments = symbol.getDocumentationComment(typeChecker);
checkComments(node, describeNode(nodeType), comments, requirementNode);
return false;
}
function checkComments(node, nodeDescriptor, comments, requirementNode) {
if (comments
.map(function (comment) { return comment.text; })
.join("")
.trim() === "") {
addDocumentationFailure(node, nodeDescriptor, requirementNode);
function nodeHasDocs(node) {
var docs = getApparentJsDoc(node);
if (docs === undefined) {
return false;
}
var comments = docs
.map(function (doc) { return doc.comment; })
.filter(function (comment) { return comment !== undefined && comment.trim() !== ""; });
return comments.length !== 0;
}

@@ -327,2 +338,42 @@ function addDocumentationFailure(node, nodeType, requirementNode) {

}
function getCorrespondingAccessor(node) {
var propertyName = tsutils.getPropertyName(node.name);
if (propertyName === undefined) {
return undefined;
}
var parent = node.parent;
var correspondingKindCheck = node.kind === ts.SyntaxKind.GetAccessor ? isSetAccessor : isGetAccessor;
for (var _i = 0, _a = parent.members; _i < _a.length; _i++) {
var member = _a[_i];
if (!correspondingKindCheck(member)) {
continue;
}
if (tsutils.getPropertyName(member.name) === propertyName) {
return member;
}
}
return undefined;
}
/**
* @remarks See https://github.com/ajafff/tsutils/issues/16
*/
function getApparentJsDoc(node) {
if (ts.isVariableDeclaration(node)) {
if (variableIsAfterFirstInDeclarationList(node)) {
return undefined;
}
node = node.parent;
}
if (ts.isVariableDeclarationList(node)) {
node = node.parent;
}
return tsutils.getJsDoc(node);
}
function variableIsAfterFirstInDeclarationList(node) {
var parent = node.parent;
if (parent === undefined) {
return false;
}
return ts.isVariableDeclarationList(parent) && node !== parent.declarations[0];
}
function describeDocumentationFailure(node, nodeType) {

@@ -345,2 +396,8 @@ var description = Rule.FAILURE_STRING_EXIST;

}
function isGetAccessor(node) {
return node.kind === ts.SyntaxKind.GetAccessor;
}
function isSetAccessor(node) {
return node.kind === ts.SyntaxKind.SetAccessor;
}
var templateObject_1, templateObject_2;

@@ -23,2 +23,3 @@ "use strict";

var Lint = require("../index");
var utils_1 = require("../utils");
var curly_examples_1 = require("./code-examples/curly.examples");

@@ -138,13 +139,6 @@ var OPTION_AS_NEEDED = "as-needed";

else {
var match = /\n([\t ])/.exec(node.getFullText(this.sourceFile)); // determine which character to use (tab or space)
var indentation = match === null
? ""
: // indentation should match start of statement
match[1].repeat(ts.getLineAndCharacterOfPosition(this.sourceFile, node.getStart(this.sourceFile)).character);
var maybeCarriageReturn = this.sourceFile.text[this.sourceFile.getLineEndOfPosition(node.pos) - 1] === "\r"
? "\r"
: "";
var newLine = utils_1.newLineWithIndentation(node, this.sourceFile);
return [
Lint.Replacement.appendText(statement.pos, " {"),
Lint.Replacement.appendText(statement.end, maybeCarriageReturn + "\n" + indentation + "}"),
Lint.Replacement.appendText(statement.end, newLine + "}"),
];

@@ -151,0 +145,0 @@ }

@@ -51,3 +51,3 @@ "use strict";

hasFix: true,
type: "maintainability",
type: "formatting",
typescriptOnly: false,

@@ -54,0 +54,0 @@ };

@@ -23,2 +23,3 @@ /**

static IMPLICIT_NAMED_IMPORT_FAILURE_STRING: string;
static FAILURE_STRING_REGEX: string;
static MAKE_NAMED_IMPORT_FAILURE_STRING(importName: string): string;

@@ -25,0 +26,0 @@ isEnabled(): boolean;

@@ -41,5 +41,5 @@ "use strict";

ruleName: "import-blacklist",
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Disallows importing the specified modules via `import` and `require`,\n or importing specific named exports of the specified modules."], ["\n Disallows importing the specified modules via \\`import\\` and \\`require\\`,\n or importing specific named exports of the specified modules."]))),
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Disallows importing the specified modules via `import` and `require`,\n or importing specific named exports of the specified modules,\n or using imports matching specified regular expression patterns."], ["\n Disallows importing the specified modules via \\`import\\` and \\`require\\`,\n or importing specific named exports of the specified modules,\n or using imports matching specified regular expression patterns."]))),
rationale: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n For some libraries, importing the library directly can cause unused\n submodules to be loaded, so you may want to block these imports and\n require that users directly import only the submodules they need.\n In other cases, you may simply want to ban an import because using\n it is undesirable or unsafe."], ["\n For some libraries, importing the library directly can cause unused\n submodules to be loaded, so you may want to block these imports and\n require that users directly import only the submodules they need.\n In other cases, you may simply want to ban an import because using\n it is undesirable or unsafe."]))),
optionsDescription: "A list of blacklisted modules or named imports.",
optionsDescription: "A list of blacklisted modules, named imports, or regular expression patterns.",
options: {

@@ -64,2 +64,9 @@ type: "array",

},
{
type: "array",
items: {
type: "string",
},
minLength: 1,
},
],

@@ -72,2 +79,3 @@ },

[true, "lodash", { lodash: ["pull", "pullAll"] }],
[true, "rxjs", { lodash: ["pull", "pullAll"] }, [".*\\.temp$", ".*\\.tmp$"]],
],

@@ -81,2 +89,3 @@ type: "functionality",

"instead of the whole module.";
Rule.FAILURE_STRING_REGEX = "This import is blacklisted by ";
return Rule;

@@ -93,3 +102,3 @@ }(Lint.Rules.AbstractRule));

}
else {
else if (!Array.isArray(it)) {
Object.keys(it).forEach(function (moduleName) {

@@ -108,4 +117,14 @@ if (acc[moduleName] instanceof Set) {

}, Object.create(null));
for (var _i = 0, _a = tsutils_1.findImports(ctx.sourceFile, 63 /* All */); _i < _a.length; _i++) {
var name = _a[_i];
var regexOptions = [];
for (var _i = 0, _a = ctx.options; _i < _a.length; _i++) {
var option = _a[_i];
if (Array.isArray(option)) {
for (var _b = 0, option_1 = option; _b < option_1.length; _b++) {
var pattern = option_1[_b];
regexOptions.push(RegExp(pattern));
}
}
}
for (var _c = 0, _d = tsutils_1.findImports(ctx.sourceFile, 63 /* All */); _c < _d.length; _c++) {
var name = _d[_c];
// TODO #3963: Resolve/normalize relative file imports to a canonical path?

@@ -177,4 +196,4 @@ var importedModule = name.text;

: []), (exportClause !== undefined ? exportClause.elements.map(toExportName) : []));
for (var _b = 0, namedImportsOrReExports_1 = namedImportsOrReExports; _b < namedImportsOrReExports_1.length; _b++) {
var importName = namedImportsOrReExports_1[_b];
for (var _e = 0, namedImportsOrReExports_1 = namedImportsOrReExports; _e < namedImportsOrReExports_1.length; _e++) {
var importName = namedImportsOrReExports_1[_e];
if (bansForModule.has(importName)) {

@@ -190,4 +209,10 @@ ctx.addFailureAtNode(exportClause !== undefined ? exportClause : importClause, Rule.MAKE_NAMED_IMPORT_FAILURE_STRING(importName));

}
for (var _f = 0, regexOptions_1 = regexOptions; _f < regexOptions_1.length; _f++) {
var regex = regexOptions_1[_f];
if (regex.test(name.text)) {
ctx.addFailure(name.getStart(ctx.sourceFile) + 1, name.end - 1, Rule.FAILURE_STRING_REGEX + regex.toString());
}
}
}
}
var templateObject_1, templateObject_2;

@@ -39,3 +39,3 @@ "use strict";

optionExamples: [true],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -42,0 +42,0 @@ };

@@ -67,3 +67,3 @@ "use strict";

hasFix: true,
type: "maintainability",
type: "formatting",
typescriptOnly: false,

@@ -70,0 +70,0 @@ };

@@ -51,3 +51,3 @@ "use strict";

optionExamples: [true, [true, OPTION_CHECK_MULTILINE_START]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -54,0 +54,0 @@ };

@@ -41,3 +41,3 @@ "use strict";

optionExamples: [[true, OPTION_LINEBREAK_STYLE_LF], [true, OPTION_LINEBREAK_STYLE_CRLF]],
type: "maintainability",
type: "formatting",
typescriptOnly: false,

@@ -44,0 +44,0 @@ hasFix: true,

@@ -89,3 +89,3 @@ "use strict";

],
type: "maintainability",
type: "formatting",
typescriptOnly: false,

@@ -92,0 +92,0 @@ };

@@ -111,3 +111,3 @@ "use strict";

}
var optionsDescription = Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n One argument, which is an object, must be provided. It should contain an `order` property.\n The `order` property should have a value of one of the following strings:\n\n ", "\n\n Alternatively, the value for `order` may be an array consisting of the following strings:\n\n ", "\n\n You can also omit the access modifier to refer to \"public-\", \"protected-\", and \"private-\" all at once; for example, \"static-field\".\n\n You can also make your own categories by using an object instead of a string:\n\n {\n \"name\": \"static non-private\",\n \"kinds\": [\n \"public-static-field\",\n \"protected-static-field\",\n \"public-static-method\",\n \"protected-static-method\"\n ]\n }\n\n The '", "' option will enforce that members within the same category should be alphabetically sorted by name."], ["\n One argument, which is an object, must be provided. It should contain an \\`order\\` property.\n The \\`order\\` property should have a value of one of the following strings:\n\n ", "\n\n Alternatively, the value for \\`order\\` may be an array consisting of the following strings:\n\n ", "\n\n You can also omit the access modifier to refer to \"public-\", \"protected-\", and \"private-\" all at once; for example, \"static-field\".\n\n You can also make your own categories by using an object instead of a string:\n\n {\n \"name\": \"static non-private\",\n \"kinds\": [\n \"public-static-field\",\n \"protected-static-field\",\n \"public-static-method\",\n \"protected-static-method\"\n ]\n }\n\n The '", "' option will enforce that members within the same category should be alphabetically sorted by name."])), namesMarkdown(PRESET_NAMES), namesMarkdown(allMemberKindNames), OPTION_ALPHABETIZE);
var optionsDescription = Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n One argument, which is an object, must be provided. It should contain an `order` property.\n The `order` property should have a value of one of the following strings:\n\n ", "\n\n `fields-first` puts, in order of precedence:\n\n * fields before constructors before methods\n * static members before instance members\n * public members before protected members before private members\n\n `instance-sandwich` puts, in order of precedence:\n\n * fields before constructors before methods\n * static fields before instance fields, but static methods *after* instance methods\n * public members before protected members before private members\n\n `statics-first` puts, in order of precedence:\n\n * static members before instance members\n * public members before protected members before private members\n * fields before methods\n * instance fields before constructors before instance methods\n * fields before constructors before methods\n * public members before protected members before private members\n\n Note that these presets, despite looking similar, can have subtly different behavior due to the order in which these\n rules are specified. A fully expanded ordering can be found in the PRESETS constant in\n https://github.com/palantir/tslint/blob/master/src/rules/memberOrderingRule.ts.\n (You may need to check the version of the file corresponding to your version of tslint.)\n\n Alternatively, the value for `order` may be an array consisting of the following strings:\n\n ", "\n\n You can also omit the access modifier to refer to \"public-\", \"protected-\", and \"private-\" all at once; for example, \"static-field\".\n\n You can also make your own categories by using an object instead of a string:\n\n {\n \"name\": \"static non-private\",\n \"kinds\": [\n \"public-static-field\",\n \"protected-static-field\",\n \"public-static-method\",\n \"protected-static-method\"\n ]\n }\n\n The '", "' option will enforce that members within the same category should be alphabetically sorted by name."], ["\n One argument, which is an object, must be provided. It should contain an \\`order\\` property.\n The \\`order\\` property should have a value of one of the following strings:\n\n ", "\n\n \\`fields-first\\` puts, in order of precedence:\n\n * fields before constructors before methods\n * static members before instance members\n * public members before protected members before private members\n\n \\`instance-sandwich\\` puts, in order of precedence:\n\n * fields before constructors before methods\n * static fields before instance fields, but static methods *after* instance methods\n * public members before protected members before private members\n\n \\`statics-first\\` puts, in order of precedence:\n\n * static members before instance members\n * public members before protected members before private members\n * fields before methods\n * instance fields before constructors before instance methods\n * fields before constructors before methods\n * public members before protected members before private members\n\n Note that these presets, despite looking similar, can have subtly different behavior due to the order in which these\n rules are specified. A fully expanded ordering can be found in the PRESETS constant in\n https://github.com/palantir/tslint/blob/master/src/rules/memberOrderingRule.ts.\n (You may need to check the version of the file corresponding to your version of tslint.)\n\n Alternatively, the value for \\`order\\` may be an array consisting of the following strings:\n\n ", "\n\n You can also omit the access modifier to refer to \"public-\", \"protected-\", and \"private-\" all at once; for example, \"static-field\".\n\n You can also make your own categories by using an object instead of a string:\n\n {\n \"name\": \"static non-private\",\n \"kinds\": [\n \"public-static-field\",\n \"protected-static-field\",\n \"public-static-method\",\n \"protected-static-method\"\n ]\n }\n\n The '", "' option will enforce that members within the same category should be alphabetically sorted by name."])), namesMarkdown(PRESET_NAMES), namesMarkdown(allMemberKindNames), OPTION_ALPHABETIZE);
var Rule = /** @class */ (function (_super) {

@@ -162,2 +162,5 @@ tslib_1.__extends(Rule, _super);

},
alphabetize: {
type: "boolean",
},
},

@@ -182,2 +185,3 @@ additionalProperties: false,

],
alphabetize: true,
},

@@ -237,3 +241,3 @@ ],

/**
* Check wether the passed members adhere to the configured order. If not, RuleFailures are generated and a single
* Check whether the passed members adhere to the configured order. If not, RuleFailures are generated and a single
* Lint.Replacement is generated, which replaces the entire NodeArray with a correctly sorted one. The Replacement

@@ -240,0 +244,0 @@ * is not immediately added to a RuleFailure, as incorrectly sorted nodes can be nested (e.g. a class declaration

@@ -23,2 +23,3 @@ "use strict";

var Lint = require("../index");
var utils_1 = require("../utils");
var Rule = /** @class */ (function (_super) {

@@ -37,6 +38,7 @@ tslib_1.__extends(Rule, _super);

rationale: "Helps maintain a readable style in your codebase.",
hasFix: true,
optionsDescription: "Not configurable.",
options: {},
optionExamples: [true],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -88,4 +90,7 @@ };

if (prevLine >= line - 1) {
var fixer = Lint.Replacement.replaceFromTo(line === prevLine ? node.pos : node.pos + 1, start, line === prevLine
? utils_1.newLineWithIndentation(prev, this.sourceFile, 2)
: utils_1.newLineWithIndentation(prev, this.sourceFile));
// Previous statement is on the same or previous line
this.addFailure(start, start, Rule.FAILURE_STRING);
this.addFailure(start, start, Rule.FAILURE_STRING, fixer);
}

@@ -92,0 +97,0 @@ };

@@ -38,3 +38,3 @@ "use strict";

optionExamples: [true],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -41,0 +41,0 @@ };

@@ -58,3 +58,3 @@ "use strict";

optionExamples: [true, [true, 2]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -61,0 +61,0 @@ };

@@ -66,3 +66,3 @@ "use strict";

descriptionDetails: "Import named members instead.",
rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts.\n\n The rule supposed to narrow the scope of your changes in the case of monorepo.\n Say, you have packages `A`, `B`, `C` and `utils`, where `A`, `B`, `C` dependends on `utils`,\n which is full of default exports.\n `\"no-default-export\"` requires you to remove default _export_ from `utils`, which leads to changes\n in packages `A`, `B`, `C`. It's harder to get merged bigger changeset by various reasons (harder to get your code approved\n due to a number of required reviewers; longer build time due to a number of affected packages)\n and could result in ignored `\"no-default-export\"` rule in `utils'`.\n\n Unlike `\"no-default-export\"`, the rule requires you to repalce default _import_ with named only in `A` you work on,\n and `utils` you import from."], ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts.\n\n The rule supposed to narrow the scope of your changes in the case of monorepo.\n Say, you have packages \\`A\\`, \\`B\\`, \\`C\\` and \\`utils\\`, where \\`A\\`, \\`B\\`, \\`C\\` dependends on \\`utils\\`,\n which is full of default exports.\n \\`\"no-default-export\"\\` requires you to remove default _export_ from \\`utils\\`, which leads to changes\n in packages \\`A\\`, \\`B\\`, \\`C\\`. It's harder to get merged bigger changeset by various reasons (harder to get your code approved\n due to a number of required reviewers; longer build time due to a number of affected packages)\n and could result in ignored \\`\"no-default-export\"\\` rule in \\`utils'\\`.\n\n Unlike \\`\"no-default-export\"\\`, the rule requires you to repalce default _import_ with named only in \\`A\\` you work on,\n and \\`utils\\` you import from."]))),
rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts.\n\n The rule supposed to narrow the scope of your changes in the case of monorepo.\n Say, you have packages `A`, `B`, `C` and `utils`, where `A`, `B`, `C` dependends on `utils`,\n which is full of default exports.\n `\"no-default-export\"` requires you to remove default _export_ from `utils`, which leads to changes\n in packages `A`, `B`, `C`. It's harder to get merged bigger changeset by various reasons (harder to get your code approved\n due to a number of required reviewers; longer build time due to a number of affected packages)\n and could result in ignored `\"no-default-export\"` rule in `utils'`.\n\n Unlike `\"no-default-export\"`, the rule requires you to replace default _import_ with named only in `A` you work on,\n and `utils` you import from."], ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts.\n\n The rule supposed to narrow the scope of your changes in the case of monorepo.\n Say, you have packages \\`A\\`, \\`B\\`, \\`C\\` and \\`utils\\`, where \\`A\\`, \\`B\\`, \\`C\\` dependends on \\`utils\\`,\n which is full of default exports.\n \\`\"no-default-export\"\\` requires you to remove default _export_ from \\`utils\\`, which leads to changes\n in packages \\`A\\`, \\`B\\`, \\`C\\`. It's harder to get merged bigger changeset by various reasons (harder to get your code approved\n due to a number of required reviewers; longer build time due to a number of affected packages)\n and could result in ignored \\`\"no-default-export\"\\` rule in \\`utils'\\`.\n\n Unlike \\`\"no-default-export\"\\`, the rule requires you to replace default _import_ with named only in \\`A\\` you work on,\n and \\`utils\\` you import from."]))),
optionsDescription: "optionsDescription",

@@ -69,0 +69,0 @@ options: {

@@ -37,3 +37,3 @@ "use strict";

optionExamples: [true],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -40,0 +40,0 @@ };

@@ -20,6 +20,9 @@ "use strict";

var tslib_1 = require("tslib");
var _a, _b;
var tsutils_1 = require("tsutils");
var ts = require("typescript");
var tsutils_1 = require("tsutils");
var Lint = require("../index");
var utils_1 = require("../language/utils");
var IGNORE_JSX_OPTION = "ignore-jsx";
var ALLOWED_NUMBERS_OPTION = "allowed-numbers";
var Rule = /** @class */ (function (_super) {

@@ -34,3 +37,5 @@ tslib_1.__extends(Rule, _super);

Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new NoMagicNumbersWalker(sourceFile, this.ruleName, this.ruleArguments.length > 0 ? this.ruleArguments : Rule.DEFAULT_ALLOWED));
return this.applyWithWalker(new NoMagicNumbersWalker(sourceFile, this.ruleName, this.ruleArguments.length > 0
? parseOptions(this.ruleArguments)
: parseOptions(Rule.DEFAULT_ALLOWED)));
};

@@ -42,3 +47,3 @@ /* tslint:disable:object-literal-sort-keys */

rationale: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n Magic numbers should be avoided as they often lack documentation.\n Forcing them to be stored in variables gives them implicit documentation.\n "], ["\n Magic numbers should be avoided as they often lack documentation.\n Forcing them to be stored in variables gives them implicit documentation.\n "]))),
optionsDescription: "A list of allowed numbers.",
optionsDescription: Lint.Utils.dedent(templateObject_3 || (templateObject_3 = tslib_1.__makeTemplateObject(["\n Options may either be a list of numbers to ignore (not consider 'magic'), or an object containing up to two properties:\n * `", "` as the list of numbers to ignore.\n * `", "` to specify that 'magic' numbers should be allowed as JSX attributes."], ["\n Options may either be a list of numbers to ignore (not consider 'magic'), or an object containing up to two properties:\n * \\`", "\\` as the list of numbers to ignore.\n * \\`", "\\` to specify that 'magic' numbers should be allowed as JSX attributes."])), ALLOWED_NUMBERS_OPTION, IGNORE_JSX_OPTION),
options: {

@@ -49,5 +54,24 @@ type: "array",

},
properties: (_a = {
type: "object"
},
_a[ALLOWED_NUMBERS_OPTION] = {
type: "array",
},
_a[IGNORE_JSX_OPTION] = {
type: "boolean",
},
_a),
minLength: 1,
},
optionExamples: [true, [true, 1, 2, 3]],
optionExamples: [
[true, 1, 2, 3],
[
true,
(_b = {},
_b[ALLOWED_NUMBERS_OPTION] = [1, 2, 3],
_b[IGNORE_JSX_OPTION] = true,
_b),
],
],
type: "typescript",

@@ -73,2 +97,25 @@ typescriptOnly: false,

exports.Rule = Rule;
function parseOptions(options) {
var _a;
var parsedOptions = (_a = {}, _a[ALLOWED_NUMBERS_OPTION] = [], _a);
for (var _i = 0, options_1 = options; _i < options_1.length; _i++) {
var option = options_1[_i];
if (typeof option === "number") {
parsedOptions[ALLOWED_NUMBERS_OPTION].push(option);
continue;
}
if (option.hasOwnProperty(ALLOWED_NUMBERS_OPTION)) {
var numberOptions = option[ALLOWED_NUMBERS_OPTION];
if (Array.isArray(numberOptions) && numberOptions.length > 0) {
numberOptions.forEach(function (num) {
return parsedOptions[ALLOWED_NUMBERS_OPTION].push(num);
});
}
}
if (option.hasOwnProperty(IGNORE_JSX_OPTION)) {
parsedOptions[IGNORE_JSX_OPTION] = option[IGNORE_JSX_OPTION];
}
}
return parsedOptions;
}
var NoMagicNumbersWalker = /** @class */ (function (_super) {

@@ -97,6 +144,18 @@ tslib_1.__extends(NoMagicNumbersWalker, _super);

};
NoMagicNumbersWalker.prototype.isAllowedNumber = function (num) {
var numberOptions = this.options[ALLOWED_NUMBERS_OPTION];
if (numberOptions.length > 0) {
return numberOptions.some(function (allowedNum) {
/* Using Object.is() to differentiate between pos/neg zero */
return Object.is(allowedNum, parseFloat(num));
});
}
return false;
};
NoMagicNumbersWalker.prototype.checkNumericLiteral = function (node, num) {
/* Using Object.is() to differentiate between pos/neg zero */
var shouldIgnoreJsxExpression = node.parent.kind === ts.SyntaxKind.JsxExpression &&
this.options[IGNORE_JSX_OPTION];
if (!Rule.ALLOWED_NODES.has(node.parent.kind) &&
!this.options.some(function (allowedNum) { return Object.is(allowedNum, parseFloat(num)); })) {
!this.isAllowedNumber(num) &&
!shouldIgnoreJsxExpression) {
this.addFailureAtNode(node, Rule.FAILURE_STRING(num));

@@ -107,2 +166,2 @@ }

}(Lint.AbstractWalker));
var templateObject_1, templateObject_2;
var templateObject_1, templateObject_2, templateObject_3;

@@ -62,3 +62,3 @@ "use strict";

optionExamples: [true, [true, OPTION_IGNORE_COMMENTS], [true, OPTION_IGNORE_JSDOC]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -65,0 +65,0 @@ };

@@ -20,2 +20,3 @@ "use strict";

var tslib_1 = require("tslib");
var _a, _b;
var tsutils_1 = require("tsutils");

@@ -25,2 +26,12 @@ var ts = require("typescript");

var OPTION_IGNORE_STATIC = "ignore-static";
var OPTION_WHITELIST = "whitelist";
var OPTION_ALLOW_TYPEOF = "allow-typeof";
var OPTION_WHITELIST_EXAMPLE = [
true,
(_a = {},
_a[OPTION_IGNORE_STATIC] = true,
_a[OPTION_WHITELIST] = ["expect"],
_a[OPTION_ALLOW_TYPEOF] = true,
_a),
];
var Rule = /** @class */ (function (_super) {

@@ -32,5 +43,3 @@ tslib_1.__extends(Rule, _super);

Rule.prototype.applyWithProgram = function (sourceFile, program) {
return this.applyWithFunction(sourceFile, walk, {
ignoreStatic: this.ruleArguments.indexOf(OPTION_IGNORE_STATIC) !== -1,
}, program.getTypeChecker());
return this.applyWithFunction(sourceFile, walk, parseArguments(this.ruleArguments), program.getTypeChecker());
};

@@ -41,9 +50,25 @@ /* tslint:disable:object-literal-sort-keys */

description: "Warns when a method is used outside of a method call.",
optionsDescription: "You may optionally pass \"" + OPTION_IGNORE_STATIC + "\" to ignore static methods.",
optionsDescription: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n You may additionally pass \"", "\" to ignore static methods, or an options object.\n \n The object may have three properties:\n \n * \"", "\" - to ignore static methods.\n * \"", "\" - ignore methods referenced in a typeof expression.\n * \"", "\" - ignore method references in parameters of specifed function calls.\n \n "], ["\n You may additionally pass \"", "\" to ignore static methods, or an options object.\n \n The object may have three properties:\n \n * \"", "\" - to ignore static methods.\n * \"", "\" - ignore methods referenced in a typeof expression.\n * \"", "\" - ignore method references in parameters of specifed function calls.\n \n "])), OPTION_IGNORE_STATIC, OPTION_IGNORE_STATIC, OPTION_ALLOW_TYPEOF, OPTION_WHITELIST),
options: {
type: "string",
enum: [OPTION_IGNORE_STATIC],
anyOf: [
{
type: "string",
enum: [OPTION_IGNORE_STATIC],
},
{
type: "object",
properties: (_b = {},
_b[OPTION_ALLOW_TYPEOF] = { type: "boolean" },
_b[OPTION_IGNORE_STATIC] = { type: "boolean" },
_b[OPTION_WHITELIST] = {
type: "array",
items: { type: "string" },
minLength: 1,
},
_b),
},
],
},
optionExamples: [true, [true, OPTION_IGNORE_STATIC]],
rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Class functions don't preserve the class scope when passed as standalone variables.\n For example, this code will log the global scope (`window`/`global`), not the class instance:\n\n ```\n class MyClass {\n public log(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const log = instance.log;\n\n log();\n ```\n\n You need to either use an arrow lambda (`() => {...}`) or call the function with the correct scope.\n\n ```\n class MyClass {\n public logArrowBound = (): void => {\n console.log(bound);\n };\n\n public logManualBind(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const logArrowBound = instance.logArrowBound;\n const logManualBind = instance.logManualBind.bind(instance);\n\n logArrowBound();\n logManualBind();\n ```\n "], ["\n Class functions don't preserve the class scope when passed as standalone variables.\n For example, this code will log the global scope (\\`window\\`/\\`global\\`), not the class instance:\n\n \\`\\`\\`\n class MyClass {\n public log(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const log = instance.log;\n\n log();\n \\`\\`\\`\n\n You need to either use an arrow lambda (\\`() => {...}\\`) or call the function with the correct scope.\n\n \\`\\`\\`\n class MyClass {\n public logArrowBound = (): void => {\n console.log(bound);\n };\n\n public logManualBind(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const logArrowBound = instance.logArrowBound;\n const logManualBind = instance.logManualBind.bind(instance);\n\n logArrowBound();\n logManualBind();\n \\`\\`\\`\n "]))),
optionExamples: [true, [true, OPTION_IGNORE_STATIC], OPTION_WHITELIST_EXAMPLE],
rationale: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n Class functions don't preserve the class scope when passed as standalone variables.\n For example, this code will log the global scope (`window`/`global`), not the class instance:\n\n ```\n class MyClass {\n public log(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const log = instance.log;\n\n log();\n ```\n\n You need to either use an arrow lambda (`() => {...}`) or call the function with the correct scope.\n\n ```\n class MyClass {\n public logArrowBound = (): void => {\n console.log(bound);\n };\n\n public logManualBind(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const logArrowBound = instance.logArrowBound;\n const logManualBind = instance.logManualBind.bind(instance);\n\n logArrowBound();\n logManualBind();\n ```\n "], ["\n Class functions don't preserve the class scope when passed as standalone variables.\n For example, this code will log the global scope (\\`window\\`/\\`global\\`), not the class instance:\n\n \\`\\`\\`\n class MyClass {\n public log(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const log = instance.log;\n\n log();\n \\`\\`\\`\n\n You need to either use an arrow lambda (\\`() => {...}\\`) or call the function with the correct scope.\n\n \\`\\`\\`\n class MyClass {\n public logArrowBound = (): void => {\n console.log(bound);\n };\n\n public logManualBind(): void {\n console.log(this);\n }\n }\n\n const instance = new MyClass();\n const logArrowBound = instance.logArrowBound;\n const logManualBind = instance.logManualBind.bind(instance);\n\n logArrowBound();\n logManualBind();\n \\`\\`\\`\n "]))),
type: "functionality",

@@ -58,2 +83,23 @@ typescriptOnly: true,

exports.Rule = Rule;
function parseArguments(args) {
var options = {
allowTypeof: false,
ignoreStatic: false,
whitelist: new Set(),
};
for (var _i = 0, args_1 = args; _i < args_1.length; _i++) {
var arg = args_1[_i];
if (typeof arg === "string") {
if (arg === OPTION_IGNORE_STATIC) {
options.ignoreStatic = true;
}
}
else {
options.allowTypeof = arg[OPTION_ALLOW_TYPEOF] || false;
options.ignoreStatic = arg[OPTION_IGNORE_STATIC] || false;
options.whitelist = new Set(arg[OPTION_WHITELIST]);
}
}
return options;
}
function walk(ctx, tc) {

@@ -64,3 +110,6 @@ return ts.forEachChild(ctx.sourceFile, function cb(node) {

var declaration = symbol === undefined ? undefined : symbol.valueDeclaration;
if (declaration !== undefined && isMethod(declaration, ctx.options.ignoreStatic)) {
var isMethodAccess = declaration !== undefined && isMethod(declaration, ctx.options.ignoreStatic);
var shouldBeReported = isMethodAccess &&
!isWhitelisted(node, ctx.options.whitelist, ctx.options.allowTypeof);
if (shouldBeReported) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);

@@ -113,2 +162,13 @@ }

}
var templateObject_1;
function isWhitelisted(node, whitelist, allowTypeof) {
if (tsutils_1.isTypeOfExpression(node.parent)) {
return allowTypeof;
}
if (tsutils_1.isCallExpression(node.parent) && tsutils_1.isIdentifier(node.parent.expression)) {
var expression = node.parent.expression;
var callingMethodName = expression.text;
return whitelist.has(callingMethodName);
}
return false;
}
var templateObject_1, templateObject_2;

@@ -20,5 +20,5 @@ "use strict";

var tslib_1 = require("tslib");
var tsutils_1 = require("tsutils");
var ts = require("typescript");
var Lint = require("../index");
var tsutils_1 = require("tsutils");
var OPTION__ALLOW_CONSTRUCTOR_ONLY = "allow-constructor-only";

@@ -25,0 +25,0 @@ var OPTION__ALLOW_EMPTY_CLASS = "allow-empty-class";

@@ -35,3 +35,3 @@ "use strict";

ruleName: "no-unsafe-any",
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for `{} | null | undefined`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as `\"\" + x`) are allowed."], ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for \\`{} | null | undefined\\`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as \\`\"\" + x\\`) are allowed."]))),
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for `{} | null | undefined`.\n Downcasting to unknown is always safe.\n Type casts and tests are allowed.\n Expressions that work on all values (such as `\"\" + x`) are allowed."], ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for \\`{} | null | undefined\\`.\n Downcasting to unknown is always safe.\n Type casts and tests are allowed.\n Expressions that work on all values (such as \\`\"\" + x\\`) are allowed."]))),
optionsDescription: "Not configurable.",

@@ -122,3 +122,3 @@ options: null,

return (initializer !== undefined &&
this.visitNode(initializer, isPropertyAny(node, this.checker)));
this.visitNode(initializer, isPropertyAnyOrUnknown(node, this.checker)));
}

@@ -275,3 +275,4 @@ case ts.SyntaxKind.SpreadAssignment:

var type = this.checker.getContextualType(node);
return this.visitNode(node, (type === undefined && allowIfNoContextualType) || isAny(type));
var anyOk = (type === undefined && allowIfNoContextualType) || isAny(type, true);
return this.visitNode(node, anyOk);
};

@@ -282,9 +283,10 @@ // Allow `const x = foo;` and `const x: any = foo`, but not `const x: Foo = foo;`.

this.checkBindingName(name);
// Always allow the LHS to be `any`. Just don't allow RHS to be `any` when LHS isn't.
return (initializer !== undefined &&
this.visitNode(initializer,
/*anyOk*/
(name.kind === ts.SyntaxKind.Identifier &&
(type === undefined || type.kind === ts.SyntaxKind.AnyKeyword)) ||
(type !== undefined && type.kind === ts.SyntaxKind.AnyKeyword)));
// Always allow the LHS to be `any`. Just don't allow RHS to be `any` when LHS isn't `any` or `unknown`.
var anyOk = (name.kind === ts.SyntaxKind.Identifier &&
(type === undefined ||
type.kind === ts.SyntaxKind.AnyKeyword ||
type.kind === ts.SyntaxKind.UnknownKeyword)) ||
(type !== undefined && type.kind === ts.SyntaxKind.AnyKeyword) ||
(type !== undefined && type.kind === ts.SyntaxKind.UnknownKeyword);
return initializer !== undefined && this.visitNode(initializer, anyOk);
};

@@ -310,3 +312,3 @@ NoUnsafeAnyWalker.prototype.checkBinaryExpression = function (node, anyOk) {

allowAnyLeft = true;
allowAnyRight = isNodeAny(node.left, this.checker);
allowAnyRight = isNodeAny(node.left, this.checker, true);
break;

@@ -366,4 +368,5 @@ case ts.SyntaxKind.PlusToken: // Allow implicit stringification

/** Check if property has no type annotation in this class and the base class */
function isPropertyAny(node, checker) {
if (!isNodeAny(node.name, checker) || node.name.kind === ts.SyntaxKind.ComputedPropertyName) {
function isPropertyAnyOrUnknown(node, checker) {
if (!isNodeAny(node.name, checker, true) ||
node.name.kind === ts.SyntaxKind.ComputedPropertyName) {
return false;

@@ -375,3 +378,3 @@ }

if (prop !== undefined && prop.declarations !== undefined) {
return isAny(checker.getTypeOfSymbolAtLocation(prop, prop.declarations[0]));
return isAny(checker.getTypeOfSymbolAtLocation(prop, prop.declarations[0]), true);
}

@@ -381,3 +384,7 @@ }

}
function isNodeAny(node, checker) {
/**
* @param orUnknown If true, this function will also return true when the node is unknown.
*/
function isNodeAny(node, checker, orUnknown) {
if (orUnknown === void 0) { orUnknown = false; }
var symbol = checker.getSymbolAtLocation(node);

@@ -393,3 +400,3 @@ if (symbol !== undefined && tsutils_1.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {

if (tsutils_1.isSymbolFlagSet(symbol, ts.SymbolFlags.Type)) {
return isAny(checker.getDeclaredTypeOfSymbol(symbol));
return isAny(checker.getDeclaredTypeOfSymbol(symbol), orUnknown);
}

@@ -401,3 +408,3 @@ }

}
return isAny(checker.getTypeAtLocation(node));
return isAny(checker.getTypeAtLocation(node), orUnknown);
}

@@ -422,5 +429,8 @@ var jsxElementTypes = new Set([

}
function isAny(type) {
return type !== undefined && tsutils_1.isTypeFlagSet(type, ts.TypeFlags.Any);
function isAny(type, orUnknown) {
if (orUnknown === void 0) { orUnknown = false; }
return (type !== undefined &&
(tsutils_1.isTypeFlagSet(type, ts.TypeFlags.Any) ||
(orUnknown && tsutils_1.isTypeFlagSet(type, ts.TypeFlags.Unknown))));
}
var templateObject_1, templateObject_2;

@@ -20,4 +20,4 @@ "use strict";

var tslib_1 = require("tslib");
var tsutils_1 = require("tsutils");
var ts = require("typescript");
var tsutils_1 = require("tsutils");
var Lint = require("../index");

@@ -24,0 +24,0 @@ var noUseBeforeDeclare_examples_1 = require("./code-examples/noUseBeforeDeclare.examples");

@@ -35,2 +35,3 @@ "use strict";

ruleName: "number-literal-format",
hasFix: true,
description: "Checks that decimal literals should begin with '0.' instead of just '.', and should not end with a trailing '0'.",

@@ -41,3 +42,3 @@ optionsDescription: "Not configurable.",

rationale: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Helps keep a consistent style with numeric literals.\n Non-standard literals are more difficult to scan through and can be a symptom of typos.\n "], ["\n Helps keep a consistent style with numeric literals.\n Non-standard literals are more difficult to scan through and can be a symptom of typos.\n "]))),
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -65,2 +66,3 @@ };

var text = node.getText(sourceFile);
var start = node.getStart();
if (text.length <= 1) {

@@ -73,4 +75,6 @@ return;

case "x":
if (!utils_1.isUpperCase(text.slice(2))) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_NOT_UPPERCASE);
// strip "0x"
var hexNumber = text.slice(2);
if (!utils_1.isUpperCase(hexNumber)) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_NOT_UPPERCASE, Lint.Replacement.replaceNode(node, "0x" + hexNumber.toUpperCase()));
}

@@ -84,9 +88,16 @@ return;

default:
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_LEADING_0);
ctx.addFailureAtNode(node, Rule.FAILURE_STRING_LEADING_0, Lint.Replacement.deleteFromTo(start, start + /^0+/.exec(text)[0].length));
return;
}
}
var _a = text.split(/e/i), num = _a[0], exp = _a[1];
if (exp !== undefined && (exp.startsWith("-0") || exp.startsWith("0"))) {
ctx.addFailureAt(node.getEnd() - exp.length, exp.length, Rule.FAILURE_STRING_LEADING_0);
var _a = text.split(/e/i), num = _a[0], _b = _a[1], exp = _b === void 0 ? "" : _b;
var _c = num.split("."), integer = _c[0], _d = _c[1], float = _d === void 0 ? "" : _d;
var matchedNumeric = /(\.)([1-9]*)(0+)/.exec(num);
var _e = Array.isArray(matchedNumeric)
? matchedNumeric.slice(1)
: [], _f = _e[0], dot = _f === void 0 ? "" : _f, _g = _e[1], numbers = _g === void 0 ? "" : _g, _h = _e[2], zeroes = _h === void 0 ? "" : _h;
if (exp.startsWith("-0") || exp.startsWith("0")) {
var expStart = start + num.length + 1; // position of exp part
var expNumberStart = /\D/.test(exp.charAt(0)) ? expStart + 1 : expStart; // do not remove "-" or "+"
ctx.addFailureAt(node.getEnd() - exp.length, exp.length, Rule.FAILURE_STRING_LEADING_0, Lint.Replacement.deleteFromTo(expNumberStart, expNumberStart + /0+/.exec(exp)[0].length));
}

@@ -97,13 +108,18 @@ if (!num.includes(".")) {

if (num.startsWith(".")) {
fail(Rule.FAILURE_STRING_LEADING_DECIMAL);
// .1 -> 0.1
fail(Rule.FAILURE_STRING_LEADING_DECIMAL, Lint.Replacement.appendText(start, "0"));
}
if (num.endsWith(".")) {
fail(Rule.FAILURE_STRING_TRAILING_DECIMAL);
else if (num.endsWith(".")) {
// 1. -> 1
fail(Rule.FAILURE_STRING_TRAILING_DECIMAL, Lint.Replacement.deleteText(start + num.length - 1, 1));
}
// Allow '10', but not '1.0'
if (num.endsWith("0")) {
fail(Rule.FAILURE_STRING_TRAILING_0);
if (float.endsWith("0")) {
// 1.0 -> 1
var offset = numbers.length > 0 ? dot.length + numbers.length : 0;
var length = (numbers.length > 0 ? 0 : dot.length) + zeroes.length;
fail(Rule.FAILURE_STRING_TRAILING_0, Lint.Replacement.deleteText(start + integer.length + offset, length));
}
function fail(message) {
ctx.addFailureAt(node.getStart(sourceFile), num.length, message);
function fail(message, fix) {
ctx.addFailureAt(node.getStart(sourceFile), num.length, message, fix);
}

@@ -110,0 +126,0 @@ }

@@ -22,2 +22,3 @@ "use strict";

var ts = require("typescript");
var error_1 = require("../error");
var Lint = require("../index");

@@ -28,2 +29,3 @@ var objectLiteralSortKeys_examples_1 = require("./code-examples/objectLiteralSortKeys.examples");

var OPTION_MATCH_DECLARATION_ORDER = "match-declaration-order";
var OPTION_MATCH_DECLARATION_ORDER_ONLY = "match-declaration-order-only";
var OPTION_SHORTHAND_FIRST = "shorthand-first";

@@ -48,4 +50,5 @@ var Rule = /** @class */ (function (_super) {

var options = parseOptions(this.ruleArguments);
if (options.matchDeclarationOrder) {
throw new Error(this.ruleName + " needs type info to use \"" + OPTION_MATCH_DECLARATION_ORDER + "\".");
if (options.matchDeclarationOrder || options.matchDeclarationOrderOnly) {
error_1.showWarningOnce(Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n ", " needs type info to use \"", "\" or\n \"", "\".\n See https://palantir.github.io/tslint/usage/type-checking/ for documentation on\n how to enable this feature.\n "], ["\n ", " needs type info to use \"", "\" or\n \"", "\".\n See https://palantir.github.io/tslint/usage/type-checking/ for documentation on\n how to enable this feature.\n "])), this.ruleName, OPTION_MATCH_DECLARATION_ORDER, OPTION_MATCH_DECLARATION_ORDER_ONLY));
return [];
}

@@ -55,2 +58,8 @@ return this.applyWithFunction(sourceFile, walk, options);

Rule.prototype.applyWithProgram = function (sourceFile, program) {
var options = parseOptions(this.ruleArguments);
if (options.matchDeclarationOrder && options.matchDeclarationOrderOnly) {
error_1.showWarningOnce("\"" + OPTION_MATCH_DECLARATION_ORDER + "\" will be ignored since " +
("\"" + OPTION_MATCH_DECLARATION_ORDER_ONLY + "\" has been enabled for " + this.ruleName + "."));
return [];
}
return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments), program.getTypeChecker());

@@ -61,5 +70,5 @@ };

ruleName: "object-literal-sort-keys",
description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Checks ordering of keys in object literals.\n\n When using the default alphabetical ordering, additional blank lines may be used to group\n object properties together while keeping the elements within each group in alphabetical order.\n "], ["\n Checks ordering of keys in object literals.\n\n When using the default alphabetical ordering, additional blank lines may be used to group\n object properties together while keeping the elements within each group in alphabetical order.\n "]))),
description: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n Checks ordering of keys in object literals.\n\n When using the default alphabetical ordering, additional blank lines may be used to group\n object properties together while keeping the elements within each group in alphabetical order.\n "], ["\n Checks ordering of keys in object literals.\n\n When using the default alphabetical ordering, additional blank lines may be used to group\n object properties together while keeping the elements within each group in alphabetical order.\n "]))),
rationale: "Useful in preventing merge conflicts",
optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n By default, this rule checks that keys are in alphabetical order.\n The following may optionally be passed:\n\n * `", "` will compare keys in a case insensitive way.\n * `", "` will compare keys using the expected sort order of special characters, such as accents.\n * `", "` will prefer to use the key ordering of the contextual type of the object literal, as in:\n\n ```\n interface I { foo: number; bar: number; }\n const obj: I = { foo: 1, bar: 2 };\n ```\n\n If a contextual type is not found, alphabetical ordering will be used instead.\n * `", "` will enforce shorthand properties to appear first, as in:\n\n ```\n const obj = { a, c, b: true };\n ```\n "], ["\n By default, this rule checks that keys are in alphabetical order.\n The following may optionally be passed:\n\n * \\`", "\\` will compare keys in a case insensitive way.\n * \\`", "\\` will compare keys using the expected sort order of special characters, such as accents.\n * \\`", "\\` will prefer to use the key ordering of the contextual type of the object literal, as in:\n\n \\`\\`\\`\n interface I { foo: number; bar: number; }\n const obj: I = { foo: 1, bar: 2 };\n \\`\\`\\`\n\n If a contextual type is not found, alphabetical ordering will be used instead.\n * \\`", "\\` will enforce shorthand properties to appear first, as in:\n\n \\`\\`\\`\n const obj = { a, c, b: true };\n \\`\\`\\`\n "])), OPTION_IGNORE_CASE, OPTION_LOCALE_COMPARE, OPTION_MATCH_DECLARATION_ORDER, OPTION_SHORTHAND_FIRST),
optionsDescription: Lint.Utils.dedent(templateObject_3 || (templateObject_3 = tslib_1.__makeTemplateObject(["\n By default, this rule checks that keys are in alphabetical order.\n The following may optionally be passed:\n\n * `", "` will compare keys in a case insensitive way.\n * `", "` will compare keys using the expected sort order of special characters, such as accents.\n * `", "` will prefer to use the key ordering of the contextual type of the object literal, as in:\n\n ```\n interface I { foo: number; bar: number; }\n const obj: I = { foo: 1, bar: 2 };\n ```\n\n If a contextual type is not found, alphabetical ordering will be used instead.\n * \"", "\" exactly like \"", "\",\n but don't fall back to alphabetical if a contextual type is not found.\n\n Note: If both ", " and ", " options are present,\n ", " will take precedence and alphabetical fallback will not occur.\n\n * `", "` will enforce shorthand properties to appear first, as in:\n\n ```\n const obj = { a, c, b: true };\n ```\n "], ["\n By default, this rule checks that keys are in alphabetical order.\n The following may optionally be passed:\n\n * \\`", "\\` will compare keys in a case insensitive way.\n * \\`", "\\` will compare keys using the expected sort order of special characters, such as accents.\n * \\`", "\\` will prefer to use the key ordering of the contextual type of the object literal, as in:\n\n \\`\\`\\`\n interface I { foo: number; bar: number; }\n const obj: I = { foo: 1, bar: 2 };\n \\`\\`\\`\n\n If a contextual type is not found, alphabetical ordering will be used instead.\n * \"", "\" exactly like \"", "\",\n but don't fall back to alphabetical if a contextual type is not found.\n\n Note: If both ", " and ", " options are present,\n ", " will take precedence and alphabetical fallback will not occur.\n\n * \\`", "\\` will enforce shorthand properties to appear first, as in:\n\n \\`\\`\\`\n const obj = { a, c, b: true };\n \\`\\`\\`\n "])), OPTION_IGNORE_CASE, OPTION_LOCALE_COMPARE, OPTION_MATCH_DECLARATION_ORDER, OPTION_MATCH_DECLARATION_ORDER_ONLY, OPTION_MATCH_DECLARATION_ORDER, OPTION_MATCH_DECLARATION_ORDER_ONLY, OPTION_MATCH_DECLARATION_ORDER, OPTION_MATCH_DECLARATION_ORDER_ONLY, OPTION_SHORTHAND_FIRST),
options: {

@@ -71,2 +80,3 @@ type: "string",

OPTION_MATCH_DECLARATION_ORDER,
OPTION_MATCH_DECLARATION_ORDER_ONLY,
OPTION_SHORTHAND_FIRST,

@@ -97,2 +107,3 @@ ],

matchDeclarationOrder: has(OPTION_MATCH_DECLARATION_ORDER),
matchDeclarationOrderOnly: has(OPTION_MATCH_DECLARATION_ORDER_ONLY),
shorthandFirst: has(OPTION_SHORTHAND_FIRST),

@@ -105,3 +116,3 @@ };

function walk(ctx, checker) {
var sourceFile = ctx.sourceFile, _a = ctx.options, ignoreCase = _a.ignoreCase, localeCompare = _a.localeCompare, matchDeclarationOrder = _a.matchDeclarationOrder, shorthandFirst = _a.shorthandFirst;
var sourceFile = ctx.sourceFile, _a = ctx.options, ignoreCase = _a.ignoreCase, localeCompare = _a.localeCompare, matchDeclarationOrder = _a.matchDeclarationOrder, matchDeclarationOrderOnly = _a.matchDeclarationOrderOnly, shorthandFirst = _a.shorthandFirst;
ts.forEachChild(sourceFile, function cb(node) {

@@ -114,3 +125,3 @@ if (tsutils_1.isObjectLiteralExpression(node) && node.properties.length > 1) {

function check(node) {
if (matchDeclarationOrder) {
if (matchDeclarationOrder || matchDeclarationOrderOnly) {
var type = getContextualType(node, checker);

@@ -128,3 +139,5 @@ // If type has an index signature, we can't check ordering.

}
checkAlphabetical(node);
if (!matchDeclarationOrderOnly) {
checkAlphabetical(node);
}
}

@@ -246,2 +259,2 @@ function checkAlphabetical(node) {

}
var templateObject_1, templateObject_2;
var templateObject_1, templateObject_2, templateObject_3;

@@ -21,7 +21,6 @@ /**

static metadata: Lint.IRuleMetadata;
static IMPORT_SOURCES_NOT_GROUPED: string;
static IMPORT_SOURCES_NOT_GROUPED_PREFIX: string;
static IMPORT_SOURCES_UNORDERED: string;
static NAMED_IMPORTS_UNORDERED: string;
static IMPORT_SOURCES_OF_SAME_TYPE_NOT_IN_ONE_GROUP: string;
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[];
}

@@ -35,5 +35,5 @@ "use strict";

description: "Requires that import statements be alphabetized and grouped.",
descriptionDetails: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically or can you can\n enforce a grouping of third-party, parent directories and the current directory."], ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically or can you can\n enforce a grouping of third-party, parent directories and the current directory."]))),
descriptionDetails: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use this rule to group\n imports however you like, e.g. by first- vs. third-party or thematically or\n you can define groups based upon patterns in import path names."], ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use this rule to group\n imports however you like, e.g. by first- vs. third-party or thematically or\n you can define groups based upon patterns in import path names."]))),
hasFix: true,
optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n You may set the `\"import-sources-order\"` option to control the ordering of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"import-sources-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `\"Bar\"`, `\"baz\"`, `\"Foo\"`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `\"baz\"`, `\"Bar\"`, `\"Foo\"`.\n * `\"lowercase-last\"`: Correct order is `\"Bar\"`, `\"Foo\"`, `\"baz\"`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"grouped-imports\"` option to control the grouping of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"grouped-imports\"` are:\n\n * `false`: Do not enforce grouping. (This is the default.)\n * `true`: Group source imports by `\"bar\"`, `\"../baz\"`, `\"./foo\"`.\n\n You may set the `\"named-imports-order\"` option to control the ordering of named\n imports (the `{A, B, C}` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"named-imports-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `{A, b, C}`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `{b, A, C}`.\n * `\"lowercase-last\"`: Correct order is `{A, C, b}`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"module-source-path\"` option to control the ordering of imports based full path\n or just the module name\n\n Possible values for `\"module-source-path\"` are:\n\n * `\"full'`: Correct order is `\"./a/Foo\"`, `\"./b/baz\"`, `\"./c/Bar\"`. (This is the default.)\n * `\"basename\"`: Correct order is `\"./c/Bar\"`, `\"./b/baz\"`, `\"./a/Foo\"`.\n\n "], ["\n You may set the \\`\"import-sources-order\"\\` option to control the ordering of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"import-sources-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`\"Bar\"\\`, \\`\"baz\"\\`, \\`\"Foo\"\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`\"baz\"\\`, \\`\"Bar\"\\`, \\`\"Foo\"\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`\"Bar\"\\`, \\`\"Foo\"\\`, \\`\"baz\"\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"grouped-imports\"\\` option to control the grouping of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"grouped-imports\"\\` are:\n\n * \\`false\\`: Do not enforce grouping. (This is the default.)\n * \\`true\\`: Group source imports by \\`\"bar\"\\`, \\`\"../baz\"\\`, \\`\"./foo\"\\`.\n\n You may set the \\`\"named-imports-order\"\\` option to control the ordering of named\n imports (the \\`{A, B, C}\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"named-imports-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`{A, b, C}\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`{b, A, C}\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`{A, C, b}\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"module-source-path\"\\` option to control the ordering of imports based full path\n or just the module name\n\n Possible values for \\`\"module-source-path\"\\` are:\n\n * \\`\"full'\\`: Correct order is \\`\"./a/Foo\"\\`, \\`\"./b/baz\"\\`, \\`\"./c/Bar\"\\`. (This is the default.)\n * \\`\"basename\"\\`: Correct order is \\`\"./c/Bar\"\\`, \\`\"./b/baz\"\\`, \\`\"./a/Foo\"\\`.\n\n "]))),
optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n You may set the `\"import-sources-order\"` option to control the ordering of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"import-sources-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `\"Bar\"`, `\"baz\"`, `\"Foo\"`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `\"baz\"`, `\"Bar\"`, `\"Foo\"`.\n * `\"lowercase-last\"`: Correct order is `\"Bar\"`, `\"Foo\"`, `\"baz\"`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"grouped-imports\"` option to control the grouping of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`). The grouping used\n is controlled by the `\"groups\"` option.\n\n Possible values for `\"grouped-imports\"` are:\n\n * `false`: Do not enforce grouping. (This is the default.)\n * `true`: Group source imports using default grouping or groups setting.\n\n The value of `\"groups\"` is a list of group rules of the form:\n\n [{\n \"name\": \"optional rule name\",\n \"match\": \"regex string\",\n \"order\": 10\n }, {\n \"name\": \"pkga imports\",\n \"match\": \"^@pkga\",\n \"order\": 20\n }]\n\n there is also a simplified form where you only pass a list of patterns and\n the order is given by the position in the list\n\n [\"^@pkga\", \"^\\.\\.\"]\n\n The first rule in the list to match a given import is the group that is used.\n If no rule in matched then the import will be put in an `unmatched` group\n at the end of all groups. The groups must be ordered based upon the sequential\n value of the `order` value. (ie. order 0 is first)\n\n If no `\"groups\"` options is set, a default grouping is used of third-party,\n parent directories and the current directory. (`\"bar\"`, `\"../baz\"`, `\"./foo\"`.)\n\n You may set the `\"named-imports-order\"` option to control the ordering of named\n imports (the `{A, B, C}` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"named-imports-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `{A, b, C}`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `{b, A, C}`.\n * `\"lowercase-last\"`: Correct order is `{A, C, b}`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"module-source-path\"` option to control the ordering of imports based full path\n or just the module name\n\n Possible values for `\"module-source-path\"` are:\n\n * `\"full'`: Correct order is `\"./a/Foo\"`, `\"./b/baz\"`, `\"./c/Bar\"`. (This is the default.)\n * `\"basename\"`: Correct order is `\"./c/Bar\"`, `\"./b/baz\"`, `\"./a/Foo\"`.\n\n "], ["\n You may set the \\`\"import-sources-order\"\\` option to control the ordering of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"import-sources-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`\"Bar\"\\`, \\`\"baz\"\\`, \\`\"Foo\"\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`\"baz\"\\`, \\`\"Bar\"\\`, \\`\"Foo\"\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`\"Bar\"\\`, \\`\"Foo\"\\`, \\`\"baz\"\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"grouped-imports\"\\` option to control the grouping of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`). The grouping used\n is controlled by the \\`\"groups\"\\` option.\n\n Possible values for \\`\"grouped-imports\"\\` are:\n\n * \\`false\\`: Do not enforce grouping. (This is the default.)\n * \\`true\\`: Group source imports using default grouping or groups setting.\n\n The value of \\`\"groups\"\\` is a list of group rules of the form:\n\n [{\n \"name\": \"optional rule name\",\n \"match\": \"regex string\",\n \"order\": 10\n }, {\n \"name\": \"pkga imports\",\n \"match\": \"^@pkga\",\n \"order\": 20\n }]\n\n there is also a simplified form where you only pass a list of patterns and\n the order is given by the position in the list\n\n [\"^@pkga\", \"^\\\\.\\\\.\"]\n\n The first rule in the list to match a given import is the group that is used.\n If no rule in matched then the import will be put in an \\`unmatched\\` group\n at the end of all groups. The groups must be ordered based upon the sequential\n value of the \\`order\\` value. (ie. order 0 is first)\n\n If no \\`\"groups\"\\` options is set, a default grouping is used of third-party,\n parent directories and the current directory. (\\`\"bar\"\\`, \\`\"../baz\"\\`, \\`\"./foo\"\\`.)\n\n You may set the \\`\"named-imports-order\"\\` option to control the ordering of named\n imports (the \\`{A, B, C}\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"named-imports-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`{A, b, C}\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`{b, A, C}\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`{A, C, b}\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"module-source-path\"\\` option to control the ordering of imports based full path\n or just the module name\n\n Possible values for \\`\"module-source-path\"\\` are:\n\n * \\`\"full'\\`: Correct order is \\`\"./a/Foo\"\\`, \\`\"./b/baz\"\\`, \\`\"./c/Bar\"\\`. (This is the default.)\n * \\`\"basename\"\\`: Correct order is \\`\"./c/Bar\"\\`, \\`\"./b/baz\"\\`, \\`\"./a/Foo\"\\`.\n\n "]))),
options: {

@@ -45,2 +45,21 @@ type: "object",

},
groups: {
type: "list",
listType: {
oneOf: [
{
type: "string",
},
{
type: "object",
properties: {
name: { type: "string" },
match: { type: "string" },
order: { type: "number" },
},
required: ["match", "order"],
},
],
},
},
"import-sources-order": {

@@ -75,6 +94,5 @@ type: "string",

/* tslint:enable:object-literal-sort-keys */
Rule.IMPORT_SOURCES_NOT_GROUPED = "Import sources of different groups must be sorted by: libraries, parent directories, current directory.";
Rule.IMPORT_SOURCES_NOT_GROUPED_PREFIX = "Imports from this module are not allowed in this group. The expected groups (in order) are:";
Rule.IMPORT_SOURCES_UNORDERED = "Import sources within a group must be alphabetized.";
Rule.NAMED_IMPORTS_UNORDERED = "Named imports must be alphabetized.";
Rule.IMPORT_SOURCES_OF_SAME_TYPE_NOT_IN_ONE_GROUP = "Import sources of the same type (package, same folder, different folder) must be grouped together.";
return Rule;

@@ -103,15 +121,31 @@ }(Lint.Rules.AbstractRule));

]);
var ImportType;
(function (ImportType) {
ImportType[ImportType["LIBRARY_IMPORT"] = 1] = "LIBRARY_IMPORT";
ImportType[ImportType["PARENT_DIRECTORY_IMPORT"] = 2] = "PARENT_DIRECTORY_IMPORT";
ImportType[ImportType["CURRENT_DIRECTORY_IMPORT"] = 3] = "CURRENT_DIRECTORY_IMPORT";
})(ImportType || (ImportType = {}));
function parseOptions(ruleArguments) {
var optionSet = ruleArguments[0];
var _a = optionSet === undefined ? {} : optionSet, _b = _a["grouped-imports"], isGrouped = _b === void 0 ? false : _b, _c = _a["import-sources-order"], sources = _c === void 0 ? "case-insensitive" : _c, _d = _a["named-imports-order"], named = _d === void 0 ? "case-insensitive" : _d, _e = _a["module-source-path"], path = _e === void 0 ? "full" : _e;
// Use default groups to order by third-party, parent, local
var defaultGroups = [
{ name: "parent directories", match: "^\\.\\.", order: 20 },
{ name: "current directory", match: "^\\.", order: 30 },
{ name: "libraries", match: ".*", order: 10 },
];
var _a = optionSet === undefined ? {} : optionSet, _b = _a["grouped-imports"], isGrouped = _b === void 0 ? false : _b, _c = _a["import-sources-order"], sources = _c === void 0 ? "case-insensitive" : _c, _d = _a["named-imports-order"], named = _d === void 0 ? "case-insensitive" : _d, _e = _a["module-source-path"], path = _e === void 0 ? "full" : _e, _f = _a.groups, groups = _f === void 0 ? defaultGroups : _f;
// build up list of compiled groups
// - handle case where "group" is just a string pattern
// vs a full group object
var compiledGroups = groups.map(function (g, idx) {
if (typeof g === "string") {
return { name: "/" + g + "/", match: new RegExp(g), order: idx };
}
else {
return {
match: new RegExp(g.match),
name: g.name !== undefined ? g.name : "/" + g.match + "/",
order: g.order,
};
}
});
return {
groupedImports: isGrouped,
groups: compiledGroups,
importSourcesOrderTransform: TRANSFORMS.get(sources),
moduleSourcePath: TRANSFORMS.get(path),
moduleSourceTransform: TRANSFORMS.get(path),
namedImportsOrderTransform: TRANSFORMS.get(named),

@@ -125,3 +159,8 @@ };

_this.importsBlocks = [new ImportsBlock()];
_this.nextType = ImportType.LIBRARY_IMPORT;
// group to use when no other group matches
_this.defaultGroup = {
match: /.*/,
name: "unmatched",
order: Number.MAX_SAFE_INTEGER,
};
return _this;

@@ -137,2 +176,4 @@ }

Walker.prototype.walk = function (sourceFile) {
// Walk through all statements checking import statements
// and building up ImportsBlocks along the way (with replacements)
for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) {

@@ -143,2 +184,3 @@ var statement = _a[_i];

this.endBlock();
// Optionally check the ImportsBlocks for grouping
if (this.options.groupedImports) {

@@ -171,2 +213,3 @@ this.checkBlocksGrouping();

Walker.prototype.checkImportDeclaration = function (node) {
// ex: import {name1, name2 } from 'import/path';
if (!tsutils_1.isStringLiteral(node.moduleSpecifier)) {

@@ -176,4 +219,5 @@ // Ignore grammar error

}
var source = removeQuotes(node.moduleSpecifier.text);
this.checkSource(source, node);
var importPath = removeQuotes(node.moduleSpecifier.text);
this.checkImport(importPath, node);
// check the names in the import are ordered correctly
var importClause = node.importClause;

@@ -196,12 +240,17 @@ if (importClause !== undefined &&

}
var source = removeQuotes(expression.text);
this.checkSource(source, node);
var importPath = removeQuotes(expression.text);
this.checkImport(importPath, node);
};
Walker.prototype.checkSource = function (originalSource, node) {
var type = getImportType(originalSource);
var source = this.options.importSourcesOrderTransform(originalSource);
var currentSource = this.options.moduleSourcePath(source);
var previousSource = this.currentImportsBlock.getLastImportSource();
this.currentImportsBlock.addImportDeclaration(this.sourceFile, node, currentSource, type);
if (previousSource !== null && compare(currentSource, previousSource) === -1) {
/**
* Check the given import to see if we have valid import ordering.
*/
Walker.prototype.checkImport = function (fullImportPath, node) {
// from this point forward we use the transformed import paths
// - group lookup is based upon the full import path with no transform
var matchingGroup = this.getMatchingGroup(fullImportPath);
// determine the module name to use for sorting after the required transforms
var importPath = this.options.importSourcesOrderTransform(this.options.moduleSourceTransform(fullImportPath));
var prevImportPath = this.currentImportsBlock.getLastImportSource();
this.currentImportsBlock.addImportDeclaration(this.sourceFile, node, importPath, matchingGroup);
if (prevImportPath !== null && compare(importPath, prevImportPath) === -1) {
this.lastFix = [];

@@ -221,2 +270,7 @@ this.addFailureAtNode(node, Rule.IMPORT_SOURCES_UNORDERED, this.lastFix);

};
/**
* Check that names within the given import are ordered correctly as required.
* If not, adds a failure and updates import blocks with correct order
* for replacement.
*/
Walker.prototype.checkNamedImports = function (node) {

@@ -242,54 +296,62 @@ var _this = this;

};
/**
* Check all import blocks stopping at the first failure.
*/
Walker.prototype.checkBlocksGrouping = function () {
this.checkBlocksUniqueness();
this.importsBlocks.some(this.checkBlockGroups, this);
};
Walker.prototype.checkBlocksUniqueness = function () {
var _this = this;
var typesEncountered = new Map([
[ImportType.LIBRARY_IMPORT, false],
[ImportType.PARENT_DIRECTORY_IMPORT, false],
[ImportType.CURRENT_DIRECTORY_IMPORT, false],
]);
var nonEmptyBlocks = this.importsBlocks.filter(function (block) { return block.getImportDeclarations().length > 0; });
nonEmptyBlocks.forEach(function (block) {
// assume the whole block is of the same type, hence use the first one as the representing one
var firstInBlock = block.getImportDeclarations()[0];
if (typesEncountered.get(firstInBlock.type)) {
_this.addFailureAtNode(firstInBlock.node, Rule.IMPORT_SOURCES_OF_SAME_TYPE_NOT_IN_ONE_GROUP);
var prevBlockOrder = Number.MIN_SAFE_INTEGER;
var addFailingImportDecl = function (decl) {
var groupsMsg = _this.options.groups.slice().sort(function (a, b) { return a.order - b.order; })
.map(function (g) { return g.name; })
.join(", ");
var msg = Rule.IMPORT_SOURCES_NOT_GROUPED_PREFIX + " " + groupsMsg + ".";
_this.addFailureAtNode(decl.node, msg, _this.getGroupOrderReplacements());
};
var blocksWithContent = this.importsBlocks.filter(function (b) { return b.getImportDeclarations().length > 0; });
// Check if each block is out of order
for (var _i = 0, blocksWithContent_1 = blocksWithContent; _i < blocksWithContent_1.length; _i++) {
var block = blocksWithContent_1[_i];
var importDeclarations = block.getImportDeclarations();
var blockOrder = importDeclarations[0].group.order;
// check if group is out of order
if (blockOrder <= prevBlockOrder) {
addFailingImportDecl(importDeclarations[0]);
return;
}
else {
typesEncountered.set(firstInBlock.type, true);
// check if all declarations have the same order value
// and mark the first one that is out of order
for (var _a = 0, importDeclarations_1 = importDeclarations; _a < importDeclarations_1.length; _a++) {
var decl = importDeclarations_1[_a];
if (decl.group.order !== blockOrder) {
addFailingImportDecl(decl);
return;
}
}
});
};
Walker.prototype.checkBlockGroups = function (importsBlock) {
var oddImportDeclaration = this.getOddImportDeclaration(importsBlock);
if (oddImportDeclaration !== undefined) {
this.addFailureAtNode(oddImportDeclaration.node, Rule.IMPORT_SOURCES_NOT_GROUPED, this.getReplacements());
return true;
prevBlockOrder = blockOrder;
}
return false;
};
Walker.prototype.getOddImportDeclaration = function (importsBlock) {
var importDeclarations = importsBlock.getImportDeclarations();
if (importDeclarations.length === 0) {
return undefined;
/**
* Return the first import group pattern matching the given import path.
*/
Walker.prototype.getMatchingGroup = function (importPath) {
// find the first matching group.
for (var _i = 0, _a = this.options.groups; _i < _a.length; _i++) {
var group = _a[_i];
if (group.match.test(importPath)) {
return group;
}
}
var type = importDeclarations[0].type;
if (type < this.nextType) {
return importDeclarations[0];
}
else {
this.nextType = type;
return importDeclarations.find(function (importDeclaration) { return importDeclaration.type !== type; });
}
return this.defaultGroup;
};
Walker.prototype.getReplacements = function () {
/**
* Build up replaces to remove all imports and replace with grouped and sorted imports.
*/
Walker.prototype.getGroupOrderReplacements = function () {
var _a;
var importDeclarationsList = this.importsBlocks
// Get all import declarations for all ImportBlocks groups that are not empty
var groupedDeclarations = this.importsBlocks
.map(function (block) { return block.getImportDeclarations(); })
.filter(function (imports) { return imports.length > 0; });
var allImportDeclarations = (_a = []).concat.apply(_a, importDeclarationsList);
var replacements = this.getReplacementsForExistingImports(importDeclarationsList);
var replacements = this.getGroupRemovalReplacements(groupedDeclarations);
var allImportDeclarations = (_a = []).concat.apply(_a, groupedDeclarations);
var startOffset = allImportDeclarations.length === 0 ? 0 : allImportDeclarations[0].nodeStartOffset;

@@ -299,8 +361,11 @@ replacements.push(Lint.Replacement.appendText(startOffset, this.getGroupedImports(allImportDeclarations)));

};
Walker.prototype.getReplacementsForExistingImports = function (importDeclarationsList) {
/**
* Get set of replacements that delete all existing imports.
*/
Walker.prototype.getGroupRemovalReplacements = function (groupedDeclarations) {
var _this = this;
return importDeclarationsList.map(function (items, index) {
return groupedDeclarations.map(function (items, index) {
var start = items[0].nodeStartOffset;
if (index > 0) {
var prevItems = importDeclarationsList[index - 1];
var prevItems = groupedDeclarations[index - 1];
var last = prevItems[prevItems.length - 1];

@@ -315,10 +380,14 @@ if (/[\r\n]+/.test(_this.sourceFile.text.slice(last.nodeEndOffset, start))) {

};
/**
* Get text of new set of grouped and sorted imports as text.
*/
Walker.prototype.getGroupedImports = function (importDeclarations) {
return [
ImportType.LIBRARY_IMPORT,
ImportType.PARENT_DIRECTORY_IMPORT,
ImportType.CURRENT_DIRECTORY_IMPORT,
]
.map(function (type) {
var imports = importDeclarations.filter(function (importDeclaration) { return importDeclaration.type === type; });
// list of all unique order values in sorted order
var orderValues = importDeclarations
.map(function (decl) { return decl.group.order; })
.filter(function (v, i, a) { return a.indexOf(v) === i; })
.sort(function (a, b) { return a - b; });
return orderValues
.map(function (curOrder) {
var imports = importDeclarations.filter(function (i) { return i.group.order === curOrder; });
return getSortedImportDeclarationsAsText(imports);

@@ -329,2 +398,5 @@ })

};
/**
* Return the type of newline that should be used in the codebase.
*/
Walker.prototype.getEolChar = function () {

@@ -345,2 +417,6 @@ var lineEnd = this.sourceFile.getLineEndOfPosition(0);

}(Lint.AbstractWalker));
/**
* Wrapper around a set of imports grouped together in a sequence (block)
* in the source code.
*/
var ImportsBlock = /** @class */ (function () {

@@ -350,3 +426,6 @@ function ImportsBlock() {

}
ImportsBlock.prototype.addImportDeclaration = function (sourceFile, node, sourcePath, type) {
/**
* Add a new import declaration to the block
*/
ImportsBlock.prototype.addImportDeclaration = function (sourceFile, node, importPath, group) {
var start = this.getStartOffset(node);

@@ -361,8 +440,8 @@ var end = this.getEndOffset(sourceFile, node);

this.importDeclarations.push({
group: group,
importPath: importPath,
node: node,
nodeEndOffset: end,
nodeStartOffset: start,
sourcePath: sourcePath,
text: text,
type: type,
});

@@ -373,3 +452,7 @@ };

};
// replaces the named imports on the most recent import declaration
/**
* Replaces the named imports on the most recent import declaration.
* Updates the imports in place so the getReplacement method below can
* return full fixes for the entire import block.
*/
ImportsBlock.prototype.replaceNamedImports = function (fileOffset, length, replacement) {

@@ -389,2 +472,5 @@ var importDeclaration = this.getLastImportDeclaration();

};
/**
* Return the source path of the most recently added import.
*/
ImportsBlock.prototype.getLastImportSource = function () {

@@ -394,5 +480,7 @@ if (this.importDeclarations.length === 0) {

}
return this.getLastImportDeclaration().sourcePath;
return this.getLastImportDeclaration().importPath;
};
// creates a Lint.Replacement object with ordering fixes for the entire block
/**
* Return a Lint.Replacement object with ordering fixes for the entire block.
*/
ImportsBlock.prototype.getReplacement = function () {

@@ -423,15 +511,2 @@ if (this.importDeclarations.length === 0) {

}());
function getImportType(sourcePath) {
if (sourcePath.charAt(0) === ".") {
if (sourcePath.charAt(1) === ".") {
return ImportType.PARENT_DIRECTORY_IMPORT;
}
else {
return ImportType.CURRENT_DIRECTORY_IMPORT;
}
}
else {
return ImportType.LIBRARY_IMPORT;
}
}
// Convert aBcD --> AbCd

@@ -487,3 +562,3 @@ function flipCase(str) {

function getSortedImportDeclarationsAsText(importDeclarations) {
var sortedDeclarations = sortByKey(importDeclarations.slice(), function (x) { return x.sourcePath; });
var sortedDeclarations = sortByKey(importDeclarations.slice(), function (x) { return x.importPath; });
return sortedDeclarations.map(function (x) { return x.text; }).join("");

@@ -490,0 +565,0 @@ }

@@ -20,5 +20,5 @@ "use strict";

var tslib_1 = require("tslib");
var utils = require("tsutils");
var ts = require("typescript");
var Lint = require("../index");
var utils = require("tsutils");
var OPTION_DESTRUCTURING_ALL = "all";

@@ -25,0 +25,0 @@ var OPTION_DESTRUCTURING_ANY = "any";

@@ -80,3 +80,3 @@ "use strict";

],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -83,0 +83,0 @@ };

@@ -73,3 +73,3 @@ "use strict";

],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -76,0 +76,0 @@ };

@@ -30,3 +30,4 @@ "use strict";

var OPTION_ALLOW_BOOLEAN_OR_UNDEFINED = "allow-boolean-or-undefined";
// tslint:disable object-literal-sort-keys
var OPTION_IGNORE_RHS = "ignore-rhs";
// tslint:disable object-literal-sort-keys no-bitwise
var Rule = /** @class */ (function (_super) {

@@ -44,3 +45,3 @@ tslib_1.__extends(Rule, _super);

description: Lint.Utils.dedent(templateObject_1 || (templateObject_1 = tslib_1.__makeTemplateObject(["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the `!`, `&&`, and `||` operators\n * The condition in a conditional expression (`cond ? x : y`)\n * Conditions for `if`, `for`, `while`, and `do-while` statements."], ["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the \\`!\\`, \\`&&\\`, and \\`||\\` operators\n * The condition in a conditional expression (\\`cond ? x : y\\`)\n * Conditions for \\`if\\`, \\`for\\`, \\`while\\`, and \\`do-while\\` statements."]))),
optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n These options may be provided:\n\n * `", "` allows union types containing `null`.\n - It does *not* allow `null` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows union types containing `undefined`.\n - It does *not* allow `undefined` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows strings.\n - It does *not* allow unions containing `string`.\n - It does *not* allow string literal types.\n * `", "` allows enums.\n - It does *not* allow unions containing `enum`.\n * `", "` allows numbers.\n - It does *not* allow unions containing `number`.\n - It does *not* allow enums or number literal types.\n * `", "` allows multiple of the above to appear together.\n - For example, `string | number` or `RegExp | null | undefined` would normally not be allowed.\n - A type like `\"foo\" | \"bar\" | undefined` is always allowed, because it has only one way to be false.\n * `", "` allows `boolean | undefined`.\n - Also allows `true | false | undefined`.\n - Does not allow `false | undefined`.\n - This option is a subset of `", "`, so you don't need to enable both options at the same time.\n "], ["\n These options may be provided:\n\n * \\`", "\\` allows union types containing \\`null\\`.\n - It does *not* allow \\`null\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows union types containing \\`undefined\\`.\n - It does *not* allow \\`undefined\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows strings.\n - It does *not* allow unions containing \\`string\\`.\n - It does *not* allow string literal types.\n * \\`", "\\` allows enums.\n - It does *not* allow unions containing \\`enum\\`.\n * \\`", "\\` allows numbers.\n - It does *not* allow unions containing \\`number\\`.\n - It does *not* allow enums or number literal types.\n * \\`", "\\` allows multiple of the above to appear together.\n - For example, \\`string | number\\` or \\`RegExp | null | undefined\\` would normally not be allowed.\n - A type like \\`\"foo\" | \"bar\" | undefined\\` is always allowed, because it has only one way to be false.\n * \\`", "\\` allows \\`boolean | undefined\\`.\n - Also allows \\`true | false | undefined\\`.\n - Does not allow \\`false | undefined\\`.\n - This option is a subset of \\`", "\\`, so you don't need to enable both options at the same time.\n "])), OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_ENUM, OPTION_ALLOW_NUMBER, OPTION_ALLOW_MIX, OPTION_ALLOW_BOOLEAN_OR_UNDEFINED, OPTION_ALLOW_UNDEFINED_UNION),
optionsDescription: Lint.Utils.dedent(templateObject_2 || (templateObject_2 = tslib_1.__makeTemplateObject(["\n These options may be provided:\n\n * `", "` allows union types containing `null`.\n - It does *not* allow `null` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows union types containing `undefined`.\n - It does *not* allow `undefined` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows strings.\n - It does *not* allow unions containing `string`.\n - It does *not* allow string literal types.\n * `", "` allows enums.\n - It does *not* allow unions containing `enum`.\n * `", "` allows numbers.\n - It does *not* allow unions containing `number`.\n - It does *not* allow enums or number literal types.\n * `", "` allows multiple of the above to appear together.\n - For example, `string | number` or `RegExp | null | undefined` would normally not be allowed.\n - A type like `\"foo\" | \"bar\" | undefined` is always allowed, because it has only one way to be false.\n * `", "` allows `boolean | undefined`.\n - Also allows `true | false | undefined`.\n - Does not allow `false | undefined`.\n - This option is a subset of `", "`, so you don't need to enable both options at the same time.\n * `", "` ignores the right-hand operand of `&&` and `||'\n "], ["\n These options may be provided:\n\n * \\`", "\\` allows union types containing \\`null\\`.\n - It does *not* allow \\`null\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows union types containing \\`undefined\\`.\n - It does *not* allow \\`undefined\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows strings.\n - It does *not* allow unions containing \\`string\\`.\n - It does *not* allow string literal types.\n * \\`", "\\` allows enums.\n - It does *not* allow unions containing \\`enum\\`.\n * \\`", "\\` allows numbers.\n - It does *not* allow unions containing \\`number\\`.\n - It does *not* allow enums or number literal types.\n * \\`", "\\` allows multiple of the above to appear together.\n - For example, \\`string | number\\` or \\`RegExp | null | undefined\\` would normally not be allowed.\n - A type like \\`\"foo\" | \"bar\" | undefined\\` is always allowed, because it has only one way to be false.\n * \\`", "\\` allows \\`boolean | undefined\\`.\n - Also allows \\`true | false | undefined\\`.\n - Does not allow \\`false | undefined\\`.\n - This option is a subset of \\`", "\\`, so you don't need to enable both options at the same time.\n * \\`", "\\` ignores the right-hand operand of \\`&&\\` and \\`||\\'\n "])), OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_ENUM, OPTION_ALLOW_NUMBER, OPTION_ALLOW_MIX, OPTION_ALLOW_BOOLEAN_OR_UNDEFINED, OPTION_ALLOW_UNDEFINED_UNION, OPTION_IGNORE_RHS),
options: {

@@ -57,6 +58,7 @@ type: "array",

OPTION_ALLOW_BOOLEAN_OR_UNDEFINED,
OPTION_IGNORE_RHS,
],
},
minLength: 0,
maxLength: 5,
maxLength: 7,
},

@@ -92,2 +94,3 @@ optionExamples: [

allowBooleanOrUndefined: has(OPTION_ALLOW_BOOLEAN_OR_UNDEFINED),
ignoreRhs: has(OPTION_IGNORE_RHS),
};

@@ -103,13 +106,18 @@ function has(name) {

case ts.SyntaxKind.BinaryExpression: {
var b_1 = node;
if (binaryBooleanExpressionKind(b_1) !== undefined) {
var left = b_1.left, right = b_1.right;
var checkHalf = function (expr) {
// If it's another boolean binary expression, we'll check it when recursing.
if (!isBooleanBinaryExpression(expr)) {
checkExpression(expr, b_1);
}
};
checkHalf(left);
checkHalf(right);
var b = node;
if (binaryBooleanExpressionKind(b) !== undefined) {
var left = b.left, right = b.right;
// If ignore-rhs is off, we don't have to analyze a boolean binary expression
// on the left side because it will be checked well enough on its own. However,
// if ignore-rhs is on, we have to analyze the overall result of the left
// side no matter what, because its right side might not follow the rules.
if (options.ignoreRhs || !isBooleanBinaryExpression(left)) {
checkExpression(left, b);
}
// If ignore-rhs is on, we don't have to analyze the right hand side
// We also don't have to analyze the right hand side if it is also a
// boolean binary expression; its own inner check is sufficient.
if (!(options.ignoreRhs || isBooleanBinaryExpression(right))) {
checkExpression(right, b);
}
}

@@ -173,3 +181,2 @@ break;

// Allow 'any'. Allow 'true' itself, but not any other always-truthy type.
// tslint:disable-next-line no-bitwise
return tsutils_1.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.BooleanLiteral)

@@ -290,20 +297,19 @@ ? undefined

? 6 /* Null */
: // tslint:disable-next-line:no-bitwise
is(ts.TypeFlags.Undefined | ts.TypeFlags.Void)
? 7 /* Undefined */
: is(ts.TypeFlags.EnumLike)
? 8 /* Enum */
: is(ts.TypeFlags.NumberLiteral)
? numberLiteralIsZero(type)
? 3 /* FalseNumberLiteral */
: is(ts.TypeFlags.Undefined | ts.TypeFlags.Void)
? 7 /* Undefined */
: is(ts.TypeFlags.EnumLike)
? 8 /* Enum */
: is(ts.TypeFlags.NumberLiteral)
? numberLiteralIsZero(type)
? 3 /* FalseNumberLiteral */
: 9 /* AlwaysTruthy */
: is(ts.TypeFlags.StringLiteral)
? stringLiteralIsEmpty(type)
? 1 /* FalseStringLiteral */
: 9 /* AlwaysTruthy */
: is(ts.TypeFlags.StringLiteral)
? stringLiteralIsEmpty(type)
? 1 /* FalseStringLiteral */
: 9 /* AlwaysTruthy */
: is(ts.TypeFlags.BooleanLiteral)
? type.intrinsicName === "true"
? 9 /* AlwaysTruthy */
: 5 /* FalseBooleanLiteral */
: 9 /* AlwaysTruthy */;
: is(ts.TypeFlags.BooleanLiteral)
? type.intrinsicName === "true"
? 9 /* AlwaysTruthy */
: 5 /* FalseBooleanLiteral */
: 9 /* AlwaysTruthy */;
function is(flags) {

@@ -310,0 +316,0 @@ return tsutils_1.isTypeFlagSet(type, flags);

@@ -103,3 +103,3 @@ "use strict";

],
type: "maintainability",
type: "formatting",
typescriptOnly: false,

@@ -169,3 +169,6 @@ };

case ts.SyntaxKind.CallSignature:
_this.checkList(node.parameters, tsutils_1.getChildOfKind(node, ts.SyntaxKind.CloseParenToken, _this.sourceFile).end, "functions", isRestParameter);
var closingParen = tsutils_1.getChildOfKind(node, ts.SyntaxKind.CloseParenToken, _this.sourceFile);
if (closingParen !== undefined) {
_this.checkList(node.parameters, closingParen.end, "functions", isRestParameter);
}
break;

@@ -172,0 +175,0 @@ case ts.SyntaxKind.TypeLiteral:

@@ -85,3 +85,3 @@ "use strict";

],
type: "typescript",
type: "formatting",
typescriptOnly: true,

@@ -88,0 +88,0 @@ hasFix: true,

@@ -70,3 +70,3 @@ "use strict";

optionExamples: [[true, "check-branch", "check-operator", "check-typecast"]],
type: "style",
type: "formatting",
typescriptOnly: false,

@@ -73,0 +73,0 @@ hasFix: true,

@@ -23,2 +23,4 @@ "use strict";

var fs = require("fs");
var mkdirp = require("mkdirp");
var path = require("path");
var linter_1 = require("./linter");

@@ -181,5 +183,7 @@ var runner_1 = require("./runner");

}
var outputStream = argv.out === undefined
? process.stdout
: fs.createWriteStream(argv.out, { flags: "w+", mode: 420 });
var outputStream = process.stdout;
if (argv.out !== undefined) {
mkdirp.sync(path.dirname(argv.out));
outputStream = fs.createWriteStream(argv.out, { flags: "w+", mode: 420 });
}
runner_1.run({

@@ -186,0 +190,0 @@ config: argv.config,

@@ -72,4 +72,12 @@ /**

/**
* Gets the full indentation of the provided node
*/
export declare function getIndentation(node: ts.Node, sourceFile: ts.SourceFile): string;
/**
* Creates x new lines with a proper indentation at the last one based on the provided node
*/
export declare function newLineWithIndentation(node: ts.Node, sourceFile: ts.SourceFile, linesCount?: number): string;
/**
* @deprecated Copied from tsutils 2.27.2. This will be removed once TSLint requires tsutils > 3.0.
*/
export declare function isFunctionScopeBoundary(node: ts.Node): boolean;

@@ -279,2 +279,21 @@ "use strict";

/**
* Gets the full indentation of the provided node
*/
function getIndentation(node, sourceFile) {
var text = sourceFile.text.substr(node.pos, node.getStart() - node.pos);
var matches = text.match(/([ \t]*)$/);
return matches !== null ? matches[1] : "";
}
exports.getIndentation = getIndentation;
/**
* Creates x new lines with a proper indentation at the last one based on the provided node
*/
function newLineWithIndentation(node, sourceFile, linesCount) {
if (linesCount === void 0) { linesCount = 1; }
var maybeCarriageReturn = sourceFile.text[sourceFile.getLineEndOfPosition(node.pos) - 1] === "\r" ? "\r" : "";
var indentation = getIndentation(node, sourceFile);
return "" + (maybeCarriageReturn + "\n").repeat(linesCount) + indentation;
}
exports.newLineWithIndentation = newLineWithIndentation;
/**
* @deprecated Copied from tsutils 2.27.2. This will be removed once TSLint requires tsutils > 3.0.

@@ -281,0 +300,0 @@ */

{
"name": "tslint",
"version": "5.12.1",
"version": "5.13.0",
"description": "An extensible static analysis linter for the TypeScript language",

@@ -10,12 +10,2 @@ "bin": {

"typings": "./lib/index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/palantir/tslint.git"
},
"keywords": [
"cli",
"typescript",
"linter"
],
"homepage": "https://palantir.github.io/tslint",
"scripts": {

@@ -31,7 +21,4 @@ "clean": "npm-run-all -p clean:core clean:test",

"lint": "npm-run-all -p lint:global lint:from-bin",
"lint:global": "tslint --project test/tsconfig.json --format stylish",
"lint:from-bin": "node bin/tslint --project test/tsconfig.json --format stylish",
"precommit": "npm-run-all precommit:prettier",
"precommit:prettier": "pretty-quick --staged",
"prettier": "prettier --write './**/*.{js,ts,css,scss,md,yml}' --ignore-path ./.prettierignore",
"lint:global": "tslint --project test/tsconfig.json --format codeFrame",
"lint:from-bin": "node bin/tslint --project test/tsconfig.json --format codeFrame",
"publish:local": "./scripts/npmPublish.sh",

@@ -54,2 +41,3 @@ "test": "npm-run-all test:pre -p test:mocha test:rules",

"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"resolve": "^1.3.2",

@@ -61,3 +49,3 @@ "semver": "^5.3.0",

"peerDependencies": {
"typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev"
"typescript": ">=2.1.0 || >=2.1.0-dev || >=2.2.0-dev || >=2.3.0-dev || >=2.4.0-dev || >=2.5.0-dev || >=2.6.0-dev || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev || >= 3.1.0-dev || >= 3.2.0-dev"
},

@@ -71,2 +59,3 @@ "devDependencies": {

"@types/minimatch": "^2.0.29",
"@types/mkdirp": "^0.5.2",
"@types/mocha": "^2.2.35",

@@ -85,14 +74,24 @@ "@types/node": "^7.0.29",

"prettier": "1.14.3",
"pretty-quick": "^1.6.0",
"rimraf": "^2.5.4",
"ts-node": "^3.3.0",
"tslint": "^5.8.0",
"tslint-config-prettier": "^1.13.0",
"tslint": "~5.12.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^2.0.1",
"tslint-test-config-non-relative": "file:test/external/tslint-test-config-non-relative",
"typescript": "~3.1.6"
},
"license": "Apache-2.0",
"engines": {
"node": ">=4.8.0"
}
},
"homepage": "https://palantir.github.io/tslint",
"repository": {
"type": "git",
"url": "https://github.com/palantir/tslint.git"
},
"keywords": [
"cli",
"typescript",
"linter"
],
"license": "Apache-2.0"
}

@@ -20,3 +20,3 @@ [![NPM version](https://badge.fury.io/js/tslint.svg)](http://badge.fury.io/js/tslint)

- automatic fixing of formatting & style violations
- integration with [MSBuild](https://github.com/joshuakgoldberg/tslint.msbuild), [Grunt](https://github.com/palantir/grunt-tslint), [Gulp](https://github.com/panuhorsmalahti/gulp-tslint), [Atom](https://github.com/AtomLinter/linter-tslint), [Eclipse](https://github.com/palantir/eclipse-tslint), [Emacs](http://flycheck.org), [Sublime](https://packagecontrol.io/packages/SublimeLinter-contrib-tslint), [Vim](https://github.com/scrooloose/syntastic), [Visual Studio 2015](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebAnalyzer), [Visual Studio 2017](https://marketplace.visualstudio.com/items?itemName=RichNewman.TypeScriptAnalyzer), [Visual Studio code](https://marketplace.visualstudio.com/items?itemName=eg2.tslint), [WebStorm](https://www.jetbrains.com/webstorm/help/tslint.html) and [more](https://palantir.github.io/tslint/usage/third-party-tools/)
- integration with [MSBuild](https://github.com/joshuakgoldberg/tslint.msbuild), [Grunt](https://github.com/palantir/grunt-tslint), [Gulp](https://github.com/panuhorsmalahti/gulp-tslint), [Atom](https://github.com/AtomLinter/linter-tslint), [Eclipse](https://github.com/palantir/eclipse-tslint), [Emacs](https://www.flycheck.org/), [Sublime](https://packagecontrol.io/packages/SublimeLinter-contrib-tslint), [Vim](https://github.com/scrooloose/syntastic), [Visual Studio 2015](https://marketplace.visualstudio.com/items?itemName=MadsKristensen.WebAnalyzer), [Visual Studio 2017](https://marketplace.visualstudio.com/items?itemName=RichNewman.TypeScriptAnalyzer), [Visual Studio code](https://marketplace.visualstudio.com/items?itemName=eg2.tslint), [WebStorm](https://www.jetbrains.com/webstorm/help/tslint.html) and [more](https://palantir.github.io/tslint/usage/third-party-tools/)

@@ -23,0 +23,0 @@ ## Installation & Usage

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc