eslint-plugin-node-dependencies 1.1.2 → 1.3.0
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/README.md +1 -0
- package/dist/configs/flat/recommended.d.ts +2 -2
- package/dist/configs/recommended.d.ts +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/rules/absolute-version.js +2 -1
- package/dist/rules/compat-engines.js +2 -1
- package/dist/rules/no-deprecated.js +2 -1
- package/dist/rules/no-dupe-deps.js +2 -1
- package/dist/rules/no-restricted-deps.js +2 -1
- package/dist/rules/prefer-caret-range-version.js +2 -1
- package/dist/rules/prefer-tilde-range-version.js +2 -1
- package/dist/rules/require-provenance-deps.d.ts +2 -0
- package/dist/rules/require-provenance-deps.js +98 -0
- package/dist/rules/valid-semver.js +2 -1
- package/dist/utils/meta.d.ts +5 -0
- package/dist/utils/meta.js +10 -9
- package/dist/utils/rules.js +2 -0
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -158,6 +158,7 @@ The rules with the following star :star: are included in the `plugin:node-depend
|
|
|
158
158
|
| [node-dependencies/absolute-version](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/absolute-version.html) | require or disallow absolute version of dependency. | |
|
|
159
159
|
| [node-dependencies/no-deprecated](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/no-deprecated.html) | disallow having dependencies on deprecate packages. | |
|
|
160
160
|
| [node-dependencies/no-restricted-deps](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/no-restricted-deps.html) | Disallows dependence on the specified package. | |
|
|
161
|
+
| [node-dependencies/require-provenance-deps](https://ota-meshi.github.io/eslint-plugin-node-dependencies/rules/require-provenance-deps.html) | Require provenance information for dependencies | |
|
|
161
162
|
|
|
162
163
|
### Stylistic Issues
|
|
163
164
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ESLint
|
|
1
|
+
import type { ESLint } from "eslint";
|
|
2
2
|
import * as jsonParser from "jsonc-eslint-parser";
|
|
3
3
|
export declare const recommendedConfig: ({
|
|
4
4
|
plugins: {
|
|
@@ -12,6 +12,6 @@ export declare const recommendedConfig: ({
|
|
|
12
12
|
languageOptions: {
|
|
13
13
|
parser: typeof jsonParser;
|
|
14
14
|
};
|
|
15
|
-
rules:
|
|
15
|
+
rules: import("@eslint/core").RulesConfig;
|
|
16
16
|
plugins?: undefined;
|
|
17
17
|
})[];
|
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ declare const _default: {
|
|
|
8
8
|
overrides: {
|
|
9
9
|
files: string[];
|
|
10
10
|
parser: string;
|
|
11
|
-
rules: import("eslint").
|
|
11
|
+
rules: import("@eslint/core").RulesConfig;
|
|
12
12
|
}[];
|
|
13
13
|
};
|
|
14
14
|
"flat/recommended": ({
|
|
@@ -23,7 +23,7 @@ declare const _default: {
|
|
|
23
23
|
languageOptions: {
|
|
24
24
|
parser: typeof import("jsonc-eslint-parser");
|
|
25
25
|
};
|
|
26
|
-
rules: import("eslint").
|
|
26
|
+
rules: import("@eslint/core").RulesConfig;
|
|
27
27
|
plugins?: undefined;
|
|
28
28
|
})[];
|
|
29
29
|
};
|
|
@@ -5,6 +5,7 @@ const utils_1 = require("../utils");
|
|
|
5
5
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
6
6
|
const regexp_1 = require("../utils/regexp");
|
|
7
7
|
const semver_1 = require("../utils/semver");
|
|
8
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
8
9
|
const PREFERS = ["always", "never", "ignore"];
|
|
9
10
|
const SCHEMA_FOR_DEPS_PROPERTIES = {
|
|
10
11
|
dependencies: { enum: PREFERS },
|
|
@@ -100,7 +101,7 @@ exports.default = (0, utils_1.createRule)("absolute-version", {
|
|
|
100
101
|
type: "suggestion",
|
|
101
102
|
},
|
|
102
103
|
create(context) {
|
|
103
|
-
const sourceCode =
|
|
104
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
104
105
|
if (!sourceCode.parserServices.isJSON) {
|
|
105
106
|
return {};
|
|
106
107
|
}
|
|
@@ -9,6 +9,7 @@ const semver_1 = __importDefault(require("semver"));
|
|
|
9
9
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
10
10
|
const semver_2 = require("../utils/semver");
|
|
11
11
|
const meta_1 = require("../utils/meta");
|
|
12
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
12
13
|
class EnginesContext {
|
|
13
14
|
constructor(engineNames, validDependencies = new Set()) {
|
|
14
15
|
this.unprocessedEngines = new Set();
|
|
@@ -141,7 +142,7 @@ exports.default = (0, utils_1.createRule)("compat-engines", {
|
|
|
141
142
|
},
|
|
142
143
|
create(context) {
|
|
143
144
|
var _a, _b, _c;
|
|
144
|
-
const sourceCode =
|
|
145
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
145
146
|
if (!sourceCode.parserServices.isJSON) {
|
|
146
147
|
return {};
|
|
147
148
|
}
|
|
@@ -4,6 +4,7 @@ const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
|
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
6
6
|
const meta_1 = require("../utils/meta");
|
|
7
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
7
8
|
exports.default = (0, utils_1.createRule)("no-deprecated", {
|
|
8
9
|
meta: {
|
|
9
10
|
docs: {
|
|
@@ -30,7 +31,7 @@ exports.default = (0, utils_1.createRule)("no-deprecated", {
|
|
|
30
31
|
},
|
|
31
32
|
create(context) {
|
|
32
33
|
var _a;
|
|
33
|
-
const sourceCode =
|
|
34
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
34
35
|
if (!sourceCode.parserServices.isJSON) {
|
|
35
36
|
return {};
|
|
36
37
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const utils_1 = require("../utils");
|
|
4
4
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
5
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
5
6
|
const DEPS = [
|
|
6
7
|
"dependencies",
|
|
7
8
|
"peerDependencies",
|
|
@@ -33,7 +34,7 @@ exports.default = (0, utils_1.createRule)("no-dupe-deps", {
|
|
|
33
34
|
type: "problem",
|
|
34
35
|
},
|
|
35
36
|
create(context) {
|
|
36
|
-
const sourceCode =
|
|
37
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
37
38
|
if (!sourceCode.parserServices.isJSON) {
|
|
38
39
|
return {};
|
|
39
40
|
}
|
|
@@ -7,6 +7,7 @@ const semver_2 = require("../utils/semver");
|
|
|
7
7
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
8
8
|
const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
|
|
9
9
|
const meta_1 = require("../utils/meta");
|
|
10
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
10
11
|
const DEPS = [
|
|
11
12
|
"dependencies",
|
|
12
13
|
"peerDependencies",
|
|
@@ -173,7 +174,7 @@ exports.default = (0, utils_1.createRule)("no-restricted-deps", {
|
|
|
173
174
|
type: "suggestion",
|
|
174
175
|
},
|
|
175
176
|
create(context) {
|
|
176
|
-
const sourceCode =
|
|
177
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
177
178
|
if (!sourceCode.parserServices.isJSON) {
|
|
178
179
|
return {};
|
|
179
180
|
}
|
|
@@ -4,6 +4,7 @@ const semver_1 = require("semver");
|
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const semver_2 = require("../utils/semver");
|
|
6
6
|
const semver_range_1 = require("../utils/semver-range");
|
|
7
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
7
8
|
exports.default = (0, utils_1.createRule)("prefer-caret-range-version", {
|
|
8
9
|
meta: {
|
|
9
10
|
docs: {
|
|
@@ -17,7 +18,7 @@ exports.default = (0, utils_1.createRule)("prefer-caret-range-version", {
|
|
|
17
18
|
type: "suggestion",
|
|
18
19
|
},
|
|
19
20
|
create(context) {
|
|
20
|
-
const sourceCode =
|
|
21
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
21
22
|
if (!sourceCode.parserServices.isJSON) {
|
|
22
23
|
return {};
|
|
23
24
|
}
|
|
@@ -4,6 +4,7 @@ const semver_1 = require("semver");
|
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const semver_2 = require("../utils/semver");
|
|
6
6
|
const semver_range_1 = require("../utils/semver-range");
|
|
7
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
7
8
|
exports.default = (0, utils_1.createRule)("prefer-tilde-range-version", {
|
|
8
9
|
meta: {
|
|
9
10
|
docs: {
|
|
@@ -17,7 +18,7 @@ exports.default = (0, utils_1.createRule)("prefer-tilde-range-version", {
|
|
|
17
18
|
type: "suggestion",
|
|
18
19
|
},
|
|
19
20
|
create(context) {
|
|
20
|
-
const sourceCode =
|
|
21
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
21
22
|
if (!sourceCode.parserServices.isJSON) {
|
|
22
23
|
return {};
|
|
23
24
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("../utils");
|
|
4
|
+
const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
|
|
5
|
+
const ast_utils_1 = require("../utils/ast-utils");
|
|
6
|
+
const meta_1 = require("../utils/meta");
|
|
7
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
8
|
+
exports.default = (0, utils_1.createRule)("require-provenance-deps", {
|
|
9
|
+
meta: {
|
|
10
|
+
docs: {
|
|
11
|
+
description: "Require provenance information for dependencies",
|
|
12
|
+
category: "Best Practices",
|
|
13
|
+
recommended: false,
|
|
14
|
+
},
|
|
15
|
+
schema: [
|
|
16
|
+
{
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
devDependencies: { type: "boolean" },
|
|
20
|
+
allows: {
|
|
21
|
+
type: "array",
|
|
22
|
+
items: { type: "string" },
|
|
23
|
+
uniqueItems: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
additionalProperties: false,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
messages: {
|
|
30
|
+
missingProvenance: 'Dependency "{{name}}" has versions without provenance information: {{versions}}.',
|
|
31
|
+
},
|
|
32
|
+
type: "suggestion",
|
|
33
|
+
},
|
|
34
|
+
create(context) {
|
|
35
|
+
var _a;
|
|
36
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
37
|
+
if (!sourceCode.parserServices.isJSON) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
const devDependencies = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.devDependencies);
|
|
41
|
+
function extractNoProvenanceRanges(meta) {
|
|
42
|
+
var _a, _b;
|
|
43
|
+
const noProvenanceRanges = [];
|
|
44
|
+
let prev = null;
|
|
45
|
+
for (let index = 0; index < meta.length; index++) {
|
|
46
|
+
const m = meta[index];
|
|
47
|
+
if ((_b = (_a = m.dist) === null || _a === void 0 ? void 0 : _a.attestations) === null || _b === void 0 ? void 0 : _b.provenance) {
|
|
48
|
+
prev = null;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (prev == null) {
|
|
52
|
+
prev = [m.version, m.version];
|
|
53
|
+
noProvenanceRanges.push(prev);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
prev[1] = m.version;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return noProvenanceRanges;
|
|
60
|
+
}
|
|
61
|
+
return (0, utils_1.defineJsonVisitor)({
|
|
62
|
+
[devDependencies
|
|
63
|
+
? "dependencies, peerDependencies, devDependencies"
|
|
64
|
+
: "dependencies, peerDependencies"](node) {
|
|
65
|
+
var _a, _b;
|
|
66
|
+
const name = (0, ast_utils_1.getKeyFromJSONProperty)(node);
|
|
67
|
+
const ver = (0, jsonc_eslint_parser_1.getStaticJSONValue)(node.value);
|
|
68
|
+
if (typeof name !== "string" || typeof ver !== "string" || !ver) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if ((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allows) === null || _b === void 0 ? void 0 : _b.includes(name)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const meta = (0, meta_1.getMetaFromNpm)(name, ver).get();
|
|
75
|
+
if (!meta || !meta.length) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const noProvenanceRanges = extractNoProvenanceRanges(meta);
|
|
79
|
+
if (noProvenanceRanges.length === 0) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
context.report({
|
|
83
|
+
loc: node.loc,
|
|
84
|
+
messageId: "missingProvenance",
|
|
85
|
+
data: {
|
|
86
|
+
name,
|
|
87
|
+
versions: formatList(noProvenanceRanges.map(([from, to]) => from === to ? `${from}` : `${from} - ${to}`)),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
function formatList(items) {
|
|
93
|
+
return items.length <= 2
|
|
94
|
+
? items.join(" and ")
|
|
95
|
+
: `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
});
|
|
@@ -4,6 +4,7 @@ const jsonc_eslint_parser_1 = require("jsonc-eslint-parser");
|
|
|
4
4
|
const utils_1 = require("../utils");
|
|
5
5
|
const ast_utils_1 = require("../utils/ast-utils");
|
|
6
6
|
const semver_1 = require("../utils/semver");
|
|
7
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
7
8
|
exports.default = (0, utils_1.createRule)("valid-semver", {
|
|
8
9
|
meta: {
|
|
9
10
|
docs: {
|
|
@@ -16,7 +17,7 @@ exports.default = (0, utils_1.createRule)("valid-semver", {
|
|
|
16
17
|
type: "problem",
|
|
17
18
|
},
|
|
18
19
|
create(context) {
|
|
19
|
-
const sourceCode =
|
|
20
|
+
const sourceCode = (0, eslint_compat_utils_1.getSourceCode)(context);
|
|
20
21
|
if (!sourceCode.parserServices.isJSON) {
|
|
21
22
|
return {};
|
|
22
23
|
}
|
package/dist/utils/meta.d.ts
CHANGED
|
@@ -12,6 +12,11 @@ export type NpmPackageMeta = PackageMeta & {
|
|
|
12
12
|
"dist-tags": {
|
|
13
13
|
[key: string]: string | void;
|
|
14
14
|
} | undefined;
|
|
15
|
+
dist?: {
|
|
16
|
+
attestations?: {
|
|
17
|
+
provenance?: Record<string, unknown>;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
15
20
|
};
|
|
16
21
|
export declare function getMetaFromNodeModules(name: string, ver: string, options: {
|
|
17
22
|
context: Rule.RuleContext;
|
package/dist/utils/meta.js
CHANGED
|
@@ -47,14 +47,16 @@ const semver_1 = require("./semver");
|
|
|
47
47
|
const semver_2 = require("semver");
|
|
48
48
|
const npm_package_arg_1 = __importDefault(require("npm-package-arg"));
|
|
49
49
|
const package_json_1 = require("./package-json");
|
|
50
|
+
const eslint_compat_utils_1 = require("eslint-compat-utils");
|
|
50
51
|
const TTL = 1000 * 60 * 60;
|
|
52
|
+
const CACHE_VERSION = 2;
|
|
51
53
|
const CACHED_META_ROOT = path_1.default.join(__dirname, `../../.cached_meta`);
|
|
52
54
|
function getMetaFromNodeModules(name, ver, options) {
|
|
53
55
|
try {
|
|
54
|
-
const ownerJsonPath = options.ownerPackageJsonPath || options.context
|
|
56
|
+
const ownerJsonPath = options.ownerPackageJsonPath || (0, eslint_compat_utils_1.getFilename)(options.context);
|
|
55
57
|
const relativeTo = path_1.default.join(ownerJsonPath && path_1.default.isAbsolute(ownerJsonPath)
|
|
56
58
|
? (0, path_1.dirname)(ownerJsonPath)
|
|
57
|
-
: getCwd(options.context), "__placeholder__.js");
|
|
59
|
+
: (0, eslint_compat_utils_1.getCwd)(options.context), "__placeholder__.js");
|
|
58
60
|
const req = module_1.default.createRequire(relativeTo);
|
|
59
61
|
const where = req.resolve(`${name}/package.json`);
|
|
60
62
|
const pkg = req(where);
|
|
@@ -176,7 +178,10 @@ function getMetaFromName(name, cachedFilePath) {
|
|
|
176
178
|
return null;
|
|
177
179
|
}
|
|
178
180
|
const data = require(cachedFilePath);
|
|
179
|
-
if (data.meta == null) {
|
|
181
|
+
if (!data || data.meta == null) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
if (data.v !== CACHE_VERSION) {
|
|
180
185
|
return null;
|
|
181
186
|
}
|
|
182
187
|
const alive = Boolean((typeof data.expired === "number" && data.expired >= Date.now()) ||
|
|
@@ -202,6 +207,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
|
|
|
202
207
|
optionalDependencies: vm.optionalDependencies,
|
|
203
208
|
"dist-tags": allMeta["dist-tags"],
|
|
204
209
|
deprecated: vm.deprecated,
|
|
210
|
+
dist: vm.dist,
|
|
205
211
|
};
|
|
206
212
|
});
|
|
207
213
|
}
|
|
@@ -210,6 +216,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
|
|
|
210
216
|
}
|
|
211
217
|
const timestamp = Date.now();
|
|
212
218
|
const content = {
|
|
219
|
+
v: CACHE_VERSION,
|
|
213
220
|
meta,
|
|
214
221
|
timestamp,
|
|
215
222
|
expired: timestamp + Math.floor(Math.random() * 1000 * 60),
|
|
@@ -260,9 +267,3 @@ function makeDirs(dir) {
|
|
|
260
267
|
fs_1.default.mkdirSync(d);
|
|
261
268
|
}
|
|
262
269
|
}
|
|
263
|
-
function getCwd(context) {
|
|
264
|
-
if (context.getCwd) {
|
|
265
|
-
return context.getCwd();
|
|
266
|
-
}
|
|
267
|
-
return path_1.default.resolve("");
|
|
268
|
-
}
|
package/dist/utils/rules.js
CHANGED
|
@@ -11,6 +11,7 @@ const no_dupe_deps_1 = __importDefault(require("../rules/no-dupe-deps"));
|
|
|
11
11
|
const no_restricted_deps_1 = __importDefault(require("../rules/no-restricted-deps"));
|
|
12
12
|
const prefer_caret_range_version_1 = __importDefault(require("../rules/prefer-caret-range-version"));
|
|
13
13
|
const prefer_tilde_range_version_1 = __importDefault(require("../rules/prefer-tilde-range-version"));
|
|
14
|
+
const require_provenance_deps_1 = __importDefault(require("../rules/require-provenance-deps"));
|
|
14
15
|
const valid_engines_1 = __importDefault(require("../rules/valid-engines"));
|
|
15
16
|
const valid_semver_1 = __importDefault(require("../rules/valid-semver"));
|
|
16
17
|
exports.rules = [
|
|
@@ -21,6 +22,7 @@ exports.rules = [
|
|
|
21
22
|
no_restricted_deps_1.default,
|
|
22
23
|
prefer_caret_range_version_1.default,
|
|
23
24
|
prefer_tilde_range_version_1.default,
|
|
25
|
+
require_provenance_deps_1.default,
|
|
24
26
|
valid_engines_1.default,
|
|
25
27
|
valid_semver_1.default,
|
|
26
28
|
];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-node-dependencies",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "ESLint plugin to check Node.js dependencies.",
|
|
5
5
|
"repository": "git+https://github.com/ota-meshi/eslint-plugin-node-dependencies.git",
|
|
6
6
|
"homepage": "https://github.com/ota-meshi/eslint-plugin-node-dependencies#readme",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"eslint": ">=6.0.0"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
+
"eslint-compat-utils": "^0.6.5",
|
|
36
37
|
"jsonc-eslint-parser": "^2.0.2",
|
|
37
38
|
"npm-package-arg": "^12.0.2",
|
|
38
39
|
"package-json": "^10.0.1",
|