@definitelytyped/eslint-plugin 0.0.186 → 0.0.188
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/configs/all.js +1 -0
- package/dist/configs/all.js.map +1 -1
- package/dist/rules/index.d.ts +1 -1
- package/dist/rules/no-bad-reference.d.ts +1 -1
- package/dist/rules/no-bad-reference.js +172 -28
- package/dist/rules/no-bad-reference.js.map +1 -1
- package/dist/rules/no-declare-current-package.js +4 -1
- package/dist/rules/no-declare-current-package.js.map +1 -1
- package/dist/rules/no-import-default-of-export-equals.js +4 -3
- package/dist/rules/no-import-default-of-export-equals.js.map +1 -1
- package/dist/rules/no-import-of-dev-dependencies.js +32 -60
- package/dist/rules/no-import-of-dev-dependencies.js.map +1 -1
- package/dist/rules/no-old-dt-header.js +2 -1
- package/dist/rules/no-old-dt-header.js.map +1 -1
- package/dist/rules/no-relative-import-in-test.js +2 -3
- package/dist/rules/no-relative-import-in-test.js.map +1 -1
- package/dist/rules/no-self-import.js +3 -0
- package/dist/rules/no-self-import.js.map +1 -1
- package/dist/rules/prefer-declare-function.js +2 -1
- package/dist/rules/prefer-declare-function.js.map +1 -1
- package/dist/util.d.ts +15 -0
- package/dist/util.js +50 -8
- package/dist/util.js.map +1 -1
- package/package.json +2 -2
- package/src/configs/all.ts +1 -0
- package/src/rules/no-bad-reference.ts +176 -33
- package/src/rules/no-declare-current-package.ts +4 -1
- package/src/rules/no-import-default-of-export-equals.ts +2 -1
- package/src/rules/no-import-of-dev-dependencies.ts +40 -59
- package/src/rules/no-old-dt-header.ts +2 -1
- package/src/rules/no-relative-import-in-test.ts +2 -5
- package/src/rules/no-self-import.ts +3 -0
- package/src/rules/prefer-declare-function.ts +2 -1
- package/src/util.ts +69 -9
- package/test/fixtureTester.ts +64 -0
- package/test/fixtures/notNeededPackages.json +3 -0
- package/test/fixtures/package.json +4 -0
- package/test/fixtures/types/foo/foo-tests.ts +0 -0
- package/test/fixtures/types/foo/index.d.ts +1 -0
- package/test/fixtures/types/foo/package.json +5 -0
- package/test/fixtures/types/foo/tsconfig.json +20 -0
- package/test/fixtures/types/foo/v1/foo-tests.ts +0 -0
- package/test/fixtures/types/foo/v1/index.d.ts +1 -0
- package/test/fixtures/types/foo/v1/package.json +5 -0
- package/test/fixtures/types/foo/v1/tsconfig.json +20 -0
- package/test/fixtures/types/no-bad-reference/index.d.ts +16 -0
- package/test/fixtures/types/no-bad-reference/no-bad-reference-tests.ts +2 -0
- package/test/fixtures/types/no-bad-reference/package.json +5 -0
- package/test/fixtures/types/no-bad-reference/tsconfig.json +20 -0
- package/test/fixtures/types/no-bad-reference/v0.1/index.d.ts +15 -0
- package/test/fixtures/types/no-bad-reference/v0.1/no-bad-reference-tests.ts +0 -0
- package/test/fixtures/types/no-bad-reference/v0.1/package.json +5 -0
- package/test/fixtures/types/no-bad-reference/v0.1/tsconfig.json +20 -0
- package/test/fixtures/types/no-bad-reference/v11/index.d.ts +15 -0
- package/test/fixtures/types/no-bad-reference/v11/no-bad-reference-tests.ts +0 -0
- package/test/fixtures/types/no-bad-reference/v11/package.json +5 -0
- package/test/fixtures/types/no-bad-reference/v11/tsconfig.json +20 -0
- package/test/fixtures/types/no-declare-current-package/index.d.ts +1 -0
- package/test/fixtures/types/no-declare-current-package/no-declare-current-package-tests.ts +0 -0
- package/test/fixtures/types/no-declare-current-package/package.json +8 -0
- package/test/fixtures/types/no-declare-current-package/test/deep/import.d.ts +1 -0
- package/test/fixtures/types/no-declare-current-package/tsconfig.json +20 -0
- package/test/fixtures/types/no-declare-current-package-other/index.d.ts +2 -0
- package/test/fixtures/types/no-declare-current-package-other/no-declare-current-package-other-tests.ts +0 -0
- package/test/fixtures/types/no-declare-current-package-other/package.json +8 -0
- package/test/fixtures/types/no-declare-current-package-other/tsconfig.json +20 -0
- package/test/fixtures/types/no-import-of-dev-dependencies/bad.d.ts +5 -0
- package/test/fixtures/types/no-import-of-dev-dependencies/index.d.ts +4 -0
- package/test/fixtures/types/no-import-of-dev-dependencies/no-import-of-dev-dependencies-tests.ts +9 -0
- package/test/fixtures/types/no-import-of-dev-dependencies/package.json +14 -0
- package/test/fixtures/types/no-import-of-dev-dependencies/tsconfig.json +20 -0
- package/test/fixtures/types/no-relative-references/index.d.ts +12 -0
- package/test/fixtures/types/no-relative-references/no-relative-references-tests.ts +0 -0
- package/test/fixtures/types/no-relative-references/other/other.d.ts +7 -0
- package/test/fixtures/types/no-relative-references/package.json +5 -0
- package/test/fixtures/types/no-relative-references/tsconfig.json +20 -0
- package/test/fixtures/types/no-relative-references/v1/index.d.ts +15 -0
- package/test/fixtures/types/no-relative-references/v1/no-relative-references-tests.ts +0 -0
- package/test/fixtures/types/no-relative-references/v1/other/other.d.ts +7 -0
- package/test/fixtures/types/no-relative-references/v1/package.json +5 -0
- package/test/fixtures/types/no-relative-references/v1/tsconfig.json +20 -0
- package/test/fixtures/types/no-self-import/bad.d.ts +8 -0
- package/test/fixtures/types/no-self-import/index.d.ts +7 -0
- package/test/fixtures/types/no-self-import/no-self-import-tests.ts +9 -0
- package/test/fixtures/types/no-self-import/package.json +11 -0
- package/test/fixtures/types/no-self-import/tsconfig.json +20 -0
- package/test/fixtures/types/other/index.d.ts +1 -0
- package/test/fixtures/types/other/other-tests.ts +0 -0
- package/test/fixtures/types/other/package.json +5 -0
- package/test/fixtures/types/other/tsconfig.json +20 -0
- package/test/fixtures/types/other/v1/index.d.ts +1 -0
- package/test/fixtures/types/other/v1/other-tests.ts +0 -0
- package/test/fixtures/types/other/v1/package.json +5 -0
- package/test/fixtures/types/other/v1/tsconfig.json +20 -0
- package/test/fixtures/types/scoped__foo/index.d.ts +1 -0
- package/test/fixtures/types/scoped__foo/package.json +5 -0
- package/test/fixtures/types/scoped__foo/scoped__foo-tests.ts +0 -0
- package/test/fixtures/types/scoped__foo/tsconfig.json +20 -0
- package/test/fixtures/types/scoped__foo/v1/index.d.ts +1 -0
- package/test/fixtures/types/scoped__foo/v1/package.json +5 -0
- package/test/fixtures/types/scoped__foo/v1/scoped__foo-tests.ts +0 -0
- package/test/fixtures/types/scoped__foo/v1/tsconfig.json +20 -0
- package/test/fixtures/types/scoped__no-declare-current-package/index.d.ts +1 -0
- package/test/fixtures/types/scoped__no-declare-current-package/no-declare-current-package-tests.ts +0 -0
- package/test/fixtures/types/scoped__no-declare-current-package/package.json +8 -0
- package/test/fixtures/types/scoped__no-declare-current-package/test/deep/import.d.ts +1 -0
- package/test/fixtures/types/scoped__no-declare-current-package/tsconfig.json +20 -0
- package/test/fixtures/types/scoped__no-relative-references/index.d.ts +12 -0
- package/test/fixtures/types/scoped__no-relative-references/no-relative-references-tests.ts +0 -0
- package/test/fixtures/types/scoped__no-relative-references/other/other.d.ts +7 -0
- package/test/fixtures/types/scoped__no-relative-references/package.json +5 -0
- package/test/fixtures/types/scoped__no-relative-references/tsconfig.json +20 -0
- package/test/fixtures/types/scoped__no-relative-references/v1/index.d.ts +15 -0
- package/test/fixtures/types/scoped__no-relative-references/v1/no-relative-references-tests.ts +0 -0
- package/test/fixtures/types/scoped__no-relative-references/v1/other/other.d.ts +7 -0
- package/test/fixtures/types/scoped__no-relative-references/v1/package.json +5 -0
- package/test/fixtures/types/scoped__no-relative-references/v1/tsconfig.json +20 -0
- package/test/no-bad-reference.test.ts +87 -94
- package/test/no-declare-current-package.test.ts +31 -31
- package/test/no-import-of-dev-dependencies.test.ts +14 -59
- package/test/no-self-import.test.ts +16 -100
- package/test/util.test.ts +29 -18
- package/tsconfig.tsbuildinfo +1 -1
package/dist/util.d.ts
CHANGED
|
@@ -4,3 +4,18 @@ import { RuleListener, RuleModule, SourceCode } from "@typescript-eslint/utils/d
|
|
|
4
4
|
export declare const createRule: <TOptions extends readonly unknown[], TMessageIds extends string>(opts: Readonly<RuleWithMetaAndName<TOptions, TMessageIds, RuleListener>>) => RuleModule<TMessageIds, TOptions>;
|
|
5
5
|
export declare function getTypesPackageForDeclarationFile(file: string): string | undefined;
|
|
6
6
|
export declare function commentsMatching(sourceFile: Readonly<SourceCode>, regex: RegExp, f: (match: string, c: TSESTree.Comment) => void): void;
|
|
7
|
+
export interface TypesPackageInfo {
|
|
8
|
+
dir: string;
|
|
9
|
+
/** package.json with name="@types/foo__bar-baz" */
|
|
10
|
+
packageJson: PackageJSON;
|
|
11
|
+
/** real package name being typed, like "@foo/bar-baz" */
|
|
12
|
+
realName: string;
|
|
13
|
+
}
|
|
14
|
+
export interface PackageJSON {
|
|
15
|
+
name: string;
|
|
16
|
+
version: string;
|
|
17
|
+
owners: string[];
|
|
18
|
+
dependencies?: Record<string, string | undefined>;
|
|
19
|
+
devDependencies?: Record<string, string | undefined>;
|
|
20
|
+
}
|
|
21
|
+
export declare function findTypesPackage(file: string): TypesPackageInfo | undefined;
|
package/dist/util.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.commentsMatching = exports.getTypesPackageForDeclarationFile = exports.createRule = void 0;
|
|
6
|
+
exports.findTypesPackage = exports.commentsMatching = exports.getTypesPackageForDeclarationFile = exports.createRule = void 0;
|
|
4
7
|
const utils_1 = require("@definitelytyped/utils");
|
|
5
8
|
const utils_2 = require("@typescript-eslint/utils");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
6
11
|
// Possible TS bug can't figure out how to do declaration emit of created rules
|
|
7
12
|
// without an explicit type annotation here due to pnpm symlink stuff
|
|
8
13
|
exports.createRule = utils_2.ESLintUtils.RuleCreator((name) => `https://github.com/microsoft/DefinitelyTyped-tools/tree/master/packages/eslint-plugin/docs/rules/${name}.md`);
|
|
9
14
|
function getTypesPackageForDeclarationFile(file) {
|
|
10
|
-
var _a
|
|
11
|
-
if (!
|
|
15
|
+
var _a;
|
|
16
|
+
if (!(0, utils_1.isDeclarationPath)(file)) {
|
|
12
17
|
return undefined;
|
|
13
18
|
}
|
|
14
|
-
|
|
15
|
-
if (!match) {
|
|
16
|
-
return undefined;
|
|
17
|
-
}
|
|
18
|
-
return (_b = (0, utils_1.unmangleScopedPackage)(match)) !== null && _b !== void 0 ? _b : match;
|
|
19
|
+
return (_a = findTypesPackage(file)) === null || _a === void 0 ? void 0 : _a.realName;
|
|
19
20
|
}
|
|
20
21
|
exports.getTypesPackageForDeclarationFile = getTypesPackageForDeclarationFile;
|
|
21
22
|
function commentsMatching(sourceFile, regex, f) {
|
|
@@ -26,4 +27,45 @@ function commentsMatching(sourceFile, regex, f) {
|
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
exports.commentsMatching = commentsMatching;
|
|
30
|
+
function findUp(p, fn) {
|
|
31
|
+
p = path_1.default.resolve(p);
|
|
32
|
+
const root = path_1.default.parse(p).root;
|
|
33
|
+
while (true) {
|
|
34
|
+
const v = fn(p);
|
|
35
|
+
if (v !== undefined) {
|
|
36
|
+
return v;
|
|
37
|
+
}
|
|
38
|
+
if (p === root) {
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
p = path_1.default.dirname(p);
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
// TODO(jakebailey): pull this helper out to util package?
|
|
46
|
+
function isTypesPackage(packageJson) {
|
|
47
|
+
return (typeof packageJson.name === "string" &&
|
|
48
|
+
packageJson.name.startsWith("@types/") &&
|
|
49
|
+
typeof packageJson.version === "string" &&
|
|
50
|
+
Array.isArray(packageJson.owners));
|
|
51
|
+
}
|
|
52
|
+
function findTypesPackage(file) {
|
|
53
|
+
return findUp(file, (p) => {
|
|
54
|
+
const packageJsonPath = path_1.default.join(p, "package.json");
|
|
55
|
+
if (!fs_1.default.existsSync(packageJsonPath)) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
const packageJsonContents = fs_1.default.readFileSync(packageJsonPath, "utf8");
|
|
59
|
+
const packageJson = JSON.parse(packageJsonContents);
|
|
60
|
+
if (!isTypesPackage(packageJson)) {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
dir: p,
|
|
65
|
+
packageJson,
|
|
66
|
+
realName: (0, utils_1.typesPackageNameToRealName)(packageJson.name),
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
exports.findTypesPackage = findTypesPackage;
|
|
29
71
|
//# sourceMappingURL=util.js.map
|
package/dist/util.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":";;;;;;AAAA,kDAAuF;AACvF,oDAAiE;AAGjE,gDAAwB;AACxB,4CAAoB;AAEpB,+EAA+E;AAC/E,qEAAqE;AACxD,QAAA,UAAU,GAEkB,mBAAW,CAAC,WAAW,CAC9D,CAAC,IAAI,EAAE,EAAE,CACP,oGAAoG,IAAI,KAAK,CAChH,CAAC;AAEF,SAAgB,iCAAiC,CAAC,IAAY;;IAC5D,IAAI,CAAC,IAAA,yBAAiB,EAAC,IAAI,CAAC,EAAE;QAC5B,OAAO,SAAS,CAAC;KAClB;IACD,OAAO,MAAA,gBAAgB,CAAC,IAAI,CAAC,0CAAE,QAAQ,CAAC;AAC1C,CAAC;AALD,8EAKC;AAED,SAAgB,gBAAgB,CAC9B,UAAgC,EAChC,KAAa,EACb,CAA+C;IAE/C,KAAK,MAAM,OAAO,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,EAAE;QAC7C,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC;YAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;KACzB;AACH,CAAC;AATD,4CASC;AAED,SAAS,MAAM,CAAe,CAAS,EAAE,EAAgC;IACvE,CAAC,GAAG,cAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,IAAI,GAAG,cAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhC,OAAO,IAAI,EAAE;QACX,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,CAAC,KAAK,SAAS,EAAE;YACnB,OAAO,CAAC,CAAC;SACV;QACD,IAAI,CAAC,KAAK,IAAI,EAAE;YACd,MAAM;SACP;QACD,CAAC,GAAG,cAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;KACrB;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAkBD,0DAA0D;AAC1D,SAAS,cAAc,CAAC,WAAiC;IACvD,OAAO,CACL,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ;QACpC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QACtC,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ;QACvC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,CAAC,CAClC,CAAC;AACJ,CAAC;AAED,SAAgB,gBAAgB,CAAC,IAAY;IAC3C,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE;QACxB,MAAM,eAAe,GAAG,cAAI,CAAC,IAAI,CAAC,CAAC,EAAE,cAAc,CAAC,CAAC;QACrD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE;YACnC,OAAO,SAAS,CAAC;SAClB;QAED,MAAM,mBAAmB,GAAG,YAAE,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;QACrE,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACpD,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE;YAChC,OAAO,SAAS,CAAC;SAClB;QACD,OAAO;YACL,GAAG,EAAE,CAAC;YACN,WAAW;YACX,QAAQ,EAAE,IAAA,kCAA0B,EAAC,WAAW,CAAC,IAAI,CAAC;SACvD,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAlBD,4CAkBC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@definitelytyped/eslint-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.188",
|
|
4
4
|
"description": "ESLint rules for DefinitelyTyped",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"@typescript-eslint/types": "^5.56.0",
|
|
22
22
|
"@typescript-eslint/utils": "^5.55.0",
|
|
23
|
-
"@definitelytyped/utils": "0.0.
|
|
23
|
+
"@definitelytyped/utils": "0.0.184"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
package/src/configs/all.ts
CHANGED
|
@@ -136,6 +136,7 @@ export const all: Linter.BaseConfig = {
|
|
|
136
136
|
},
|
|
137
137
|
rules: {
|
|
138
138
|
...Object.fromEntries(Object.keys(rules).map((name) => [`@definitelytyped/${name}`, "error"])),
|
|
139
|
+
"unicode-bom": ["error", "never"],
|
|
139
140
|
"@typescript-eslint/ban-ts-comment": [
|
|
140
141
|
"error",
|
|
141
142
|
{
|
|
@@ -1,58 +1,201 @@
|
|
|
1
|
-
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
-
import {
|
|
1
|
+
import { ESLintUtils, TSESTree } from "@typescript-eslint/utils";
|
|
2
|
+
import { createRule, findTypesPackage } from "../util";
|
|
3
|
+
import * as ts from "typescript";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { isDeclarationPath } from "@definitelytyped/utils";
|
|
6
|
+
|
|
7
|
+
interface Reference {
|
|
8
|
+
kind: "path" | "import" | "types";
|
|
9
|
+
text: string;
|
|
10
|
+
range: ts.TextRange;
|
|
11
|
+
}
|
|
3
12
|
|
|
4
|
-
type MessageId = "referencePathPackage" | "referencePathTest" | "referencePathOldVersion";
|
|
5
13
|
const rule = createRule({
|
|
6
14
|
name: "no-bad-reference",
|
|
7
15
|
defaultOptions: [],
|
|
8
16
|
meta: {
|
|
9
17
|
type: "problem",
|
|
10
18
|
docs: {
|
|
11
|
-
description:
|
|
19
|
+
description:
|
|
20
|
+
"Forbids bad references, including those that resolve outside of the package or path references in non-declaration files.",
|
|
12
21
|
recommended: "error",
|
|
13
22
|
},
|
|
14
23
|
messages: {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
24
|
+
importOutside:
|
|
25
|
+
'The import "{{text}}" resolves outside of the package. Use a bare import to reference other packages.',
|
|
26
|
+
importLeaves: 'The import "{{text}}" resolves to the current package, but uses relative paths.',
|
|
27
|
+
referenceOutside:
|
|
28
|
+
'The reference "{{text}}" resolves outside of the package. Use a global reference to reference other packages.',
|
|
29
|
+
referenceLeaves: 'The reference "{{text}}" resolves to the current package, but uses relative paths.',
|
|
30
|
+
testReference:
|
|
31
|
+
'The path reference "{{text}}" is disallowed outside declaration files. Use "<reference types>" or include the file in tsconfig instead.',
|
|
32
|
+
backslashes: "Use forward slashes in paths.",
|
|
20
33
|
},
|
|
21
34
|
schema: [],
|
|
22
35
|
},
|
|
23
36
|
create(context) {
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
const containingFileName = context.getFilename();
|
|
38
|
+
const typesPackage = findTypesPackage(containingFileName);
|
|
39
|
+
if (!typesPackage) {
|
|
40
|
+
return {};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const containingDirectory = path.dirname(containingFileName);
|
|
44
|
+
|
|
45
|
+
const realNamePlusSlash = typesPackage.realName + "/";
|
|
46
|
+
function isRelativeOrSelf(name: string) {
|
|
47
|
+
return name.startsWith(".") || name.startsWith(realNamePlusSlash);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const ast = context.getSourceCode().ast;
|
|
51
|
+
const parserServices = ESLintUtils.getParserServices(context, true);
|
|
52
|
+
const sourceFile = parserServices.esTreeNodeToTSNodeMap.get(ast);
|
|
53
|
+
|
|
54
|
+
const refs: Reference[] = [];
|
|
55
|
+
for (const ref of sourceFile.referencedFiles) {
|
|
56
|
+
if (isDeclarationPath(containingFileName)) {
|
|
57
|
+
refs.push({ kind: "path", text: ref.fileName, range: ref });
|
|
33
58
|
} else {
|
|
34
|
-
report(
|
|
59
|
+
context.report({
|
|
60
|
+
messageId: "testReference",
|
|
61
|
+
loc: tsRangeToESLintLocation(ref, sourceFile),
|
|
62
|
+
data: { text: ref.fileName },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
for (const ref of sourceFile.typeReferenceDirectives) {
|
|
67
|
+
if (isRelativeOrSelf(ref.fileName)) {
|
|
68
|
+
refs.push({ kind: "types", text: ref.fileName, range: ref });
|
|
35
69
|
}
|
|
36
|
-
}
|
|
70
|
+
}
|
|
71
|
+
for (const ref of imports(sourceFile)) {
|
|
72
|
+
if (isRelativeOrSelf(ref.text)) {
|
|
73
|
+
refs.push({ kind: "import", text: ref.text, range: ref });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
37
76
|
|
|
38
|
-
|
|
77
|
+
for (const ref of refs) {
|
|
78
|
+
if (ref.text.includes("\\")) {
|
|
79
|
+
context.report({
|
|
80
|
+
messageId: "backslashes",
|
|
81
|
+
loc: tsRangeToESLintLocation(ref.range, sourceFile),
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const p = ref.text.startsWith(realNamePlusSlash)
|
|
86
|
+
? path.posix.join(
|
|
87
|
+
path.posix.relative(containingDirectory, typesPackage.dir),
|
|
88
|
+
ref.text.slice(realNamePlusSlash.length)
|
|
89
|
+
)
|
|
90
|
+
: ref.text;
|
|
91
|
+
|
|
92
|
+
const resolved = path.resolve(containingDirectory, p);
|
|
93
|
+
const otherPackage = findTypesPackage(resolved);
|
|
94
|
+
|
|
95
|
+
if (otherPackage && otherPackage.dir === typesPackage.dir) {
|
|
96
|
+
// Perf trick; if a path doesn't have ".." anywhere, then it can't have resolved
|
|
97
|
+
// up and out of a package dir so we can skip this work.
|
|
98
|
+
if (p.includes("..")) {
|
|
99
|
+
// If we resolved to something in the correct package, we still could have
|
|
100
|
+
// gotten here by leaving the package (up into a parent, or down into a versioned dir).
|
|
101
|
+
// Manually walk the path to see if that happened.
|
|
102
|
+
const parts = p.split("/");
|
|
103
|
+
let cwd = containingDirectory;
|
|
104
|
+
for (const part of parts) {
|
|
105
|
+
if (part === "" || part === ".") {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
if (part === "..") {
|
|
109
|
+
cwd = path.posix.dirname(cwd);
|
|
110
|
+
} else {
|
|
111
|
+
cwd = path.posix.join(cwd, part);
|
|
112
|
+
}
|
|
113
|
+
const otherPackage = findTypesPackage(cwd);
|
|
114
|
+
if (otherPackage && otherPackage.dir === typesPackage.dir) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
context.report({
|
|
119
|
+
messageId: ref.kind === "import" ? "importLeaves" : "referenceLeaves",
|
|
120
|
+
loc: tsRangeToESLintLocation(ref.range, sourceFile),
|
|
121
|
+
data: { text: ref.text },
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
39
128
|
|
|
40
|
-
function report(comment: TSESTree.Comment, messageId: MessageId) {
|
|
41
129
|
context.report({
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
line: comment.loc.end.line,
|
|
46
|
-
},
|
|
47
|
-
start: {
|
|
48
|
-
column: comment.value.indexOf(`"`) + 1,
|
|
49
|
-
line: comment.loc.start.line,
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
messageId,
|
|
130
|
+
messageId: ref.kind === "import" ? "importOutside" : "referenceOutside",
|
|
131
|
+
loc: tsRangeToESLintLocation(ref.range, sourceFile),
|
|
132
|
+
data: { text: ref.text },
|
|
53
133
|
});
|
|
54
134
|
}
|
|
135
|
+
|
|
136
|
+
return {};
|
|
55
137
|
},
|
|
56
138
|
});
|
|
57
139
|
|
|
140
|
+
function tsRangeToESLintLocation(range: ts.TextRange, sourceFile: ts.SourceFile): TSESTree.SourceLocation {
|
|
141
|
+
const pos = sourceFile.getLineAndCharacterOfPosition(range.pos);
|
|
142
|
+
const end = sourceFile.getLineAndCharacterOfPosition(range.end);
|
|
143
|
+
return {
|
|
144
|
+
start: { line: pos.line + 1, column: pos.character + 1 },
|
|
145
|
+
end: { line: end.line + 1, column: end.character + 1 },
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* All strings referenced in `import` statements.
|
|
151
|
+
* Does *not* include <reference> directives.
|
|
152
|
+
*/
|
|
153
|
+
function imports({ statements }: ts.SourceFile): Iterable<ts.StringLiteralLike> {
|
|
154
|
+
const result: ts.StringLiteralLike[] = [];
|
|
155
|
+
for (const node of statements) {
|
|
156
|
+
recur(node);
|
|
157
|
+
}
|
|
158
|
+
return result;
|
|
159
|
+
|
|
160
|
+
function recur(node: ts.Node) {
|
|
161
|
+
switch (node.kind) {
|
|
162
|
+
case ts.SyntaxKind.ImportDeclaration:
|
|
163
|
+
case ts.SyntaxKind.ExportDeclaration: {
|
|
164
|
+
const { moduleSpecifier } = node as ts.ImportDeclaration | ts.ExportDeclaration;
|
|
165
|
+
if (moduleSpecifier && moduleSpecifier.kind === ts.SyntaxKind.StringLiteral) {
|
|
166
|
+
result.push(moduleSpecifier as ts.StringLiteral);
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
case ts.SyntaxKind.ImportEqualsDeclaration: {
|
|
172
|
+
const { moduleReference } = node as ts.ImportEqualsDeclaration;
|
|
173
|
+
if (moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
|
|
174
|
+
result.push(parseRequire(moduleReference));
|
|
175
|
+
}
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
case ts.SyntaxKind.ImportType: {
|
|
180
|
+
const { argument } = node as ts.ImportTypeNode;
|
|
181
|
+
if (ts.isLiteralTypeNode(argument) && ts.isStringLiteral(argument.literal)) {
|
|
182
|
+
result.push(argument.literal);
|
|
183
|
+
}
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
default:
|
|
188
|
+
ts.forEachChild(node, recur);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function parseRequire(reference: ts.ExternalModuleReference): ts.StringLiteralLike {
|
|
194
|
+
const { expression } = reference;
|
|
195
|
+
if (!expression || !ts.isStringLiteral(expression)) {
|
|
196
|
+
throw new Error(`Bad 'import =' reference: ${reference.getText()}`);
|
|
197
|
+
}
|
|
198
|
+
return expression;
|
|
199
|
+
}
|
|
200
|
+
|
|
58
201
|
export = rule;
|
|
@@ -19,6 +19,9 @@ const rule = createRule({
|
|
|
19
19
|
},
|
|
20
20
|
create(context) {
|
|
21
21
|
const packageName = getTypesPackageForDeclarationFile(context.getFilename());
|
|
22
|
+
if (!packageName) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
22
25
|
|
|
23
26
|
return {
|
|
24
27
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -28,7 +31,7 @@ const rule = createRule({
|
|
|
28
31
|
(node.id.value === packageName || node.id.value.startsWith(packageName + "/"))
|
|
29
32
|
) {
|
|
30
33
|
const text = node.id.value;
|
|
31
|
-
const preferred = text === packageName ? '"index.d.ts"' : `"${text}.d.ts" or "${text}/index.d.ts`;
|
|
34
|
+
const preferred = text === packageName ? '"index.d.ts"' : `"${text}.d.ts" or "${text}/index.d.ts"`;
|
|
32
35
|
context.report({
|
|
33
36
|
messageId: "noDeclareCurrentPackage",
|
|
34
37
|
data: { text, preferred },
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDeclarationPath } from "@definitelytyped/utils";
|
|
1
2
|
import { createRule } from "../util";
|
|
2
3
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
3
4
|
import * as ts from "typescript";
|
|
@@ -19,7 +20,7 @@ const rule = createRule({
|
|
|
19
20
|
create(context) {
|
|
20
21
|
const parserServices = ESLintUtils.getParserServices(context);
|
|
21
22
|
const checker = parserServices.program.getTypeChecker();
|
|
22
|
-
if (context.getFilename()
|
|
23
|
+
if (isDeclarationPath(context.getFilename())) {
|
|
23
24
|
return {
|
|
24
25
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
25
26
|
ImportDeclaration(node) {
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { TSESTree } from "@typescript-eslint/utils";
|
|
2
|
-
import { createRule, commentsMatching,
|
|
3
|
-
import
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { unmangleScopedPackage } from "@definitelytyped/utils";
|
|
2
|
+
import { createRule, commentsMatching, findTypesPackage } from "../util";
|
|
3
|
+
import { isDeclarationPath, isTypesPackageName, typesPackageNameToRealName } from "@definitelytyped/utils";
|
|
6
4
|
|
|
7
5
|
type MessageId = "noImportOfDevDependencies" | "noReferenceOfDevDependencies";
|
|
8
6
|
const rule = createRule({
|
|
@@ -21,45 +19,47 @@ const rule = createRule({
|
|
|
21
19
|
schema: [],
|
|
22
20
|
},
|
|
23
21
|
create(context) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
const devdeps = packageJson
|
|
28
|
-
? Object.keys(packageJson.devDependencies).map((dep) => {
|
|
29
|
-
const withoutTypes = dep.replace(/^@types\//, "");
|
|
30
|
-
return unmangleScopedPackage(withoutTypes) || withoutTypes;
|
|
31
|
-
})
|
|
32
|
-
: [];
|
|
33
|
-
const deps = packageJson
|
|
34
|
-
? Object.keys(packageJson.dependencies ?? {}).map((dep) => {
|
|
35
|
-
const withoutTypes = dep.replace(/^@types\//, "");
|
|
36
|
-
return unmangleScopedPackage(withoutTypes) || withoutTypes;
|
|
37
|
-
})
|
|
38
|
-
: [];
|
|
39
|
-
commentsMatching(context.getSourceCode(), /<reference\s+types\s*=\s*"(.+)"\s*\/>/, (ref, comment) => {
|
|
40
|
-
if (devdeps.includes(ref) && ref !== packageName && !deps.includes(ref)) {
|
|
41
|
-
report(comment, "noReferenceOfDevDependencies");
|
|
42
|
-
}
|
|
43
|
-
});
|
|
22
|
+
if (!isDeclarationPath(context.getFilename())) {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
44
25
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
) {
|
|
53
|
-
context.report({
|
|
54
|
-
messageId: "noImportOfDevDependencies",
|
|
55
|
-
node,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
};
|
|
60
|
-
} else {
|
|
26
|
+
const info = findTypesPackage(context.getFilename());
|
|
27
|
+
if (!info) {
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const packageJson = info.packageJson;
|
|
32
|
+
if (!packageJson.devDependencies) {
|
|
61
33
|
return {};
|
|
62
34
|
}
|
|
35
|
+
|
|
36
|
+
const devDeps = Object.keys(packageJson.devDependencies)
|
|
37
|
+
.map((dep) => {
|
|
38
|
+
if (isTypesPackageName(dep)) {
|
|
39
|
+
return typesPackageNameToRealName(dep);
|
|
40
|
+
}
|
|
41
|
+
return dep;
|
|
42
|
+
})
|
|
43
|
+
.filter((dep) => dep !== info.realName && packageJson.dependencies?.[dep] === undefined); // TODO(jakebailey): add test for this case from https://github.com/microsoft/DefinitelyTyped-tools/pull/773
|
|
44
|
+
|
|
45
|
+
commentsMatching(context.getSourceCode(), /<reference\s+types\s*=\s*"(.+)"\s*\/>/, (ref, comment) => {
|
|
46
|
+
if (devDeps.includes(ref)) {
|
|
47
|
+
report(comment, "noReferenceOfDevDependencies");
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
53
|
+
ImportDeclaration(node) {
|
|
54
|
+
if (devDeps.includes(node.source.value)) {
|
|
55
|
+
context.report({
|
|
56
|
+
messageId: "noImportOfDevDependencies",
|
|
57
|
+
node,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
|
|
63
63
|
function report(comment: TSESTree.Comment, messageId: MessageId) {
|
|
64
64
|
context.report({
|
|
65
65
|
loc: {
|
|
@@ -77,24 +77,5 @@ const rule = createRule({
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
});
|
|
80
|
-
function getPackageJson(
|
|
81
|
-
sourceFile: string
|
|
82
|
-
): { dependencies?: Record<string, string>; devDependencies: Record<string, string> } | undefined {
|
|
83
|
-
let dir = path.dirname(sourceFile);
|
|
84
|
-
let text: string | undefined;
|
|
85
|
-
while (dir !== "/") {
|
|
86
|
-
try {
|
|
87
|
-
text = fs.readFileSync(path.join(dir, "package.json"), "utf8");
|
|
88
|
-
break;
|
|
89
|
-
} catch {
|
|
90
|
-
// presumably because file does not exist, so continue
|
|
91
|
-
}
|
|
92
|
-
dir = path.dirname(dir);
|
|
93
|
-
}
|
|
94
|
-
if (!text) return undefined;
|
|
95
|
-
const json = JSON.parse(text);
|
|
96
|
-
if ("devDependencies" in json) return json;
|
|
97
|
-
return undefined;
|
|
98
|
-
}
|
|
99
80
|
|
|
100
81
|
export = rule;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isDeclarationPath } from "@definitelytyped/utils";
|
|
1
2
|
import { createRule } from "../util";
|
|
2
3
|
|
|
3
4
|
const rule = createRule({
|
|
@@ -18,7 +19,7 @@ const rule = createRule({
|
|
|
18
19
|
create(context) {
|
|
19
20
|
const text = context.getSourceCode().text;
|
|
20
21
|
if (
|
|
21
|
-
context.getFilename()
|
|
22
|
+
isDeclarationPath(context.getFilename()) &&
|
|
22
23
|
text.indexOf("// Type definitions for ") === 0 &&
|
|
23
24
|
text.indexOf("// Definitions by: ") > 0
|
|
24
25
|
) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ESLintUtils } from "@typescript-eslint/utils";
|
|
2
2
|
import * as ts from "typescript";
|
|
3
3
|
import { createRule } from "../util";
|
|
4
|
+
import { isDeclarationPath } from "@definitelytyped/utils";
|
|
4
5
|
|
|
5
6
|
const rule = createRule({
|
|
6
7
|
name: "no-relative-import-in-test",
|
|
@@ -18,11 +19,7 @@ const rule = createRule({
|
|
|
18
19
|
schema: [],
|
|
19
20
|
},
|
|
20
21
|
create(context) {
|
|
21
|
-
if (
|
|
22
|
-
context.getFilename().endsWith(".d.ts") ||
|
|
23
|
-
context.getFilename().endsWith(".d.mts") ||
|
|
24
|
-
context.getFilename().endsWith(".d.cts")
|
|
25
|
-
) {
|
|
22
|
+
if (isDeclarationPath(context.getFilename())) {
|
|
26
23
|
return {};
|
|
27
24
|
}
|
|
28
25
|
|
|
@@ -17,6 +17,9 @@ const rule = createRule({
|
|
|
17
17
|
},
|
|
18
18
|
create(context) {
|
|
19
19
|
const packageName = getTypesPackageForDeclarationFile(context.getFilename());
|
|
20
|
+
if (!packageName) {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
20
23
|
|
|
21
24
|
return {
|
|
22
25
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AST_NODE_TYPES, TSESTree } from "@typescript-eslint/utils";
|
|
2
2
|
|
|
3
3
|
import { createRule } from "../util";
|
|
4
|
+
import { isDeclarationPath } from "@definitelytyped/utils";
|
|
4
5
|
|
|
5
6
|
const rule = createRule({
|
|
6
7
|
defaultOptions: [],
|
|
@@ -22,7 +23,7 @@ const rule = createRule({
|
|
|
22
23
|
"VariableDeclaration > VariableDeclarator"(node: TSESTree.VariableDeclarator) {
|
|
23
24
|
if (
|
|
24
25
|
node.id.typeAnnotation?.typeAnnotation.type === AST_NODE_TYPES.TSFunctionType &&
|
|
25
|
-
context.getFilename()
|
|
26
|
+
isDeclarationPath(context.getFilename())
|
|
26
27
|
) {
|
|
27
28
|
context.report({
|
|
28
29
|
messageId: "variableFunction",
|