eslint-plugin-node-dependencies 1.1.2 → 1.2.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/require-provenance-deps.d.ts +2 -0
- package/dist/rules/require-provenance-deps.js +97 -0
- package/dist/utils/meta.d.ts +5 -0
- package/dist/utils/meta.js +7 -1
- package/dist/utils/rules.js +2 -0
- package/package.json +1 -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
|
};
|
|
@@ -0,0 +1,97 @@
|
|
|
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
|
+
exports.default = (0, utils_1.createRule)("require-provenance-deps", {
|
|
8
|
+
meta: {
|
|
9
|
+
docs: {
|
|
10
|
+
description: "Require provenance information for dependencies",
|
|
11
|
+
category: "Best Practices",
|
|
12
|
+
recommended: false,
|
|
13
|
+
},
|
|
14
|
+
schema: [
|
|
15
|
+
{
|
|
16
|
+
type: "object",
|
|
17
|
+
properties: {
|
|
18
|
+
devDependencies: { type: "boolean" },
|
|
19
|
+
allows: {
|
|
20
|
+
type: "array",
|
|
21
|
+
items: { type: "string" },
|
|
22
|
+
uniqueItems: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
messages: {
|
|
29
|
+
missingProvenance: 'Dependency "{{name}}" has versions without provenance information: {{versions}}.',
|
|
30
|
+
},
|
|
31
|
+
type: "suggestion",
|
|
32
|
+
},
|
|
33
|
+
create(context) {
|
|
34
|
+
var _a;
|
|
35
|
+
const sourceCode = context.getSourceCode();
|
|
36
|
+
if (!sourceCode.parserServices.isJSON) {
|
|
37
|
+
return {};
|
|
38
|
+
}
|
|
39
|
+
const devDependencies = Boolean((_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.devDependencies);
|
|
40
|
+
function extractNoProvenanceRanges(meta) {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
const noProvenanceRanges = [];
|
|
43
|
+
let prev = null;
|
|
44
|
+
for (let index = 0; index < meta.length; index++) {
|
|
45
|
+
const m = meta[index];
|
|
46
|
+
if ((_b = (_a = m.dist) === null || _a === void 0 ? void 0 : _a.attestations) === null || _b === void 0 ? void 0 : _b.provenance) {
|
|
47
|
+
prev = null;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (prev == null) {
|
|
51
|
+
prev = [m.version, m.version];
|
|
52
|
+
noProvenanceRanges.push(prev);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
prev[1] = m.version;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return noProvenanceRanges;
|
|
59
|
+
}
|
|
60
|
+
return (0, utils_1.defineJsonVisitor)({
|
|
61
|
+
[devDependencies
|
|
62
|
+
? "dependencies, peerDependencies, devDependencies"
|
|
63
|
+
: "dependencies, peerDependencies"](node) {
|
|
64
|
+
var _a, _b;
|
|
65
|
+
const name = (0, ast_utils_1.getKeyFromJSONProperty)(node);
|
|
66
|
+
const ver = (0, jsonc_eslint_parser_1.getStaticJSONValue)(node.value);
|
|
67
|
+
if (typeof name !== "string" || typeof ver !== "string" || !ver) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
if ((_b = (_a = context.options[0]) === null || _a === void 0 ? void 0 : _a.allows) === null || _b === void 0 ? void 0 : _b.includes(name)) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const meta = (0, meta_1.getMetaFromNpm)(name, ver).get();
|
|
74
|
+
if (!meta || !meta.length) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const noProvenanceRanges = extractNoProvenanceRanges(meta);
|
|
78
|
+
if (noProvenanceRanges.length === 0) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
context.report({
|
|
82
|
+
loc: node.loc,
|
|
83
|
+
messageId: "missingProvenance",
|
|
84
|
+
data: {
|
|
85
|
+
name,
|
|
86
|
+
versions: formatList(noProvenanceRanges.map(([from, to]) => from === to ? `${from}` : `${from} - ${to}`)),
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
function formatList(items) {
|
|
92
|
+
return items.length <= 2
|
|
93
|
+
? items.join(" and ")
|
|
94
|
+
: `${items.slice(0, -1).join(", ")}, and ${items[items.length - 1]}`;
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
});
|
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
|
@@ -48,6 +48,7 @@ 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
50
|
const TTL = 1000 * 60 * 60;
|
|
51
|
+
const CACHE_VERSION = 2;
|
|
51
52
|
const CACHED_META_ROOT = path_1.default.join(__dirname, `../../.cached_meta`);
|
|
52
53
|
function getMetaFromNodeModules(name, ver, options) {
|
|
53
54
|
try {
|
|
@@ -176,7 +177,10 @@ function getMetaFromName(name, cachedFilePath) {
|
|
|
176
177
|
return null;
|
|
177
178
|
}
|
|
178
179
|
const data = require(cachedFilePath);
|
|
179
|
-
if (data.meta == null) {
|
|
180
|
+
if (!data || data.meta == null) {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
if (data.v !== CACHE_VERSION) {
|
|
180
184
|
return null;
|
|
181
185
|
}
|
|
182
186
|
const alive = Boolean((typeof data.expired === "number" && data.expired >= Date.now()) ||
|
|
@@ -202,6 +206,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
|
|
|
202
206
|
optionalDependencies: vm.optionalDependencies,
|
|
203
207
|
"dist-tags": allMeta["dist-tags"],
|
|
204
208
|
deprecated: vm.deprecated,
|
|
209
|
+
dist: vm.dist,
|
|
205
210
|
};
|
|
206
211
|
});
|
|
207
212
|
}
|
|
@@ -210,6 +215,7 @@ function getMetaFromNameWithoutCache(name, cachedFilePath) {
|
|
|
210
215
|
}
|
|
211
216
|
const timestamp = Date.now();
|
|
212
217
|
const content = {
|
|
218
|
+
v: CACHE_VERSION,
|
|
213
219
|
meta,
|
|
214
220
|
timestamp,
|
|
215
221
|
expired: timestamp + Math.floor(Math.random() * 1000 * 60),
|
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.2.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",
|