@definitelytyped/eslint-plugin 0.0.197 → 0.0.198
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 +8 -0
- package/dist/configs/all.js +5 -1
- package/dist/configs/all.js.map +1 -1
- package/dist/rules/index.d.ts +1 -0
- package/dist/rules/index.js +2 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/npm-naming/types.d.ts +10 -0
- package/dist/rules/npm-naming/types.js +3 -0
- package/dist/rules/npm-naming/types.js.map +1 -0
- package/dist/rules/npm-naming.d.ts +3 -0
- package/dist/rules/npm-naming.js +180 -0
- package/dist/rules/npm-naming.js.map +1 -0
- package/dist/suggestions.d.ts +4 -0
- package/dist/suggestions.js +62 -0
- package/dist/suggestions.js.map +1 -0
- package/dist/util.d.ts +1 -0
- package/dist/util.js +19 -1
- package/dist/util.js.map +1 -1
- package/docs/rules/npm-naming.md +137 -0
- package/package.json +3 -1
- package/src/configs/all.ts +7 -1
- package/src/rules/index.ts +2 -0
- package/src/rules/npm-naming/types.ts +14 -0
- package/src/rules/npm-naming.ts +211 -0
- package/src/suggestions.ts +75 -0
- package/src/util.ts +21 -0
- package/test/__snapshots__/plugin.test.ts.snap +262 -0
- package/test/npm-naming.test.ts +57 -0
- package/test/plugin.test.ts +14 -0
- package/test/types/dts-critic/index.d.ts +9 -0
- package/test/types/dts-critic/package.json +17 -0
- package/test/types/wenceslas/index.d.ts +0 -0
- package/test/types/wenceslas/package.json +17 -0
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CheckOptions as CriticOptions,
|
|
3
|
+
dtsCritic as critic,
|
|
4
|
+
ErrorKind,
|
|
5
|
+
ExportErrorKind,
|
|
6
|
+
Mode,
|
|
7
|
+
parseExportErrorKind,
|
|
8
|
+
CriticError,
|
|
9
|
+
} from "@definitelytyped/dts-critic";
|
|
10
|
+
|
|
11
|
+
import { addSuggestion } from "../suggestions";
|
|
12
|
+
import { createRule, isMainFile } from "../util";
|
|
13
|
+
import { CodeRawOptionError, NpmNamingOptions } from "./npm-naming/types";
|
|
14
|
+
|
|
15
|
+
function parseEnabledErrors(errors: CodeRawOptionError[]): [ExportErrorKind, boolean][] {
|
|
16
|
+
const enabledChecks: [ExportErrorKind, boolean][] = [];
|
|
17
|
+
for (const tuple of errors) {
|
|
18
|
+
const error = parseExportErrorKind(tuple[0]);
|
|
19
|
+
if (error) {
|
|
20
|
+
enabledChecks.push([error, tuple[1]]);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return enabledChecks;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function parseRawOptions(rawOptions: NpmNamingOptions): CriticOptions {
|
|
27
|
+
switch (rawOptions.mode) {
|
|
28
|
+
case Mode.Code:
|
|
29
|
+
return { ...rawOptions, errors: new Map(parseEnabledErrors(rawOptions.errors)) };
|
|
30
|
+
case Mode.NameOnly:
|
|
31
|
+
return rawOptions;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const enabledSuggestions: ExportErrorKind[] = [ErrorKind.JsPropertyNotInDts, ErrorKind.JsSignatureNotInDts];
|
|
36
|
+
|
|
37
|
+
function toOptionsWithSuggestions(options: CriticOptions): CriticOptions {
|
|
38
|
+
if (options.mode === Mode.NameOnly) {
|
|
39
|
+
return options;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const optionsWithSuggestions = { mode: options.mode, errors: new Map(options.errors) };
|
|
43
|
+
|
|
44
|
+
for (const err of enabledSuggestions) {
|
|
45
|
+
optionsWithSuggestions.errors.set(err, true);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return optionsWithSuggestions;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function eslintDisableOption(error: ErrorKind): string {
|
|
52
|
+
switch (error) {
|
|
53
|
+
case ErrorKind.NoMatchingNpmPackage:
|
|
54
|
+
case ErrorKind.NoMatchingNpmVersion:
|
|
55
|
+
case ErrorKind.NonNpmHasMatchingPackage:
|
|
56
|
+
return `"off"`;
|
|
57
|
+
case ErrorKind.NoDefaultExport:
|
|
58
|
+
case ErrorKind.NeedsExportEquals:
|
|
59
|
+
case ErrorKind.JsSignatureNotInDts:
|
|
60
|
+
case ErrorKind.JsPropertyNotInDts:
|
|
61
|
+
case ErrorKind.DtsSignatureNotInJs:
|
|
62
|
+
case ErrorKind.DtsPropertyNotInJs:
|
|
63
|
+
return JSON.stringify(["error", { mode: Mode.Code, errors: [[error, false]] }]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const rule = createRule<[NpmNamingOptions], "error">({
|
|
68
|
+
name: "npm-naming",
|
|
69
|
+
defaultOptions: [
|
|
70
|
+
{
|
|
71
|
+
mode: Mode.NameOnly,
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
meta: {
|
|
75
|
+
type: "problem",
|
|
76
|
+
docs: {
|
|
77
|
+
description: "Ensure that package name and DefinitelyTyped header match npm package info.",
|
|
78
|
+
},
|
|
79
|
+
messages: {
|
|
80
|
+
error: `{{ error }}
|
|
81
|
+
If you won't fix this error now or you think this error is wrong,
|
|
82
|
+
you can disable this check by adding the following options to your project's .eslintrc.json file under "rules":
|
|
83
|
+
|
|
84
|
+
"@definitelytyped/npm-naming": {{ option }}`,
|
|
85
|
+
},
|
|
86
|
+
schema: [
|
|
87
|
+
{
|
|
88
|
+
oneOf: [
|
|
89
|
+
{
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
properties: {
|
|
92
|
+
mode: {
|
|
93
|
+
type: "string",
|
|
94
|
+
enum: [Mode.NameOnly],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
type: "object",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
additionalProperties: false,
|
|
101
|
+
type: "object",
|
|
102
|
+
properties: {
|
|
103
|
+
mode: {
|
|
104
|
+
type: "string",
|
|
105
|
+
enum: [Mode.Code],
|
|
106
|
+
},
|
|
107
|
+
errors: {
|
|
108
|
+
type: "array",
|
|
109
|
+
items: {
|
|
110
|
+
type: "array",
|
|
111
|
+
items: [
|
|
112
|
+
{
|
|
113
|
+
description: "Name of the check.",
|
|
114
|
+
type: "string",
|
|
115
|
+
enum: [ErrorKind.NeedsExportEquals, ErrorKind.NoDefaultExport],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
description: "Whether the check is enabled or disabled.",
|
|
119
|
+
type: "boolean",
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
minItems: 2,
|
|
123
|
+
maxItems: 2,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
130
|
+
],
|
|
131
|
+
},
|
|
132
|
+
create(context, [rawOptions]) {
|
|
133
|
+
if (!isMainFile(context.filename, /*allowNested*/ false)) {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const options = parseRawOptions(rawOptions);
|
|
138
|
+
const optionsWithSuggestions = toOptionsWithSuggestions(options);
|
|
139
|
+
const diagnostics = critic(context.filename, /* sourcePath */ undefined, optionsWithSuggestions);
|
|
140
|
+
const errors = filterErrors(diagnostics);
|
|
141
|
+
|
|
142
|
+
for (const error of errors) {
|
|
143
|
+
switch (error.kind) {
|
|
144
|
+
case ErrorKind.NoMatchingNpmPackage:
|
|
145
|
+
case ErrorKind.NoMatchingNpmVersion:
|
|
146
|
+
case ErrorKind.NonNpmHasMatchingPackage:
|
|
147
|
+
case ErrorKind.DtsPropertyNotInJs:
|
|
148
|
+
case ErrorKind.DtsSignatureNotInJs:
|
|
149
|
+
case ErrorKind.JsPropertyNotInDts:
|
|
150
|
+
case ErrorKind.JsSignatureNotInDts:
|
|
151
|
+
case ErrorKind.NeedsExportEquals:
|
|
152
|
+
case ErrorKind.NoDefaultExport:
|
|
153
|
+
context.report({
|
|
154
|
+
data: {
|
|
155
|
+
error: error.message,
|
|
156
|
+
option: eslintDisableOption(error.kind),
|
|
157
|
+
},
|
|
158
|
+
loc: error.position
|
|
159
|
+
? {
|
|
160
|
+
start: context.sourceCode.getLocFromIndex(error.position.start),
|
|
161
|
+
end: context.sourceCode.getLocFromIndex(error.position.start + error.position.length),
|
|
162
|
+
}
|
|
163
|
+
: {
|
|
164
|
+
end: {
|
|
165
|
+
line: 2,
|
|
166
|
+
column: 0,
|
|
167
|
+
},
|
|
168
|
+
start: {
|
|
169
|
+
line: 1,
|
|
170
|
+
column: 0,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
messageId: "error",
|
|
174
|
+
});
|
|
175
|
+
break;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return {};
|
|
180
|
+
|
|
181
|
+
function filterErrors(diagnostics: CriticError[]): CriticError[] {
|
|
182
|
+
const errors: CriticError[] = [];
|
|
183
|
+
|
|
184
|
+
diagnostics.forEach((diagnostic) => {
|
|
185
|
+
if (isSuggestion(diagnostic)) {
|
|
186
|
+
addSuggestion(
|
|
187
|
+
context.filename,
|
|
188
|
+
"npm-naming",
|
|
189
|
+
diagnostic.message,
|
|
190
|
+
diagnostic.position?.start,
|
|
191
|
+
diagnostic.position?.length,
|
|
192
|
+
);
|
|
193
|
+
} else {
|
|
194
|
+
errors.push(diagnostic);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return errors;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function isSuggestion(diagnostic: CriticError): boolean {
|
|
202
|
+
return (
|
|
203
|
+
options.mode === Mode.Code &&
|
|
204
|
+
enabledSuggestions.includes(diagnostic.kind as ExportErrorKind) &&
|
|
205
|
+
!(options.errors as Map<ErrorKind, boolean>).get(diagnostic.kind)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
export = rule;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import fs = require("fs");
|
|
2
|
+
import os = require("os");
|
|
3
|
+
import path = require("path");
|
|
4
|
+
|
|
5
|
+
const suggestionsDir = path.join(os.homedir(), ".dts", "suggestions");
|
|
6
|
+
|
|
7
|
+
interface Suggestion {
|
|
8
|
+
fileName: string;
|
|
9
|
+
ruleName: string;
|
|
10
|
+
message: string;
|
|
11
|
+
start?: number;
|
|
12
|
+
width?: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Packages for which suggestions were already added in this run of dtslint.
|
|
16
|
+
const existingPackages = new Set();
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* A rule should call this function to provide a suggestion instead of a lint failure.
|
|
20
|
+
*/
|
|
21
|
+
export function addSuggestion(fileName: string, ruleName: string, message: string, start?: number, width?: number) {
|
|
22
|
+
const suggestion: Suggestion = {
|
|
23
|
+
fileName,
|
|
24
|
+
ruleName,
|
|
25
|
+
message,
|
|
26
|
+
start,
|
|
27
|
+
width,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const packageName = dtPackageName(fileName);
|
|
31
|
+
if (!packageName) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let flag = "a";
|
|
35
|
+
if (!existingPackages.has(packageName)) {
|
|
36
|
+
flag = "w";
|
|
37
|
+
existingPackages.add(packageName);
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
if (!fs.existsSync(suggestionsDir)) {
|
|
41
|
+
fs.mkdirSync(suggestionsDir, { recursive: true });
|
|
42
|
+
}
|
|
43
|
+
fs.writeFileSync(
|
|
44
|
+
path.join(suggestionsDir, packageName + ".txt"),
|
|
45
|
+
flag === "a" ? "\n" + formatSuggestion(suggestion) : formatSuggestion(suggestion),
|
|
46
|
+
{ flag, encoding: "utf8" },
|
|
47
|
+
);
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.log(`Could not write suggestions for package ${packageName}. ${(e as Error).message || ""}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const dtPath = path.join("DefinitelyTyped", "types");
|
|
54
|
+
|
|
55
|
+
function dtPackageName(filePath: string): string | undefined {
|
|
56
|
+
const dtIndex = filePath.indexOf(dtPath);
|
|
57
|
+
if (dtIndex === -1) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
const basePath = filePath.substr(dtIndex + dtPath.length);
|
|
61
|
+
const dirs = basePath.split(path.sep).filter((dir) => dir !== "");
|
|
62
|
+
if (dirs.length === 0) {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const packageName = dirs[0];
|
|
66
|
+
// Check if this is an old version of a package.
|
|
67
|
+
if (dirs.length > 1 && /^v\d+(\.\d+)?$/.test(dirs[1])) {
|
|
68
|
+
return packageName + dirs[1];
|
|
69
|
+
}
|
|
70
|
+
return packageName;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function formatSuggestion(suggestion: Suggestion): string {
|
|
74
|
+
return JSON.stringify(suggestion, /*replacer*/ undefined, 0);
|
|
75
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -116,3 +116,24 @@ export function getImportSource(
|
|
|
116
116
|
|
|
117
117
|
return undefined;
|
|
118
118
|
}
|
|
119
|
+
|
|
120
|
+
export function isMainFile(fileName: string, allowNested: boolean) {
|
|
121
|
+
// Linter may be run with cwd of the package. We want `index.d.ts` but not `submodule/index.d.ts` to match.
|
|
122
|
+
if (fileName === "index.d.ts") {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
if (path.basename(fileName) !== "index.d.ts") {
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let parent = path.dirname(fileName);
|
|
131
|
+
// May be a directory for an older version, e.g. `v0`.
|
|
132
|
+
// Note a types redirect `foo/ts3.1` should not have its own header.
|
|
133
|
+
if (allowNested && /^v(0\.)?\d+$/.test(path.basename(parent))) {
|
|
134
|
+
parent = path.dirname(parent);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Allow "types/foo/index.d.ts", not "types/foo/utils/index.d.ts"
|
|
138
|
+
return path.basename(path.dirname(parent)) === "types";
|
|
139
|
+
}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`plugin should have the expected exports 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"configs": {
|
|
6
|
+
"all": {
|
|
7
|
+
"overrides": [
|
|
8
|
+
{
|
|
9
|
+
"files": [
|
|
10
|
+
"*.cts",
|
|
11
|
+
"*.mts",
|
|
12
|
+
"*.ts",
|
|
13
|
+
"*.tsx",
|
|
14
|
+
],
|
|
15
|
+
"parser": "@typescript-eslint/parser",
|
|
16
|
+
"parserOptions": {
|
|
17
|
+
"project": true,
|
|
18
|
+
"warnOnUnsupportedTypeScriptVersion": false,
|
|
19
|
+
},
|
|
20
|
+
"rules": {
|
|
21
|
+
"@definitelytyped/expect": "error",
|
|
22
|
+
"@definitelytyped/export-just-namespace": "error",
|
|
23
|
+
"@definitelytyped/no-any-union": "error",
|
|
24
|
+
"@definitelytyped/no-bad-reference": "error",
|
|
25
|
+
"@definitelytyped/no-const-enum": "error",
|
|
26
|
+
"@definitelytyped/no-dead-reference": "error",
|
|
27
|
+
"@definitelytyped/no-declare-current-package": "error",
|
|
28
|
+
"@definitelytyped/no-import-default-of-export-equals": "error",
|
|
29
|
+
"@definitelytyped/no-import-of-dev-dependencies": "error",
|
|
30
|
+
"@definitelytyped/no-old-dt-header": "error",
|
|
31
|
+
"@definitelytyped/no-relative-import-in-test": "error",
|
|
32
|
+
"@definitelytyped/no-self-import": "error",
|
|
33
|
+
"@definitelytyped/no-single-declare-module": "error",
|
|
34
|
+
"@definitelytyped/no-single-element-tuple-type": "error",
|
|
35
|
+
"@definitelytyped/no-unnecessary-generics": "error",
|
|
36
|
+
"@definitelytyped/no-useless-files": "error",
|
|
37
|
+
"@definitelytyped/prefer-declare-function": "error",
|
|
38
|
+
"@definitelytyped/redundant-undefined": "error",
|
|
39
|
+
"@definitelytyped/strict-export-declare-modifiers": "error",
|
|
40
|
+
"@typescript-eslint/adjacent-overload-signatures": "error",
|
|
41
|
+
"@typescript-eslint/array-type": [
|
|
42
|
+
"error",
|
|
43
|
+
{
|
|
44
|
+
"default": "array-simple",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
"@typescript-eslint/ban-ts-comment": [
|
|
48
|
+
"error",
|
|
49
|
+
{
|
|
50
|
+
"ts-check": false,
|
|
51
|
+
"ts-expect-error": false,
|
|
52
|
+
"ts-ignore": "allow-with-description",
|
|
53
|
+
"ts-nocheck": true,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"@typescript-eslint/ban-types": [
|
|
57
|
+
"error",
|
|
58
|
+
{
|
|
59
|
+
"extendDefaults": true,
|
|
60
|
+
"types": {
|
|
61
|
+
"{}": false,
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
"@typescript-eslint/consistent-type-definitions": "error",
|
|
66
|
+
"@typescript-eslint/explicit-member-accessibility": [
|
|
67
|
+
"error",
|
|
68
|
+
{
|
|
69
|
+
"accessibility": "no-public",
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
"@typescript-eslint/naming-convention": [
|
|
73
|
+
"error",
|
|
74
|
+
{
|
|
75
|
+
"custom": {
|
|
76
|
+
"match": false,
|
|
77
|
+
"regex": "^I[A-Z]",
|
|
78
|
+
},
|
|
79
|
+
"format": [],
|
|
80
|
+
"selector": "interface",
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
"@typescript-eslint/no-empty-interface": "error",
|
|
84
|
+
"@typescript-eslint/no-invalid-void-type": [
|
|
85
|
+
"error",
|
|
86
|
+
{
|
|
87
|
+
"allowAsThisParameter": true,
|
|
88
|
+
"allowInGenericTypeArguments": true,
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
"@typescript-eslint/no-misused-new": "error",
|
|
92
|
+
"@typescript-eslint/prefer-namespace-keyword": "error",
|
|
93
|
+
"@typescript-eslint/triple-slash-reference": [
|
|
94
|
+
"error",
|
|
95
|
+
{
|
|
96
|
+
"path": "always",
|
|
97
|
+
"types": "prefer-import",
|
|
98
|
+
},
|
|
99
|
+
],
|
|
100
|
+
"no-duplicate-imports": "error",
|
|
101
|
+
"unicode-bom": [
|
|
102
|
+
"error",
|
|
103
|
+
"never",
|
|
104
|
+
],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
"plugins": [
|
|
109
|
+
"@definitelytyped",
|
|
110
|
+
"@typescript-eslint",
|
|
111
|
+
"jsdoc",
|
|
112
|
+
],
|
|
113
|
+
"rules": {
|
|
114
|
+
"jsdoc/check-tag-names": [
|
|
115
|
+
"error",
|
|
116
|
+
{
|
|
117
|
+
"definedTags": [
|
|
118
|
+
"addVersion",
|
|
119
|
+
"also",
|
|
120
|
+
"api",
|
|
121
|
+
"author",
|
|
122
|
+
"beta",
|
|
123
|
+
"brief",
|
|
124
|
+
"category",
|
|
125
|
+
"cfg",
|
|
126
|
+
"chainable",
|
|
127
|
+
"check",
|
|
128
|
+
"checkReturnValue",
|
|
129
|
+
"classDescription",
|
|
130
|
+
"condparamprivilege",
|
|
131
|
+
"constraint",
|
|
132
|
+
"credits",
|
|
133
|
+
"declaration",
|
|
134
|
+
"defApiFeature",
|
|
135
|
+
"defaultValue",
|
|
136
|
+
"detail",
|
|
137
|
+
"end",
|
|
138
|
+
"eventproperty",
|
|
139
|
+
"experimental",
|
|
140
|
+
"export",
|
|
141
|
+
"expose",
|
|
142
|
+
"extendscript",
|
|
143
|
+
"factory",
|
|
144
|
+
"field",
|
|
145
|
+
"final",
|
|
146
|
+
"fixme",
|
|
147
|
+
"fluent",
|
|
148
|
+
"for",
|
|
149
|
+
"governance",
|
|
150
|
+
"header",
|
|
151
|
+
"hidden-property",
|
|
152
|
+
"hidden",
|
|
153
|
+
"id",
|
|
154
|
+
"jsx",
|
|
155
|
+
"jsxImportSource",
|
|
156
|
+
"label",
|
|
157
|
+
"language",
|
|
158
|
+
"legacy",
|
|
159
|
+
"link",
|
|
160
|
+
"listen",
|
|
161
|
+
"locus",
|
|
162
|
+
"methodOf",
|
|
163
|
+
"minVersion",
|
|
164
|
+
"ngdoc",
|
|
165
|
+
"nonstandard",
|
|
166
|
+
"note",
|
|
167
|
+
"npm",
|
|
168
|
+
"observable",
|
|
169
|
+
"option",
|
|
170
|
+
"optionobject",
|
|
171
|
+
"options",
|
|
172
|
+
"packageDocumentation",
|
|
173
|
+
"param",
|
|
174
|
+
"parent",
|
|
175
|
+
"platform",
|
|
176
|
+
"plugin",
|
|
177
|
+
"preserve",
|
|
178
|
+
"privateRemarks",
|
|
179
|
+
"privilegeLevel",
|
|
180
|
+
"privilegeName",
|
|
181
|
+
"proposed",
|
|
182
|
+
"range",
|
|
183
|
+
"readOnly",
|
|
184
|
+
"related",
|
|
185
|
+
"remark",
|
|
186
|
+
"remarks",
|
|
187
|
+
"required",
|
|
188
|
+
"requires",
|
|
189
|
+
"restriction",
|
|
190
|
+
"returnType",
|
|
191
|
+
"section",
|
|
192
|
+
"see",
|
|
193
|
+
"since",
|
|
194
|
+
"const",
|
|
195
|
+
"singleton",
|
|
196
|
+
"source",
|
|
197
|
+
"struct",
|
|
198
|
+
"suppress",
|
|
199
|
+
"targetfolder",
|
|
200
|
+
"enum",
|
|
201
|
+
"title",
|
|
202
|
+
"record",
|
|
203
|
+
"title",
|
|
204
|
+
"TODO",
|
|
205
|
+
"trigger",
|
|
206
|
+
"triggers",
|
|
207
|
+
"typeparam",
|
|
208
|
+
"typeParam",
|
|
209
|
+
"unsupported",
|
|
210
|
+
"url",
|
|
211
|
+
"usage",
|
|
212
|
+
"warn",
|
|
213
|
+
"warning",
|
|
214
|
+
"version",
|
|
215
|
+
],
|
|
216
|
+
"typed": true,
|
|
217
|
+
},
|
|
218
|
+
],
|
|
219
|
+
},
|
|
220
|
+
"settings": {
|
|
221
|
+
"jsdoc": {
|
|
222
|
+
"tagNamePreference": {
|
|
223
|
+
"argument": "argument",
|
|
224
|
+
"exception": "exception",
|
|
225
|
+
"function": "function",
|
|
226
|
+
"method": "method",
|
|
227
|
+
"param": "param",
|
|
228
|
+
"return": "return",
|
|
229
|
+
"returns": "returns",
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
"meta": {
|
|
236
|
+
"name": "@definitelytyped/eslint-plugin",
|
|
237
|
+
"version": "version",
|
|
238
|
+
},
|
|
239
|
+
"rules": [
|
|
240
|
+
"export-just-namespace",
|
|
241
|
+
"no-any-union",
|
|
242
|
+
"no-bad-reference",
|
|
243
|
+
"no-const-enum",
|
|
244
|
+
"no-dead-reference",
|
|
245
|
+
"no-declare-current-package",
|
|
246
|
+
"no-import-default-of-export-equals",
|
|
247
|
+
"no-relative-import-in-test",
|
|
248
|
+
"no-self-import",
|
|
249
|
+
"no-single-element-tuple-type",
|
|
250
|
+
"no-unnecessary-generics",
|
|
251
|
+
"no-useless-files",
|
|
252
|
+
"prefer-declare-function",
|
|
253
|
+
"redundant-undefined",
|
|
254
|
+
"strict-export-declare-modifiers",
|
|
255
|
+
"no-single-declare-module",
|
|
256
|
+
"no-old-dt-header",
|
|
257
|
+
"no-import-of-dev-dependencies",
|
|
258
|
+
"npm-naming",
|
|
259
|
+
"expect",
|
|
260
|
+
],
|
|
261
|
+
}
|
|
262
|
+
`;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { RuleTester } from "@typescript-eslint/rule-tester";
|
|
2
|
+
|
|
3
|
+
import * as npmNaming from "../src/rules/npm-naming";
|
|
4
|
+
import { ErrorKind, Mode } from "@definitelytyped/dts-critic";
|
|
5
|
+
|
|
6
|
+
const ruleTester = new RuleTester({
|
|
7
|
+
parser: "@typescript-eslint/parser",
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
ruleTester.run("npm-naming", npmNaming, {
|
|
11
|
+
invalid: [
|
|
12
|
+
{
|
|
13
|
+
code: `export default dtsCritic();`,
|
|
14
|
+
errors: [
|
|
15
|
+
{
|
|
16
|
+
data: {
|
|
17
|
+
error: `The declaration doesn't match the JavaScript module 'dts-critic'. Reason:
|
|
18
|
+
The declaration should use 'export =' syntax because the JavaScript source uses 'module.exports =' syntax and 'module.exports' can be called or constructed.
|
|
19
|
+
|
|
20
|
+
To learn more about 'export =' syntax, see https://www.typescriptlang.org/docs/handbook/modules.html#export--and-import--require.`,
|
|
21
|
+
option: `["error",{"mode":"code","errors":[["NeedsExportEquals",false]]}]`,
|
|
22
|
+
},
|
|
23
|
+
column: 1,
|
|
24
|
+
endColumn: 1,
|
|
25
|
+
line: 1,
|
|
26
|
+
endLine: 2,
|
|
27
|
+
messageId: "error",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
filename: "packages/eslint-plugin/test/types/dts-critic/index.d.ts",
|
|
31
|
+
options: [{ mode: Mode.Code, errors: [[ErrorKind.NeedsExportEquals, true]] }],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
code: `// test content`,
|
|
35
|
+
errors: [
|
|
36
|
+
{
|
|
37
|
+
data: {
|
|
38
|
+
error: `Declaration file must have a matching npm package.
|
|
39
|
+
To resolve this error, either:
|
|
40
|
+
1. Change the name to match an npm package.
|
|
41
|
+
2. Add \`\"nonNpm\": true\` to the package.json to indicate that this is not an npm package.
|
|
42
|
+
Ensure the package name is descriptive enough to avoid conflicts with future npm packages.`,
|
|
43
|
+
option: `"off"`,
|
|
44
|
+
},
|
|
45
|
+
column: 1,
|
|
46
|
+
endColumn: 1,
|
|
47
|
+
line: 1,
|
|
48
|
+
endLine: 2,
|
|
49
|
+
messageId: "error",
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
filename: "packages/eslint-plugin/test/types/wenceslas/index.d.ts",
|
|
53
|
+
options: [{ mode: Mode.NameOnly }],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
valid: [],
|
|
57
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import plugin = require("../src/index");
|
|
2
|
+
|
|
3
|
+
describe("plugin", () => {
|
|
4
|
+
it("should have the expected exports", () => {
|
|
5
|
+
expect({
|
|
6
|
+
...plugin,
|
|
7
|
+
meta: {
|
|
8
|
+
...plugin.meta,
|
|
9
|
+
version: "version",
|
|
10
|
+
},
|
|
11
|
+
rules: Object.keys(plugin.rules),
|
|
12
|
+
}).toMatchSnapshot();
|
|
13
|
+
});
|
|
14
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
declare function _default(): void;
|
|
2
|
+
|
|
3
|
+
declare namespace _default {
|
|
4
|
+
export function findDtsName(dtsPath: string): string;
|
|
5
|
+
export function checkNames(names: string[]): unknown;
|
|
6
|
+
export function checkSource(text: string): unknown;
|
|
7
|
+
export function findNames(): string[];
|
|
8
|
+
export function retrieveNpmHomepageOrFail(): string[];
|
|
9
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"devDependencies": {
|
|
3
|
+
"@types/dts-critic": "workspace:."
|
|
4
|
+
},
|
|
5
|
+
"private": true,
|
|
6
|
+
"projects": [
|
|
7
|
+
"https://typescriptlang.org"
|
|
8
|
+
],
|
|
9
|
+
"version": "1.0.9999",
|
|
10
|
+
"name": "@types/dts-critic",
|
|
11
|
+
"owners": [
|
|
12
|
+
{
|
|
13
|
+
"githubUsername": "ghost",
|
|
14
|
+
"name": "Not Default"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"devDependencies": {
|
|
3
|
+
"@types/wenceslas": "workspace:."
|
|
4
|
+
},
|
|
5
|
+
"private": true,
|
|
6
|
+
"projects": [
|
|
7
|
+
"https://typescriptlang.org"
|
|
8
|
+
],
|
|
9
|
+
"version": "0.9.9999",
|
|
10
|
+
"name": "@types/wenceslas",
|
|
11
|
+
"owners": [
|
|
12
|
+
{
|
|
13
|
+
"githubUsername": "ghost",
|
|
14
|
+
"name": "Not Default"
|
|
15
|
+
}
|
|
16
|
+
]
|
|
17
|
+
}
|